1 /* 2 * Copyright (c) 2023 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 MAPLEBE_INCLUDE_CG_PEEP_H 17 #define MAPLEBE_INCLUDE_CG_PEEP_H 18 19 #include "cg.h" 20 #include "optimize_common.h" 21 22 namespace maplebe { 23 enum ReturnType : uint8 { kResUseFirst, kResDefFirst, kResNotFind }; 24 25 class PeepOptimizeManager { 26 public: 27 /* normal constructor */ PeepOptimizeManager(CGFunc & f,BB & bb,Insn & insn)28 PeepOptimizeManager(CGFunc &f, BB &bb, Insn &insn) : cgFunc(&f), currBB(&bb), currInsn(&insn), ssaInfo(nullptr) {} 29 /* constructor for ssa */ PeepOptimizeManager(CGFunc & f,BB & bb,Insn & insn,CGSSAInfo & info)30 PeepOptimizeManager(CGFunc &f, BB &bb, Insn &insn, CGSSAInfo &info) 31 : cgFunc(&f), currBB(&bb), currInsn(&insn), ssaInfo(&info) 32 { 33 } 34 ~PeepOptimizeManager() = default; 35 template <typename OptimizePattern> 36 void Optimize(bool patternEnable = false) 37 { 38 if (!patternEnable) { 39 return; 40 } 41 OptimizePattern optPattern(*cgFunc, *currBB, *currInsn, *ssaInfo); 42 optPattern.Run(*currBB, *currInsn); 43 optSuccess = optPattern.GetPatternRes() || optSuccess; 44 if (optSuccess && optPattern.GetCurrInsn() != nullptr) { 45 currInsn = optPattern.GetCurrInsn(); 46 } 47 } 48 template <typename OptimizePattern> 49 void NormalPatternOpt(bool patternEnable = false) 50 { 51 if (!patternEnable) { 52 return; 53 } 54 OptimizePattern optPattern(*cgFunc, *currBB, *currInsn); 55 optPattern.Run(*currBB, *currInsn); 56 optSuccess = optPattern.GetPatternRes() || optSuccess; 57 if (optSuccess && optPattern.GetCurrInsn() != nullptr) { 58 currInsn = optPattern.GetCurrInsn(); 59 } 60 } SetOptSuccess(bool optRes)61 void SetOptSuccess(bool optRes) 62 { 63 optSuccess = optRes; 64 } OptSuccess()65 bool OptSuccess() const 66 { 67 return optSuccess; 68 } 69 70 private: 71 CGFunc *cgFunc; 72 BB *currBB; 73 Insn *currInsn; 74 CGSSAInfo *ssaInfo; 75 /* 76 * The flag indicates whether the optimization pattern is successful, 77 * this prevents the next optimization pattern that processs the same mop from failing to get the validInsn, 78 * which was changed by previous pattern. 79 * 80 * Set the flag to true when the pattern optimize successfully. 81 */ 82 bool optSuccess = false; 83 }; 84 85 class CGPeepHole { 86 public: 87 /* normal constructor */ CGPeepHole(CGFunc & f,MemPool * memPool)88 CGPeepHole(CGFunc &f, MemPool *memPool) : cgFunc(&f), peepMemPool(memPool), ssaInfo(nullptr) {} 89 /* constructor for ssa */ CGPeepHole(CGFunc & f,MemPool * memPool,CGSSAInfo * cgssaInfo)90 CGPeepHole(CGFunc &f, MemPool *memPool, CGSSAInfo *cgssaInfo) : cgFunc(&f), peepMemPool(memPool), ssaInfo(cgssaInfo) 91 { 92 } ~CGPeepHole()93 virtual ~CGPeepHole() 94 { 95 ssaInfo = nullptr; 96 } 97 98 virtual void Run() = 0; 99 virtual bool DoSSAOptimize(BB &bb, Insn &insn) = 0; 100 virtual void DoNormalOptimize(BB &bb, Insn &insn) = 0; 101 102 protected: 103 CGFunc *cgFunc; 104 MemPool *peepMemPool; 105 CGSSAInfo *ssaInfo; 106 PeepOptimizeManager *manager = nullptr; 107 }; 108 109 class PeepPattern { 110 public: PeepPattern(CGFunc & oneCGFunc)111 explicit PeepPattern(CGFunc &oneCGFunc) : cgFunc(oneCGFunc) {} 112 virtual ~PeepPattern() = default; 113 virtual void Run(BB &bb, Insn &insn) = 0; 114 /* optimization support function */ 115 bool IfOperandIsLiveAfterInsn(const RegOperand ®Opnd, Insn &insn); 116 bool FindRegLiveOut(const RegOperand ®Opnd, const BB &bb); 117 bool CheckOpndLiveinSuccs(const RegOperand ®Opnd, const BB &bb) const; 118 bool CheckRegLiveinReturnBB(const RegOperand ®Opnd, const BB &bb) const; 119 ReturnType IsOpndLiveinBB(const RegOperand ®Opnd, const BB &bb) const; 120 int LogValueAtBase2(int64 val) const; 121 bool IsMemOperandOptPattern(const Insn &insn, Insn &nextInsn); 122 123 protected: 124 CGFunc &cgFunc; 125 }; 126 127 class CGPeepPattern { 128 public: 129 /* normal constructor */ CGPeepPattern(CGFunc & f,BB & bb,Insn & insn)130 CGPeepPattern(CGFunc &f, BB &bb, Insn &insn) : cgFunc(&f), currBB(&bb), currInsn(&insn), ssaInfo(nullptr) {} 131 /* constructor for ssa */ CGPeepPattern(CGFunc & f,BB & bb,Insn & insn,CGSSAInfo & info)132 CGPeepPattern(CGFunc &f, BB &bb, Insn &insn, CGSSAInfo &info) 133 : cgFunc(&f), currBB(&bb), currInsn(&insn), ssaInfo(&info) 134 { 135 } 136 virtual ~CGPeepPattern() = default; 137 PhaseName()138 std::string PhaseName() const 139 { 140 return "cgpeephole"; 141 } 142 143 virtual std::string GetPatternName() = 0; 144 Insn *GetDefInsn(const RegOperand &useReg); 145 void DumpAfterPattern(std::vector<Insn *> &prevInsns, const Insn *replacedInsn, const Insn *newInsn); 146 InsnSet GetAllUseInsn(const RegOperand &defReg) const; 147 int64 GetLogValueAtBase2(int64 val) const; 148 /* The CC reg is unique and cannot cross-version props. */ 149 bool IsCCRegCrossVersion(Insn &startInsn, Insn &endInsn, const RegOperand &ccReg) const; 150 /* optimization support function */ 151 bool IfOperandIsLiveAfterInsn(const RegOperand ®Opnd, Insn &insn); 152 bool FindRegLiveOut(const RegOperand ®Opnd, const BB &bb); 153 bool CheckOpndLiveinSuccs(const RegOperand ®Opnd, const BB &bb) const; 154 bool CheckRegLiveinReturnBB(const RegOperand ®Opnd, const BB &bb) const; 155 ReturnType IsOpndLiveinBB(const RegOperand ®Opnd, const BB &bb) const; GetPatternRes()156 bool GetPatternRes() const 157 { 158 return optSuccess; 159 } GetCurrInsn()160 Insn *GetCurrInsn() 161 { 162 return currInsn; 163 } SetCurrInsn(Insn * updateInsn)164 void SetCurrInsn(Insn *updateInsn) 165 { 166 currInsn = updateInsn; 167 } 168 virtual void Run(BB &bb, Insn &insn) = 0; 169 virtual bool CheckCondition(Insn &insn) = 0; 170 171 protected: 172 CGFunc *cgFunc; 173 BB *currBB; 174 Insn *currInsn; 175 CGSSAInfo *ssaInfo; 176 // !!! If the pattern is optimized, set the $optSuccess to true and check before the subsequent patterns 177 // of the same mop, otherwise, the subsequent patterns of the same mop will get the old wrong instruction. 178 bool optSuccess = false; 179 }; 180 181 class PeepHoleOptimizer { 182 public: PeepHoleOptimizer(CGFunc * cf)183 explicit PeepHoleOptimizer(CGFunc *cf) : cgFunc(cf) 184 { 185 cg = cgFunc->GetCG(); 186 } 187 ~PeepHoleOptimizer() = default; 188 void Peephole0(); 189 void PeepholeOpt(); 190 void PrePeepholeOpt(); 191 void PrePeepholeOpt1(); 192 193 private: 194 CGFunc *cgFunc; 195 CG *cg = nullptr; 196 }; /* class PeepHoleOptimizer */ 197 198 class PeepPatternMatch { 199 public: PeepPatternMatch(CGFunc & oneCGFunc,MemPool * memPool)200 PeepPatternMatch(CGFunc &oneCGFunc, MemPool *memPool) 201 : optOwnMemPool(memPool), peepAllocator(memPool), optimizations(peepAllocator.Adapter()), cgFunc(oneCGFunc) 202 { 203 } 204 virtual ~PeepPatternMatch() = default; 205 virtual void Run(BB &bb, Insn &insn) = 0; 206 virtual void InitOpts() = 0; 207 208 protected: 209 MemPool *optOwnMemPool; 210 MapleAllocator peepAllocator; 211 MapleVector<PeepPattern *> optimizations; 212 CGFunc &cgFunc; 213 }; 214 215 class PeepOptimizer { 216 public: PeepOptimizer(CGFunc & oneCGFunc,MemPool * memPool)217 PeepOptimizer(CGFunc &oneCGFunc, MemPool *memPool) : cgFunc(oneCGFunc), peepOptMemPool(memPool) 218 { 219 index = 0; 220 } 221 ~PeepOptimizer() = default; 222 template <typename T> 223 void Run(); 224 static int32 index; 225 226 private: 227 CGFunc &cgFunc; 228 MemPool *peepOptMemPool; 229 }; 230 231 MAPLE_FUNC_PHASE_DECLARE(CgPeepHole, maplebe::CGFunc) 232 MAPLE_FUNC_PHASE_DECLARE_BEGIN(CgPrePeepHole, maplebe::CGFunc) 233 MAPLE_FUNC_PHASE_DECLARE_END 234 MAPLE_FUNC_PHASE_DECLARE_BEGIN(CgPostPeepHole, maplebe::CGFunc) 235 MAPLE_FUNC_PHASE_DECLARE_END 236 MAPLE_FUNC_PHASE_DECLARE_BEGIN(CgPrePeepHole0, maplebe::CGFunc) 237 MAPLE_FUNC_PHASE_DECLARE_END 238 MAPLE_FUNC_PHASE_DECLARE_BEGIN(CgPrePeepHole1, maplebe::CGFunc) 239 MAPLE_FUNC_PHASE_DECLARE_END 240 MAPLE_FUNC_PHASE_DECLARE_BEGIN(CgPeepHole0, maplebe::CGFunc) 241 MAPLE_FUNC_PHASE_DECLARE_END 242 MAPLE_FUNC_PHASE_DECLARE_BEGIN(CgPeepHole1, maplebe::CGFunc) 243 MAPLE_FUNC_PHASE_DECLARE_END 244 } /* namespace maplebe */ 245 #endif /* MAPLEBE_INCLUDE_CG_PEEP_H */ 246