From 02add78907dea283fee2c0e633846ad9c3669eb4 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Thu, 6 Oct 2022 05:31:33 -0700 Subject: [PATCH 01/22] Fixed the path of the profile file name written in .s under --profileGen so GCOV_PREFIX_STRIP can work correctly Fixed the interpretation of GCOV_PREFIX and GCOV_PREFIX_STRIP under --profileUse. Added new flag --missing-profdata-is-error (default is true) which means the compiler will complain under --profileUse if the .mprofdata file is not found. Specifying --no-missing-profdata-is-error will change it to just emitting a warning. Under --profileUse, do not look for .mprofdata file when the file has no executable code. Changed inlinter to not inline when profile data indicates the callee is not executed. Removed an assertion in PreMeMIRLower:LowerWhileStmt(). Made FuncProfInfo::SetStmtFreq() treat freq value of -1 to mean no freq info. In loopvec phase, update remainder loop freq to 0 (previously no freq). --- .../maple_driver/include/driver_options.h | 1 + .../maple_driver/src/driver_options.cpp | 6 +++ src/mapleall/maple_ir/include/mir_module.h | 12 +---- src/mapleall/maple_ir/src/mir_lower.cpp | 3 ++ src/mapleall/maple_ir/src/mir_module.cpp | 17 +++++++ src/mapleall/maple_me/src/lfo_loop_vec.cpp | 5 +++ src/mapleall/maple_me/src/me_cfg.cpp | 16 ++++--- .../maple_me/src/me_value_range_prop.cpp | 1 - src/mapleall/maple_me/src/pme_mir_lower.cpp | 3 +- .../maple_util/include/mpl_profdata.h | 3 ++ src/mapleall/mpl2mpl/src/gen_profile.cpp | 3 +- src/mapleall/mpl2mpl/src/inline.cpp | 9 +++- .../mpl2mpl/src/mpl_profdata_parser.cpp | 44 +++++++++++-------- 13 files changed, 83 insertions(+), 40 deletions(-) diff --git a/src/mapleall/maple_driver/include/driver_options.h b/src/mapleall/maple_driver/include/driver_options.h index 7798e14091..5b04c6414e 100644 --- a/src/mapleall/maple_driver/include/driver_options.h +++ b/src/mapleall/maple_driver/include/driver_options.h @@ -72,6 +72,7 @@ extern maplecl::Option genMapleBC; extern maplecl::Option genLMBC; extern maplecl::Option profileGen; extern maplecl::Option profileUse; +extern maplecl::Option missingProfDataIsError; extern maplecl::Option stackProtectorStrong; extern maplecl::Option stackProtectorAll; diff --git a/src/mapleall/maple_driver/src/driver_options.cpp b/src/mapleall/maple_driver/src/driver_options.cpp index c159d57f1e..dc694aaef9 100644 --- a/src/mapleall/maple_driver/src/driver_options.cpp +++ b/src/mapleall/maple_driver/src/driver_options.cpp @@ -171,6 +171,12 @@ maplecl::Option profileUse({"--profileUse"}, " --profileUse \tOptimize static languages with profile data\n", {driverCategory, mpl2mplCategory}); +maplecl::Option missingProfDataIsError({"--missing-profdata-is-error"}, + " --missing-profdata-is-error \tTreat missing profile data file as error\n" + " --no-missing-profdata-is-error \tOnly warn on missing profile data file\n", + {driverCategory}, + maplecl::DisableWith("--no-missing-profdata-is-error"), + maplecl::Init(true)); maplecl::Option stackProtectorStrong({"--stack-protector-strong"}, " --stack-protector-strong \tadd stack guard for some function\n", {driverCategory, meCategory, cgCategory}); diff --git a/src/mapleall/maple_ir/include/mir_module.h b/src/mapleall/maple_ir/include/mir_module.h index 1b02a9dbca..2ef8d9992e 100644 --- a/src/mapleall/maple_ir/include/mir_module.h +++ b/src/mapleall/maple_ir/include/mir_module.h @@ -340,21 +340,11 @@ class MIRModule { } std::string GetFileNameAsPostfix() const; + std::string GetFileNameWithPath() const; void SetFileName(const std::string &name) { fileName = name; } - std::string GetProfileDataFileName() const { - std::string profileDataFileName = GetFileName().substr(0, GetFileName().find_last_of(".")); - const char *gcovPath = std::getenv("GCOV_PREFIX"); - std::string gcovPrefix = gcovPath ? gcovPath : ""; - if (!gcovPrefix.empty() && (gcovPrefix.back() != '/')) { - gcovPrefix.append("/"); - } - profileDataFileName = gcovPrefix + profileDataFileName; - return profileDataFileName; - } - bool IsJavaModule() const { return srcLang == kSrcLangJava; } diff --git a/src/mapleall/maple_ir/src/mir_lower.cpp b/src/mapleall/maple_ir/src/mir_lower.cpp index 389dc6fc87..a7cbef418e 100644 --- a/src/mapleall/maple_ir/src/mir_lower.cpp +++ b/src/mapleall/maple_ir/src/mir_lower.cpp @@ -404,6 +404,9 @@ BlockNode *MIRLower::LowerDoloopStmt(DoloopNode &doloop) { if (GetFuncProfData()) { doloopnodeFreq = static_cast(GetFuncProfData()->GetStmtFreq(doloop.GetStmtID())); bodynodeFreq = static_cast(GetFuncProfData()->GetStmtFreq(doloop.GetDoBody()->GetStmtID())); + if (doloopnodeFreq < bodynodeFreq) { + doloopnodeFreq = bodynodeFreq; + } } auto *blk = mirModule.CurFuncCodeMemPool()->New(); if (doloop.IsPreg()) { diff --git a/src/mapleall/maple_ir/src/mir_module.cpp b/src/mapleall/maple_ir/src/mir_module.cpp index 334216779e..8e53cfaf03 100644 --- a/src/mapleall/maple_ir/src/mir_module.cpp +++ b/src/mapleall/maple_ir/src/mir_module.cpp @@ -747,6 +747,23 @@ std::string MIRModule::GetFileNameAsPostfix() const { return fileNameStr; } +std::string MIRModule::GetFileNameWithPath() const { + MIRInfoPair fileInfoElem = fileInfo.front(); + std::string fileNameWithoutPath = GlobalTables::GetStrTable().GetStringFromStrIdx(fileInfoElem.second); + // strip out the suffix + fileNameWithoutPath = fileNameWithoutPath.substr(0, fileNameWithoutPath.find_last_of(".")); + std::string fileNameWithPath; + // find the right entry because some entries are for included files + for (size_t i = 0; i < srcFileInfo.size(); ++i) { + MIRInfoPair infoElem = srcFileInfo[i]; + fileNameWithPath = GlobalTables::GetStrTable().GetStringFromStrIdx(infoElem.first); + if (fileNameWithPath.find(fileNameWithoutPath) != std::string::npos) { + break; + } + } + return fileNameWithPath; +} + void MIRModule::AddClass(TyIdx tyIdx) { (void)classList.insert(tyIdx); } diff --git a/src/mapleall/maple_me/src/lfo_loop_vec.cpp b/src/mapleall/maple_me/src/lfo_loop_vec.cpp index 189a49ec6e..17e548f7e6 100644 --- a/src/mapleall/maple_me/src/lfo_loop_vec.cpp +++ b/src/mapleall/maple_me/src/lfo_loop_vec.cpp @@ -1754,6 +1754,11 @@ DoloopNode *LoopVectorization::PrepareDoloop(DoloopNode *doloop, LoopTransPlan * ASSERT(parent && (parent->GetOpCode() == OP_block), "nullptr check"); BlockNode *pblock = static_cast(parent); pblock->InsertAfter(doloop, edoloop); + auto *profData = mirFunc->GetFuncProfData(); + if (profData) { + profData->SetStmtFreq(edoloop->GetStmtID(), 0); + profData->SetStmtFreq(edoloop->GetDoBody()->GetStmtID(), 0); + } } return doloop; } diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index 4b3547b7a7..2d8a4ed49a 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -1875,15 +1875,20 @@ void MeCFG::ConstructEdgeFreqFromBBFreq() { if (fallthru->GetPred().size() == 1) { auto succ0Freq = fallthru->GetFrequency(); bb->PushBackSuccFreq(succ0Freq); - ASSERT(bb->GetFrequency() + 1 >= succ0Freq, "sanity check"); - bb->PushBackSuccFreq(bb->GetFrequency() - succ0Freq); + if (bb->GetFrequency() > succ0Freq) { + bb->PushBackSuccFreq(bb->GetFrequency() - succ0Freq); + } else { + bb->PushBackSuccFreq(0); + } } else if (targetBB->GetPred().size() == 1) { auto succ1Freq = targetBB->GetFrequency(); - ASSERT(bb->GetFrequency() >= succ1Freq, "sanity check"); if (bb->GetAttributes(kBBAttrWontExit) && bb->GetSuccFreq().size() == 1) { // special case: WontExitAnalysis() has pushed 0 to bb->succFreq bb->GetSuccFreq()[0] = bb->GetFrequency(); bb->PushBackSuccFreq(0); + } else if (bb->GetFrequency() >= succ1Freq) { // tolerate inaccuracy + bb->PushBackSuccFreq(0); + bb->PushBackSuccFreq(bb->GetFrequency()); } else { bb->PushBackSuccFreq(bb->GetFrequency() - succ1Freq); bb->PushBackSuccFreq(succ1Freq); @@ -1917,10 +1922,11 @@ void MeCFG::ConstructBBFreqFromStmtFreq() { for (auto bIt = valid_begin(); bIt != eIt; ++bIt) { if ((*bIt)->IsEmpty()) continue; StmtNode &first = (*bIt)->GetFirst(); + StmtNode &last = (*bIt)->GetLast(); if (funcData->stmtFreqs.count(first.GetStmtID()) > 0) { (*bIt)->SetFrequency(funcData->stmtFreqs[first.GetStmtID()]); - } else if (funcData->stmtFreqs.count((*bIt)->GetLast().GetStmtID()) > 0) { - (*bIt)->SetFrequency(funcData->stmtFreqs[(*bIt)->GetLast().GetStmtID()]); + } else if (funcData->stmtFreqs.count(last.GetStmtID()) > 0) { + (*bIt)->SetFrequency(funcData->stmtFreqs[last.GetStmtID()]); } else { LogInfo::MapleLogger() << "ERROR:: bb " << (*bIt)->GetBBId() << "frequency is not set" << "\n"; diff --git a/src/mapleall/maple_me/src/me_value_range_prop.cpp b/src/mapleall/maple_me/src/me_value_range_prop.cpp index bcfa6a8a5f..8fa5664796 100644 --- a/src/mapleall/maple_me/src/me_value_range_prop.cpp +++ b/src/mapleall/maple_me/src/me_value_range_prop.cpp @@ -3921,7 +3921,6 @@ bool ValueRangePropagation::RemoveTheEdgeOfPredBB( uint64 edgeFreq = 0; if (func.GetCfg()->UpdateCFGFreq()) { edgeFreq = pred.GetSuccFreq()[index]; - ASSERT(bb.GetFrequency() >= edgeFreq, "sanity check"); } pred.RemoveSucc(bb); DeleteThePhiNodeWhichOnlyHasOneOpnd(bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); diff --git a/src/mapleall/maple_me/src/pme_mir_lower.cpp b/src/mapleall/maple_me/src/pme_mir_lower.cpp index 048ff7464a..994f9929b6 100644 --- a/src/mapleall/maple_me/src/pme_mir_lower.cpp +++ b/src/mapleall/maple_me/src/pme_mir_lower.cpp @@ -73,8 +73,7 @@ BlockNode *PreMeMIRLower::LowerWhileStmt(WhileStmtNode &whileStmt) { if (GetFuncProfData()) { int64_t freq = GetFuncProfData()->GetStmtFreq(whileStmt.GetStmtID()) - GetFuncProfData()->GetStmtFreq(whilegotonode->GetStmtID()); - ASSERT(freq >= 0, "sanity check"); - GetFuncProfData()->SetStmtFreq(endlblstmt->GetStmtID(), freq); + GetFuncProfData()->SetStmtFreq(endlblstmt->GetStmtID(), freq > 0 ? freq : 0); } return blk; } diff --git a/src/mapleall/maple_util/include/mpl_profdata.h b/src/mapleall/maple_util/include/mpl_profdata.h index 23cf6f99b9..767bbf2ea4 100644 --- a/src/mapleall/maple_util/include/mpl_profdata.h +++ b/src/mapleall/maple_util/include/mpl_profdata.h @@ -130,6 +130,9 @@ class FuncProfInfo { return -1; // unstored } void SetStmtFreq(uint32_t stmtID, uint64_t freq) { + if (static_cast(freq) == -1) { + return; + } stmtFreqs[stmtID] = freq; } void EraseStmtFreq(uint32_t stmtID) { diff --git a/src/mapleall/mpl2mpl/src/gen_profile.cpp b/src/mapleall/mpl2mpl/src/gen_profile.cpp index f354ecf23b..26783fd50a 100644 --- a/src/mapleall/mpl2mpl/src/gen_profile.cpp +++ b/src/mapleall/mpl2mpl/src/gen_profile.cpp @@ -103,8 +103,9 @@ void ProfileGen::CreateModProfDesc() { MIRIntConst *checksumMirConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst(cfgChkSum, *u32Ty); modProfDescSymMirConst->AddItem(checksumMirConst, 5); + std::string fileNameWithPath = mod.GetFileNameWithPath(); // Make the profile file name as fileName.gcda - std::string profFileName = mod.GetFileName().substr(0, mod.GetFileName().find_last_of(".")) + namemangler::kProfFileNameExt; + std::string profFileName = fileNameWithPath.substr(0, fileNameWithPath.find_last_of(".")) + namemangler::kProfFileNameExt; auto *profileFNMirConst = modMP->New(profFileName, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(PTY_a64))); modProfDescSymMirConst->AddItem(profileFNMirConst, 6); diff --git a/src/mapleall/mpl2mpl/src/inline.cpp b/src/mapleall/mpl2mpl/src/inline.cpp index e351a1e247..af673b7f42 100644 --- a/src/mapleall/mpl2mpl/src/inline.cpp +++ b/src/mapleall/mpl2mpl/src/inline.cpp @@ -531,8 +531,13 @@ void MInline::InlineCallsBlockInternal(MIRFunction &func, BaseNode &baseNode, bo InlineResult result; result.reason = GetInlineFailedStr(failCode); if (canInline) { - result = AnalyzeCallee(func, *callee, callStmt); - canInline = result.canInline; + if (Options::profileUse && callee->GetFuncProfData() == nullptr) { + // callee is never executed according to profile data + canInline = false; + } else { + result = AnalyzeCallee(func, *callee, callStmt); + canInline = result.canInline; + } } if (canInline) { module.SetCurFunction(&func); diff --git a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp index 1d0ed18d7f..8fac14a282 100644 --- a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp +++ b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp @@ -87,6 +87,7 @@ int MplProfDataParser::ReadMapleProfileData() { std::string mprofDataFile = Options::profile; if (mprofDataFile.empty()) { if (const char *envGcovprefix = std::getenv("GCOV_PREFIX")) { + std::string fileNameWithPath = m.GetFileNameWithPath(); static_cast(mprofDataFile.append(envGcovprefix)); if (mprofDataFile.back() != '/') { static_cast(mprofDataFile.append("/")); @@ -102,33 +103,30 @@ int MplProfDataParser::ReadMapleProfileData() { LogInfo::MapleLogger() << "set env GCOV_PREFIX_STRIP=" << strip << std::endl; } } - std::string profDataFileName = m.GetProfileDataFileName(); - if (dumpDetail) { - LogInfo::MapleLogger() << "profdata file stem before strip: " << profDataFileName << std::endl; - } - // reduce path in profDataFileName - while (stripnum > 0 && profDataFileName.size() > 1) { - size_t pos = profDataFileName.find_first_of("/", 1); + // strip path in fileNameWithPath according to stripnum + while (stripnum > 0 && fileNameWithPath.size() > 1) { + size_t pos = fileNameWithPath.find_first_of("/", 1); if (pos == std::string::npos) { break; } - profDataFileName = profDataFileName.substr(pos); + fileNameWithPath= fileNameWithPath.substr(pos); stripnum--; } if (dumpDetail) { - LogInfo::MapleLogger() << "profdata file stem after strip: " << profDataFileName << std::endl; + LogInfo::MapleLogger() << "profdata file stem after strip: " << fileNameWithPath<< std::endl; } - CHECK_FATAL(profDataFileName.size() > 0, "sanity check"); - static_cast(mprofDataFile.append(profDataFileName)); + CHECK_FATAL(fileNameWithPath.size() > 0, "sanity check"); + static_cast(mprofDataFile.append(fileNameWithPath)); } else { - // if gcov_prefix is not set, find .mprofdata according to m.profiledata - mprofDataFile = m.GetProfileDataFileName(); - if (dumpDetail) { - LogInfo::MapleLogger() << "NO ENV, profdata file stem: " << mprofDataFile << std::endl; + mprofDataFile = m.GetFileName(); + // strip path in mprofDataFile + size_t pos = mprofDataFile.find_last_of("/"); + if (pos != std::string::npos) { + mprofDataFile = mprofDataFile.substr(pos+1); } } - // add .mprofdata - static_cast(mprofDataFile.append(namemangler::kMplProfFileNameExt)); + // change the suffix to .mprofdata + mprofDataFile = mprofDataFile.substr(0, mprofDataFile.find_last_of(".")) + namemangler::kMplProfFileNameExt; } ASSERT(!mprofDataFile.empty(), "null check"); LogInfo::MapleLogger() << "profileUse will open " << mprofDataFile << std::endl; @@ -136,7 +134,14 @@ int MplProfDataParser::ReadMapleProfileData() { profData = mempool->New(mempool, &alloc); // read .mprofdata std::ifstream inputStream(mprofDataFile, (std::ios::in | std::ios::binary)); - CHECK_FATAL(inputStream, "Could not open the file %s, quit\n", mprofDataFile.c_str()); + if (!inputStream) { + if (opts::missingProfDataIsError) { + CHECK_FATAL(inputStream, "Could not open profile data file %s, quit\n", mprofDataFile.c_str()); + } else { + WARN(kLncWarn, "Could not open profile data file %s\n", mprofDataFile.c_str()); + } + return 1; + } // get length of file static_cast(inputStream.seekg(0, std::ios::end)); uint32_t length = static_cast(inputStream.tellg()); @@ -175,6 +180,9 @@ void MMplProfDataParser::GetAnalysisDependence(AnalysisDep &aDep) const { bool MMplProfDataParser::PhaseRun(maple::MIRModule &m) { MemPool *memPool = m.GetMemPool(); // use global pool to store profile data bool enableDebug = false; // true to dump trace + if (m.GetFunctionList().empty()) { + return false; // there is no executable code + } MplProfDataParser parser(m, memPool, enableDebug); int res = parser.ReadMapleProfileData(); if (res) { -- Gitee From 9d88e06455c8dd30d01a0fec97ebd9c6e20b507e Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Thu, 6 Oct 2022 22:20:37 -0700 Subject: [PATCH 02/22] Some additional PGO-related fixes --- src/mapleall/maple_ipa/src/ipa_clone.cpp | 6 ++++++ src/mapleall/maple_me/src/me_cfg.cpp | 19 ++++++++++++++----- .../maple_me/src/me_loop_inversion.cpp | 1 - src/mapleall/maple_me/src/optimizeCFG.cpp | 7 +++++-- src/mapleall/maple_me/src/pme_emit.cpp | 2 +- .../mpl2mpl/src/mpl_profdata_parser.cpp | 4 ++-- 6 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/mapleall/maple_ipa/src/ipa_clone.cpp b/src/mapleall/maple_ipa/src/ipa_clone.cpp index 929a3977b2..a030db068a 100644 --- a/src/mapleall/maple_ipa/src/ipa_clone.cpp +++ b/src/mapleall/maple_ipa/src/ipa_clone.cpp @@ -395,6 +395,9 @@ void IpaClone::DecideCloneFunction(std::vector &result, uint32 paramInd if (oldCallNode == nullptr) { continue; } + if (callerFunc->GetFuncProfData() == nullptr) { + continue; + } uint64_t callsiteFreq = callerFunc->GetFuncProfData()->GetStmtFreq(stmtId); clonedSiteFreqs += callsiteFreq; } @@ -546,6 +549,9 @@ void IpaClone::CloneNoImportantExpressFunction(MIRFunction *func, uint32 paramIn if (oldCallNode == nullptr) { continue; } + if (callerFunc->GetFuncProfData() == nullptr) { + continue; + } uint64_t callsiteFreq = callerFunc->GetFuncProfData()->GetStmtFreq(stmtId); clonedSiteFreqs += callsiteFreq; } diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index 2d8a4ed49a..33c6be7082 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -1546,9 +1546,9 @@ void MeCFG::CreateBasicBlocks() { curBB->SetBBLabel(labelIdx); // label node is not real node in bb, get frequency information to bb if (Options::profileUse && func.GetMirFunc()->GetFuncProfData()) { - auto freq = func.GetMirFunc()->GetFuncProfData()->GetStmtFreq(stmt->GetStmtID()); + int64 freq = func.GetMirFunc()->GetFuncProfData()->GetStmtFreq(stmt->GetStmtID()); if (freq >= 0) { - curBB->SetFrequency(freq); + curBB->SetFrequency(static_cast(freq)); } } break; @@ -1928,9 +1928,18 @@ void MeCFG::ConstructBBFreqFromStmtFreq() { } else if (funcData->stmtFreqs.count(last.GetStmtID()) > 0) { (*bIt)->SetFrequency(funcData->stmtFreqs[last.GetStmtID()]); } else { - LogInfo::MapleLogger() << "ERROR:: bb " << (*bIt)->GetBBId() << "frequency is not set" - << "\n"; - ASSERT(0, "no freq set"); + bool foundFreq = false; + for (StmtNode &stmt : (*bIt)->GetStmtNodes()) { + if (funcData->stmtFreqs.count(stmt.GetStmtID()) > 0) { + (*bIt)->SetFrequency(funcData->stmtFreqs[stmt.GetStmtID()]); + foundFreq = true; + break; + } + } + if (not foundFreq) { + LogInfo::MapleLogger() << "ERROR:: bb " << (*bIt)->GetBBId() << " has not stmt with set freq" << "\n"; + CHECK_FATAL(0, "MeCFG::ConstructBBFreqFromStmtFreq: cannot set BB freq"); + } } } // add common entry and common exit diff --git a/src/mapleall/maple_me/src/me_loop_inversion.cpp b/src/mapleall/maple_me/src/me_loop_inversion.cpp index 9616adf642..8e09de97c9 100644 --- a/src/mapleall/maple_me/src/me_loop_inversion.cpp +++ b/src/mapleall/maple_me/src/me_loop_inversion.cpp @@ -243,7 +243,6 @@ void MeLoopInversion::Convert(MeFunction &func, BB &bb, BB &pred, MapleMapGetFrequency() == 0, "sanity check"); latchBB->PushBackSuccFreq(0); latchBB->PushBackSuccFreq(0); } diff --git a/src/mapleall/maple_me/src/optimizeCFG.cpp b/src/mapleall/maple_me/src/optimizeCFG.cpp index a01ee97b68..991030daa3 100644 --- a/src/mapleall/maple_me/src/optimizeCFG.cpp +++ b/src/mapleall/maple_me/src/optimizeCFG.cpp @@ -1904,8 +1904,11 @@ bool OptimizeBB::SkipRedundantCond(BB &pred, BB &succ) { idx = succ.GetSuccIndex(*affectedBB); ASSERT(idx >= 0 && idx < succ.GetSucc().size(), "sanity check"); int64_t oldedgeFreq = static_cast(succ.GetSuccFreq()[static_cast(idx)]); - ASSERT(oldedgeFreq >= freq, "sanity check"); - succ.SetSuccFreq(idx, static_cast(oldedgeFreq) - freq); + if (oldedgeFreq >= freq) { + succ.SetSuccFreq(idx, static_cast(oldedgeFreq) - freq); + } else { + succ.SetSuccFreq(idx, 0); + } } return true; } diff --git a/src/mapleall/maple_me/src/pme_emit.cpp b/src/mapleall/maple_me/src/pme_emit.cpp index 928446b366..db98e6c0fa 100644 --- a/src/mapleall/maple_me/src/pme_emit.cpp +++ b/src/mapleall/maple_me/src/pme_emit.cpp @@ -833,7 +833,7 @@ void PreMeEmitter::EmitBB(BB *bb, BlockNode *curBlk) { if (setLastFreq) { GetFuncProfData()->SetStmtFreq(curBlk->GetLast()->GetStmtID(), bb->GetFrequency()); } else if (bbIsEmpty) { - LogInfo::MapleLogger() << " bb " << bb->GetBBId() << "no stmt used to add frequency, add commentnode\n"; + LogInfo::MapleLogger() << " bb " << bb->GetBBId() << ": no stmt used to add frequency; added comment node\n"; CommentNode *commentNode = codeMP->New(*(mirFunc->GetModule())); commentNode->SetComment("freqStmt"+std::to_string(commentNode->GetStmtID())); GetFuncProfData()->SetStmtFreq(commentNode->GetStmtID(), bb->GetFrequency()); diff --git a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp index 8fac14a282..8d316ce631 100644 --- a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp +++ b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp @@ -146,8 +146,8 @@ int MplProfDataParser::ReadMapleProfileData() { static_cast(inputStream.seekg(0, std::ios::end)); uint32_t length = static_cast(inputStream.tellg()); static_cast(inputStream.seekg(0, std::ios::beg)); - const uint32_t sizeThreshold = 1024 * 10; - CHECK_FATAL(length <= sizeThreshold, "NYI::large .mprofdata file size is larger than threashold, do chunk memory\n"); +//const uint32_t sizeThreshold = 1024 * 10; +//CHECK_FATAL(length <= sizeThreshold, "NYI::large .mprofdata file size is larger than threashold, do chunk memory\n"); std::unique_ptr buffer = std::make_unique(length); static_cast(inputStream.read(buffer.get(), length)); -- Gitee From a51d0985d089ee5a5a081841e2d3c9f49b214f63 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Fri, 7 Oct 2022 16:25:37 -0700 Subject: [PATCH 03/22] Under -O0, make --patch-long-branch the default so 502.gcc_s can be built under --profileGen --- src/mapleall/maple_be/include/cg/cg.h | 2 +- src/mapleall/maple_me/src/me_profile_use.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mapleall/maple_be/include/cg/cg.h b/src/mapleall/maple_be/include/cg/cg.h index 1def4dc50a..4fd607dd25 100644 --- a/src/mapleall/maple_be/include/cg/cg.h +++ b/src/mapleall/maple_be/include/cg/cg.h @@ -214,7 +214,7 @@ class CG { } bool DoPatchLongBranch() const { - return cgOption.DoPatchLongBranch(); + return cgOption.DoPatchLongBranch() || (Globals::GetInstance()->GetOptimLevel() == CGOptions::kLevel0); } uint8 GetRematLevel() const { diff --git a/src/mapleall/maple_me/src/me_profile_use.cpp b/src/mapleall/maple_me/src/me_profile_use.cpp index d43fa03e73..d22d98e97a 100644 --- a/src/mapleall/maple_me/src/me_profile_use.cpp +++ b/src/mapleall/maple_me/src/me_profile_use.cpp @@ -103,7 +103,7 @@ void MeProfUse::ComputeEdgeFreq() { while (change) { change = false; pass++; - CHECK_FATAL(pass != UINT8_MAX, "parse all edges fail"); + CHECK_FATAL(pass != UINT16_MAX, "too many passes in MeProfUse::ComputeEdgeFreq: %d", pass); /* * use the bb edge to infer the bb's count,when all bb's count is valid * then all edges count is valid -- Gitee From 2d57ff839d2c3f074bf6b4ca0ba6c5c6130cca39 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Thu, 6 Oct 2022 05:31:33 -0700 Subject: [PATCH 04/22] Fixed the path of the profile file name written in .s under --profileGen so GCOV_PREFIX_STRIP can work correctly Fixed the interpretation of GCOV_PREFIX and GCOV_PREFIX_STRIP under --profileUse. Added new flag --missing-profdata-is-error (default is true) which means the compiler will complain under --profileUse if the .mprofdata file is not found. Specifying --no-missing-profdata-is-error will change it to just emitting a warning. Under --profileUse, do not look for .mprofdata file when the file has no executable code. Changed inlinter to not inline when profile data indicates the callee is not executed. Removed an assertion in PreMeMIRLower:LowerWhileStmt(). Made FuncProfInfo::SetStmtFreq() treat freq value of -1 to mean no freq info. In loopvec phase, update remainder loop freq to 0 (previously no freq). --- .../maple_driver/include/driver_options.h | 1 + .../maple_driver/src/driver_options.cpp | 6 +++ src/mapleall/maple_ir/include/mir_module.h | 12 +---- src/mapleall/maple_ir/src/mir_lower.cpp | 3 ++ src/mapleall/maple_ir/src/mir_module.cpp | 17 +++++++ src/mapleall/maple_me/src/lfo_loop_vec.cpp | 5 +++ src/mapleall/maple_me/src/me_cfg.cpp | 16 ++++--- .../maple_me/src/me_value_range_prop.cpp | 1 - src/mapleall/maple_me/src/pme_mir_lower.cpp | 3 +- .../maple_util/include/mpl_profdata.h | 3 ++ src/mapleall/mpl2mpl/src/gen_profile.cpp | 4 +- src/mapleall/mpl2mpl/src/inline.cpp | 9 +++- .../mpl2mpl/src/mpl_profdata_parser.cpp | 44 +++++++++++-------- 13 files changed, 83 insertions(+), 41 deletions(-) diff --git a/src/mapleall/maple_driver/include/driver_options.h b/src/mapleall/maple_driver/include/driver_options.h index 7798e14091..5b04c6414e 100644 --- a/src/mapleall/maple_driver/include/driver_options.h +++ b/src/mapleall/maple_driver/include/driver_options.h @@ -72,6 +72,7 @@ extern maplecl::Option genMapleBC; extern maplecl::Option genLMBC; extern maplecl::Option profileGen; extern maplecl::Option profileUse; +extern maplecl::Option missingProfDataIsError; extern maplecl::Option stackProtectorStrong; extern maplecl::Option stackProtectorAll; diff --git a/src/mapleall/maple_driver/src/driver_options.cpp b/src/mapleall/maple_driver/src/driver_options.cpp index c159d57f1e..dc694aaef9 100644 --- a/src/mapleall/maple_driver/src/driver_options.cpp +++ b/src/mapleall/maple_driver/src/driver_options.cpp @@ -171,6 +171,12 @@ maplecl::Option profileUse({"--profileUse"}, " --profileUse \tOptimize static languages with profile data\n", {driverCategory, mpl2mplCategory}); +maplecl::Option missingProfDataIsError({"--missing-profdata-is-error"}, + " --missing-profdata-is-error \tTreat missing profile data file as error\n" + " --no-missing-profdata-is-error \tOnly warn on missing profile data file\n", + {driverCategory}, + maplecl::DisableWith("--no-missing-profdata-is-error"), + maplecl::Init(true)); maplecl::Option stackProtectorStrong({"--stack-protector-strong"}, " --stack-protector-strong \tadd stack guard for some function\n", {driverCategory, meCategory, cgCategory}); diff --git a/src/mapleall/maple_ir/include/mir_module.h b/src/mapleall/maple_ir/include/mir_module.h index 83eae82df7..e09c84e554 100644 --- a/src/mapleall/maple_ir/include/mir_module.h +++ b/src/mapleall/maple_ir/include/mir_module.h @@ -344,21 +344,11 @@ class MIRModule { } std::string GetFileNameAsPostfix() const; + std::string GetFileNameWithPath() const; void SetFileName(const std::string &name) { fileName = name; } - std::string GetProfileDataFileName() const { - std::string profileDataFileName = GetFileName().substr(0, GetFileName().find_last_of(".")); - const char *gcovPath = std::getenv("GCOV_PREFIX"); - std::string gcovPrefix = gcovPath ? gcovPath : ""; - if (!gcovPrefix.empty() && (gcovPrefix.back() != '/')) { - gcovPrefix.append("/"); - } - profileDataFileName = gcovPrefix + profileDataFileName; - return profileDataFileName; - } - bool IsJavaModule() const { return srcLang == kSrcLangJava; } diff --git a/src/mapleall/maple_ir/src/mir_lower.cpp b/src/mapleall/maple_ir/src/mir_lower.cpp index 389dc6fc87..a7cbef418e 100644 --- a/src/mapleall/maple_ir/src/mir_lower.cpp +++ b/src/mapleall/maple_ir/src/mir_lower.cpp @@ -404,6 +404,9 @@ BlockNode *MIRLower::LowerDoloopStmt(DoloopNode &doloop) { if (GetFuncProfData()) { doloopnodeFreq = static_cast(GetFuncProfData()->GetStmtFreq(doloop.GetStmtID())); bodynodeFreq = static_cast(GetFuncProfData()->GetStmtFreq(doloop.GetDoBody()->GetStmtID())); + if (doloopnodeFreq < bodynodeFreq) { + doloopnodeFreq = bodynodeFreq; + } } auto *blk = mirModule.CurFuncCodeMemPool()->New(); if (doloop.IsPreg()) { diff --git a/src/mapleall/maple_ir/src/mir_module.cpp b/src/mapleall/maple_ir/src/mir_module.cpp index 334216779e..8e53cfaf03 100644 --- a/src/mapleall/maple_ir/src/mir_module.cpp +++ b/src/mapleall/maple_ir/src/mir_module.cpp @@ -747,6 +747,23 @@ std::string MIRModule::GetFileNameAsPostfix() const { return fileNameStr; } +std::string MIRModule::GetFileNameWithPath() const { + MIRInfoPair fileInfoElem = fileInfo.front(); + std::string fileNameWithoutPath = GlobalTables::GetStrTable().GetStringFromStrIdx(fileInfoElem.second); + // strip out the suffix + fileNameWithoutPath = fileNameWithoutPath.substr(0, fileNameWithoutPath.find_last_of(".")); + std::string fileNameWithPath; + // find the right entry because some entries are for included files + for (size_t i = 0; i < srcFileInfo.size(); ++i) { + MIRInfoPair infoElem = srcFileInfo[i]; + fileNameWithPath = GlobalTables::GetStrTable().GetStringFromStrIdx(infoElem.first); + if (fileNameWithPath.find(fileNameWithoutPath) != std::string::npos) { + break; + } + } + return fileNameWithPath; +} + void MIRModule::AddClass(TyIdx tyIdx) { (void)classList.insert(tyIdx); } diff --git a/src/mapleall/maple_me/src/lfo_loop_vec.cpp b/src/mapleall/maple_me/src/lfo_loop_vec.cpp index 189a49ec6e..17e548f7e6 100644 --- a/src/mapleall/maple_me/src/lfo_loop_vec.cpp +++ b/src/mapleall/maple_me/src/lfo_loop_vec.cpp @@ -1754,6 +1754,11 @@ DoloopNode *LoopVectorization::PrepareDoloop(DoloopNode *doloop, LoopTransPlan * ASSERT(parent && (parent->GetOpCode() == OP_block), "nullptr check"); BlockNode *pblock = static_cast(parent); pblock->InsertAfter(doloop, edoloop); + auto *profData = mirFunc->GetFuncProfData(); + if (profData) { + profData->SetStmtFreq(edoloop->GetStmtID(), 0); + profData->SetStmtFreq(edoloop->GetDoBody()->GetStmtID(), 0); + } } return doloop; } diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index 4b3547b7a7..2d8a4ed49a 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -1875,15 +1875,20 @@ void MeCFG::ConstructEdgeFreqFromBBFreq() { if (fallthru->GetPred().size() == 1) { auto succ0Freq = fallthru->GetFrequency(); bb->PushBackSuccFreq(succ0Freq); - ASSERT(bb->GetFrequency() + 1 >= succ0Freq, "sanity check"); - bb->PushBackSuccFreq(bb->GetFrequency() - succ0Freq); + if (bb->GetFrequency() > succ0Freq) { + bb->PushBackSuccFreq(bb->GetFrequency() - succ0Freq); + } else { + bb->PushBackSuccFreq(0); + } } else if (targetBB->GetPred().size() == 1) { auto succ1Freq = targetBB->GetFrequency(); - ASSERT(bb->GetFrequency() >= succ1Freq, "sanity check"); if (bb->GetAttributes(kBBAttrWontExit) && bb->GetSuccFreq().size() == 1) { // special case: WontExitAnalysis() has pushed 0 to bb->succFreq bb->GetSuccFreq()[0] = bb->GetFrequency(); bb->PushBackSuccFreq(0); + } else if (bb->GetFrequency() >= succ1Freq) { // tolerate inaccuracy + bb->PushBackSuccFreq(0); + bb->PushBackSuccFreq(bb->GetFrequency()); } else { bb->PushBackSuccFreq(bb->GetFrequency() - succ1Freq); bb->PushBackSuccFreq(succ1Freq); @@ -1917,10 +1922,11 @@ void MeCFG::ConstructBBFreqFromStmtFreq() { for (auto bIt = valid_begin(); bIt != eIt; ++bIt) { if ((*bIt)->IsEmpty()) continue; StmtNode &first = (*bIt)->GetFirst(); + StmtNode &last = (*bIt)->GetLast(); if (funcData->stmtFreqs.count(first.GetStmtID()) > 0) { (*bIt)->SetFrequency(funcData->stmtFreqs[first.GetStmtID()]); - } else if (funcData->stmtFreqs.count((*bIt)->GetLast().GetStmtID()) > 0) { - (*bIt)->SetFrequency(funcData->stmtFreqs[(*bIt)->GetLast().GetStmtID()]); + } else if (funcData->stmtFreqs.count(last.GetStmtID()) > 0) { + (*bIt)->SetFrequency(funcData->stmtFreqs[last.GetStmtID()]); } else { LogInfo::MapleLogger() << "ERROR:: bb " << (*bIt)->GetBBId() << "frequency is not set" << "\n"; diff --git a/src/mapleall/maple_me/src/me_value_range_prop.cpp b/src/mapleall/maple_me/src/me_value_range_prop.cpp index 44af1ab942..ac594edbf8 100644 --- a/src/mapleall/maple_me/src/me_value_range_prop.cpp +++ b/src/mapleall/maple_me/src/me_value_range_prop.cpp @@ -3923,7 +3923,6 @@ bool ValueRangePropagation::RemoveTheEdgeOfPredBB( uint64 edgeFreq = 0; if (func.GetCfg()->UpdateCFGFreq()) { edgeFreq = pred.GetSuccFreq()[index]; - ASSERT(bb.GetFrequency() >= edgeFreq, "sanity check"); } pred.RemoveSucc(bb); DeleteThePhiNodeWhichOnlyHasOneOpnd(bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); diff --git a/src/mapleall/maple_me/src/pme_mir_lower.cpp b/src/mapleall/maple_me/src/pme_mir_lower.cpp index 048ff7464a..994f9929b6 100644 --- a/src/mapleall/maple_me/src/pme_mir_lower.cpp +++ b/src/mapleall/maple_me/src/pme_mir_lower.cpp @@ -73,8 +73,7 @@ BlockNode *PreMeMIRLower::LowerWhileStmt(WhileStmtNode &whileStmt) { if (GetFuncProfData()) { int64_t freq = GetFuncProfData()->GetStmtFreq(whileStmt.GetStmtID()) - GetFuncProfData()->GetStmtFreq(whilegotonode->GetStmtID()); - ASSERT(freq >= 0, "sanity check"); - GetFuncProfData()->SetStmtFreq(endlblstmt->GetStmtID(), freq); + GetFuncProfData()->SetStmtFreq(endlblstmt->GetStmtID(), freq > 0 ? freq : 0); } return blk; } diff --git a/src/mapleall/maple_util/include/mpl_profdata.h b/src/mapleall/maple_util/include/mpl_profdata.h index 23cf6f99b9..767bbf2ea4 100644 --- a/src/mapleall/maple_util/include/mpl_profdata.h +++ b/src/mapleall/maple_util/include/mpl_profdata.h @@ -130,6 +130,9 @@ class FuncProfInfo { return -1; // unstored } void SetStmtFreq(uint32_t stmtID, uint64_t freq) { + if (static_cast(freq) == -1) { + return; + } stmtFreqs[stmtID] = freq; } void EraseStmtFreq(uint32_t stmtID) { diff --git a/src/mapleall/mpl2mpl/src/gen_profile.cpp b/src/mapleall/mpl2mpl/src/gen_profile.cpp index a54af1b99d..26783fd50a 100644 --- a/src/mapleall/mpl2mpl/src/gen_profile.cpp +++ b/src/mapleall/mpl2mpl/src/gen_profile.cpp @@ -103,9 +103,9 @@ void ProfileGen::CreateModProfDesc() { MIRIntConst *checksumMirConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst(cfgChkSum, *u32Ty); modProfDescSymMirConst->AddItem(checksumMirConst, 5); + std::string fileNameWithPath = mod.GetFileNameWithPath(); // Make the profile file name as fileName.gcda - std::string profFileName = mod.GetFileName().substr(0, mod.GetFileName().find_last_of(".")) + - namemangler::kProfFileNameExt; + std::string profFileName = fileNameWithPath.substr(0, fileNameWithPath.find_last_of(".")) + namemangler::kProfFileNameExt; auto *profileFNMirConst = modMP->New(profFileName, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(PTY_a64))); modProfDescSymMirConst->AddItem(profileFNMirConst, 6); diff --git a/src/mapleall/mpl2mpl/src/inline.cpp b/src/mapleall/mpl2mpl/src/inline.cpp index 8f0694170f..ad6ad38673 100644 --- a/src/mapleall/mpl2mpl/src/inline.cpp +++ b/src/mapleall/mpl2mpl/src/inline.cpp @@ -532,8 +532,13 @@ void MInline::InlineCallsBlockInternal(MIRFunction &func, BaseNode &baseNode, bo InlineResult result; result.reason = GetInlineFailedStr(failCode); if (canInline) { - result = AnalyzeCallee(func, *callee, callStmt); - canInline = result.canInline; + if (Options::profileUse && callee->GetFuncProfData() == nullptr) { + // callee is never executed according to profile data + canInline = false; + } else { + result = AnalyzeCallee(func, *callee, callStmt); + canInline = result.canInline; + } } if (canInline) { module.SetCurFunction(&func); diff --git a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp index 1d0ed18d7f..8fac14a282 100644 --- a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp +++ b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp @@ -87,6 +87,7 @@ int MplProfDataParser::ReadMapleProfileData() { std::string mprofDataFile = Options::profile; if (mprofDataFile.empty()) { if (const char *envGcovprefix = std::getenv("GCOV_PREFIX")) { + std::string fileNameWithPath = m.GetFileNameWithPath(); static_cast(mprofDataFile.append(envGcovprefix)); if (mprofDataFile.back() != '/') { static_cast(mprofDataFile.append("/")); @@ -102,33 +103,30 @@ int MplProfDataParser::ReadMapleProfileData() { LogInfo::MapleLogger() << "set env GCOV_PREFIX_STRIP=" << strip << std::endl; } } - std::string profDataFileName = m.GetProfileDataFileName(); - if (dumpDetail) { - LogInfo::MapleLogger() << "profdata file stem before strip: " << profDataFileName << std::endl; - } - // reduce path in profDataFileName - while (stripnum > 0 && profDataFileName.size() > 1) { - size_t pos = profDataFileName.find_first_of("/", 1); + // strip path in fileNameWithPath according to stripnum + while (stripnum > 0 && fileNameWithPath.size() > 1) { + size_t pos = fileNameWithPath.find_first_of("/", 1); if (pos == std::string::npos) { break; } - profDataFileName = profDataFileName.substr(pos); + fileNameWithPath= fileNameWithPath.substr(pos); stripnum--; } if (dumpDetail) { - LogInfo::MapleLogger() << "profdata file stem after strip: " << profDataFileName << std::endl; + LogInfo::MapleLogger() << "profdata file stem after strip: " << fileNameWithPath<< std::endl; } - CHECK_FATAL(profDataFileName.size() > 0, "sanity check"); - static_cast(mprofDataFile.append(profDataFileName)); + CHECK_FATAL(fileNameWithPath.size() > 0, "sanity check"); + static_cast(mprofDataFile.append(fileNameWithPath)); } else { - // if gcov_prefix is not set, find .mprofdata according to m.profiledata - mprofDataFile = m.GetProfileDataFileName(); - if (dumpDetail) { - LogInfo::MapleLogger() << "NO ENV, profdata file stem: " << mprofDataFile << std::endl; + mprofDataFile = m.GetFileName(); + // strip path in mprofDataFile + size_t pos = mprofDataFile.find_last_of("/"); + if (pos != std::string::npos) { + mprofDataFile = mprofDataFile.substr(pos+1); } } - // add .mprofdata - static_cast(mprofDataFile.append(namemangler::kMplProfFileNameExt)); + // change the suffix to .mprofdata + mprofDataFile = mprofDataFile.substr(0, mprofDataFile.find_last_of(".")) + namemangler::kMplProfFileNameExt; } ASSERT(!mprofDataFile.empty(), "null check"); LogInfo::MapleLogger() << "profileUse will open " << mprofDataFile << std::endl; @@ -136,7 +134,14 @@ int MplProfDataParser::ReadMapleProfileData() { profData = mempool->New(mempool, &alloc); // read .mprofdata std::ifstream inputStream(mprofDataFile, (std::ios::in | std::ios::binary)); - CHECK_FATAL(inputStream, "Could not open the file %s, quit\n", mprofDataFile.c_str()); + if (!inputStream) { + if (opts::missingProfDataIsError) { + CHECK_FATAL(inputStream, "Could not open profile data file %s, quit\n", mprofDataFile.c_str()); + } else { + WARN(kLncWarn, "Could not open profile data file %s\n", mprofDataFile.c_str()); + } + return 1; + } // get length of file static_cast(inputStream.seekg(0, std::ios::end)); uint32_t length = static_cast(inputStream.tellg()); @@ -175,6 +180,9 @@ void MMplProfDataParser::GetAnalysisDependence(AnalysisDep &aDep) const { bool MMplProfDataParser::PhaseRun(maple::MIRModule &m) { MemPool *memPool = m.GetMemPool(); // use global pool to store profile data bool enableDebug = false; // true to dump trace + if (m.GetFunctionList().empty()) { + return false; // there is no executable code + } MplProfDataParser parser(m, memPool, enableDebug); int res = parser.ReadMapleProfileData(); if (res) { -- Gitee From 72ee7fe3829e6567d8e1d1a70aaf93628a85be88 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Thu, 6 Oct 2022 22:20:37 -0700 Subject: [PATCH 05/22] Some additional PGO-related fixes --- src/mapleall/maple_ipa/src/ipa_clone.cpp | 6 ++++++ src/mapleall/maple_me/src/me_cfg.cpp | 19 ++++++++++++++----- .../maple_me/src/me_loop_inversion.cpp | 1 - src/mapleall/maple_me/src/optimizeCFG.cpp | 7 +++++-- src/mapleall/maple_me/src/pme_emit.cpp | 2 +- .../mpl2mpl/src/mpl_profdata_parser.cpp | 4 ++-- 6 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/mapleall/maple_ipa/src/ipa_clone.cpp b/src/mapleall/maple_ipa/src/ipa_clone.cpp index 929a3977b2..a030db068a 100644 --- a/src/mapleall/maple_ipa/src/ipa_clone.cpp +++ b/src/mapleall/maple_ipa/src/ipa_clone.cpp @@ -395,6 +395,9 @@ void IpaClone::DecideCloneFunction(std::vector &result, uint32 paramInd if (oldCallNode == nullptr) { continue; } + if (callerFunc->GetFuncProfData() == nullptr) { + continue; + } uint64_t callsiteFreq = callerFunc->GetFuncProfData()->GetStmtFreq(stmtId); clonedSiteFreqs += callsiteFreq; } @@ -546,6 +549,9 @@ void IpaClone::CloneNoImportantExpressFunction(MIRFunction *func, uint32 paramIn if (oldCallNode == nullptr) { continue; } + if (callerFunc->GetFuncProfData() == nullptr) { + continue; + } uint64_t callsiteFreq = callerFunc->GetFuncProfData()->GetStmtFreq(stmtId); clonedSiteFreqs += callsiteFreq; } diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index 2d8a4ed49a..33c6be7082 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -1546,9 +1546,9 @@ void MeCFG::CreateBasicBlocks() { curBB->SetBBLabel(labelIdx); // label node is not real node in bb, get frequency information to bb if (Options::profileUse && func.GetMirFunc()->GetFuncProfData()) { - auto freq = func.GetMirFunc()->GetFuncProfData()->GetStmtFreq(stmt->GetStmtID()); + int64 freq = func.GetMirFunc()->GetFuncProfData()->GetStmtFreq(stmt->GetStmtID()); if (freq >= 0) { - curBB->SetFrequency(freq); + curBB->SetFrequency(static_cast(freq)); } } break; @@ -1928,9 +1928,18 @@ void MeCFG::ConstructBBFreqFromStmtFreq() { } else if (funcData->stmtFreqs.count(last.GetStmtID()) > 0) { (*bIt)->SetFrequency(funcData->stmtFreqs[last.GetStmtID()]); } else { - LogInfo::MapleLogger() << "ERROR:: bb " << (*bIt)->GetBBId() << "frequency is not set" - << "\n"; - ASSERT(0, "no freq set"); + bool foundFreq = false; + for (StmtNode &stmt : (*bIt)->GetStmtNodes()) { + if (funcData->stmtFreqs.count(stmt.GetStmtID()) > 0) { + (*bIt)->SetFrequency(funcData->stmtFreqs[stmt.GetStmtID()]); + foundFreq = true; + break; + } + } + if (not foundFreq) { + LogInfo::MapleLogger() << "ERROR:: bb " << (*bIt)->GetBBId() << " has not stmt with set freq" << "\n"; + CHECK_FATAL(0, "MeCFG::ConstructBBFreqFromStmtFreq: cannot set BB freq"); + } } } // add common entry and common exit diff --git a/src/mapleall/maple_me/src/me_loop_inversion.cpp b/src/mapleall/maple_me/src/me_loop_inversion.cpp index fddacb87d9..7a615caf77 100644 --- a/src/mapleall/maple_me/src/me_loop_inversion.cpp +++ b/src/mapleall/maple_me/src/me_loop_inversion.cpp @@ -243,7 +243,6 @@ void MeLoopInversion::Convert(MeFunction &func, BB &bb, BB &pred, MapleMapGetFrequency() == 0, "sanity check"); latchBB->PushBackSuccFreq(0); latchBB->PushBackSuccFreq(0); } diff --git a/src/mapleall/maple_me/src/optimizeCFG.cpp b/src/mapleall/maple_me/src/optimizeCFG.cpp index a6c6826b31..ec8ccdcd97 100644 --- a/src/mapleall/maple_me/src/optimizeCFG.cpp +++ b/src/mapleall/maple_me/src/optimizeCFG.cpp @@ -1904,8 +1904,11 @@ bool OptimizeBB::SkipRedundantCond(BB &pred, BB &succ) { idx = succ.GetSuccIndex(*affectedBB); ASSERT(idx >= 0 && idx < succ.GetSucc().size(), "sanity check"); int64_t oldedgeFreq = static_cast(succ.GetSuccFreq()[static_cast(idx)]); - ASSERT(oldedgeFreq >= freq, "sanity check"); - succ.SetSuccFreq(idx, static_cast(oldedgeFreq) - freq); + if (oldedgeFreq >= freq) { + succ.SetSuccFreq(idx, static_cast(oldedgeFreq) - freq); + } else { + succ.SetSuccFreq(idx, 0); + } } return true; } diff --git a/src/mapleall/maple_me/src/pme_emit.cpp b/src/mapleall/maple_me/src/pme_emit.cpp index 928446b366..db98e6c0fa 100644 --- a/src/mapleall/maple_me/src/pme_emit.cpp +++ b/src/mapleall/maple_me/src/pme_emit.cpp @@ -833,7 +833,7 @@ void PreMeEmitter::EmitBB(BB *bb, BlockNode *curBlk) { if (setLastFreq) { GetFuncProfData()->SetStmtFreq(curBlk->GetLast()->GetStmtID(), bb->GetFrequency()); } else if (bbIsEmpty) { - LogInfo::MapleLogger() << " bb " << bb->GetBBId() << "no stmt used to add frequency, add commentnode\n"; + LogInfo::MapleLogger() << " bb " << bb->GetBBId() << ": no stmt used to add frequency; added comment node\n"; CommentNode *commentNode = codeMP->New(*(mirFunc->GetModule())); commentNode->SetComment("freqStmt"+std::to_string(commentNode->GetStmtID())); GetFuncProfData()->SetStmtFreq(commentNode->GetStmtID(), bb->GetFrequency()); diff --git a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp index 8fac14a282..8d316ce631 100644 --- a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp +++ b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp @@ -146,8 +146,8 @@ int MplProfDataParser::ReadMapleProfileData() { static_cast(inputStream.seekg(0, std::ios::end)); uint32_t length = static_cast(inputStream.tellg()); static_cast(inputStream.seekg(0, std::ios::beg)); - const uint32_t sizeThreshold = 1024 * 10; - CHECK_FATAL(length <= sizeThreshold, "NYI::large .mprofdata file size is larger than threashold, do chunk memory\n"); +//const uint32_t sizeThreshold = 1024 * 10; +//CHECK_FATAL(length <= sizeThreshold, "NYI::large .mprofdata file size is larger than threashold, do chunk memory\n"); std::unique_ptr buffer = std::make_unique(length); static_cast(inputStream.read(buffer.get(), length)); -- Gitee From 2c19ff23066b7826e38686b824e50a13b6269e6d Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Fri, 7 Oct 2022 16:25:37 -0700 Subject: [PATCH 06/22] Under -O0, make --patch-long-branch the default so 502.gcc_s can be built under --profileGen --- src/mapleall/maple_be/include/cg/cg.h | 2 +- src/mapleall/maple_me/src/me_profile_use.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mapleall/maple_be/include/cg/cg.h b/src/mapleall/maple_be/include/cg/cg.h index e24f4ebf85..56750dd559 100644 --- a/src/mapleall/maple_be/include/cg/cg.h +++ b/src/mapleall/maple_be/include/cg/cg.h @@ -201,7 +201,7 @@ class CG { } bool DoPatchLongBranch() const { - return cgOption.DoPatchLongBranch(); + return cgOption.DoPatchLongBranch() || (Globals::GetInstance()->GetOptimLevel() == CGOptions::kLevel0); } uint8 GetRematLevel() const { diff --git a/src/mapleall/maple_me/src/me_profile_use.cpp b/src/mapleall/maple_me/src/me_profile_use.cpp index d43fa03e73..d22d98e97a 100644 --- a/src/mapleall/maple_me/src/me_profile_use.cpp +++ b/src/mapleall/maple_me/src/me_profile_use.cpp @@ -103,7 +103,7 @@ void MeProfUse::ComputeEdgeFreq() { while (change) { change = false; pass++; - CHECK_FATAL(pass != UINT8_MAX, "parse all edges fail"); + CHECK_FATAL(pass != UINT16_MAX, "too many passes in MeProfUse::ComputeEdgeFreq: %d", pass); /* * use the bb edge to infer the bb's count,when all bb's count is valid * then all edges count is valid -- Gitee From fef82e0878b731fcf2ba6b4a0ba8de1eb77b1efe Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Thu, 6 Oct 2022 05:31:33 -0700 Subject: [PATCH 07/22] Fixed the path of the profile file name written in .s under --profileGen so GCOV_PREFIX_STRIP can work correctly Fixed the interpretation of GCOV_PREFIX and GCOV_PREFIX_STRIP under --profileUse. Added new flag --missing-profdata-is-error (default is true) which means the compiler will complain under --profileUse if the .mprofdata file is not found. Specifying --no-missing-profdata-is-error will change it to just emitting a warning. Under --profileUse, do not look for .mprofdata file when the file has no executable code. Changed inlinter to not inline when profile data indicates the callee is not executed. Removed an assertion in PreMeMIRLower:LowerWhileStmt(). Made FuncProfInfo::SetStmtFreq() treat freq value of -1 to mean no freq info. In loopvec phase, update remainder loop freq to 0 (previously no freq). --- .../maple_driver/include/driver_options.h | 1 + .../maple_driver/src/driver_options.cpp | 6 +++ src/mapleall/maple_ir/include/mir_module.h | 12 +---- src/mapleall/maple_ir/src/mir_lower.cpp | 3 ++ src/mapleall/maple_ir/src/mir_module.cpp | 17 +++++++ src/mapleall/maple_me/src/lfo_loop_vec.cpp | 5 +++ src/mapleall/maple_me/src/me_cfg.cpp | 16 ++++--- .../maple_me/src/me_value_range_prop.cpp | 1 - src/mapleall/maple_me/src/pme_mir_lower.cpp | 3 +- .../maple_util/include/mpl_profdata.h | 3 ++ src/mapleall/mpl2mpl/src/gen_profile.cpp | 4 +- src/mapleall/mpl2mpl/src/inline.cpp | 9 +++- .../mpl2mpl/src/mpl_profdata_parser.cpp | 44 +++++++++++-------- 13 files changed, 83 insertions(+), 41 deletions(-) diff --git a/src/mapleall/maple_driver/include/driver_options.h b/src/mapleall/maple_driver/include/driver_options.h index 61a57df5d8..a7dbccfd73 100644 --- a/src/mapleall/maple_driver/include/driver_options.h +++ b/src/mapleall/maple_driver/include/driver_options.h @@ -72,6 +72,7 @@ extern maplecl::Option genMapleBC; extern maplecl::Option genLMBC; extern maplecl::Option profileGen; extern maplecl::Option profileUse; +extern maplecl::Option missingProfDataIsError; extern maplecl::Option stackProtectorStrong; extern maplecl::Option stackProtectorAll; extern maplecl::Option inlineAsWeak; diff --git a/src/mapleall/maple_driver/src/driver_options.cpp b/src/mapleall/maple_driver/src/driver_options.cpp index 1f035bc54b..33b4a04bb1 100644 --- a/src/mapleall/maple_driver/src/driver_options.cpp +++ b/src/mapleall/maple_driver/src/driver_options.cpp @@ -171,6 +171,12 @@ maplecl::Option profileUse({"--profileUse"}, " --profileUse \tOptimize static languages with profile data\n", {driverCategory, mpl2mplCategory}); +maplecl::Option missingProfDataIsError({"--missing-profdata-is-error"}, + " --missing-profdata-is-error \tTreat missing profile data file as error\n" + " --no-missing-profdata-is-error \tOnly warn on missing profile data file\n", + {driverCategory}, + maplecl::DisableWith("--no-missing-profdata-is-error"), + maplecl::Init(true)); maplecl::Option stackProtectorStrong({"--stack-protector-strong"}, " --stack-protector-strong \tadd stack guard for some function\n", {driverCategory, meCategory, cgCategory}); diff --git a/src/mapleall/maple_ir/include/mir_module.h b/src/mapleall/maple_ir/include/mir_module.h index 83eae82df7..e09c84e554 100644 --- a/src/mapleall/maple_ir/include/mir_module.h +++ b/src/mapleall/maple_ir/include/mir_module.h @@ -344,21 +344,11 @@ class MIRModule { } std::string GetFileNameAsPostfix() const; + std::string GetFileNameWithPath() const; void SetFileName(const std::string &name) { fileName = name; } - std::string GetProfileDataFileName() const { - std::string profileDataFileName = GetFileName().substr(0, GetFileName().find_last_of(".")); - const char *gcovPath = std::getenv("GCOV_PREFIX"); - std::string gcovPrefix = gcovPath ? gcovPath : ""; - if (!gcovPrefix.empty() && (gcovPrefix.back() != '/')) { - gcovPrefix.append("/"); - } - profileDataFileName = gcovPrefix + profileDataFileName; - return profileDataFileName; - } - bool IsJavaModule() const { return srcLang == kSrcLangJava; } diff --git a/src/mapleall/maple_ir/src/mir_lower.cpp b/src/mapleall/maple_ir/src/mir_lower.cpp index 389dc6fc87..a7cbef418e 100644 --- a/src/mapleall/maple_ir/src/mir_lower.cpp +++ b/src/mapleall/maple_ir/src/mir_lower.cpp @@ -404,6 +404,9 @@ BlockNode *MIRLower::LowerDoloopStmt(DoloopNode &doloop) { if (GetFuncProfData()) { doloopnodeFreq = static_cast(GetFuncProfData()->GetStmtFreq(doloop.GetStmtID())); bodynodeFreq = static_cast(GetFuncProfData()->GetStmtFreq(doloop.GetDoBody()->GetStmtID())); + if (doloopnodeFreq < bodynodeFreq) { + doloopnodeFreq = bodynodeFreq; + } } auto *blk = mirModule.CurFuncCodeMemPool()->New(); if (doloop.IsPreg()) { diff --git a/src/mapleall/maple_ir/src/mir_module.cpp b/src/mapleall/maple_ir/src/mir_module.cpp index 334216779e..8e53cfaf03 100644 --- a/src/mapleall/maple_ir/src/mir_module.cpp +++ b/src/mapleall/maple_ir/src/mir_module.cpp @@ -747,6 +747,23 @@ std::string MIRModule::GetFileNameAsPostfix() const { return fileNameStr; } +std::string MIRModule::GetFileNameWithPath() const { + MIRInfoPair fileInfoElem = fileInfo.front(); + std::string fileNameWithoutPath = GlobalTables::GetStrTable().GetStringFromStrIdx(fileInfoElem.second); + // strip out the suffix + fileNameWithoutPath = fileNameWithoutPath.substr(0, fileNameWithoutPath.find_last_of(".")); + std::string fileNameWithPath; + // find the right entry because some entries are for included files + for (size_t i = 0; i < srcFileInfo.size(); ++i) { + MIRInfoPair infoElem = srcFileInfo[i]; + fileNameWithPath = GlobalTables::GetStrTable().GetStringFromStrIdx(infoElem.first); + if (fileNameWithPath.find(fileNameWithoutPath) != std::string::npos) { + break; + } + } + return fileNameWithPath; +} + void MIRModule::AddClass(TyIdx tyIdx) { (void)classList.insert(tyIdx); } diff --git a/src/mapleall/maple_me/src/lfo_loop_vec.cpp b/src/mapleall/maple_me/src/lfo_loop_vec.cpp index 189a49ec6e..17e548f7e6 100644 --- a/src/mapleall/maple_me/src/lfo_loop_vec.cpp +++ b/src/mapleall/maple_me/src/lfo_loop_vec.cpp @@ -1754,6 +1754,11 @@ DoloopNode *LoopVectorization::PrepareDoloop(DoloopNode *doloop, LoopTransPlan * ASSERT(parent && (parent->GetOpCode() == OP_block), "nullptr check"); BlockNode *pblock = static_cast(parent); pblock->InsertAfter(doloop, edoloop); + auto *profData = mirFunc->GetFuncProfData(); + if (profData) { + profData->SetStmtFreq(edoloop->GetStmtID(), 0); + profData->SetStmtFreq(edoloop->GetDoBody()->GetStmtID(), 0); + } } return doloop; } diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index 4b3547b7a7..2d8a4ed49a 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -1875,15 +1875,20 @@ void MeCFG::ConstructEdgeFreqFromBBFreq() { if (fallthru->GetPred().size() == 1) { auto succ0Freq = fallthru->GetFrequency(); bb->PushBackSuccFreq(succ0Freq); - ASSERT(bb->GetFrequency() + 1 >= succ0Freq, "sanity check"); - bb->PushBackSuccFreq(bb->GetFrequency() - succ0Freq); + if (bb->GetFrequency() > succ0Freq) { + bb->PushBackSuccFreq(bb->GetFrequency() - succ0Freq); + } else { + bb->PushBackSuccFreq(0); + } } else if (targetBB->GetPred().size() == 1) { auto succ1Freq = targetBB->GetFrequency(); - ASSERT(bb->GetFrequency() >= succ1Freq, "sanity check"); if (bb->GetAttributes(kBBAttrWontExit) && bb->GetSuccFreq().size() == 1) { // special case: WontExitAnalysis() has pushed 0 to bb->succFreq bb->GetSuccFreq()[0] = bb->GetFrequency(); bb->PushBackSuccFreq(0); + } else if (bb->GetFrequency() >= succ1Freq) { // tolerate inaccuracy + bb->PushBackSuccFreq(0); + bb->PushBackSuccFreq(bb->GetFrequency()); } else { bb->PushBackSuccFreq(bb->GetFrequency() - succ1Freq); bb->PushBackSuccFreq(succ1Freq); @@ -1917,10 +1922,11 @@ void MeCFG::ConstructBBFreqFromStmtFreq() { for (auto bIt = valid_begin(); bIt != eIt; ++bIt) { if ((*bIt)->IsEmpty()) continue; StmtNode &first = (*bIt)->GetFirst(); + StmtNode &last = (*bIt)->GetLast(); if (funcData->stmtFreqs.count(first.GetStmtID()) > 0) { (*bIt)->SetFrequency(funcData->stmtFreqs[first.GetStmtID()]); - } else if (funcData->stmtFreqs.count((*bIt)->GetLast().GetStmtID()) > 0) { - (*bIt)->SetFrequency(funcData->stmtFreqs[(*bIt)->GetLast().GetStmtID()]); + } else if (funcData->stmtFreqs.count(last.GetStmtID()) > 0) { + (*bIt)->SetFrequency(funcData->stmtFreqs[last.GetStmtID()]); } else { LogInfo::MapleLogger() << "ERROR:: bb " << (*bIt)->GetBBId() << "frequency is not set" << "\n"; diff --git a/src/mapleall/maple_me/src/me_value_range_prop.cpp b/src/mapleall/maple_me/src/me_value_range_prop.cpp index 93ea6b8eb5..0b2c818b8b 100644 --- a/src/mapleall/maple_me/src/me_value_range_prop.cpp +++ b/src/mapleall/maple_me/src/me_value_range_prop.cpp @@ -3925,7 +3925,6 @@ bool ValueRangePropagation::RemoveTheEdgeOfPredBB( uint64 edgeFreq = 0; if (func.GetCfg()->UpdateCFGFreq()) { edgeFreq = pred.GetSuccFreq()[index]; - ASSERT(bb.GetFrequency() >= edgeFreq, "sanity check"); } pred.RemoveSucc(bb); DeleteThePhiNodeWhichOnlyHasOneOpnd(bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); diff --git a/src/mapleall/maple_me/src/pme_mir_lower.cpp b/src/mapleall/maple_me/src/pme_mir_lower.cpp index 048ff7464a..994f9929b6 100644 --- a/src/mapleall/maple_me/src/pme_mir_lower.cpp +++ b/src/mapleall/maple_me/src/pme_mir_lower.cpp @@ -73,8 +73,7 @@ BlockNode *PreMeMIRLower::LowerWhileStmt(WhileStmtNode &whileStmt) { if (GetFuncProfData()) { int64_t freq = GetFuncProfData()->GetStmtFreq(whileStmt.GetStmtID()) - GetFuncProfData()->GetStmtFreq(whilegotonode->GetStmtID()); - ASSERT(freq >= 0, "sanity check"); - GetFuncProfData()->SetStmtFreq(endlblstmt->GetStmtID(), freq); + GetFuncProfData()->SetStmtFreq(endlblstmt->GetStmtID(), freq > 0 ? freq : 0); } return blk; } diff --git a/src/mapleall/maple_util/include/mpl_profdata.h b/src/mapleall/maple_util/include/mpl_profdata.h index 23cf6f99b9..767bbf2ea4 100644 --- a/src/mapleall/maple_util/include/mpl_profdata.h +++ b/src/mapleall/maple_util/include/mpl_profdata.h @@ -130,6 +130,9 @@ class FuncProfInfo { return -1; // unstored } void SetStmtFreq(uint32_t stmtID, uint64_t freq) { + if (static_cast(freq) == -1) { + return; + } stmtFreqs[stmtID] = freq; } void EraseStmtFreq(uint32_t stmtID) { diff --git a/src/mapleall/mpl2mpl/src/gen_profile.cpp b/src/mapleall/mpl2mpl/src/gen_profile.cpp index a54af1b99d..26783fd50a 100644 --- a/src/mapleall/mpl2mpl/src/gen_profile.cpp +++ b/src/mapleall/mpl2mpl/src/gen_profile.cpp @@ -103,9 +103,9 @@ void ProfileGen::CreateModProfDesc() { MIRIntConst *checksumMirConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst(cfgChkSum, *u32Ty); modProfDescSymMirConst->AddItem(checksumMirConst, 5); + std::string fileNameWithPath = mod.GetFileNameWithPath(); // Make the profile file name as fileName.gcda - std::string profFileName = mod.GetFileName().substr(0, mod.GetFileName().find_last_of(".")) + - namemangler::kProfFileNameExt; + std::string profFileName = fileNameWithPath.substr(0, fileNameWithPath.find_last_of(".")) + namemangler::kProfFileNameExt; auto *profileFNMirConst = modMP->New(profFileName, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(PTY_a64))); modProfDescSymMirConst->AddItem(profileFNMirConst, 6); diff --git a/src/mapleall/mpl2mpl/src/inline.cpp b/src/mapleall/mpl2mpl/src/inline.cpp index 3c7a5871cf..9686a7e497 100644 --- a/src/mapleall/mpl2mpl/src/inline.cpp +++ b/src/mapleall/mpl2mpl/src/inline.cpp @@ -539,8 +539,13 @@ void MInline::InlineCallsBlockInternal(MIRFunction &func, BaseNode &baseNode, bo InlineResult result; result.reason = GetInlineFailedStr(failCode); if (canInline) { - result = AnalyzeCallee(func, *callee, callStmt); - canInline = result.canInline; + if (Options::profileUse && callee->GetFuncProfData() == nullptr) { + // callee is never executed according to profile data + canInline = false; + } else { + result = AnalyzeCallee(func, *callee, callStmt); + canInline = result.canInline; + } } if (canInline) { module.SetCurFunction(&func); diff --git a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp index 1d0ed18d7f..8fac14a282 100644 --- a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp +++ b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp @@ -87,6 +87,7 @@ int MplProfDataParser::ReadMapleProfileData() { std::string mprofDataFile = Options::profile; if (mprofDataFile.empty()) { if (const char *envGcovprefix = std::getenv("GCOV_PREFIX")) { + std::string fileNameWithPath = m.GetFileNameWithPath(); static_cast(mprofDataFile.append(envGcovprefix)); if (mprofDataFile.back() != '/') { static_cast(mprofDataFile.append("/")); @@ -102,33 +103,30 @@ int MplProfDataParser::ReadMapleProfileData() { LogInfo::MapleLogger() << "set env GCOV_PREFIX_STRIP=" << strip << std::endl; } } - std::string profDataFileName = m.GetProfileDataFileName(); - if (dumpDetail) { - LogInfo::MapleLogger() << "profdata file stem before strip: " << profDataFileName << std::endl; - } - // reduce path in profDataFileName - while (stripnum > 0 && profDataFileName.size() > 1) { - size_t pos = profDataFileName.find_first_of("/", 1); + // strip path in fileNameWithPath according to stripnum + while (stripnum > 0 && fileNameWithPath.size() > 1) { + size_t pos = fileNameWithPath.find_first_of("/", 1); if (pos == std::string::npos) { break; } - profDataFileName = profDataFileName.substr(pos); + fileNameWithPath= fileNameWithPath.substr(pos); stripnum--; } if (dumpDetail) { - LogInfo::MapleLogger() << "profdata file stem after strip: " << profDataFileName << std::endl; + LogInfo::MapleLogger() << "profdata file stem after strip: " << fileNameWithPath<< std::endl; } - CHECK_FATAL(profDataFileName.size() > 0, "sanity check"); - static_cast(mprofDataFile.append(profDataFileName)); + CHECK_FATAL(fileNameWithPath.size() > 0, "sanity check"); + static_cast(mprofDataFile.append(fileNameWithPath)); } else { - // if gcov_prefix is not set, find .mprofdata according to m.profiledata - mprofDataFile = m.GetProfileDataFileName(); - if (dumpDetail) { - LogInfo::MapleLogger() << "NO ENV, profdata file stem: " << mprofDataFile << std::endl; + mprofDataFile = m.GetFileName(); + // strip path in mprofDataFile + size_t pos = mprofDataFile.find_last_of("/"); + if (pos != std::string::npos) { + mprofDataFile = mprofDataFile.substr(pos+1); } } - // add .mprofdata - static_cast(mprofDataFile.append(namemangler::kMplProfFileNameExt)); + // change the suffix to .mprofdata + mprofDataFile = mprofDataFile.substr(0, mprofDataFile.find_last_of(".")) + namemangler::kMplProfFileNameExt; } ASSERT(!mprofDataFile.empty(), "null check"); LogInfo::MapleLogger() << "profileUse will open " << mprofDataFile << std::endl; @@ -136,7 +134,14 @@ int MplProfDataParser::ReadMapleProfileData() { profData = mempool->New(mempool, &alloc); // read .mprofdata std::ifstream inputStream(mprofDataFile, (std::ios::in | std::ios::binary)); - CHECK_FATAL(inputStream, "Could not open the file %s, quit\n", mprofDataFile.c_str()); + if (!inputStream) { + if (opts::missingProfDataIsError) { + CHECK_FATAL(inputStream, "Could not open profile data file %s, quit\n", mprofDataFile.c_str()); + } else { + WARN(kLncWarn, "Could not open profile data file %s\n", mprofDataFile.c_str()); + } + return 1; + } // get length of file static_cast(inputStream.seekg(0, std::ios::end)); uint32_t length = static_cast(inputStream.tellg()); @@ -175,6 +180,9 @@ void MMplProfDataParser::GetAnalysisDependence(AnalysisDep &aDep) const { bool MMplProfDataParser::PhaseRun(maple::MIRModule &m) { MemPool *memPool = m.GetMemPool(); // use global pool to store profile data bool enableDebug = false; // true to dump trace + if (m.GetFunctionList().empty()) { + return false; // there is no executable code + } MplProfDataParser parser(m, memPool, enableDebug); int res = parser.ReadMapleProfileData(); if (res) { -- Gitee From 8aea5dac5b348d7d8fac105e077fdd0d4065d65d Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Thu, 6 Oct 2022 22:20:37 -0700 Subject: [PATCH 08/22] Some additional PGO-related fixes --- src/mapleall/maple_ipa/src/ipa_clone.cpp | 6 ++++++ src/mapleall/maple_me/src/me_cfg.cpp | 19 ++++++++++++++----- .../maple_me/src/me_loop_inversion.cpp | 1 - src/mapleall/maple_me/src/optimizeCFG.cpp | 7 +++++-- src/mapleall/maple_me/src/pme_emit.cpp | 2 +- .../mpl2mpl/src/mpl_profdata_parser.cpp | 4 ++-- 6 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/mapleall/maple_ipa/src/ipa_clone.cpp b/src/mapleall/maple_ipa/src/ipa_clone.cpp index 929a3977b2..a030db068a 100644 --- a/src/mapleall/maple_ipa/src/ipa_clone.cpp +++ b/src/mapleall/maple_ipa/src/ipa_clone.cpp @@ -395,6 +395,9 @@ void IpaClone::DecideCloneFunction(std::vector &result, uint32 paramInd if (oldCallNode == nullptr) { continue; } + if (callerFunc->GetFuncProfData() == nullptr) { + continue; + } uint64_t callsiteFreq = callerFunc->GetFuncProfData()->GetStmtFreq(stmtId); clonedSiteFreqs += callsiteFreq; } @@ -546,6 +549,9 @@ void IpaClone::CloneNoImportantExpressFunction(MIRFunction *func, uint32 paramIn if (oldCallNode == nullptr) { continue; } + if (callerFunc->GetFuncProfData() == nullptr) { + continue; + } uint64_t callsiteFreq = callerFunc->GetFuncProfData()->GetStmtFreq(stmtId); clonedSiteFreqs += callsiteFreq; } diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index 2d8a4ed49a..33c6be7082 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -1546,9 +1546,9 @@ void MeCFG::CreateBasicBlocks() { curBB->SetBBLabel(labelIdx); // label node is not real node in bb, get frequency information to bb if (Options::profileUse && func.GetMirFunc()->GetFuncProfData()) { - auto freq = func.GetMirFunc()->GetFuncProfData()->GetStmtFreq(stmt->GetStmtID()); + int64 freq = func.GetMirFunc()->GetFuncProfData()->GetStmtFreq(stmt->GetStmtID()); if (freq >= 0) { - curBB->SetFrequency(freq); + curBB->SetFrequency(static_cast(freq)); } } break; @@ -1928,9 +1928,18 @@ void MeCFG::ConstructBBFreqFromStmtFreq() { } else if (funcData->stmtFreqs.count(last.GetStmtID()) > 0) { (*bIt)->SetFrequency(funcData->stmtFreqs[last.GetStmtID()]); } else { - LogInfo::MapleLogger() << "ERROR:: bb " << (*bIt)->GetBBId() << "frequency is not set" - << "\n"; - ASSERT(0, "no freq set"); + bool foundFreq = false; + for (StmtNode &stmt : (*bIt)->GetStmtNodes()) { + if (funcData->stmtFreqs.count(stmt.GetStmtID()) > 0) { + (*bIt)->SetFrequency(funcData->stmtFreqs[stmt.GetStmtID()]); + foundFreq = true; + break; + } + } + if (not foundFreq) { + LogInfo::MapleLogger() << "ERROR:: bb " << (*bIt)->GetBBId() << " has not stmt with set freq" << "\n"; + CHECK_FATAL(0, "MeCFG::ConstructBBFreqFromStmtFreq: cannot set BB freq"); + } } } // add common entry and common exit diff --git a/src/mapleall/maple_me/src/me_loop_inversion.cpp b/src/mapleall/maple_me/src/me_loop_inversion.cpp index fddacb87d9..7a615caf77 100644 --- a/src/mapleall/maple_me/src/me_loop_inversion.cpp +++ b/src/mapleall/maple_me/src/me_loop_inversion.cpp @@ -243,7 +243,6 @@ void MeLoopInversion::Convert(MeFunction &func, BB &bb, BB &pred, MapleMapGetFrequency() == 0, "sanity check"); latchBB->PushBackSuccFreq(0); latchBB->PushBackSuccFreq(0); } diff --git a/src/mapleall/maple_me/src/optimizeCFG.cpp b/src/mapleall/maple_me/src/optimizeCFG.cpp index a6c6826b31..ec8ccdcd97 100644 --- a/src/mapleall/maple_me/src/optimizeCFG.cpp +++ b/src/mapleall/maple_me/src/optimizeCFG.cpp @@ -1904,8 +1904,11 @@ bool OptimizeBB::SkipRedundantCond(BB &pred, BB &succ) { idx = succ.GetSuccIndex(*affectedBB); ASSERT(idx >= 0 && idx < succ.GetSucc().size(), "sanity check"); int64_t oldedgeFreq = static_cast(succ.GetSuccFreq()[static_cast(idx)]); - ASSERT(oldedgeFreq >= freq, "sanity check"); - succ.SetSuccFreq(idx, static_cast(oldedgeFreq) - freq); + if (oldedgeFreq >= freq) { + succ.SetSuccFreq(idx, static_cast(oldedgeFreq) - freq); + } else { + succ.SetSuccFreq(idx, 0); + } } return true; } diff --git a/src/mapleall/maple_me/src/pme_emit.cpp b/src/mapleall/maple_me/src/pme_emit.cpp index d5cf1e015e..a567e52090 100644 --- a/src/mapleall/maple_me/src/pme_emit.cpp +++ b/src/mapleall/maple_me/src/pme_emit.cpp @@ -833,7 +833,7 @@ void PreMeEmitter::EmitBB(BB *bb, BlockNode *curBlk) { if (setLastFreq) { GetFuncProfData()->SetStmtFreq(curBlk->GetLast()->GetStmtID(), bb->GetFrequency()); } else if (bbIsEmpty) { - LogInfo::MapleLogger() << " bb " << bb->GetBBId() << "no stmt used to add frequency, add commentnode\n"; + LogInfo::MapleLogger() << " bb " << bb->GetBBId() << ": no stmt used to add frequency; added comment node\n"; CommentNode *commentNode = codeMP->New(*(mirFunc->GetModule())); commentNode->SetComment("freqStmt"+std::to_string(commentNode->GetStmtID())); GetFuncProfData()->SetStmtFreq(commentNode->GetStmtID(), bb->GetFrequency()); diff --git a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp index 8fac14a282..8d316ce631 100644 --- a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp +++ b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp @@ -146,8 +146,8 @@ int MplProfDataParser::ReadMapleProfileData() { static_cast(inputStream.seekg(0, std::ios::end)); uint32_t length = static_cast(inputStream.tellg()); static_cast(inputStream.seekg(0, std::ios::beg)); - const uint32_t sizeThreshold = 1024 * 10; - CHECK_FATAL(length <= sizeThreshold, "NYI::large .mprofdata file size is larger than threashold, do chunk memory\n"); +//const uint32_t sizeThreshold = 1024 * 10; +//CHECK_FATAL(length <= sizeThreshold, "NYI::large .mprofdata file size is larger than threashold, do chunk memory\n"); std::unique_ptr buffer = std::make_unique(length); static_cast(inputStream.read(buffer.get(), length)); -- Gitee From b6b6941b6ccdc64978573c141a4168e40ba89ded Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Fri, 7 Oct 2022 16:25:37 -0700 Subject: [PATCH 09/22] Under -O0, make --patch-long-branch the default so 502.gcc_s can be built under --profileGen --- src/mapleall/maple_be/include/cg/cg.h | 2 +- src/mapleall/maple_me/src/me_profile_use.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mapleall/maple_be/include/cg/cg.h b/src/mapleall/maple_be/include/cg/cg.h index e24f4ebf85..56750dd559 100644 --- a/src/mapleall/maple_be/include/cg/cg.h +++ b/src/mapleall/maple_be/include/cg/cg.h @@ -201,7 +201,7 @@ class CG { } bool DoPatchLongBranch() const { - return cgOption.DoPatchLongBranch(); + return cgOption.DoPatchLongBranch() || (Globals::GetInstance()->GetOptimLevel() == CGOptions::kLevel0); } uint8 GetRematLevel() const { diff --git a/src/mapleall/maple_me/src/me_profile_use.cpp b/src/mapleall/maple_me/src/me_profile_use.cpp index d43fa03e73..d22d98e97a 100644 --- a/src/mapleall/maple_me/src/me_profile_use.cpp +++ b/src/mapleall/maple_me/src/me_profile_use.cpp @@ -103,7 +103,7 @@ void MeProfUse::ComputeEdgeFreq() { while (change) { change = false; pass++; - CHECK_FATAL(pass != UINT8_MAX, "parse all edges fail"); + CHECK_FATAL(pass != UINT16_MAX, "too many passes in MeProfUse::ComputeEdgeFreq: %d", pass); /* * use the bb edge to infer the bb's count,when all bb's count is valid * then all edges count is valid -- Gitee From 9657be88359a2104ab9df95b41b2d9aa82593231 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Tue, 1 Nov 2022 23:42:30 -0700 Subject: [PATCH 10/22] Fixed coding style warnings --- src/mapleall/mpl2mpl/src/gen_profile.cpp | 3 ++- src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp | 4 +--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/mapleall/mpl2mpl/src/gen_profile.cpp b/src/mapleall/mpl2mpl/src/gen_profile.cpp index 26783fd50a..5741f7faa1 100644 --- a/src/mapleall/mpl2mpl/src/gen_profile.cpp +++ b/src/mapleall/mpl2mpl/src/gen_profile.cpp @@ -105,7 +105,8 @@ void ProfileGen::CreateModProfDesc() { std::string fileNameWithPath = mod.GetFileNameWithPath(); // Make the profile file name as fileName.gcda - std::string profFileName = fileNameWithPath.substr(0, fileNameWithPath.find_last_of(".")) + namemangler::kProfFileNameExt; + std::string profFileName = fileNameWithPath.substr(0, fileNameWithPath.find_last_of(".")) + + namemangler::kProfFileNameExt; auto *profileFNMirConst = modMP->New(profFileName, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(PTY_a64))); modProfDescSymMirConst->AddItem(profileFNMirConst, 6); diff --git a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp index 8d316ce631..a0702c4cf2 100644 --- a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp +++ b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp @@ -122,7 +122,7 @@ int MplProfDataParser::ReadMapleProfileData() { // strip path in mprofDataFile size_t pos = mprofDataFile.find_last_of("/"); if (pos != std::string::npos) { - mprofDataFile = mprofDataFile.substr(pos+1); + mprofDataFile = mprofDataFile.substr(pos + 1); } } // change the suffix to .mprofdata @@ -146,8 +146,6 @@ int MplProfDataParser::ReadMapleProfileData() { static_cast(inputStream.seekg(0, std::ios::end)); uint32_t length = static_cast(inputStream.tellg()); static_cast(inputStream.seekg(0, std::ios::beg)); -//const uint32_t sizeThreshold = 1024 * 10; -//CHECK_FATAL(length <= sizeThreshold, "NYI::large .mprofdata file size is larger than threashold, do chunk memory\n"); std::unique_ptr buffer = std::make_unique(length); static_cast(inputStream.read(buffer.get(), length)); -- Gitee From 6cfbf7a46a2617490e24ec30bcfd6734113fc849 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Thu, 6 Oct 2022 05:31:33 -0700 Subject: [PATCH 11/22] Fixed the path of the profile file name written in .s under --profileGen so GCOV_PREFIX_STRIP can work correctly Fixed the interpretation of GCOV_PREFIX and GCOV_PREFIX_STRIP under --profileUse. Added new flag --missing-profdata-is-error (default is true) which means the compiler will complain under --profileUse if the .mprofdata file is not found. Specifying --no-missing-profdata-is-error will change it to just emitting a warning. Under --profileUse, do not look for .mprofdata file when the file has no executable code. Changed inlinter to not inline when profile data indicates the callee is not executed. Removed an assertion in PreMeMIRLower:LowerWhileStmt(). Made FuncProfInfo::SetStmtFreq() treat freq value of -1 to mean no freq info. In loopvec phase, update remainder loop freq to 0 (previously no freq). --- .../maple_driver/include/driver_options.h | 1 + .../maple_driver/src/driver_options.cpp | 6 ++ src/mapleall/maple_ir/include/mir_module.h | 12 +--- src/mapleall/maple_ir/src/mir_lower.cpp | 3 + src/mapleall/maple_ir/src/mir_module.cpp | 17 +++++ src/mapleall/maple_me/src/lfo_loop_vec.cpp | 5 ++ src/mapleall/maple_me/src/me_cfg.cpp | 64 ++++++++++++++----- .../maple_me/src/me_value_range_prop.cpp | 1 - src/mapleall/maple_me/src/pme_mir_lower.cpp | 3 +- .../maple_util/include/mpl_profdata.h | 3 + src/mapleall/mpl2mpl/src/gen_profile.cpp | 4 +- src/mapleall/mpl2mpl/src/inline.cpp | 9 ++- .../mpl2mpl/src/mpl_profdata_parser.cpp | 44 +++++++------ 13 files changed, 119 insertions(+), 53 deletions(-) diff --git a/src/mapleall/maple_driver/include/driver_options.h b/src/mapleall/maple_driver/include/driver_options.h index 61a57df5d8..a7dbccfd73 100644 --- a/src/mapleall/maple_driver/include/driver_options.h +++ b/src/mapleall/maple_driver/include/driver_options.h @@ -72,6 +72,7 @@ extern maplecl::Option genMapleBC; extern maplecl::Option genLMBC; extern maplecl::Option profileGen; extern maplecl::Option profileUse; +extern maplecl::Option missingProfDataIsError; extern maplecl::Option stackProtectorStrong; extern maplecl::Option stackProtectorAll; extern maplecl::Option inlineAsWeak; diff --git a/src/mapleall/maple_driver/src/driver_options.cpp b/src/mapleall/maple_driver/src/driver_options.cpp index 1f035bc54b..33b4a04bb1 100644 --- a/src/mapleall/maple_driver/src/driver_options.cpp +++ b/src/mapleall/maple_driver/src/driver_options.cpp @@ -171,6 +171,12 @@ maplecl::Option profileUse({"--profileUse"}, " --profileUse \tOptimize static languages with profile data\n", {driverCategory, mpl2mplCategory}); +maplecl::Option missingProfDataIsError({"--missing-profdata-is-error"}, + " --missing-profdata-is-error \tTreat missing profile data file as error\n" + " --no-missing-profdata-is-error \tOnly warn on missing profile data file\n", + {driverCategory}, + maplecl::DisableWith("--no-missing-profdata-is-error"), + maplecl::Init(true)); maplecl::Option stackProtectorStrong({"--stack-protector-strong"}, " --stack-protector-strong \tadd stack guard for some function\n", {driverCategory, meCategory, cgCategory}); diff --git a/src/mapleall/maple_ir/include/mir_module.h b/src/mapleall/maple_ir/include/mir_module.h index 83eae82df7..e09c84e554 100644 --- a/src/mapleall/maple_ir/include/mir_module.h +++ b/src/mapleall/maple_ir/include/mir_module.h @@ -344,21 +344,11 @@ class MIRModule { } std::string GetFileNameAsPostfix() const; + std::string GetFileNameWithPath() const; void SetFileName(const std::string &name) { fileName = name; } - std::string GetProfileDataFileName() const { - std::string profileDataFileName = GetFileName().substr(0, GetFileName().find_last_of(".")); - const char *gcovPath = std::getenv("GCOV_PREFIX"); - std::string gcovPrefix = gcovPath ? gcovPath : ""; - if (!gcovPrefix.empty() && (gcovPrefix.back() != '/')) { - gcovPrefix.append("/"); - } - profileDataFileName = gcovPrefix + profileDataFileName; - return profileDataFileName; - } - bool IsJavaModule() const { return srcLang == kSrcLangJava; } diff --git a/src/mapleall/maple_ir/src/mir_lower.cpp b/src/mapleall/maple_ir/src/mir_lower.cpp index 389dc6fc87..a7cbef418e 100644 --- a/src/mapleall/maple_ir/src/mir_lower.cpp +++ b/src/mapleall/maple_ir/src/mir_lower.cpp @@ -404,6 +404,9 @@ BlockNode *MIRLower::LowerDoloopStmt(DoloopNode &doloop) { if (GetFuncProfData()) { doloopnodeFreq = static_cast(GetFuncProfData()->GetStmtFreq(doloop.GetStmtID())); bodynodeFreq = static_cast(GetFuncProfData()->GetStmtFreq(doloop.GetDoBody()->GetStmtID())); + if (doloopnodeFreq < bodynodeFreq) { + doloopnodeFreq = bodynodeFreq; + } } auto *blk = mirModule.CurFuncCodeMemPool()->New(); if (doloop.IsPreg()) { diff --git a/src/mapleall/maple_ir/src/mir_module.cpp b/src/mapleall/maple_ir/src/mir_module.cpp index 334216779e..8e53cfaf03 100644 --- a/src/mapleall/maple_ir/src/mir_module.cpp +++ b/src/mapleall/maple_ir/src/mir_module.cpp @@ -747,6 +747,23 @@ std::string MIRModule::GetFileNameAsPostfix() const { return fileNameStr; } +std::string MIRModule::GetFileNameWithPath() const { + MIRInfoPair fileInfoElem = fileInfo.front(); + std::string fileNameWithoutPath = GlobalTables::GetStrTable().GetStringFromStrIdx(fileInfoElem.second); + // strip out the suffix + fileNameWithoutPath = fileNameWithoutPath.substr(0, fileNameWithoutPath.find_last_of(".")); + std::string fileNameWithPath; + // find the right entry because some entries are for included files + for (size_t i = 0; i < srcFileInfo.size(); ++i) { + MIRInfoPair infoElem = srcFileInfo[i]; + fileNameWithPath = GlobalTables::GetStrTable().GetStringFromStrIdx(infoElem.first); + if (fileNameWithPath.find(fileNameWithoutPath) != std::string::npos) { + break; + } + } + return fileNameWithPath; +} + void MIRModule::AddClass(TyIdx tyIdx) { (void)classList.insert(tyIdx); } diff --git a/src/mapleall/maple_me/src/lfo_loop_vec.cpp b/src/mapleall/maple_me/src/lfo_loop_vec.cpp index b44c1fe97b..f68d321989 100644 --- a/src/mapleall/maple_me/src/lfo_loop_vec.cpp +++ b/src/mapleall/maple_me/src/lfo_loop_vec.cpp @@ -1750,6 +1750,11 @@ DoloopNode *LoopVectorization::PrepareDoloop(DoloopNode *doloop, LoopTransPlan * ASSERT(parent && (parent->GetOpCode() == OP_block), "nullptr check"); BlockNode *pblock = static_cast(parent); pblock->InsertAfter(doloop, edoloop); + auto *profData = mirFunc->GetFuncProfData(); + if (profData) { + profData->SetStmtFreq(edoloop->GetStmtID(), 0); + profData->SetStmtFreq(edoloop->GetDoBody()->GetStmtID(), 0); + } } return doloop; } diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index 202d51f7fe..0246e0c2c9 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -1553,9 +1553,9 @@ void MeCFG::CreateBasicBlocks() { curBB->SetBBLabel(labelIdx); // label node is not real node in bb, get frequency information to bb if (Options::profileUse && func.GetMirFunc()->GetFuncProfData()) { - auto freq = func.GetMirFunc()->GetFuncProfData()->GetStmtFreq(stmt->GetStmtID()); + int64 freq = func.GetMirFunc()->GetFuncProfData()->GetStmtFreq(stmt->GetStmtID()); if (freq >= 0) { - curBB->SetFrequency(freq); + curBB->SetFrequency(static_cast(freq)); } } break; @@ -1625,6 +1625,10 @@ void MeCFG::CreateBasicBlocks() { lastBB->SetFirst(func.GetMIRModule().GetMIRBuilder()->CreateStmtReturn(nullptr)); lastBB->SetLast(lastBB->GetStmtNodes().begin().d()); lastBB->SetKindReturn(); + if (updateFreq) { + FuncProfInfo *funcData = func.GetMirFunc()->GetFuncProfData(); + funcData->stmtFreqs[lastBB->GetLast().GetStmtID()] = 0; + } } else if (lastBB->GetKind() == kBBUnknown) { lastBB->SetKindReturn(); lastBB->SetAttributes(kBBAttrIsExit); @@ -1878,15 +1882,30 @@ void MeCFG::ConstructEdgeFreqFromBBFreq() { if (fallthru->GetPred().size() == 1) { auto succ0Freq = fallthru->GetFrequency(); bb->PushBackSuccFreq(succ0Freq); - ASSERT(bb->GetFrequency() >= succ0Freq, "sanity check"); - bb->PushBackSuccFreq(bb->GetFrequency() - succ0Freq); + if (bb->GetFrequency() > succ0Freq) { + bb->PushBackSuccFreq(bb->GetFrequency() - succ0Freq); + } else { + bb->PushBackSuccFreq(0); + } } else if (targetBB->GetPred().size() == 1) { auto succ1Freq = targetBB->GetFrequency(); - ASSERT(bb->GetFrequency() >= succ1Freq, "sanity check"); - bb->PushBackSuccFreq(bb->GetFrequency() - succ1Freq); - bb->PushBackSuccFreq(succ1Freq); + if (bb->GetAttributes(kBBAttrWontExit) && bb->GetSuccFreq().size() == 1) { + // special case: WontExitAnalysis() has pushed 0 to bb->succFreq + bb->GetSuccFreq()[0] = bb->GetFrequency(); + bb->PushBackSuccFreq(0); + } else if (bb->GetFrequency() >= succ1Freq) { // tolerate inaccuracy + bb->PushBackSuccFreq(0); + bb->PushBackSuccFreq(bb->GetFrequency()); + } else { + bb->PushBackSuccFreq(bb->GetFrequency() - succ1Freq); + bb->PushBackSuccFreq(succ1Freq); + } + } else if (fallthru->GetFrequency() > targetBB->GetFrequency()) { + bb->PushBackSuccFreq(bb->GetFrequency()); + bb->PushBackSuccFreq(0); } else { - CHECK_FATAL(false, "ConstructEdgeFreqFromBBFreq::NYI critical edge"); + bb->PushBackSuccFreq(0); + bb->PushBackSuccFreq(bb->GetFrequency()); } } else if (bb->GetSucc().size() > 2) { // switch case, no critical edge is supposted @@ -1910,14 +1929,24 @@ void MeCFG::ConstructBBFreqFromStmtFreq() { for (auto bIt = valid_begin(); bIt != eIt; ++bIt) { if ((*bIt)->IsEmpty()) continue; StmtNode &first = (*bIt)->GetFirst(); + StmtNode &last = (*bIt)->GetLast(); if (funcData->stmtFreqs.count(first.GetStmtID()) > 0) { (*bIt)->SetFrequency(funcData->stmtFreqs[first.GetStmtID()]); - } else if (funcData->stmtFreqs.count((*bIt)->GetLast().GetStmtID()) > 0) { - (*bIt)->SetFrequency(funcData->stmtFreqs[(*bIt)->GetLast().GetStmtID()]); + } else if (funcData->stmtFreqs.count(last.GetStmtID()) > 0) { + (*bIt)->SetFrequency(funcData->stmtFreqs[last.GetStmtID()]); } else { - LogInfo::MapleLogger() << "ERROR:: bb " << (*bIt)->GetBBId() << "frequency is not set" - << "\n"; - ASSERT(0, "no freq set"); + bool foundFreq = false; + for (StmtNode &stmt : (*bIt)->GetStmtNodes()) { + if (funcData->stmtFreqs.count(stmt.GetStmtID()) > 0) { + (*bIt)->SetFrequency(funcData->stmtFreqs[stmt.GetStmtID()]); + foundFreq = true; + break; + } + } + if (not foundFreq) { + LogInfo::MapleLogger() << "ERROR:: bb " << (*bIt)->GetBBId() << " has not stmt with set freq" << "\n"; + CHECK_FATAL(0, "MeCFG::ConstructBBFreqFromStmtFreq: cannot set BB freq"); + } } } // add common entry and common exit @@ -1937,9 +1966,6 @@ void MeCFG::ConstructBBFreqFromStmtFreq() { ConstructEdgeFreqFromBBFreq(); // clear stmtFreqs since cfg frequency is create funcData->stmtFreqs.clear(); - - // set updateFrequency with true - updateFreq = true; } void MeCFG::ConstructStmtFreq() { @@ -2086,6 +2112,10 @@ bool MEMeCfg::PhaseRun(MeFunction &f) { MemPool *meCfgMp = GetPhaseMemPool(); theCFG = meCfgMp->New(meCfgMp, f); f.SetTheCfg(theCFG); + + if (Options::profileUse && f.GetMirFunc()->GetFuncProfData()) { + theCFG->SetUpdateCFGFreq(true); + } theCFG->CreateBasicBlocks(); if (theCFG->NumBBs() == 0) { /* there's no basicblock generated */ @@ -2104,7 +2134,7 @@ bool MEMeCfg::PhaseRun(MeFunction &f) { } theCFG->Verify(); // construct bb freq from stmt freq - if (Options::profileUse && f.GetMirFunc()->GetFuncProfData()) { + if (theCFG->UpdateCFGFreq()) { theCFG->ConstructBBFreqFromStmtFreq(); if (theCFG->DumpIRProfileFile()) { std::string fileName = "after-mecfgbuild"; diff --git a/src/mapleall/maple_me/src/me_value_range_prop.cpp b/src/mapleall/maple_me/src/me_value_range_prop.cpp index 11e582d32f..5a23aafa8f 100644 --- a/src/mapleall/maple_me/src/me_value_range_prop.cpp +++ b/src/mapleall/maple_me/src/me_value_range_prop.cpp @@ -3925,7 +3925,6 @@ bool ValueRangePropagation::RemoveTheEdgeOfPredBB( uint64 edgeFreq = 0; if (func.GetCfg()->UpdateCFGFreq()) { edgeFreq = pred.GetSuccFreq()[index]; - ASSERT(bb.GetFrequency() >= edgeFreq, "sanity check"); } pred.RemoveSucc(bb); DeleteThePhiNodeWhichOnlyHasOneOpnd(bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); diff --git a/src/mapleall/maple_me/src/pme_mir_lower.cpp b/src/mapleall/maple_me/src/pme_mir_lower.cpp index e2a45d62d4..604a70ebf5 100644 --- a/src/mapleall/maple_me/src/pme_mir_lower.cpp +++ b/src/mapleall/maple_me/src/pme_mir_lower.cpp @@ -73,8 +73,7 @@ BlockNode *PreMeMIRLower::LowerWhileStmt(WhileStmtNode &whileStmt) { if (GetFuncProfData()) { int64_t freq = GetFuncProfData()->GetStmtFreq(whileStmt.GetStmtID()) - GetFuncProfData()->GetStmtFreq(whilegotonode->GetStmtID()); - ASSERT(freq >= 0, "sanity check"); - GetFuncProfData()->SetStmtFreq(endlblstmt->GetStmtID(), freq); + GetFuncProfData()->SetStmtFreq(endlblstmt->GetStmtID(), freq > 0 ? freq : 0); } return blk; } diff --git a/src/mapleall/maple_util/include/mpl_profdata.h b/src/mapleall/maple_util/include/mpl_profdata.h index 23cf6f99b9..767bbf2ea4 100644 --- a/src/mapleall/maple_util/include/mpl_profdata.h +++ b/src/mapleall/maple_util/include/mpl_profdata.h @@ -130,6 +130,9 @@ class FuncProfInfo { return -1; // unstored } void SetStmtFreq(uint32_t stmtID, uint64_t freq) { + if (static_cast(freq) == -1) { + return; + } stmtFreqs[stmtID] = freq; } void EraseStmtFreq(uint32_t stmtID) { diff --git a/src/mapleall/mpl2mpl/src/gen_profile.cpp b/src/mapleall/mpl2mpl/src/gen_profile.cpp index a54af1b99d..26783fd50a 100644 --- a/src/mapleall/mpl2mpl/src/gen_profile.cpp +++ b/src/mapleall/mpl2mpl/src/gen_profile.cpp @@ -103,9 +103,9 @@ void ProfileGen::CreateModProfDesc() { MIRIntConst *checksumMirConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst(cfgChkSum, *u32Ty); modProfDescSymMirConst->AddItem(checksumMirConst, 5); + std::string fileNameWithPath = mod.GetFileNameWithPath(); // Make the profile file name as fileName.gcda - std::string profFileName = mod.GetFileName().substr(0, mod.GetFileName().find_last_of(".")) + - namemangler::kProfFileNameExt; + std::string profFileName = fileNameWithPath.substr(0, fileNameWithPath.find_last_of(".")) + namemangler::kProfFileNameExt; auto *profileFNMirConst = modMP->New(profFileName, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(PTY_a64))); modProfDescSymMirConst->AddItem(profileFNMirConst, 6); diff --git a/src/mapleall/mpl2mpl/src/inline.cpp b/src/mapleall/mpl2mpl/src/inline.cpp index 3c7a5871cf..9686a7e497 100644 --- a/src/mapleall/mpl2mpl/src/inline.cpp +++ b/src/mapleall/mpl2mpl/src/inline.cpp @@ -539,8 +539,13 @@ void MInline::InlineCallsBlockInternal(MIRFunction &func, BaseNode &baseNode, bo InlineResult result; result.reason = GetInlineFailedStr(failCode); if (canInline) { - result = AnalyzeCallee(func, *callee, callStmt); - canInline = result.canInline; + if (Options::profileUse && callee->GetFuncProfData() == nullptr) { + // callee is never executed according to profile data + canInline = false; + } else { + result = AnalyzeCallee(func, *callee, callStmt); + canInline = result.canInline; + } } if (canInline) { module.SetCurFunction(&func); diff --git a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp index 1d0ed18d7f..8fac14a282 100644 --- a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp +++ b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp @@ -87,6 +87,7 @@ int MplProfDataParser::ReadMapleProfileData() { std::string mprofDataFile = Options::profile; if (mprofDataFile.empty()) { if (const char *envGcovprefix = std::getenv("GCOV_PREFIX")) { + std::string fileNameWithPath = m.GetFileNameWithPath(); static_cast(mprofDataFile.append(envGcovprefix)); if (mprofDataFile.back() != '/') { static_cast(mprofDataFile.append("/")); @@ -102,33 +103,30 @@ int MplProfDataParser::ReadMapleProfileData() { LogInfo::MapleLogger() << "set env GCOV_PREFIX_STRIP=" << strip << std::endl; } } - std::string profDataFileName = m.GetProfileDataFileName(); - if (dumpDetail) { - LogInfo::MapleLogger() << "profdata file stem before strip: " << profDataFileName << std::endl; - } - // reduce path in profDataFileName - while (stripnum > 0 && profDataFileName.size() > 1) { - size_t pos = profDataFileName.find_first_of("/", 1); + // strip path in fileNameWithPath according to stripnum + while (stripnum > 0 && fileNameWithPath.size() > 1) { + size_t pos = fileNameWithPath.find_first_of("/", 1); if (pos == std::string::npos) { break; } - profDataFileName = profDataFileName.substr(pos); + fileNameWithPath= fileNameWithPath.substr(pos); stripnum--; } if (dumpDetail) { - LogInfo::MapleLogger() << "profdata file stem after strip: " << profDataFileName << std::endl; + LogInfo::MapleLogger() << "profdata file stem after strip: " << fileNameWithPath<< std::endl; } - CHECK_FATAL(profDataFileName.size() > 0, "sanity check"); - static_cast(mprofDataFile.append(profDataFileName)); + CHECK_FATAL(fileNameWithPath.size() > 0, "sanity check"); + static_cast(mprofDataFile.append(fileNameWithPath)); } else { - // if gcov_prefix is not set, find .mprofdata according to m.profiledata - mprofDataFile = m.GetProfileDataFileName(); - if (dumpDetail) { - LogInfo::MapleLogger() << "NO ENV, profdata file stem: " << mprofDataFile << std::endl; + mprofDataFile = m.GetFileName(); + // strip path in mprofDataFile + size_t pos = mprofDataFile.find_last_of("/"); + if (pos != std::string::npos) { + mprofDataFile = mprofDataFile.substr(pos+1); } } - // add .mprofdata - static_cast(mprofDataFile.append(namemangler::kMplProfFileNameExt)); + // change the suffix to .mprofdata + mprofDataFile = mprofDataFile.substr(0, mprofDataFile.find_last_of(".")) + namemangler::kMplProfFileNameExt; } ASSERT(!mprofDataFile.empty(), "null check"); LogInfo::MapleLogger() << "profileUse will open " << mprofDataFile << std::endl; @@ -136,7 +134,14 @@ int MplProfDataParser::ReadMapleProfileData() { profData = mempool->New(mempool, &alloc); // read .mprofdata std::ifstream inputStream(mprofDataFile, (std::ios::in | std::ios::binary)); - CHECK_FATAL(inputStream, "Could not open the file %s, quit\n", mprofDataFile.c_str()); + if (!inputStream) { + if (opts::missingProfDataIsError) { + CHECK_FATAL(inputStream, "Could not open profile data file %s, quit\n", mprofDataFile.c_str()); + } else { + WARN(kLncWarn, "Could not open profile data file %s\n", mprofDataFile.c_str()); + } + return 1; + } // get length of file static_cast(inputStream.seekg(0, std::ios::end)); uint32_t length = static_cast(inputStream.tellg()); @@ -175,6 +180,9 @@ void MMplProfDataParser::GetAnalysisDependence(AnalysisDep &aDep) const { bool MMplProfDataParser::PhaseRun(maple::MIRModule &m) { MemPool *memPool = m.GetMemPool(); // use global pool to store profile data bool enableDebug = false; // true to dump trace + if (m.GetFunctionList().empty()) { + return false; // there is no executable code + } MplProfDataParser parser(m, memPool, enableDebug); int res = parser.ReadMapleProfileData(); if (res) { -- Gitee From a832bafe96fd1dc408880908b22ce912a7d4716f Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Thu, 6 Oct 2022 22:20:37 -0700 Subject: [PATCH 12/22] Some additional PGO-related fixes --- src/mapleall/maple_ipa/src/ipa_clone.cpp | 6 ++++++ src/mapleall/maple_me/src/me_loop_inversion.cpp | 1 - src/mapleall/maple_me/src/optimizeCFG.cpp | 7 +++++-- src/mapleall/maple_me/src/pme_emit.cpp | 2 +- src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp | 4 ++-- 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/mapleall/maple_ipa/src/ipa_clone.cpp b/src/mapleall/maple_ipa/src/ipa_clone.cpp index f164000454..fcbcf84c83 100644 --- a/src/mapleall/maple_ipa/src/ipa_clone.cpp +++ b/src/mapleall/maple_ipa/src/ipa_clone.cpp @@ -395,6 +395,9 @@ void IpaClone::DecideCloneFunction(std::vector &result, uint32 paramInd if (oldCallNode == nullptr) { continue; } + if (callerFunc->GetFuncProfData() == nullptr) { + continue; + } uint64_t callsiteFreq = callerFunc->GetFuncProfData()->GetStmtFreq(stmtId); clonedSiteFreqs += callsiteFreq; } @@ -546,6 +549,9 @@ void IpaClone::CloneNoImportantExpressFunction(MIRFunction *func, uint32 paramIn if (oldCallNode == nullptr) { continue; } + if (callerFunc->GetFuncProfData() == nullptr) { + continue; + } uint64_t callsiteFreq = callerFunc->GetFuncProfData()->GetStmtFreq(stmtId); clonedSiteFreqs += callsiteFreq; } diff --git a/src/mapleall/maple_me/src/me_loop_inversion.cpp b/src/mapleall/maple_me/src/me_loop_inversion.cpp index fddacb87d9..7a615caf77 100644 --- a/src/mapleall/maple_me/src/me_loop_inversion.cpp +++ b/src/mapleall/maple_me/src/me_loop_inversion.cpp @@ -243,7 +243,6 @@ void MeLoopInversion::Convert(MeFunction &func, BB &bb, BB &pred, MapleMapGetFrequency() == 0, "sanity check"); latchBB->PushBackSuccFreq(0); latchBB->PushBackSuccFreq(0); } diff --git a/src/mapleall/maple_me/src/optimizeCFG.cpp b/src/mapleall/maple_me/src/optimizeCFG.cpp index 5a5d02ec19..3c21bfc4c2 100644 --- a/src/mapleall/maple_me/src/optimizeCFG.cpp +++ b/src/mapleall/maple_me/src/optimizeCFG.cpp @@ -1908,8 +1908,11 @@ bool OptimizeBB::SkipRedundantCond(BB &pred, BB &succ) { idx = succ.GetSuccIndex(*affectedBB); ASSERT(idx >= 0 && idx < succ.GetSucc().size(), "sanity check"); int64_t oldedgeFreq = static_cast(succ.GetSuccFreq()[static_cast(idx)]); - ASSERT(oldedgeFreq >= freq, "sanity check"); - succ.SetSuccFreq(idx, static_cast(oldedgeFreq) - freq); + if (oldedgeFreq >= freq) { + succ.SetSuccFreq(idx, static_cast(oldedgeFreq) - freq); + } else { + succ.SetSuccFreq(idx, 0); + } } return true; } diff --git a/src/mapleall/maple_me/src/pme_emit.cpp b/src/mapleall/maple_me/src/pme_emit.cpp index 5a9fa5e4c4..b27b1d7e94 100644 --- a/src/mapleall/maple_me/src/pme_emit.cpp +++ b/src/mapleall/maple_me/src/pme_emit.cpp @@ -829,7 +829,7 @@ void PreMeEmitter::EmitBB(BB *bb, BlockNode *curBlk) { if (setLastFreq) { GetFuncProfData()->SetStmtFreq(curBlk->GetLast()->GetStmtID(), bb->GetFrequency()); } else if (bbIsEmpty) { - LogInfo::MapleLogger() << " bb " << bb->GetBBId() << "no stmt used to add frequency, add commentnode\n"; + LogInfo::MapleLogger() << " bb " << bb->GetBBId() << ": no stmt used to add frequency; added comment node\n"; CommentNode *commentNode = codeMP->New(*(mirFunc->GetModule())); commentNode->SetComment("freqStmt"+std::to_string(commentNode->GetStmtID())); GetFuncProfData()->SetStmtFreq(commentNode->GetStmtID(), bb->GetFrequency()); diff --git a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp index 8fac14a282..8d316ce631 100644 --- a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp +++ b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp @@ -146,8 +146,8 @@ int MplProfDataParser::ReadMapleProfileData() { static_cast(inputStream.seekg(0, std::ios::end)); uint32_t length = static_cast(inputStream.tellg()); static_cast(inputStream.seekg(0, std::ios::beg)); - const uint32_t sizeThreshold = 1024 * 10; - CHECK_FATAL(length <= sizeThreshold, "NYI::large .mprofdata file size is larger than threashold, do chunk memory\n"); +//const uint32_t sizeThreshold = 1024 * 10; +//CHECK_FATAL(length <= sizeThreshold, "NYI::large .mprofdata file size is larger than threashold, do chunk memory\n"); std::unique_ptr buffer = std::make_unique(length); static_cast(inputStream.read(buffer.get(), length)); -- Gitee From c5706508c15a61106bedaaca84d11c4ddb4bd20c Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Fri, 7 Oct 2022 16:25:37 -0700 Subject: [PATCH 13/22] Under -O0, make --patch-long-branch the default so 502.gcc_s can be built under --profileGen --- src/mapleall/maple_be/include/cg/cg.h | 2 +- src/mapleall/maple_me/src/me_profile_use.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mapleall/maple_be/include/cg/cg.h b/src/mapleall/maple_be/include/cg/cg.h index 8cc3b4e74a..5c48b3cff7 100644 --- a/src/mapleall/maple_be/include/cg/cg.h +++ b/src/mapleall/maple_be/include/cg/cg.h @@ -201,7 +201,7 @@ class CG { } bool DoPatchLongBranch() const { - return cgOption.DoPatchLongBranch(); + return cgOption.DoPatchLongBranch() || (Globals::GetInstance()->GetOptimLevel() == CGOptions::kLevel0); } uint8 GetRematLevel() const { diff --git a/src/mapleall/maple_me/src/me_profile_use.cpp b/src/mapleall/maple_me/src/me_profile_use.cpp index d43fa03e73..d22d98e97a 100644 --- a/src/mapleall/maple_me/src/me_profile_use.cpp +++ b/src/mapleall/maple_me/src/me_profile_use.cpp @@ -103,7 +103,7 @@ void MeProfUse::ComputeEdgeFreq() { while (change) { change = false; pass++; - CHECK_FATAL(pass != UINT8_MAX, "parse all edges fail"); + CHECK_FATAL(pass != UINT16_MAX, "too many passes in MeProfUse::ComputeEdgeFreq: %d", pass); /* * use the bb edge to infer the bb's count,when all bb's count is valid * then all edges count is valid -- Gitee From 1ef489acd625cbfceb2339c43bc18fcca746c0b0 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Tue, 1 Nov 2022 23:42:30 -0700 Subject: [PATCH 14/22] Fixed coding style warnings --- src/mapleall/mpl2mpl/src/gen_profile.cpp | 3 ++- src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp | 4 +--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/mapleall/mpl2mpl/src/gen_profile.cpp b/src/mapleall/mpl2mpl/src/gen_profile.cpp index 26783fd50a..5741f7faa1 100644 --- a/src/mapleall/mpl2mpl/src/gen_profile.cpp +++ b/src/mapleall/mpl2mpl/src/gen_profile.cpp @@ -105,7 +105,8 @@ void ProfileGen::CreateModProfDesc() { std::string fileNameWithPath = mod.GetFileNameWithPath(); // Make the profile file name as fileName.gcda - std::string profFileName = fileNameWithPath.substr(0, fileNameWithPath.find_last_of(".")) + namemangler::kProfFileNameExt; + std::string profFileName = fileNameWithPath.substr(0, fileNameWithPath.find_last_of(".")) + + namemangler::kProfFileNameExt; auto *profileFNMirConst = modMP->New(profFileName, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(PTY_a64))); modProfDescSymMirConst->AddItem(profileFNMirConst, 6); diff --git a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp index 8d316ce631..a0702c4cf2 100644 --- a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp +++ b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp @@ -122,7 +122,7 @@ int MplProfDataParser::ReadMapleProfileData() { // strip path in mprofDataFile size_t pos = mprofDataFile.find_last_of("/"); if (pos != std::string::npos) { - mprofDataFile = mprofDataFile.substr(pos+1); + mprofDataFile = mprofDataFile.substr(pos + 1); } } // change the suffix to .mprofdata @@ -146,8 +146,6 @@ int MplProfDataParser::ReadMapleProfileData() { static_cast(inputStream.seekg(0, std::ios::end)); uint32_t length = static_cast(inputStream.tellg()); static_cast(inputStream.seekg(0, std::ios::beg)); -//const uint32_t sizeThreshold = 1024 * 10; -//CHECK_FATAL(length <= sizeThreshold, "NYI::large .mprofdata file size is larger than threashold, do chunk memory\n"); std::unique_ptr buffer = std::make_unique(length); static_cast(inputStream.read(buffer.get(), length)); -- Gitee From 9c1910095726d20d2d1c97718d87161a40d8d8e4 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Thu, 6 Oct 2022 05:31:33 -0700 Subject: [PATCH 15/22] Fixed the path of the profile file name written in .s under --profileGen so GCOV_PREFIX_STRIP can work correctly Fixed the interpretation of GCOV_PREFIX and GCOV_PREFIX_STRIP under --profileUse. Added new flag --missing-profdata-is-error (default is true) which means the compiler will complain under --profileUse if the .mprofdata file is not found. Specifying --no-missing-profdata-is-error will change it to just emitting a warning. Under --profileUse, do not look for .mprofdata file when the file has no executable code. Changed inlinter to not inline when profile data indicates the callee is not executed. Removed an assertion in PreMeMIRLower:LowerWhileStmt(). Made FuncProfInfo::SetStmtFreq() treat freq value of -1 to mean no freq info. In loopvec phase, update remainder loop freq to 0 (previously no freq). --- src/mapleall/mpl2mpl/src/gen_profile.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/mapleall/mpl2mpl/src/gen_profile.cpp b/src/mapleall/mpl2mpl/src/gen_profile.cpp index 5741f7faa1..26783fd50a 100644 --- a/src/mapleall/mpl2mpl/src/gen_profile.cpp +++ b/src/mapleall/mpl2mpl/src/gen_profile.cpp @@ -105,8 +105,7 @@ void ProfileGen::CreateModProfDesc() { std::string fileNameWithPath = mod.GetFileNameWithPath(); // Make the profile file name as fileName.gcda - std::string profFileName = fileNameWithPath.substr(0, fileNameWithPath.find_last_of(".")) + - namemangler::kProfFileNameExt; + std::string profFileName = fileNameWithPath.substr(0, fileNameWithPath.find_last_of(".")) + namemangler::kProfFileNameExt; auto *profileFNMirConst = modMP->New(profFileName, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(PTY_a64))); modProfDescSymMirConst->AddItem(profileFNMirConst, 6); -- Gitee From 483a4ca6f9d13d36cff7f88b4fd995a1195b01db Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Thu, 6 Oct 2022 05:31:33 -0700 Subject: [PATCH 16/22] Fixed the path of the profile file name written in .s under --profileGen so GCOV_PREFIX_STRIP can work correctly Fixed the interpretation of GCOV_PREFIX and GCOV_PREFIX_STRIP under --profileUse. Added new flag --missing-profdata-is-error (default is true) which means the compiler will complain under --profileUse if the .mprofdata file is not found. Specifying --no-missing-profdata-is-error will change it to just emitting a warning. Under --profileUse, do not look for .mprofdata file when the file has no executable code. Changed inlinter to not inline when profile data indicates the callee is not executed. Removed an assertion in PreMeMIRLower:LowerWhileStmt(). Made FuncProfInfo::SetStmtFreq() treat freq value of -1 to mean no freq info. In loopvec phase, update remainder loop freq to 0 (previously no freq). --- .../maple_driver/include/driver_options.h | 1 + .../maple_driver/src/driver_options.cpp | 6 ++ src/mapleall/maple_ir/include/mir_module.h | 12 +--- src/mapleall/maple_ir/src/mir_lower.cpp | 3 + src/mapleall/maple_ir/src/mir_module.cpp | 17 +++++ src/mapleall/maple_me/src/lfo_loop_vec.cpp | 5 ++ src/mapleall/maple_me/src/me_cfg.cpp | 64 ++++++++++++++----- .../maple_me/src/me_value_range_prop.cpp | 1 - src/mapleall/maple_me/src/pme_mir_lower.cpp | 3 +- .../maple_util/include/mpl_profdata.h | 3 + src/mapleall/mpl2mpl/src/gen_profile.cpp | 4 +- src/mapleall/mpl2mpl/src/inline.cpp | 9 ++- .../mpl2mpl/src/mpl_profdata_parser.cpp | 44 +++++++------ 13 files changed, 119 insertions(+), 53 deletions(-) diff --git a/src/mapleall/maple_driver/include/driver_options.h b/src/mapleall/maple_driver/include/driver_options.h index 61a57df5d8..a7dbccfd73 100644 --- a/src/mapleall/maple_driver/include/driver_options.h +++ b/src/mapleall/maple_driver/include/driver_options.h @@ -72,6 +72,7 @@ extern maplecl::Option genMapleBC; extern maplecl::Option genLMBC; extern maplecl::Option profileGen; extern maplecl::Option profileUse; +extern maplecl::Option missingProfDataIsError; extern maplecl::Option stackProtectorStrong; extern maplecl::Option stackProtectorAll; extern maplecl::Option inlineAsWeak; diff --git a/src/mapleall/maple_driver/src/driver_options.cpp b/src/mapleall/maple_driver/src/driver_options.cpp index 1f035bc54b..33b4a04bb1 100644 --- a/src/mapleall/maple_driver/src/driver_options.cpp +++ b/src/mapleall/maple_driver/src/driver_options.cpp @@ -171,6 +171,12 @@ maplecl::Option profileUse({"--profileUse"}, " --profileUse \tOptimize static languages with profile data\n", {driverCategory, mpl2mplCategory}); +maplecl::Option missingProfDataIsError({"--missing-profdata-is-error"}, + " --missing-profdata-is-error \tTreat missing profile data file as error\n" + " --no-missing-profdata-is-error \tOnly warn on missing profile data file\n", + {driverCategory}, + maplecl::DisableWith("--no-missing-profdata-is-error"), + maplecl::Init(true)); maplecl::Option stackProtectorStrong({"--stack-protector-strong"}, " --stack-protector-strong \tadd stack guard for some function\n", {driverCategory, meCategory, cgCategory}); diff --git a/src/mapleall/maple_ir/include/mir_module.h b/src/mapleall/maple_ir/include/mir_module.h index 83eae82df7..e09c84e554 100644 --- a/src/mapleall/maple_ir/include/mir_module.h +++ b/src/mapleall/maple_ir/include/mir_module.h @@ -344,21 +344,11 @@ class MIRModule { } std::string GetFileNameAsPostfix() const; + std::string GetFileNameWithPath() const; void SetFileName(const std::string &name) { fileName = name; } - std::string GetProfileDataFileName() const { - std::string profileDataFileName = GetFileName().substr(0, GetFileName().find_last_of(".")); - const char *gcovPath = std::getenv("GCOV_PREFIX"); - std::string gcovPrefix = gcovPath ? gcovPath : ""; - if (!gcovPrefix.empty() && (gcovPrefix.back() != '/')) { - gcovPrefix.append("/"); - } - profileDataFileName = gcovPrefix + profileDataFileName; - return profileDataFileName; - } - bool IsJavaModule() const { return srcLang == kSrcLangJava; } diff --git a/src/mapleall/maple_ir/src/mir_lower.cpp b/src/mapleall/maple_ir/src/mir_lower.cpp index 9c989137c0..38b6507b76 100644 --- a/src/mapleall/maple_ir/src/mir_lower.cpp +++ b/src/mapleall/maple_ir/src/mir_lower.cpp @@ -408,6 +408,9 @@ BlockNode *MIRLower::LowerDoloopStmt(DoloopNode &doloop) { if (GetFuncProfData()) { doloopnodeFreq = static_cast(GetFuncProfData()->GetStmtFreq(doloop.GetStmtID())); bodynodeFreq = static_cast(GetFuncProfData()->GetStmtFreq(doloop.GetDoBody()->GetStmtID())); + if (doloopnodeFreq < bodynodeFreq) { + doloopnodeFreq = bodynodeFreq; + } } auto *blk = mirModule.CurFuncCodeMemPool()->New(); if (doloop.IsPreg()) { diff --git a/src/mapleall/maple_ir/src/mir_module.cpp b/src/mapleall/maple_ir/src/mir_module.cpp index 334216779e..8e53cfaf03 100644 --- a/src/mapleall/maple_ir/src/mir_module.cpp +++ b/src/mapleall/maple_ir/src/mir_module.cpp @@ -747,6 +747,23 @@ std::string MIRModule::GetFileNameAsPostfix() const { return fileNameStr; } +std::string MIRModule::GetFileNameWithPath() const { + MIRInfoPair fileInfoElem = fileInfo.front(); + std::string fileNameWithoutPath = GlobalTables::GetStrTable().GetStringFromStrIdx(fileInfoElem.second); + // strip out the suffix + fileNameWithoutPath = fileNameWithoutPath.substr(0, fileNameWithoutPath.find_last_of(".")); + std::string fileNameWithPath; + // find the right entry because some entries are for included files + for (size_t i = 0; i < srcFileInfo.size(); ++i) { + MIRInfoPair infoElem = srcFileInfo[i]; + fileNameWithPath = GlobalTables::GetStrTable().GetStringFromStrIdx(infoElem.first); + if (fileNameWithPath.find(fileNameWithoutPath) != std::string::npos) { + break; + } + } + return fileNameWithPath; +} + void MIRModule::AddClass(TyIdx tyIdx) { (void)classList.insert(tyIdx); } diff --git a/src/mapleall/maple_me/src/lfo_loop_vec.cpp b/src/mapleall/maple_me/src/lfo_loop_vec.cpp index 189a49ec6e..17e548f7e6 100644 --- a/src/mapleall/maple_me/src/lfo_loop_vec.cpp +++ b/src/mapleall/maple_me/src/lfo_loop_vec.cpp @@ -1754,6 +1754,11 @@ DoloopNode *LoopVectorization::PrepareDoloop(DoloopNode *doloop, LoopTransPlan * ASSERT(parent && (parent->GetOpCode() == OP_block), "nullptr check"); BlockNode *pblock = static_cast(parent); pblock->InsertAfter(doloop, edoloop); + auto *profData = mirFunc->GetFuncProfData(); + if (profData) { + profData->SetStmtFreq(edoloop->GetStmtID(), 0); + profData->SetStmtFreq(edoloop->GetDoBody()->GetStmtID(), 0); + } } return doloop; } diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index 202d51f7fe..0246e0c2c9 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -1553,9 +1553,9 @@ void MeCFG::CreateBasicBlocks() { curBB->SetBBLabel(labelIdx); // label node is not real node in bb, get frequency information to bb if (Options::profileUse && func.GetMirFunc()->GetFuncProfData()) { - auto freq = func.GetMirFunc()->GetFuncProfData()->GetStmtFreq(stmt->GetStmtID()); + int64 freq = func.GetMirFunc()->GetFuncProfData()->GetStmtFreq(stmt->GetStmtID()); if (freq >= 0) { - curBB->SetFrequency(freq); + curBB->SetFrequency(static_cast(freq)); } } break; @@ -1625,6 +1625,10 @@ void MeCFG::CreateBasicBlocks() { lastBB->SetFirst(func.GetMIRModule().GetMIRBuilder()->CreateStmtReturn(nullptr)); lastBB->SetLast(lastBB->GetStmtNodes().begin().d()); lastBB->SetKindReturn(); + if (updateFreq) { + FuncProfInfo *funcData = func.GetMirFunc()->GetFuncProfData(); + funcData->stmtFreqs[lastBB->GetLast().GetStmtID()] = 0; + } } else if (lastBB->GetKind() == kBBUnknown) { lastBB->SetKindReturn(); lastBB->SetAttributes(kBBAttrIsExit); @@ -1878,15 +1882,30 @@ void MeCFG::ConstructEdgeFreqFromBBFreq() { if (fallthru->GetPred().size() == 1) { auto succ0Freq = fallthru->GetFrequency(); bb->PushBackSuccFreq(succ0Freq); - ASSERT(bb->GetFrequency() >= succ0Freq, "sanity check"); - bb->PushBackSuccFreq(bb->GetFrequency() - succ0Freq); + if (bb->GetFrequency() > succ0Freq) { + bb->PushBackSuccFreq(bb->GetFrequency() - succ0Freq); + } else { + bb->PushBackSuccFreq(0); + } } else if (targetBB->GetPred().size() == 1) { auto succ1Freq = targetBB->GetFrequency(); - ASSERT(bb->GetFrequency() >= succ1Freq, "sanity check"); - bb->PushBackSuccFreq(bb->GetFrequency() - succ1Freq); - bb->PushBackSuccFreq(succ1Freq); + if (bb->GetAttributes(kBBAttrWontExit) && bb->GetSuccFreq().size() == 1) { + // special case: WontExitAnalysis() has pushed 0 to bb->succFreq + bb->GetSuccFreq()[0] = bb->GetFrequency(); + bb->PushBackSuccFreq(0); + } else if (bb->GetFrequency() >= succ1Freq) { // tolerate inaccuracy + bb->PushBackSuccFreq(0); + bb->PushBackSuccFreq(bb->GetFrequency()); + } else { + bb->PushBackSuccFreq(bb->GetFrequency() - succ1Freq); + bb->PushBackSuccFreq(succ1Freq); + } + } else if (fallthru->GetFrequency() > targetBB->GetFrequency()) { + bb->PushBackSuccFreq(bb->GetFrequency()); + bb->PushBackSuccFreq(0); } else { - CHECK_FATAL(false, "ConstructEdgeFreqFromBBFreq::NYI critical edge"); + bb->PushBackSuccFreq(0); + bb->PushBackSuccFreq(bb->GetFrequency()); } } else if (bb->GetSucc().size() > 2) { // switch case, no critical edge is supposted @@ -1910,14 +1929,24 @@ void MeCFG::ConstructBBFreqFromStmtFreq() { for (auto bIt = valid_begin(); bIt != eIt; ++bIt) { if ((*bIt)->IsEmpty()) continue; StmtNode &first = (*bIt)->GetFirst(); + StmtNode &last = (*bIt)->GetLast(); if (funcData->stmtFreqs.count(first.GetStmtID()) > 0) { (*bIt)->SetFrequency(funcData->stmtFreqs[first.GetStmtID()]); - } else if (funcData->stmtFreqs.count((*bIt)->GetLast().GetStmtID()) > 0) { - (*bIt)->SetFrequency(funcData->stmtFreqs[(*bIt)->GetLast().GetStmtID()]); + } else if (funcData->stmtFreqs.count(last.GetStmtID()) > 0) { + (*bIt)->SetFrequency(funcData->stmtFreqs[last.GetStmtID()]); } else { - LogInfo::MapleLogger() << "ERROR:: bb " << (*bIt)->GetBBId() << "frequency is not set" - << "\n"; - ASSERT(0, "no freq set"); + bool foundFreq = false; + for (StmtNode &stmt : (*bIt)->GetStmtNodes()) { + if (funcData->stmtFreqs.count(stmt.GetStmtID()) > 0) { + (*bIt)->SetFrequency(funcData->stmtFreqs[stmt.GetStmtID()]); + foundFreq = true; + break; + } + } + if (not foundFreq) { + LogInfo::MapleLogger() << "ERROR:: bb " << (*bIt)->GetBBId() << " has not stmt with set freq" << "\n"; + CHECK_FATAL(0, "MeCFG::ConstructBBFreqFromStmtFreq: cannot set BB freq"); + } } } // add common entry and common exit @@ -1937,9 +1966,6 @@ void MeCFG::ConstructBBFreqFromStmtFreq() { ConstructEdgeFreqFromBBFreq(); // clear stmtFreqs since cfg frequency is create funcData->stmtFreqs.clear(); - - // set updateFrequency with true - updateFreq = true; } void MeCFG::ConstructStmtFreq() { @@ -2086,6 +2112,10 @@ bool MEMeCfg::PhaseRun(MeFunction &f) { MemPool *meCfgMp = GetPhaseMemPool(); theCFG = meCfgMp->New(meCfgMp, f); f.SetTheCfg(theCFG); + + if (Options::profileUse && f.GetMirFunc()->GetFuncProfData()) { + theCFG->SetUpdateCFGFreq(true); + } theCFG->CreateBasicBlocks(); if (theCFG->NumBBs() == 0) { /* there's no basicblock generated */ @@ -2104,7 +2134,7 @@ bool MEMeCfg::PhaseRun(MeFunction &f) { } theCFG->Verify(); // construct bb freq from stmt freq - if (Options::profileUse && f.GetMirFunc()->GetFuncProfData()) { + if (theCFG->UpdateCFGFreq()) { theCFG->ConstructBBFreqFromStmtFreq(); if (theCFG->DumpIRProfileFile()) { std::string fileName = "after-mecfgbuild"; diff --git a/src/mapleall/maple_me/src/me_value_range_prop.cpp b/src/mapleall/maple_me/src/me_value_range_prop.cpp index cc6b15f8dc..96b8a8397b 100644 --- a/src/mapleall/maple_me/src/me_value_range_prop.cpp +++ b/src/mapleall/maple_me/src/me_value_range_prop.cpp @@ -3933,7 +3933,6 @@ bool ValueRangePropagation::RemoveTheEdgeOfPredBB( uint64 edgeFreq = 0; if (func.GetCfg()->UpdateCFGFreq()) { edgeFreq = pred.GetSuccFreq()[index]; - ASSERT(bb.GetFrequency() >= edgeFreq, "sanity check"); } pred.RemoveSucc(bb); DeleteThePhiNodeWhichOnlyHasOneOpnd(bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); diff --git a/src/mapleall/maple_me/src/pme_mir_lower.cpp b/src/mapleall/maple_me/src/pme_mir_lower.cpp index fdb427c437..c30a981218 100644 --- a/src/mapleall/maple_me/src/pme_mir_lower.cpp +++ b/src/mapleall/maple_me/src/pme_mir_lower.cpp @@ -73,8 +73,7 @@ BlockNode *PreMeMIRLower::LowerWhileStmt(WhileStmtNode &whileStmt) { if (GetFuncProfData()) { int64_t freq = GetFuncProfData()->GetStmtFreq(whileStmt.GetStmtID()) - GetFuncProfData()->GetStmtFreq(whilegotonode->GetStmtID()); - ASSERT(freq >= 0, "sanity check"); - GetFuncProfData()->SetStmtFreq(endlblstmt->GetStmtID(), freq); + GetFuncProfData()->SetStmtFreq(endlblstmt->GetStmtID(), freq > 0 ? freq : 0); } return blk; } diff --git a/src/mapleall/maple_util/include/mpl_profdata.h b/src/mapleall/maple_util/include/mpl_profdata.h index 23cf6f99b9..767bbf2ea4 100644 --- a/src/mapleall/maple_util/include/mpl_profdata.h +++ b/src/mapleall/maple_util/include/mpl_profdata.h @@ -130,6 +130,9 @@ class FuncProfInfo { return -1; // unstored } void SetStmtFreq(uint32_t stmtID, uint64_t freq) { + if (static_cast(freq) == -1) { + return; + } stmtFreqs[stmtID] = freq; } void EraseStmtFreq(uint32_t stmtID) { diff --git a/src/mapleall/mpl2mpl/src/gen_profile.cpp b/src/mapleall/mpl2mpl/src/gen_profile.cpp index a54af1b99d..26783fd50a 100644 --- a/src/mapleall/mpl2mpl/src/gen_profile.cpp +++ b/src/mapleall/mpl2mpl/src/gen_profile.cpp @@ -103,9 +103,9 @@ void ProfileGen::CreateModProfDesc() { MIRIntConst *checksumMirConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst(cfgChkSum, *u32Ty); modProfDescSymMirConst->AddItem(checksumMirConst, 5); + std::string fileNameWithPath = mod.GetFileNameWithPath(); // Make the profile file name as fileName.gcda - std::string profFileName = mod.GetFileName().substr(0, mod.GetFileName().find_last_of(".")) + - namemangler::kProfFileNameExt; + std::string profFileName = fileNameWithPath.substr(0, fileNameWithPath.find_last_of(".")) + namemangler::kProfFileNameExt; auto *profileFNMirConst = modMP->New(profFileName, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(PTY_a64))); modProfDescSymMirConst->AddItem(profileFNMirConst, 6); diff --git a/src/mapleall/mpl2mpl/src/inline.cpp b/src/mapleall/mpl2mpl/src/inline.cpp index d6c5a33d6c..c3e5586082 100644 --- a/src/mapleall/mpl2mpl/src/inline.cpp +++ b/src/mapleall/mpl2mpl/src/inline.cpp @@ -539,8 +539,13 @@ void MInline::InlineCallsBlockInternal(MIRFunction &func, BaseNode &baseNode, bo InlineResult result; result.reason = GetInlineFailedStr(failCode); if (canInline) { - result = AnalyzeCallee(func, *callee, callStmt); - canInline = result.canInline; + if (Options::profileUse && callee->GetFuncProfData() == nullptr) { + // callee is never executed according to profile data + canInline = false; + } else { + result = AnalyzeCallee(func, *callee, callStmt); + canInline = result.canInline; + } } if (canInline) { module.SetCurFunction(&func); diff --git a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp index 1d0ed18d7f..8fac14a282 100644 --- a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp +++ b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp @@ -87,6 +87,7 @@ int MplProfDataParser::ReadMapleProfileData() { std::string mprofDataFile = Options::profile; if (mprofDataFile.empty()) { if (const char *envGcovprefix = std::getenv("GCOV_PREFIX")) { + std::string fileNameWithPath = m.GetFileNameWithPath(); static_cast(mprofDataFile.append(envGcovprefix)); if (mprofDataFile.back() != '/') { static_cast(mprofDataFile.append("/")); @@ -102,33 +103,30 @@ int MplProfDataParser::ReadMapleProfileData() { LogInfo::MapleLogger() << "set env GCOV_PREFIX_STRIP=" << strip << std::endl; } } - std::string profDataFileName = m.GetProfileDataFileName(); - if (dumpDetail) { - LogInfo::MapleLogger() << "profdata file stem before strip: " << profDataFileName << std::endl; - } - // reduce path in profDataFileName - while (stripnum > 0 && profDataFileName.size() > 1) { - size_t pos = profDataFileName.find_first_of("/", 1); + // strip path in fileNameWithPath according to stripnum + while (stripnum > 0 && fileNameWithPath.size() > 1) { + size_t pos = fileNameWithPath.find_first_of("/", 1); if (pos == std::string::npos) { break; } - profDataFileName = profDataFileName.substr(pos); + fileNameWithPath= fileNameWithPath.substr(pos); stripnum--; } if (dumpDetail) { - LogInfo::MapleLogger() << "profdata file stem after strip: " << profDataFileName << std::endl; + LogInfo::MapleLogger() << "profdata file stem after strip: " << fileNameWithPath<< std::endl; } - CHECK_FATAL(profDataFileName.size() > 0, "sanity check"); - static_cast(mprofDataFile.append(profDataFileName)); + CHECK_FATAL(fileNameWithPath.size() > 0, "sanity check"); + static_cast(mprofDataFile.append(fileNameWithPath)); } else { - // if gcov_prefix is not set, find .mprofdata according to m.profiledata - mprofDataFile = m.GetProfileDataFileName(); - if (dumpDetail) { - LogInfo::MapleLogger() << "NO ENV, profdata file stem: " << mprofDataFile << std::endl; + mprofDataFile = m.GetFileName(); + // strip path in mprofDataFile + size_t pos = mprofDataFile.find_last_of("/"); + if (pos != std::string::npos) { + mprofDataFile = mprofDataFile.substr(pos+1); } } - // add .mprofdata - static_cast(mprofDataFile.append(namemangler::kMplProfFileNameExt)); + // change the suffix to .mprofdata + mprofDataFile = mprofDataFile.substr(0, mprofDataFile.find_last_of(".")) + namemangler::kMplProfFileNameExt; } ASSERT(!mprofDataFile.empty(), "null check"); LogInfo::MapleLogger() << "profileUse will open " << mprofDataFile << std::endl; @@ -136,7 +134,14 @@ int MplProfDataParser::ReadMapleProfileData() { profData = mempool->New(mempool, &alloc); // read .mprofdata std::ifstream inputStream(mprofDataFile, (std::ios::in | std::ios::binary)); - CHECK_FATAL(inputStream, "Could not open the file %s, quit\n", mprofDataFile.c_str()); + if (!inputStream) { + if (opts::missingProfDataIsError) { + CHECK_FATAL(inputStream, "Could not open profile data file %s, quit\n", mprofDataFile.c_str()); + } else { + WARN(kLncWarn, "Could not open profile data file %s\n", mprofDataFile.c_str()); + } + return 1; + } // get length of file static_cast(inputStream.seekg(0, std::ios::end)); uint32_t length = static_cast(inputStream.tellg()); @@ -175,6 +180,9 @@ void MMplProfDataParser::GetAnalysisDependence(AnalysisDep &aDep) const { bool MMplProfDataParser::PhaseRun(maple::MIRModule &m) { MemPool *memPool = m.GetMemPool(); // use global pool to store profile data bool enableDebug = false; // true to dump trace + if (m.GetFunctionList().empty()) { + return false; // there is no executable code + } MplProfDataParser parser(m, memPool, enableDebug); int res = parser.ReadMapleProfileData(); if (res) { -- Gitee From 99d2732bac56a2495186765cc9a9eb79394b2e48 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Thu, 6 Oct 2022 22:20:37 -0700 Subject: [PATCH 17/22] Some additional PGO-related fixes --- src/mapleall/maple_ipa/src/ipa_clone.cpp | 6 ++++++ src/mapleall/maple_me/src/me_loop_inversion.cpp | 1 - src/mapleall/maple_me/src/optimizeCFG.cpp | 7 +++++-- src/mapleall/maple_me/src/pme_emit.cpp | 2 +- src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp | 4 ++-- 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/mapleall/maple_ipa/src/ipa_clone.cpp b/src/mapleall/maple_ipa/src/ipa_clone.cpp index f164000454..fcbcf84c83 100644 --- a/src/mapleall/maple_ipa/src/ipa_clone.cpp +++ b/src/mapleall/maple_ipa/src/ipa_clone.cpp @@ -395,6 +395,9 @@ void IpaClone::DecideCloneFunction(std::vector &result, uint32 paramInd if (oldCallNode == nullptr) { continue; } + if (callerFunc->GetFuncProfData() == nullptr) { + continue; + } uint64_t callsiteFreq = callerFunc->GetFuncProfData()->GetStmtFreq(stmtId); clonedSiteFreqs += callsiteFreq; } @@ -546,6 +549,9 @@ void IpaClone::CloneNoImportantExpressFunction(MIRFunction *func, uint32 paramIn if (oldCallNode == nullptr) { continue; } + if (callerFunc->GetFuncProfData() == nullptr) { + continue; + } uint64_t callsiteFreq = callerFunc->GetFuncProfData()->GetStmtFreq(stmtId); clonedSiteFreqs += callsiteFreq; } diff --git a/src/mapleall/maple_me/src/me_loop_inversion.cpp b/src/mapleall/maple_me/src/me_loop_inversion.cpp index fddacb87d9..7a615caf77 100644 --- a/src/mapleall/maple_me/src/me_loop_inversion.cpp +++ b/src/mapleall/maple_me/src/me_loop_inversion.cpp @@ -243,7 +243,6 @@ void MeLoopInversion::Convert(MeFunction &func, BB &bb, BB &pred, MapleMapGetFrequency() == 0, "sanity check"); latchBB->PushBackSuccFreq(0); latchBB->PushBackSuccFreq(0); } diff --git a/src/mapleall/maple_me/src/optimizeCFG.cpp b/src/mapleall/maple_me/src/optimizeCFG.cpp index a6c6826b31..ec8ccdcd97 100644 --- a/src/mapleall/maple_me/src/optimizeCFG.cpp +++ b/src/mapleall/maple_me/src/optimizeCFG.cpp @@ -1904,8 +1904,11 @@ bool OptimizeBB::SkipRedundantCond(BB &pred, BB &succ) { idx = succ.GetSuccIndex(*affectedBB); ASSERT(idx >= 0 && idx < succ.GetSucc().size(), "sanity check"); int64_t oldedgeFreq = static_cast(succ.GetSuccFreq()[static_cast(idx)]); - ASSERT(oldedgeFreq >= freq, "sanity check"); - succ.SetSuccFreq(idx, static_cast(oldedgeFreq) - freq); + if (oldedgeFreq >= freq) { + succ.SetSuccFreq(idx, static_cast(oldedgeFreq) - freq); + } else { + succ.SetSuccFreq(idx, 0); + } } return true; } diff --git a/src/mapleall/maple_me/src/pme_emit.cpp b/src/mapleall/maple_me/src/pme_emit.cpp index d5cf1e015e..a567e52090 100644 --- a/src/mapleall/maple_me/src/pme_emit.cpp +++ b/src/mapleall/maple_me/src/pme_emit.cpp @@ -833,7 +833,7 @@ void PreMeEmitter::EmitBB(BB *bb, BlockNode *curBlk) { if (setLastFreq) { GetFuncProfData()->SetStmtFreq(curBlk->GetLast()->GetStmtID(), bb->GetFrequency()); } else if (bbIsEmpty) { - LogInfo::MapleLogger() << " bb " << bb->GetBBId() << "no stmt used to add frequency, add commentnode\n"; + LogInfo::MapleLogger() << " bb " << bb->GetBBId() << ": no stmt used to add frequency; added comment node\n"; CommentNode *commentNode = codeMP->New(*(mirFunc->GetModule())); commentNode->SetComment("freqStmt"+std::to_string(commentNode->GetStmtID())); GetFuncProfData()->SetStmtFreq(commentNode->GetStmtID(), bb->GetFrequency()); diff --git a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp index 8fac14a282..8d316ce631 100644 --- a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp +++ b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp @@ -146,8 +146,8 @@ int MplProfDataParser::ReadMapleProfileData() { static_cast(inputStream.seekg(0, std::ios::end)); uint32_t length = static_cast(inputStream.tellg()); static_cast(inputStream.seekg(0, std::ios::beg)); - const uint32_t sizeThreshold = 1024 * 10; - CHECK_FATAL(length <= sizeThreshold, "NYI::large .mprofdata file size is larger than threashold, do chunk memory\n"); +//const uint32_t sizeThreshold = 1024 * 10; +//CHECK_FATAL(length <= sizeThreshold, "NYI::large .mprofdata file size is larger than threashold, do chunk memory\n"); std::unique_ptr buffer = std::make_unique(length); static_cast(inputStream.read(buffer.get(), length)); -- Gitee From 3c185f9f035a26d4f3aac46aa9bf9a0c78983dc1 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Fri, 7 Oct 2022 16:25:37 -0700 Subject: [PATCH 18/22] Under -O0, make --patch-long-branch the default so 502.gcc_s can be built under --profileGen --- src/mapleall/maple_be/include/cg/cg.h | 2 +- src/mapleall/maple_me/src/me_profile_use.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mapleall/maple_be/include/cg/cg.h b/src/mapleall/maple_be/include/cg/cg.h index 8cc3b4e74a..5c48b3cff7 100644 --- a/src/mapleall/maple_be/include/cg/cg.h +++ b/src/mapleall/maple_be/include/cg/cg.h @@ -201,7 +201,7 @@ class CG { } bool DoPatchLongBranch() const { - return cgOption.DoPatchLongBranch(); + return cgOption.DoPatchLongBranch() || (Globals::GetInstance()->GetOptimLevel() == CGOptions::kLevel0); } uint8 GetRematLevel() const { diff --git a/src/mapleall/maple_me/src/me_profile_use.cpp b/src/mapleall/maple_me/src/me_profile_use.cpp index d43fa03e73..d22d98e97a 100644 --- a/src/mapleall/maple_me/src/me_profile_use.cpp +++ b/src/mapleall/maple_me/src/me_profile_use.cpp @@ -103,7 +103,7 @@ void MeProfUse::ComputeEdgeFreq() { while (change) { change = false; pass++; - CHECK_FATAL(pass != UINT8_MAX, "parse all edges fail"); + CHECK_FATAL(pass != UINT16_MAX, "too many passes in MeProfUse::ComputeEdgeFreq: %d", pass); /* * use the bb edge to infer the bb's count,when all bb's count is valid * then all edges count is valid -- Gitee From ea74b1cd8136e1fc6b7e588dfaa51cbf4b834030 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Tue, 1 Nov 2022 23:42:30 -0700 Subject: [PATCH 19/22] Fixed coding style warnings --- src/mapleall/mpl2mpl/src/gen_profile.cpp | 3 ++- src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp | 4 +--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/mapleall/mpl2mpl/src/gen_profile.cpp b/src/mapleall/mpl2mpl/src/gen_profile.cpp index 26783fd50a..5741f7faa1 100644 --- a/src/mapleall/mpl2mpl/src/gen_profile.cpp +++ b/src/mapleall/mpl2mpl/src/gen_profile.cpp @@ -105,7 +105,8 @@ void ProfileGen::CreateModProfDesc() { std::string fileNameWithPath = mod.GetFileNameWithPath(); // Make the profile file name as fileName.gcda - std::string profFileName = fileNameWithPath.substr(0, fileNameWithPath.find_last_of(".")) + namemangler::kProfFileNameExt; + std::string profFileName = fileNameWithPath.substr(0, fileNameWithPath.find_last_of(".")) + + namemangler::kProfFileNameExt; auto *profileFNMirConst = modMP->New(profFileName, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(PTY_a64))); modProfDescSymMirConst->AddItem(profileFNMirConst, 6); diff --git a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp index 8d316ce631..a0702c4cf2 100644 --- a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp +++ b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp @@ -122,7 +122,7 @@ int MplProfDataParser::ReadMapleProfileData() { // strip path in mprofDataFile size_t pos = mprofDataFile.find_last_of("/"); if (pos != std::string::npos) { - mprofDataFile = mprofDataFile.substr(pos+1); + mprofDataFile = mprofDataFile.substr(pos + 1); } } // change the suffix to .mprofdata @@ -146,8 +146,6 @@ int MplProfDataParser::ReadMapleProfileData() { static_cast(inputStream.seekg(0, std::ios::end)); uint32_t length = static_cast(inputStream.tellg()); static_cast(inputStream.seekg(0, std::ios::beg)); -//const uint32_t sizeThreshold = 1024 * 10; -//CHECK_FATAL(length <= sizeThreshold, "NYI::large .mprofdata file size is larger than threashold, do chunk memory\n"); std::unique_ptr buffer = std::make_unique(length); static_cast(inputStream.read(buffer.get(), length)); -- Gitee From e57e74cdee81fedc3d5fb713f9af2542c1728375 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Thu, 6 Oct 2022 05:31:33 -0700 Subject: [PATCH 20/22] Fixed the path of the profile file name written in .s under --profileGen so GCOV_PREFIX_STRIP can work correctly Fixed the interpretation of GCOV_PREFIX and GCOV_PREFIX_STRIP under --profileUse. Added new flag --missing-profdata-is-error (default is true) which means the compiler will complain under --profileUse if the .mprofdata file is not found. Specifying --no-missing-profdata-is-error will change it to just emitting a warning. Under --profileUse, do not look for .mprofdata file when the file has no executable code. Changed inlinter to not inline when profile data indicates the callee is not executed. Removed an assertion in PreMeMIRLower:LowerWhileStmt(). Made FuncProfInfo::SetStmtFreq() treat freq value of -1 to mean no freq info. In loopvec phase, update remainder loop freq to 0 (previously no freq). --- src/mapleall/mpl2mpl/src/gen_profile.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/mapleall/mpl2mpl/src/gen_profile.cpp b/src/mapleall/mpl2mpl/src/gen_profile.cpp index 5741f7faa1..26783fd50a 100644 --- a/src/mapleall/mpl2mpl/src/gen_profile.cpp +++ b/src/mapleall/mpl2mpl/src/gen_profile.cpp @@ -105,8 +105,7 @@ void ProfileGen::CreateModProfDesc() { std::string fileNameWithPath = mod.GetFileNameWithPath(); // Make the profile file name as fileName.gcda - std::string profFileName = fileNameWithPath.substr(0, fileNameWithPath.find_last_of(".")) + - namemangler::kProfFileNameExt; + std::string profFileName = fileNameWithPath.substr(0, fileNameWithPath.find_last_of(".")) + namemangler::kProfFileNameExt; auto *profileFNMirConst = modMP->New(profFileName, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(PTY_a64))); modProfDescSymMirConst->AddItem(profileFNMirConst, 6); -- Gitee From e07721341c471d2b5c07de5bce501cceead0ec3e Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Tue, 1 Nov 2022 23:42:30 -0700 Subject: [PATCH 21/22] Fixed coding style warnings --- src/mapleall/mpl2mpl/src/gen_profile.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mapleall/mpl2mpl/src/gen_profile.cpp b/src/mapleall/mpl2mpl/src/gen_profile.cpp index 26783fd50a..5741f7faa1 100644 --- a/src/mapleall/mpl2mpl/src/gen_profile.cpp +++ b/src/mapleall/mpl2mpl/src/gen_profile.cpp @@ -105,7 +105,8 @@ void ProfileGen::CreateModProfDesc() { std::string fileNameWithPath = mod.GetFileNameWithPath(); // Make the profile file name as fileName.gcda - std::string profFileName = fileNameWithPath.substr(0, fileNameWithPath.find_last_of(".")) + namemangler::kProfFileNameExt; + std::string profFileName = fileNameWithPath.substr(0, fileNameWithPath.find_last_of(".")) + + namemangler::kProfFileNameExt; auto *profileFNMirConst = modMP->New(profFileName, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(PTY_a64))); modProfDescSymMirConst->AddItem(profileFNMirConst, 6); -- Gitee From bd67e6756a4373dac4654782dd3a3d9f39791b12 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Thu, 17 Nov 2022 12:01:52 -0800 Subject: [PATCH 22/22] remove excessive nesting depth to avoid code scan warning --- src/mapleall/maple_me/src/me_cfg.cpp | 65 +++++++++++++++------------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index 0246e0c2c9..5eb25c28fa 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -1864,6 +1864,40 @@ void MeCFG::SwapBBId(BB &bb1, BB &bb2) { bb2.SetBBId(tmp); } +// bb must have 2 successors; construct the edge frequencies for the 2 edges +inline void ConstructEdgeFreqForBBWith2Succs(BB *bb) { + BB *fallthru = bb->GetSucc(0); + BB *targetBB = bb->GetSucc(1); + if (fallthru->GetPred().size() == 1) { + uint64 succ0Freq = fallthru->GetFrequency(); + bb->PushBackSuccFreq(succ0Freq); + if (bb->GetFrequency() > succ0Freq) { + bb->PushBackSuccFreq(bb->GetFrequency() - succ0Freq); + } else { + bb->PushBackSuccFreq(0); + } + } else if (targetBB->GetPred().size() == 1) { + uint64 succ1Freq = targetBB->GetFrequency(); + if (bb->GetAttributes(kBBAttrWontExit) && bb->GetSuccFreq().size() == 1) { + // special case: WontExitAnalysis() has pushed 0 to bb->succFreq + bb->GetSuccFreq()[0] = bb->GetFrequency(); + bb->PushBackSuccFreq(0); + } else if (bb->GetFrequency() >= succ1Freq) { // tolerate inaccuracy + bb->PushBackSuccFreq(0); + bb->PushBackSuccFreq(bb->GetFrequency()); + } else { + bb->PushBackSuccFreq(bb->GetFrequency() - succ1Freq); + bb->PushBackSuccFreq(succ1Freq); + } + } else if (fallthru->GetFrequency() > targetBB->GetFrequency()) { + bb->PushBackSuccFreq(bb->GetFrequency()); + bb->PushBackSuccFreq(0); + } else { + bb->PushBackSuccFreq(0); + bb->PushBackSuccFreq(bb->GetFrequency()); + } +} + // set bb succ frequency from bb freq // no critical edge is expected void MeCFG::ConstructEdgeFreqFromBBFreq() { @@ -1877,36 +1911,7 @@ void MeCFG::ConstructEdgeFreqFromBBFreq() { if (bb->GetSucc().size() == 1) { bb->PushBackSuccFreq(bb->GetFrequency()); } else if (bb->GetSucc().size() == 2) { - auto *fallthru = bb->GetSucc(0); - auto *targetBB = bb->GetSucc(1); - if (fallthru->GetPred().size() == 1) { - auto succ0Freq = fallthru->GetFrequency(); - bb->PushBackSuccFreq(succ0Freq); - if (bb->GetFrequency() > succ0Freq) { - bb->PushBackSuccFreq(bb->GetFrequency() - succ0Freq); - } else { - bb->PushBackSuccFreq(0); - } - } else if (targetBB->GetPred().size() == 1) { - auto succ1Freq = targetBB->GetFrequency(); - if (bb->GetAttributes(kBBAttrWontExit) && bb->GetSuccFreq().size() == 1) { - // special case: WontExitAnalysis() has pushed 0 to bb->succFreq - bb->GetSuccFreq()[0] = bb->GetFrequency(); - bb->PushBackSuccFreq(0); - } else if (bb->GetFrequency() >= succ1Freq) { // tolerate inaccuracy - bb->PushBackSuccFreq(0); - bb->PushBackSuccFreq(bb->GetFrequency()); - } else { - bb->PushBackSuccFreq(bb->GetFrequency() - succ1Freq); - bb->PushBackSuccFreq(succ1Freq); - } - } else if (fallthru->GetFrequency() > targetBB->GetFrequency()) { - bb->PushBackSuccFreq(bb->GetFrequency()); - bb->PushBackSuccFreq(0); - } else { - bb->PushBackSuccFreq(0); - bb->PushBackSuccFreq(bb->GetFrequency()); - } + ConstructEdgeFreqForBBWith2Succs(bb); } else if (bb->GetSucc().size() > 2) { // switch case, no critical edge is supposted for (size_t i = 0; i < bb->GetSucc().size(); ++i) { -- Gitee