• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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_IR_ANALYSIS_H
17 #define COMPILER_OPTIMIZER_IR_ANALYSIS_H
18 
19 #include "graph.h"
20 
21 #include <optional>
22 
23 namespace ark::compiler {
24 
25 /// The file contains small analysis functions which can be used in different passes
26 class Inst;
27 class BasicBlock;
28 // returns Store value, for StoreArrayPair and StoreArrayPairI saved not last store value in second_value
29 Inst *InstStoredValue(Inst *inst, Inst **secondValue);
30 Inst *InstStoredValue(Inst *inst);
31 
32 template <typename T = Inst>
33 bool HasOsrEntryBetween(T *dominate, T *current);
34 bool HasTryBlockBetween(Inst *dominateInst, Inst *inst);
35 bool IsSuitableForImplicitNullCheck(const Inst *inst);
36 bool IsInstNotNull(const Inst *inst);
37 bool CheckFcmpInputs(Inst *input0, Inst *input1);
38 bool CheckFcmpWithConstInput(Inst *input0, Inst *input1);
39 int64_t GetPowerOfTwo(uint64_t n);
40 bool CanRemoveOverflowCheck(Inst *inst, Marker marker);
41 bool IsCastAllowedInBytecode(const Inst *inst);
42 bool IsInputTypeMismatch(Inst *inst, int32_t inputIndex, Arch arch);
43 bool ApplyForCastJoin(Inst *cast, Inst *input, Inst *origInst, Arch arch);
44 SaveStateInst *CopySaveState(Graph *graph, SaveStateInst *inst);
45 std::optional<bool> IsIfInverted(BasicBlock *phiBlock, IfImmInst *ifImm);
46 
47 // If object input has known class, return pointer to the class, else returns nullptr
48 RuntimeInterface::ClassPtr GetClassPtrForObject(Inst *inst, size_t inputNum = 0);
49 RuntimeInterface::ClassPtr GetObjectClass(Inst *inst);
50 RuntimeInterface::ClassPtr GetClass(Inst *inst);
51 
IsInstInDifferentBlocks(Inst * i1,Inst * i2)52 inline bool IsInstInDifferentBlocks(Inst *i1, Inst *i2)
53 {
54     return i1->GetBasicBlock() != i2->GetBasicBlock();
55 }
56 
57 // This function bypass all blocks and delete 'SaveStateOSR' if the block is no longer the header of the loop
58 void CleanupGraphSaveStateOSR(Graph *graph);
59 
60 class IsSaveState;
61 class IsSaveStateCanTriggerGc;
62 // returns true is there is SaveState/SafePoint between instructions
63 template <typename T = IsSaveState>
64 bool HasSaveStateBetween(Inst *domInst, Inst *inst);
65 
66 bool IsSaveStateForGc(const Inst *inst);
67 
68 /**
69  * Functions below are using for create bridge in SaveStates between source instruction and target instruction.
70  * It use in GVN etc. It inserts `source` instruction into `SaveStates` on each path between `source` and
71  * `target` instructions to save the object in case GC is triggered on this path.
72  * Instructions on how to use it: compiler/docs/bridges.md
73  */
74 class SaveStateBridgesBuilder {
75 public:
76     ArenaVector<Inst *> *SearchMissingObjInSaveStates(Graph *graph, Inst *source, Inst *target,
77                                                       Inst *stopSearch = nullptr, BasicBlock *targetBlock = nullptr);
78     void CreateBridgeInSS(Inst *source);
79     void SearchAndCreateMissingObjInSaveState(Graph *graph, Inst *source, Inst *target, Inst *stopSearchInst = nullptr,
80                                               BasicBlock *targetBlock = nullptr);
81     void FixInstUsageInSS(Graph *graph, Inst *inst);
82     void FixSaveStatesInBB(BasicBlock *block);
83     void FixPhisWithCheckInputs(BasicBlock *block);
84     void DumpBridges(std::ostream &out, Inst *source);
85 
86 private:
87     void SearchSSOnWay(BasicBlock *block, Inst *startFrom, Inst *sourceInst, Marker visited, Inst *stopSearch);
88     bool IsSaveStateForGc(Inst *inst);
89     void ProcessSSUserPreds(Graph *graph, Inst *inst, Inst *targetInst);
90     void SearchInSaveStateAndFillBridgeVector(Inst *inst, Inst *searchedInst);
91     void FixUsageInstInOtherBB(BasicBlock *block, Inst *inst);
92     void FixUsagePhiInBB(BasicBlock *block, Inst *inst);
93     void DeleteUnrealObjInSaveState(Inst *ss);
94     /**
95      * Pointer to moved out to class for reduce memory usage in each pair of equal instructions.
96      * When using functions, it looks like we work as if every time get a new vector,
97      * but one vector is always used and cleaned before use.
98      */
99     ArenaVector<Inst *> *bridges_ {nullptr};
100 };
101 
102 class InstAppender {
103 public:
block_(block)104     explicit InstAppender(BasicBlock *block, Inst *insertAfter = nullptr) : block_(block), prev_(insertAfter) {}
105     ~InstAppender() = default;
106     DEFAULT_MOVE_SEMANTIC(InstAppender);
107     NO_COPY_SEMANTIC(InstAppender);
108 
109     void Append(Inst *inst);
110     void Append(std::initializer_list<Inst *> instructions);
111 
112 private:
113     BasicBlock *block_;
114     Inst *prev_ {nullptr};
115 };
116 
117 bool StoreValueCanBeObject(Inst *inst);
118 
119 bool IsConditionEqual(const Inst *inst0, const Inst *inst1, bool inverted);
120 
121 }  // namespace ark::compiler
122 
123 #endif  // COMPILER_OPTIMIZER_IR_ANALYSIS_H
124