• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "compiler/optimizer/optimizations/inlining.h"
17 #include "optimizer/ir/graph.h"
18 
19 namespace ark::compiler {
20 /*
21 1. Let actualLength = LoadObject obj (escompat.Array.actualLength)
22 2. BoundsCheck actualLength index (forced de-opt if check fails)
23 3. Let buffer = LoadObject obj (escompat.Array.buffer)
24 4. Let value = LoadArray buffer, index
25 Returns value
26 */
ExpandIntrinsicEscompatArrayGet(CallInst * callInst)27 void Inlining::ExpandIntrinsicEscompatArrayGet(CallInst *callInst)
28 {
29     auto bcAddr = callInst->GetPc();
30     auto *obj = callInst->GetInput(0).GetInst()->CastToNullCheck();
31     auto *index = callInst->GetInput(1).GetInst();
32     auto *saveState = callInst->GetInput(2).GetInst()->CastToSaveState();
33 
34     auto *runtime = GetGraph()->GetRuntime();
35     auto *arrayClass = runtime->GetEscompatArrayClass();
36     auto *actualLengthField = runtime->GetEscompatArrayActualLength(arrayClass);
37     auto *bufferField = runtime->GetEscompatArrayBuffer(arrayClass);
38 
39     auto *actualLength = GetGraph()->CreateInstLoadObject(
40         DataType::INT32, bcAddr, obj, TypeIdMixin {runtime->GetFieldId(actualLengthField), callInst->GetCallMethod()},
41         actualLengthField, runtime->IsFieldVolatile(actualLengthField));
42     BoundsCheckInst *boundsCheck =
43         GetGraph()->CreateInstBoundsCheck(DataType::INT32, bcAddr, actualLength, index, saveState);
44     boundsCheck->SetFlag(inst_flags::CAN_DEOPTIMIZE);
45 
46     auto buffer = GetGraph()->CreateInstLoadObject(
47         DataType::REFERENCE, bcAddr, obj, TypeIdMixin {runtime->GetFieldId(bufferField), callInst->GetCallMethod()},
48         bufferField, runtime->IsFieldVolatile(bufferField));
49     auto *result = GetGraph()->CreateInstLoadArray(DataType::REFERENCE, bcAddr, buffer, boundsCheck);
50 
51     callInst->InsertAfter(actualLength);
52     actualLength->InsertAfter(boundsCheck);
53     boundsCheck->InsertAfter(buffer);
54     buffer->InsertAfter(result);
55 
56     callInst->ReplaceUsers(result);
57 }
58 
59 /*
60 1. Let actualLength = LoadObject obj (escompat.Array.actualLength)
61 2. BoundsCheck actualLength index (forced de-opt if check fails)
62 3. Let buffer = LoadObject obj (escompat.Array.buffer)
63 4. StoreArray buffer, index, value
64 */
ExpandIntrinsicEscompatArraySet(CallInst * callInst)65 void Inlining::ExpandIntrinsicEscompatArraySet(CallInst *callInst)
66 {
67     auto bcAddr = callInst->GetPc();
68     auto *obj = callInst->GetInput(0).GetInst()->CastToNullCheck();
69     auto *index = callInst->GetInput(1).GetInst();
70     auto *value = callInst->GetInput(2).GetInst();
71     auto *saveState = callInst->GetInput(3).GetInst()->CastToSaveState();
72 
73     auto *runtime = GetGraph()->GetRuntime();
74     auto *arrayClass = runtime->GetEscompatArrayClass();
75     auto *actualLengthField = runtime->GetEscompatArrayActualLength(arrayClass);
76     auto *bufferField = runtime->GetEscompatArrayBuffer(arrayClass);
77 
78     auto *actualLength = GetGraph()->CreateInstLoadObject(
79         DataType::INT32, bcAddr, obj, TypeIdMixin {runtime->GetFieldId(actualLengthField), callInst->GetCallMethod()},
80         actualLengthField, runtime->IsFieldVolatile(actualLengthField));
81     auto *boundsCheck = GetGraph()->CreateInstBoundsCheck(DataType::INT32, bcAddr, actualLength, index, saveState);
82     boundsCheck->SetFlag(inst_flags::CAN_DEOPTIMIZE);
83 
84     auto buffer = GetGraph()->CreateInstLoadObject(
85         DataType::REFERENCE, bcAddr, obj, TypeIdMixin {runtime->GetFieldId(bufferField), callInst->GetCallMethod()},
86         bufferField, runtime->IsFieldVolatile(bufferField));
87     // true : needBarrier
88     auto *storeValue = GetGraph()->CreateInstStoreArray(DataType::REFERENCE, bcAddr, buffer, boundsCheck, value, true);
89 
90     callInst->InsertAfter(actualLength);
91     actualLength->InsertAfter(boundsCheck);
92     boundsCheck->InsertAfter(buffer);
93     buffer->InsertAfter(storeValue);
94 }
95 }  // namespace ark::compiler
96