• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "cg_phasemanager.h"
17 #include <vector>
18 #include <string>
19 #include "cg_option.h"
20 #include "args.h"
21 #include "label_creation.h"
22 #include "isel.h"
23 #include "offset_adjust.h"
24 #include "alignment.h"
25 #include "yieldpoint.h"
26 #include "emit.h"
27 #include "reg_alloc.h"
28 #if TARGAARCH64
29 #include "aarch64_emitter.h"
30 #include "aarch64_obj_emitter.h"
31 #include "aarch64_cg.h"
32 #endif
33 #if defined(TARGRISCV64)
34 #include "riscv64_emitter.h"
35 #endif
36 #if defined(TARGX86_64)
37 #include "x64_cg.h"
38 #include "x64_emitter.h"
39 #include "string_utils.h"
40 #endif
41 #include "triple.h"
42 
43 namespace maplebe {
44 #define CLANG (module.GetSrcLang() == kSrcLangC)
45 
46 #define RELEASE(pointer)            \
47     do {                            \
48         if ((pointer) != nullptr) { \
49             delete (pointer);       \
50             (pointer) = nullptr;    \
51         }                           \
52     } while (0)
53 
54 namespace {
55 
DumpMIRFunc(MIRFunction & func,const char * msg,bool printAlways=false,const char * extraMsg=nullptr)56 void DumpMIRFunc(MIRFunction &func, const char *msg, bool printAlways = false, const char *extraMsg = nullptr)
57 {
58     bool dumpAll = (CGOptions::GetDumpPhases().find("*") != CGOptions::GetDumpPhases().end());
59     bool dumpFunc = CGOptions::FuncFilter(func.GetName());
60     if (printAlways || (dumpAll && dumpFunc)) {
61         LogInfo::MapleLogger() << msg << '\n';
62         func.Dump();
63 
64         if (extraMsg) {
65             LogInfo::MapleLogger() << extraMsg << '\n';
66         }
67     }
68 }
69 
70 } /* anonymous namespace */
71 
GenerateOutPutFile(MIRModule & m)72 void CgFuncPM::GenerateOutPutFile(MIRModule &m)
73 {
74     CHECK_FATAL(cg != nullptr, "cg is null");
75     CHECK_FATAL(Triple::GetTriple().GetArch() != Triple::ArchType::UnknownArch, "should have triple init before!");
76     auto codegen = cg;
77     if (Triple::GetTriple().GetArch() == Triple::ArchType::x64) {
78         cg->Emit([codegen, &m](Emitter *emitter) {
79             assembler::Assembler &objAssm = static_cast<X64Emitter &>(*emitter).GetAssembler();
80             if (!codegen->GetCGOptions().SuppressFileInfo()) {
81                 objAssm.InitialFileInfo(m.GetInputFileName());
82             }
83             if (codegen->GetCGOptions().WithDwarf()) {
84                 objAssm.EmitDIHeader();
85             }
86         });
87     } else if (Triple::GetTriple().GetArch() == Triple::ArchType::aarch64) {
88         cg->template Emit<CG::EmitterType::AsmEmitter>([codegen, &m](Emitter *emitter) {
89             if (!codegen->GetCGOptions().SuppressFileInfo()) {
90                 emitter->EmitFileInfo(m.GetInputFileName());
91             }
92             if (codegen->GetCGOptions().WithDwarf()) {
93                 emitter->EmitDIHeader();
94             }
95         });
96     } else {
97         CHECK_FATAL(false, "unsupportted target!");
98     }
99     InitProfile(m);
100 }
101 
FuncLevelRun(CGFunc & cgFunc,AnalysisDataManager & serialADM)102 bool CgFuncPM::FuncLevelRun(CGFunc &cgFunc, AnalysisDataManager &serialADM)
103 {
104     bool changed = false;
105     for (size_t i = 0; i < phasesSequence.size(); ++i) {
106         SolveSkipFrom(CGOptions::GetSkipFromPhase(), i);
107         const MaplePhaseInfo *curPhase = MaplePhaseRegister::GetMaplePhaseRegister()->GetPhaseByID(phasesSequence[i]);
108         if (!IsQuiet()) {
109             LogInfo::MapleLogger() << "---Run MplCG " << (curPhase->IsAnalysis() ? "analysis" : "transform")
110                                    << " Phase [ " << curPhase->PhaseName() << " ]---\n";
111         }
112         if (curPhase->IsAnalysis()) {
113             changed |= RunAnalysisPhase<MapleFunctionPhase<CGFunc>, CGFunc>(*curPhase, serialADM, cgFunc);
114         } else {
115             changed |= RunTransformPhase<MapleFunctionPhase<CGFunc>, CGFunc>(*curPhase, serialADM, cgFunc);
116             DumpFuncCGIR(cgFunc, curPhase->PhaseName());
117         }
118         SolveSkipAfter(CGOptions::GetSkipAfterPhase(), i);
119     }
120     return changed;
121 }
122 
PostOutPut(MIRModule & m)123 void CgFuncPM::PostOutPut(MIRModule &m)
124 {
125     if (Triple::GetTriple().GetArch() == Triple::ArchType::x64) {
126         cg->Emit([this](Emitter * emitter) {
127             X64Emitter *x64Emitter = static_cast<X64Emitter *>(emitter);
128             assembler::Assembler &assm = x64Emitter->GetAssembler();
129             if (cgOptions->WithDwarf()) {
130                 assm.EmitDIFooter();
131             }
132             x64Emitter->EmitGlobalVariable(*cg);
133             x64Emitter->EmitDebugInfo(*cg);
134             assm.FinalizeFileInfo();
135             assm.CloseOutput();
136         });
137     } else if (Triple::GetTriple().GetArch() == Triple::ArchType::aarch64) {
138         cg->template Emit<CG::EmitterType::AsmEmitter>([this, &m](Emitter* emitter) {
139             emitter->EmitHugeSoRoutines(true);
140             if (cgOptions->WithDwarf()) {
141                 emitter->EmitDIFooter();
142             }
143             /* Emit global info */
144             EmitGlobalInfo(m);
145         });
146         cg->template Emit<CG::EmitterType::ObjEmiter>([](Emitter* emitter) {
147             emitter->Finish();
148             emitter->CloseOutput();
149         });
150     } else {
151         CHECK_FATAL(false, "unsupported target");
152     }
153 }
154 
155 void MarkUsedStaticSymbol(const StIdx &symbolIdx);
156 std::map<StIdx, bool> visitedSym;
157 
CollectStaticSymbolInVar(MIRConst * mirConst)158 void CollectStaticSymbolInVar(MIRConst *mirConst)
159 {
160     if (mirConst->GetKind() == kConstAddrof) {
161         auto *addrSymbol = static_cast<MIRAddrofConst *>(mirConst);
162         MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(addrSymbol->GetSymbolIndex().Idx(), true);
163         if (sym != nullptr) {
164             MarkUsedStaticSymbol(sym->GetStIdx());
165         }
166     } else if (mirConst->GetKind() == kConstAggConst) {
167         auto &constVec = static_cast<MIRAggConst *>(mirConst)->GetConstVec();
168         for (auto &cst : constVec) {
169             CollectStaticSymbolInVar(cst);
170         }
171     }
172 }
173 
MarkUsedStaticSymbol(const StIdx & symbolIdx)174 void MarkUsedStaticSymbol(const StIdx &symbolIdx)
175 {
176     if (!symbolIdx.IsGlobal()) {
177         return;
178     }
179     MIRSymbol *symbol = GlobalTables::GetGsymTable().GetSymbolFromStidx(symbolIdx.Idx(), true);
180     if (symbol == nullptr) {
181         return;
182     }
183     if (visitedSym[symbolIdx]) {
184         return;
185     } else {
186         visitedSym[symbolIdx] = true;
187     }
188     symbol->ResetIsDeleted();
189     if (symbol->IsConst()) {
190         auto *konst = symbol->GetKonst();
191         CollectStaticSymbolInVar(konst);
192     }
193 }
194 
RecursiveMarkUsedStaticSymbol(const BaseNode * baseNode)195 void RecursiveMarkUsedStaticSymbol(const BaseNode *baseNode)
196 {
197     if (baseNode == nullptr) {
198         return;
199     }
200     Opcode op = baseNode->GetOpCode();
201     switch (op) {
202         case OP_block: {
203             const BlockNode *blk = static_cast<const BlockNode *>(baseNode);
204             for (auto &stmt : blk->GetStmtNodes()) {
205                 RecursiveMarkUsedStaticSymbol(&stmt);
206             }
207             break;
208         }
209         case OP_dassign: {
210             const DassignNode *dassignNode = static_cast<const DassignNode *>(baseNode);
211             MarkUsedStaticSymbol(dassignNode->GetStIdx());
212             break;
213         }
214         case OP_addrof:
215         case OP_addrofoff:
216         case OP_dread: {
217             const AddrofNode *dreadNode = static_cast<const AddrofNode *>(baseNode);
218             MarkUsedStaticSymbol(dreadNode->GetStIdx());
219             break;
220         }
221         default: {
222             break;
223         }
224     }
225     for (size_t i = 0; i < baseNode->NumOpnds(); ++i) {
226         RecursiveMarkUsedStaticSymbol(baseNode->Opnd(i));
227     }
228 }
229 
CollectStaticSymbolInFunction(MIRFunction & func)230 void CollectStaticSymbolInFunction(MIRFunction &func)
231 {
232     RecursiveMarkUsedStaticSymbol(func.GetBody());
233 }
234 
SweepUnusedStaticSymbol(MIRModule & m)235 void CgFuncPM::SweepUnusedStaticSymbol(MIRModule &m)
236 {
237     if (!m.IsCModule()) {
238         return;
239     }
240     size_t size = GlobalTables::GetGsymTable().GetSymbolTableSize();
241     for (size_t i = 0; i < size; ++i) {
242         MIRSymbol *mirSymbol = GlobalTables::GetGsymTable().GetSymbolFromStidx(static_cast<uint32>(i));
243         if (mirSymbol != nullptr && (mirSymbol->GetSKind() == kStVar || mirSymbol->GetSKind() == kStConst) &&
244             (mirSymbol->GetStorageClass() == kScFstatic || mirSymbol->GetStorageClass() == kScPstatic)) {
245             mirSymbol->SetIsDeleted();
246         }
247     }
248 
249     visitedSym.clear();
250     /* scan all funtions  */
251     std::vector<MIRFunction *> &funcTable = GlobalTables::GetFunctionTable().GetFuncTable();
252     /* don't optimize this loop to iterator or range-base loop
253      * because AddCallGraphNode(mirFunc) will change GlobalTables::GetFunctionTable().GetFuncTable()
254      */
255     for (size_t index = 0; index < funcTable.size(); ++index) {
256         MIRFunction *mirFunc = funcTable.at(index);
257         if (mirFunc == nullptr || mirFunc->GetBody() == nullptr) {
258             continue;
259         }
260         m.SetCurFunction(mirFunc);
261         CollectStaticSymbolInFunction(*mirFunc);
262         /* scan function symbol declaration
263          * find addrof static const */
264         MIRSymbolTable *funcSymTab = mirFunc->GetSymTab();
265         if (funcSymTab) {
266             size_t localSymSize = funcSymTab->GetSymbolTableSize();
267             for (uint32 i = 0; i < localSymSize; ++i) {
268                 MIRSymbol *st = funcSymTab->GetSymbolFromStIdx(i);
269                 if (st && st->IsConst()) {
270                     MIRConst *mirConst = st->GetKonst();
271                     CollectStaticSymbolInVar(mirConst);
272                 }
273             }
274         }
275     }
276     /* scan global symbol declaration
277      * find addrof static const */
278     auto &symbolSet = m.GetSymbolSet();
279     for (auto sit = symbolSet.begin(); sit != symbolSet.end(); ++sit) {
280         MIRSymbol *s = GlobalTables::GetGsymTable().GetSymbolFromStidx(sit->Idx(), true);
281         DEBUG_ASSERT(s != nullptr, "s should not be nullptr");
282         if (s->IsConst()) {
283             MIRConst *mirConst = s->GetKonst();
284             CollectStaticSymbolInVar(mirConst);
285         }
286     }
287 }
288 
289 /* =================== new phase manager ===================  */
PhaseRun(MIRModule & m)290 bool CgFuncPM::PhaseRun(MIRModule &m)
291 {
292     // registry target based on build, cgfunc, emitter need to be registried.
293     InitializeAllTargetInfos(m.GetMemPool());
294     std::string compileTarget = "";
295     if (Triple::GetTriple().IsAarch64BeOrLe()) {
296         compileTarget = "aarch64";
297     } else if (Triple::GetTriple().GetArch() == Triple::ArchType::x64) {
298         compileTarget = "x86";
299     } else {
300         CHECK_FATAL(false, "unsupport");
301     }
302     const Target *TheTarget = nullptr;
303     TheTarget = TargetRegistry::lookupTarget(compileTarget);
304     // get target based on option
305     CreateCGAndBeCommon(m, TheTarget);
306     bool changed = false;
307     /* reserve static symbol for debugging */
308     if (!cgOptions->WithDwarf()) {
309         SweepUnusedStaticSymbol(m);
310     }
311     if (cgOptions->IsRunCG()) {
312         GenerateOutPutFile(m);
313 
314         /* Run the cg optimizations phases */
315         PrepareLower(m);
316 
317         uint32 countFuncId = 0;
318         unsigned long rangeNum = 0;
319 
320         auto userDefinedOptLevel = cgOptions->GetOptimizeLevel();
321         cg->EnrollTargetPhases(this);
322 
323         auto admMempool = AllocateMemPoolInPhaseManager("cg phase manager's analysis data manager mempool");
324         auto *serialADM = GetManagerMemPool()->New<AnalysisDataManager>(*(admMempool.get()));
325         for (auto it = m.GetFunctionList().begin(); it != m.GetFunctionList().end(); ++it) {
326             DEBUG_ASSERT(serialADM->CheckAnalysisInfoEmpty(), "clean adm before function run");
327             MIRFunction *mirFunc = *it;
328             if (mirFunc->GetBody() == nullptr) {
329                 continue;
330             }
331             if (userDefinedOptLevel == CGOptions::kLevel2 && m.HasPartO2List()) {
332                 if (m.IsInPartO2List(mirFunc->GetNameStrIdx())) {
333                     cgOptions->EnableO2();
334                 } else {
335                     cgOptions->EnableO0();
336                 }
337                 ClearAllPhases();
338                 cg->EnrollTargetPhases(this);
339                 cg->UpdateCGOptions(*cgOptions);
340                 Globals::GetInstance()->SetOptimLevel(cgOptions->GetOptimizeLevel());
341             }
342             if (!IsQuiet()) {
343                 LogInfo::MapleLogger() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>> Optimizing Function  < " << mirFunc->GetName()
344                                        << " id=" << mirFunc->GetPuidxOrigin() << " >---\n";
345             }
346             /* LowerIR. */
347             m.SetCurFunction(mirFunc);
348             if (cg->DoConstFold()) {
349                 DumpMIRFunc(*mirFunc, "************* before ConstantFold **************");
350                 ConstantFold cf(m);
351                 (void)cf.Simplify(mirFunc->GetBody());
352             }
353 
354             if (m.GetFlavor() != MIRFlavor::kFlavorLmbc) {
355                 DoFuncCGLower(m, *mirFunc);
356             }
357             /* create CGFunc */
358             MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(mirFunc->GetStIdx().Idx());
359             CHECK_NULL_FATAL(funcSt);
360             auto funcMp = std::make_unique<ThreadLocalMemPool>(memPoolCtrler, funcSt->GetName());
361             auto stackMp = std::make_unique<StackMemPool>(funcMp->GetCtrler(), "");
362             MapleAllocator funcScopeAllocator(funcMp.get());
363             mirFunc->SetPuidxOrigin(++countFuncId);
364             CGFunc *cgFunc =
365                 cg->CreateCGFunc(m, *mirFunc, *beCommon, *funcMp, *stackMp, funcScopeAllocator, countFuncId);
366             CHECK_FATAL(cgFunc != nullptr, "Create CG Function failed in cg_phase_manager");
367             CG::SetCurCGFunc(*cgFunc);
368 
369             if (cgOptions->WithDwarf()) {
370                 cgFunc->SetDebugInfo(m.GetDbgInfo());
371             }
372             /* Run the cg optimizations phases. */
373             if (CGOptions::UseRange() && rangeNum >= CGOptions::GetRangeBegin() &&
374                 rangeNum <= CGOptions::GetRangeEnd()) {
375                 CGOptions::EnableInRange();
376             }
377             changed = FuncLevelRun(*cgFunc, *serialADM);
378             /* Delete mempool. */
379             mirFunc->ReleaseCodeMemory();
380             ++rangeNum;
381             CGOptions::DisableInRange();
382         }
383         PostOutPut(m);
384 #ifdef RA_PERF_ANALYSIS
385         if (cgOptions->IsEnableTimePhases()) {
386             printLSRATime();
387         }
388 #endif
389     } else {
390         LogInfo::MapleLogger(kLlErr) << "Skipped generating .s because -no-cg is given" << '\n';
391     }
392     RELEASE(cg);
393     RELEASE(beCommon);
394     return changed;
395 }
396 
DumpFuncCGIR(const CGFunc & f,const std::string & phaseName) const397 void CgFuncPM::DumpFuncCGIR(const CGFunc &f, const std::string &phaseName) const
398 {
399     if (CGOptions::DumpPhase(phaseName) && CGOptions::FuncFilter(f.GetName())) {
400         LogInfo::MapleLogger() << "\n******** CG IR After " << phaseName << ": *********\n";
401         f.DumpCGIR();
402     }
403 }
404 
EmitGlobalInfo(MIRModule & m) const405 void CgFuncPM::EmitGlobalInfo(MIRModule &m) const
406 {
407     EmitDuplicatedAsmFunc(m);
408     if (cgOptions->IsGenerateObjectMap()) {
409         cg->GenerateObjectMaps(*beCommon);
410     }
411     cg->template Emit<CG::EmitterType::AsmEmitter>([this, &m](Emitter* emitter) {
412         emitter->EmitGlobalVariable();
413         EmitDebugInfo(m);
414         emitter->CloseOutput();
415     });
416 }
417 
InitProfile(MIRModule & m) const418 void CgFuncPM::InitProfile(MIRModule &m) const
419 {
420     if (!CGOptions::IsProfileDataEmpty()) {
421         uint32 dexNameIdx = m.GetFileinfo(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName("INFO_filename"));
422         const std::string &dexName = GlobalTables::GetStrTable().GetStringFromStrIdx(GStrIdx(dexNameIdx));
423         bool deCompressSucc = m.GetProfile().DeCompress(CGOptions::GetProfileData(), dexName);
424         if (!deCompressSucc) {
425             LogInfo::MapleLogger() << "WARN: DeCompress() " << CGOptions::GetProfileData() << "failed in mplcg()\n";
426         }
427     }
428 }
429 
CreateCGAndBeCommon(MIRModule & m,const Target * t)430 void CgFuncPM::CreateCGAndBeCommon(MIRModule &m, const Target *t)
431 {
432     DEBUG_ASSERT(cgOptions != nullptr, "New cg phase manager running FAILED  :: cgOptions unset");
433     auto outputFileName = m.GetOutputFileName();
434     Emitter *objEmitter = nullptr;
435     Emitter *asmEmitter = nullptr;
436     cg = t->createCG(m, *cgOptions, cgOptions->GetEHExclusiveFunctionNameVec(), CGOptions::GetCyclePatternMap());
437     CHECK_FATAL(cg, "you may not register the target");
438     if (Triple::GetTriple().GetArch() == Triple::ArchType::x64) {
439         assembler::Assembler *asmAssembler = nullptr;
440         if (cg->GetCGOptions().IsAsmEmitterEnable()) {
441             asmAssembler = new assembler::AsmAssembler(outputFileName);
442             asmEmitter = t->createDecoupledEmitter(*cg, *asmAssembler);
443         }
444         outputFileName = outputFileName.replace(outputFileName.length() - 1, 1, 1, 'o');
445         auto objAssembler = new assembler::ElfAssembler(outputFileName);
446         objEmitter = t->createDecoupledEmitter(*cg, *objAssembler);
447     } else if (Triple::GetTriple().GetArch() == Triple::ArchType::aarch64) {
448         if (cgOptions->IsAsmEmitterEnable()) {
449             asmEmitter = m.GetMemPool()->New<AArch64AsmEmitter>(*cg, outputFileName);
450         }
451         outputFileName = outputFileName.replace(outputFileName.length() - 1, 1, 1, 'o');
452         objEmitter = m.GetMemPool()->New<AArch64ObjEmitter>(*cg, outputFileName);
453     } else {
454         CHECK_FATAL(false, "unsupportted");
455     }
456     CHECK_FATAL(objEmitter, "you may not register emitter");
457     cg->SetObjEmitter(*objEmitter);
458     if (cg->GetCGOptions().IsAsmEmitterEnable()) {
459         CHECK_FATAL(asmEmitter, "you may not register emitter");
460         cg->SetAsmEmitter(*asmEmitter);
461     }
462     TargetMachine *targetMachine = t->createTargetMachine();
463     CHECK_FATAL(targetMachine, "you may not register targetMachine");
464     cg->SetTargetMachine(*targetMachine);
465 
466     /*
467      * Must be done before creating any BECommon instances.
468      *
469      * BECommon, when constructed, will calculate the type, size and align of all types.  As a side effect, it will also
470      * lower ptr and ref types into a64. That will drop the information of what a ptr or ref points to.
471      *
472      * All metadata generation passes which depend on the pointed-to type must be done here.
473      */
474     cg->GenPrimordialObjectList(m.GetBaseName());
475     /* We initialize a couple of BECommon's tables using the size information of GlobalTables.type_table_.
476      * So, BECommon must be allocated after all the parsing is done and user-defined types are all acounted.
477      */
478     beCommon = new BECommon(m);
479     Globals::GetInstance()->SetBECommon(*beCommon);
480     Globals::GetInstance()->SetTarget(*cg);
481 
482     /* If a metadata generation pass depends on object layout it must be done after creating BECommon. */
483     cg->GenExtraTypeMetadata(cgOptions->GetClassListFile(), m.GetBaseName());
484 
485     if (cg->NeedInsertInstrumentationFunction()) {
486         CHECK_FATAL(cgOptions->IsInsertCall(), "handling of --insert-call is not correct");
487         cg->SetInstrumentationFunction(cgOptions->GetInstrumentationFunction());
488     }
489     if (!m.IsCModule() && Triple::GetTriple().IsAarch64BeOrLe()) {
490         CGOptions::EnableFramePointer();
491     }
492 }
493 
PrepareLower(MIRModule & m)494 void CgFuncPM::PrepareLower(MIRModule &m)
495 {
496     mirLower = GetManagerMemPool()->New<MIRLower>(m, nullptr);
497     mirLower->Init();
498     cgLower =
499         GetManagerMemPool()->New<CGLowerer>(m, *beCommon, cg->GenerateExceptionHandlingCode(), cg->GenerateVerboseCG());
500     cgLower->RegisterBuiltIns();
501     cgLower->RegisterExternalLibraryFunctions();
502     cgLower->SetCheckLoadStore(CGOptions::IsCheckArrayStore());
503     if (cg->IsStackProtectorStrong() || cg->IsStackProtectorAll() || m.HasPartO2List()) {
504         cg->AddStackGuardvar();
505     }
506 }
507 
DoFuncCGLower(const MIRModule & m,MIRFunction & mirFunc)508 void CgFuncPM::DoFuncCGLower(const MIRModule &m, MIRFunction &mirFunc)
509 {
510     if (m.GetFlavor() <= kFeProduced) {
511         mirLower->SetLowerCG();
512         mirLower->SetMirFunc(&mirFunc);
513 
514         DumpMIRFunc(mirFunc, "************* before MIRLowerer **************");
515         mirLower->LowerFunc(mirFunc);
516     }
517 
518     bool isNotQuiet = !CGOptions::IsQuiet();
519     DumpMIRFunc(mirFunc, "************* before CGLowerer **************", isNotQuiet);
520 
521     cgLower->LowerFunc(mirFunc);
522 
523     DumpMIRFunc(mirFunc, "************* after  CGLowerer **************", isNotQuiet,
524                 "************* end    CGLowerer **************");
525 }
526 
EmitDuplicatedAsmFunc(MIRModule & m) const527 void CgFuncPM::EmitDuplicatedAsmFunc(MIRModule &m) const
528 {
529     if (CGOptions::IsDuplicateAsmFileEmpty()) {
530         return;
531     }
532 
533     std::ifstream duplicateAsmFileFD(CGOptions::GetDuplicateAsmFile());
534 
535     if (!duplicateAsmFileFD.is_open()) {
536         duplicateAsmFileFD.close();
537         ERR(kLncErr, " %s open failed!", CGOptions::GetDuplicateAsmFile().c_str());
538         return;
539     }
540     std::string contend;
541     bool onlyForFramework = false;
542     bool isFramework = IsFramework(m);
543 
544     while (getline(duplicateAsmFileFD, contend)) {
545         if (!contend.compare("#Libframework_start")) {
546             onlyForFramework = true;
547         }
548 
549         if (!contend.compare("#Libframework_end")) {
550             onlyForFramework = false;
551         }
552 
553         if (onlyForFramework && !isFramework) {
554             continue;
555         }
556 
557         cg->Emit([&contend](Emitter *emitter) {
558             emitter->Emit(contend + "\n");
559         });
560     }
561     duplicateAsmFileFD.close();
562 }
563 
EmitDebugInfo(const MIRModule & m) const564 void CgFuncPM::EmitDebugInfo(const MIRModule &m) const
565 {
566     if (!cgOptions->WithDwarf()) {
567         return;
568     }
569     cg->Emit([&m](Emitter* emitter) {
570         emitter->SetupDBGInfo(m.GetDbgInfo());
571         emitter->EmitDIHeaderFileInfo();
572         emitter->EmitDIDebugInfoSection(m.GetDbgInfo());
573         emitter->EmitDIDebugAbbrevSection(m.GetDbgInfo());
574         emitter->EmitDIDebugARangesSection();
575         emitter->EmitDIDebugRangesSection();
576         emitter->EmitDIDebugLineSection();
577         emitter->EmitDIDebugStrSection();
578     });
579 }
580 
IsFramework(MIRModule & m) const581 bool CgFuncPM::IsFramework([[maybe_unused]] MIRModule &m) const
582 {
583     return false;
584 }
585 MAPLE_TRANSFORM_PHASE_REGISTER(CgFuncPM, cgFuncPhaseManager)
586 /* register codegen common phases */
587 MAPLE_TRANSFORM_PHASE_REGISTER(CgLayoutFrame, layoutstackframe)
588 MAPLE_TRANSFORM_PHASE_REGISTER(CgCreateLabel, createstartendlabel)
589 MAPLE_TRANSFORM_PHASE_REGISTER(InstructionSelector, instructionselector)
590 MAPLE_TRANSFORM_PHASE_REGISTER(CgMoveRegArgs, moveargs)
591 MAPLE_TRANSFORM_PHASE_REGISTER(CgRegAlloc, regalloc)
592 MAPLE_TRANSFORM_PHASE_REGISTER(CgAlignAnalysis, alignanalysis)
593 MAPLE_TRANSFORM_PHASE_REGISTER(CgFrameFinalize, framefinalize)
594 MAPLE_TRANSFORM_PHASE_REGISTER(CgYieldPointInsertion, yieldpoint)
595 MAPLE_TRANSFORM_PHASE_REGISTER(CgGenProEpiLog, generateproepilog)
596 } /* namespace maplebe */
597