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 <fstream>
18 #include <unordered_map>
19 #include "cg_options.h"
20 #include "driver_options.h"
21 #include "mpl_logging.h"
22 #include "parser_opt.h"
23 #include "mir_parser.h"
24 #include "string_utils.h"
25 #include "triple.h"
26
27 namespace maplebe {
28 using namespace maple;
29
30 const std::string kMplcgVersion = "";
31
32 bool CGOptions::timePhases = false;
33 std::string CGOptions::targetArch = "";
34 std::unordered_set<std::string> CGOptions::dumpPhases = {};
35 std::unordered_set<std::string> CGOptions::skipPhases = {};
36 std::unordered_map<std::string, std::vector<std::string>> CGOptions::cyclePatternMap = {};
37 std::string CGOptions::skipFrom = "";
38 std::string CGOptions::skipAfter = "";
39 std::string CGOptions::dumpFunc = "*";
40 std::string CGOptions::globalVarProfile = "";
41 std::string CGOptions::profileData = "";
42 std::string CGOptions::profileFuncData = "";
43 std::string CGOptions::profileClassData = "";
44 #ifdef TARGARM32
45 std::string CGOptions::duplicateAsmFile = "";
46 #else
47 std::string CGOptions::duplicateAsmFile = "maple/mrt/codetricks/arch/arm64/duplicateFunc.s";
48 #endif
49 Range CGOptions::range = Range();
50 std::string CGOptions::fastFuncsAsmFile = "";
51 Range CGOptions::spillRanges = Range();
52 uint8 CGOptions::fastAllocMode = 0; /* 0: fast, 1: spill all */
53 bool CGOptions::fastAlloc = false;
54 uint64 CGOptions::lsraBBOptSize = 150000;
55 uint64 CGOptions::lsraInsnOptSize = 200000;
56 uint64 CGOptions::overlapNum = 28;
57 uint8 CGOptions::rematLevel = 2;
58 bool CGOptions::optForSize = false;
59 bool CGOptions::enableHotColdSplit = false;
60 uint32 CGOptions::alignMinBBSize = 16;
61 uint32 CGOptions::alignMaxBBSize = 96;
62 uint32 CGOptions::loopAlignPow = 4;
63 uint32 CGOptions::jumpAlignPow = 5;
64 uint32 CGOptions::funcAlignPow = 5;
65 bool CGOptions::doOptimizedFrameLayout = true;
66 bool CGOptions::supportFuncSymbol = false;
67 #if TARGAARCH64 || TARGRISCV64
68 bool CGOptions::useBarriersForVolatile = false;
69 #else
70 bool CGOptions::useBarriersForVolatile = true;
71 #endif
72 bool CGOptions::exclusiveEH = false;
73 bool CGOptions::doEBO = false;
74 bool CGOptions::doCGSSA = false;
75 bool CGOptions::doLocalSchedule = false;
76 bool CGOptions::doCGRegCoalesce = false;
77 bool CGOptions::doIPARA = true;
78 bool CGOptions::doCFGO = false;
79 bool CGOptions::doICO = false;
80 bool CGOptions::doStoreLoadOpt = false;
81 bool CGOptions::doGlobalOpt = false;
82 bool CGOptions::doVregRename = false;
83 bool CGOptions::doMultiPassColorRA = true;
84 bool CGOptions::doPrePeephole = false;
85 bool CGOptions::doPeephole = false;
86 bool CGOptions::doRetMerge = false;
87 bool CGOptions::doSchedule = false;
88 bool CGOptions::doWriteRefFieldOpt = false;
89 bool CGOptions::dumpOptimizeCommonLog = false;
90 bool CGOptions::checkArrayStore = false;
91 bool CGOptions::doPIC = false;
92 bool CGOptions::noDupBB = false;
93 bool CGOptions::noCalleeCFI = true;
94 bool CGOptions::emitCyclePattern = false;
95 bool CGOptions::insertYieldPoint = false;
96 bool CGOptions::mapleLinker = false;
97 bool CGOptions::printFunction = false;
98 bool CGOptions::nativeOpt = false;
99 bool CGOptions::lazyBinding = false;
100 bool CGOptions::hotFix = false;
101 bool CGOptions::debugSched = false;
102 bool CGOptions::bruteForceSched = false;
103 bool CGOptions::simulateSched = false;
104 CGOptions::ABIType CGOptions::abiType = kABIHard;
105 bool CGOptions::genLongCalls = false;
106 bool CGOptions::functionSections = false;
107 bool CGOptions::useFramePointer = false;
108 bool CGOptions::gcOnly = false;
109 bool CGOptions::quiet = true;
110 bool CGOptions::doPatchLongBranch = false;
111 bool CGOptions::doPreSchedule = false;
112 bool CGOptions::emitBlockMarker = true;
113 bool CGOptions::inRange = false;
114 bool CGOptions::doPreLSRAOpt = false;
115 bool CGOptions::doRegSavesOpt = false;
116 bool CGOptions::useSsaPreSave = false;
117 bool CGOptions::useSsuPreRestore = false;
118 bool CGOptions::replaceASM = false;
119 bool CGOptions::generalRegOnly = false;
120 bool CGOptions::fastMath = false;
121 bool CGOptions::doAlignAnalysis = false;
122 bool CGOptions::doCondBrAlign = false;
123 bool CGOptions::cgBigEndian = false;
124 bool CGOptions::arm64ilp32 = false;
125 bool CGOptions::noCommon = false;
126 bool CGOptions::doCgirVerify = false;
127 bool CGOptions::useJitCodeSign = false;
128
GetInstance()129 CGOptions &CGOptions::GetInstance()
130 {
131 static CGOptions instance;
132 return instance;
133 }
134
GetLogStream() const135 std::ostream& CGOptions::GetLogStream() const
136 {
137 return LogInfo::MapleLogger();
138 }
139
DecideMplcgRealLevel(bool isDebug)140 void CGOptions::DecideMplcgRealLevel(bool isDebug)
141 {
142 if (opts::cg::o0) {
143 if (isDebug) {
144 LogInfo::MapleLogger() << "Real Mplcg level: O0\n";
145 }
146 EnableO0();
147 }
148
149 if (opts::cg::o1) {
150 if (isDebug) {
151 LogInfo::MapleLogger() << "Real Mplcg level: O1\n";
152 }
153 EnableO1();
154 }
155
156 if (opts::cg::o2 || opts::cg::os) {
157 if (opts::cg::os) {
158 optForSize = true;
159 }
160 if (isDebug) {
161 std::string oLog = (opts::cg::os == true) ? "Os" : "O2";
162 LogInfo::MapleLogger() << "Real Mplcg level: " << oLog << "\n";
163 }
164 EnableO2();
165 }
166 if (opts::cg::olitecg) {
167 if (isDebug) {
168 LogInfo::MapleLogger() << "Real Mplcg level: LiteCG\n";
169 }
170 EnableLiteCG();
171 }
172 }
173
SolveOptions(bool isDebug)174 bool CGOptions::SolveOptions(bool isDebug)
175 {
176 DecideMplcgRealLevel(isDebug);
177
178 for (const auto &opt : cgCategory.GetEnabledOptions()) {
179 std::string printOpt;
180 if (isDebug) {
181 for (const auto &val : opt->GetRawValues()) {
182 printOpt += opt->GetName() + " " + val + " ";
183 }
184 LogInfo::MapleLogger() << "cg options: " << printOpt << '\n';
185 }
186 }
187
188 if (opts::cg::supportFuncSymbol.IsEnabledByUser()) {
189 opts::cg::supportFuncSymbol ? EnableSupportFuncSymbol() : DisableSupportFuncSymbol();
190 }
191
192 if (opts::cg::quiet.IsEnabledByUser()) {
193 SetQuiet(true);
194 }
195
196 if (opts::verbose.IsEnabledByUser()) {
197 SetQuiet(false);
198 }
199
200 if (opts::cg::pie.IsEnabledByUser()) {
201 opts::cg::pie ? SetOption(CGOptions::kGenPie) : ClearOption(CGOptions::kGenPie);
202 }
203
204 if (opts::cg::fpic.IsEnabledByUser()) {
205 if (opts::cg::fpic) {
206 EnablePIC();
207 SetOption(CGOptions::kGenPic);
208 } else {
209 DisablePIC();
210 ClearOption(CGOptions::kGenPic);
211 }
212 }
213
214 if (opts::cg::verboseAsm.IsEnabledByUser()) {
215 opts::cg::verboseAsm ? SetOption(CGOptions::kVerboseAsm) : ClearOption(CGOptions::kVerboseAsm);
216 SetAsmEmitterEnable(true);
217 }
218
219 if (opts::cg::verboseCg.IsEnabledByUser()) {
220 opts::cg::verboseCg ? SetOption(CGOptions::kVerboseCG) : ClearOption(CGOptions::kVerboseCG);
221 }
222
223 if (opts::cg::maplelinker.IsEnabledByUser()) {
224 opts::cg::maplelinker ? EnableMapleLinker() : DisableMapleLinker();
225 }
226
227 if (opts::cg::fastAlloc.IsEnabledByUser()) {
228 EnableFastAlloc();
229 SetFastAllocMode(opts::cg::fastAlloc);
230 }
231
232 if (opts::cg::useBarriersForVolatile.IsEnabledByUser()) {
233 opts::cg::useBarriersForVolatile ? EnableBarriersForVolatile() : DisableBarriersForVolatile();
234 }
235
236 if (opts::cg::spillRange.IsEnabledByUser()) {
237 SetRange(opts::cg::spillRange, "--pill-range", GetSpillRanges());
238 }
239
240 if (opts::cg::range.IsEnabledByUser()) {
241 SetRange(opts::cg::range, "--range", GetRange());
242 }
243
244 if (opts::cg::timePhases.IsEnabledByUser()) {
245 opts::cg::timePhases ? EnableTimePhases() : DisableTimePhases();
246 }
247
248 if (opts::cg::dumpFunc.IsEnabledByUser()) {
249 SetDumpFunc(opts::cg::dumpFunc);
250 }
251
252 if (opts::cg::duplicateAsmList.IsEnabledByUser()) {
253 SetDuplicateAsmFile(opts::cg::duplicateAsmList);
254 }
255
256 if (opts::cg::duplicateAsmList2.IsEnabledByUser()) {
257 SetFastFuncsAsmFile(opts::cg::duplicateAsmList2);
258 }
259
260 if (opts::cg::insertCall.IsEnabledByUser()) {
261 SetOption(kGenInsertCall);
262 SetInstrumentationFunction(opts::cg::insertCall);
263 SetInsertCall(true);
264 }
265
266 if (opts::cg::stackProtectorStrong.IsEnabledByUser()) {
267 SetOption(kUseStackProtectorStrong);
268 }
269
270 if (opts::cg::stackProtectorAll.IsEnabledByUser()) {
271 SetOption(kUseStackProtectorAll);
272 }
273
274 if (opts::cg::debug.IsEnabledByUser()) {
275 SetOption(kDebugFriendly);
276 SetOption(kWithLoc);
277 ClearOption(kSuppressFileInfo);
278 }
279
280 if (opts::cg::gdwarf.IsEnabledByUser()) {
281 SetOption(kDebugFriendly);
282 SetOption(kWithLoc);
283 SetOption(kWithDwarf);
284 SetParserOption(kWithDbgInfo);
285 ClearOption(kSuppressFileInfo);
286 }
287
288 if (opts::cg::gsrc.IsEnabledByUser()) {
289 SetOption(kDebugFriendly);
290 SetOption(kWithLoc);
291 SetOption(kWithSrc);
292 ClearOption(kWithMpl);
293 }
294
295 if (opts::cg::gmixedsrc.IsEnabledByUser()) {
296 SetOption(kDebugFriendly);
297 SetOption(kWithLoc);
298 SetOption(kWithSrc);
299 SetOption(kWithMpl);
300 }
301
302 if (opts::cg::gmixedasm.IsEnabledByUser()) {
303 SetOption(kDebugFriendly);
304 SetOption(kWithLoc);
305 SetOption(kWithSrc);
306 SetOption(kWithMpl);
307 SetOption(kWithAsm);
308 }
309
310 if (opts::cg::profile.IsEnabledByUser()) {
311 SetOption(kWithProfileCode);
312 SetParserOption(kWithProfileInfo);
313 }
314
315 if (opts::cg::withRaLinearScan.IsEnabledByUser()) {
316 SetOption(kDoLinearScanRegAlloc);
317 ClearOption(kDoColorRegAlloc);
318 }
319
320 if (opts::cg::withRaGraphColor.IsEnabledByUser()) {
321 SetOption(kDoColorRegAlloc);
322 ClearOption(kDoLinearScanRegAlloc);
323 }
324
325 if (opts::cg::printFunc.IsEnabledByUser()) {
326 opts::cg::printFunc ? EnablePrintFunction() : DisablePrintFunction();
327 }
328
329 if (opts::cg::addDebugTrace.IsEnabledByUser()) {
330 SetOption(kAddDebugTrace);
331 }
332
333 if (opts::cg::addFuncProfile.IsEnabledByUser()) {
334 SetOption(kAddFuncProfile);
335 }
336
337 if (opts::cg::suppressFileinfo.IsEnabledByUser()) {
338 SetOption(kSuppressFileInfo);
339 }
340
341 if (opts::cg::patchLongBranch.IsEnabledByUser()) {
342 SetOption(kPatchLongBranch);
343 }
344
345 if (opts::cg::constFold.IsEnabledByUser()) {
346 opts::cg::constFold ? SetOption(kConstFold) : ClearOption(kConstFold);
347 }
348
349 if (opts::cg::dumpCfg.IsEnabledByUser()) {
350 SetOption(kDumpCFG);
351 }
352
353 if (opts::cg::classListFile.IsEnabledByUser()) {
354 SetClassListFile(opts::cg::classListFile);
355 }
356
357 if (opts::cg::genCMacroDef.IsEnabledByUser()) {
358 SetOrClear(GetGenerateFlags(), CGOptions::kCMacroDef, opts::cg::genCMacroDef);
359 }
360
361 if (opts::cg::genGctibFile.IsEnabledByUser()) {
362 SetOrClear(GetGenerateFlags(), CGOptions::kGctib, opts::cg::genGctibFile);
363 }
364
365 if (opts::cg::yieldpoint.IsEnabledByUser()) {
366 SetOrClear(GetGenerateFlags(), CGOptions::kGenYieldPoint, opts::cg::yieldpoint);
367 }
368
369 if (opts::cg::localRc.IsEnabledByUser()) {
370 SetOrClear(GetGenerateFlags(), CGOptions::kGenLocalRc, opts::cg::localRc);
371 }
372
373 if (opts::cg::ehExclusiveList.IsEnabledByUser()) {
374 SetEHExclusiveFile(opts::cg::ehExclusiveList);
375 EnableExclusiveEH();
376 ParseExclusiveFunc(opts::cg::ehExclusiveList);
377 }
378
379 if (opts::cg::cyclePatternList.IsEnabledByUser()) {
380 SetCyclePatternFile(opts::cg::cyclePatternList);
381 EnableEmitCyclePattern();
382 ParseCyclePattern(opts::cg::cyclePatternList);
383 }
384
385 if (opts::cg::cg.IsEnabledByUser()) {
386 SetRunCGFlag(opts::cg::cg);
387 opts::cg::cg ? SetOption(CGOptions::kDoCg) : ClearOption(CGOptions::kDoCg);
388 }
389
390 if (opts::cg::objmap.IsEnabledByUser()) {
391 SetGenerateObjectMap(opts::cg::objmap);
392 }
393
394 if (opts::cg::replaceAsm.IsEnabledByUser()) {
395 opts::cg::replaceAsm ? EnableReplaceASM() : DisableReplaceASM();
396 }
397
398 if (opts::cg::generalRegOnly.IsEnabledByUser()) {
399 opts::cg::generalRegOnly ? EnableGeneralRegOnly() : DisableGeneralRegOnly();
400 }
401
402 if (opts::cg::lazyBinding.IsEnabledByUser()) {
403 opts::cg::lazyBinding ? EnableLazyBinding() : DisableLazyBinding();
404 }
405
406 if (opts::cg::hotFix.IsEnabledByUser()) {
407 opts::cg::hotFix ? EnableHotFix() : DisableHotFix();
408 }
409
410 if (opts::cg::soeCheck.IsEnabledByUser()) {
411 SetOption(CGOptions::kSoeCheckInsert);
412 }
413
414 if (opts::cg::checkArraystore.IsEnabledByUser()) {
415 opts::cg::checkArraystore ? EnableCheckArrayStore() : DisableCheckArrayStore();
416 }
417
418 if (opts::cg::ebo.IsEnabledByUser()) {
419 opts::cg::ebo ? EnableEBO() : DisableEBO();
420 }
421
422 if (opts::cg::cfgo.IsEnabledByUser()) {
423 opts::cg::cfgo ? EnableCFGO() : DisableCFGO();
424 }
425
426 if (opts::cg::ico.IsEnabledByUser()) {
427 opts::cg::ico ? EnableICO() : DisableICO();
428 }
429
430 if (opts::cg::storeloadopt.IsEnabledByUser()) {
431 opts::cg::storeloadopt ? EnableStoreLoadOpt() : DisableStoreLoadOpt();
432 }
433
434 if (opts::cg::globalopt.IsEnabledByUser()) {
435 opts::cg::globalopt ? EnableGlobalOpt() : DisableGlobalOpt();
436 }
437
438 if (opts::cg::hotcoldsplit.IsEnabledByUser()) {
439 opts::cg::hotcoldsplit ? EnableHotColdSplit() : DisableHotColdSplit();
440 }
441
442 if (opts::cg::prelsra.IsEnabledByUser()) {
443 opts::cg::prelsra ? EnablePreLSRAOpt() : DisablePreLSRAOpt();
444 }
445
446 if (opts::cg::prepeep.IsEnabledByUser()) {
447 opts::cg::prepeep ? EnablePrePeephole() : DisablePrePeephole();
448 }
449
450 if (opts::cg::peep.IsEnabledByUser()) {
451 opts::cg::peep ? EnablePeephole() : DisablePeephole();
452 }
453
454 if (opts::cg::retMerge.IsEnabledByUser()) {
455 opts::cg::retMerge ? EnableRetMerge() : DisableRetMerge();
456 }
457
458 if (opts::cg::preschedule.IsEnabledByUser()) {
459 opts::cg::preschedule ? EnablePreSchedule() : DisablePreSchedule();
460 }
461
462 if (opts::cg::schedule.IsEnabledByUser()) {
463 opts::cg::schedule ? EnableSchedule() : DisableSchedule();
464 }
465
466 if (opts::cg::vregRename.IsEnabledByUser()) {
467 opts::cg::vregRename ? EnableVregRename() : DisableVregRename();
468 }
469
470 if (opts::cg::fullcolor.IsEnabledByUser()) {
471 opts::cg::fullcolor ? EnableMultiPassColorRA() : DisableMultiPassColorRA();
472 }
473
474 if (opts::cg::writefieldopt.IsEnabledByUser()) {
475 opts::cg::writefieldopt ? EnableWriteRefFieldOpt() : DisableWriteRefFieldOpt();
476 }
477
478 if (opts::cg::dumpOlog.IsEnabledByUser()) {
479 opts::cg::dumpOlog ? EnableDumpOptimizeCommonLog() : DisableDumpOptimizeCommonLog();
480 }
481
482 if (opts::cg::nativeopt.IsEnabledByUser()) {
483 // Disabling Looks strage: should be checked by author of the code
484 DisableNativeOpt();
485 }
486
487 if (opts::cg::dupBb.IsEnabledByUser()) {
488 opts::cg::dupBb ? DisableNoDupBB() : EnableNoDupBB();
489 }
490
491 if (opts::cg::calleeCfi.IsEnabledByUser()) {
492 opts::cg::calleeCfi ? DisableNoCalleeCFI() : EnableNoCalleeCFI();
493 }
494
495 if (opts::cg::proepilogue.IsEnabledByUser()) {
496 opts::cg::proepilogue ? SetOption(CGOptions::kProEpilogueOpt) : ClearOption(CGOptions::kProEpilogueOpt);
497 }
498
499 if (opts::cg::tailcall.IsEnabledByUser()) {
500 opts::cg::tailcall ? SetOption(CGOptions::kTailCallOpt) : ClearOption(CGOptions::kTailCallOpt);
501 }
502
503 if (opts::cg::calleeregsPlacement.IsEnabledByUser()) {
504 opts::cg::calleeregsPlacement ? EnableRegSavesOpt() : DisableRegSavesOpt();
505 }
506
507 if (opts::cg::ssapreSave.IsEnabledByUser()) {
508 opts::cg::ssapreSave ? EnableSsaPreSave() : DisableSsaPreSave();
509 }
510
511 if (opts::cg::ssupreRestore.IsEnabledByUser()) {
512 opts::cg::ssupreRestore ? EnableSsuPreRestore() : DisableSsuPreRestore();
513 }
514
515 if (opts::cg::lsraBb.IsEnabledByUser()) {
516 SetLSRABBOptSize(opts::cg::lsraBb);
517 }
518
519 if (opts::cg::lsraInsn.IsEnabledByUser()) {
520 SetLSRAInsnOptSize(opts::cg::lsraInsn);
521 }
522
523 if (opts::cg::lsraOverlap.IsEnabledByUser()) {
524 SetOverlapNum(opts::cg::lsraOverlap);
525 }
526
527 if (opts::cg::remat.IsEnabledByUser()) {
528 SetRematLevel(opts::cg::remat);
529 }
530
531 if (opts::cg::dumpPhases.IsEnabledByUser()) {
532 SplitPhases(opts::cg::dumpPhases, GetDumpPhases());
533 }
534
535 if (opts::cg::target.IsEnabledByUser()) {
536 SetTargetMachine(opts::cg::target);
537 }
538
539 if (opts::cg::skipPhases.IsEnabledByUser()) {
540 SplitPhases(opts::cg::skipPhases, GetSkipPhases());
541 }
542
543 if (opts::cg::skipFrom.IsEnabledByUser()) {
544 SetSkipFrom(opts::cg::skipFrom);
545 }
546
547 if (opts::cg::skipAfter.IsEnabledByUser()) {
548 SetSkipAfter(opts::cg::skipAfter);
549 }
550
551 if (opts::cg::debugSchedule.IsEnabledByUser()) {
552 opts::cg::debugSchedule ? EnableDebugSched() : DisableDebugSched();
553 }
554
555 if (opts::cg::bruteforceSchedule.IsEnabledByUser()) {
556 opts::cg::bruteforceSchedule ? EnableDruteForceSched() : DisableDruteForceSched();
557 }
558
559 if (opts::cg::simulateSchedule.IsEnabledByUser()) {
560 opts::cg::simulateSchedule ? EnableSimulateSched() : DisableSimulateSched();
561 }
562
563 if (opts::cg::floatAbi.IsEnabledByUser()) {
564 SetABIType(opts::cg::floatAbi);
565 }
566
567 if (opts::cg::longCalls.IsEnabledByUser()) {
568 opts::cg::longCalls ? EnableLongCalls() : DisableLongCalls();
569 }
570
571 if (opts::cg::functionSections.IsEnabledByUser()) {
572 opts::cg::functionSections ? EnableFunctionSections() : DisableFunctionSections();
573 }
574
575 if (opts::cg::omitFramePointer.IsEnabledByUser()) {
576 opts::cg::omitFramePointer ? DisableFramePointer() : EnableFramePointer();
577 }
578
579 if (opts::cg::fastMath.IsEnabledByUser()) {
580 opts::cg::fastMath ? EnableFastMath() : DisableFastMath();
581 }
582
583 if (opts::cg::alignAnalysis.IsEnabledByUser()) {
584 opts::cg::alignAnalysis ? EnableAlignAnalysis() : DisableAlignAnalysis();
585 }
586
587 if (opts::cg::condbrAlign.IsEnabledByUser()) {
588 opts::cg::condbrAlign ? EnableCondBrAlign() : DisableCondBrAlign();
589 }
590
591 /* big endian can be set with several options: --target, -Be.
592 * Triple takes to account all these options and allows to detect big endian with IsBigEndian() interface */
593 Triple::GetTriple().IsBigEndian() ? EnableBigEndianInCG() : DisableBigEndianInCG();
594 (maple::Triple::GetTriple().GetEnvironment() == Triple::GNUILP32) ? EnableArm64ilp32() : DisableArm64ilp32();
595
596 if (opts::cg::cgSsa.IsEnabledByUser()) {
597 opts::cg::cgSsa ? EnableCGSSA() : DisableCGSSA();
598 }
599
600 if (opts::cg::common.IsEnabledByUser()) {
601 opts::cg::common ? EnableCommon() : DisableCommon();
602 }
603
604 if (opts::cg::alignMinBbSize.IsEnabledByUser()) {
605 SetAlignMinBBSize(opts::cg::alignMinBbSize);
606 }
607
608 if (opts::cg::alignMaxBbSize.IsEnabledByUser()) {
609 SetAlignMaxBBSize(opts::cg::alignMaxBbSize);
610 }
611
612 if (opts::cg::loopAlignPow.IsEnabledByUser()) {
613 SetLoopAlignPow(opts::cg::loopAlignPow);
614 }
615
616 if (opts::cg::jumpAlignPow.IsEnabledByUser()) {
617 SetJumpAlignPow(opts::cg::jumpAlignPow);
618 }
619
620 if (opts::cg::funcAlignPow.IsEnabledByUser()) {
621 SetFuncAlignPow(opts::cg::funcAlignPow);
622 }
623
624 if (opts::cg::optimizedFrameLayout.IsEnabledByUser()) {
625 opts::cg::optimizedFrameLayout ? EnableOptimizedFrameLayout() : DisableOptimizedFrameLayout();
626 }
627
628 /* override some options when loc, dwarf is generated */
629 if (WithLoc()) {
630 DisableSchedule();
631 SetOption(kWithSrc);
632 }
633 if (WithDwarf()) {
634 DisableEBO();
635 DisableCFGO();
636 DisableICO();
637 DisableSchedule();
638 SetOption(kDebugFriendly);
639 SetOption(kWithSrc);
640 SetOption(kWithLoc);
641 ClearOption(kSuppressFileInfo);
642 }
643
644 return true;
645 }
646
ParseExclusiveFunc(const std::string & fileName)647 void CGOptions::ParseExclusiveFunc(const std::string &fileName)
648 {
649 std::ifstream file(fileName);
650 if (!file.is_open()) {
651 ERR(kLncErr, "%s open failed!", fileName.c_str());
652 return;
653 }
654 std::string content;
655 while (file >> content) {
656 ehExclusiveFunctionName.push_back(content);
657 }
658 }
659
ParseCyclePattern(const std::string & fileName)660 void CGOptions::ParseCyclePattern(const std::string &fileName)
661 {
662 std::ifstream file(fileName);
663 if (!file.is_open()) {
664 ERR(kLncErr, "%s open failed!", fileName.c_str());
665 return;
666 }
667 std::string content;
668 std::string classStr("class: ");
669 while (getline(file, content)) {
670 if (content.compare(0, classStr.length(), classStr) == 0) {
671 std::vector<std::string> classPatternContent;
672 std::string patternContent;
673 while (getline(file, patternContent)) {
674 if (patternContent.length() == 0) {
675 break;
676 }
677 classPatternContent.push_back(patternContent);
678 }
679 std::string className = content.substr(classStr.length());
680 CGOptions::cyclePatternMap[className] = std::move(classPatternContent);
681 }
682 }
683 }
684
SetRange(const std::string & str,const std::string & cmd,Range & subRange)685 void CGOptions::SetRange(const std::string &str, const std::string &cmd, Range &subRange)
686 {
687 const std::string &tmpStr = str;
688 size_t comma = tmpStr.find_first_of(",", 0);
689 subRange.enable = true;
690
691 if (comma != std::string::npos) {
692 subRange.begin = std::stoul(tmpStr.substr(0, comma), nullptr);
693 subRange.end = std::stoul(tmpStr.substr(comma + 1, std::string::npos - (comma + 1)), nullptr);
694 }
695 CHECK_FATAL(range.begin < range.end, "invalid values for %s=%lu,%lu", cmd.c_str(), subRange.begin, subRange.end);
696 }
697
698 /* Set default options according to different languages. */
SetDefaultOptions(const maple::MIRModule & mod)699 void CGOptions::SetDefaultOptions(const maple::MIRModule &mod)
700 {
701 insertYieldPoint = GenYieldPoint();
702 }
703
EnableO0()704 void CGOptions::EnableO0()
705 {
706 optimizeLevel = kLevel0;
707 doEBO = false;
708 doCGSSA = false;
709 doLocalSchedule = false;
710 doCFGO = false;
711 doICO = false;
712 doPrePeephole = false;
713 doPeephole = false;
714 doStoreLoadOpt = false;
715 doGlobalOpt = false;
716 doPreLSRAOpt = false;
717 doPreSchedule = false;
718 doSchedule = false;
719 doRegSavesOpt = false;
720 useSsaPreSave = false;
721 useSsuPreRestore = false;
722 doWriteRefFieldOpt = false;
723 doAlignAnalysis = false;
724 doCondBrAlign = false;
725
726 if (maple::Triple::GetTriple().GetEnvironment() == Triple::GNUILP32) {
727 ClearOption(kUseStackProtectorStrong);
728 ClearOption(kUseStackProtectorAll);
729 } else {
730 SetOption(kUseStackProtectorStrong);
731 SetOption(kUseStackProtectorAll);
732 }
733
734 ClearOption(kConstFold);
735 ClearOption(kProEpilogueOpt);
736 ClearOption(kTailCallOpt);
737 }
738
EnableO1()739 void CGOptions::EnableO1()
740 {
741 optimizeLevel = kLevel1;
742 doPreLSRAOpt = true;
743 SetOption(kConstFold);
744 SetOption(kProEpilogueOpt);
745 SetOption(kTailCallOpt);
746 ClearOption(kUseStackProtectorStrong);
747 ClearOption(kUseStackProtectorAll);
748 }
749
EnableO2()750 void CGOptions::EnableO2()
751 {
752 optimizeLevel = kLevel2;
753 doEBO = true;
754 doCGSSA = true;
755 doLocalSchedule = true;
756 doCFGO = true;
757 doICO = true;
758 doPrePeephole = true;
759 doPeephole = true;
760 doStoreLoadOpt = true;
761 doGlobalOpt = true;
762 doPreSchedule = true;
763 doSchedule = true;
764 doAlignAnalysis = true;
765 doCondBrAlign = true;
766 SetOption(kConstFold);
767 ClearOption(kUseStackProtectorStrong);
768 ClearOption(kUseStackProtectorAll);
769 #if TARGARM32
770 doPreLSRAOpt = false;
771 doWriteRefFieldOpt = false;
772 ClearOption(kProEpilogueOpt);
773 ClearOption(kTailCallOpt);
774 #else
775 doPreLSRAOpt = true;
776 doRegSavesOpt = false;
777 useSsaPreSave = false;
778 useSsuPreRestore = true;
779 doWriteRefFieldOpt = true;
780 SetOption(kProEpilogueOpt);
781 SetOption(kTailCallOpt);
782 #endif
783 }
784
EnableLiteCG()785 void CGOptions::EnableLiteCG()
786 {
787 optimizeLevel = kLevelLiteCG;
788 doEBO = false;
789 doCGSSA = false;
790 doLocalSchedule = false;
791 doCGRegCoalesce = false;
792 doCFGO = true;
793 doICO = false;
794 doPrePeephole = false;
795 doPeephole = true;
796 doStoreLoadOpt = false;
797 doGlobalOpt = false;
798 doPreLSRAOpt = false;
799 doPreSchedule = false;
800 doSchedule = false;
801 doRegSavesOpt = false;
802 useSsaPreSave = false;
803 useSsuPreRestore = false;
804 doWriteRefFieldOpt = false;
805 doAlignAnalysis = false;
806 doCondBrAlign = false;
807 supportFuncSymbol = true;
808
809 ClearOption(kUseStackProtectorStrong);
810 ClearOption(kUseStackProtectorAll);
811 ClearOption(kConstFold);
812 ClearOption(kProEpilogueOpt);
813 ClearOption(kTailCallOpt);
814 ClearOption(kDoColorRegAlloc);
815 SetOption(kDoLinearScanRegAlloc);
816 }
817
SetTargetMachine(const std::string & str)818 void CGOptions::SetTargetMachine(const std::string &str)
819 {
820 // this is a temporary plan, all ilp32 logic follow the same path with aarch64
821 if (str == "aarch64" || str == "aarch64_be-linux-gnu_ilp32" || str == "aarch64_be-linux-gnu") {
822 targetArch = "aarch64";
823 } else if (str == "x86_64") {
824 targetArch = "x86_64";
825 } else {
826 CHECK_FATAL_FALSE("unsupported target!!");
827 }
828 }
829
SplitPhases(const std::string & str,std::unordered_set<std::string> & set)830 void CGOptions::SplitPhases(const std::string &str, std::unordered_set<std::string> &set)
831 {
832 const std::string &tmpStr {str};
833 if ((tmpStr.compare("*") == 0) || (tmpStr.compare("cgir") == 0)) {
834 (void)set.insert(tmpStr);
835 return;
836 }
837 StringUtils::Split(tmpStr, set, ',');
838 }
839
DumpPhase(const std::string & phase)840 bool CGOptions::DumpPhase(const std::string &phase)
841 {
842 return (IS_STR_IN_SET(dumpPhases, "*") || IS_STR_IN_SET(dumpPhases, "cgir") || IS_STR_IN_SET(dumpPhases, phase));
843 }
844
845 /* match sub std::string of function name */
FuncFilter(const std::string & name)846 bool CGOptions::FuncFilter(const std::string &name)
847 {
848 return dumpFunc == "*" || dumpFunc == name;
849 }
850 } /* namespace maplebe */
851