diff --git a/src/mapleall/maple_be/include/be/lower.h b/src/mapleall/maple_be/include/be/lower.h index 70e9e00d4db3966936a3a41205bf1b391e907599..04c1ffc52533c33286ef5f9ca51daa929cfd14b9 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 38467837836606acc5e9aa7112ad38634a3c25a7..18450a1b39e0dd1d797054c80a519f8255932cd8 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 62eeaa7055cae1114570e1c5e093574a7fab13c7..52d3aa7aa0536936ca1c82580d37fa4501948161 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 f22950bf629819e7e8adf71ac5d31909e1903ec8..7789e5cf203c8d0ce69c8590d692524b6c8592ae 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 eaea1c8ede9397eef91e4b36343875634e051e78..28d59e43145fcb5e65e35865e3c8432edc858170 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; }