diff --git a/src/bin/jbc2mpl b/src/bin/jbc2mpl index ca2d61716b6f8f33e01056c20f5b4da66abeecf2..c11294d2deccbda369d588904194662c5674647c 100755 Binary files a/src/bin/jbc2mpl and b/src/bin/jbc2mpl differ diff --git a/src/bin/maple b/src/bin/maple index ee03e846ee01f7b301bd6431480e2cbe00b3d1f5..fb67f14ffef69d2e3ee39ce90af13151d911247a 100755 Binary files a/src/bin/maple and b/src/bin/maple differ diff --git a/src/maple_be/include/be/common_utils.h b/src/maple_be/include/be/common_utils.h index b2f3583e753a1d04527f1e1b911eff61d8895d22..05c5db1897c356ecb8b68f9d0cc58b860fcce521 100644 --- a/src/maple_be/include/be/common_utils.h +++ b/src/maple_be/include/be/common_utils.h @@ -49,6 +49,7 @@ constexpr uint32 k14ByteSize = 14; constexpr uint32 k15ByteSize = 15; constexpr uint32 k16ByteSize = 16; +constexpr uint32 k4BitShift = 2; /* 4 is 1 << 2; */ constexpr uint32 k8BitShift = 3; /* 8 is 1 << 3; */ constexpr uint32 k16BitShift = 4; /* 16 is 1 << 4 */ diff --git a/src/maple_be/include/cg/aarch64/aarch64_cgfunc.h b/src/maple_be/include/cg/aarch64/aarch64_cgfunc.h index 6cb19f0fd9102720080ea5ff72fbb8200990c187..94c0ad07693e1eda7b5f572c40338cacab8ed8a3 100644 --- a/src/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -156,9 +156,9 @@ class AArch64CGFunc : public CGFunc { Operand *SelectMpy(BinaryNode &node, Operand &o0, Operand &o1) override; void SelectMpy(Operand &resOpnd, Operand &o0, Operand &o1, PrimType primType) override; /* method description contains method information which is metadata for reflection. */ - MemOperand *AdjustMemOperandIfOffsetOutOfRange(MemOperand *memOpnd, regno_t regNO, uint8 isDest, Insn &insn, - AArch64reg regNum, uint8 &isOutOfRange); - void SelectAddAfterInsn(Operand &resOpnd, Operand &o0, Operand &o1, PrimType primType, uint32 isDest, Insn &insn); + MemOperand *AdjustMemOperandIfOffsetOutOfRange(MemOperand *memOpnd, regno_t regNO, bool isDest, Insn &insn, + AArch64reg regNum, bool &isOutOfRange); + void SelectAddAfterInsn(Operand &resOpnd, Operand &o0, Operand &o1, PrimType primType, bool isDest, Insn &insn); bool IsImmediateOffsetOutOfRange(AArch64MemOperand &memOpnd, uint32 bitLen); Operand *SelectRem(BinaryNode &node, Operand &opnd0, Operand &opnd1) override; void SelectDiv(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) override; @@ -422,7 +422,7 @@ class AArch64CGFunc : public CGFunc { bool CheckIfSplitOffsetWithAdd(const AArch64MemOperand &memOpnd, uint32 bitLen); AArch64MemOperand &SplitOffsetWithAddInstruction(const AArch64MemOperand &memOpnd, uint32 bitLen, - AArch64reg baseRegNum = AArch64reg::kRinvalid, uint32 isDest = 0, + AArch64reg baseRegNum = AArch64reg::kRinvalid, bool isDest = false, Insn *insn = nullptr); AArch64MemOperand &CreateReplacementMemOperand(uint32 bitLen, RegOperand &baseReg, int32 offset); diff --git a/src/maple_be/include/cg/aarch64/aarch64_color_ra.h b/src/maple_be/include/cg/aarch64/aarch64_color_ra.h index 74203b1f297abe5ad411ebcaf1755238d1b164ee..c6e1df4869b9379f4d028cd100ee600c729367b1 100644 --- a/src/maple_be/include/cg/aarch64/aarch64_color_ra.h +++ b/src/maple_be/include/cg/aarch64/aarch64_color_ra.h @@ -1177,7 +1177,7 @@ class GraphColorRegAllocator : public AArch64RegAllocator { void LocalRaFinalAssignment(LocalRegAllocator &localRa, BBAssignInfo &bbInfo); void LocalRaDebug(BB &bb, LocalRegAllocator &localRa); void LocalRegisterAllocator(bool allocate); - MemOperand *GetSpillOrReuseMem(LiveRange &lr, uint32 regSize, uint8 &isOutOfRange, Insn &insn, bool isDef); + MemOperand *GetSpillOrReuseMem(LiveRange &lr, uint32 regSize, bool &isOutOfRange, Insn &insn, bool isDef); void SpillOperandForSpillPre(Insn &insn, const Operand &opnd, RegOperand &phyOpnd, uint32 spillIdx, bool needSpill); void SpillOperandForSpillPost(Insn &insn, const Operand &opnd, RegOperand &phyOpnd, uint32 spillIdx, bool needSpill); Insn *SpillOperand(Insn &insn, const Operand &opnd, bool isDef, RegOperand &phyOpnd); @@ -1186,7 +1186,7 @@ class GraphColorRegAllocator : public AArch64RegAllocator { MemOperand *GetCommonReuseMem(const uint64 *conflict, const std::set &usedMemOpnd, uint32 size, RegType regType); MemOperand *GetReuseMem(uint32 vregNO, uint32 size, RegType regType); - MemOperand *GetSpillMem(uint32 vregNO, uint8 isDest, Insn &insn, AArch64reg regNO, uint8 &isOutOfRange); + MemOperand *GetSpillMem(uint32 vregNO, bool isDest, Insn &insn, AArch64reg regNO, bool &isOutOfRange); bool SetAvailableSpillReg(std::set &cannotUseReg, LiveRange &lr, uint64 &usedRegMask); void CollectCannotUseReg(std::set &cannotUseReg, LiveRange &lr, Insn &insn); regno_t PickRegForSpill(uint64 &usedRegMask, RegType regType, uint32 spillIdx, bool &needSpillLr); diff --git a/src/maple_be/include/cg/cg_option.h b/src/maple_be/include/cg/cg_option.h index 3e066d5bcfc0bc95e0c706bd4771dac4e3051511..750b303dc414bc6effb38b2c4762ae3021ae5adf 100644 --- a/src/maple_be/include/cg/cg_option.h +++ b/src/maple_be/include/cg/cg_option.h @@ -19,6 +19,7 @@ #include "mempool_allocator.h" #include "mir_module.h" #include "types_def.h" +#include "driver_option_common.h" namespace maplebe { using namespace maple; @@ -28,7 +29,7 @@ struct Range { uint64 end; }; -class CGOptions { +class CGOptions : public MapleDriverOptionBase { public: enum OptionEnum : uint64 { kUndefined = 0ULL, @@ -108,8 +109,11 @@ class CGOptions { static const GenerateFlag kDefaultGflags = GenerateFlag(kGrootList | kPrimorList); public: - explicit CGOptions(MemPool &memPool) : optionAlloc(&memPool) {} + static CGOptions &GetInstance(); + CGOptions(); virtual ~CGOptions() = default; + bool SolveOptions(const std::vector &opts, bool isDebug); + void DecideMplcgRealLevel(const std::vector &inputOptions, bool isDebug); void DumpOptions(); std::vector &GetSequence() { @@ -593,7 +597,6 @@ class CGOptions { } private: - MapleAllocator optionAlloc; std::vector phaseSequence; bool insertCall = false; diff --git a/src/maple_be/include/cg/cgfunc.h b/src/maple_be/include/cg/cgfunc.h index 5ed67c860fda3885e14d18e27ad09dc45fd92757..b8586311f48ecb5b4c86f08f78b2ff0df6d85129 100644 --- a/src/maple_be/include/cg/cgfunc.h +++ b/src/maple_be/include/cg/cgfunc.h @@ -243,9 +243,7 @@ class CGFunc { virtual Operand *GetTrueOpnd() { return nullptr; } - virtual void ClearUnreachableGotInfos(BB &bb) { - return; - } + virtual void ClearUnreachableGotInfos(BB &bb) {}; LabelIdx CreateLabel(); virtual Operand &CreateFPImmZero(PrimType primType) = 0; diff --git a/src/maple_be/include/cg/datainfo.h b/src/maple_be/include/cg/datainfo.h index b8698e6c67420c8ab6a05a25e66512e67ecc5be8..5a0c8ea7cc62ef04e9af2ed5ccfc94d26c1ae490 100644 --- a/src/maple_be/include/cg/datainfo.h +++ b/src/maple_be/include/cg/datainfo.h @@ -141,10 +141,6 @@ class DataInfo { } } - int32 GetInfoIndex(const uint32 bitNO) const { - return bitNO / kWordSize; - } - MapleSet GetBitsOfInfo() { MapleSet wordRes(allocator.Adapter()); wordRes.clear(); diff --git a/src/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp b/src/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp index d2b71d4aadeaeab70692265e613c6826523c82e2..660055c692597df9011ebb80624fdbac054d8e5d 100644 --- a/src/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -710,7 +710,7 @@ bool AArch64CGFunc::CheckIfSplitOffsetWithAdd(const AArch64MemOperand &memOpnd, } AArch64MemOperand &AArch64CGFunc::SplitOffsetWithAddInstruction(const AArch64MemOperand &memOpnd, uint32 bitLen, - AArch64reg baseRegNum, uint32 isDest, Insn *insn) { + AArch64reg baseRegNum, bool isDest, Insn *insn) { ASSERT((memOpnd.GetAddrMode() == AArch64MemOperand::kAddrModeBOi), "expect kAddrModeBOi memOpnd"); ASSERT(memOpnd.IsIntactIndexed(), "expect intactIndexed memOpnd"); AArch64OfstOperand *ofstOpnd = memOpnd.GetOffsetImmediate(); @@ -5525,7 +5525,7 @@ void AArch64CGFunc::AppendCall(const MIRSymbol &funcSymbol) { } void AArch64CGFunc::SelectAddAfterInsn(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType, - uint32 isDest, Insn &insn) { + bool isDest, Insn &insn) { uint32 dsize = GetPrimTypeBitSize(primType); bool is64Bits = (dsize == k64BitSize); ASSERT(opnd0.GetKind() == Operand::kOpdRegister, "Spill memory operand should based on register"); @@ -5579,7 +5579,7 @@ void AArch64CGFunc::SelectAddAfterInsn(Operand &resOpnd, Operand &opnd0, Operand } MemOperand *AArch64CGFunc::AdjustMemOperandIfOffsetOutOfRange( - MemOperand *memOpnd, regno_t vrNum, uint8 isDest, Insn &insn, AArch64reg regNum, uint8 &isOutOfRange) { + MemOperand *memOpnd, regno_t vrNum, bool isDest, Insn &insn, AArch64reg regNum, bool &isOutOfRange) { if (vrNum >= vRegTable.size()) { CHECK_FATAL(false, "index out of range in AArch64CGFunc::AdjustMemOperandIfOffsetOutOfRange"); } @@ -5587,12 +5587,12 @@ MemOperand *AArch64CGFunc::AdjustMemOperandIfOffsetOutOfRange( auto *a64MemOpnd = static_cast(memOpnd); if (IsImmediateOffsetOutOfRange(*a64MemOpnd, dataSize)) { if (CheckIfSplitOffsetWithAdd(*a64MemOpnd, dataSize)) { - isOutOfRange = 1; + isOutOfRange = true; } memOpnd = &SplitOffsetWithAddInstruction(*a64MemOpnd, dataSize, regNum, isDest, &insn); } else { - isOutOfRange = 0; + isOutOfRange = false; } return memOpnd; } diff --git a/src/maple_be/src/cg/aarch64/aarch64_color_ra.cpp b/src/maple_be/src/cg/aarch64/aarch64_color_ra.cpp index 2ec6c501f09aaa79489b0094f05844d2ba7b456f..dd641e8b88cb7d5f575d65ab767f46520c6b2aa2 100644 --- a/src/maple_be/src/cg/aarch64/aarch64_color_ra.cpp +++ b/src/maple_be/src/cg/aarch64/aarch64_color_ra.cpp @@ -2445,8 +2445,8 @@ MemOperand *GraphColorRegAllocator::GetReuseMem(uint32 vregNO, uint32 size, RegT #endif /* CONSISTENT_MEMOPNDi */ } -MemOperand *GraphColorRegAllocator::GetSpillMem(uint32 vregNO, uint8 isDest, Insn &insn, AArch64reg regNO, - uint8 &isOutOfRange) { +MemOperand *GraphColorRegAllocator::GetSpillMem(uint32 vregNO, bool isDest, Insn &insn, AArch64reg regNO, + bool &isOutOfRange) { auto *a64CGFunc = static_cast(cgFunc); MemOperand *memOpnd = a64CGFunc->GetOrCreatSpillMem(vregNO); return (a64CGFunc->AdjustMemOperandIfOffsetOutOfRange(memOpnd, vregNO, isDest, insn, regNO, isOutOfRange)); @@ -2525,7 +2525,7 @@ void GraphColorRegAllocator::SpillOperandForSpillPost(Insn &insn, const Operand } } -MemOperand *GraphColorRegAllocator::GetSpillOrReuseMem(LiveRange &lr, uint32 regSize, uint8 &isOutOfRange, Insn &insn, +MemOperand *GraphColorRegAllocator::GetSpillOrReuseMem(LiveRange &lr, uint32 regSize, bool &isOutOfRange, Insn &insn, bool isDef) { (void)regSize; MemOperand *memOpnd = nullptr; @@ -2577,7 +2577,7 @@ Insn *GraphColorRegAllocator::SpillOperand(Insn &insn, const Operand &opnd, bool } uint32 regSize = regOpnd.GetSize(); - uint8 isOutOfRange = 0; + bool isOutOfRange = false; PrimType stype; RegType regType = regOpnd.GetRegisterType(); if (regType == kRegTyInt) { diff --git a/src/maple_be/src/cg/cg_option.cpp b/src/maple_be/src/cg/cg_option.cpp index 821256198b93f90587dbf6a9b4ea0611c98d22de..099306f688aea895012c722be0a4bbcbbd1fd852 100644 --- a/src/maple_be/src/cg/cg_option.cpp +++ b/src/maple_be/src/cg/cg_option.cpp @@ -60,6 +60,792 @@ bool CGOptions::hotFix = false; bool CGOptions::genLongCalls = false; bool CGOptions::gcOnly = false; +enum OptionIndex : uint64 { + kCGQuiet = kCommonOptionEnd + 1, + kPie, + kPic, + kVerbose, + kCGMapleLinker, + kCGHelp, + kCgen, + kCGNativeOpt, + kInsertCall, + kTrace, + kCGClassList, + kGenDef, + kGenGctib, + kCGBarrier, + kGenPrimorList, + kRaColor, + kConstFoldOpt, + kSuppressFinfo, + kEhList, + kObjMap, + kCGDumpcfg, + kCGDumpBefore, + kCGDumpAfter, + kCGTimePhases, + kCGDumpFunc, + kDebuggingInfo, + kStackGuard, + kDebugGenDwarf, + kDebugUseSrc, + kDebugUseMix, + kDebugAsmMix, + kProfilingInfo, + kProfileEnable, + kCGO0, + kCGO1, + kCGO2, + kProfileData, + kProepilogue, + kYieldPoing, + kLocalRc, + kCalleeCFI, + kCyclePatternList, + kDuplicateToDelPlt, + kInsertSoe, + kCheckArrayStore, + kPrintFunction, + kCGDumpPhases, + kCGSkipPhases, + kCGSkipFrom, + kCGSkipAfter, + kCGLazyBinding, + kCGHotFix, + kLongCalls, + kGcOnly, +}; + +const Descriptor kUsage[] = { + { kPie, + kEnable, + nullptr, + "pie", + kBuildTypeAll, + kArgCheckPolicyBool, + " --pie \tGenerate position-independent executable\n", + "mplcg", + {} }, + { kPic, + kEnable, + nullptr, + "fpic", + kBuildTypeAll, + kArgCheckPolicyBool, + " --fpic \tGenerate position-independent shared library\n", + "mplcg", + {} }, + { kVerbose, + kEnable, + nullptr, + "verbose-asm", + kBuildTypeAll, + kArgCheckPolicyBool, + " --verbose-asm \tAdd comments to asm output\n", + "mplcg", + {} }, + { kCGMapleLinker, + kEnable, + nullptr, + "maplelinker", + kBuildTypeAll, + kArgCheckPolicyBool, + " --maplelinker \tGenerate the MapleLinker .s format\n", + "mplcg", + {} }, + { kCGQuiet, + kEnable, + nullptr, + "quiet", + kBuildTypeAll, + kArgCheckPolicyBool, + " --quiet \tBe quiet (don't output debug messages)\n", + "mplcg", + {} }, + { kCGHelp, + 0, + "h-mplcg", + "help-mplcg", + kBuildTypeAll, + kArgCheckPolicyOptional, + " -h-mplcg --help-mplcg \tPrint usage and exit.Available command names:\n" + " \tmplcg\n", + "all", + {} }, + { kCgen, + kEnable, + nullptr, + "cg", + kBuildTypeAll, + kArgCheckPolicyBool, + " --cg \tGenerate the output .s file\n", + "mplcg", + {} }, + { kCGLazyBinding, + kEnable, + nullptr, + "lazy-binding", + kBuildTypeAll, + kArgCheckPolicyBool, + " --lazy-binding \tBind class symbols lazily[default off]\n", + "mplcg", + {} }, + { kCGHotFix, + kEnable, + nullptr, + "hot-fix", + kBuildTypeAll, + kArgCheckPolicyBool, + " --hot-fix \tOpen for App hot fix[default off]\n", + "mplcg", + {} }, + { kCGNativeOpt, + kEnable, + nullptr, + "nativeopt", + kBuildTypeAll, + kArgCheckPolicyBool, + " --nativeopt \tEnable native opt\n", + "mplcg", + {} }, + { kObjMap, + kEnable, + nullptr, + "objmap", + kBuildTypeAll, + kArgCheckPolicyBool, + " --objmap \tCreate object maps (GCTIBs) inside the main output (.s) file\n", + "mplcg", + {} }, + { kYieldPoing, + kEnable, + nullptr, + "yieldpoint", + kBuildTypeAll, + kArgCheckPolicyBool, + " --yieldpoint \tGenerate yieldpoints [default]\n", + "mplcg", + {} }, + { kProepilogue, + kEnable, + nullptr, + "proepilogue", + kBuildTypeAll, + kArgCheckPolicyBool, + " --proepilogue \tDo tail call optimization and eliminate unnecessary prologue and epilogue.\n", + "mplcg", + {} }, + { kLocalRc, + kEnable, + nullptr, + "local-rc", + kBuildTypeAll, + kArgCheckPolicyBool, + " --local-rc \tHandle Local Stack RC [default]\n", + "mplcg", + {} }, + { kInsertCall, + 0, + nullptr, + "insert-call", + kBuildTypeAll, + kArgCheckPolicyRequired, + " --insert-call=name \tInsert a call to the named function\n", + "mplcg", + {} }, + { kTrace, + 0, + nullptr, + "add-debug-trace", + kBuildTypeAll, + kArgCheckPolicyNone, + " --add-debug-trace \tInstrument the output .s file to print call traces at runtime\n", + "mplcg", + {} }, + { kCGClassList, + 0, + nullptr, + "class-list-file", + kBuildTypeAll, + kArgCheckPolicyRequired, + " --class-list-file \tSet the class list file for the following generation options,\n" + " \tif not given, generate for all visible classes\n" + " \t--class-list-file=class_list_file\n", + "mplcg", + {} }, + { kGenDef, + kEnable, + nullptr, + "gen-c-macro-def", + kBuildTypeAll, + kArgCheckPolicyBool, + " --gen-c-macro-def \tGenerate a .def file that contains extra type metadata, including the\n" + " \tclass instance sizes and field offsets (default)\n", + "mplcg", + {} }, + { kGenGctib, + kEnable, + nullptr, + "gen-gctib-file", + kBuildTypeAll, + kArgCheckPolicyBool, + " --gen-gctib-file \tGenerate a separate .s file for GCTIBs. Usually used together with\n" + " \t--no-objmap (not implemented yet)\n", + "mplcg", + {} }, + { kStackGuard, + kEnable, + nullptr, + "stackguard", + kBuildTypeAll, + kArgCheckPolicyBool, + " -stackguard \tadd stack guard\n", + "mplcg", + {} }, + { kDebuggingInfo, + 0, + "g", + nullptr, + kBuildTypeAll, + kArgCheckPolicyNone, + " -g \tGenerate debug information\n", + "mplcg", + {} }, + { kDebugGenDwarf, + 0, + nullptr, + "gdwarf", + kBuildTypeAll, + kArgCheckPolicyNone, + " --gdwarf \tGenerate dwarf infomation\n", + "mplcg", + {} }, + { kDebugUseSrc, + 0, + nullptr, + "gsrc", + kBuildTypeAll, + kArgCheckPolicyNone, + " --gsrc \tUse original source file instead of mpl file for debugging\n", + "mplcg", + {} }, + { kDebugUseMix, + 0, + nullptr, + "gmixedsrc", + kBuildTypeAll, + kArgCheckPolicyNone, + " --gmixedsrc \tUse both original source file and mpl file for debugging\n", + "mplcg", + {} }, + { kDebugAsmMix, + 0, + nullptr, + "gmixedasm", + kBuildTypeAll, + kArgCheckPolicyNone, + " --gmixedasm \tComment out both original source file and mpl file for debugging\n", + "mplcg", + {} }, + { kRaColor, + 0, + nullptr, + "with-ra-graph-color", + kBuildTypeAll, + kArgCheckPolicyNone, + " --with-ra-graph-color \tDo coloring-based register allocation\n", + "mplcg", + {} }, + { kConstFoldOpt, + 0, + nullptr, + "const-fold", + kBuildTypeAll, + kArgCheckPolicyNone, + " --const-fold \tEnable constant folding\n", + "mplcg", + {} }, + { kEhList, + 0, + nullptr, + "eh-exclusive-list", + kBuildTypeAll, + kArgCheckPolicyRequired, + " --eh-exclusive-list \tFor generating gold files in unit testing\n" + " \t--eh-exclusive-list=list_file\n", + "mplcg", + {} }, + { kCGO0, + 0, + nullptr, + "O0", + kBuildTypeAll, + kArgCheckPolicyNone, + " -O0 \tNo optimization.\n", + "mplcg", + {} }, + { kCGO1, + 0, + nullptr, + "O1", + kBuildTypeAll, + kArgCheckPolicyOptional, + " -O1 \tDo some optimization.\n", + "mplcg", + {} }, + { kCGO2, + 0, + nullptr, + "O2", + kBuildTypeAll, + kArgCheckPolicyOptional, + " -O2 \tDo some optimization.\n", + "mplcg", + {} }, + { kSuppressFinfo, + 0, + nullptr, + "suppress-fileinfo", + kBuildTypeAll, + kArgCheckPolicyNone, + " --suppress-fileinfo \tFor generating gold files in unit testing\n", + "mplcg", + {} }, + { kCGDumpcfg, + 0, + nullptr, + "dump-cfg", + kBuildTypeAll, + kArgCheckPolicyNone, + " --dump-cfg\n", + "mplcg", + {} }, + { kCGDumpPhases, + 0, + nullptr, + "dump-phases", + kBuildTypeAll, + kArgCheckPolicyRequired, + " --dump-phases=PHASENAME,... \tEnable debug trace for specified phases in the comma separated list\n", + "mplcg", + {} }, + { kCGSkipPhases, + 0, + nullptr, + "skip-phases", + kBuildTypeAll, + kArgCheckPolicyRequired, + " --skip-phases=PHASENAME,... \tSkip the phases specified in the comma separated list\n", + "mplcg", + {} }, + { kCGSkipFrom, + 0, + nullptr, + "skip-from", + kBuildTypeAll, + kArgCheckPolicyRequired, + " --skip-from=PHASENAME \tSkip the rest phases from PHASENAME(included)\n", + "mplcg", + {} }, + { kCGSkipAfter, + 0, + nullptr, + "skip-after", + kBuildTypeAll, + kArgCheckPolicyRequired, + " --skip-after=PHASENAME \tSkip the rest phases after PHASENAME(excluded)\n", + "mplcg", + {} }, + { kCGDumpFunc, + 0, + nullptr, + "dump-func", + kBuildTypeAll, + kArgCheckPolicyRequired, + " --dump-func=FUNCNAME \tDump/trace only for functions whose names contain FUNCNAME as substring\n" + " \t(can only specify once)\n", + "mplcg", + {} }, + { kCGDumpBefore, + kEnable, + nullptr, + "dump-before", + kBuildTypeAll, + kArgCheckPolicyBool, + " --dump-before \tDo extra IR dump before the specified phase\n" + " --no-dump-before \tDon't extra IR dump before the specified phase\n", + "mplcg", + {} }, + { kCGDumpAfter, + kEnable, + nullptr, + "dump-after", + kBuildTypeAll, + kArgCheckPolicyBool, + " --dump-after \tDo extra IR dump after the specified phase\n" + " --no-dump-after \tDon't extra IR dump after the specified phase\n", + "mplcg", + {} }, + { kCGTimePhases, + kEnable, + nullptr, + "time-phases", + kBuildTypeAll, + kArgCheckPolicyBool, + " --time-phases \tCollect compilation time stats for each phase\n" + " --no-time-phases \tDon't Collect compilation time stats for each phase\n", + "mplcg", + {} }, + { kCGBarrier, + kEnable, + nullptr, + "use-barriers-for-volatile", + kBuildTypeAll, + kArgCheckPolicyBool, + " --use-barriers-for-volatile \tOptimize volatile load/str\n" + " --no-use-barriers-for-volatile\n", + "mplcg", + {} }, + { kCalleeCFI, + kEnable, + nullptr, + "callee-cfi", + kBuildTypeAll, + kArgCheckPolicyBool, + " --callee-cfi \tcallee cfi message will be generated\n" + " --no-callee-cfi \tcallee cfi message will not be generated\n", + "mplcg", + {} }, + { kPrintFunction, + kEnable, + nullptr, + "print-func", + kBuildTypeAll, + kArgCheckPolicyBool, + " --print-func\n" + " --no-print-func\n", + "mplcg", + {} }, + { kCyclePatternList, + 0, + nullptr, + "cycle-pattern-list", + kBuildTypeAll, + kArgCheckPolicyRequired, + " --cycle-pattern-list \tFor generating cycle pattern meta\n" + " \t--cycle-pattern-list=list_file\n", + "mplcg", + {} }, + { kDuplicateToDelPlt, + 0, + nullptr, + "duplicate_asm_list", + kBuildTypeAll, + kArgCheckPolicyRequired, + " --duplicate_asm_list \tDuplicate asm functions to delete plt call\n" + " \t--duplicate_asm_list=list_file\n", + "mplcg", + {} }, + { kInsertSoe, + 0, + nullptr, + "soe-check", + kBuildTypeAll, + kArgCheckPolicyNone, + " --soe-check \tInsert a soe check instruction[default off]\n", + "mplcg", + {} }, + { kCheckArrayStore, + kEnable, + nullptr, + "check-arraystore", + kBuildTypeAll, + kArgCheckPolicyBool, + " --check-arraystore \tcheck arraystore exception[default off]\n", + "mplcg", + {} }, + { kLongCalls, + kEnable, + nullptr, + "long-calls", + kBuildTypeAll, + kArgCheckPolicyBool, + " --long-calls \tgenerate long call\n", + "mplcg", + {} }, + { kGcOnly, + kEnable, + nullptr, + "gconly", + kBuildTypeAll, + kArgCheckPolicyBool, + " --gconly \tEnable GCONLY, generate code without RC\n", + "mplcg", + {} }, +// End + { kUnknown, + 0, + nullptr, + nullptr, + kBuildTypeAll, + kArgCheckPolicyNone, + nullptr, + "mplcg", + {} } +}; + +CGOptions &CGOptions::GetInstance() { + static CGOptions instance; + return instance; +} + +CGOptions::CGOptions() { + CreateUsages(kUsage); +} + +void CGOptions::DecideMplcgRealLevel(const std::vector &inputOptions, bool isDebug) { + int realLevel = -1; + for (const mapleOption::Option &opt : inputOptions) { + switch (opt.Index()) { + case kCGO0: + realLevel = CGOptions::kLevel0; + break; + case kCGO1: + realLevel = CGOptions::kLevel1; + break; + case kCGO2: + realLevel = CGOptions::kLevel2; + break; + default: + break; + } + } + if (isDebug) { + LogInfo::MapleLogger() << "Real Mplcg level:" << std::to_string(realLevel) << "\n"; + } + if (realLevel == CGOptions::kLevel0) { + EnableO0(); + } else if (realLevel == CGOptions::kLevel1) { + EnableO1(); + } else if (realLevel == CGOptions::kLevel2) { + EnableO2(); + } +} + +bool CGOptions::SolveOptions(const std::vector