From 6a3959471d8c2acad71f692f13c83b71e653b228 Mon Sep 17 00:00:00 2001 From: fye Date: Mon, 24 Oct 2022 10:57:23 -0700 Subject: [PATCH 1/2] PGO: switch stmt lowerer --- src/mapleall/maple_be/include/be/lower.h | 7 +++ .../maple_be/include/be/switch_lowerer.h | 10 +++ src/mapleall/maple_be/src/be/lower.cpp | 13 ++++ .../maple_be/src/be/switch_lowerer.cpp | 62 +++++++++++++++---- src/mapleall/maple_me/src/me_emit.cpp | 3 - 5 files changed, 81 insertions(+), 14 deletions(-) diff --git a/src/mapleall/maple_be/include/be/lower.h b/src/mapleall/maple_be/include/be/lower.h index 70e9e00d4d..0d3505490c 100644 --- a/src/mapleall/maple_be/include/be/lower.h +++ b/src/mapleall/maple_be/include/be/lower.h @@ -265,6 +265,12 @@ class CGLowerer { static constexpr int kMCCSyncEnterFast2 = 2; static constexpr int kMCCSyncEnterFast3 = 3; + void BuildLabel2FreqMap(); + + std::unordered_map GetLabel2Freq() { + return l2fMap; + } + protected: /* * true if the lower level (e.g. mplcg) can handle the intrinsic directly. @@ -334,6 +340,7 @@ class CGLowerer { uint32 labelIdx = 0; static std::unordered_map intrinFuncIDs; static std::unordered_map arrayClassCacheIndex; + std::unordered_map l2fMap; //Map label to frequency on profileUse }; } /* namespace maplebe */ diff --git a/src/mapleall/maple_be/include/be/switch_lowerer.h b/src/mapleall/maple_be/include/be/switch_lowerer.h index 3846783783..18450a1b39 100644 --- a/src/mapleall/maple_be/include/be/switch_lowerer.h +++ b/src/mapleall/maple_be/include/be/switch_lowerer.h @@ -16,6 +16,7 @@ #define MAPLEBE_INCLUDE_BE_SWITCH_LOWERER_H #include "mir_nodes.h" #include "mir_module.h" +#include "lower.h" namespace maplebe { using namespace maple; @@ -23,6 +24,14 @@ class BELowerer; class SwitchLowerer { public: + SwitchLowerer(maple::MIRModule &mod, maple::SwitchNode &stmt, + CGLowerer *lower, maple::MapleAllocator &allocator) + : mirModule(mod), + stmt(&stmt), + cgLowerer(lower), + switchItems(allocator.Adapter()), + ownAllocator(&allocator) {} + SwitchLowerer(maple::MIRModule &mod, maple::SwitchNode &stmt, maple::MapleAllocator &allocator) : mirModule(mod), @@ -40,6 +49,7 @@ class SwitchLowerer { maple::MIRModule &mirModule; maple::SwitchNode *stmt; + CGLowerer *cgLowerer; /* * the original switch table is sorted and then each dense (in terms of the * case tags) region is condensed into 1 switch item; in the switchItems diff --git a/src/mapleall/maple_be/src/be/lower.cpp b/src/mapleall/maple_be/src/be/lower.cpp index 62eeaa7055..52d3aa7aa0 100644 --- a/src/mapleall/maple_be/src/be/lower.cpp +++ b/src/mapleall/maple_be/src/be/lower.cpp @@ -4118,12 +4118,25 @@ void CGLowerer::InitArrayClassCacheTableIndex() { } } +void CGLowerer::BuildLabel2FreqMap() { + StmtNodes stmtNodes = GetCurrentFunc()->GetBody()->GetStmtNodes(); + FuncProfInfo* funcProfile = mirModule.CurFunction()->GetFuncProfData(); + if (Options::profileUse && (funcProfile != nullptr)) { + for (StmtNode& stmt : stmtNodes) { + if (stmt.GetOpCode() == OP_label) { + l2fMap[static_cast(stmt).GetLabelIdx()] = funcProfile->GetStmtFreq(stmt.GetStmtID()); + } + } + } +} + void CGLowerer::LowerFunc(MIRFunction &func) { labelIdx = 0; SetCurrentFunc(&func); hasTry = false; LowerEntry(func); LowerPseudoRegs(func); + BuildLabel2FreqMap(); BlockNode *origBody = func.GetBody(); CHECK_FATAL(origBody != nullptr, "origBody should not be nullptr"); diff --git a/src/mapleall/maple_be/src/be/switch_lowerer.cpp b/src/mapleall/maple_be/src/be/switch_lowerer.cpp index f22950bf62..7789e5cf20 100644 --- a/src/mapleall/maple_be/src/be/switch_lowerer.cpp +++ b/src/mapleall/maple_be/src/be/switch_lowerer.cpp @@ -262,20 +262,60 @@ BlockNode *SwitchLowerer::BuildCodeForSwitchItems(int32 start, int32 end, bool l } if (end < (start + kClusterSwitchCutoff)) { /* generate equality checks for what remains */ - while ((start <= end) && (switchItems[start].second == 0)) { - if ((start == end) && lowBlockNodeChecked && highBlockNodeChecked) { - cGoto = reinterpret_cast(BuildGotoNode(switchItems[start].first)); /* can omit the condition */ - } else { - cGoto = BuildCondGotoNode(switchItems[start].first, OP_brtrue, *BuildCmpNode(OP_eq, switchItems[start].first)); + std::vector > freq2case; + int32 lastIdx = -1; + bool freqPriority = false; + // The setting of kClusterSwitchDensityLow to such a lower value (0.2) makes other strategies less useful + if (Options::profileUse && cgLowerer->GetLabel2Freq().size()) { + for (int32 idx = start; idx <= end; idx++) { + if (switchItems[idx].second == 0) { + freq2case.push_back(std::make_pair( + cgLowerer->GetLabel2Freq()[stmt->GetCasePair(switchItems[idx].first).second], + switchItems[idx].first)); + lastIdx = idx; + } else { + break; + } } - if (cGoto != nullptr) { - localBlk->AddStatement(cGoto); + + std::sort(freq2case.rbegin(), freq2case.rend()); + if (freq2case.size() > 0 && freq2case[0].first != freq2case[freq2case.size()-1].first) { + freqPriority = true; + } + } + + if (Options::profileUse && freqPriority) { + for (std::pair f2c : freq2case) { + int32 idx = f2c.second; + cGoto = BuildCondGotoNode(switchItems[idx].first, OP_brtrue, *BuildCmpNode(OP_eq, switchItems[idx].first)); + if (cGoto != nullptr) { + localBlk->AddStatement(cGoto); + } } - if (lowBlockNodeChecked && (start < end)) { - lowBlockNodeChecked = (stmt->GetCasePair(switchItems[start].first).first + 1 == - stmt->GetCasePair(switchItems[start + 1].first).first); + + if (lastIdx != -1) { + if (lowBlockNodeChecked && (lastIdx < end)) { + lowBlockNodeChecked = (stmt->GetCasePair(switchItems[lastIdx].first).first + 1 == + stmt->GetCasePair(switchItems[lastIdx + 1].first).first); + } + start = lastIdx + 1; + } + } else { + while ((start <= end) && (switchItems[start].second == 0)) { + if ((start == end) && lowBlockNodeChecked && highBlockNodeChecked) { + cGoto = reinterpret_cast(BuildGotoNode(switchItems[start].first)); /* can omit the condition */ + } else { + cGoto = BuildCondGotoNode(switchItems[start].first, OP_brtrue, *BuildCmpNode(OP_eq, switchItems[start].first)); + } + if (cGoto != nullptr) { + localBlk->AddStatement(cGoto); + } + if (lowBlockNodeChecked && (start < end)) { + lowBlockNodeChecked = (stmt->GetCasePair(switchItems[start].first).first + 1 == + stmt->GetCasePair(switchItems[start + 1].first).first); + } + ++start; } - ++start; } if (start <= end) { /* recursive call */ BlockNode *tmp = BuildCodeForSwitchItems(start, end, lowBlockNodeChecked, highBlockNodeChecked); diff --git a/src/mapleall/maple_me/src/me_emit.cpp b/src/mapleall/maple_me/src/me_emit.cpp index eaea1c8ede..28d59e4314 100644 --- a/src/mapleall/maple_me/src/me_emit.cpp +++ b/src/mapleall/maple_me/src/me_emit.cpp @@ -144,9 +144,6 @@ bool MEEmit::PhaseRun(maple::MeFunction &f) { f.GetCfg()->DumpToFile("meemit", true); } } - if (Options::profileUse && f.GetMirFunc()->GetFuncProfData()) { - f.GetMirFunc()->SetFuncProfData(nullptr); - } return false; } -- Gitee From 72bcfe67eed530aa5a3cd4923d85539d6bd77ca3 Mon Sep 17 00:00:00 2001 From: fye Date: Fri, 28 Oct 2022 09:27:43 -0700 Subject: [PATCH 2/2] PGO: switch stmt lowerer --- src/mapleall/maple_be/include/be/lower.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mapleall/maple_be/include/be/lower.h b/src/mapleall/maple_be/include/be/lower.h index 0d3505490c..04c1ffc525 100644 --- a/src/mapleall/maple_be/include/be/lower.h +++ b/src/mapleall/maple_be/include/be/lower.h @@ -267,7 +267,7 @@ class CGLowerer { void BuildLabel2FreqMap(); - std::unordered_map GetLabel2Freq() { + std::unordered_map &GetLabel2Freq() { return l2fMap; } -- Gitee