diff --git a/src/mapleall/bin/dex2mpl b/src/mapleall/bin/dex2mpl index b707beb10e1ffae0f3859ec930fa2c7300ab5868..85f50967dbf5e5deb7fef8a24eb88ff3e570cd1c 100755 Binary files a/src/mapleall/bin/dex2mpl and b/src/mapleall/bin/dex2mpl differ diff --git a/src/mapleall/bin/dex2mpl_android b/src/mapleall/bin/dex2mpl_android index 059efa42d7e34f1d3329fbe55b16760fe3e5b0a8..f8c967e95aa27a28d1b61ba3e273e2662e814c0f 100755 Binary files a/src/mapleall/bin/dex2mpl_android and b/src/mapleall/bin/dex2mpl_android differ diff --git a/src/mapleall/bin/jbc2mpl b/src/mapleall/bin/jbc2mpl index 52d92a6d1d87fddd97edddb0c182b353a353d6b7..043c0fee411604d1df78b17e99db691f65f1dbc9 100755 Binary files a/src/mapleall/bin/jbc2mpl and b/src/mapleall/bin/jbc2mpl differ diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 0302893398476125a0cd91ab3afa3c5c44a34dff..8fa66b34caa2def02d257ee4b99cb6ffd62dedff 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -245,14 +245,14 @@ void AArch64MoveRegArgs::GenerateStrInsn(ArgInfo &argInfo, AArch64reg reg2, uint GenOneInsn(argInfo, *baseOpnd, part2BitSize, reg2, (stOffset + kSizeOfPtr)); } else if (numFpRegs > kOneRegister) { uint32 fpSizeBits = fpSize * kBitsPerByte; - AArch64reg regFp2 = static_cast(static_cast(argInfo.reg) + kOneRegister); + AArch64reg regFp2 = static_cast(argInfo.reg + kOneRegister); GenOneInsn(argInfo, *baseOpnd, fpSizeBits, regFp2, (stOffset + static_cast(fpSize))); if (numFpRegs > kTwoRegister) { - AArch64reg regFp3 = static_cast(static_cast(argInfo.reg) + kTwoRegister); + AArch64reg regFp3 = static_cast(argInfo.reg + kTwoRegister); GenOneInsn(argInfo, *baseOpnd, fpSizeBits, regFp3, (stOffset + static_cast(fpSize * k4BitShift))); } if (numFpRegs > kThreeRegister) { - AArch64reg regFp3 = static_cast(static_cast(argInfo.reg) + kThreeRegister); + AArch64reg regFp3 = static_cast(argInfo.reg + kThreeRegister); GenOneInsn(argInfo, *baseOpnd, fpSizeBits, regFp3, (stOffset + static_cast(fpSize * k8BitShift))); } } diff --git a/src/mapleall/maple_driver/defs/phases.def b/src/mapleall/maple_driver/defs/phases.def index 7f23a7cbca31943278488fd9900703203d4ed0d7..9a81103ebfd261baaf2b9072d07409d1364cedd7 100644 --- a/src/mapleall/maple_driver/defs/phases.def +++ b/src/mapleall/maple_driver/defs/phases.def @@ -46,6 +46,7 @@ ADD_PHASE("rename2preg", MeOption::optLevel == 2) ADD_PHASE("pregrename", MeOption::optLevel == 2) ADD_PHASE("bblayout", MeOption::optLevel == 2 || JAVALANG) ADD_PHASE("emit", MeOption::optLevel == 2 || JAVALANG) +ADD_PHASE("meverify", JAVALANG && MeOption::meVerify) // mephase end ADD_PHASE("clinit", JAVALANG) ADD_PHASE("VtableImpl", JAVALANG) diff --git a/src/mapleall/maple_driver/include/compiler.h b/src/mapleall/maple_driver/include/compiler.h index 58502442d04536952c643f0d85ded540ce19a049..364816f26fb799b44e3cb8ce30420fc9ac3dba3e 100644 --- a/src/mapleall/maple_driver/include/compiler.h +++ b/src/mapleall/maple_driver/include/compiler.h @@ -23,6 +23,7 @@ #include "option.h" #include "mir_module.h" #include "mir_parser.h" +#include "driver_runner.h" #include "bin_mplt.h" namespace maple { @@ -39,7 +40,7 @@ class Compiler { virtual ~Compiler() = default; - virtual ErrorCode Compile(const MplOptions &options, std::unique_ptr &theModule); + virtual ErrorCode Compile(MplOptions &options, std::unique_ptr &theModule); virtual void GetTmpFilesToDelete(const MplOptions&, std::vector&) const {} @@ -104,7 +105,7 @@ class MapleCombCompiler : public Compiler { ~MapleCombCompiler() = default; - ErrorCode Compile(const MplOptions &options, std::unique_ptr &theModule) override; + ErrorCode Compile(MplOptions &options, std::unique_ptr &theModule) override; void PrintCommand(const MplOptions &options) const override; std::string GetInputFileName(const MplOptions &options) const override; @@ -112,8 +113,9 @@ class MapleCombCompiler : public Compiler { std::string realRunningExe; std::unordered_set GetFinalOutputs(const MplOptions &mplOptions) const override; void GetTmpFilesToDelete(const MplOptions &mplOptions, std::vector &tempFiles) const override; - bool MakeMeOptions(const MplOptions &options); - bool MakeMpl2MplOptions(const MplOptions &options); + ErrorCode MakeMeOptions(const MplOptions &options, DriverRunner &runner); + ErrorCode MakeMpl2MplOptions(const MplOptions &options, DriverRunner &runner); + std::string DecideOutExe(const MplOptions &options); }; class MplcgCompiler : public Compiler { @@ -121,12 +123,12 @@ class MplcgCompiler : public Compiler { explicit MplcgCompiler(const std::string &name) : Compiler(name) {} ~MplcgCompiler() = default; - ErrorCode Compile(const MplOptions &options, std::unique_ptr &theModule) override; + ErrorCode Compile(MplOptions &options, std::unique_ptr &theModule) override; void PrintCommand(const MplOptions &options) const override; private: std::string GetInputFileName(const MplOptions &options) const override; DefaultOption GetDefaultOptions(const MplOptions &options) const override; - bool MakeCGOptions(const MplOptions &options); + ErrorCode MakeCGOptions(const MplOptions &options); const std::string &GetBinName() const override; }; } // namespace maple diff --git a/src/mapleall/maple_driver/include/compiler_factory.h b/src/mapleall/maple_driver/include/compiler_factory.h index 341595a08f2695eea96e78e3f814c72a5c600cc0..4a6046d22b837144ee1b570bea020d37b83c5479 100644 --- a/src/mapleall/maple_driver/include/compiler_factory.h +++ b/src/mapleall/maple_driver/include/compiler_factory.h @@ -30,7 +30,7 @@ class CompilerFactory { CompilerFactory &operator=(const CompilerFactory&) = delete; CompilerFactory &operator=(CompilerFactory&&) = delete; ~CompilerFactory(); - ErrorCode Compile(const MplOptions &mplOptions); + ErrorCode Compile(MplOptions &mplOptions); private: bool compileFinished = false; diff --git a/src/mapleall/maple_driver/include/driver_option_common.h b/src/mapleall/maple_driver/include/driver_option_common.h index c4cee4ea61da0c8c498393882714ce5d139294b5..b2cd14dae7a3d3aa2f0bc1884db37950eba04fe1 100644 --- a/src/mapleall/maple_driver/include/driver_option_common.h +++ b/src/mapleall/maple_driver/include/driver_option_common.h @@ -26,8 +26,6 @@ enum DriverOptionIndex { kOptimization0, kOptimization1, kOptimization2, - kCLangOptimization0, - kCLangOptimization2, kWithIpa, kJbc2mplOpt, kDex2mplOpt, diff --git a/src/mapleall/maple_driver/include/driver_runner.h b/src/mapleall/maple_driver/include/driver_runner.h index 39204e134722b0ac33f62475733e5a92ed0aad42..854de244256f744ee22dbb9918d2964ef549631c 100644 --- a/src/mapleall/maple_driver/include/driver_runner.h +++ b/src/mapleall/maple_driver/include/driver_runner.h @@ -32,15 +32,13 @@ extern const std::string mplME; class DriverRunner final { public: - DriverRunner(MIRModule *theModule, const std::vector &exeNames, InputFileType inpFileType, Options *mpl2mplOptions, - std::string mpl2mplInput, MeOption *meOptions, const std::string &meInput, std::string actualInput, + DriverRunner(MIRModule *theModule, const std::vector &exeNames, InputFileType inpFileType, + std::string mpl2mplInput, const std::string &meInput, std::string actualInput, MemPool *optMp, bool fileParsed = false, bool timePhases = false, bool genVtableImpl = false, bool genMeMpl = false) : theModule(theModule), exeNames(exeNames), - mpl2mplOptions(mpl2mplOptions), mpl2mplInput(mpl2mplInput), - meOptions(meOptions), meInput(meInput), actualInput(actualInput), optMp(optMp), @@ -48,12 +46,19 @@ class DriverRunner final { timePhases(timePhases), genVtableImpl(genVtableImpl), genMeMpl(genMeMpl), - inputFileType(inpFileType) {} + inputFileType(inpFileType) { + auto lastDot = actualInput.find_last_of("."); + baseName = (lastDot == std::string::npos) ? actualInput : actualInput.substr(0, lastDot); + } - DriverRunner(MIRModule *theModule, const std::vector &exeNames, InputFileType inpFileType, std::string actualInput, MemPool *optMp, - bool fileParsed = false, bool timePhases = false, bool genVtableImpl = false, bool genMeMpl = false) - : DriverRunner(theModule, exeNames, inpFileType, nullptr, "", nullptr, "", actualInput, optMp, fileParsed, timePhases, - genVtableImpl, genMeMpl) {} + DriverRunner(MIRModule *theModule, const std::vector &exeNames, InputFileType inpFileType, + std::string actualInput, MemPool *optMp, bool fileParsed = false, bool timePhases = false, + bool genVtableImpl = false, bool genMeMpl = false) + : DriverRunner(theModule, exeNames, inpFileType, "", "", actualInput, optMp, fileParsed, timePhases, + genVtableImpl, genMeMpl) { + auto lastDot = actualInput.find_last_of("."); + baseName = (lastDot == std::string::npos) ? actualInput : actualInput.substr(0, lastDot); + } ~DriverRunner() = default; @@ -63,10 +68,23 @@ class DriverRunner final { this->cgOptions = cgOptions; this->cgInput = cgInput; } + ErrorCode ParseInput() const; + + void SetPrintOutExe (const std::string outExe) { + printOutExe = outExe; + } + + void SetMpl2mplOptions(Options *options) { + mpl2mplOptions = options; + } + + void SetMeOptions(MeOption *options) { + meOptions = options; + } + private: bool IsFramework() const; - ErrorCode ParseInput(const std::string &outputFile, const std::string &oriBasename) const; - std::string GetPostfix() const; + std::string GetPostfix(); void InitPhases(InterleavedManager &mgr, const std::vector &phases) const; void AddPhases(InterleavedManager &mgr, const std::vector &phases, const PhaseManager &phaseManager) const; @@ -83,7 +101,7 @@ class DriverRunner final { void ProcessExtraTime(const std::vector &extraPhasesTime, const std::vector &extraPhasesName, CgFuncPhaseManager &cgfpm) const; MIRModule *theModule; - std::vector exeNames; + std::vector exeNames = {}; Options *mpl2mplOptions = nullptr; std::string mpl2mplInput; MeOption *meOptions = nullptr; @@ -94,8 +112,10 @@ class DriverRunner final { bool timePhases = false; bool genVtableImpl = false; bool genMeMpl = false; + std::string printOutExe = ""; + std::string baseName; + std::string outputFile; InputFileType inputFileType; - std::string printOutExe; }; } // namespace maple diff --git a/src/mapleall/maple_driver/include/mpl_options.h b/src/mapleall/maple_driver/include/mpl_options.h index c8973eafb73910284b5f668c17e8c293fc419a39..1e9648cdc74ae2353bfd554e04db304141bb5062 100644 --- a/src/mapleall/maple_driver/include/mpl_options.h +++ b/src/mapleall/maple_driver/include/mpl_options.h @@ -26,6 +26,7 @@ #include "file_utils.h" #include "option_parser.h" #include "mpl_logging.h" +#include "mir_module.h" namespace maple { enum InputFileType { @@ -157,6 +158,10 @@ class MplOptions { return runningExes; } + const std::vector &GetSelectedExes() const { + return selectedExes; + } + const std::string &GetPrintCommandStr() const { return printCommandStr; } @@ -177,6 +182,12 @@ class MplOptions { return genVtableImpl; } + ErrorCode AppendCombOptions(MIRSrcLang srcLang); + ErrorCode AppendMplcgOptions(); + std::string GetInputFileNameForPrint() const; + void PrintCommand(); + void connectOptStr(std::string &optionStr, const std::string &exeName, bool &firstComb, std::string &runStr); + void PrintDetailCommand(bool isBeforeParse); private: bool Init(const std::string &inputFile); ErrorCode HandleGeneralOptions(); @@ -187,8 +198,6 @@ class MplOptions { ErrorCode AddOption(const mapleOption::Option &option); ErrorCode UpdatePhaseOption(const std::string &args, const std::string &exeName); ErrorCode UpdateExtraOptionOpt(const std::string &args); - ErrorCode AppendDefaultCombOptions(); - ErrorCode AppendDefaultCgOptions(); ErrorCode AppendDefaultOptions(const std::string &exeName, MplOption mplOptions[], unsigned int length); void UpdateRunningExe(const std::string &args); std::unique_ptr optionParser = nullptr; @@ -200,6 +209,9 @@ class MplOptions { std::string outputName = "maple"; std::string exeFolder = ""; std::string mpltFile = ""; + std::string meOptArgs = ""; + std::string mpl2mplOptArgs = ""; + std::string mplcgOptArgs = ""; InputFileType inputFileType = InputFileType::kFileTypeNone; OptimizationLevel optimizationLevel = OptimizationLevel::kO0; RunMode runMode = RunMode::kUnkownRun; @@ -209,11 +221,14 @@ class MplOptions { std::vector splitsInputFiles = {}; std::map> extras = {}; std::vector runningExes = {}; - std::string printCommandStr = ""; + std::vector selectedExes = {}; + std::string printCommandStr; + std::ostringstream printExtraOptStr; bool debugFlag = false; bool timePhases = false; bool genMeMpl = false; bool genVtableImpl = false; + bool hasPrinted = false; unsigned int helpLevel = mapleOption::kBuildTypeDefault; }; } // namespace maple diff --git a/src/mapleall/maple_driver/src/compiler.cpp b/src/mapleall/maple_driver/src/compiler.cpp index ebe2fdb3e129b5ec879343bbd23ad1c38504b9b7..5f4ea1c2d0d679de0efd79266d6e96074bbbc31a 100644 --- a/src/mapleall/maple_driver/src/compiler.cpp +++ b/src/mapleall/maple_driver/src/compiler.cpp @@ -42,7 +42,7 @@ std::string Compiler::GetBinPath(const MplOptions &mplOptions) const { return binPath; } -ErrorCode Compiler::Compile(const MplOptions &options, std::unique_ptr &) { +ErrorCode Compiler::Compile(MplOptions &options, std::unique_ptr &) { MPLTimer timer = MPLTimer(); LogInfo::MapleLogger() << "Starting " << GetName() << '\n'; timer.Start(); diff --git a/src/mapleall/maple_driver/src/compiler_factory.cpp b/src/mapleall/maple_driver/src/compiler_factory.cpp index 72256e1e12d855c76994c4ce532eae02aecfcb14..737be222706f136c7a6d089d5f66242f50565bd4 100644 --- a/src/mapleall/maple_driver/src/compiler_factory.cpp +++ b/src/mapleall/maple_driver/src/compiler_factory.cpp @@ -35,6 +35,7 @@ CompilerFactory::CompilerFactory() { ADD_COMPILER("jbc2mpl", Jbc2MplCompiler) ADD_COMPILER("me", MapleCombCompiler) ADD_COMPILER("mpl2mpl", MapleCombCompiler) + ADD_COMPILER("maplecomb", MapleCombCompiler) ADD_COMPILER("mplcg", MplcgCompiler) compilerSelector = new CompilerSelectorImpl(); } @@ -78,7 +79,7 @@ ErrorCode CompilerFactory::DeleteTmpFiles(const MplOptions &mplOptions, const st return ret == 0 ? kErrorNoError : kErrorFileNotFound; } -ErrorCode CompilerFactory::Compile(const MplOptions &mplOptions) { +ErrorCode CompilerFactory::Compile(MplOptions &mplOptions) { if (compileFinished) { LogInfo::MapleLogger() << "Failed! Compilation has been completed in previous time and multi-instance compilation is not supported\n"; @@ -104,6 +105,9 @@ ErrorCode CompilerFactory::Compile(const MplOptions &mplOptions) { return ret; } } + if (mplOptions.HasSetDebugFlag()) { + mplOptions.PrintDetailCommand(false); + } // Compiler finished compileFinished = true; diff --git a/src/mapleall/maple_driver/src/compiler_selector.cpp b/src/mapleall/maple_driver/src/compiler_selector.cpp index 39d9453efb87d2b19ee145f2856f2cf38c501d7f..2b2b31c3b4b821bcabe46a9a6a142a0803a85990 100644 --- a/src/mapleall/maple_driver/src/compiler_selector.cpp +++ b/src/mapleall/maple_driver/src/compiler_selector.cpp @@ -43,8 +43,8 @@ ErrorCode CompilerSelectorImpl::InsertCompilerIfNeeded(std::vector &s ErrorCode CompilerSelectorImpl::Select(const SupportedCompilers &supportedCompilers, const MplOptions &mplOptions, std::vector &selected) const { bool combPhases = false; - if (!mplOptions.GetRunningExes().empty()) { - for (const std::string &runningExe : mplOptions.GetRunningExes()) { + if (!mplOptions.GetSelectedExes().empty()) { + for (const std::string &runningExe : mplOptions.GetSelectedExes()) { if (runningExe == kBinNameMe) { combPhases = true; } else if (runningExe == kBinNameMpl2mpl && combPhases) { diff --git a/src/mapleall/maple_driver/src/driver_option_common.cpp b/src/mapleall/maple_driver/src/driver_option_common.cpp index 86a1f56cbb0f3bc8ae9617f658d4ff0faf6faa28..87c89867c90cae16628386fef0646e1283bf0b35 100644 --- a/src/mapleall/maple_driver/src/driver_option_common.cpp +++ b/src/mapleall/maple_driver/src/driver_option_common.cpp @@ -91,24 +91,6 @@ const mapleOption::Descriptor usages[] = { " -O2 \tDo more optimization. (Default)\n", "all", {} }, - { kCLangOptimization0, - 0, - "c-O0", - "", - kBuildTypeProduct, - kArgCheckPolicyNone, - " -c-O0 \tNo optimization.\n", - "all", - {} }, - { kCLangOptimization2, - 0, - "c-O2", - "", - kBuildTypeProduct, - kArgCheckPolicyNone, - " -c-O2 \tDo more optimization. (Default)\n", - "all", - {} }, { kGCOnly, kEnable, "", diff --git a/src/mapleall/maple_driver/src/driver_runner.cpp b/src/mapleall/maple_driver/src/driver_runner.cpp index 90a5a7573193489cd4f6ced3f98956edcc7806ed..6d377bef875f866d4d47a2e1f452a780224cab00 100644 --- a/src/mapleall/maple_driver/src/driver_runner.cpp +++ b/src/mapleall/maple_driver/src/driver_runner.cpp @@ -83,19 +83,9 @@ ErrorCode DriverRunner::Run() { LogInfo::MapleLogger() << "Fatal error: no exe specified" << '\n'; return kErrorExit; } - - printOutExe = exeNames[exeNames.size() - 1]; - - // Prepare output file - auto lastDot = actualInput.find_last_of("."); - std::string baseName = (lastDot == std::string::npos) ? actualInput : actualInput.substr(0, lastDot); std::string originBaseName = baseName; - std::string outputFile = baseName.append(GetPostfix()); - - ErrorCode ret = ParseInput(outputFile, originBaseName); - if (ret != kErrorNoError) { - return kErrorExit; - } + outputFile = baseName; + outputFile.append(GetPostfix()); if (mpl2mplOptions != nullptr || meOptions != nullptr) { std::string vtableImplFile = originBaseName; vtableImplFile.append(".VtableImpl.mpl"); @@ -110,7 +100,7 @@ bool DriverRunner::IsFramework() const { return false; } -std::string DriverRunner::GetPostfix() const { +std::string DriverRunner::GetPostfix() { if (printOutExe == kMplMe) { return ".me.mpl"; } @@ -118,22 +108,26 @@ std::string DriverRunner::GetPostfix() const { return ".VtableImpl.mpl"; } if (printOutExe == kMplCg) { - return ".VtableImpl.s"; + if (theModule->GetSrcLang() == kSrcLangC) { + return ".s"; + } else { + return ".VtableImpl.s"; + } } return ""; } -ErrorCode DriverRunner::ParseInput(const std::string &outputFile, const std::string &originBaseName) const { +ErrorCode DriverRunner::ParseInput() const { CHECK_MODULE(kErrorExit); + std::string originBaseName = baseName; LogInfo::MapleLogger() << "Starting parse input" << '\n'; MPLTimer timer; timer.Start(); - + MIRParser parser(*theModule); ErrorCode ret = kErrorNoError; if (!fileParsed) { if (inputFileType != kFileTypeBpl) { - MIRParser parser(*theModule); MPLTimer parseMirTimer; parseMirTimer.Start(); bool parsed = parser.ParseMIR(0, 0, false, true); @@ -142,7 +136,7 @@ ErrorCode DriverRunner::ParseInput(const std::string &outputFile, const std::str std::pair("parseMpl", parseMirTimer.ElapsedMicroseconds())); if (!parsed) { ret = kErrorExit; - parser.EmitError(outputFile); + parser.EmitError(actualInput); } } else { BinaryMplImport binMplt(*theModule); @@ -160,6 +154,40 @@ ErrorCode DriverRunner::ParseInput(const std::string &outputFile, const std::str } } } + // read in optimized mpl routines + if (MeOption::optLevel == kLevelO2 && !Options::lazyBinding && + Options::skipPhase != "inline" && Options::buildApp == 0 && + Options::useInline && Options::useCrossModuleInline && JAVALANG) { + const MapleVector &inputMplt = theModule->GetImportedMplt(); + auto it = inputMplt.cbegin(); + for (++it; it != inputMplt.cend(); ++it) { + const std::string &curStr = *it; + auto lastDotInner = curStr.find_last_of("."); + std::string tmp = (lastDotInner == std::string::npos) ? curStr : curStr.substr(0, lastDotInner); + if (tmp.find("framework") != std::string::npos && originBaseName.find("framework") != std::string::npos) { + continue; + } + // Skip the import file + if (tmp.find(FileUtils::GetFileName(originBaseName, true)) != std::string::npos) { + continue; + } + size_t index = curStr.rfind("."); + CHECK_FATAL(index != std::string::npos, "can not find ."); + + std::string inputInline = curStr.substr(0, index + 1) + "mplt_inline"; + std::ifstream optFile(inputInline); + if (!optFile.is_open()) { + continue; + } + + LogInfo::MapleLogger() << "Starting parse " << inputInline << '\n'; + bool parsed = parser.ParseInlineFuncBody(optFile); + if (!parsed) { + parser.EmitError(outputFile); + } + optFile.close(); + } + } timer.Stop(); LogInfo::MapleLogger() << "Parse consumed " << timer.Elapsed() << "s" << '\n'; return ret; @@ -169,7 +197,7 @@ void DriverRunner::ProcessMpl2mplAndMePhases(const std::string &outputFile, cons CHECK_MODULE(); theMIRModule = theModule; if (mpl2mplOptions != nullptr || meOptions != nullptr) { - LogInfo::MapleLogger() << "Processing mpl2mpl&mplme" << '\n'; + LogInfo::MapleLogger() << "Processing maplecomb" << '\n'; InterleavedManager mgr(optMp, theModule, meInput, timePhases); std::vector phases; @@ -189,7 +217,7 @@ void DriverRunner::ProcessMpl2mplAndMePhases(const std::string &outputFile, cons emitVtableMplTimer.Stop(); mgr.SetEmitVtableImplTime(emitVtableMplTimer.ElapsedMicroseconds()); timer.Stop(); - LogInfo::MapleLogger() << " Mpl2mpl&mplme consumed " << timer.Elapsed() << "s" << '\n'; + LogInfo::MapleLogger() << " maplecomb consumed " << timer.Elapsed() << "s" << '\n'; } } diff --git a/src/mapleall/maple_driver/src/maple_comb_compiler.cpp b/src/mapleall/maple_driver/src/maple_comb_compiler.cpp index eeee8c07a864b990b0fed7f193c4a0622a36ed62..1bd79f2920ecc235793e4ed736a1ae51da1f1082 100644 --- a/src/mapleall/maple_driver/src/maple_comb_compiler.cpp +++ b/src/mapleall/maple_driver/src/maple_comb_compiler.cpp @@ -97,37 +97,67 @@ void MapleCombCompiler::PrintCommand(const MplOptions &options) const { << GetInputFileName(options) << options.GetPrintCommandStr() << '\n'; } -bool MapleCombCompiler::MakeMeOptions(const MplOptions &options) { +ErrorCode MapleCombCompiler::MakeMeOptions(const MplOptions &options, DriverRunner &runner) { + auto it = std::find(options.GetRunningExes().begin(), options.GetRunningExes().end(), kBinNameMe); + if (it == options.GetRunningExes().end()) { + return kErrorNoError; + } MeOption &meOption = MeOption::GetInstance(); - auto it = options.GetExeOptions().find(kBinNameMe); - if (it == options.GetExeOptions().end()) { + auto itOpt = options.GetExeOptions().find(kBinNameMe); + if (itOpt == options.GetExeOptions().end()) { LogInfo::MapleLogger() << "no me input options\n"; - return false; + return kErrorCompileFail; } - bool result = meOption.SolveOptions(it->second, options.HasSetDebugFlag()); + bool result = meOption.SolveOptions(itOpt->second, options.HasSetDebugFlag()); if (result == false) { LogInfo::MapleLogger() << "Meet error me options\n"; - return false; + return kErrorCompileFail; } - return true; + // Set me options for driver runner + runner.SetMeOptions(&MeOption::GetInstance()); + return kErrorNoError; } -bool MapleCombCompiler::MakeMpl2MplOptions(const MplOptions &options) { +ErrorCode MapleCombCompiler::MakeMpl2MplOptions(const MplOptions &options, DriverRunner &runner) { + auto it = std::find(options.GetRunningExes().begin(), options.GetRunningExes().end(), kBinNameMpl2mpl); + if (it == options.GetRunningExes().end()) { + return kErrorNoError; + } auto &mpl2mplOption = Options::GetInstance(); - auto it = options.GetExeOptions().find(kBinNameMpl2mpl); - if (it == options.GetExeOptions().end()) { + auto itOption = options.GetExeOptions().find(kBinNameMpl2mpl); + if (itOption == options.GetExeOptions().end()) { LogInfo::MapleLogger() << "no mpl2mpl input options\n"; - return false; + return kErrorCompileFail; } - bool result = mpl2mplOption.SolveOptions(it->second, options.HasSetDebugFlag()); + bool result = mpl2mplOption.SolveOptions(itOption->second, options.HasSetDebugFlag()); if (result == false) { LogInfo::MapleLogger() << "Meet error mpl2mpl options\n"; - return false; + return kErrorCompileFail; + } + // Set mpl2mpl options for driver runner + runner.SetMpl2mplOptions(&Options::GetInstance()); + return kErrorNoError; +} + +std::string MapleCombCompiler::DecideOutExe(const MplOptions &options) { + std::string printOutExe = ""; + auto &selectExes = options.GetSelectedExes(); + if (selectExes[selectExes.size() - 1] == kBinNameMapleComb) { + auto it = std::find(options.GetRunningExes().begin(), options.GetRunningExes().end(), kBinNameMpl2mpl); + if (it != options.GetRunningExes().end()) { + printOutExe = kBinNameMpl2mpl; + return printOutExe; + } + it = std::find(options.GetRunningExes().begin(), options.GetRunningExes().end(), kBinNameMe); + if (it != options.GetRunningExes().end()) { + printOutExe = kBinNameMe; + return printOutExe; + } } - return true; + return selectExes[selectExes.size() - 1]; } -ErrorCode MapleCombCompiler::Compile(const MplOptions &options, std::unique_ptr &theModule) { +ErrorCode MapleCombCompiler::Compile(MplOptions &options, std::unique_ptr &theModule) { MemPool *optMp = memPoolCtrler.NewMemPool("maplecomb mempool"); std::string fileName = GetInputFileName(options); bool fileParsed = true; @@ -135,28 +165,39 @@ ErrorCode MapleCombCompiler::Compile(const MplOptions &options, std::unique_ptr< theModule = std::make_unique(fileName); fileParsed = false; } - MeOption &meOptions = MeOption::GetInstance(); - Options &mpl2mplOptions = Options::GetInstance(); - auto it = std::find(options.GetRunningExes().begin(), options.GetRunningExes().end(), kBinNameMe); - if (it != options.GetRunningExes().end()) { - bool result = MakeMeOptions(options); - if (!result) { - return kErrorCompileFail; - } - } - auto iterMpl2Mpl = std::find(options.GetRunningExes().begin(), options.GetRunningExes().end(), kBinNameMpl2mpl); - if (iterMpl2Mpl != options.GetRunningExes().end()) { - bool result = MakeMpl2MplOptions(options); - if (!result) { - return kErrorCompileFail; - } - } + options.PrintCommand(); + LogInfo::MapleLogger() << "Starting maplecomb\n"; - LogInfo::MapleLogger() << "Starting mpl2mpl&mplme\n"; - PrintCommand(options); - DriverRunner runner(theModule.get(), options.GetRunningExes(), options.GetInputFileType(), &mpl2mplOptions, fileName, &meOptions, + DriverRunner runner(theModule.get(), options.GetSelectedExes(), options.GetInputFileType(), fileName, fileName, fileName, optMp, fileParsed, options.HasSetTimePhases(), options.HasSetGenVtableImpl(), options.HasSetGenMeMpl()); + // Parse the input file + ErrorCode ret = runner.ParseInput(); + if (ret != kErrorNoError) { + memPoolCtrler.DeleteMemPool(optMp); + return ret; + } + // Add running phases and default options according to the srcLang (only for auto mode) + ret = options.AppendCombOptions(theModule->GetSrcLang()); + if (ret != kErrorNoError) { + memPoolCtrler.DeleteMemPool(optMp); + return ret; + } + + ret = MakeMeOptions(options, runner); + if (ret != kErrorNoError) { + memPoolCtrler.DeleteMemPool(optMp); + return ret; + } + ret = MakeMpl2MplOptions(options, runner); + if (ret != kErrorNoError) { + memPoolCtrler.DeleteMemPool(optMp); + return ret; + } + runner.SetPrintOutExe(DecideOutExe(options)); + if (options.HasSetDebugFlag()) { + PrintCommand(options); + } ErrorCode nErr = runner.Run(); memPoolCtrler.DeleteMemPool(optMp); diff --git a/src/mapleall/maple_driver/src/mpl_options.cpp b/src/mapleall/maple_driver/src/mpl_options.cpp index 501241837922d92cfb995dcd918a7fae09f48f69..30ef4d5b58bc8ea069d8c62ab59963f41f18b602 100644 --- a/src/mapleall/maple_driver/src/mpl_options.cpp +++ b/src/mapleall/maple_driver/src/mpl_options.cpp @@ -111,22 +111,16 @@ ErrorCode MplOptions::HandleGeneralOptions() { return kErrorExitHelp; } case kMeOpt: - ret = UpdatePhaseOption(opt.Args(), kBinNameMe); - if (ret != kErrorNoError) { - return ret; - } + meOptArgs = opt.Args(); + printExtraOptStr << " --me-opt=" << "\"" << meOptArgs << "\""; break; case kMpl2MplOpt: - ret = UpdatePhaseOption(opt.Args(), kBinNameMpl2mpl); - if (ret != kErrorNoError) { - return ret; - } + mpl2mplOptArgs = opt.Args(); + printExtraOptStr << " --mpl2mpl-opt=" << "\"" << mpl2mplOptArgs << "\""; break; case kMplcgOpt: - ret = UpdatePhaseOption(opt.Args(), kBinNameMplcg); - if (ret != kErrorNoError) { - return ret; - } + mplcgOptArgs = opt.Args(); + printExtraOptStr << " --mplcg-opt=" << "\"" << mplcgOptArgs << "\""; break; case kTimePhases: timePhases = true; @@ -189,22 +183,6 @@ ErrorCode MplOptions::DecideRunType() { optimizationLevel = kO2; } break; - case kCLangOptimization0: - if (runMode == RunMode::kCustomRun) { // O0 and run should not appear at the same time - runModeConflict = true; - } else { - runMode = RunMode::kAutoRun; - optimizationLevel = kCLangO0; - } - break; - case kCLangOptimization2: - if (runMode == RunMode::kCustomRun) { // O0 and run should not appear at the same time - runModeConflict = true; - } else { - runMode = RunMode::kAutoRun; - optimizationLevel = kCLangO2; - } - break; case kRun: if (runMode == RunMode::kAutoRun) { // O0 and run should not appear at the same time runModeConflict = true; @@ -257,16 +235,10 @@ ErrorCode MplOptions::DecideRunningPhases() { break; } if (isNeedMapleComb) { - ret = AppendDefaultCombOptions(); - if (ret != kErrorNoError) { - return ret; - } + selectedExes.push_back(kBinNameMapleComb); } if (isNeedMplcg) { - ret = AppendDefaultCgOptions(); - if (ret != kErrorNoError) { - return ret; - } + selectedExes.push_back(kBinNameMplcg); } return ret; } @@ -356,51 +328,61 @@ bool MplOptions::Init(const std::string &inputFile) { return true; } -ErrorCode MplOptions::AppendDefaultCombOptions() { +ErrorCode MplOptions::AppendCombOptions(MIRSrcLang srcLang) { ErrorCode ret = kErrorNoError; - if (optimizationLevel == kO0 || optimizationLevel == kCLangO0) { + if (runMode == RunMode::kCustomRun) { + return ret; + } + if (optimizationLevel == kO0) { ret = AppendDefaultOptions(kBinNameMe, kMeDefaultOptionsO0, sizeof(kMeDefaultOptionsO0) / sizeof(MplOption)); if (ret != kErrorNoError) { return ret; } - if (optimizationLevel == kO0) { + if (srcLang != kSrcLangC) { ret = AppendDefaultOptions(kBinNameMpl2mpl, kMpl2MplDefaultOptionsO0, sizeof(kMpl2MplDefaultOptionsO0) / sizeof(MplOption)); + UpdatePhaseOption(mpl2mplOptArgs, kBinNameMpl2mpl); } if (ret != kErrorNoError) { return ret; } - } else if (optimizationLevel == kO2 || optimizationLevel == kCLangO2) { + } else if (optimizationLevel == kO2) { ret = AppendDefaultOptions(kBinNameMe, kMeDefaultOptionsO2, sizeof(kMeDefaultOptionsO2) / sizeof(MplOption)); if (ret != kErrorNoError) { return ret; } - if (optimizationLevel == kO2) { + if (srcLang != kSrcLangC) { ret = AppendDefaultOptions(kBinNameMpl2mpl, kMpl2MplDefaultOptionsO2, sizeof(kMpl2MplDefaultOptionsO2) / sizeof(MplOption)); + UpdatePhaseOption(mpl2mplOptArgs, kBinNameMpl2mpl); } if (ret != kErrorNoError) { return ret; } } + UpdatePhaseOption(meOptArgs, kBinNameMe); return ret; } -ErrorCode MplOptions::AppendDefaultCgOptions() { +ErrorCode MplOptions::AppendMplcgOptions() { ErrorCode ret = kErrorNoError; - if (optimizationLevel == kO0 || optimizationLevel == kCLangO0) { + if (runMode == RunMode::kCustomRun) { + return ret; + } + if (optimizationLevel == kO0) { ret = AppendDefaultOptions(kBinNameMplcg, kMplcgDefaultOptionsO0, sizeof(kMplcgDefaultOptionsO0) / sizeof(MplOption)); if (ret != kErrorNoError) { return ret; } - } else if (optimizationLevel == kO2 || optimizationLevel == kCLangO2) { + } else if (optimizationLevel == kO2) { ret = AppendDefaultOptions(kBinNameMplcg, kMplcgDefaultOptionsO2, sizeof(kMplcgDefaultOptionsO2) / sizeof(MplOption)); if (ret != kErrorNoError) { return ret; } } + UpdatePhaseOption(mplcgOptArgs, kBinNameMplcg); return ret; } @@ -469,7 +451,80 @@ void MplOptions::UpdateRunningExe(const std::string &args) { auto iter = std::find(runningExes.begin(), runningExes.end(), results[i]); if (iter == runningExes.end()) { runningExes.push_back(results[i]); + selectedExes.push_back(results[i]); + } + } +} + +std::string MplOptions::GetInputFileNameForPrint() const{ + if (!runningExes.empty()) { + if (runningExes[0] == kBinNameMe || runningExes[0] == kBinNameMpl2mpl + || runningExes[0] == kBinNameMplcg) { + return inputFiles; + } + } + if (inputFileType == InputFileType::kFileTypeVtableImplMpl) { + return outputFolder + outputName + ".VtableImpl.mpl"; + } + return outputFolder + outputName + ".mpl"; +} + +void MplOptions::PrintCommand() { + if (hasPrinted) { + return; + } + std::ostringstream optionStr; + if (runMode == RunMode::kAutoRun) { + if (optimizationLevel == kO0) { + optionStr << " -O0"; + } else if (optimizationLevel == kO2) { + optionStr << " -O2"; } + LogInfo::MapleLogger() << "Starting:" << exeFolder << "maple " << optionStr.str() << " " + << printExtraOptStr.str() << printCommandStr << " " << GetInputFileNameForPrint() << '\n'; + } + if (runMode == RunMode::kCustomRun) { + PrintDetailCommand(true); + } + hasPrinted = true; +} +void MplOptions::connectOptStr(std::string &optionStr, const std::string &exeName, bool &firstComb, + std::string &runStr) { + std::string connectSym = ""; + if (exeOptions.find(exeName) != exeOptions.end()) { + if (!firstComb) { + runStr += (":" + exeName); + optionStr += ":"; + } else { + runStr += exeName; + firstComb = false; + } + auto it = exeOptions.find(exeName); + for (const mapleOption::Option &opt : it->second) { + connectSym = !opt.Args().empty() ? "=" : ""; + optionStr += (" --" + opt.OptionKey() + connectSym + opt.Args());; + } + } +} +void MplOptions::PrintDetailCommand(bool isBeforeParse) { + if (exeOptions.find(kBinNameMe) == exeOptions.end() && exeOptions.find(kBinNameMpl2mpl) == exeOptions.end() + && exeOptions.find(kBinNameMplcg) == exeOptions.end()) { + return; + } + std::string runStr = "--run="; + std::string optionStr; + optionStr += "--option=\""; + bool firstComb = true; + connectOptStr(optionStr, kBinNameMe, firstComb, runStr); + connectOptStr(optionStr, kBinNameMpl2mpl, firstComb, runStr); + connectOptStr(optionStr, kBinNameMplcg, firstComb, runStr); + optionStr += "\""; + if (isBeforeParse) { + LogInfo::MapleLogger() << "Starting:" << exeFolder << "maple " << runStr << " " << optionStr << " " + << printExtraOptStr.str() << printCommandStr << " " << GetInputFileNameForPrint() << '\n'; + } else { + LogInfo::MapleLogger() << "Finished:" << exeFolder << "maple " << runStr << " " << optionStr << " " + << printCommandStr << " " << GetInputFileNameForPrint() << '\n'; } } } // namespace maple diff --git a/src/mapleall/maple_driver/src/mplcg_compiler.cpp b/src/mapleall/maple_driver/src/mplcg_compiler.cpp index 7b3e188f39d60e787d8dada12ff2677505b50d51..6c27c878d790831c0834807cba8d98f2be26d380 100644 --- a/src/mapleall/maple_driver/src/mplcg_compiler.cpp +++ b/src/mapleall/maple_driver/src/mplcg_compiler.cpp @@ -79,39 +79,48 @@ void MplcgCompiler::PrintCommand(const MplOptions &options) const { << " --infile " << GetInputFileName(options) << '\n'; } -bool MplcgCompiler::MakeCGOptions(const MplOptions &options) { +ErrorCode MplcgCompiler::MakeCGOptions(const MplOptions &options) { + auto it = std::find(options.GetRunningExes().begin(), options.GetRunningExes().end(), kBinNameMplcg); + if (it == options.GetRunningExes().end()) { + return kErrorNoError; + } CGOptions &cgOption = CGOptions::GetInstance(); cgOption.SetOption(CGOptions::kDefaultOptions); cgOption.SetOption(CGOptions::kWithMpl); cgOption.SetGenerateFlags(CGOptions::kDefaultGflags); - auto it = options.GetExeOptions().find(kBinNameMplcg); - if (it == options.GetExeOptions().end()) { - LogInfo::MapleLogger() << "no me input options\n"; - return false; + auto itOpt = options.GetExeOptions().find(kBinNameMplcg); + if (itOpt == options.GetExeOptions().end()) { + LogInfo::MapleLogger() << "no mplcg input options\n"; + return kErrorCompileFail; } - bool result = cgOption.SolveOptions(it->second, options.HasSetDebugFlag()); + bool result = cgOption.SolveOptions(itOpt->second, options.HasSetDebugFlag()); if (result == false) { LogInfo::MapleLogger() << "Meet error mplcg options\n"; - return false; + return kErrorCompileFail; } - return true; + return kErrorNoError; } -ErrorCode MplcgCompiler::Compile(const MplOptions &options, std::unique_ptr &theModule) { - MemPool *optMp = memPoolCtrler.NewMemPool("maplecg mempool"); +ErrorCode MplcgCompiler::Compile(MplOptions &options, std::unique_ptr &theModule) { + // Append Default cg options for auto mode + ErrorCode ret = options.AppendMplcgOptions(); + if (ret != kErrorNoError) { + return kErrorCompileFail; + } CGOptions &cgOption = CGOptions::GetInstance(); - bool result = MakeCGOptions(options); - if (!result) { + ret = MakeCGOptions(options); + if (ret != kErrorNoError) { return kErrorCompileFail; } std::string fileName = GetInputFileName(options); std::string baseName = options.GetOutputFolder() + FileUtils::GetFileName(fileName, false); std::string output = baseName + ".s"; - bool fileread = true; + MemPool *optMp = memPoolCtrler.NewMemPool("maplecg mempool"); + bool fileRead = true; if (theModule == nullptr) { MPLTimer timer; timer.Start(); - fileread = false; + fileRead = false; theModule = std::make_unique(fileName); theModule->SetWithMe( std::find(options.GetRunningExes().begin(), options.GetRunningExes().end(), @@ -147,9 +156,12 @@ ErrorCode MplcgCompiler::Compile(const MplOptions &options, std::unique_ptr; + void WriteEaField(const CallGraph &cg); + void WriteEaCgField(EAConnectionGraph *eaCg); + void OutEaCgNode(EACGBaseNode &node); + void OutEaCgBaseNode(EACGBaseNode &node, bool firstPart); + void OutEaCgFieldNode(EACGFieldNode &node); + void OutEaCgRefNode(EACGRefNode &node); + void OutEaCgActNode(EACGActualNode &node); + void OutEaCgObjNode(EACGObjectNode &node); + void WriteCgField(uint64 contentIdx, const CallGraph *cg); + void WriteSeField(); + void OutputCallInfo(CallInfo &callInfo); void WriteContentField4mplt(int fieldNum, uint64 *fieldStartP); void WriteContentField4nonmplt(int fieldNum, uint64 *fieldStartP); void WriteContentField4nonJava(int fieldNum, uint64 *fieldStartP); @@ -188,5 +200,66 @@ class BinaryMplExport { static int typeMarkOffset; // offset of mark (tag in binmplimport) resulting from duplicated function }; +class DoUpdateMplt : public ModulePhase { + public: + class ManualSideEffect { + public: + ManualSideEffect(std::string name, bool p, bool u, bool d, bool o, bool e) + : funcName(name), pure(p), defArg(u), def(d), object(o), exception(e) {}; + virtual ~ManualSideEffect() = default; + + const std::string &GetFuncName() const { + return funcName; + } + + bool GetPure() const { + return pure; + } + + bool GetDefArg() const { + return defArg; + } + + bool GetDef() const { + return def; + } + + bool GetObject() const { + return object; + } + + bool GetException() const { + return exception; + } + + bool GetPrivateUse() const { + return privateUse; + } + + bool GetPrivateDef() const { + return privateDef; + } + + private: + std::string funcName; + bool pure; + bool defArg; + bool def; + bool object; + bool exception; + bool privateUse = false; + bool privateDef = false; + }; + + explicit DoUpdateMplt(ModulePhaseID id) : ModulePhase(id) {} + + ~DoUpdateMplt() = default; + + void UpdateCgField(BinaryMplt &binMplt, const CallGraph &cg); + AnalysisResult *Run(MIRModule *module, ModuleResultMgr *moduleResultMgr) override; + std::string PhaseName() const override { + return "updatemplt"; + } +}; } // namespace maple #endif // MAPLE_IR_INCLUDE_BIN_MPL_EXPORT_H diff --git a/src/mapleall/maple_ir/include/global_tables.h b/src/mapleall/maple_ir/include/global_tables.h index ca688dee1c029489cc7dae2c41418f34acbd8990..614c649f3c4a63825837c63ed96f0d0978d84827 100644 --- a/src/mapleall/maple_ir/include/global_tables.h +++ b/src/mapleall/maple_ir/include/global_tables.h @@ -102,6 +102,18 @@ class TypeTable { return typeTable; } + auto &GetTypeHashTable() const { + return typeHashTable; + } + + auto &GetPtrTypeMap() const { + return ptrTypeMap; + } + + auto &GetRefTypeMap() const { + return refTypeMap; + } + MIRType *GetTypeFromTyIdx(TyIdx tyIdx) { return const_cast(const_cast(this)->GetTypeFromTyIdx(tyIdx)); } @@ -316,6 +328,7 @@ class TypeTable { return voidPtrType; } + void UpdateMIRType(const MIRType &pType, const TyIdx tyIdx); MIRArrayType *GetOrCreateArrayType(const MIRType &elem, uint8 dim, const uint32 *sizeArray); MIRArrayType *GetOrCreateArrayType(const MIRType &elem, uint32 size); // For one dimention array MIRType *GetOrCreateFarrayType(const MIRType &elem); diff --git a/src/mapleall/maple_ir/include/mir_symbol.h b/src/mapleall/maple_ir/include/mir_symbol.h index 849443aafee7739921f8ac20de091f12f1a8356f..b4e142494f1fb8f2c8b735456db9d94e9b113635 100644 --- a/src/mapleall/maple_ir/include/mir_symbol.h +++ b/src/mapleall/maple_ir/include/mir_symbol.h @@ -293,6 +293,10 @@ class MIRSymbol { return isDeleted; } + bool IsVar() const { + return sKind == kStVar; + } + bool IsPreg() const { return sKind == kStPreg; } diff --git a/src/mapleall/maple_ir/include/mir_symbol_builder.h b/src/mapleall/maple_ir/include/mir_symbol_builder.h index b17304b32db3e57c6f894ac76697b4387eeafcd7..7d12f87eaa2c19a8442d0e407c7b71c7880c23f6 100644 --- a/src/mapleall/maple_ir/include/mir_symbol_builder.h +++ b/src/mapleall/maple_ir/include/mir_symbol_builder.h @@ -49,6 +49,8 @@ class MIRSymbolBuilder { MIRSymbol *CreateSymbol(TyIdx tyIdx, GStrIdx strIdx, MIRSymKind mClass, MIRStorageClass sClass, MIRFunction *func, uint8 scpID) const; MIRSymbol *CreatePregFormalSymbol(TyIdx tyIdx, PregIdx pRegIdx, MIRFunction &func) const; + size_t GetSymbolTableSize(const MIRFunction *func = nullptr) const; + const MIRSymbol *GetSymbolFromStIdx(uint32 idx, const MIRFunction *func = nullptr) const; private: MIRSymbolBuilder() = default; diff --git a/src/mapleall/maple_ir/src/bin_mpl_export.cpp b/src/mapleall/maple_ir/src/bin_mpl_export.cpp index 6a1bae0e0328f4d4cbb4feb2994f4174ba593419..26e6aa9ff1614f7e4651d550f9bc42ebf59d7825 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_export.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_export.cpp @@ -573,15 +573,19 @@ void BinaryMplExport::OutputClassTypeData(const MIRClassType &type) { OutputType(type.GetParentTyIdx(), false); OutputImplementedInterfaces(type.GetInterfaceImplemented()); OutputInfoIsString(type.GetInfoIsString()); - OutputInfo(type.GetInfo(), type.GetInfoIsString()); - OutputPragmaVec(type.GetPragmaVec()); + if (!inIPA) { + OutputInfo(type.GetInfo(), type.GetInfoIsString()); + OutputPragmaVec(type.GetPragmaVec()); + } } void BinaryMplExport::OutputInterfaceTypeData(const MIRInterfaceType &type) { OutputImplementedInterfaces(type.GetParentsTyIdx()); OutputInfoIsString(type.GetInfoIsString()); - OutputInfo(type.GetInfo(), type.GetInfoIsString()); - OutputPragmaVec(type.GetPragmaVec()); + if (!inIPA) { + OutputInfo(type.GetInfo(), type.GetInfoIsString()); + OutputPragmaVec(type.GetPragmaVec()); + } } void BinaryMplExport::Init() { @@ -595,6 +599,7 @@ void BinaryMplExport::Init() { uStrMark[UStrIdx(0)] = 0; symMark[nullptr] = 0; funcMark[nullptr] = 0; + eaNodeMark[nullptr] = 0; for (uint32 pti = static_cast(PTY_begin); pti < static_cast(PTY_end); ++pti) { typMark[GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(pti))] = pti; } @@ -674,6 +679,31 @@ void BinaryMplExport::OutputFunction(PUIdx puIdx) { OutputType(formalDef.formalTyIdx, false); WriteNum(formalDef.formalAttrs.GetAttrFlag()); } + // store Side Effect for each func + if (func2SEMap) { + uint32 isSee = func->IsIpaSeen() == true ? 1 : 0; + uint32 isPure = func->IsPure() == true ? 1 : 0; + uint32 noDefArg = func->IsNoDefArgEffect() == true ? 1 : 0; + uint32 noDef = func->IsNoDefEffect() == true ? 1 : 0; + uint32 noRetGlobal = func->IsNoRetGlobal() == true ? 1 : 0; + uint32 noThr = func->IsNoThrowException() == true ? 1 : 0; + uint32 noRetArg = func->IsNoRetArg() == true ? 1 : 0; + uint32 noPriDef = func->IsNoPrivateDefEffect() == true ? 1 : 0; + uint32 i = 0; + uint8 se = noThr << i++; + se |= noRetGlobal << i++; + se |= noDef << i++; + se |= noDefArg << i++; + se |= isPure << i++; + se |= isSee << i++; + se |= noRetArg << i++; + se |= noPriDef << i; + if ((*func2SEMap).find(func->GetNameStrIdx()) == (*func2SEMap).end()) { + (*func2SEMap)[func->GetNameStrIdx()] = se; + } else if ((*func2SEMap)[func->GetNameStrIdx()] != se) { + FATAL(kLncFatal, "It is a bug."); + } + } mod.SetCurFunction(savedFunc); } @@ -760,6 +790,276 @@ void BinaryMplExport::WriteTypeField(uint64 contentIdx, bool useClassList) { WriteNum(~kBinTypeStart); } +void BinaryMplExport::OutputCallInfo(CallInfo &callInfo) { + auto it = callInfoMark.find(callInfo.GetID()); + if (it != callInfoMark.end()) { + WriteNum(-(it->second)); + return; + } + WriteNum(kBinCallinfo); + size_t mark = callInfoMark.size(); + callInfoMark[callInfo.GetID()] = mark; + WriteNum(callInfo.GetCallType()); // call type + WriteInt(callInfo.GetLoopDepth()); + WriteInt(callInfo.GetID()); + callInfo.AreAllArgsLocal() ? Write(1) : Write(0); // All args are local variables or not. + OutputSymbol(callInfo.GetFunc()->GetFuncSymbol()); +} + +void BinaryMplExport::WriteCgField(uint64 contentIdx, const CallGraph *cg) { + if (contentIdx != 0) { + Fixup(contentIdx, buf.size()); + } + WriteNum(kBinCgStart); + size_t totalSizeIdx = buf.size(); + ExpandFourBuffSize(); // total size of this field to ~BIN_CG_START + size_t outcgSizeIdx = buf.size(); + ExpandFourBuffSize(); // size of OutCG + int32 size = 0; + if (cg != nullptr) { + for (auto entry : cg->GetNodesMap()) { + MIRSymbol *methodSym = entry.first->GetFuncSymbol(); + WriteNum(kStartMethod); + OutputSymbol(methodSym); + size_t targetTyIdx = buf.size(); + ExpandFourBuffSize(); + int32 targSize = 0; + callInfoMark.clear(); + callInfoMark[0xffffffff] = 0; + for (const auto &callSite : entry.second->GetCallee()) { + OutputCallInfo(*(callSite.first)); + ++targSize; + } + Fixup(targetTyIdx, targSize); + WriteNum(~kStartMethod); + ++size; + } + } + + ASSERT((buf.size() - totalSizeIdx) <= 0xffffffff, "Integer overflow."); + Fixup(totalSizeIdx, buf.size() - totalSizeIdx); + Fixup(outcgSizeIdx, size); + WriteNum(~kBinCgStart); +} + +void BinaryMplExport::WriteSeField() { + ASSERT(func2SEMap != nullptr, "Expecting a func2SE map"); + WriteNum(kBinSeStart); + size_t totalSizeIdx = buf.size(); + ExpandFourBuffSize(); // total size of this field to ~BIN_SYM_START + size_t outseSizeIdx = buf.size(); + ExpandFourBuffSize(); // size of OutSym + int32 size = 0; + + for (const auto &func2SE : *func2SEMap) { + uint8 se = func2SE.second; + if (static_cast(se)) { + OutputStr(func2SE.first); + Write(se); + if ((se & kPureFunc) == kPureFunc) { + const std::string &funcStr = GlobalTables::GetStrTable().GetStringFromStrIdx(func2SE.first); + auto *funcSymbol = + GlobalTables::GetGsymTable().GetSymbolFromStrIdx(GlobalTables::GetStrTable().GetStrIdxFromName(funcStr)); + MIRFunction *func = (funcSymbol != nullptr) ? GetMIRModule().GetMIRBuilder()->GetFunctionFromSymbol(*funcSymbol) + : nullptr; + OutputType(func->GetReturnTyIdx(), false); + } + ++size; + } + } + Fixup(totalSizeIdx, buf.size() - totalSizeIdx); + Fixup(outseSizeIdx, size); + WriteNum(~kBinSeStart); +} + +void BinaryMplExport::OutEaCgBaseNode(EACGBaseNode &node, bool firstPart) { + if (firstPart) { + WriteNum(node.eaStatus); + WriteInt(node.id); + } else { + // in and out set in base node is not necessary to be outed + // start to out point-to set + size_t outP2SizeIdx = buf.size(); + WriteInt(0); + uint32 size = 0; + for (EACGBaseNode *outNode : node.GetPointsToSet()) { + OutEaCgNode(*outNode); + ++size; + } + Fixup(outP2SizeIdx, size); + // start to out in set + outP2SizeIdx = buf.size(); + WriteInt(0); + size = 0; + for (EACGBaseNode *outNode : node.GetInSet()) { + OutEaCgNode(*outNode); + ++size; + } + Fixup(outP2SizeIdx, size); + // start to out out set + outP2SizeIdx = buf.size(); + WriteInt(0); + size = 0; + for (EACGBaseNode *outNode : node.GetOutSet()) { + OutEaCgNode(*outNode); + ++size; + } + Fixup(outP2SizeIdx, size); + } +} + +void BinaryMplExport::OutEaCgObjNode(EACGObjectNode &obj) { + Write(uint8(obj.isPhantom)); + size_t outFieldSizeIdx = buf.size(); + WriteInt(0); + uint32 size = 0; + for (const auto &fieldNodePair : obj.fieldNodes) { + EACGBaseNode *fieldNode = fieldNodePair.second; + ASSERT(fieldNodePair.first == static_cast(fieldNode)->GetFieldID(), "Must be."); + OutEaCgNode(*fieldNode); + ++size; + } + Fixup(outFieldSizeIdx, size); + // start to out point by + outFieldSizeIdx = buf.size(); + WriteInt(0); + size = 0; + for (EACGBaseNode *node : obj.pointsBy) { + OutEaCgNode(*node); + ++size; + } + Fixup(outFieldSizeIdx, size); +} + +void BinaryMplExport::OutEaCgRefNode(EACGRefNode &ref) { + Write(uint8(ref.isStaticField)); +} + +void BinaryMplExport::OutEaCgFieldNode(EACGFieldNode &field) { + WriteInt(field.GetFieldID()); + int32 size = 0; + size_t outFieldSizeIdx = buf.size(); + WriteInt(0); + for (EACGBaseNode *obj : field.belongsTo) { + OutEaCgNode(*obj); + ++size; + } + Fixup(outFieldSizeIdx, size); + Write(uint8(field.isPhantom)); +} + +void BinaryMplExport::OutEaCgActNode(EACGActualNode &act) { + Write(uint8(act.isPhantom)); + Write(uint8(act.isReturn)); + Write(act.argIdx); + WriteInt(act.callSiteInfo); +} + +void BinaryMplExport::OutEaCgNode(EACGBaseNode &node) { + auto it = eaNodeMark.find(&node); + if (it != eaNodeMark.end()) { + WriteNum(-it->second); + return; + } + size_t mark = eaNodeMark.size(); + eaNodeMark[&node] = mark; + WriteNum(kBinEaCgNode); + WriteNum(node.kind); + OutEaCgBaseNode(node, true); + if (node.IsActualNode()) { + WriteNum(kBinEaCgActNode); + OutEaCgActNode(static_cast(node)); + } else if (node.IsFieldNode()) { + WriteNum(kBinEaCgFieldNode); + OutEaCgFieldNode(static_cast(node)); + } else if (node.IsObjectNode()) { + WriteNum(kBinEaCgObjNode); + OutEaCgObjNode(static_cast(node)); + } else if (node.IsReferenceNode()) { + WriteNum(kBinEaCgRefNode); + OutEaCgRefNode(static_cast(node)); + } else { + ASSERT(false, "Must be."); + } + OutEaCgBaseNode(node, false); + WriteNum(~kBinEaCgNode); +} + +void BinaryMplExport::WriteEaField(const CallGraph &cg) { + WriteNum(kBinEaStart); + uint64 totalSizeIdx = buf.size(); + WriteInt(0); + uint64 outeaSizeIdx = buf.size(); + WriteInt(0); + int32 size = 0; + for (auto cgNodePair : cg.GetNodesMap()) { + MIRFunction *func = cgNodePair.first; + if (func->GetEACG() == nullptr) { + continue; + } + EAConnectionGraph *eacg = func->GetEACG(); + ASSERT(eacg != nullptr, "Must be."); + OutputStr(eacg->GetFuncNameStrIdx()); + WriteInt(eacg->GetNodes().size()); + OutEaCgNode(*eacg->GetGlobalObject()); + uint64 outFunceaIdx = buf.size(); + WriteInt(0); + size_t funceaSize = 0; + for (EACGBaseNode *node : eacg->GetFuncArgNodes()) { + OutEaCgNode(*node); + ++funceaSize; + } + Fixup(outFunceaIdx, funceaSize); + ++size; + } + Fixup(totalSizeIdx, buf.size() - totalSizeIdx); + Fixup(outeaSizeIdx, size); + WriteNum(~kBinEaStart); +} + +void BinaryMplExport::WriteEaCgField(EAConnectionGraph *eacg){ + if (eacg == nullptr) { + WriteNum(~kBinEaCgStart); + return; + } + WriteNum(kBinEaCgStart); + size_t totalSizeIdx = buf.size(); + WriteInt(0); + // out this function's arg list + OutputStr(eacg->GetFuncNameStrIdx()); + WriteInt(eacg->GetNodes().size()); + OutEaCgNode(*eacg->GetGlobalObject()); + size_t outNodeSizeIdx = buf.size(); + WriteInt(0); + size_t argNodeSize = 0; + for (EACGBaseNode *node : eacg->GetFuncArgNodes()) { + OutEaCgNode(*node); + ++argNodeSize; + } + Fixup(outNodeSizeIdx, argNodeSize); + // out this function's call site's arg list + outNodeSizeIdx = buf.size(); + WriteInt(0); + size_t callSiteSize = 0; + for (auto nodePair : eacg->GetCallSite2Nodes()) { + uint32 id = nodePair.first; + MapleVector *calleeArgNode = nodePair.second; + WriteInt(id); + size_t outCalleeArgSizeIdx = buf.size(); + WriteInt(0); + size_t calleeArgSize = 0; + for (EACGBaseNode *node : *calleeArgNode) { + OutEaCgNode(*node); + ++calleeArgSize; + } + Fixup(outCalleeArgSizeIdx, calleeArgSize); + ++callSiteSize; + } + Fixup(outNodeSizeIdx, callSiteSize); + + Fixup(totalSizeIdx, buf.size()-totalSizeIdx); + WriteNum(~kBinEaCgStart); +} void BinaryMplExport::WriteSymField(uint64 contentIdx) { Fixup(contentIdx, buf.size()); @@ -881,6 +1181,7 @@ void BinaryMplExport::Export(const std::string &fname, std::unordered_set tmp; + binExport.func2SEMap = &tmp; + binExport.inIPA = true; + binExport.WriteCgField(0, &cg); + binExport.Init(); + binExport.WriteSeField(); + binExport.eaNodeMark.clear(); + binExport.eaNodeMark[nullptr] = 0; + binExport.gStrMark.clear(); + binExport.gStrMark[GStrIdx(0)] = 0; + binExport.WriteEaField(cg); + binExport.WriteNum(kBinFinish); + std::string filename(binMplt.GetImportFileName()); + binExport.AppendAt(filename, cgStart); +} + +AnalysisResult *DoUpdateMplt::Run(MIRModule *module, ModuleResultMgr *moduleResultMgr) { + if (moduleResultMgr == nullptr) { + return nullptr; + } + auto *cg = static_cast(moduleResultMgr->GetAnalysisResult(MoPhase_CALLGRAPH_ANALYSIS, module)); + CHECK_FATAL(cg != nullptr, "Expecting a valid CallGraph, found nullptr."); + BinaryMplt *binMplt = module->GetBinMplt(); + CHECK_FATAL(binMplt != nullptr, "Expecting a valid binMplt, found nullptr."); + UpdateCgField(*binMplt, *cg); + delete module->GetBinMplt(); + module->SetBinMplt(nullptr); + return nullptr; +} } // namespace maple diff --git a/src/mapleall/maple_ir/src/bin_mpl_import.cpp b/src/mapleall/maple_ir/src/bin_mpl_import.cpp index df94e65b3326bcd5ad7250a1401fc6370a51bd1c..147fe1b0bc0804e71aa7c6360d7279beb6bc3a88 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_import.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_import.cpp @@ -475,6 +475,7 @@ void BinaryMplImport::Reset() { uStrTab.push_back(UStrIdx(0)); // Dummy symTab.push_back(nullptr); // Dummy funcTab.push_back(nullptr); // Dummy + eaCgTab.push_back(nullptr); for (int32 pti = static_cast(PTY_begin); pti < static_cast(PTY_end); ++pti) { typTab.push_back(GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(pti))); } @@ -779,10 +780,6 @@ MIRType &BinaryMplImport::InsertInTypeTables(MIRType &type) { return *resultTypePtr; } -void BinaryMplImport::UpdateDebugInfo() { -} - - void BinaryMplImport::SetupEHRootType() { // setup eh root type with most recent Ljava_2Flang_2FObject_3B GStrIdx gStrIdx = GlobalTables::GetStrTable().GetStrIdxFromName(namemangler::kJavaLangObjectStr); @@ -888,7 +885,42 @@ PUIdx BinaryMplImport::ImportFunction() { func->SetMIRFuncType(static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcTyIdx))); func->SetStIdx(funcSt->GetStIdx()); - func->SetFuncAttrs(ReadNum()); + if (!inCG) { + func->SetFuncAttrs(ReadNum()); // merge side effect + } else { + if (!func->IsDirty()) { + func->SetDirty(true); + func->SetFuncAttrs(ReadNum()); // merge side effect + } else { + FuncAttrs tmp; + tmp.SetAttrFlag(ReadNum()); + if (func->IsNoDefArgEffect() != tmp.GetAttr(FUNCATTR_nodefargeffect)) { + tmp.SetAttr(FUNCATTR_nodefargeffect, true); + } + if (func->IsNoDefEffect() != tmp.GetAttr(FUNCATTR_nodefeffect)) { + tmp.SetAttr(FUNCATTR_nodefeffect, true); + } + if (func->IsNoRetGlobal() != tmp.GetAttr(FUNCATTR_noretglobal)) { + tmp.SetAttr(FUNCATTR_noretglobal, true); + } + if (func->IsNoThrowException() != tmp.GetAttr(FUNCATTR_nothrow_exception)) { + tmp.SetAttr(FUNCATTR_nothrow_exception, true); + } + if (func->IsIpaSeen() != tmp.GetAttr(FUNCATTR_ipaseen)) { + tmp.SetAttr(FUNCATTR_ipaseen); + } + if (func->IsPure() != tmp.GetAttr(FUNCATTR_pure)) { + tmp.SetAttr(FUNCATTR_pure, true); + } + if (func->IsNoRetArg() != tmp.GetAttr(FUNCATTR_noretarg)) { + tmp.SetAttr(FUNCATTR_noretarg, true); + } + if (func->IsNoPrivateDefEffect() != tmp.GetAttr(FUNCATTR_noprivate_defeffect)) { + tmp.SetAttr(FUNCATTR_noprivate_defeffect, true); + } + func->SetFuncAttrs(tmp); + } + } func->SetFlag(ReadNum()); (void)ImportType(); // not set the field to mimic parser size_t size = ReadNum(); @@ -987,6 +1019,287 @@ void BinaryMplImport::ReadTypeField() { CHECK_FATAL(tag == ~kBinTypeStart, "pattern mismatch in Read TYPE"); } +CallInfo *BinaryMplImport::ImportCallInfo() { + int64 tag = ReadNum(); + if (tag < 0) { + CHECK_FATAL(static_cast(-tag) < callInfoTab.size(), "index out of bounds"); + return callInfoTab.at(-tag); + } + CHECK_FATAL(tag == kBinCallinfo, "expecting kBinCallinfo"); + CallType ctype = (CallType)ReadNum(); // call type + uint32 loopDepth = static_cast(ReadInt()); + uint32 id = static_cast(ReadInt()); + bool argLocal = Read() == 1; + MIRSymbol *funcSym = InSymbol(nullptr); + CHECK_FATAL(funcSym != nullptr, "func_sym is null in BinaryMplImport::InCallInfo"); + CallInfo *ret = mod.GetMemPool()->New(ctype, *funcSym->GetFunction(), + static_cast(nullptr), loopDepth, id, argLocal); + callInfoTab.push_back(ret); + return ret; +} + +void BinaryMplImport::MergeDuplicated(PUIdx methodPuidx, std::vector &targetSet, + std::vector &newSet) { + if (targetSet.empty()) { + (void)targetSet.insert(targetSet.begin(), newSet.begin(), newSet.end()); + std::unordered_set tmp; + mod.AddValueToMethod2TargetHash(methodPuidx, tmp); + for (size_t i = 0; i < newSet.size(); ++i) { + mod.InsertTargetHash(methodPuidx, newSet[i]->GetID()); + } + } else { + for (size_t i = 0; i < newSet.size(); ++i) { + CallInfo *newItem = newSet[i]; + if (!mod.HasTargetHash(methodPuidx, newItem->GetID())) { + targetSet.push_back(newItem); + mod.InsertTargetHash(methodPuidx, newItem->GetID()); + } + } + } +} + +void BinaryMplImport::ReadCgField() { + SkipTotalSize(); + + int32 size = ReadInt(); + int64 tag = 0; + + for (int i = 0; i < size; ++i) { + tag = ReadNum(); + CHECK_FATAL(tag == kStartMethod, " should be start point of method"); + MIRSymbol *tmpInSymbol = InSymbol(nullptr); + CHECK_FATAL(tmpInSymbol != nullptr, "null ptr check"); + PUIdx methodPuidx = tmpInSymbol->GetFunction()->GetPuidx(); + CHECK_FATAL(methodPuidx, "should not be 0"); + if (mod.GetMethod2TargetMap().find(methodPuidx) == mod.GetMethod2TargetMap().end()) { + std::vector targetSetTmp; + mod.AddMemToMethod2TargetMap(methodPuidx, targetSetTmp); + } + int32 targSize = ReadInt(); + std::vector targetSet; + callInfoTab.clear(); + callInfoTab.push_back(nullptr); + for (int32 j = 0; j < targSize; ++j) { + CallInfo *callInfo = ImportCallInfo(); + targetSet.push_back(callInfo); + } + MergeDuplicated(methodPuidx, mod.GetMemFromMethod2TargetMap(methodPuidx), targetSet); + tag = ReadNum(); + CHECK_FATAL(tag == ~kStartMethod, " should be start point of method"); + } + tag = ReadNum(); + CHECK_FATAL(tag == ~kBinCgStart, "pattern mismatch in Read CG"); +} + +void BinaryMplImport::ReadEaField() { + ReadInt(); + int size = ReadInt(); + for (int i = 0; i < size; ++i) { + GStrIdx funcName = ImportStr(); + int nodesSize = ReadInt(); + EAConnectionGraph *newEaCg = mod.GetMemPool()->New(&mod, &mod.GetMPAllocator(), funcName, true); + newEaCg->ResizeNodes(nodesSize, nullptr); + InEaCgNode(*newEaCg); + int eaSize = ReadInt(); + for (int j = 0; j < eaSize; ++j) { + EACGBaseNode *node = &InEaCgNode(*newEaCg); + newEaCg->funcArgNodes.push_back(node); + } + mod.SetEAConnectionGraph(funcName, newEaCg); + } + CHECK_FATAL(ReadNum() == ~kBinEaStart, "pattern mismatch in Read EA"); +} + +void BinaryMplImport::ReadSeField() { + SkipTotalSize(); + + int32 size = ReadInt(); +#ifdef MPLT_DEBUG + LogInfo::MapleLogger() << "SE SIZE : " << size << '\n'; +#endif + for (int32 i = 0; i < size; ++i) { + GStrIdx funcName = ImportStr(); + uint8 specialEffect = Read(); + TyIdx tyIdx = kInitTyIdx; + if ((specialEffect & kPureFunc) == kPureFunc) { + tyIdx = ImportType(); + } + const std::string &funcStr = GlobalTables::GetStrTable().GetStringFromStrIdx(funcName); + if (funcStr == "Ljava_2Flang_2FObject_3B_7Cwait_7C_28_29V") { + specialEffect = 0; + } + auto *funcSymbol = + GlobalTables::GetGsymTable().GetSymbolFromStrIdx(GlobalTables::GetStrTable().GetStrIdxFromName(funcStr)); + MIRFunction *func = funcSymbol != nullptr ? mirBuilder.GetFunctionFromSymbol(*funcSymbol) : nullptr; + if (func != nullptr) { + func->SetAttrsFromSe(specialEffect); + } else if ((specialEffect & kPureFunc) == kPureFunc) { + func = mirBuilder.GetOrCreateFunction(funcStr, tyIdx); + func->SetAttrsFromSe(specialEffect); + } + } + int64 tag = ReadNum(); + CHECK_FATAL(tag == ~kBinSeStart, "pattern mismatch in Read TYPE"); +} + +void BinaryMplImport::InEaCgBaseNode(EACGBaseNode &base, EAConnectionGraph &newEaCg, bool firstPart) { + if (firstPart) { + base.SetEAStatus((EAStatus)ReadNum()); + base.SetID(ReadInt()); + } else { + // start to in points to + int size = ReadInt(); + for (int i = 0; i < size; ++i) { + EACGBaseNode *point2Node = &InEaCgNode(newEaCg); + CHECK_FATAL(point2Node->IsObjectNode(), "must be"); + (void)base.pointsTo.insert(static_cast(point2Node)); + } + // start to in in + size = ReadInt(); + for (int i = 0; i < size; ++i) { + EACGBaseNode *point2Node = &InEaCgNode(newEaCg); + base.InsertInSet(point2Node); + } + // start to in out + size = ReadInt(); + for (int i = 0; i < size; ++i) { + EACGBaseNode *point2Node = &InEaCgNode(newEaCg); + base.InsertOutSet(point2Node); + } + } +} + +void BinaryMplImport::InEaCgActNode(EACGActualNode &actual) { + actual.isPhantom = Read() == 1; + actual.isReturn = Read() == 1; + actual.argIdx = Read(); + actual.callSiteInfo = static_cast(ReadInt()); +} + +void BinaryMplImport::InEaCgFieldNode(EACGFieldNode &field, EAConnectionGraph &newEaCg) { + field.SetFieldID(ReadInt()); + int size = ReadInt(); + for (int i = 0; i < size; ++i) { + EACGBaseNode* node = &InEaCgNode(newEaCg); + CHECK_FATAL(node->IsObjectNode(), "must be"); + (void)field.belongsTo.insert(static_cast(node)); + } + field.isPhantom = Read() == 1; +} + +void BinaryMplImport::InEaCgObjNode(EACGObjectNode &obj, EAConnectionGraph &newEaCg) { + Read(); + obj.isPhantom = true; int size = ReadInt(); + for (int i = 0; i < size; ++i) { + EACGBaseNode *node = &InEaCgNode(newEaCg); + CHECK_FATAL(node->IsFieldNode(), "must be"); + auto *field = static_cast(node); + obj.fieldNodes[static_cast(field)->GetFieldID()] = field; + } + // start to in point by + size = ReadInt(); + for (int i = 0; i < size; ++i) { + EACGBaseNode *point2Node = &InEaCgNode(newEaCg); + (void)obj.pointsBy.insert(point2Node); + } +} + +void BinaryMplImport::InEaCgRefNode(EACGRefNode &ref) { + ref.isStaticField = Read() == 1 ? true : false; +} + +EACGBaseNode &BinaryMplImport::InEaCgNode(EAConnectionGraph &newEaCg) { + int64 tag = ReadNum(); + if (tag < 0) { + CHECK_FATAL(static_cast(-tag) < eaCgTab.size(), "index out of bounds"); + return *eaCgTab[-tag]; + } + CHECK_FATAL(tag == kBinEaCgNode, "must be"); + NodeKind kind = (NodeKind)ReadNum(); + EACGBaseNode *node = nullptr; + switch (kind) { + case kObejectNode: + node = new EACGObjectNode(&mod, &mod.GetMPAllocator(), &newEaCg); + break; + case kReferenceNode: + node = new EACGRefNode(&mod, &mod.GetMPAllocator(), &newEaCg); + break; + case kFieldNode: + node = new EACGFieldNode(&mod, &mod.GetMPAllocator(), &newEaCg); + break; + case kActualNode: + node = new EACGActualNode(&mod, &mod.GetMPAllocator(), &newEaCg); + break; + default: + CHECK_FATAL(false, "impossible"); + } + node->SetEACG(&newEaCg); + eaCgTab.push_back(node); + InEaCgBaseNode(*node, newEaCg, true); + newEaCg.SetNodeAt(node->id - 1, node); + if (node->IsActualNode()) { + CHECK_FATAL(ReadNum() == kBinEaCgActNode, "must be"); + InEaCgActNode(static_cast(*node)); + } else if (node->IsFieldNode()) { + CHECK_FATAL(ReadNum() == kBinEaCgFieldNode, "must be"); + InEaCgFieldNode(static_cast(*node), newEaCg); + } else if (node->IsObjectNode()) { + CHECK_FATAL(ReadNum() == kBinEaCgObjNode, "must be"); + InEaCgObjNode(static_cast(*node), newEaCg); + } else if (node->IsReferenceNode()) { + CHECK_FATAL(ReadNum() == kBinEaCgRefNode, "must be"); + InEaCgRefNode(static_cast(*node)); + } + InEaCgBaseNode(*node, newEaCg, false); + CHECK_FATAL(ReadNum() == ~kBinEaCgNode, "must be"); + return *node; +} + +EAConnectionGraph* BinaryMplImport::ReadEaCgField() { + if (ReadNum() == ~kBinEaCgStart) { + return nullptr; + } + ReadInt(); + GStrIdx funcStr = ImportStr(); + int nodesSize = ReadInt(); + EAConnectionGraph *newEaCg = mod.GetMemPool()->New(&mod, &mod.GetMPAllocator(), funcStr, true); + newEaCg->ResizeNodes(nodesSize, nullptr); + InEaCgNode(*newEaCg); + CHECK_FATAL(newEaCg->GetNode(0)->IsObjectNode(), "must be"); + CHECK_FATAL(newEaCg->GetNode(1)->IsReferenceNode(), "must be"); + CHECK_FATAL(newEaCg->GetNode(2)->IsFieldNode(), "must be"); + newEaCg->globalField = static_cast(newEaCg->GetNode(2)); + newEaCg->globalObj = static_cast(newEaCg->GetNode(0)); + newEaCg->globalRef = static_cast(newEaCg->GetNode(1)); + CHECK_FATAL(newEaCg->globalField && newEaCg->globalObj && newEaCg->globalRef, "must be"); + int32 nodeSize = ReadInt(); + for (int j = 0; j < nodeSize; ++j) { + EACGBaseNode *node = &InEaCgNode(*newEaCg); + newEaCg->funcArgNodes.push_back(node); + } + + int32 callSitesize = ReadInt(); + for (int i = 0; i < callSitesize; ++i) { + uint32 id = static_cast(ReadInt()); + newEaCg->callSite2Nodes[id] = mod.GetMemPool()->New>(mod.GetMPAllocator().Adapter()); + int32 calleeArgSize = ReadInt(); + for (int j = 0; j < calleeArgSize; ++j) { + EACGBaseNode *node = &InEaCgNode(*newEaCg); + newEaCg->callSite2Nodes[id]->push_back(node); + } + } + +#ifdef DEBUG + for (EACGBaseNode *node : newEaCg->GetNodes()) { + if (node == nullptr) { + continue; + } + node->CheckAllConnectionInNodes(); + } +#endif + CHECK_FATAL(ReadNum() == ~kBinEaCgStart, "pattern mismatch in Read EACG"); + return newEaCg; +} void BinaryMplImport::ReadSymField() { SkipTotalSize(); @@ -1031,6 +1344,9 @@ void BinaryMplImport::Jump2NextField() { ReadNum(); // skip end tag for this field } +void BinaryMplImport::UpdateDebugInfo() { +} + bool BinaryMplImport::Import(const std::string &fname, bool readSymbols, bool readSe) { Reset(); ReadFileAt(fname, 0); @@ -1041,6 +1357,34 @@ bool BinaryMplImport::Import(const std::string &fname, bool readSymbols, bool re } importingFromMplt = kMpltMagicNumber == magic; int64 fieldID = ReadNum(); + if (readSe) { + while (fieldID != kBinFinish) { + if (fieldID == kBinSeStart) { +#ifdef MPLT_DEBUG + LogInfo::MapleLogger() << "read SE of : " << fname << '\n'; +#endif + BinaryMplImport tmp(mod); + tmp.Reset(); + tmp.buf = buf; + tmp.bufI = bufI; + tmp.importFileName = fname; + tmp.ReadSeField(); + Jump2NextField(); + } else if (fieldID == kBinEaStart) { + BinaryMplImport tmp(mod); + tmp.Reset(); + tmp.buf = buf; + tmp.bufI = bufI; + tmp.importFileName = fname; + tmp.ReadEaField(); + Jump2NextField(); + } else { + Jump2NextField(); + } + fieldID = ReadNum(); + } + return true; + } while (fieldID != kBinFinish) { switch (fieldID) { case kBinContentStart: { @@ -1072,9 +1416,45 @@ bool BinaryMplImport::Import(const std::string &fname, bool readSymbols, bool re break; } case kBinCgStart: { + if (readSymbols) { +#ifdef MPLT_DEBUG + LogInfo::MapleLogger() << "read CG of : " << fname << '\n'; +#endif + BinaryMplImport tmp(mod); + tmp.Reset(); + tmp.inIPA = true; + tmp.buf = buf; + tmp.bufI = bufI; + tmp.importFileName = fname; + tmp.ReadCgField(); + tmp.UpdateMethodSymbols(); + Jump2NextField(); + } else { + Jump2NextField(); + } + break; + } + case kBinSeStart: { Jump2NextField(); break; } + case kBinEaStart: { + if (readSymbols) { +#ifdef MPLT_DEBUG + LogInfo::MapleLogger() << "read EA of : " << fname << '\n'; +#endif + BinaryMplImport tmp(mod); + tmp.Reset(); + tmp.buf = buf; + tmp.bufI = bufI; + tmp.importFileName = fname; + tmp.ReadEaField(); + Jump2NextField(); + } else { + Jump2NextField(); + } + break; + } case kBinFunctionBodyStart: { ReadFunctionBodyField(); break; diff --git a/src/mapleall/maple_ir/src/global_tables.cpp b/src/mapleall/maple_ir/src/global_tables.cpp index 254cd7fd0cd761fc023b6156739d3a2daa5c6810..f387526ce3dfe912de40b57db5faa4cc41970a90 100644 --- a/src/mapleall/maple_ir/src/global_tables.cpp +++ b/src/mapleall/maple_ir/src/global_tables.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2019-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -53,6 +53,7 @@ void TypeTable::SetTypeWithTyIdx(const TyIdx &tyIdx, MIRType &type) { #if 0 // cannot delete because typTab in BinaryMplImport is still pointing to it delete oldType; #endif + (void)typeHashTable.insert(&type); } } @@ -67,6 +68,12 @@ void TypeTable::PutToHashTable(MIRType *mirType) { (void)typeHashTable.insert(mirType); } +void TypeTable::UpdateMIRType(const MIRType &pType, const TyIdx tyIdx) { + MIRType *nType = pType.CopyMIRTypeNode(); + nType->SetTypeIndex(tyIdx); + SetTypeWithTyIdx(tyIdx, *nType); +} + MIRType *TypeTable::CreateAndUpdateMirTypeNode(MIRType &pType) { MIRType *nType = pType.CopyMIRTypeNode(); nType->SetTypeIndex(TyIdx(typeTable.size())); @@ -80,6 +87,8 @@ MIRType *TypeTable::CreateAndUpdateMirTypeNode(MIRType &pType) { } else { refTypeMap[pty.GetPointedTyIdx()] = nType->GetTypeIndex(); } + } else { + (void)typeHashTable.insert(nType); } } else { (void)typeHashTable.insert(nType); diff --git a/src/mapleall/maple_ir/src/mir_symbol_builder.cpp b/src/mapleall/maple_ir/src/mir_symbol_builder.cpp index 27620687e9ff16319b2cc3cb96754ab7e227a2f4..1a15dbca7432c26873ab500cad29798b789ac7db 100644 --- a/src/mapleall/maple_ir/src/mir_symbol_builder.cpp +++ b/src/mapleall/maple_ir/src/mir_symbol_builder.cpp @@ -107,4 +107,19 @@ MIRSymbol *MIRSymbolBuilder::CreatePregFormalSymbol(TyIdx tyIdx, PregIdx pRegIdx st->SetPreg(pregTab->PregFromPregIdx(pRegIdx)); return st; } + +size_t MIRSymbolBuilder::GetSymbolTableSize(const MIRFunction *func) const { + return (func == nullptr) ? GlobalTables::GetGsymTable().GetSymbolTableSize() : + func->GetSymTab()->GetSymbolTableSize(); +} + +const MIRSymbol *MIRSymbolBuilder::GetSymbolFromStIdx(uint32 idx, const MIRFunction *func) const { + if (func == nullptr) { + auto &symTab = GlobalTables::GetGsymTable(); + return symTab.GetSymbolFromStidx(idx); + } else { + auto &symTab = *func->GetSymTab(); + return symTab.GetSymbolFromStIdx(idx); + } +} } // maple diff --git a/src/mapleall/maple_ir/src/parser.cpp b/src/mapleall/maple_ir/src/parser.cpp index df4c134cc2741d7a01740d758336cc685faef954..779d060535da83e81c4c6be7ad15d29c8c1074ea 100644 --- a/src/mapleall/maple_ir/src/parser.cpp +++ b/src/mapleall/maple_ir/src/parser.cpp @@ -813,6 +813,7 @@ bool MIRParser::ParseStructType(TyIdx &styIdx) { if (!ParseFields(structType)) { return false; } + // Dex file create a struct type with name, but do not check the type field. if (styIdx != 0u) { MIRType *prevType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(styIdx); if (prevType->GetKind() != kTypeByName) { @@ -848,6 +849,7 @@ bool MIRParser::ParseClassType(TyIdx &styidx) { if (!ParseFields(classType)) { return false; } + // Dex file create a strtuct type with name, but donot check the type field. MIRType *prevType = nullptr; if (styidx != 0u) { prevType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(styidx); @@ -894,6 +896,7 @@ bool MIRParser::ParseInterfaceType(TyIdx &sTyIdx) { if (!ParseFields(interfaceType)) { return false; } + // Dex file create a strtuct type with name, but donot check the type field. if (sTyIdx != 0u) { MIRType *prevType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sTyIdx); ASSERT(prevType->GetKind() == kTypeInterface || prevType->IsIncomplete(), @@ -1944,6 +1947,10 @@ bool MIRParser::ParseFunction(uint32 fileIdx) { maple::MIRBuilder mirBuilder(&mod); funcSymbol = mirBuilder.CreateSymbol(TyIdx(0), strIdx, kStFunc, kScText, nullptr, kScopeGlobal); SetSrcPos(funcSymbol->GetSrcPosition(), lexer.GetLineNum()); + // when parsing func in mplt_inline file, set it as tmpunused. + if (options & kParseInlineFuncBody) { + funcSymbol->SetIsTmpUnused(true); + } func = mod.GetMemPool()->New(&mod, funcSymbol->GetStIdx()); func->SetPuidx(GlobalTables::GetFunctionTable().GetFuncTable().size()); GlobalTables::GetFunctionTable().GetFuncTable().push_back(func); @@ -2292,6 +2299,22 @@ bool MIRParser::ParseMIR(std::ifstream &mplFile) { return status; } +bool MIRParser::ParseInlineFuncBody(std::ifstream &mplFile) { + std::ifstream *origFile = lexer.GetFile(); + lexer.SetFile(mplFile); + // try to read the first line + if (lexer.ReadALine() < 0) { + lexer.lineNum = 0; + } else { + lexer.lineNum = 1; + } + // parse mplFile + bool status = ParseMIR(0, kParseOptFunc | kParseInlineFuncBody); + // restore airFile + lexer.SetFile(*origFile); + return status; +} + bool MIRParser::ParseMIR(uint32 fileIdx, uint32 option, bool isIPA, bool isComb) { if ((option & kParseOptFunc) == 0) { PrepareParsingMIR(); @@ -2390,6 +2413,10 @@ bool MIRParser::ParseMIRForFunc() { if (!ParseFunction(paramFileIdx)) { return false; } + // when parsing function in mplt_inline file, set fromMpltInline as true. + if ((this->options & kParseInlineFuncBody) && curFunc) { + curFunc->SetFromMpltInline(true); + } if ((this->options & kParseOptFunc) && curFunc) { curFunc->SetAttr(FUNCATTR_optimized); mod.AddOptFuncs(curFunc); @@ -2426,6 +2453,10 @@ bool MIRParser::ParseMIRForVar() { maple::MIRBuilder mirBuilder(&mod); MIRSymbol *newst = mirBuilder.CreateSymbol(st.GetTyIdx(), st.GetNameStrIdx(), st.GetSKind(), st.GetStorageClass(), nullptr, kScopeGlobal); + // when parsing var in mplt_inline file, set it as tmpunused. + if (this->options & kParseInlineFuncBody) { + newst->SetIsTmpUnused(true); + } newst->SetAttrs(st.GetAttrs()); newst->SetNameStrIdx(st.GetNameStrIdx()); newst->SetValue(st.GetValue()); diff --git a/src/mapleall/maple_me/BUILD.gn b/src/mapleall/maple_me/BUILD.gn index 5678a1aaeb88b0d119c3f58f3f68e407af18956e..3a4869221e94526b14694eb77d3d67d21f67ed46 100755 --- a/src/mapleall/maple_me/BUILD.gn +++ b/src/mapleall/maple_me/BUILD.gn @@ -86,6 +86,7 @@ src_libmplme = [ "src/me_gc_lowering.cpp", "src/me_gc_write_barrier_opt.cpp", "src/me_subsum_rc.cpp", + "src/me_verify.cpp", ] src_libmplmewpo = [ diff --git a/src/mapleall/maple_me/include/bb.h b/src/mapleall/maple_me/include/bb.h index a51c239f1e6ebdbe875be395bd60a9e8252499cb..f4a496e983458625671ba7a3082a3fe94a27b3b2 100644 --- a/src/mapleall/maple_me/include/bb.h +++ b/src/mapleall/maple_me/include/bb.h @@ -284,6 +284,10 @@ class BB { return meStmtList.empty(); } + bool IsReturnBB() const { + return kind == kBBReturn && !stmtNodeList.empty() && stmtNodeList.back().GetOpCode() == OP_return; + } + void FindReachableBBs(std::vector &visitedBBs) const; void FindWillExitBBs(std::vector &visitedBBs) const; const PhiNode *PhiofVerStInserted(const VersionSt &versionSt) const; diff --git a/src/mapleall/maple_me/include/irmap.h b/src/mapleall/maple_me/include/irmap.h index 0b7f583eab03c661a55d213571a8bb0d5e4bb083..6ec120292fb28459d3622f0261563c2cd9f04b31 100644 --- a/src/mapleall/maple_me/include/irmap.h +++ b/src/mapleall/maple_me/include/irmap.h @@ -118,8 +118,8 @@ class IRMap : public AnalysisResult { UnaryMeStmt *CreateUnaryMeStmt(Opcode op, MeExpr *opnd, BB *bb, const SrcPosition *src); IntrinsiccallMeStmt *CreateIntrinsicCallMeStmt(MIRIntrinsicID idx, std::vector &opnds, TyIdx tyIdx = TyIdx()); - IntrinsiccallMeStmt *CreateIntrinsicCallAssignedMeStmt(MIRIntrinsicID idx, std::vector &opnds, ScalarMeExpr *ret, - TyIdx tyIdx = TyIdx()); + IntrinsiccallMeStmt *CreateIntrinsicCallAssignedMeStmt(MIRIntrinsicID idx, std::vector &opnds, + ScalarMeExpr *ret, TyIdx tyIdx = TyIdx()); MeExpr *SimplifyOpMeExpr(OpMeExpr *opmeexpr); MeExpr *SimplifyMeExpr(MeExpr *x); diff --git a/src/mapleall/maple_me/include/me_bb_layout.h b/src/mapleall/maple_me/include/me_bb_layout.h index e40cc7c41142772e4e712dfbdadc3a493c9809a7..46a56d277796eebea5525b545e5d7d4b8207d3ee 100644 --- a/src/mapleall/maple_me/include/me_bb_layout.h +++ b/src/mapleall/maple_me/include/me_bb_layout.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2019-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -104,6 +104,8 @@ class BBLayout{ void FixEndTryBB(BB &bb); void FixTryBB(BB &startTryBB, BB &nextBB); void DealWithStartTryBB(); + void UpdateNewBBWithAttrTry(const BB &bb, BB &fallthru) const; + void SetAttrTryForTheCanBeMovedBB(BB &bb, BB &fallthru) const; MeFunction &func; MapleAllocator layoutAlloc; diff --git a/src/mapleall/maple_me/include/me_critical_edge.h b/src/mapleall/maple_me/include/me_critical_edge.h index 5b27d77418a61beaf73ebc0d95d855668f2769d6..815ae03b7190819e75ce64f1dcb7d0ddd4b00d0e 100644 --- a/src/mapleall/maple_me/include/me_critical_edge.h +++ b/src/mapleall/maple_me/include/me_critical_edge.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -32,10 +32,11 @@ class MeDoSplitCEdge : public MeFuncPhase { } private: - void UpdateNewBBInTry(BB &newBB, const BB &pred) const; void UpdateGotoLabel(BB &newBB, MeFunction &func, BB &pred, BB &succ) const; void UpdateCaseLabel(BB &newBB, MeFunction &func, BB &pred, BB &succ) const; void BreakCriticalEdge(MeFunction &func, BB &pred, BB &succ) const; + void UpdateNewBBInTry(MeFunction &func, BB &newBB, const BB &pred) const; + void DealWithTryBB(MeFunction &func, BB &pred, BB &succ, BB *&newBB, bool &isInsertAfterPred) const; }; } // namespace maple #endif // MAPLE_ME_INCLUDE_MECRITICALEDGE_H diff --git a/src/mapleall/maple_me/include/me_function.h b/src/mapleall/maple_me/include/me_function.h index 6fe34a2f9555110d41a496d8b904686f42982695..ad220806f749459a0a2c89bcfd8431f24a3301cd 100644 --- a/src/mapleall/maple_me/include/me_function.h +++ b/src/mapleall/maple_me/include/me_function.h @@ -296,7 +296,7 @@ class MeFunction : public FuncEmit { } BB *NewBasicBlock(); - BB &InsertNewBasicBlock(const BB &position); + BB &InsertNewBasicBlock(const BB &position, bool isInsertBefore = true); void DeleteBasicBlock(const BB &bb); BB *NextBB(const BB *bb); BB *PrevBB(const BB *bb); diff --git a/src/mapleall/maple_me/include/me_ir.h b/src/mapleall/maple_me/include/me_ir.h index 064a6ed08a1651e6cf92bfc94834b9d8b34bb29c..10c8ab7cc31f54fd84b1dcd2e6c6aabeb7285dc2 100644 --- a/src/mapleall/maple_me/include/me_ir.h +++ b/src/mapleall/maple_me/include/me_ir.h @@ -1202,7 +1202,7 @@ class MeStmt { return false; } - virtual void SetNeedIncref(bool val = true) {} + virtual void SetNeedIncref(bool) {} virtual void EnableNeedIncref() {} @@ -1482,10 +1482,9 @@ class PiassignMeStmt : public MeStmt { class AssignMeStmt : public MeStmt { public: - AssignMeStmt(const StmtNode *stt) : MeStmt(stt) {} + explicit AssignMeStmt(const StmtNode *stt) : MeStmt(stt) {} - explicit AssignMeStmt(Opcode op, ScalarMeExpr *thelhs, MeExpr *rhsVal): MeStmt(op), rhs(rhsVal), lhs(thelhs) { - } + AssignMeStmt(Opcode op, ScalarMeExpr *theLhs, MeExpr *rhsVal): MeStmt(op), rhs(rhsVal), lhs(theLhs) {} ~AssignMeStmt() = default; @@ -1527,6 +1526,14 @@ class AssignMeStmt : public MeStmt { needDecref = value; } + void EnableNeedDecref() { + needDecref = true; + } + + void DisableNeedDecref() { + needDecref = false; + } + ScalarMeExpr *GetLHS() const { return lhs; } @@ -1564,8 +1571,8 @@ class DassignMeStmt : public AssignMeStmt { : AssignMeStmt(stt), chiList(std::less(), alloc->Adapter()) {} - explicit DassignMeStmt(MapleAllocator *alloc, VarMeExpr *thelhs, MeExpr *rhsVal) - : AssignMeStmt(OP_dassign, thelhs, rhsVal), + DassignMeStmt(MapleAllocator *alloc, VarMeExpr *theLhs, MeExpr *rhsVal) + : AssignMeStmt(OP_dassign, theLhs, rhsVal), chiList(std::less(), alloc->Adapter()) {} DassignMeStmt(MapleAllocator *alloc, const DassignMeStmt *dass) @@ -1609,8 +1616,6 @@ class DassignMeStmt : public AssignMeStmt { } MeExpr *GetLHSRef(bool excludeLocalRefVar); - - StmtNode &EmitStmt(SSATab &ssaTab); private: @@ -1939,8 +1944,14 @@ class AssignedPart { public: explicit AssignedPart(MapleAllocator *alloc) : mustDefList(alloc->Adapter()) {} - explicit AssignedPart(const MapleVector &mustDefList) - : mustDefList(mustDefList) {} + AssignedPart(MapleAllocator *alloc, MeStmt *defStmt, const MapleVector &mustDefList) + : mustDefList(alloc->Adapter()) { + for (auto &mustDef : mustDefList) { + auto newMustDefNode = alloc->GetMemPool()->New(mustDef); + newMustDefNode->SetBase(defStmt); + this->mustDefList.push_back(*newMustDefNode); + } + } virtual ~AssignedPart() = default; @@ -1975,7 +1986,7 @@ class CallMeStmt : public NaryMeStmt, public MuChiMePart, public AssignedPart { CallMeStmt(MapleAllocator *alloc, const CallMeStmt *cstmt) : NaryMeStmt(alloc, cstmt), MuChiMePart(alloc), - AssignedPart(cstmt->mustDefList), + AssignedPart(alloc, this, cstmt->mustDefList), puIdx(cstmt->GetPUIdx()) {} virtual ~CallMeStmt() = default; @@ -2093,7 +2104,7 @@ class IcallMeStmt : public NaryMeStmt, public MuChiMePart, public AssignedPart { IcallMeStmt(MapleAllocator *alloc, const IcallMeStmt *cstmt) : NaryMeStmt(alloc, cstmt), MuChiMePart(alloc), - AssignedPart(cstmt->mustDefList), + AssignedPart(alloc, this, cstmt->mustDefList), retTyIdx(cstmt->retTyIdx), stmtID(cstmt->stmtID) {} @@ -2189,7 +2200,7 @@ class IntrinsiccallMeStmt : public NaryMeStmt, public MuChiMePart, public Assign IntrinsiccallMeStmt(MapleAllocator *alloc, const IntrinsiccallMeStmt *intrn) : NaryMeStmt(alloc, intrn), MuChiMePart(alloc), - AssignedPart(intrn->mustDefList), + AssignedPart(alloc, this, intrn->mustDefList), intrinsic(intrn->GetIntrinsic()), tyIdx(intrn->tyIdx), retPType(intrn->retPType) {} @@ -2423,6 +2434,10 @@ class TryMeStmt : public MeStmt { offsets.push_back(curr); } + const MapleVector &GetOffsets() const { + return offsets; + } + StmtNode &EmitStmt(SSATab &ssaTab); private: diff --git a/src/mapleall/maple_me/include/me_loop_canon.h b/src/mapleall/maple_me/include/me_loop_canon.h index 0a7742c7f3715c0cc28d6f9e425e6f1a1e0edbba..b917fab6f9bb493c4562d1a0471f6549faa964a1 100644 --- a/src/mapleall/maple_me/include/me_loop_canon.h +++ b/src/mapleall/maple_me/include/me_loop_canon.h @@ -45,6 +45,7 @@ class MeDoLoopCanon : public MeFuncPhase { void SplitCondGotBB(MeFunction &func, LoopDesc &loop); void ExecuteLoopCanon(MeFunction &func, MeFuncResultMgr &m, Dominance &dom); void ExecuteLoopNormalization(MeFunction &func, MeFuncResultMgr *m, Dominance &dom); + void UpdateTheOffsetOfStmtWhenTargetBBIsChange(MeFunction &func, BB &curBB, const BB &oldSuccBB, BB &newSuccBB) const; }; } // namespace maple #endif // MAPLE_ME_INCLUDE_MELOOPCANON_H diff --git a/src/mapleall/maple_me/include/me_option.h b/src/mapleall/maple_me/include/me_option.h index abb8c0b13080c6cb958732409575dd79704d71b9..4e812748869fe722e31bb4e59f2cad5ffe68ddd5 100644 --- a/src/mapleall/maple_me/include/me_option.h +++ b/src/mapleall/maple_me/include/me_option.h @@ -120,6 +120,7 @@ class MeOption : public MapleDriverOptionBase { static bool placementRC; static bool subsumRC; static std::string inlineFuncList; + static bool meVerify; #if MIR_JAVA static std::string acquireFuncName; static std::string releaseFuncName; diff --git a/src/mapleall/maple_me/include/me_phases.def b/src/mapleall/maple_me/include/me_phases.def index ff881179ef024fcc3112abb181d9efbdf24c072d..53f926c404d617ce3847c50157dc0c4b80fbf9b0 100644 --- a/src/mapleall/maple_me/include/me_phases.def +++ b/src/mapleall/maple_me/include/me_phases.def @@ -46,6 +46,7 @@ FUNCTPHASE(MeFuncPhase_STOREPRE, MeDoStorePre) FUNCTPHASE(MeFuncPhase_STMTPRE, MeDoStmtPre) FUNCTPHASE(MeFuncPhase_SSARENAME2PREG, MeDoSSARename2Preg) FUNCTPHASE(MeFuncPhase_PREGRENAMER, MeDoPregRename) +FUNCAPHASE(MeFuncPhase_MEVERIFY, MeDoVerify) FUNCTPHASE(MeFuncPhase_INTRACONSTPROP, MeDoIntraConstProp) FUNCTPHASE(MeFuncPhase_INTERCONSTPROP, MeDoInterConstProp) #if MIR_JAVA diff --git a/src/mapleall/maple_me/include/me_verify.h b/src/mapleall/maple_me/include/me_verify.h new file mode 100644 index 0000000000000000000000000000000000000000..c08efe16c59fd2d52178f62dae4cece37f096fc2 --- /dev/null +++ b/src/mapleall/maple_me/include/me_verify.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) [2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * + * http://license.coscl.org.cn/MulanPSL + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v1 for more details. + */ +#ifndef MAPLE_ME_VERIFY_H +#define MAPLE_ME_VERIFY_H +#include "me_ir.h" +#include "me_phase.h" +#include "me_function.h" +#include "me_irmap.h" +#include "class_hierarchy.h" + +namespace maple { +void VerifyGlobalTypeTable(); + +class MeVerify { + public: + explicit MeVerify(MeFunction &func) : meFunc(func) {} + ~MeVerify() = default; + + void VerifyFunction(); + void VerifyPhiNode(const BB &bb, Dominance &dom) const; + + static bool enableDebug; + private: + void VerifySuccAndPredOfBB(const BB &bb) const; + void VerifyBBKind(const BB &bb) const; + void DealWithSpecialCase(const BB &currBB, const BB &tryBB) const; + void VerifyNestedTry(const BB &tryBB, const BB &currBB) const; + void VerifyAttrTryBB(BB &tryBB, int index); + void VerifyCondGotoBB(const BB &bb) const; + void VerifyGotoBB(const BB &bb) const; + void VerifyFallthruBB(const BB &bb) const; + void VerifyCommonExitBB() const; + bool IsOnlyHaveReturnOrThrowStmt(const BB &bb, Opcode op) const; + void VerifyReturnBB(const BB &bb) const; + void VerifySwitchBB(const BB &bb) const; + void VerifyPredBBOfSuccBB(const BB &bb, const MapleVector &succs) const; + + MeFunction &meFunc; +}; + +class MeDoVerify : public MeFuncPhase { + public: + explicit MeDoVerify(MePhaseID id) : MeFuncPhase(id) {} + ~MeDoVerify() = default; + + AnalysisResult *Run(MeFunction *func, MeFuncResultMgr *m, ModuleResultMgr*mrm) override; + std::string PhaseName() const override { + return "meverify"; + } +}; +} // namespace maple +#endif // MAPLE_ME_VERIFY_H diff --git a/src/mapleall/maple_me/src/me_alias_class.cpp b/src/mapleall/maple_me/src/me_alias_class.cpp index 9d1ad4f7ea015846bc492dc80d11ef4c2bec221c..a7cb64adc76f2baa498e9af20c56abcd8cf269d5 100644 --- a/src/mapleall/maple_me/src/me_alias_class.cpp +++ b/src/mapleall/maple_me/src/me_alias_class.cpp @@ -88,8 +88,7 @@ AnalysisResult *MeDoAliasClass::Run(MeFunction *func, MeFuncResultMgr *funcResMg MemPool *aliasClassMp = NewMemPool(); KlassHierarchy *kh = nullptr; if (func->GetMIRModule().IsJavaModule()) { - kh = static_cast(moduleResMgr->GetAnalysisResult( - MoPhase_CHA, &func->GetMIRModule())); + kh = static_cast(moduleResMgr->GetAnalysisResult(MoPhase_CHA, &func->GetMIRModule())); } MeAliasClass *aliasClass = aliasClassMp->New( *aliasClassMp, func->GetMIRModule(), *func->GetMeSSATab(), *func, MeOption::lessThrowAlias, diff --git a/src/mapleall/maple_me/src/me_bb_layout.cpp b/src/mapleall/maple_me/src/me_bb_layout.cpp index 8889fc86c00432d2be08188e9be9d2c863a29d4b..27f36d263b470fc36f711803f0989f2d421d892f 100644 --- a/src/mapleall/maple_me/src/me_bb_layout.cpp +++ b/src/mapleall/maple_me/src/me_bb_layout.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2019-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -421,6 +421,7 @@ void BBLayout::ResolveUnconditionalFallThru(BB &bb, BB &nextBB) { if (fallthru != &nextBB) { if (BBCanBeMoved(*fallthru, bb)) { AddBB(*fallthru); + SetAttrTryForTheCanBeMovedBB(bb, *fallthru); ResolveUnconditionalFallThru(*fallthru, nextBB); OptimizeBranchTarget(*fallthru); } else { @@ -469,11 +470,23 @@ void BBLayout::DealWithStartTryBB() { } else { curBB->RemoveAllSucc(); func.NullifyBBByID(curBB->GetBBId()); + for (auto it = layoutBBs.begin(); it != layoutBBs.end(); ++it) { + if (*it == curBB) { + layoutBBs.erase(it); + break; + } + } } break; } else if (j == size - 1) { curBB->RemoveAllSucc(); func.NullifyBBByID(curBB->GetBBId()); + for (auto it = layoutBBs.begin(); it != layoutBBs.end(); ++it) { + if (*it == curBB) { + layoutBBs.erase(it); + break; + } + } } } startTryBBVec[i] = false; @@ -509,6 +522,36 @@ void BBLayout::RemoveUnreachable(BB &bb) { } bb.RemoveAllSucc(); func.NullifyBBByID(bb.GetBBId()); + for (auto it = layoutBBs.begin(); it != layoutBBs.end(); ++it) { + if (*it == &bb) { + layoutBBs.erase(it); + break; + } + } +} + + +void BBLayout::UpdateNewBBWithAttrTry(const BB &bb, BB &fallthru) const { + auto tryBB = &bb; + fallthru.SetAttributes(kBBAttrIsTry); + if (bb.IsReturnBB()) { + int i = 1; + tryBB = func.GetBBFromID(bb.GetBBId() - i); + while (tryBB == nullptr || tryBB->IsReturnBB()) { + ++i; + tryBB = func.GetBBFromID(bb.GetBBId() - i); + } + ASSERT_NOT_NULL(tryBB); + ASSERT(tryBB->GetAttributes(kBBAttrIsTry), "must be try"); + } + bool setEHEdge = false; + for (auto *candCatch : tryBB->GetSucc()) { + if (candCatch != nullptr && candCatch->GetAttributes(kBBAttrIsCatch)) { + setEHEdge = true; + fallthru.AddSucc(*candCatch); + } + } + ASSERT(setEHEdge, "must set eh edge"); } // create a new fallthru that contains a goto to the original fallthru @@ -555,6 +598,7 @@ BB *BBLayout::CreateGotoBBAfterCondBB(BB &bb, BB &fallthru) { LogInfo::MapleLogger() << "Created fallthru and goto original fallthru" << '\n'; } AddBB(*newFallthru); + SetAttrTryForTheCanBeMovedBB(bb, *newFallthru); return newFallthru; } @@ -582,6 +626,17 @@ void BBLayout::OptimiseCFG() { } } +void BBLayout::SetAttrTryForTheCanBeMovedBB(BB &bb, BB &canBeMovedBB) const { + if (bb.GetAttributes(kBBAttrIsTryEnd)) { + bb.ClearAttributes(kBBAttrIsTryEnd); + canBeMovedBB.SetAttributes(kBBAttrIsTryEnd); + func.SetTryBBByOtherEndTryBB(&canBeMovedBB, &bb); + } + if (bb.GetAttributes(kBBAttrIsTry) && !canBeMovedBB.GetAttributes(kBBAttrIsTry)) { + UpdateNewBBWithAttrTry(bb, canBeMovedBB); + } +} + void BBLayout::LayoutWithoutProf() { BB *bb = func.GetFirstBB(); while (bb != nullptr) { @@ -627,12 +682,21 @@ void BBLayout::LayoutWithoutProf() { condGotoNode.SetOffset(fallthruLabel); condGotoNode.SetOpCode((condGotoNode.GetOpCode() == OP_brtrue) ? OP_brfalse : OP_brtrue); } + // The offset of condgotostmt must be the label of second succ bb. + ASSERT(bb->GetSucc(0)->GetBBId() == fallthru->GetBBId(), "must be the fallthru"); + ASSERT(bb->GetSucc(1)->GetBBId() == brTargetBB->GetBBId(), "must be the brTargetBB"); + bb->SetSucc(0, brTargetBB); + bb->SetSucc(1, fallthru); + ASSERT(bb->GetSucc(1)->GetBBLabel() == static_cast(bb->GetMeStmts().back()).GetOffset(), + "bbLayout: wrong branch target BB"); AddBB(*brTargetBB); + SetAttrTryForTheCanBeMovedBB(*bb, *brTargetBB); ResolveUnconditionalFallThru(*brTargetBB, *nextBB); OptimizeBranchTarget(*brTargetBB); } else if (fallthru != nextBB) { if (BBCanBeMoved(*fallthru, *bb)) { AddBB(*fallthru); + SetAttrTryForTheCanBeMovedBB(*bb, *fallthru); ResolveUnconditionalFallThru(*fallthru, *nextBB); OptimizeBranchTarget(*fallthru); } else { @@ -648,6 +712,7 @@ void BBLayout::LayoutWithoutProf() { if (gotoTarget != nextBB && BBCanBeMoved(*gotoTarget, *bb)) { AddBB(*gotoTarget); + SetAttrTryForTheCanBeMovedBB(*bb, *gotoTarget); ChangeToFallthruFromGoto(*bb); ResolveUnconditionalFallThru(*gotoTarget, *nextBB); OptimizeBranchTarget(*gotoTarget); @@ -655,9 +720,11 @@ void BBLayout::LayoutWithoutProf() { BB *targetNext = gotoTarget->GetSucc().front(); if (targetNext != nextBB && BBCanBeMoved(*targetNext, *bb)) { AddBB(*gotoTarget); + SetAttrTryForTheCanBeMovedBB(*bb, *gotoTarget); ChangeToFallthruFromGoto(*bb); OptimizeBranchTarget(*gotoTarget); AddBB(*targetNext); + SetAttrTryForTheCanBeMovedBB(*bb, *targetNext); ResolveUnconditionalFallThru(*targetNext, *nextBB); OptimizeBranchTarget(*targetNext); } diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index 40e5d3c49aa245a89c32e6b4a58b37587829e3a8..a2a25998b4641ebd916e4ad2c55bf04327dfe436 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -761,13 +761,15 @@ void MeCFG::ConvertMePhiList2IdentityAssigns(BB &meBB) const { const OriginalSt *ost = func.GetMeSSATab()->GetOriginalStFromID(phiIt->first); if (ost->IsSymbolOst() && ost->GetIndirectLev() == 0) { MePhiNode *varPhi = phiIt->second; - auto *dassign = func.GetIRMap()->NewInPool(static_cast(varPhi->GetLHS()), varPhi->GetOpnd(0)); + auto *dassign = func.GetIRMap()->NewInPool( + static_cast(varPhi->GetLHS()), varPhi->GetOpnd(0)); dassign->SetBB(varPhi->GetDefBB()); dassign->SetIsLive(varPhi->GetIsLive()); meBB.PrependMeStmt(dassign); } else if (ost->IsPregOst()) { MePhiNode *regPhi = phiIt->second; - auto *regAss = func.GetIRMap()->New(OP_regassign, static_cast(regPhi->GetLHS()), regPhi->GetOpnd(0)); + auto *regAss = func.GetIRMap()->New( + OP_regassign, static_cast(regPhi->GetLHS()), regPhi->GetOpnd(0)); regAss->SetBB(regPhi->GetDefBB()); regAss->SetIsLive(regPhi->GetIsLive()); meBB.PrependMeStmt(regAss); diff --git a/src/mapleall/maple_me/src/me_critical_edge.cpp b/src/mapleall/maple_me/src/me_critical_edge.cpp index 20f11e559cc5f95c88865864ad37ebdec8497ad9..f7010caa31a1e1fabcf8832d42f2a1479a8cc96a 100644 --- a/src/mapleall/maple_me/src/me_critical_edge.cpp +++ b/src/mapleall/maple_me/src/me_critical_edge.cpp @@ -32,13 +32,30 @@ // newbb is always appended at the end of bb_vec_ and pred/succ will be updated. // The bblayout phase will determine the final layout order of the bbs. namespace maple { -void MeDoSplitCEdge::UpdateNewBBInTry(BB &newBB, const BB &pred) const { +// This function is used to find the eh edge when predBB is tryBB. +void MeDoSplitCEdge::UpdateNewBBInTry(MeFunction &func, BB &newBB, const BB &pred) const { + auto tryBB = &pred; newBB.SetAttributes(kBBAttrIsTry); - for (auto *candCatch : pred.GetSucc()) { + // The bb which is returnBB and only have return stmt would not have eh edge, + // so need find a try bb which have eh edge continue. + if (pred.IsReturnBB()) { + int i = 1; + tryBB = func.GetBBFromID(newBB.GetBBId() - i); + while (tryBB == nullptr || tryBB->IsReturnBB()) { + ++i; + tryBB = func.GetBBFromID(newBB.GetBBId() - i); + } + ASSERT_NOT_NULL(tryBB); + ASSERT(tryBB->GetAttributes(kBBAttrIsTry), "must be try"); + } + bool setEHEdge = false; + for (auto *candCatch : tryBB->GetSucc()) { if (candCatch != nullptr && candCatch->GetAttributes(kBBAttrIsCatch)) { + setEHEdge = true; newBB.AddSucc(*candCatch); } } + ASSERT(setEHEdge, "must set eh edge"); } void MeDoSplitCEdge::UpdateGotoLabel(BB &newBB, MeFunction &func, BB &pred, BB &succ) const { @@ -79,6 +96,21 @@ void MeDoSplitCEdge::UpdateCaseLabel(BB &newBB, MeFunction &func, BB &pred, BB & } } +void MeDoSplitCEdge::DealWithTryBB(MeFunction &func, BB &pred, BB &succ, BB *&newBB, bool &isInsertAfterPred) const { + if (!succ.GetStmtNodes().empty() && succ.GetStmtNodes().front().GetOpCode() == OP_try) { + newBB = &func.InsertNewBasicBlock(pred, false); + isInsertAfterPred = true; + if (pred.GetAttributes(kBBAttrIsTryEnd)) { + newBB->SetAttributes(kBBAttrIsTryEnd); + pred.ClearAttributes(kBBAttrIsTryEnd); + func.SetTryBBByOtherEndTryBB(newBB, &pred); + } + } else { + newBB = &func.InsertNewBasicBlock(succ); + isInsertAfterPred = false; + } +} + void MeDoSplitCEdge::BreakCriticalEdge(MeFunction &func, BB &pred, BB &succ) const { if (DEBUGFUNC(&func)) { LogInfo::MapleLogger() << "******before break : critical edge : BB" << pred.GetBBId() << " -> BB" << @@ -90,6 +122,8 @@ void MeDoSplitCEdge::BreakCriticalEdge(MeFunction &func, BB &pred, BB &succ) con // create newBB and set pred/succ BB *newBB = nullptr; // use replace instead of remove/add to keep position in pred/succ + bool isInsertAfterPred = false; + bool needUpdateTryAttr = true; size_t index = succ.GetPred().size(); if (&pred == func.GetCommonEntryBB()) { newBB = &func.InsertNewBasicBlock(*func.GetFirstBB()); @@ -97,8 +131,14 @@ void MeDoSplitCEdge::BreakCriticalEdge(MeFunction &func, BB &pred, BB &succ) con succ.ClearAttributes(kBBAttrIsEntry); pred.RemoveEntry(succ); pred.AddEntry(*newBB); + needUpdateTryAttr = false; } else { - newBB = func.NewBasicBlock(); + if (pred.GetAttributes(kBBAttrIsTry)) { + DealWithTryBB(func, pred, succ, newBB, isInsertAfterPred); + } else { + newBB = func.NewBasicBlock(); + needUpdateTryAttr = false; + } while (index > 0) { if (succ.GetPred(index - 1) == &pred) { break; @@ -114,8 +154,12 @@ void MeDoSplitCEdge::BreakCriticalEdge(MeFunction &func, BB &pred, BB &succ) con newBB->SetKind(kBBFallthru); // default kind newBB->SetAttributes(kBBAttrArtificial); - if (pred.GetAttributes(kBBAttrIsTry)) { - UpdateNewBBInTry(*newBB, pred); + if (needUpdateTryAttr && isInsertAfterPred && pred.GetAttributes(kBBAttrIsTry)) { + UpdateNewBBInTry(func, *newBB, pred); + } + if (needUpdateTryAttr && !isInsertAfterPred && succ.GetAttributes(kBBAttrIsTry) && + (succ.GetStmtNodes().empty() || succ.GetStmtNodes().front().GetOpCode() != OP_try)) { + UpdateNewBBInTry(func, *newBB, succ); } // update statement offset if succ is goto target if (pred.GetKind() == kBBCondGoto) { diff --git a/src/mapleall/maple_me/src/me_function.cpp b/src/mapleall/maple_me/src/me_function.cpp index 0bca6e30ef7409809d8fa3804c8fe782386077b2..961bad39f469f60dad71fe7bff2f15db0738db00 100644 --- a/src/mapleall/maple_me/src/me_function.cpp +++ b/src/mapleall/maple_me/src/me_function.cpp @@ -506,12 +506,16 @@ BB *MeFunction::NewBasicBlock() { return newBB; } -// new a basic block and insert before position -BB &MeFunction::InsertNewBasicBlock(const BB &position) { +// new a basic block and insert before position or after position +BB &MeFunction::InsertNewBasicBlock(const BB &position, bool isInsertBefore) { BB *newBB = memPool->New(&alloc, &versAlloc, BBId(nextBBId++)); auto bIt = std::find(begin(), end(), &position); auto idx = position.GetBBId(); + if (!isInsertBefore) { + ++bIt; + ++idx; + } auto newIt = bbVec.insert(bIt, newBB); auto eIt = end(); // update bb's idx diff --git a/src/mapleall/maple_me/src/me_gc_lowering.cpp b/src/mapleall/maple_me/src/me_gc_lowering.cpp index 1ac38a8decb757538699b8eb89048ac36babcdf3..12d47d9cc4baf3236fd7a2f73158370119c6ed87 100644 --- a/src/mapleall/maple_me/src/me_gc_lowering.cpp +++ b/src/mapleall/maple_me/src/me_gc_lowering.cpp @@ -101,7 +101,14 @@ void GCLowering::HandleVarAssignMeStmt(MeStmt &stmt) { } MIRIntrinsicID GCLowering::SelectWriteBarrier(MeStmt &stmt) { - MeExpr *lhs = stmt.GetLHS(); + MeExpr *lhs = nullptr; + if (stmt.GetOp() == OP_dassign) { + lhs = stmt.GetLHS(); + } else if (stmt.GetOp() == OP_iassign) { + lhs = static_cast(stmt).GetLHSVal(); + } else { + CHECK_FATAL(false, "NIY"); + } CHECK_NULL_FATAL(lhs); MeExprOp meOp = lhs->GetMeOp(); CHECK_FATAL((meOp == kMeOpVar || meOp == kMeOpIvar), "Not Expected meOp"); diff --git a/src/mapleall/maple_me/src/me_loop_canon.cpp b/src/mapleall/maple_me/src/me_loop_canon.cpp index 50d4644d19e846f6a50707b28b9a65fb49f10980..c0d799c4a8fd4261a347f68d22b1f2a283613664 100644 --- a/src/mapleall/maple_me/src/me_loop_canon.cpp +++ b/src/mapleall/maple_me/src/me_loop_canon.cpp @@ -300,6 +300,31 @@ void MeDoLoopCanon::FindHeadBBs(MeFunction &func, Dominance &dom, const BB *bb) } } +void MeDoLoopCanon::UpdateTheOffsetOfStmtWhenTargetBBIsChange(MeFunction &func, BB &curBB, + const BB &oldSuccBB, BB &newSuccBB) const { + StmtNode *lastStmt = &(curBB.GetStmtNodes().back()); + if ((lastStmt->GetOpCode() == OP_brtrue || lastStmt->GetOpCode() == OP_brfalse) && + static_cast(lastStmt)->GetOffset() == oldSuccBB.GetBBLabel()) { + LabelIdx label = func.GetOrCreateBBLabel(newSuccBB); + static_cast(lastStmt)->SetOffset(label); + } else if (lastStmt->GetOpCode() == OP_goto && + static_cast(lastStmt)->GetOffset() == oldSuccBB.GetBBLabel()) { + LabelIdx label = func.GetOrCreateBBLabel(newSuccBB); + static_cast(lastStmt)->SetOffset(label); + } else if (lastStmt->GetOpCode() == OP_switch) { + SwitchNode *switchNode = static_cast(lastStmt); + if (switchNode->GetDefaultLabel() == oldSuccBB.GetBBLabel()) { + switchNode->SetDefaultLabel(func.GetOrCreateBBLabel(newSuccBB)); + } + for (size_t i = 0; i < switchNode->GetSwitchTable().size(); ++i) { + LabelIdx labelIdx = switchNode->GetCasePair(i).second; + if (labelIdx == oldSuccBB.GetBBLabel()) { + switchNode->UpdateCaseLabelAt(i, func.GetOrCreateBBLabel(newSuccBB)); + } + } + } +} + // merge backedges with the same headBB void MeDoLoopCanon::Merge(MeFunction &func) { for (auto iter = heads.begin(); iter != heads.end(); ++iter) { @@ -312,34 +337,7 @@ void MeDoLoopCanon::Merge(MeFunction &func) { if (tail->GetStmtNodes().empty()) { continue; } - if (tail->GetKind() == kBBCondGoto) { - CondGotoNode &condGotoNode = static_cast(tail->GetStmtNodes().back()); - LabelIdx oldlabIdx = condGotoNode.GetOffset(); - if (oldlabIdx == head->GetBBLabel()) { - LabelIdx label = func.GetOrCreateBBLabel(*latchBB); - condGotoNode.SetOffset(label); - } - } else if (tail->GetKind() == kBBGoto) { - GotoNode &gotoStmt = static_cast(tail->GetStmtNodes().back()); - LabelIdx oldlabIdx = gotoStmt.GetOffset(); - if (oldlabIdx == head->GetBBLabel()) { - LabelIdx label = func.GetOrCreateBBLabel(*latchBB); - gotoStmt.SetOffset(label); - } - } else if (tail->GetKind() == kBBSwitch) { - SwitchNode &switchNode = static_cast(tail->GetStmtNodes().back()); - if (switchNode.GetDefaultLabel() == head->GetBBLabel()) { - switchNode.SetDefaultLabel(func.GetOrCreateBBLabel(*latchBB)); - } - for (size_t i = 0; i < switchNode.GetSwitchTable().size(); ++i) { - LabelIdx labelIdx = switchNode.GetCasePair(i).second; - if (labelIdx == head->GetBBLabel()) { - switchNode.UpdateCaseLabelAt(i, func.GetOrCreateBBLabel(*latchBB)); - } - } - } else if (tail->GetKind() != kBBFallthru) { - CHECK_FATAL(false, "can not support"); - } + UpdateTheOffsetOfStmtWhenTargetBBIsChange(func, *tail, *head, *latchBB); } head->AddPred(*latchBB); } @@ -372,34 +370,7 @@ void MeDoLoopCanon::AddPreheader(MeFunction &func) { if (pred->GetStmtNodes().empty()) { continue; } - if (pred->GetKind() == kBBCondGoto) { - CondGotoNode &condGotoNode = static_cast(pred->GetStmtNodes().back()); - LabelIdx oldlabIdx = condGotoNode.GetOffset(); - if (oldlabIdx == head->GetBBLabel()) { - LabelIdx label = func.GetOrCreateBBLabel(*preheader); - condGotoNode.SetOffset(label); - } - } else if (pred->GetKind() == kBBGoto) { - GotoNode &gotoStmt = static_cast(pred->GetStmtNodes().back()); - LabelIdx oldlabIdx = gotoStmt.GetOffset(); - if (oldlabIdx == head->GetBBLabel()) { - LabelIdx label = func.GetOrCreateBBLabel(*preheader); - gotoStmt.SetOffset(label); - } - } else if (pred->GetKind() == kBBSwitch) { - SwitchNode &switchNode = static_cast(pred->GetStmtNodes().back()); - if (switchNode.GetDefaultLabel() == head->GetBBLabel()) { - switchNode.SetDefaultLabel(func.GetOrCreateBBLabel(*preheader)); - } - for (size_t i = 0; i < switchNode.GetSwitchTable().size(); ++i) { - LabelIdx labelIdx = switchNode.GetCasePair(i).second; - if (labelIdx == head->GetBBLabel()) { - switchNode.UpdateCaseLabelAt(i, func.GetOrCreateBBLabel(*preheader)); - } - } - } else if (pred->GetKind() != kBBFallthru) { - CHECK_FATAL(false, "can not support"); - } + UpdateTheOffsetOfStmtWhenTargetBBIsChange(func, *pred, *head, *preheader); } head->AddPred(*preheader); } @@ -435,16 +406,7 @@ void MeDoLoopCanon::InsertNewExitBB(MeFunction &func, LoopDesc &loop) { if (curBB->GetStmtNodes().empty()) { continue; } - StmtNode *lastStmt = &(curBB->GetStmtNodes().back()); - if ((lastStmt->GetOpCode() == OP_brtrue || lastStmt->GetOpCode() == OP_brfalse) && - static_cast(lastStmt)->GetOffset() == succBB->GetBBLabel()) { - LabelIdx label = func.GetOrCreateBBLabel(*newExitBB); - static_cast(lastStmt)->SetOffset(label); - } else if (lastStmt->GetOpCode() == OP_goto && - static_cast(lastStmt)->GetOffset() == succBB->GetBBLabel()) { - LabelIdx label = func.GetOrCreateBBLabel(*newExitBB); - static_cast(lastStmt)->SetOffset(label); - } + UpdateTheOffsetOfStmtWhenTargetBBIsChange(func, *curBB, *succBB, *newExitBB); } } } diff --git a/src/mapleall/maple_me/src/me_option.cpp b/src/mapleall/maple_me/src/me_option.cpp index 12a11a2182b3b1630d03c21ff9923304536de8c7..90b68394a8e15fff27a67428bcf124ada9fb2b29 100644 --- a/src/mapleall/maple_me/src/me_option.cpp +++ b/src/mapleall/maple_me/src/me_option.cpp @@ -94,6 +94,7 @@ bool MeOption::enableEA = false; bool MeOption::placementRC = false; bool MeOption::subsumRC = false; std::string MeOption::inlineFuncList = ""; +bool MeOption::meVerify = false; #if MIR_JAVA std::string MeOption::acquireFuncName = "Landroid/location/LocationManager;|requestLocationUpdates|"; std::string MeOption::releaseFuncName = "Landroid/location/LocationManager;|removeUpdates|"; @@ -197,6 +198,7 @@ enum OptionIndex { kMeInlineHint, kMeThreads, kMeIgnoreInferredRetType, + kMeVerify, }; const Descriptor kUsage[] = { @@ -914,6 +916,15 @@ const Descriptor kUsage[] = { " --no-ignore-inferred-ret-type\tDo not ignore func return type inferred by ssadevirt\n", "me", {} }, + { kMeVerify, + kEnable, + "", + "meverify", + kBuildTypeProduct, + kArgCheckPolicyNone, + " --meverify \tenable meverify features\n", + "me", + {}}, #if MIR_JAVA { kMeAcquireFunc, 0, @@ -1298,6 +1309,9 @@ bool MeOption::SolveOptions(const std::vector &opts, bool i case kMeIgnoreInferredRetType: ignoreInferredRetType = (opt.Type() == kEnable); break; + case kMeVerify: + meVerify = (opt.Type() == kEnable); + break; #if MIR_JAVA case kMeAcquireFunc: acquireFuncName = opt.Args(); diff --git a/src/mapleall/maple_me/src/me_phase_manager.cpp b/src/mapleall/maple_me/src/me_phase_manager.cpp index 18343daf1be641a6599a5fa64c1fee9209b5e4f6..752c0aa6429ae7301791028d646e10f7e87722f6 100644 --- a/src/mapleall/maple_me/src/me_phase_manager.cpp +++ b/src/mapleall/maple_me/src/me_phase_manager.cpp @@ -67,6 +67,7 @@ #include "me_ssa_tab.h" #include "mpl_timer.h" #include "constantfold.h" +#include "me_verify.h" #define JAVALANG (mirModule.IsJavaModule()) @@ -139,6 +140,7 @@ void MeFuncPhaseManager::AddPhases(const std::unordered_set &skipPh addPhase("rclowering"); addPhase("bblayout"); addPhase("emit"); + addPhase("meverify"); } } diff --git a/src/mapleall/maple_me/src/me_placement_rc.cpp b/src/mapleall/maple_me/src/me_placement_rc.cpp index 143f7f704c3f26b4e5e1b23645f0d4a994207449..7af2d23b779aa5eea77fd02949759ab27d6949a6 100644 --- a/src/mapleall/maple_me/src/me_placement_rc.cpp +++ b/src/mapleall/maple_me/src/me_placement_rc.cpp @@ -92,7 +92,8 @@ void PlacementRC::HandleThrowOperand(SRealOcc &realOcc, ThrowMeStmt &thwStmt) { } // Generate a copy to tempVar and regard this as the last use of workCand - DassignMeStmt *newDass = static_cast(irMap->CreateAssignMeStmt(*tempVar, *realOcc.GetVar(), realOcc.GetBB())); + DassignMeStmt *newDass = + static_cast(irMap->CreateAssignMeStmt(*tempVar, *realOcc.GetVar(), realOcc.GetBB())); newDass->SetSrcPos(thwStmt.GetSrcPosition()); newDass->EnableNeedDecref(); tempVar->SetDefByStmt(*newDass); @@ -596,7 +597,8 @@ void PlacementRC::CodeMotionForReal(SOcc &occ, const UnaryMeStmt *entryIncref) { if (realOcc.GetVar()->PointsToStringLiteral()) { MeExpr *zeroExpr = irMap->CreateIntConstMeExpr(0, realOcc.GetVar()->GetPrimType()); VarMeExpr *newVar = irMap->CreateVarMeExprVersion(*realOcc.GetVar()); - DassignMeStmt *newstmt = static_cast(irMap->CreateAssignMeStmt(*newVar, *zeroExpr, realOcc.GetBB())); + DassignMeStmt *newstmt = + static_cast(irMap->CreateAssignMeStmt(*newVar, *zeroExpr, realOcc.GetBB())); realOcc.GetBB().ReplaceMeStmt(decrefStmt, newstmt); return; } diff --git a/src/mapleall/maple_me/src/me_rename2preg.cpp b/src/mapleall/maple_me/src/me_rename2preg.cpp index e25a2e2530b0e0ad4a101df7ef0a2eea0abacf20..c5391fb10c1c740e8778ca9908bf1b43c8ba795c 100644 --- a/src/mapleall/maple_me/src/me_rename2preg.cpp +++ b/src/mapleall/maple_me/src/me_rename2preg.cpp @@ -135,6 +135,7 @@ void SSARename2Preg::UpdateRegPhi(MePhiNode *mevarphinode, MePhiNode *regphinode } regphinode->GetOpnds().push_back(opndtemp); } + regphinode->GetDefBB()->GetMePhiList().insert(std::make_pair(regphinode->GetLHS()->GetOstIdx(), regphinode)); (void)lhs; } @@ -146,6 +147,8 @@ void SSARename2Preg::Rename2PregPhi(MePhiNode *mevarphinode, MapleMapCreateMePhi(*lhsreg); regphinode->SetDefBB(mevarphinode->GetDefBB()); UpdateRegPhi(mevarphinode, regphinode, lhsreg, lhs); + regphinode->SetIsLive(mevarphinode->GetIsLive()); + mevarphinode->SetIsLive(false); (void)regPhiList.insert(std::make_pair(lhsreg->GetOst()->GetIndex(), regphinode)); } } diff --git a/src/mapleall/maple_me/src/me_ssa_lpre.cpp b/src/mapleall/maple_me/src/me_ssa_lpre.cpp index 5a5906e50b597b2109287d323848d813e872817c..aea8a2e7fe2a683fd77a199c7c6466b34a6d3ddf 100644 --- a/src/mapleall/maple_me/src/me_ssa_lpre.cpp +++ b/src/mapleall/maple_me/src/me_ssa_lpre.cpp @@ -62,7 +62,8 @@ void MeSSALPre::GenerateSaveRealOcc(MeRealOcc &realOcc) { // to this statement in order to get to the rhs expression; // this assume AssignMeStmt has smaller size then DassignMeStmt and // MaydassignMeStmt - AssignMeStmt *rass = new (realOcc.GetMeStmt()) AssignMeStmt(OP_regassign, static_cast(regOrVar), savedRHS); + auto *rass = + new (realOcc.GetMeStmt()) AssignMeStmt(OP_regassign, static_cast(regOrVar), savedRHS); rass->SetSrcPos(savedSrcPos); rass->SetBB(savedBB); rass->SetPrev(savedPrev); diff --git a/src/mapleall/maple_me/src/me_stmt_pre.cpp b/src/mapleall/maple_me/src/me_stmt_pre.cpp index 574c3771d3601ee1521e78f26a1a091d67582e2e..549a8d98f1a0c85a25e4d678116f3595f6182e4d 100644 --- a/src/mapleall/maple_me/src/me_stmt_pre.cpp +++ b/src/mapleall/maple_me/src/me_stmt_pre.cpp @@ -124,7 +124,10 @@ void MeStmtPre::CodeMotion() { (void)candsForSSAUpdate[ostIdx]->insert(occ->GetBB()->GetBBId()); } VarMeExpr *newVarVersion = irMap->CreateVarMeExprVersion(*var); - call->GetMustDefList()->front().UpdateLHS(*newVarVersion); + auto &mustDef = call->GetMustDefList()->front(); + mustDef.UpdateLHS(*newVarVersion); + newVarVersion->SetDefBy(kDefByMustDef); + newVarVersion->SetDefMustDef(mustDef); } } if (insertedOcc->GetOpcodeOfMeStmt() == OP_intrinsiccallwithtype && diff --git a/src/mapleall/maple_me/src/me_verify.cpp b/src/mapleall/maple_me/src/me_verify.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c48071e8086668f7d14de561ac344839005d7355 --- /dev/null +++ b/src/mapleall/maple_me/src/me_verify.cpp @@ -0,0 +1,528 @@ +/* + * Copyright (c) [2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * + * http://license.coscl.org.cn/MulanPSL + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v1 for more details. + */ +#include "me_verify.h" +#include "me_cfg.h" +#include "me_dominance.h" + +namespace maple { +bool MeVerify::enableDebug = false; + +void MeVerify::VerifyFunction() { + if (enableDebug) { + LogInfo::MapleLogger() << meFunc.GetName() << "\n"; + } + VerifyCommonExitBB(); + int i = 0; + for (auto &bb : meFunc.GetLaidOutBBs()) { + ++i; + if (bb->GetSucc().empty() && bb->GetPred().empty()) { + continue; + } + if (bb->GetPred().empty() && !bb->GetAttributes(kBBAttrIsEntry)) { + continue; + } + VerifyBBKind(*bb); + VerifySuccAndPredOfBB(*bb); + if (bb->GetAttributes(kBBAttrIsTry) && !bb->GetMeStmts().empty() && + bb->GetMeStmts().front().GetOp() == OP_try) { + VerifyAttrTryBB(*bb, i - 1); + } + } +} + +void DealWithPoninterType(const MIRType &type, std::string &str); + +void AddTypeKindToStr(const MIRType &type, std::string &str) { + if (type.GetKind() != kTypeClass && type.GetKind() != kTypeStruct && type.GetKind() != kTypeInterface && + type.GetKind() != kTypeClassIncomplete && type.GetKind() != kTypeStructIncomplete && + type.GetKind() != kTypeInterfaceIncomplete) { + str += "_" + std::to_string(type.GetKind()); + } +} + +void DealWithFuncType(const MIRType &type, std::string &str) { + auto funcType = static_cast(type); + str += "_" + std::to_string(funcType.GetRetTyIdx().GetIdx()); + str += "_" + std::to_string(funcType.IsVarargs()); + for (auto &item : funcType.GetParamTypeList()) { + str += "_" + std::to_string(item.GetIdx()); + } + for (auto &item : funcType.GetParamAttrsList()) { + str += "_" + std::to_string(item.GetAttrFlag()) + std::to_string(item.GetAlignValue()); + } +} + +void GetAttrOfType(const MIRType &type, std::string &str) { + str += "_" + std::to_string(type.GetPrimType()); + AddTypeKindToStr(type, str); + switch (type.GetKind()) { + case kTypePointer: { + DealWithPoninterType(type, str); + break; + } + case kTypeFArray: + case kTypeJArray: { + auto farrayType = static_cast(type); + GetAttrOfType(*farrayType.GetElemType(), str); + break; + } + case kTypeArray: { + auto arryType = static_cast(type); + for (size_t i = 0; i < arryType.GetDim(); ++i) { + str += "_" + std::to_string(arryType.GetSizeArrayItem(i)); + break; + } + GetAttrOfType(*arryType.GetElemType(), str); + break; + } + case kTypeBitField: { + str += "_" + std::to_string(static_cast(type).GetFieldSize()); + break; + } + case kTypeFunction: { + DealWithFuncType(type, str); + break; + } + case kTypeInstantVector: { + for (auto &item : static_cast(type).GetInstantVec()) { + str += "_" + std::to_string(item.first.GetIdx()); + str += "_" + std::to_string(item.second.GetIdx()); + } + break; + } + case kTypeGenericInstant: { + str += "_" + std::to_string(static_cast(type).GetGenericTyIdx()); + break; + } + case kTypeByName: { + str += "_" + std::to_string(type.IsNameIsLocal()); + break; + } + default: + break; + } +} + +void DealWithPoninterType(const MIRType &type, std::string &str) { + auto ptrType = static_cast(type); + str += "_" + std::to_string(ptrType.GetTypeAttrs().GetAlignValue()) + "_" + + std::to_string(ptrType.GetTypeAttrs().GetAttrFlag()); + GetAttrOfType(*ptrType.GetPointedType(), str); +} + +// The type must exited in typeHashTable, ptrTypeTable or refTypeTable. +bool FindTypeInOtherTable(MIRType &mirType) { + const auto &typeHashTable = GlobalTables::GetTypeTable().GetTypeHashTable(); + const auto &ptrTypeTable = GlobalTables::GetTypeTable().GetPtrTypeMap(); + const auto &refTypeTable = GlobalTables::GetTypeTable().GetRefTypeMap(); + if (typeHashTable.find(&mirType) != typeHashTable.end()) { + return true; + } + bool inTypeHash = false; + for (auto &iter : typeHashTable) { + if (iter->GetTypeIndex() == mirType.GetTypeIndex()) { + inTypeHash = true; + } + } + if (inTypeHash) { + return true; + } + if (mirType.IsMIRPtrType() && + ptrTypeTable.find(static_cast(mirType).GetPointedTyIdx()) != ptrTypeTable.end()) { + return true; + } + if (mirType.IsMIRPtrType() && + refTypeTable.find(static_cast(mirType).GetPointedTyIdx()) != refTypeTable.end()) { + return true; + } + return false; +} + +void FindTypeInTypeTable() { + const auto &typeHashTable = GlobalTables::GetTypeTable().GetTypeHashTable(); + const auto &ptrTypeTable = GlobalTables::GetTypeTable().GetPtrTypeMap(); + const auto &refTypeTable = GlobalTables::GetTypeTable().GetRefTypeMap(); + std::set tyIdxs; + for (auto &iter : typeHashTable) { + if (GlobalTables::GetTypeTable().GetTypeFromTyIdx(iter->GetTypeIndex()) == nullptr) { + CHECK_FATAL(false, "%s %d is not exit in typeTable", + iter->GetMplTypeName().c_str(), iter->GetTypeIndex().GetIdx()); + } + size_t size = tyIdxs.size(); + tyIdxs.insert(iter->GetTypeIndex()); + if (tyIdxs.size() == size) { + CHECK_FATAL(false, "%s %d repeated in typeHashTable", + iter->GetMplTypeName().c_str(), iter->GetTypeIndex().GetIdx()); + } + } + tyIdxs.clear(); + for (auto &iter : ptrTypeTable) { + if (GlobalTables::GetTypeTable().GetTypeFromTyIdx(iter.first) == nullptr) { + CHECK_FATAL(false, "%d is not exit in typeTable", iter.first.GetIdx()); + } + size_t size = tyIdxs.size(); + tyIdxs.insert(iter.first); + if (tyIdxs.size() == size) { + CHECK_FATAL(false, "%d repeated in ptrTypeTable", iter.first.GetIdx()); + } + } + tyIdxs.clear(); + for (auto &iter : refTypeTable) { + if (GlobalTables::GetTypeTable().GetTypeFromTyIdx(iter.first) == nullptr) { + CHECK_FATAL(false, "%d is not exit in typeTable", iter.first.GetIdx()); + } + size_t size = tyIdxs.size(); + tyIdxs.insert(iter.first); + if (tyIdxs.size() == size) { + CHECK_FATAL(false, "%d is repeated in refTypeTable", iter.first.GetIdx()); + } + } +} + +void VerifyGlobalTypeTable() { + const auto &typeTable = GlobalTables::GetTypeTable().GetTypeTable(); + const auto &typeHashTable = GlobalTables::GetTypeTable().GetTypeHashTable(); + const auto &ptrTypeTable = GlobalTables::GetTypeTable().GetPtrTypeMap(); + const auto &refTypeTable = GlobalTables::GetTypeTable().GetRefTypeMap(); + FindTypeInTypeTable(); + auto sizeOfMIRTypes = typeHashTable.size() + ptrTypeTable.size() + refTypeTable.size(); + // nullptr and struct mirtype classmeta in typetable but not in other tables. + if (sizeOfMIRTypes != typeTable.size() - 1) { + if (MeVerify::enableDebug) { + LogInfo::MapleLogger() << typeTable.size() << " " << typeHashTable.size() << " " << ptrTypeTable.size() << " " << + refTypeTable.size() << " " << (typeHashTable.size() + ptrTypeTable.size() + refTypeTable.size()) << "\n"; + } + CHECK_FATAL(false, "verify failed, sizeOfMIRTypes: %d, typeTable.size(): %d", sizeOfMIRTypes, typeTable.size()); + } + int i = 0; + std::set primTypeAndTypeName; + std::set tyIdxs; + for (auto &mirType : typeTable) { + if (mirType == nullptr) { + continue; + } + size_t idx = tyIdxs.size(); + tyIdxs.insert(mirType->GetTypeIndex()); + CHECK_FATAL(idx != tyIdxs.size(), "the same tyidx in type table"); + size_t size = primTypeAndTypeName.size(); + std::string currName = mirType->GetMplTypeName(); + GetAttrOfType(*mirType, currName); + primTypeAndTypeName.insert(currName); + if (MeVerify::enableDebug) { + LogInfo::MapleLogger() << currName << "\n"; + } + if (size == primTypeAndTypeName.size()) { + ++i; + CHECK_FATAL(false, "the type has been created %s %d", currName.c_str(), mirType->GetTypeIndex().GetIdx()); + } + if (FindTypeInOtherTable(*mirType)) { + continue; + } + if (mirType->GetMplTypeName().find(namemangler::kClassMetadataTypeName) != std::string::npos) { + continue; + } + CHECK_FATAL(false, "%d %s is in typetable,", mirType->GetTypeIndex().GetIdx(), mirType->GetMplTypeName().c_str()); + } + // the first elem of type table is nullptr + CHECK_FATAL(tyIdxs.size() == typeTable.size() - 1, "the size of tyIdxs is not equal to typeTable"); + if (MeVerify::enableDebug) { + LogInfo::MapleLogger() << i << "\n"; + } +} + +void MeVerify::VerifyPhiNode(const BB &bb, Dominance &dom) const { + if (enableDebug) { + meFunc.GetTheCfg()->DumpToFile("meverify"); + } + for (auto &it : bb.GetMePhiList()) { + auto *phiNode = it.second; + if (phiNode == nullptr) { + continue; + } + if (enableDebug) { + LogInfo::MapleLogger() << bb.GetBBId() << " " << phiNode->GetLHS()->GetExprID() << "\n"; + } + if (!phiNode->GetIsLive()) { + continue; + } + auto *lhs = phiNode->GetLHS(); + if (lhs == nullptr) { + continue; + } + CHECK_FATAL(phiNode->GetDefBB() == &bb, "current bb must be def bb"); + CHECK_FATAL(lhs->GetDefBy() == kDefByPhi, "must be kDefByPhi"); + CHECK_FATAL(&(lhs->GetDefPhi()) == phiNode, "must be the def phinode"); + CHECK_FATAL(bb.GetPred().size() == phiNode->GetOpnds().size(), "must be equal"); + for (size_t i = 0; i < phiNode->GetOpnds().size(); ++i) { + auto *opnd = phiNode->GetOpnd(i); + if (opnd->IsVolatile()) { + continue; + } + MeStmt *stmt = nullptr; + BB *defBB = opnd->GetDefByBBMeStmt(dom, stmt); + if (bb.GetPred(i) != defBB && !dom.Dominate(*defBB, *bb.GetPred(i))) { + CHECK_FATAL(false, "the defBB of opnd must be the predBB or dominate the current bb"); + } + } + } +} + +void MeVerify::VerifySuccAndPredOfBB(const BB &bb) const { + std::set temp; + for (auto &pred : bb.GetPred()) { + size_t size = temp.size(); + temp.insert(pred->GetBBId()); + CHECK_FATAL(size != temp.size(), "the bb is already existed"); + } + temp.clear(); + for (auto &succ : bb.GetSucc()) { + size_t size = temp.size(); + temp.insert(succ->GetBBId()); + CHECK_FATAL(size != temp.size(), "the bb is already existed"); + } +} + +void MeVerify::VerifyBBKind(const BB &bb) const { + switch (bb.GetKind()) { + case kBBCondGoto: { + VerifyCondGotoBB(bb); + break; + } + case kBBGoto: { + VerifyGotoBB(bb); + break; + } + case kBBFallthru: { + VerifyFallthruBB(bb); + break; + } + case kBBReturn: { + VerifyReturnBB(bb); + break; + } + case kBBSwitch: { + VerifySwitchBB(bb); + break; + } + case kBBUnknown: { + if (bb.GetBBId() != 0 && bb.GetBBId() != 1) { + CHECK_FATAL(false, "Verify: must be Entry or Exit bb"); + } + break; + } + default: { + CHECK_FATAL(false, "Verify: can not support this kind of bb"); + } + } +} + +// Filter the special case which created in the function named RemoveEhEdgesInSyncRegion of mefunction. +void MeVerify::DealWithSpecialCase(const BB &currBB, const BB &tryBB) const { + if (meFunc.GetEndTryBB2TryBB().size() != 1) { + CHECK_FATAL(false, "must be try"); + } + if (currBB.GetAttributes(kBBAttrIsTryEnd)) { + auto endTryBB = currBB; + if (!(endTryBB.GetAttributes(kBBAttrIsCatch) || endTryBB.GetAttributes(kBBAttrIsJSCatch)) || + endTryBB.GetKind() != kBBFallthru || !endTryBB.GetAttributes(kBBAttrIsTryEnd) || + !endTryBB.GetAttributes(kBBAttrIsJavaFinally) || endTryBB.GetMeStmts().back().GetOp() != OP_syncexit || + tryBB.GetMeStmts().back().GetOp() != OP_try) { + CHECK_FATAL(false, "must be try"); + } + } + if (&currBB != &tryBB && !currBB.GetAttributes(kBBAttrIsTryEnd)) { + for (auto &stmt : currBB.GetMeStmts()) { + if (stmt.GetOp() == OP_try || stmt.GetOp() == OP_catch || stmt.GetOp() == OP_throw) { + CHECK_FATAL(false, "must be try");; + } + } + } +} + +void MeVerify::VerifyNestedTry(const BB &tryBB, const BB &currBB) const { + if (&currBB != &tryBB && !currBB.GetAttributes(kBBAttrIsTryEnd)) { + for (auto &stmt : currBB.GetMeStmts()) { + if (stmt.GetOp() == OP_try) { + CHECK_FATAL(false, "nested try");; + } + } + } +} + +void MeVerify::VerifyAttrTryBB(BB &tryBB, int index) { + auto tryStmt = static_cast(tryBB.GetMeStmts().front()); + int i = 0; + for (auto offsetIt = tryStmt.GetOffsets().rbegin(), offsetEIt = tryStmt.GetOffsets().rend(); + offsetIt != offsetEIt; ++offsetIt) { + auto offsetBBId = meFunc.GetLabelBBAt(*offsetIt)->GetBBId(); + bool needExit = false; + for (size_t j = index; j < meFunc.GetLaidOutBBs().size() && !needExit; ++j) { + auto currBB = meFunc.GetLaidOutBBs().at(j); + if (currBB == nullptr) { + continue; + } + if (currBB->GetAttributes(kBBAttrIsTryEnd)) { + needExit = true; + } + // bb_layout move artificial bb without try-attribute into try + if (currBB->GetAttributes(kBBAttrArtificial)) { + continue; + } + // cannot appear nested try + VerifyNestedTry(tryBB, *currBB); + if (!currBB->GetAttributes(kBBAttrIsTry)) { + DealWithSpecialCase(*currBB, tryBB); + continue; + } + // verify try attribute + CHECK_FATAL(currBB->GetAttributes(kBBAttrIsTry), "must be try"); + if (currBB->GetKind() == kBBReturn && currBB->GetAttributes(kBBAttrIsExit) && + currBB->GetMeStmts().back().GetOp() == OP_return) { + continue; + } + // When the curr bb is catch, the preds could not include the eh edge. + if (currBB->GetAttributes(kBBAttrIsCatch) && currBB->GetAttributes(kBBAttrIsJavaFinally)) { + continue; + } + // When the size of gotoBB's succs is more than two, one is targetBB, one is wontExitBB and the other is catchBB. + if (currBB->GetKind() == kBBGoto && currBB->GetAttributes(kBBAttrWontExit)) { + if (offsetBBId != (*(currBB->GetSucc().rbegin() + i + 1))->GetBBId() && + offsetBBId != (*(currBB->GetSucc().rbegin() + i))->GetBBId()) { + CHECK_FATAL(false, "must be equal"); + } + } else { + CHECK_FATAL(offsetBBId == (*(currBB->GetSucc().rbegin() + i))->GetBBId(), "must be equal"); + } + if (enableDebug) { + LogInfo::MapleLogger() << currBB->GetBBId() << " " << (*(currBB->GetSucc().rbegin() + i))->GetBBId() << "\n"; + } + } + CHECK_FATAL(needExit, "no tryend bb"); + ++i; + } +} + +void MeVerify::VerifyPredBBOfSuccBB(const BB &bb, const MapleVector &succs) const { + bool find = false; + for (auto &succ : succs) { + for (auto &pred : succ->GetPred()) { + if (pred->GetBBId() == bb.GetBBId()) { + find = true; + break; + } + } + CHECK_FATAL(find, "Verify: bb is not pred of succ bb"); + find = false; + } +} + +void MeVerify::VerifyCondGotoBB(const BB &bb) const { + if (bb.GetAttributes(kBBAttrIsTry) || bb.GetAttributes(kBBAttrWontExit)) { + CHECK_FATAL(bb.GetSucc().size() >= 2, "Verify: condgoto bb must have more than two succ bb"); + } else { + CHECK_FATAL(bb.GetSucc().size() == 2, "Verify: condgoto bb must have two succ bb"); + } + CHECK_FATAL(!bb.GetMeStmts().empty(), "Verify: meStmts of bb should not be empty"); + if (bb.GetMeStmts().back().GetOp() != OP_brfalse && bb.GetMeStmts().back().GetOp() != OP_brtrue) { + CHECK_FATAL(false, "Verify: the opcode of last stmt must be OP_brfalse or OP_brtrue"); + } + CHECK_FATAL(static_cast(bb.GetMeStmts().back()).GetOffset() == bb.GetSucc(1)->GetBBLabel(), + "Verify: offset of condgoto stmt must equal to the label of second succ bb"); + VerifyPredBBOfSuccBB(bb, bb.GetSucc()); +} + +void MeVerify::VerifyGotoBB(const BB &bb) const { + if (bb.GetAttributes(kBBAttrIsTry) || bb.GetAttributes(kBBAttrWontExit)) { + CHECK_FATAL(bb.GetSucc().size() >= 1, "Verify: goto bb must have more than one succ bb"); + } else { + CHECK_FATAL(bb.GetSucc().size() == 1, "Verify: goto bb must have one succ bb"); + } + CHECK_FATAL(!bb.GetMeStmts().empty(), "Verify: meStmts of bb should not be empty"); + if (bb.GetMeStmts().back().GetOp() == OP_goto) { + CHECK_FATAL(static_cast(bb.GetMeStmts().back()).GetOffset() == bb.GetSucc(0)->GetBBLabel(), + "Verify: offset of goto stmt must equal to the label of succ bb"); + } + VerifyPredBBOfSuccBB(bb, bb.GetSucc()); +} + +void MeVerify::VerifyFallthruBB(const BB &bb) const { + VerifyPredBBOfSuccBB(bb, bb.GetSucc()); + if (bb.GetAttributes(kBBAttrIsTry) || bb.GetAttributes(kBBAttrWontExit)) { + CHECK_FATAL(bb.GetSucc().size() >= 1, "Verify: fallthru bb must have more than one succ bb"); + } else { + CHECK_FATAL(bb.GetSucc().size() == 1, "Verify: fallthru bb must have one succ bb"); + } +} + +bool MeVerify::IsOnlyHaveReturnOrThrowStmt(const BB &bb, Opcode op) const { + auto stmt = &bb.GetMeStmts().front(); + CHECK_NULL_FATAL(stmt); + while (stmt != nullptr) { + if (stmt->GetOp() == op || stmt->GetOp() == OP_decref || stmt->GetOp() == OP_incref || + stmt->GetOp() == OP_decrefreset || stmt->GetOp() == OP_comment) { + stmt = stmt->GetNextMeStmt(); + continue; + } + return false; + } + return true; +} + +void MeVerify::VerifyCommonExitBB() const { + for (auto &pred : meFunc.GetCommonExitBB()->GetPred()) { + if (pred->GetKind() == kBBReturn) { + continue; + } + if (pred->GetKind() == kBBGoto && IsOnlyHaveReturnOrThrowStmt(*pred, OP_throw)) { + continue; + } + CHECK_FATAL(false, "verify CommonExitBB failed"); + } +} + +void MeVerify::VerifyReturnBB(const BB &bb) const { + for (auto &pred : meFunc.GetCommonExitBB()->GetPred()) { + if (pred == &bb) { + return; + } + } + CHECK_FATAL(false, "verify return bb failed"); +} + +void MeVerify::VerifySwitchBB(const BB &bb) const { + CHECK_FATAL(!bb.GetMeStmts().empty(), "Verify: meStmts of bb should not be empty"); + auto switchMeStmt = static_cast(bb.GetMeStmts().back()); + auto switchTable = switchMeStmt.GetSwitchTable(); + CHECK_FATAL(switchMeStmt.GetDefaultLabel() == bb.GetSucc(0)->GetBBLabel(), + "Verify: defaultlabel of switchstmt must be the label of first succ bb"); + for (auto &casePair : switchTable) { + bool isExit = false; + for (auto &succBB : bb.GetSucc()) { + if (casePair.second == succBB->GetBBLabel()) { + isExit = true; + break; + } + } + CHECK_FATAL(isExit, "Verify: case label of switchtable must equal to the succ bb"); + } + VerifyPredBBOfSuccBB(bb, bb.GetSucc()); +} + +AnalysisResult *MeDoVerify::Run(MeFunction *func, MeFuncResultMgr*, ModuleResultMgr*) { + MeVerify meVerify(*func); + meVerify.VerifyFunction(); + return nullptr; +} +} // namespace maple \ No newline at end of file diff --git a/src/mapleall/maple_me/src/preg_renamer.cpp b/src/mapleall/maple_me/src/preg_renamer.cpp index be1d3769631df62aec64bec5c332de0b8ab389e7..a8f5aef807ba61c3ebd26fee4c370c3c7ccc58a0 100644 --- a/src/mapleall/maple_me/src/preg_renamer.cpp +++ b/src/mapleall/maple_me/src/preg_renamer.cpp @@ -17,6 +17,7 @@ #include "me_irmap.h" #include "preg_renamer.h" #include "union_find.h" +#include "me_verify.h" namespace maple { void PregRenamer::RunSelf() { @@ -107,8 +108,8 @@ void PregRenamer::RunSelf() { } } -AnalysisResult *MeDoPregRename::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResultMgr*) { - MeIRMap *irmap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func)); +AnalysisResult *MeDoPregRename::Run(MeFunction *func, MeFuncResultMgr *frm, ModuleResultMgr *mrm) { + MeIRMap *irmap = static_cast(frm->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func)); std::string renamePhaseName = PhaseName(); MemPool *renamemp = memPoolCtrler.NewMemPool(renamePhaseName); PregRenamer pregrenamer(renamemp, func, irmap); @@ -118,6 +119,21 @@ AnalysisResult *MeDoPregRename::Run(MeFunction *func, MeFuncResultMgr *m, Module func->Dump(); } memPoolCtrler.DeleteMemPool(renamemp); + if (MeOption::meVerify) { + frm->InvalidAnalysisResult(MeFuncPhase_DOMINANCE, func); + CHECK_FATAL(mrm != nullptr, "Needs module result manager for ipa"); + auto *dom = static_cast(frm->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); + ASSERT(dom != nullptr, "dominance phase has problem"); + auto *kh = static_cast(mrm->GetAnalysisResult(MoPhase_CHA, &func->GetMIRModule())); + CHECK_FATAL(kh != nullptr, "kh phase has problem"); + MeVerify verify(*func); + for (auto &bb : func->GetAllBBs()) { + if (bb == nullptr) { + continue; + } + verify.VerifyPhiNode(*bb, *dom); + } + } return nullptr; } } // namespace maple diff --git a/src/mapleall/mpl2mpl/BUILD.gn b/src/mapleall/mpl2mpl/BUILD.gn index 5b68cca8de1727eb159e12c0d5c6080a8f242083..9fee3f68ba533001c772945a15e94aa10be1da4c 100755 --- a/src/mapleall/mpl2mpl/BUILD.gn +++ b/src/mapleall/mpl2mpl/BUILD.gn @@ -39,6 +39,7 @@ src_libmpl2mpl = [ "src/constantfold.cpp", "src/coderelayout.cpp", "src/annotation_analysis.cpp", + "src/preme.cpp", ] configs = [ "${MAPLEALL_ROOT}:mapleallcompilecfg" ] diff --git a/src/mapleall/mpl2mpl/include/constantfold.h b/src/mapleall/mpl2mpl/include/constantfold.h index 92f1a5d9112a4547f84da55a8e41f8e0d2443126..0bf8d497a0775c36977b71a6a67618e434f91cd8 100644 --- a/src/mapleall/mpl2mpl/include/constantfold.h +++ b/src/mapleall/mpl2mpl/include/constantfold.h @@ -17,6 +17,7 @@ #include "mir_nodes.h" #include "module_phase.h" #include "phase_impl.h" +#include "me_verify.h" namespace maple { class ConstantFold : public FuncOptimizeImpl { @@ -132,6 +133,9 @@ class DoConstantFold : public ModulePhase { AnalysisResult *Run(MIRModule *mod, ModuleResultMgr *mrm) override { OPT_TEMPLATE(ConstantFold); + if (MeOption::meVerify) { + VerifyGlobalTypeTable(); + } return nullptr; } }; diff --git a/src/mapleall/mpl2mpl/include/preme.h b/src/mapleall/mpl2mpl/include/preme.h new file mode 100644 index 0000000000000000000000000000000000000000..a0496ca4d39fb7b25fe28d856bd6a4c93fedb35d --- /dev/null +++ b/src/mapleall/mpl2mpl/include/preme.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) [2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * + * http://license.coscl.org.cn/MulanPSL + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v1 for more details. + */ +#ifndef MPL2MPL_INCLUDE_PREME_H +#define MPL2MPL_INCLUDE_PREME_H +#include "module_phase.h" +#include "phase_impl.h" +#include "me_option.h" + +namespace maple { +class Preme : public FuncOptimizeImpl { + public: + Preme(MIRModule &mod, KlassHierarchy *kh, bool dump) : FuncOptimizeImpl(mod, kh, dump) {} + ~Preme() = default; + // Create global symbols and functions here when iterating mirFunc is needed + void ProcessFunc(MIRFunction *func) override; + FuncOptimizeImpl *Clone() override { + return new Preme(*this); + } + + private: + void CreateMIRTypeForAddrof(const MIRFunction &func, const BaseNode *baseNode) const; +}; + +class DoPreme : public ModulePhase { + public: + explicit DoPreme(ModulePhaseID id) : ModulePhase(id) {} + ~DoPreme() = default; + AnalysisResult *Run(MIRModule *mod, ModuleResultMgr *mrm) override; + std::string PhaseName() const override { + return "preme"; + } + + private: + void CreateMIRTypeForLowerGlobalDreads() const; +}; +} // namespace maple +#endif // MPL2MPL_INCLUDE_PREME_H diff --git a/src/mapleall/mpl2mpl/src/preme.cpp b/src/mapleall/mpl2mpl/src/preme.cpp new file mode 100644 index 0000000000000000000000000000000000000000..494121f293316870e4000773ffb102a8ef68f188 --- /dev/null +++ b/src/mapleall/mpl2mpl/src/preme.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) [2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * + * http://license.coscl.org.cn/MulanPSL + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v1 for more details. + */ +#include "preme.h" +#include "me_option.h" +#include "me_function.h" +#include "me_verify.h" +#include "mir_symbol_builder.h" + +namespace maple { +void Preme::CreateMIRTypeForAddrof(const MIRFunction &func, const BaseNode *baseNode) const { + if (baseNode == nullptr) { + return; + } + if (baseNode->GetOpCode() == OP_block) { + const BlockNode *blockNode = static_cast(baseNode); + for (auto &stmt : blockNode->GetStmtNodes()) { + CreateMIRTypeForAddrof(func, &stmt); + } + } else if (baseNode->GetOpCode() == OP_if) { + auto *ifStmtNode = static_cast(baseNode); + CreateMIRTypeForAddrof(func, ifStmtNode->GetThenPart()); + CreateMIRTypeForAddrof(func, ifStmtNode->GetElsePart()); + } else if (baseNode->GetOpCode() == OP_addrof) { + const AddrofNode *addrNode = static_cast(baseNode); + const MIRSymbol *mirSymbol = func.GetLocalOrGlobalSymbol(addrNode->GetStIdx()); + MIRPtrType ptrType(mirSymbol->GetTyIdx(), PTY_ptr); + (void)GlobalTables::GetTypeTable().GetOrCreateMIRType(&ptrType); + } + // Search for nested dread node that may include a symbol index. + for (size_t i = 0; i < baseNode->NumOpnds(); ++i) { + CreateMIRTypeForAddrof(func, baseNode->Opnd(i)); + } +} + +void Preme::ProcessFunc(MIRFunction *func) { + if (func == nullptr || func->IsEmpty()) { + return; + } + StmtNode *stmt = func->GetBody()->GetFirst(); + while (stmt != nullptr) { + CreateMIRTypeForAddrof(*func, stmt); + stmt = stmt->GetNext(); + } +} + +void DoPreme::CreateMIRTypeForLowerGlobalDreads() const { + for (uint32 i = 0; i < MIRSymbolBuilder::Instance().GetSymbolTableSize(); ++i) { + auto *symbol = MIRSymbolBuilder::Instance().GetSymbolFromStIdx(i); + if (symbol == nullptr) { + continue; + } + if (!symbol->IsVar()) { + continue; + } + MIRPtrType ptrType(symbol->GetTyIdx(), PTY_ptr); + if (symbol->IsVolatile()) { + TypeAttrs attrs; + attrs.SetAttr(ATTR_volatile); + ptrType.SetTypeAttrs(attrs); + } + (void)GlobalTables::GetTypeTable().GetOrCreateMIRType(&ptrType); + } +} + +AnalysisResult *DoPreme::Run(MIRModule *mod, ModuleResultMgr *mrm) { + OPT_TEMPLATE(Preme); + if (MeOption::optLevel == 2) { + CreateMIRTypeForLowerGlobalDreads(); + } + if (MeOption::meVerify) { + VerifyGlobalTypeTable(); + } + return nullptr; +} +} // namespace maple diff --git a/src/mapleall/mpl2mpl/src/reflection_analysis.cpp b/src/mapleall/mpl2mpl/src/reflection_analysis.cpp index b661ada833a69d96274210e21d48d7aa5bd31669..254461aa241b05fa7ef77df1a415513b8da45ece 100644 --- a/src/mapleall/mpl2mpl/src/reflection_analysis.cpp +++ b/src/mapleall/mpl2mpl/src/reflection_analysis.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2019-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -918,7 +918,8 @@ MIRSymbol *ReflectionAnalysis::GetParameterTypesSymbol(uint32 size, uint32 index GlobalTables::GetTypeTable().AddFieldToStructType(parameterTypesType, kParameterTypeItemName, *type); } - TyIdx parameterTypesTyIdx = GenMetaStructType(module, parameterTypesType, kParameterTypesName); + TyIdx parameterTypesTyIdx = GenMetaStructType(module, parameterTypesType, + kParameterTypesName + std::to_string(index)); MIRStructType ¶meterTypes = static_cast(*GlobalTables::GetTypeTable().GetTypeFromTyIdx(parameterTypesTyIdx)); MIRSymbol *parameterTypesSt = @@ -1957,8 +1958,13 @@ bool ReflectionAnalysis::IsLocalClass(const std::string annotationString) { TyIdx ReflectionAnalysis::GenMetaStructType(MIRModule &mirModule, MIRStructType &metaType, const std::string &str) { const GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(str); - TyIdx tyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&metaType); - // Global? + TyIdx tyIdx = mirModule.GetTypeNameTab()->GetTyIdxFromGStrIdx(strIdx); + // A corresponding dummy type has been created in previous phases, update it with metaType. + if (tyIdx != kInitTyIdx) { + GlobalTables::GetTypeTable().UpdateMIRType(metaType, tyIdx); + } else { + tyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&metaType); + } mirModule.GetTypeNameTab()->SetGStrIdxToTyIdx(strIdx, tyIdx); mirModule.PushbackTypeDefOrder(strIdx); if (GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx)->GetNameStrIdx() == 0u) {