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