• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-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_LICM_CONDITIONS_H
17 #define COMPILER_OPTIMIZER_OPTIMIZATIONS_LICM_CONDITIONS_H
18 
19 #include "optimizer/optimizations/loop_transform.h"
20 #include "condition_chain_manager.h"
21 #include "condition_chain_cache.h"
22 #include "compiler_options.h"
23 
24 namespace ark::compiler {
25 
26 class ConditionChainContext {
27 public:
ConditionChainContext(ConditionChain * chain,BasicBlock * multiplePredecessorsSuccessor,BasicBlock * singlePredecessorSuccessor,bool hoistPhiAvailable)28     ConditionChainContext(ConditionChain *chain, BasicBlock *multiplePredecessorsSuccessor,
29                           BasicBlock *singlePredecessorSuccessor, bool hoistPhiAvailable)
30         : chain_(chain),
31           multiplePredecessorsSuccessor_(multiplePredecessorsSuccessor),
32           singlePredecessorSuccessor_(singlePredecessorSuccessor),
33           hoistPhiAvailable_(hoistPhiAvailable)
34     {
35     }
36 
GetChain()37     ConditionChain *GetChain() const
38     {
39         return chain_;
40     }
41 
GetMultiplePredecessorsSuccessor()42     BasicBlock *GetMultiplePredecessorsSuccessor() const
43     {
44         return multiplePredecessorsSuccessor_;
45     }
46 
GetSinglePredecessorSuccessor()47     BasicBlock *GetSinglePredecessorSuccessor() const
48     {
49         return singlePredecessorSuccessor_;
50     }
51 
SetMultiplePredecessorsSuccessor(BasicBlock * multiplePredecessorsSuccessor)52     void SetMultiplePredecessorsSuccessor(BasicBlock *multiplePredecessorsSuccessor)
53     {
54         multiplePredecessorsSuccessor_ = multiplePredecessorsSuccessor;
55     }
56 
SetSingleSPredecessorSuccessor(BasicBlock * singlePredecessorSuccessor)57     void SetSingleSPredecessorSuccessor(BasicBlock *singlePredecessorSuccessor)
58     {
59         singlePredecessorSuccessor_ = singlePredecessorSuccessor;
60     }
61 
IsHoistPhiAvailable()62     bool IsHoistPhiAvailable() const
63     {
64         return hoistPhiAvailable_;
65     }
66 
67 private:
68     ConditionChain *chain_;
69     BasicBlock *multiplePredecessorsSuccessor_;
70     BasicBlock *singlePredecessorSuccessor_;
71     bool hoistPhiAvailable_;
72 };
73 
74 class LicmConditions : public LoopTransform<LoopExitPoint::LOOP_EXIT_HEADER> {
75 public:
LicmConditions(Graph * graph)76     explicit LicmConditions(Graph *graph)
77         : LoopTransform(graph),
78           conditionChainsCtx_(graph->GetLocalAllocator()->Adapter()),
79           samePhiInput_(graph->GetLocalAllocator()->Adapter()),
80           multiplePredecessorsSuccessorPreds_(graph->GetLocalAllocator()->Adapter()),
81           multiplePredecessorsSuccessorRemovedPredIndices_(graph->GetLocalAllocator()->Adapter()),
82           conditionChainsCache_(graph->GetLocalAllocator()),
83           conditionChainManager_(graph->GetLocalAllocator())
84     {
85     }
86     bool RunImpl() override;
GetPassName()87     const char *GetPassName() const override
88     {
89         return "LICM_conditions";
90     }
91 
IsEnable()92     bool IsEnable() const override
93     {
94         return g_options.IsCompilerLicmConditions();
95     }
96 
97     void InvalidateAnalyses() override;
98 
99 private:
100     static bool IsHoistPhiAvailable(const ConditionChain *chain, ArenaVector<BasicBlock *> &preds,
101                                     const BasicBlock *singlePredSucc);
102     bool TransformLoop(Loop *loop) override;
103     void MarkHoistableInst();
104     bool IsHoistable(const ConditionChain *chain);
105     bool AllInputsDominate(const Inst *inst, const Loop *loop);
106     void FindHoistableConditionChains(Loop *loop);
107     bool AllPhiAllowConditionChainHoisting(const ConditionChain *chain, const BasicBlock *multiplePredsSucc,
108                                            bool hoistPhiAvailable);
109     Inst *SamePhiInputFromChain(Inst *phi, const ConditionChain *chain);
110     void HoistConditionChains(Loop *loop);
111     void SplitChainFirstBasicBlock(ConditionChain *chain);
112     BasicBlock *ReplaceChainWithSingleBlock(BasicBlock *appendBb, const ConditionChainContext &chainCtx);
113     void SaveMulitplePredecessorsSuccessorPreds(const BasicBlock *bb);
114     PhiInst *AddPhiInst(BasicBlock *bb, const ConditionChain *chain);
115     void AddSingleIfImmInst(BasicBlock *bb, const ConditionChain *chain, Inst *input);
116     void SaveProcessedBlocks(const ConditionChain *chain);
117     void AdjustPredecessorEdges(BasicBlock *chainFirstBb, BasicBlock *bb);
118     void UpdateMultiplePredecessorsSuccessorsPreds(const ConditionChainContext &chainCtx, BasicBlock *phiBlock,
119                                                    BasicBlock *emptyBlock);
120     void UpdatePhis(const ConditionChain *chain, BasicBlock *multiplePredsSucc, BasicBlock *phiBlock,
121                     bool hoistPhiAvailable);
122     ArenaVector<ConditionChainContext> conditionChainsCtx_;
123     ArenaUnorderedMap<std::pair<const ConditionChain *, Inst *>, Inst *, PairHash> samePhiInput_;
124     ArenaVector<BasicBlock *> multiplePredecessorsSuccessorPreds_;
125     ArenaVector<size_t> multiplePredecessorsSuccessorRemovedPredIndices_;
126     ConditionChainCache conditionChainsCache_;
127     Marker processedBlocksMarker_ {UNDEF_MARKER};
128     Marker hoistableInstMarker_ {UNDEF_MARKER};
129     ConditionChainManager conditionChainManager_;
130     bool isApplied_ {false};
131 };
132 }  // namespace ark::compiler
133 
134 #endif  // COMPILER_OPTIMIZER_OPTIMIZATIONS_LICM_CONDITIONS_H
135