1 /**
2 * Copyright (c) 2024-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 #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(const Inst *inst);
30 bool IsMethodStringBuilderConstructorWithStringArg(const Inst *inst);
31 bool IsMethodStringBuilderConstructorWithCharArrayArg(const Inst *inst);
32 bool IsStringBuilderToString(const Inst *inst);
33 bool IsMethodStringBuilderDefaultConstructor(const Inst *inst);
34
35 bool IsStringBuilderCtorCall(const Inst *inst, const Inst *self = nullptr);
36 bool IsStringBuilderMethod(const Inst *inst, const Inst *self = nullptr);
37 bool IsNullCheck(const Inst *inst, const Inst *self = nullptr);
38
39 bool IsIntrinsicStringConcat(const Inst *inst);
40 void InsertBeforeWithSaveState(Inst *inst, Inst *before);
41 void InsertAfterWithSaveState(Inst *inst, Inst *after);
42 void InsertBeforeWithInputs(Inst *inst, Inst *before);
43 using FindInputPredicate = std::function<bool(Input &input)>;
44 bool HasInput(Inst *inst, const FindInputPredicate &predicate);
45 bool HasInputPhiRecursively(Inst *inst, Marker visited, const FindInputPredicate &predicate);
46 void ResetInputMarkersRecursively(Inst *inst, Marker visited);
47 using FindUserPredicate = std::function<bool(User &user)>;
48 bool HasUser(Inst *inst, const FindUserPredicate &predicate);
49 bool HasUserPhiRecursively(Inst *inst, Marker visited, const FindUserPredicate &predicate);
50 bool HasUserRecursively(Inst *inst, Marker visited, const FindUserPredicate &predicate);
51 size_t CountUsers(Inst *inst, const FindUserPredicate &predicate);
52 void ResetUserMarkersRecursively(Inst *inst, Marker visited);
53 Inst *SkipSingleUserCheckInstruction(Inst *inst);
54 bool IsUsedOutsideBasicBlock(Inst *inst, BasicBlock *bb);
55 SaveStateInst *FindFirstSaveState(BasicBlock *block);
56
57 template <bool ALLOW_INLINED = false>
IsStringBuilderAppend(const Inst * inst)58 bool IsStringBuilderAppend(const Inst *inst)
59 {
60 auto runtime = inst->GetBasicBlock()->GetGraph()->GetRuntime();
61 if (inst->GetOpcode() == Opcode::CallStatic || inst->GetOpcode() == Opcode::CallVirtual) {
62 auto callInst = static_cast<const CallInst *>(inst);
63 return (ALLOW_INLINED || !callInst->IsInlined()) &&
64 runtime->IsMethodStringBuilderAppend(callInst->GetCallMethod());
65 }
66 if (inst->IsIntrinsic()) {
67 auto intrinsic = inst->CastToIntrinsic();
68 return runtime->IsIntrinsicStringBuilderAppend(intrinsic->GetIntrinsicId());
69 }
70 return false;
71 }
72
73 bool IsIntrinsicStringBuilderAppendString(Inst *inst);
74
75 using InputDesc = std::pair<Inst *, unsigned>;
76 void RemoveFromInstructionInputs(ArenaVector<InputDesc> &inputDescriptors, bool doMarkSaveStates = false);
77 bool BreakStringBuilderAppendChains(BasicBlock *block);
78
79 Inst *GetArrayLengthConstant(Inst *newArray);
80 bool CollectArrayElements(Inst *newArray, InstVector &arrayElements);
81 void CleanupStoreArrayInstructions(Inst *inst);
82 } // namespace ark::compiler
83
84 #endif // COMPILER_OPTIMIZER_OPTIMIZATIONS_STRING_BUILDER_UTILS_H
85