1 /**
2 * Copyright (c) 2024 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 #ifndef COMPILER_OPTIMIZER_OPTIMIZATIONS_STRING_BUILDER_UTILS_H
17 #define COMPILER_OPTIMIZER_OPTIMIZATIONS_STRING_BUILDER_UTILS_H
18
19 #include "optimizer/analysis/loop_analyzer.h"
20 #include "optimizer/ir/analysis.h"
21 #include "optimizer/ir/basicblock.h"
22 #include "optimizer/ir/graph.h"
23 #include "optimizer/ir/inst.h"
24 #include "optimizer/pass.h"
25
26 namespace ark::compiler {
27
28 bool IsStringBuilderInstance(Inst *inst);
29 bool IsMethodStringConcat(Inst *inst);
30 bool IsMethodStringBuilderConstructorWithStringArg(Inst *inst);
31 bool IsMethodStringBuilderConstructorWithCharArrayArg(Inst *inst);
32 bool IsStringBuilderToString(Inst *inst);
33 bool IsMethodStringBuilderDefaultConstructor(Inst *inst);
34 void InsertBeforeWithSaveState(Inst *inst, Inst *before);
35 void InsertAfterWithSaveState(Inst *inst, Inst *after);
36 void InsertBeforeWithInputs(Inst *inst, Inst *before);
37 using FindInputPredicate = std::function<bool(Input &input)>;
38 bool HasInput(Inst *inst, const FindInputPredicate &predicate);
39 bool HasInputPhiRecursively(Inst *inst, Marker visited, const FindInputPredicate &predicate);
40 void ResetInputMarkersRecursively(Inst *inst, Marker visited);
41 using FindUserPredicate = std::function<bool(User &user)>;
42 bool HasUser(Inst *inst, const FindUserPredicate &predicate);
43 bool HasUserPhiRecursively(Inst *inst, Marker visited, const FindUserPredicate &predicate);
44 bool HasUserRecursively(Inst *inst, Marker visited, const FindUserPredicate &predicate);
45 size_t CountUsers(Inst *inst, const FindUserPredicate &predicate);
46 void ResetUserMarkersRecursively(Inst *inst, Marker visited);
47 Inst *SkipSingleUserCheckInstruction(Inst *inst);
48 bool IsUsedOutsideBasicBlock(Inst *inst, BasicBlock *bb);
49 SaveStateInst *FindFirstSaveState(BasicBlock *block);
50
51 template <bool ALLOW_INLINED = false>
IsStringBuilderAppend(Inst * inst)52 bool IsStringBuilderAppend(Inst *inst)
53 {
54 auto runtime = inst->GetBasicBlock()->GetGraph()->GetRuntime();
55 if (inst->GetOpcode() == Opcode::CallStatic || inst->GetOpcode() == Opcode::CallVirtual) {
56 auto callInst = static_cast<CallInst *>(inst);
57 return (ALLOW_INLINED || !callInst->IsInlined()) &&
58 runtime->IsMethodStringBuilderAppend(callInst->GetCallMethod());
59 }
60 if (inst->IsIntrinsic()) {
61 auto intrinsic = inst->CastToIntrinsic();
62 return runtime->IsIntrinsicStringBuilderAppend(intrinsic->GetIntrinsicId());
63 }
64 return false;
65 }
66
67 bool IsIntrinsicStringBuilderAppendString(Inst *inst);
68
69 using InputDesc = std::pair<Inst *, unsigned>;
70 void RemoveFromInstructionInputs(ArenaVector<InputDesc> &inputDescriptors);
71 bool BreakStringBuilderAppendChains(BasicBlock *block);
72
73 Inst *GetArrayLengthConstant(Inst *newArray);
74 bool CollectArrayElements(Inst *newArray, InstVector &arrayElements);
75 void CleanupStoreArrayInstructions(Inst *inst);
76 } // namespace ark::compiler
77
78 #endif // COMPILER_OPTIMIZER_OPTIMIZATIONS_STRING_BUILDER_UTILS_H
79