• 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_option.h"
17 #include "cg_options.h"
18 #include "triple.h"
19 #include "option.h"
20 
21 namespace maplebe {
22 using namespace maple;
23 
24 const std::string kMplcgVersion = "";
25 
26 bool CGOptions::timePhases = false;
27 std::string CGOptions::targetArch = "";
28 std::unordered_set<std::string> CGOptions::dumpPhases = {};
29 std::unordered_set<std::string> CGOptions::skipPhases = {};
30 std::unordered_map<std::string, std::vector<std::string>> CGOptions::cyclePatternMap = {};
31 std::string CGOptions::skipFrom = "";
32 std::string CGOptions::skipAfter = "";
33 std::string CGOptions::dumpFunc = "*";
34 std::string CGOptions::globalVarProfile = "";
35 std::string CGOptions::profileData = "";
36 std::string CGOptions::profileFuncData = "";
37 std::string CGOptions::profileClassData = "";
38 #ifdef TARGARM32
39 std::string CGOptions::duplicateAsmFile = "";
40 #else
41 std::string CGOptions::duplicateAsmFile = "maple/mrt/codetricks/arch/arm64/duplicateFunc.s";
42 #endif
43 Range CGOptions::range = Range();
44 Range CGOptions::spillRanges = Range();
45 uint64 CGOptions::lsraBBOptSize = 150000;
46 uint64 CGOptions::lsraInsnOptSize = 200000;
47 uint64 CGOptions::overlapNum = 28;
48 bool CGOptions::optForSize = false;
49 bool CGOptions::enableHotColdSplit = false;
50 uint32 CGOptions::funcAlignPow = 5;
51 bool CGOptions::doOptimizedFrameLayout = true;
52 bool CGOptions::supportFuncSymbol = false;
53 bool CGOptions::doEBO = false;
54 bool CGOptions::doCGSSA = false;
55 bool CGOptions::doLocalSchedule = false;
56 bool CGOptions::doCGRegCoalesce = false;
57 bool CGOptions::doIPARA = true;
58 bool CGOptions::doCFGO = false;
59 bool CGOptions::doICO = false;
60 bool CGOptions::doStoreLoadOpt = false;
61 bool CGOptions::doGlobalOpt = false;
62 bool CGOptions::doPrePeephole = false;
63 bool CGOptions::doPeephole = false;
64 bool CGOptions::doSchedule = false;
65 bool CGOptions::doWriteRefFieldOpt = false;
66 bool CGOptions::noDupBB = false;
67 bool CGOptions::noCalleeCFI = true;
68 bool CGOptions::lazyBinding = false;
69 bool CGOptions::hotFix = false;
70 bool CGOptions::useFramePointer = false;
71 bool CGOptions::gcOnly = false;
72 bool CGOptions::doPreSchedule = false;
73 bool CGOptions::emitBlockMarker = true;
74 bool CGOptions::inRange = false;
75 bool CGOptions::doPreLSRAOpt = false;
76 bool CGOptions::doRegSavesOpt = false;
77 bool CGOptions::useSsaPreSave = false;
78 bool CGOptions::useSsuPreRestore = false;
79 bool CGOptions::generalRegOnly = false;
80 bool CGOptions::cgBigEndian = false;
81 bool CGOptions::arm64ilp32 = false;
82 bool CGOptions::doCgirVerify = false;
83 bool CGOptions::useJitCodeSign = false;
84 
GetInstance()85 CGOptions &CGOptions::GetInstance()
86 {
87     static CGOptions instance;
88     return instance;
89 }
90 
GetLogStream() const91 std::ostream& CGOptions::GetLogStream() const
92 {
93     return LogInfo::MapleLogger();
94 }
95 
96 
SolveOptions()97 bool CGOptions::SolveOptions()
98 {
99     if (opts::cg::supportFuncSymbol.IsEnabledByUser()) {
100         opts::cg::supportFuncSymbol ? EnableSupportFuncSymbol() : DisableSupportFuncSymbol();
101     }
102 
103     if (opts::cg::verboseAsm.IsEnabledByUser()) {
104         opts::cg::verboseAsm ? SetOption(CGOptions::kVerboseAsm) : ClearOption(CGOptions::kVerboseAsm);
105         SetAsmEmitterEnable(true);
106     }
107 
108     if (opts::cg::verboseCg.IsEnabledByUser()) {
109         opts::cg::verboseCg ? SetOption(CGOptions::kVerboseCG) : ClearOption(CGOptions::kVerboseCG);
110     }
111 
112     if (opts::cg::spillRange.IsEnabledByUser()) {
113 #ifdef ARK_LITECG_DEBUG
114         SetRange(opts::cg::spillRange, "--pill-range", GetSpillRanges());
115 #endif
116     }
117 
118     if (opts::cg::range.IsEnabledByUser()) {
119 #ifdef ARK_LITECG_DEBUG
120         SetRange(opts::cg::range, "--range", GetRange());
121 #endif
122     }
123 
124     if (opts::cg::timePhases.IsEnabledByUser()) {
125         opts::cg::timePhases ? EnableTimePhases() : DisableTimePhases();
126     }
127 
128     if (opts::cg::dumpFunc.IsEnabledByUser()) {
129         SetDumpFunc(opts::cg::dumpFunc);
130     }
131 
132     if (opts::cg::debug.IsEnabledByUser()) {
133         SetOption(kDebugFriendly);
134         SetOption(kWithLoc);
135         ClearOption(kSuppressFileInfo);
136     }
137 
138     if (opts::cg::gdwarf.IsEnabledByUser()) {
139         SetOption(kDebugFriendly);
140         SetOption(kWithLoc);
141         SetOption(kWithDwarf);
142         SetParserOption(kWithDbgInfo);
143         ClearOption(kSuppressFileInfo);
144     }
145 
146     if (opts::cg::gsrc.IsEnabledByUser()) {
147         SetOption(kDebugFriendly);
148         SetOption(kWithLoc);
149         SetOption(kWithSrc);
150         ClearOption(kWithMpl);
151     }
152 
153     if (opts::cg::gmixedsrc.IsEnabledByUser()) {
154         SetOption(kDebugFriendly);
155         SetOption(kWithLoc);
156         SetOption(kWithSrc);
157         SetOption(kWithMpl);
158     }
159 
160     if (opts::cg::gmixedasm.IsEnabledByUser()) {
161         SetOption(kDebugFriendly);
162         SetOption(kWithLoc);
163         SetOption(kWithSrc);
164         SetOption(kWithMpl);
165         SetOption(kWithAsm);
166     }
167 
168     if (opts::cg::withRaLinearScan.IsEnabledByUser()) {
169         SetOption(kDoLinearScanRegAlloc);
170     }
171 
172     if (opts::cg::suppressFileinfo.IsEnabledByUser()) {
173         SetOption(kSuppressFileInfo);
174     }
175 
176     if (opts::cg::dumpCfg.IsEnabledByUser()) {
177         SetOption(kDumpCFG);
178     }
179 
180     if (opts::cg::yieldpoint.IsEnabledByUser()) {
181         SetOrClear(GetGenerateFlags(), CGOptions::kGenYieldPoint, opts::cg::yieldpoint);
182     }
183 
184     if (opts::cg::localRc.IsEnabledByUser()) {
185         SetOrClear(GetGenerateFlags(), CGOptions::kGenLocalRc, opts::cg::localRc);
186     }
187 
188     if (opts::cg::cg.IsEnabledByUser()) {
189         SetRunCGFlag(opts::cg::cg);
190         opts::cg::cg ? SetOption(CGOptions::kDoCg) : ClearOption(CGOptions::kDoCg);
191     }
192 
193     if (opts::cg::generalRegOnly.IsEnabledByUser()) {
194         opts::cg::generalRegOnly ? EnableGeneralRegOnly() : DisableGeneralRegOnly();
195     }
196 
197     if (opts::cg::lazyBinding.IsEnabledByUser()) {
198         opts::cg::lazyBinding ? EnableLazyBinding() : DisableLazyBinding();
199     }
200 
201     if (opts::cg::hotFix.IsEnabledByUser()) {
202         opts::cg::hotFix ? EnableHotFix() : DisableHotFix();
203     }
204 
205     if (opts::cg::dupBb.IsEnabledByUser()) {
206         opts::cg::dupBb ? DisableNoDupBB() : EnableNoDupBB();
207     }
208 
209     if (opts::cg::calleeCfi.IsEnabledByUser()) {
210         opts::cg::calleeCfi ? DisableNoCalleeCFI() : EnableNoCalleeCFI();
211     }
212 
213     if (opts::cg::tailcall.IsEnabledByUser()) {
214         opts::cg::tailcall ? SetOption(CGOptions::kTailCallOpt) : ClearOption(CGOptions::kTailCallOpt);
215     }
216 
217     if (opts::cg::lsraBb.IsEnabledByUser()) {
218         SetLSRABBOptSize(opts::cg::lsraBb);
219     }
220 
221     if (opts::cg::lsraInsn.IsEnabledByUser()) {
222         SetLSRAInsnOptSize(opts::cg::lsraInsn);
223     }
224 
225     if (opts::cg::lsraOverlap.IsEnabledByUser()) {
226         SetOverlapNum(opts::cg::lsraOverlap);
227     }
228 
229     if (opts::cg::dumpPhases.IsEnabledByUser()) {
230 #ifdef ARK_LITECG_DEBUG
231         SplitPhases(opts::cg::dumpPhases, GetDumpPhases());
232 #endif
233     }
234 
235     if (opts::cg::target.IsEnabledByUser()) {
236 #ifdef ARK_LITECG_DEBUG
237         SetTargetMachine(opts::cg::target);
238 #endif
239     }
240 
241     if (opts::cg::skipPhases.IsEnabledByUser()) {
242 #ifdef ARK_LITECG_DEBUG
243         SplitPhases(opts::cg::skipPhases, GetSkipPhases());
244 #endif
245     }
246 
247     if (opts::cg::skipFrom.IsEnabledByUser()) {
248         SetSkipFrom(opts::cg::skipFrom);
249     }
250 
251     if (opts::cg::skipAfter.IsEnabledByUser()) {
252         SetSkipAfter(opts::cg::skipAfter);
253     }
254 
255     if (opts::cg::omitFramePointer.IsEnabledByUser()) {
256         opts::cg::omitFramePointer ? DisableFramePointer() : EnableFramePointer();
257     }
258 
259     /* big endian can be set with several options: --target, -Be.
260      * Triple takes to account all these options and allows to detect big endian with IsBigEndian() interface */
261     Triple::GetTriple().IsBigEndian() ? EnableBigEndianInCG() : DisableBigEndianInCG();
262     (maple::Triple::GetTriple().GetEnvironment() == Triple::GNUILP32) ? EnableArm64ilp32() : DisableArm64ilp32();
263 
264     if (opts::cg::cgSsa.IsEnabledByUser()) {
265         opts::cg::cgSsa ? EnableCGSSA() : DisableCGSSA();
266     }
267 
268     if (opts::cg::funcAlignPow.IsEnabledByUser()) {
269         SetFuncAlignPow(opts::cg::funcAlignPow);
270     }
271 
272     /* override some options when loc, dwarf is generated */
273     if (WithLoc()) {
274         DisableSchedule();
275         SetOption(kWithSrc);
276     }
277 
278     return true;
279 }
280 
281 #ifdef ARK_LITECG_DEBUG
SetRange(const std::string & str,const std::string & cmd,Range & subRange)282 void CGOptions::SetRange(const std::string &str, const std::string &cmd, Range &subRange)
283 {
284     const std::string &tmpStr = str;
285     size_t comma = tmpStr.find_first_of(",", 0);
286     subRange.enable = true;
287 
288     if (comma != std::string::npos) {
289         subRange.begin = std::stoul(tmpStr.substr(0, comma), nullptr);
290         subRange.end = std::stoul(tmpStr.substr(comma + 1, std::string::npos - (comma + 1)), nullptr);
291     }
292     CHECK_FATAL(range.begin < range.end, "invalid values for %s=%lu,%lu", cmd.c_str(), subRange.begin, subRange.end);
293 }
294 
EnableO0()295 void CGOptions::EnableO0()
296 {
297     optimizeLevel = kLevel0;
298     doEBO = false;
299     doCGSSA = false;
300     doLocalSchedule = false;
301     doCFGO = false;
302     doICO = false;
303     doPrePeephole = false;
304     doPeephole = false;
305     doStoreLoadOpt = false;
306     doGlobalOpt = false;
307     doPreLSRAOpt = false;
308     doPreSchedule = false;
309     doSchedule = false;
310     doRegSavesOpt = false;
311     useSsaPreSave = false;
312     useSsuPreRestore = false;
313     doWriteRefFieldOpt = false;
314 
315     ClearOption(kTailCallOpt);
316 }
317 
EnableO1()318 void CGOptions::EnableO1()
319 {
320     optimizeLevel = kLevel1;
321     doPreLSRAOpt = true;
322     SetOption(kTailCallOpt);
323 }
324 
EnableO2()325 void CGOptions::EnableO2()
326 {
327     optimizeLevel = kLevel2;
328     doEBO = true;
329     doCGSSA = true;
330     doLocalSchedule = true;
331     doCFGO = true;
332     doICO = true;
333     doPrePeephole = true;
334     doPeephole = true;
335     doStoreLoadOpt = true;
336     doGlobalOpt = true;
337     doPreSchedule = true;
338     doSchedule = true;
339 #if TARGARM32
340     doPreLSRAOpt = false;
341     doWriteRefFieldOpt = false;
342     ClearOption(kTailCallOpt);
343 #else
344     doPreLSRAOpt = true;
345     doRegSavesOpt = false;
346     useSsaPreSave = false;
347     useSsuPreRestore = true;
348     doWriteRefFieldOpt = true;
349     SetOption(kTailCallOpt);
350 #endif
351 }
352 #endif
353 
EnableLiteCG()354 void CGOptions::EnableLiteCG()
355 {
356     optimizeLevel = kLevelLiteCG;
357     doEBO = false;
358     doCGSSA = false;
359     doLocalSchedule = false;
360     doCGRegCoalesce = false;
361     doCFGO = true;
362     doICO = false;
363     doPrePeephole = false;
364     doPeephole = true;
365     doStoreLoadOpt = false;
366     doGlobalOpt = false;
367     doPreLSRAOpt = false;
368     doPreSchedule = false;
369     doSchedule = false;
370     doRegSavesOpt = false;
371     useSsaPreSave = false;
372     useSsuPreRestore = false;
373     doWriteRefFieldOpt = false;
374     supportFuncSymbol = true;
375 
376     ClearOption(kTailCallOpt);
377     SetOption(kDoLinearScanRegAlloc);
378 }
379 
380 #ifdef ARK_LITECG_DEBUG
SetTargetMachine(const std::string & str)381 void CGOptions::SetTargetMachine(const std::string &str)
382 {
383     // this is a temporary plan, all ilp32 logic follow the same path with aarch64
384     if (str == "aarch64" || str == "aarch64_be-linux-gnu_ilp32" || str == "aarch64_be-linux-gnu") {
385         targetArch = "aarch64";
386     } else if (str == "x86_64") {
387         targetArch = "x86_64";
388     } else {
389         CHECK_FATAL_FALSE("unsupported target!!");
390     }
391 }
392 
SplitPhases(const std::string & str,std::unordered_set<std::string> & set)393 void CGOptions::SplitPhases(const std::string &str, std::unordered_set<std::string> &set)
394 {
395     const std::string &tmpStr {str};
396     if ((tmpStr.compare("*") == 0) || (tmpStr.compare("cgir") == 0)) {
397         (void)set.insert(tmpStr);
398         return;
399     }
400     StringUtils::Split(tmpStr, set, ',');
401 }
402 #endif
403 
DumpPhase(const std::string & phase)404 bool CGOptions::DumpPhase(const std::string &phase)
405 {
406     return (IS_STR_IN_SET(dumpPhases, "*") || IS_STR_IN_SET(dumpPhases, "cgir") || IS_STR_IN_SET(dumpPhases, phase));
407 }
408 
409 /* match sub std::string of function name */
FuncFilter(const std::string & name)410 bool CGOptions::FuncFilter(const std::string &name)
411 {
412     return dumpFunc == "*" || dumpFunc == name;
413 }
414 } /* namespace maplebe */
415