From 34f99956fd0ab854a9f5fcdd24fa363be527678a Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Sat, 9 Oct 2021 00:28:50 -0700 Subject: [PATCH 1/2] Implemented OptimizeCaseTargets() to optimize the jump targets in the switch table Disabled cfgOpt phase. Added option -layoutwithpredict and changed default to NOT layout based on branch prediction. --- src/mapleall/maple_me/include/me_bb_layout.h | 2 + src/mapleall/maple_me/include/me_ir.h | 2 +- src/mapleall/maple_me/include/me_option.h | 1 + src/mapleall/maple_me/src/me_bb_layout.cpp | 53 +++++++++++++++++++- src/mapleall/maple_me/src/me_option.cpp | 15 ++++++ src/mapleall/maple_phase/include/phases.def | 2 +- 6 files changed, 72 insertions(+), 3 deletions(-) diff --git a/src/mapleall/maple_me/include/me_bb_layout.h b/src/mapleall/maple_me/include/me_bb_layout.h index 6a8369587a..95deab3deb 100644 --- a/src/mapleall/maple_me/include/me_bb_layout.h +++ b/src/mapleall/maple_me/include/me_bb_layout.h @@ -53,6 +53,8 @@ class BBLayout{ return nullptr; } + bool BBIsEmpty(BB *bb); + void OptimizeCaseTargets(BB *switchBB, CaseVector *swTable); void OptimizeBranchTarget(BB &bb); bool BBEmptyAndFallthru(const BB &bb); bool BBContainsOnlyGoto(const BB &bb) const; diff --git a/src/mapleall/maple_me/include/me_ir.h b/src/mapleall/maple_me/include/me_ir.h index 11e7022158..1b9843fc1e 100644 --- a/src/mapleall/maple_me/include/me_ir.h +++ b/src/mapleall/maple_me/include/me_ir.h @@ -2697,7 +2697,7 @@ class SwitchMeStmt : public UnaryMeStmt { switchTable[caseIdx].second = label; } - const CaseVector &GetSwitchTable() { + CaseVector &GetSwitchTable() { return switchTable; } diff --git a/src/mapleall/maple_me/include/me_option.h b/src/mapleall/maple_me/include/me_option.h index 762a5d9c11..850d2a1369 100644 --- a/src/mapleall/maple_me/include/me_option.h +++ b/src/mapleall/maple_me/include/me_option.h @@ -170,6 +170,7 @@ class MeOption : public MapleDriverOptionBase { static bool loopVec; static bool seqVec; static uint8 rematLevel; + static bool layoutWithPredict; #if MIR_JAVA static std::string acquireFuncName; static std::string releaseFuncName; diff --git a/src/mapleall/maple_me/src/me_bb_layout.cpp b/src/mapleall/maple_me/src/me_bb_layout.cpp index 64e2b41cbf..16b75ab0a5 100644 --- a/src/mapleall/maple_me/src/me_bb_layout.cpp +++ b/src/mapleall/maple_me/src/me_bb_layout.cpp @@ -268,6 +268,49 @@ bool BBLayout::HasSameBranchCond(BB &bb1, BB &bb2) const { return true; } +bool BBLayout::BBIsEmpty(BB *bb) { + if (func.GetIRMap() != nullptr) { + return bb->IsMeStmtEmpty(); + } + return bb->IsEmpty(); +} + +void BBLayout::OptimizeCaseTargets(BB *switchBB, CaseVector *swTable) { + CaseVector::iterator caseIt = swTable->begin(); + for (; caseIt != swTable->end(); caseIt++) { + LabelIdx lidx = caseIt->second; + BB *brTargetBB = func.GetCfg()->GetLabelBBAt(lidx); + if (brTargetBB->GetSucc().size() != 0) { + OptimizeBranchTarget(*brTargetBB); + } + if (brTargetBB->GetSucc().size() != 1) { + continue; + } + if (!(BBContainsOnlyGoto(*brTargetBB) || BBIsEmpty(brTargetBB))) { + continue; + } + BB *newTargetBB = brTargetBB->GetSucc().front(); + if (newTargetBB == brTargetBB) { + continue; + } + LabelIdx newTargetLabel = func.GetOrCreateBBLabel(*newTargetBB); + caseIt->second = newTargetLabel; + if (!newTargetBB->IsSuccBB(*switchBB)) { + switchBB->AddSucc(*newTargetBB); + } +#if 0 // not updating CFG because there can be multiple cases with same target + switchBB->ReplaceSucc(brTargetBB, newTargetBB); + if (brTargetBB->GetPred().empty()) { + laidOut[brTargetBB->GetBBId()] = true; + RemoveUnreachable(*brTargetBB); + if (needDealWithTryBB) { + DealWithStartTryBB(); + } + } +#endif + } +} + // (1) bb's last statement is a conditional or unconditional branch; if the branch // target is a BB with only a single goto statement, optimize the branch target // to the eventual target @@ -751,6 +794,14 @@ void BBLayout::LayoutWithoutProf() { OptimizeBranchTarget(*newFallthru); } } + } else if (bb->GetKind() == kBBSwitch) { + if (func.GetIRMap() != nullptr) { + SwitchMeStmt *swStmt = &static_cast(bb->GetMeStmts().back()); + OptimizeCaseTargets(bb, &swStmt->GetSwitchTable()); + } else { + SwitchNode *swStmt = &static_cast(bb->GetStmtNodes().back()); + OptimizeCaseTargets(bb, &swStmt->GetSwitchTable()); + } } if (bb->GetKind() == kBBGoto) { // see if goto target can be placed here @@ -938,7 +989,7 @@ void BBLayout::LayoutWithProf() { void BBLayout::RunLayout() { // If the func is too large, won't run prediction - if (func.GetMIRModule().IsCModule() && cfg->GetAllBBs().size() <= kMaxNumBBToPredict) { + if (MeOption::layoutWithPredict && func.GetMIRModule().IsCModule() && cfg->GetAllBBs().size() <= kMaxNumBBToPredict) { LayoutWithProf(); } else { LayoutWithoutProf(); diff --git a/src/mapleall/maple_me/src/me_option.cpp b/src/mapleall/maple_me/src/me_option.cpp index 792f9bf20b..291e930f58 100644 --- a/src/mapleall/maple_me/src/me_option.cpp +++ b/src/mapleall/maple_me/src/me_option.cpp @@ -114,6 +114,7 @@ uint32 MeOption::hpropRunsLimit = 2; // hprop phase run at most 2 times each PU bool MeOption::loopVec = true; bool MeOption::seqVec = true; uint8 MeOption::rematLevel = 0; +bool MeOption::layoutWithPredict = false; // optimize output layout using branch prediction #if MIR_JAVA std::string MeOption::acquireFuncName = "Landroid/location/LocationManager;|requestLocationUpdates|"; std::string MeOption::releaseFuncName = "Landroid/location/LocationManager;|removeUpdates|"; @@ -238,6 +239,7 @@ enum OptionIndex { kLoopVec, kSeqVec, kRematLevel, + kLayoutWithPredict, }; const Descriptor kUsage[] = { @@ -1143,6 +1145,16 @@ const Descriptor kUsage[] = { " --no-seqvec \tDisable auto sequencial vectorization\n", "me", {} }, + { kLayoutWithPredict, + kEnable, + "", + "layoutwithpredict", + kBuildTypeExperimental, + kArgCheckPolicyBool, + " --layoutwithpredict \tEnable optimizing output layout using branch prediction\n" + " --no-layoutwithpredict \tDisable optimizing output layout using branch prediction\n", + "me", + {} }, #if MIR_JAVA { kMeAcquireFunc, 0, @@ -1611,6 +1623,9 @@ bool MeOption::SolveOptions(const std::vector &opts, bool i case kRematLevel: rematLevel = std::stoul(opt.Args(), nullptr); break; + case kLayoutWithPredict: + layoutWithPredict = (opt.Type() == kEnable); + break; #if MIR_JAVA case kMeAcquireFunc: acquireFuncName = opt.Args(); diff --git a/src/mapleall/maple_phase/include/phases.def b/src/mapleall/maple_phase/include/phases.def index 4bfd58725a..a8c5eab7df 100644 --- a/src/mapleall/maple_phase/include/phases.def +++ b/src/mapleall/maple_phase/include/phases.def @@ -38,7 +38,7 @@ ADDMAPLEMEPHASE("lfopreemit", CLANG && MeOption::optLevel >= 3) ADDMAPLEMEPHASE("deptest", CLANG && MeOption::optLevel >= 3) ADDMAPLEMEPHASE("autovec", CLANG && MeOption::optLevel >= 3) ADDMAPLEMEPHASE("mecfgbuild", MeOption::optLevel >= 2 || JAVALANG) -ADDMAPLEMEPHASE("cfgOpt", CLANG && MeOption::optLevel == 2) +//ADDMAPLEMEPHASE("cfgOpt", CLANG && MeOption::optLevel == 2) ADDMAPLEMEPHASE("bypatheh", JAVALANG && MeOption::optLevel >= 2) ADDMAPLEMEPHASE("loopcanon", MeOption::optLevel >= 2) ADDMAPLEMEPHASE("splitcriticaledge", MeOption::optLevel >= 2) -- Gitee From c053be35632ba61fe3f7f1c8aea8bd4475f0754b Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Wed, 13 Oct 2021 18:29:06 -0700 Subject: [PATCH 2/2] default -layoutwithpredict to true; undo removal of cfgOpt phase This ensures mplme's output layout keeps its default behavior for C code. --- src/mapleall/maple_me/src/me_option.cpp | 2 +- src/mapleall/maple_phase/include/phases.def | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mapleall/maple_me/src/me_option.cpp b/src/mapleall/maple_me/src/me_option.cpp index 291e930f58..39046437ff 100644 --- a/src/mapleall/maple_me/src/me_option.cpp +++ b/src/mapleall/maple_me/src/me_option.cpp @@ -114,7 +114,7 @@ uint32 MeOption::hpropRunsLimit = 2; // hprop phase run at most 2 times each PU bool MeOption::loopVec = true; bool MeOption::seqVec = true; uint8 MeOption::rematLevel = 0; -bool MeOption::layoutWithPredict = false; // optimize output layout using branch prediction +bool MeOption::layoutWithPredict = true; // optimize output layout using branch prediction #if MIR_JAVA std::string MeOption::acquireFuncName = "Landroid/location/LocationManager;|requestLocationUpdates|"; std::string MeOption::releaseFuncName = "Landroid/location/LocationManager;|removeUpdates|"; diff --git a/src/mapleall/maple_phase/include/phases.def b/src/mapleall/maple_phase/include/phases.def index a8c5eab7df..4bfd58725a 100644 --- a/src/mapleall/maple_phase/include/phases.def +++ b/src/mapleall/maple_phase/include/phases.def @@ -38,7 +38,7 @@ ADDMAPLEMEPHASE("lfopreemit", CLANG && MeOption::optLevel >= 3) ADDMAPLEMEPHASE("deptest", CLANG && MeOption::optLevel >= 3) ADDMAPLEMEPHASE("autovec", CLANG && MeOption::optLevel >= 3) ADDMAPLEMEPHASE("mecfgbuild", MeOption::optLevel >= 2 || JAVALANG) -//ADDMAPLEMEPHASE("cfgOpt", CLANG && MeOption::optLevel == 2) +ADDMAPLEMEPHASE("cfgOpt", CLANG && MeOption::optLevel == 2) ADDMAPLEMEPHASE("bypatheh", JAVALANG && MeOption::optLevel >= 2) ADDMAPLEMEPHASE("loopcanon", MeOption::optLevel >= 2) ADDMAPLEMEPHASE("splitcriticaledge", MeOption::optLevel >= 2) -- Gitee