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_AARCH64_AARCH64_CG_H 17 #define MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_CG_H 18 19 #include "cg.h" 20 #include "aarch64_cgfunc.h" 21 #include "aarch64_ssa.h" 22 #include "aarch64_phi_elimination.h" 23 #include "aarch64_prop.h" 24 #include "aarch64_dce.h" 25 #include "aarch64_live.h" 26 #include "aarch64_reaching.h" 27 #include "aarch64_args.h" 28 #include "aarch64_alignment.h" 29 #include "aarch64_validbit_opt.h" 30 #include "aarch64_reg_coalesce.h" 31 #include "aarch64_cfgo.h" 32 33 namespace maplebe { 34 constexpr int64 kShortBRDistance = (8 * 1024); 35 constexpr int64 kNegativeImmLowerLimit = -4096; 36 constexpr int32 kIntRegTypeNum = 5; 37 constexpr uint32 kAlignPseudoSize = 3; 38 constexpr uint32 kInsnSize = 4; 39 constexpr uint32 kAlignMovedFlag = 31; 40 41 /* Supporting classes for GCTIB merging */ 42 class GCTIBKey { 43 public: GCTIBKey(MapleAllocator & allocator,uint32 rcHeader,std::vector<uint64> & patternWords)44 GCTIBKey(MapleAllocator &allocator, uint32 rcHeader, std::vector<uint64> &patternWords) 45 : header(rcHeader), bitMapWords(allocator.Adapter()) 46 { 47 (void)bitMapWords.insert(bitMapWords.begin(), patternWords.begin(), patternWords.end()); 48 } 49 50 ~GCTIBKey() = default; 51 GetHeader()52 uint32 GetHeader() const 53 { 54 return header; 55 } 56 GetBitmapWords()57 const MapleVector<uint64> &GetBitmapWords() const 58 { 59 return bitMapWords; 60 } 61 62 private: 63 uint32 header; 64 MapleVector<uint64> bitMapWords; 65 }; 66 67 class Hasher { 68 public: operator()69 size_t operator()(const GCTIBKey *key) const 70 { 71 CHECK_NULL_FATAL(key); 72 size_t hash = key->GetHeader(); 73 return hash; 74 } 75 }; 76 77 class EqualFn { 78 public: operator()79 bool operator()(const GCTIBKey *firstKey, const GCTIBKey *secondKey) const 80 { 81 CHECK_NULL_FATAL(firstKey); 82 CHECK_NULL_FATAL(secondKey); 83 const MapleVector<uint64> &firstWords = firstKey->GetBitmapWords(); 84 const MapleVector<uint64> &secondWords = secondKey->GetBitmapWords(); 85 86 if ((firstKey->GetHeader() != secondKey->GetHeader()) || (firstWords.size() != secondWords.size())) { 87 return false; 88 } 89 90 for (size_t i = 0; i < firstWords.size(); ++i) { 91 if (firstWords[i] != secondWords[i]) { 92 return false; 93 } 94 } 95 return true; 96 } 97 }; 98 99 class GCTIBPattern { 100 public: GCTIBPattern(GCTIBKey & patternKey,MemPool & mp)101 GCTIBPattern(GCTIBKey &patternKey, MemPool &mp) : name(&mp) 102 { 103 key = &patternKey; 104 id = GetId(); 105 name = GCTIB_PREFIX_STR + std::string("PTN_") + std::to_string(id); 106 } 107 108 ~GCTIBPattern() = default; 109 GetId()110 int GetId() const 111 { 112 static int id = 0; 113 return id++; 114 } 115 GetName()116 std::string GetName() const 117 { 118 DEBUG_ASSERT(!name.empty(), "null name check!"); 119 return std::string(name.c_str()); 120 } 121 SetName(const std::string & ptnName)122 void SetName(const std::string &ptnName) 123 { 124 name = ptnName; 125 } 126 127 private: 128 int id; 129 MapleString name; 130 GCTIBKey *key; 131 }; 132 133 /* sub Target info & implement */ 134 class AArch64CG : public CG { 135 public: AArch64CG(MIRModule & mod,const CGOptions & opts,const std::vector<std::string> & nameVec,const std::unordered_map<std::string,std::vector<std::string>> & patternMap)136 AArch64CG(MIRModule &mod, const CGOptions &opts, const std::vector<std::string> &nameVec, 137 const std::unordered_map<std::string, std::vector<std::string>> &patternMap) 138 : CG(mod, opts), 139 ehExclusiveNameVec(nameVec), 140 cyclePatternMap(patternMap), 141 keyPatternMap(allocator.Adapter()), 142 symbolPatternMap(allocator.Adapter()) 143 { 144 } 145 146 ~AArch64CG() override = default; 147 CreateCGFunc(MIRModule & mod,MIRFunction & mirFunc,BECommon & bec,MemPool & memPool,StackMemPool & stackMp,MapleAllocator & mallocator,uint32 funcId)148 CGFunc *CreateCGFunc(MIRModule &mod, MIRFunction &mirFunc, BECommon &bec, MemPool &memPool, StackMemPool &stackMp, 149 MapleAllocator &mallocator, uint32 funcId) override 150 { 151 return memPool.New<AArch64CGFunc>(mod, *this, mirFunc, bec, memPool, stackMp, mallocator, funcId); 152 } 153 154 void EnrollTargetPhases(MaplePhaseManager *pm) const override; 155 GetCyclePatternMap()156 const std::unordered_map<std::string, std::vector<std::string>> &GetCyclePatternMap() const 157 { 158 return cyclePatternMap; 159 } 160 161 void GenerateObjectMaps(BECommon &beCommon) override; 162 163 bool IsExclusiveFunc(MIRFunction &) override; 164 165 void FindOrCreateRepresentiveSym(std::vector<uint64> &bitmapWords, uint32 rcHeader, const std::string &name); 166 167 void CreateRefSymForGlobalPtn(GCTIBPattern &ptn) const; 168 169 Insn &BuildPhiInsn(RegOperand &defOpnd, Operand &listParam) override; 170 171 PhiOperand &CreatePhiOperand(MemPool &mp, MapleAllocator &mAllocator) override; 172 173 std::string FindGCTIBPatternName(const std::string &name) const override; 174 CreateLiveAnalysis(MemPool & mp,CGFunc & f)175 LiveAnalysis *CreateLiveAnalysis(MemPool &mp, CGFunc &f) const override 176 { 177 return mp.New<AArch64LiveAnalysis>(f, mp); 178 } CreateReachingDefinition(MemPool & mp,CGFunc & f)179 ReachingDefinition *CreateReachingDefinition(MemPool &mp, CGFunc &f) const override 180 { 181 return mp.New<AArch64ReachingDefinition>(f, mp); 182 } CreateMoveRegArgs(MemPool & mp,CGFunc & f)183 MoveRegArgs *CreateMoveRegArgs(MemPool &mp, CGFunc &f) const override 184 { 185 return mp.New<AArch64MoveRegArgs>(f); 186 } CreateAlignAnalysis(MemPool & mp,CGFunc & f)187 AlignAnalysis *CreateAlignAnalysis(MemPool &mp, CGFunc &f) const override 188 { 189 return mp.New<AArch64AlignAnalysis>(f, mp); 190 } CreateCGSSAInfo(MemPool & mp,CGFunc & f,DomAnalysis & da,MemPool & tmp)191 CGSSAInfo *CreateCGSSAInfo(MemPool &mp, CGFunc &f, DomAnalysis &da, MemPool &tmp) const override 192 { 193 return mp.New<AArch64CGSSAInfo>(f, da, mp, tmp); 194 } CreateLLAnalysis(MemPool & mp,CGFunc & f)195 LiveIntervalAnalysis *CreateLLAnalysis(MemPool &mp, CGFunc &f) const override 196 { 197 return mp.New<AArch64LiveIntervalAnalysis>(f, mp); 198 }; CreatePhiElimintor(MemPool & mp,CGFunc & f,CGSSAInfo & ssaInfo)199 PhiEliminate *CreatePhiElimintor(MemPool &mp, CGFunc &f, CGSSAInfo &ssaInfo) const override 200 { 201 return mp.New<AArch64PhiEliminate>(f, ssaInfo, mp); 202 } CreateCGProp(MemPool & mp,CGFunc & f,CGSSAInfo & ssaInfo,LiveIntervalAnalysis & ll)203 CGProp *CreateCGProp(MemPool &mp, CGFunc &f, CGSSAInfo &ssaInfo, LiveIntervalAnalysis &ll) const override 204 { 205 return mp.New<AArch64Prop>(mp, f, ssaInfo, ll); 206 } CreateCGDce(MemPool & mp,CGFunc & f,CGSSAInfo & ssaInfo)207 CGDce *CreateCGDce(MemPool &mp, CGFunc &f, CGSSAInfo &ssaInfo) const override 208 { 209 return mp.New<AArch64Dce>(mp, f, ssaInfo); 210 } CreateValidBitOpt(MemPool & mp,CGFunc & f,CGSSAInfo & ssaInfo)211 ValidBitOpt *CreateValidBitOpt(MemPool &mp, CGFunc &f, CGSSAInfo &ssaInfo) const override 212 { 213 return mp.New<AArch64ValidBitOpt>(f, ssaInfo); 214 } CreateCFGOptimizer(MemPool & mp,CGFunc & f)215 CFGOptimizer *CreateCFGOptimizer(MemPool &mp, CGFunc &f) const override 216 { 217 return mp.New<AArch64CFGOptimizer>(f, mp); 218 } 219 220 /* Return the copy operand id of reg1 if it is an insn who just do copy from reg1 to reg2. 221 * i. mov reg2, reg1 222 * ii. add/sub reg2, reg1, 0/zero register 223 * iii. mul reg2, reg1, 1 224 */ 225 bool IsEffectiveCopy(Insn &insn) const final; 226 bool IsTargetInsn(MOperator mOp) const final; 227 bool IsClinitInsn(MOperator mOp) const final; 228 bool IsPseudoInsn(MOperator mOp) const final; 229 void DumpTargetOperand(Operand &opnd, const OpndDesc &opndDesc) const final; GetTargetMd(MOperator mOp)230 const InsnDesc &GetTargetMd(MOperator mOp) const final 231 { 232 return kMd[mOp]; 233 } 234 235 static const InsnDesc kMd[kMopLast]; 236 enum : uint8 { kR8List, kR16List, kR32List, kR64List, kV64List }; 237 static std::array<std::array<const std::string, kAllRegNum>, kIntRegTypeNum> intRegNames; 238 static std::array<const std::string, kAllRegNum> vectorRegNames; 239 240 private: 241 const std::vector<std::string> &ehExclusiveNameVec; 242 const std::unordered_map<std::string, std::vector<std::string>> &cyclePatternMap; 243 MapleUnorderedMap<GCTIBKey *, GCTIBPattern *, Hasher, EqualFn> keyPatternMap; 244 MapleUnorderedMap<std::string, GCTIBPattern *> symbolPatternMap; 245 }; 246 } /* namespace maplebe */ 247 248 #endif /* MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_CG_H */ 249