From 86438335cfec2ba0cd7b5d827dc1531f5dbfcc16 Mon Sep 17 00:00:00 2001 From: fye Date: Sat, 2 Apr 2022 11:47:06 -0700 Subject: [PATCH] PGO: profileGen base --- .../src/cg/aarch64/aarch64_cgfunc.cpp | 44 ++ .../src/cg/aarch64/aarch64_emitter.cpp | 8 + src/mapleall/maple_be/src/cg/emit.cpp | 2 + .../include/driver_option_common.h | 2 + .../maple_driver/src/driver_option_common.cpp | 18 + src/mapleall/maple_driver/src/mpl_options.cpp | 7 +- .../maple_ipa/include/ipa_phase_manager.h | 14 + .../maple_ipa/src/ipa_phase_manager.cpp | 59 ++- .../maple_ir/include/all_attributes.def | 4 + src/mapleall/maple_ir/include/mir_function.h | 41 +- src/mapleall/maple_ir/include/option.h | 2 + src/mapleall/maple_ir/src/option.cpp | 14 + src/mapleall/maple_me/src/me_option.cpp | 5 + src/mapleall/maple_me/src/me_profile_gen.cpp | 51 +++ src/mapleall/maple_phase/include/phases.def | 3 +- src/mapleall/maple_util/include/namemangler.h | 10 + src/mapleall/mpl2mpl/BUILD.gn | 1 + src/mapleall/mpl2mpl/include/gen_profile.h | 78 ++++ .../mpl2mpl/include/module_phase_manager.h | 1 + src/mapleall/mpl2mpl/src/gen_profile.cpp | 382 ++++++++++++++++++ .../mpl2mpl/src/module_phase_manager.cpp | 1 + 21 files changed, 738 insertions(+), 9 deletions(-) create mode 100644 src/mapleall/mpl2mpl/include/gen_profile.h create mode 100644 src/mapleall/mpl2mpl/src/gen_profile.cpp diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp index 63c33b5e58..f88b63df39 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -28,6 +28,7 @@ #include "metadata_layout.h" #include "emit.h" #include "simplify.h" +#include namespace maplebe { using namespace maple; @@ -8948,6 +8949,49 @@ bool AArch64CGFunc::IsDuplicateAsmList(const MIRSymbol &sym) const { } void AArch64CGFunc::SelectMPLProfCounterInc(const IntrinsiccallNode &intrnNode) { + if (Options::profileGen) { + ASSERT(intrnNode.NumOpnds() == 1, "must be 1 operand"); + BaseNode *arg1 = intrnNode.Opnd(0); + ASSERT(arg1 != nullptr, "nullptr check"); + regno_t vRegNO1 = NewVReg(GetRegTyFromPrimTy(PTY_a64), GetPrimTypeSize(PTY_a64)); + RegOperand &vReg1 = CreateVirtualRegisterOperand(vRegNO1); + vReg1.SetRegNotBBLocal(); + static const MIRSymbol *bbProfileTab = nullptr; + + // Ref: MeProfGen::InstrumentFunc on ctrTbl naming + std::string ctrTblName = namemangler::kprefixProfCtrTbl + + GetMirModule().GetFileName() + "_" + GetName(); + std::replace(ctrTblName.begin(), ctrTblName.end(), '.', '_'); + std::replace(ctrTblName.begin(), ctrTblName.end(), '-', '_'); + std::replace(ctrTblName.begin(), ctrTblName.end(), '/', '_'); + + if (!bbProfileTab || bbProfileTab->GetName() != ctrTblName) { + bbProfileTab = GetMirModule().GetMIRBuilder()->GetGlobalDecl(ctrTblName); + CHECK_FATAL(bbProfileTab != nullptr, "expect counter table"); + } + + ConstvalNode *constvalNode = static_cast(arg1); + MIRConst *mirConst = constvalNode->GetConstVal(); + ASSERT(mirConst != nullptr, "nullptr check"); + CHECK_FATAL(mirConst->GetKind() == kConstInt, "expect MIRIntConst type"); + MIRIntConst *mirIntConst = safe_cast(mirConst); + int64 offset = GetPrimTypeSize(PTY_u64) * mirIntConst->GetValue(); + + if (!GetCG()->IsQuiet()) { + maple::LogInfo::MapleLogger(kLlInfo) << "At counter table offset: " << offset << std::endl; + } + MemOperand *memOpnd = &GetOrCreateMemOpnd(*bbProfileTab, offset, k64BitSize); + AArch64MemOperand &ctrMemOpnd = *static_cast(memOpnd); + if (IsImmediateOffsetOutOfRange(ctrMemOpnd, k64BitSize)) { + memOpnd = &SplitOffsetWithAddInstruction(ctrMemOpnd, k64BitSize); + } + Operand *reg = &SelectCopy(*memOpnd, PTY_u64, PTY_u64); + AArch64ImmOperand &one = CreateImmOperand(1, k64BitSize, false); + SelectAdd(*reg, *reg, one, PTY_u64); + SelectCopy(*memOpnd, PTY_u64, *reg, PTY_u64); + return; + } + ASSERT(intrnNode.NumOpnds() == 1, "must be 1 operand"); BaseNode *arg1 = intrnNode.Opnd(0); ASSERT(arg1 != nullptr, "nullptr check"); diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_emitter.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_emitter.cpp index 26d79c03d8..ebcca62cb6 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_emitter.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_emitter.cpp @@ -408,6 +408,14 @@ void AArch64AsmEmitter::Run(FuncEmitInfo &funcEmitInfo) { (void)emitter.Emit("\t.section\t.init_array,\"aw\"\n"); (void)emitter.Emit("\t.quad\t").Emit(cgFunc.GetName()).Emit("\n"); } + if (cgFunc.GetFunction().GetAttr(FUNCATTR_initialization)) { + (void)emitter.Emit("\t.section\t.init_array,\"aw\"\n"); + (void)emitter.Emit("\t.quad\t").Emit(cgFunc.GetName()).Emit("\n"); + } + if (cgFunc.GetFunction().GetAttr(FUNCATTR_termination)) { + (void)emitter.Emit("\t.section\t.fini_array,\"aw\"\n"); + (void)emitter.Emit("\t.quad\t").Emit(cgFunc.GetName()).Emit("\n"); + } emitter.Emit("\n"); EmitMethodDesc(funcEmitInfo, emitter); /* emit java code to the java section. */ diff --git a/src/mapleall/maple_be/src/cg/emit.cpp b/src/mapleall/maple_be/src/cg/emit.cpp index a7c2a137f3..4df2c9ec5a 100644 --- a/src/mapleall/maple_be/src/cg/emit.cpp +++ b/src/mapleall/maple_be/src/cg/emit.cpp @@ -1645,6 +1645,8 @@ void Emitter::EmitArrayConstant(MIRConst &mirConst) { } else if (elemConst->GetType().GetKind() == kTypeStruct || elemConst->GetType().GetKind() == kTypeClass || elemConst->GetType().GetKind() == kTypeUnion) { EmitStructConstant(*elemConst); + } else if (elemConst->GetKind() == kConstAddrofFunc) { + EmitScalarConstant(*elemConst); } else { ASSERT(false, "should not run here"); } diff --git a/src/mapleall/maple_driver/include/driver_option_common.h b/src/mapleall/maple_driver/include/driver_option_common.h index 0b79889d36..8a583e16b9 100644 --- a/src/mapleall/maple_driver/include/driver_option_common.h +++ b/src/mapleall/maple_driver/include/driver_option_common.h @@ -41,6 +41,8 @@ enum DriverOptionIndex { // DAI2.0 kDecoupleInit, kProfilePath, + kProfileGen, + kProfileUse, kGCOnly, kBigEndian, kMplcgOpt, diff --git a/src/mapleall/maple_driver/src/driver_option_common.cpp b/src/mapleall/maple_driver/src/driver_option_common.cpp index a59b93c891..e84c980877 100644 --- a/src/mapleall/maple_driver/src/driver_option_common.cpp +++ b/src/mapleall/maple_driver/src/driver_option_common.cpp @@ -221,6 +221,24 @@ const mapleOption::Descriptor kUsages[] = { " \t--profile=list_file\n", "driver", { "dex2mpl", "mpl2mpl", "mplcg" } }, + { kProfileGen, + kEnable, + "", + "profileGen", + kBuildTypeProduct, + kArgCheckPolicyBool, + " --profileGen \tGenerate profile data for static languages\n", + "driver", + { "me", "mpl2mpl", "mplcg" } }, + { kProfileUse, + kEnable, + "", + "profileUse", + kBuildTypeProduct, + kArgCheckPolicyBool, + " --profileUse \tOptimize static languages with profile data\n", + "driver", + { "me", "mpl2mpl", "mplcg" } }, { kGCOnly, kEnable, "", diff --git a/src/mapleall/maple_driver/src/mpl_options.cpp b/src/mapleall/maple_driver/src/mpl_options.cpp index 9bd86f1dcd..4de0925df6 100644 --- a/src/mapleall/maple_driver/src/mpl_options.cpp +++ b/src/mapleall/maple_driver/src/mpl_options.cpp @@ -152,7 +152,12 @@ ErrorCode MplOptions::HandleGeneralOptions() { LogInfo::MapleLogger() << kMapleDriverVersion << "\n"; return kErrorExitHelp; } - + case kProfileGen: { + exeOptions[kBinNameMe].push_back(opt); + exeOptions[kBinNameMpl2mpl].push_back(opt); + //exeOptions[kBinNameMplcg].push_back(opt); + continue; + } case kDex2mplOpt: updatedOptToolName = &kBinNameDex2mpl; break; diff --git a/src/mapleall/maple_ipa/include/ipa_phase_manager.h b/src/mapleall/maple_ipa/include/ipa_phase_manager.h index 39b95bc705..187737ed04 100644 --- a/src/mapleall/maple_ipa/include/ipa_phase_manager.h +++ b/src/mapleall/maple_ipa/include/ipa_phase_manager.h @@ -66,5 +66,19 @@ class SCCEmit : public MapleSccPhase>, public MaplePhaseManager private: void GetAnalysisDependence(maple::AnalysisDep &aDep) const override; }; + +class SCCProfile : public MapleSccPhase>, public MaplePhaseManager { + public: + explicit SCCProfile(MemPool *mp) : MapleSccPhase>(&id, mp), MaplePhaseManager(*mp) {} + ~SCCProfile() override = default; + std::string PhaseName() const override; + PHASECONSTRUCTOR(SCCProfile); + bool PhaseRun(SCCNode &f) override; + AnalysisDataManager *GetResult() { + return result; + } + private: + AnalysisDataManager *result = nullptr; +}; } // namespace maple #endif // MAPLE_IPA_INCLUDE_IPA_PHASE_MANAGER_H diff --git a/src/mapleall/maple_ipa/src/ipa_phase_manager.cpp b/src/mapleall/maple_ipa/src/ipa_phase_manager.cpp index ddf7fd6551..cede8ca071 100644 --- a/src/mapleall/maple_ipa/src/ipa_phase_manager.cpp +++ b/src/mapleall/maple_ipa/src/ipa_phase_manager.cpp @@ -83,12 +83,16 @@ bool IpaSccPM::PhaseRun(MIRModule &m) { void IpaSccPM::DoPhasesPopulate(const MIRModule &mirModule) { (void)mirModule; - AddPhase("sccprepare", true); - AddPhase("prop_param_type", MeOption::npeCheckMode != SafetyCheckMode::kNoCheck); - AddPhase("prop_return_attr", MeOption::npeCheckMode != SafetyCheckMode::kNoCheck); - AddPhase("collect_ipa_info", true); - AddPhase("sccsideeffect", true); - AddPhase("sccemit", true); + if (Options::profileGen || Options::profileUse) { + AddPhase("sccprofile", true); + } else { + AddPhase("sccprepare", true); + AddPhase("prop_param_type", MeOption::npeCheckMode != SafetyCheckMode::kNoCheck); + AddPhase("prop_return_attr", MeOption::npeCheckMode != SafetyCheckMode::kNoCheck); + AddPhase("collect_ipa_info", true); + AddPhase("sccsideeffect", Options::sideEffect); + AddPhase("sccemit", true); + } } void IpaSccPM::GetAnalysisDependence(maple::AnalysisDep &aDep) const { @@ -183,7 +187,50 @@ void SCCEmit::GetAnalysisDependence(maple::AnalysisDep &aDep) const { aDep.AddRequired(); } +bool SCCProfile::PhaseRun(SCCNode &scc) { + SetQuiet(true); + AddPhase("mecfgbuild", true); + if (Options::profileGen) { + AddPhase("ssatab", true); + AddPhase("aliasclass", true); + AddPhase("ssa", true); + AddPhase("irmapbuild", true); + //AddPhase("profileIntrusionPM", true); //ref: MEProfGen + AddPhase("profileGen", true); + } else { + AddPhase("profileUse", true); + } + AddPhase("emitforipa", true); + // Not like other phasemanager which use temp mempool to hold analysis results generated from the sub phases. + // Here we use GetManagerMemPool which lives longer than this phase(manager) itself to hold all the analysis result. + // So the following phase can access the result in this phase. + result = GetManagerMemPool()->New(*GetPhaseMemPool()); + for (auto *cgNode : scc.GetNodes()) { + MIRFunction *func = cgNode->GetMIRFunction(); + if (func->IsEmpty()) { + continue; + } + MIRModule &m = *func->GetModule(); + m.SetCurFunction(func); + MeFunction &meFunc = *func->GetMeFunc(); + for (size_t i = 0; i < phasesSequence.size(); ++i) { + const MaplePhaseInfo *phase = MaplePhaseRegister::GetMaplePhaseRegister()->GetPhaseByID(phasesSequence[i]); + if (!IsQuiet()) { + LogInfo::MapleLogger() << " >> Prepare " << (phase->IsAnalysis() ? "analysis" : "transform") + << " Phase [ " << phase->PhaseName() << " ] <<\n"; + } + if (phase->IsAnalysis()) { + (void)RunAnalysisPhase(*phase, *result, meFunc, 1); + } else { + (void)RunTransformPhase(*phase, *result, meFunc, 1); + } + } + } + return false; +} + MAPLE_ANALYSIS_PHASE_REGISTER(SCCPrepare, sccprepare) +MAPLE_ANALYSIS_PHASE_REGISTER(SCCProfile, sccprofile) MAPLE_ANALYSIS_PHASE_REGISTER(SCCCollectIpaInfo, collect_ipa_info); MAPLE_ANALYSIS_PHASE_REGISTER(SCCPropReturnAttr, prop_return_attr); MAPLE_TRANSFORM_PHASE_REGISTER(SCCPropParamType, prop_param_type); diff --git a/src/mapleall/maple_ir/include/all_attributes.def b/src/mapleall/maple_ir/include/all_attributes.def index 025166edbe..6f51deb754 100644 --- a/src/mapleall/maple_ir/include/all_attributes.def +++ b/src/mapleall/maple_ir/include/all_attributes.def @@ -106,3 +106,7 @@ #if (defined(TYPE_ATTR) || defined(FIELD_ATTR)) && !defined(NOCONTENT_ATTR) ATTR(pack) #endif +#ifdef FUNC_ATTR + ATTR(initialization) + ATTR(termination) +#endif diff --git a/src/mapleall/maple_ir/include/mir_function.h b/src/mapleall/maple_ir/include/mir_function.h index 4767206ed6..52ee2bccd1 100644 --- a/src/mapleall/maple_ir/include/mir_function.h +++ b/src/mapleall/maple_ir/include/mir_function.h @@ -1113,6 +1113,42 @@ class MIRFunction { funcDesc = value; } + void SetProfCtrTbl(MIRSymbol *pct) { + CHECK_FATAL(Options::profileGen, "This is only for profileGen"); + profCtrTbl = pct; + } + + MIRSymbol *GetProfCtrTbl() { + return profCtrTbl; + } + + void SetNumCtrs(uint32 num) { + CHECK_FATAL(Options::profileGen, "This is only for profileGen"); + nCtrs = num; + } + + uint32 GetNumCtrs() { + return nCtrs; + } + + void SetFileLineNoChksum(uint64 chksum) { + CHECK_FATAL(Options::profileGen, "This is only for profileGen"); + fileLinenoChksum = chksum; + } + + uint64 GetFileLineNoChksum() { + return fileLinenoChksum; + } + + void SetCFGChksum(uint64 chksum) { + CHECK_FATAL(Options::profileGen, "This is only for profileGen"); + cfgChksum = chksum; + } + + uint64 GetCFGChksum() { + return cfgChksum; + } + void InitFuncDescToBest() { funcDesc.InitToBest(); } @@ -1234,7 +1270,10 @@ class MIRFunction { PointerAttr returnKind = PointerAttr::kPointerUndeiced; std::map paramNonullTypeMap; FuncDesc funcDesc{}; - + MIRSymbol *profCtrTbl = nullptr; + uint32 nCtrs = 0; // number of counters + uint64 fileLinenoChksum = 0; + uint64 cfgChksum = 0; void DumpFlavorLoweredThanMmpl() const; MIRFuncType *ReconstructFormals(const std::vector &symbols, bool clearOldArgs); }; diff --git a/src/mapleall/maple_ir/include/option.h b/src/mapleall/maple_ir/include/option.h index f3c2eb535c..05abab257f 100644 --- a/src/mapleall/maple_ir/include/option.h +++ b/src/mapleall/maple_ir/include/option.h @@ -147,6 +147,8 @@ class Options : public MapleDriverOptionBase { static std::string readDevirtualList; static bool usePreloadedClass; static std::string profile; + static bool profileGen; + static bool profileUse; static std::string appPackageName; static std::string proFileData; static std::string proFileFuncData; diff --git a/src/mapleall/maple_ir/src/option.cpp b/src/mapleall/maple_ir/src/option.cpp index 85f84739c0..fccdbc2922 100644 --- a/src/mapleall/maple_ir/src/option.cpp +++ b/src/mapleall/maple_ir/src/option.cpp @@ -59,6 +59,9 @@ bool Options::emitVtableImpl = false; #if MIR_JAVA bool Options::skipVirtualMethod = false; #endif +bool Options::profileGen = false; +bool Options::profileUse = false; + // Ready to be deleted. bool Options::noRC = false; bool Options::analyzeCtor = true; @@ -1226,6 +1229,17 @@ bool Options::SolveOptions(const std::deque