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 "litecg.h"
17 #include "mir_builder.h"
18 #include "cg_option.h"
19 #include "cg.h"
20 #include "maple_phase_support.h"
21 #include "maple_phase.h"
22 #include "cg_phasemanager.h"
23 #include "triple.h"
24 #include "driver_options.h"
25 
26 namespace maple {
27 
28 namespace litecg {
29 
30 using namespace maplebe;
31 
LiteCG(Module &mirModule, const std::vector<std::string> &litecgOptions)32 LiteCG::LiteCG(Module &mirModule, const std::vector<std::string> &litecgOptions) : module(mirModule)
33 {
34     // Create CGOption: set up default options
35     // should we make CGOptions local?
36     cgOptions = &CGOptions::GetInstance();
37     if (!litecgOptions.empty()) {
38         maplecl::CommandLine::GetCommandLine().Parse(litecgOptions, cgCategory);
39         cgOptions->SolveOptions();
40     }
41     cgOptions->EnableLiteCG();
42     cgOptions->SetOption(CGOptions::kDoCg);
43     Triple::GetTriple().Init(module.IsAArch64());
44     // module information prepare
45     std::string moduleName = module.GetFileName();
46     GStrIdx fileNameStrIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(moduleName);
47 
48     // is this strictly required?
49     GStrIdx nameStrIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName("INFO_filename");
50     module.PushFileInfoPair(MIRInfoPair(nameStrIdx, fileNameStrIdx.GetIdx()));
51     module.PushFileInfoIsString(true);
52 
53     module.SetFlavor(kFlavorUnknown);  // need a new flavor
54     module.GetImportFiles().clear();
55 
56     // Setup output file name
57     module.SetOutputFileName(moduleName + ".s");
58 }
59 
60 #ifdef ARK_LITECG_DEBUG
DumpIRToFile(const std::string &fileName)61 void LiteCG::DumpIRToFile(const std::string &fileName)
62 {
63     module.DumpToFile(fileName);
64 }
65 #endif
66 
DumpCGIR()67 void LiteCG::DumpCGIR()
68 {
69     cgOptions->GetDumpPhases().insert("*");
70     cgOptions->FuncFilter("*");
71 }
72 
SetupLiteCGEmitMemoryManager( void *codeSpace, MemoryManagerAllocateDataSectionCallback dataSectionAllocator, MemoryManagerSaveFunc2AddressInfoCallback funcAddressSaver, maplebe::MemoryManagerSaveFunc2FPtoPrevSPDeltaCallback funcFpSPDeltaSaver, maplebe::MemoryManagerSaveFunc2CalleeOffsetInfoCallback funcCallOffsetSaver, maplebe::MemoryManagerSavePC2DeoptInfoCallback pc2DeoptInfoSaver, maplebe::MemoryManagerSavePC2CallSiteInfoCallback pc2CallSiteInfoSaver)73 LiteCG &LiteCG::SetupLiteCGEmitMemoryManager(
74     void *codeSpace, MemoryManagerAllocateDataSectionCallback dataSectionAllocator,
75     MemoryManagerSaveFunc2AddressInfoCallback funcAddressSaver,
76     maplebe::MemoryManagerSaveFunc2FPtoPrevSPDeltaCallback funcFpSPDeltaSaver,
77     maplebe::MemoryManagerSaveFunc2CalleeOffsetInfoCallback funcCallOffsetSaver,
78     maplebe::MemoryManagerSavePC2DeoptInfoCallback pc2DeoptInfoSaver,
79     maplebe::MemoryManagerSavePC2CallSiteInfoCallback pc2CallSiteInfoSaver)
80 {
81     cgOptions->SetupEmitMemoryManager(codeSpace, dataSectionAllocator, funcAddressSaver, funcFpSPDeltaSaver,
82                                       funcCallOffsetSaver, pc2DeoptInfoSaver, pc2CallSiteInfoSaver);
83     return *this;
84 }
85 
DoCG(bool isJit)86 void LiteCG::DoCG(bool isJit)
87 {
88     bool timePhases = cgOptions->IsEnableTimePhases();
89     MPLTimer timer;
90     if (timePhases) {
91         timer.Start();
92     }
93 
94     cgOptions->SetUseJitCodeSign(isJit);
95 
96     Globals::GetInstance()->SetOptimLevel(cgOptions->GetOptimizeLevel());
97 
98     // not sure how to do this.
99     auto cgPhaseManager = std::make_unique<ThreadLocalMemPool>(memPoolCtrler, "cg function phasemanager");
100     const MaplePhaseInfo *cgPMInfo = MaplePhaseRegister::GetMaplePhaseRegister()->GetPhaseByID(&CgFuncPM::id);
101     auto *cgfuncPhaseManager = static_cast<CgFuncPM *>(cgPMInfo->GetConstructor()(cgPhaseManager.get()));
102 
103     if (timePhases) {
104         cgfuncPhaseManager->InitTimeHandler();
105     }
106 
107     /* It is a specifc work around  (need refactor) */
108     cgfuncPhaseManager->SetQuiet(true);
109     cgfuncPhaseManager->SetCGOptions(cgOptions);
110     (void)cgfuncPhaseManager->PhaseRun(module);
111 
112     if (timePhases) {
113         cgfuncPhaseManager->DumpPhaseTime();
114         timer.Stop();
115         LogInfo::MapleLogger() << "Mplcg consumed " << timer.ElapsedMilliseconds() << "ms" << '\n';
116     }
117     cgOptions->SetUseJitCodeSign(false);
118 }
119 
120 }  // namespace litecg
121 
122 }  // namespace maple
123