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_CG_H 17 #define MAPLEBE_INCLUDE_CG_CG_H 18 19 /* C++ headers. */ 20 #include <cstddef> 21 #include <string> 22 /* MapleIR headers. */ 23 #include "operand.h" 24 #include "insn.h" 25 #include "cgfunc.h" 26 #include "live.h" 27 #include "cg_option.h" 28 #include "opcode_info.h" 29 #include "global_tables.h" 30 #include "mir_function.h" 31 #include "mad.h" 32 33 namespace maplebe { 34 #define ADDTARGETPHASE(PhaseName, condition) \ 35 if (!CGOptions::IsSkipPhase(PhaseName)) { \ 36 pm->AddPhase(PhaseName, condition); \ 37 } 38 /* subtarget opt phase -- cyclic Dependency, use Forward declaring */ 39 class CGSSAInfo; 40 class PhiEliminate; 41 class DomAnalysis; 42 class CGProp; 43 class CGDce; 44 class AlignAnalysis; 45 class MoveRegArgs; 46 class MPISel; 47 class Standardize; 48 class LiveIntervalAnalysis; 49 class ValidBitOpt; 50 class CG; 51 class LocalOpt; 52 class CFGOptimizer; 53 54 class Globals { 55 public: GetInstance()56 static Globals *GetInstance() 57 { 58 static Globals instance; 59 return &instance; 60 } 61 62 ~Globals() = default; 63 SetBECommon(BECommon & bc)64 void SetBECommon(BECommon &bc) 65 { 66 beCommon = &bc; 67 } 68 GetBECommon()69 BECommon *GetBECommon() 70 { 71 return beCommon; 72 } 73 GetBECommon()74 const BECommon *GetBECommon() const 75 { 76 return beCommon; 77 } 78 SetMAD(MAD & m)79 void SetMAD(MAD &m) 80 { 81 mad = &m; 82 } 83 GetMAD()84 MAD *GetMAD() 85 { 86 return mad; 87 } 88 GetMAD()89 const MAD *GetMAD() const 90 { 91 return mad; 92 } 93 SetOptimLevel(int32 opLevel)94 void SetOptimLevel(int32 opLevel) 95 { 96 optimLevel = opLevel; 97 } 98 GetOptimLevel()99 int32 GetOptimLevel() const 100 { 101 return optimLevel; 102 } 103 104 void SetTarget(CG &target); 105 const CG *GetTarget() const; 106 107 private: 108 BECommon *beCommon = nullptr; 109 MAD *mad = nullptr; 110 int32 optimLevel = 0; 111 CG *cg = nullptr; 112 Globals() = default; 113 }; 114 115 class CG { 116 public: 117 using GenerateFlag = uint64; 118 119 public: CG(MIRModule & mod,const CGOptions & cgOptions)120 CG(MIRModule &mod, const CGOptions &cgOptions) 121 : memPool(memPoolCtrler.NewMemPool("maplecg mempool", false /* isLocalPool */)), 122 allocator(memPool), 123 mirModule(&mod), 124 emitter(nullptr), 125 labelOrderCnt(0), 126 cgOption(cgOptions), 127 instrumentationFunction(nullptr), 128 fileGP(nullptr) 129 { 130 const std::string &internalNameLiteral = namemangler::GetInternalNameLiteral(namemangler::kJavaLangObjectStr); 131 GStrIdx strIdxFromName = GlobalTables::GetStrTable().GetStrIdxFromName(internalNameLiteral); 132 isLibcore = (GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdxFromName) != nullptr); 133 DefineDebugTraceFunctions(); 134 isLmbc = (mirModule->GetFlavor() == MIRFlavor::kFlavorLmbc); 135 } 136 137 virtual ~CG(); 138 139 /* enroll all code generator phases for target machine */ 140 virtual void EnrollTargetPhases(MaplePhaseManager *pm) const = 0; 141 142 void GenExtraTypeMetadata(const std::string &classListFileName, const std::string &outputBaseName); 143 void GenPrimordialObjectList(const std::string &outputBaseName); 144 const std::string ExtractFuncName(const std::string &str); 145 146 virtual Insn &BuildPhiInsn(RegOperand &defOpnd, Operand &listParam) = 0; 147 virtual PhiOperand &CreatePhiOperand(MemPool &mp, MapleAllocator &mAllocator) = 0; 148 149 virtual CGFunc *CreateCGFunc(MIRModule &mod, MIRFunction &, BECommon &, MemPool &, StackMemPool &, MapleAllocator &, 150 uint32) = 0; 151 IsExclusiveEH()152 bool IsExclusiveEH() const 153 { 154 return CGOptions::IsExclusiveEH(); 155 } 156 157 virtual bool IsExclusiveFunc(MIRFunction &mirFunc) = 0; 158 159 /* NOTE: Consider making be_common a field of CG. */ 160 virtual void GenerateObjectMaps(BECommon &beCommon) = 0; 161 162 /* Used for GCTIB pattern merging */ 163 virtual std::string FindGCTIBPatternName(const std::string &name) const = 0; 164 GenerateVerboseAsm()165 bool GenerateVerboseAsm() const 166 { 167 return cgOption.GenerateVerboseAsm(); 168 } 169 GenerateVerboseCG()170 bool GenerateVerboseCG() const 171 { 172 return cgOption.GenerateVerboseCG(); 173 } 174 DoPrologueEpilogue()175 bool DoPrologueEpilogue() const 176 { 177 return cgOption.DoPrologueEpilogue(); 178 } 179 DoTailCall()180 bool DoTailCall() const 181 { 182 return cgOption.DoTailCall(); 183 } 184 DoCheckSOE()185 bool DoCheckSOE() const 186 { 187 return cgOption.DoCheckSOE(); 188 } 189 GenerateDebugFriendlyCode()190 bool GenerateDebugFriendlyCode() const 191 { 192 return cgOption.GenerateDebugFriendlyCode(); 193 } 194 GetOptimizeLevel()195 int32 GetOptimizeLevel() const 196 { 197 return cgOption.GetOptimizeLevel(); 198 } 199 UseFastUnwind()200 bool UseFastUnwind() const 201 { 202 return true; 203 } 204 IsStackProtectorStrong()205 bool IsStackProtectorStrong() const 206 { 207 return cgOption.IsStackProtectorStrong(); 208 } 209 IsStackProtectorAll()210 bool IsStackProtectorAll() const 211 { 212 return cgOption.IsStackProtectorAll(); 213 } 214 NeedInsertInstrumentationFunction()215 bool NeedInsertInstrumentationFunction() const 216 { 217 return cgOption.NeedInsertInstrumentationFunction(); 218 } 219 220 void SetInstrumentationFunction(const std::string &name); GetInstrumentationFunction()221 const MIRSymbol *GetInstrumentationFunction() const 222 { 223 return instrumentationFunction; 224 } 225 InstrumentWithDebugTraceCall()226 bool InstrumentWithDebugTraceCall() const 227 { 228 return cgOption.InstrumentWithDebugTraceCall(); 229 } 230 InstrumentWithProfile()231 bool InstrumentWithProfile() const 232 { 233 return cgOption.InstrumentWithProfile(); 234 } 235 DoPatchLongBranch()236 bool DoPatchLongBranch() const 237 { 238 return cgOption.DoPatchLongBranch(); 239 } 240 GetRematLevel()241 uint8 GetRematLevel() const 242 { 243 return CGOptions::GetRematLevel(); 244 } 245 GenYieldPoint()246 bool GenYieldPoint() const 247 { 248 return cgOption.GenYieldPoint(); 249 } 250 GenLocalRC()251 bool GenLocalRC() const 252 { 253 return cgOption.GenLocalRC(); 254 } 255 GenerateExceptionHandlingCode()256 bool GenerateExceptionHandlingCode() const 257 { 258 return cgOption.GenerateExceptionHandlingCode(); 259 } 260 DoConstFold()261 bool DoConstFold() const 262 { 263 return cgOption.DoConstFold(); 264 } 265 266 void AddStackGuardvar(); 267 void DefineDebugTraceFunctions(); GetMIRModule()268 MIRModule *GetMIRModule() 269 { 270 return mirModule; 271 } 272 SetEmitter(Emitter & emitter)273 void SetEmitter(Emitter &emitter) 274 { 275 this->emitter = &emitter; 276 } 277 GetEmitter()278 Emitter *GetEmitter() const 279 { 280 return emitter; 281 } 282 GetMIRModule()283 MIRModule *GetMIRModule() const 284 { 285 return mirModule; 286 } 287 IncreaseLabelOrderCnt()288 void IncreaseLabelOrderCnt() 289 { 290 labelOrderCnt++; 291 } 292 GetLabelOrderCnt()293 LabelIDOrder GetLabelOrderCnt() const 294 { 295 return labelOrderCnt; 296 } 297 GetCGOptions()298 const CGOptions &GetCGOptions() const 299 { 300 return cgOption; 301 } 302 UpdateCGOptions(const CGOptions & newOption)303 void UpdateCGOptions(const CGOptions &newOption) 304 { 305 cgOption.SetOptionFlag(newOption.GetOptionFlag()); 306 } 307 IsLibcore()308 bool IsLibcore() const 309 { 310 return isLibcore; 311 } 312 IsLmbc()313 bool IsLmbc() const 314 { 315 return isLmbc; 316 } 317 GetDebugTraceEnterFunction()318 MIRSymbol *GetDebugTraceEnterFunction() 319 { 320 return dbgTraceEnter; 321 } 322 GetDebugTraceEnterFunction()323 const MIRSymbol *GetDebugTraceEnterFunction() const 324 { 325 return dbgTraceEnter; 326 } 327 GetProfileFunction()328 MIRSymbol *GetProfileFunction() 329 { 330 return dbgFuncProfile; 331 } 332 GetProfileFunction()333 const MIRSymbol *GetProfileFunction() const 334 { 335 return dbgFuncProfile; 336 } 337 GetDebugTraceExitFunction()338 const MIRSymbol *GetDebugTraceExitFunction() const 339 { 340 return dbgTraceExit; 341 } 342 343 /* Init SubTarget phase */ CreateLiveAnalysis(MemPool & mp,CGFunc & f)344 virtual LiveAnalysis *CreateLiveAnalysis(MemPool &mp, CGFunc &f) const 345 { 346 return nullptr; 347 }; CreateReachingDefinition(MemPool & mp,CGFunc & f)348 virtual ReachingDefinition *CreateReachingDefinition(MemPool &mp, CGFunc &f) const 349 { 350 return nullptr; 351 }; CreateMoveRegArgs(MemPool & mp,CGFunc & f)352 virtual MoveRegArgs *CreateMoveRegArgs(MemPool &mp, CGFunc &f) const 353 { 354 return nullptr; 355 }; CreateAlignAnalysis(MemPool & mp,CGFunc & f)356 virtual AlignAnalysis *CreateAlignAnalysis(MemPool &mp, CGFunc &f) const 357 { 358 return nullptr; 359 }; CreateMPIsel(MemPool & mp,MapleAllocator & allocator,CGFunc & f)360 virtual MPISel *CreateMPIsel(MemPool &mp, MapleAllocator &allocator, CGFunc &f) const 361 { 362 return nullptr; 363 } CreateStandardize(MemPool & mp,CGFunc & f)364 virtual Standardize *CreateStandardize(MemPool &mp, CGFunc &f) const 365 { 366 return nullptr; 367 } CreateValidBitOpt(MemPool & mp,CGFunc & f,CGSSAInfo & ssaInfo)368 virtual ValidBitOpt *CreateValidBitOpt(MemPool &mp, CGFunc &f, CGSSAInfo &ssaInfo) const 369 { 370 return nullptr; 371 } 372 373 /* Init SubTarget optimization */ CreateCGSSAInfo(MemPool & mp,CGFunc & f,DomAnalysis & da,MemPool & tmp)374 virtual CGSSAInfo *CreateCGSSAInfo(MemPool &mp, CGFunc &f, DomAnalysis &da, MemPool &tmp) const 375 { 376 return nullptr; 377 }; CreateLLAnalysis(MemPool & mp,CGFunc & f)378 virtual LiveIntervalAnalysis *CreateLLAnalysis(MemPool &mp, CGFunc &f) const 379 { 380 return nullptr; 381 }; CreatePhiElimintor(MemPool & mp,CGFunc & f,CGSSAInfo & ssaInfo)382 virtual PhiEliminate *CreatePhiElimintor(MemPool &mp, CGFunc &f, CGSSAInfo &ssaInfo) const 383 { 384 return nullptr; 385 }; CreateCGProp(MemPool & mp,CGFunc & f,CGSSAInfo & ssaInfo,LiveIntervalAnalysis & ll)386 virtual CGProp *CreateCGProp(MemPool &mp, CGFunc &f, CGSSAInfo &ssaInfo, LiveIntervalAnalysis &ll) const 387 { 388 return nullptr; 389 }; CreateCGDce(MemPool & mp,CGFunc & f,CGSSAInfo & ssaInfo)390 virtual CGDce *CreateCGDce(MemPool &mp, CGFunc &f, CGSSAInfo &ssaInfo) const 391 { 392 return nullptr; 393 }; CreateLocalOpt(MemPool & mp,CGFunc & f,ReachingDefinition &)394 virtual LocalOpt *CreateLocalOpt(MemPool &mp, CGFunc &f, ReachingDefinition &) const 395 { 396 return nullptr; 397 }; CreateCFGOptimizer(MemPool & mp,CGFunc & f)398 virtual CFGOptimizer *CreateCFGOptimizer(MemPool &mp, CGFunc &f) const 399 { 400 return nullptr; 401 } 402 403 /* Object map generation helper */ 404 std::vector<int64> GetReferenceOffsets64(const BECommon &beCommon, MIRStructType &structType); 405 SetGP(MIRSymbol * sym)406 void SetGP(MIRSymbol *sym) 407 { 408 fileGP = sym; 409 } GetGP()410 MIRSymbol *GetGP() const 411 { 412 return fileGP; 413 } 414 IsInFuncWrapLabels(MIRFunction * func)415 static bool IsInFuncWrapLabels(MIRFunction *func) 416 { 417 return funcWrapLabels.find(func) != funcWrapLabels.end(); 418 } 419 SetFuncWrapLabels(MIRFunction * func,const std::pair<LabelIdx,LabelIdx> labels)420 static void SetFuncWrapLabels(MIRFunction *func, const std::pair<LabelIdx, LabelIdx> labels) 421 { 422 if (!IsInFuncWrapLabels(func)) { 423 funcWrapLabels[func] = labels; 424 } 425 } 426 GetFuncWrapLabels()427 static std::map<MIRFunction *, std::pair<LabelIdx, LabelIdx>> &GetFuncWrapLabels() 428 { 429 return funcWrapLabels; 430 } SetCurCGFunc(CGFunc & cgFunc)431 static void SetCurCGFunc(CGFunc &cgFunc) 432 { 433 currentCGFunction = &cgFunc; 434 } 435 GetCurCGFunc()436 static const CGFunc *GetCurCGFunc() 437 { 438 return currentCGFunction; 439 } 440 GetCurCGFuncNoConst()441 static CGFunc *GetCurCGFuncNoConst() 442 { 443 return currentCGFunction; 444 } 445 446 virtual const InsnDesc &GetTargetMd(MOperator mOp) const = 0; 447 virtual bool IsEffectiveCopy(Insn &insn) const = 0; 448 virtual bool IsTargetInsn(MOperator mOp) const = 0; 449 virtual bool IsClinitInsn(MOperator mOp) const = 0; 450 virtual bool IsPseudoInsn(MOperator mOp) const = 0; 451 virtual void DumpTargetOperand(Operand &opnd, const OpndDesc &opndDesc) const = 0; 452 453 protected: 454 MemPool *memPool; 455 MapleAllocator allocator; 456 457 private: 458 MIRModule *mirModule; 459 Emitter *emitter; 460 LabelIDOrder labelOrderCnt; 461 static CGFunc *currentCGFunction; /* current cg function being compiled */ 462 CGOptions cgOption; 463 MIRSymbol *instrumentationFunction; 464 MIRSymbol *dbgTraceEnter = nullptr; 465 MIRSymbol *dbgTraceExit = nullptr; 466 MIRSymbol *dbgFuncProfile = nullptr; 467 MIRSymbol *fileGP; /* for lmbc, one local %GP per file */ 468 static std::map<MIRFunction *, std::pair<LabelIdx, LabelIdx>> funcWrapLabels; 469 bool isLibcore; 470 bool isLmbc; 471 }; /* class CG */ 472 } /* namespace maplebe */ 473 474 #endif /* MAPLEBE_INCLUDE_CG_CG_H */ 475