From 363267b5e7748e59c496d20b59cae2cefd580514 Mon Sep 17 00:00:00 2001 From: William Chen Date: Tue, 5 Jul 2022 09:18:54 -0700 Subject: [PATCH] Reorder back-to-back cond branch and uncond brach to loop head bb --- src/mapleall/maple_be/include/cg/cfgo.h | 24 +++++++++ src/mapleall/maple_be/include/cg/loop.h | 3 +- src/mapleall/maple_be/src/cg/cfgo.cpp | 65 ++++++++++++++++++++++++- src/mapleall/maple_be/src/cg/loop.cpp | 4 ++ 4 files changed, 93 insertions(+), 3 deletions(-) diff --git a/src/mapleall/maple_be/include/cg/cfgo.h b/src/mapleall/maple_be/include/cg/cfgo.h index e7d6e07e14..2528f03413 100644 --- a/src/mapleall/maple_be/include/cg/cfgo.h +++ b/src/mapleall/maple_be/include/cg/cfgo.h @@ -18,6 +18,14 @@ #include "optimize_common.h" namespace maplebe { + +enum CfgoPhase : maple::uint8 { + CfgoDefault, + CfgoPreRegAlloc, + CfgoPostRegAlloc, + PostCfgo, +}; + class ChainingPattern : public OptimizationPattern { public: explicit ChainingPattern(CGFunc &func) : OptimizationPattern(func) { @@ -63,6 +71,14 @@ class FlipBRPattern : public OptimizationPattern { ~FlipBRPattern() override = default; bool Optimize(BB &curBB) override; + CfgoPhase GetPhase() const { + return phase; + } + void SetPhase(CfgoPhase val) { + phase = val; + } + CfgoPhase phase = CfgoDefault; + protected: void RelocateThrowBB(BB &curBB); }; @@ -120,6 +136,14 @@ class CFGOptimizer : public Optimizer { ~CFGOptimizer() override = default; void InitOptimizePatterns() override; + + CfgoPhase GetPhase() const { + return phase; + } + void SetPhase(CfgoPhase val) { + phase = val; + } + CfgoPhase phase = CfgoDefault; }; MAPLE_FUNC_PHASE_DECLARE_BEGIN(CgCfgo, maplebe::CGFunc) diff --git a/src/mapleall/maple_be/include/cg/loop.h b/src/mapleall/maple_be/include/cg/loop.h index 658ee83f04..eedf5bc02c 100644 --- a/src/mapleall/maple_be/include/cg/loop.h +++ b/src/mapleall/maple_be/include/cg/loop.h @@ -171,7 +171,8 @@ class CGFuncLoops { void CheckOverlappingInnerLoops(const MapleVector &iLoops, const MapleVector &loopMem) const; void CheckLoops() const; - void PrintLoops(const CGFuncLoops &funcLoop) const; + void PrintLoops(const CGFuncLoops &loops) const; + bool IsBBLoopMember(const BB *bb) const; const BB *GetHeader() const { return header; diff --git a/src/mapleall/maple_be/src/cg/cfgo.cpp b/src/mapleall/maple_be/src/cg/cfgo.cpp index 4fce8865a7..651204ccb8 100644 --- a/src/mapleall/maple_be/src/cg/cfgo.cpp +++ b/src/mapleall/maple_be/src/cg/cfgo.cpp @@ -42,7 +42,11 @@ void CFGOptimizer::InitOptimizePatterns() { diffPassPatterns.emplace_back(memPool->New(*cgFunc)); } diffPassPatterns.emplace_back(memPool->New(*cgFunc)); - diffPassPatterns.emplace_back(memPool->New(*cgFunc)); + FlipBRPattern *brOpt = memPool->New(*cgFunc); + if (GetPhase() == CfgoPostRegAlloc) { + brOpt->SetPhase(CfgoPostRegAlloc); + } + diffPassPatterns.emplace_back(brOpt); diffPassPatterns.emplace_back(memPool->New(*cgFunc)); diffPassPatterns.emplace_back(memPool->New(*cgFunc)); diffPassPatterns.emplace_back(memPool->New(*cgFunc)); @@ -548,7 +552,13 @@ void FlipBRPattern::RelocateThrowBB(BB &curBB) { * ftBB * targetBB * - * 2. relocate throw BB in RelocateThrowBB() + * loopHeaderBB: loopHeaderBB: + * ... ... + * cond_br loopExit: cond_br loopHeaderBB + * ftBB: ftBB: + * goto loopHeaderBB: goto loopExit + * + * 3. relocate throw BB in RelocateThrowBB() */ bool FlipBRPattern::Optimize(BB &curBB) { if (curBB.GetKind() == BB::kBBIf && !curBB.IsEmpty()) { @@ -648,6 +658,50 @@ bool FlipBRPattern::Optimize(BB &curBB) { ftBB->RemoveInsn(*brInsn); ftBB->SetKind(BB::kBBFallthru); } + } else if (GetPhase() == CfgoPostRegAlloc && ftBB->GetKind() == BB::kBBGoto && + curBB.GetLoop() != nullptr && curBB.GetLoop() == ftBB->GetLoop() && + ftBB->IsSoloGoto() && + ftBB->GetLoop()->GetHeader() == *(ftBB->GetSuccsBegin()) && + curBB.GetLoop()->IsBBLoopMember((curBB.GetSuccs().front() == ftBB) ? + curBB.GetSuccs().back() : curBB.GetSuccs().front()) == false) { + Insn *curBBBranchInsn = nullptr; + for (curBBBranchInsn = curBB.GetLastInsn(); curBBBranchInsn != nullptr; + curBBBranchInsn = curBBBranchInsn->GetPrev()) { + if (curBBBranchInsn->IsBranch()) { + break; + } + } + ASSERT(curBBBranchInsn != nullptr, "FlipBRPattern: curBB has no branch"); + Insn *brInsn = nullptr; + for (brInsn = ftBB->GetLastInsn(); brInsn != nullptr; brInsn = brInsn->GetPrev()) { + if (brInsn->IsGoto()) { + break; + } + } + ASSERT(brInsn != nullptr, "FlipBRPattern: ftBB has no branch"); + uint32 condTargetIdx = curBBBranchInsn->GetJumpTargetIdx(); + LabelOperand &condTarget = static_cast(curBBBranchInsn->GetOperand(condTargetIdx)); + MOperator mOp = curBBBranchInsn->FlipConditionOp(curBBBranchInsn->GetMachineOpcode(), condTargetIdx); + if (mOp == 0) { + return false; + } + uint32 gotoTargetIdx = brInsn->GetJumpTargetIdx(); + LabelOperand &gotoTarget = static_cast(brInsn->GetOperand(gotoTargetIdx)); + curBBBranchInsn->SetMOP(mOp); + curBBBranchInsn->SetOperand(condTargetIdx, gotoTarget); + brInsn->SetOperand(gotoTargetIdx, condTarget); + auto it = ftBB->GetSuccsBegin(); + BB *loopHeadBB = *it; + + curBB.RemoveSuccs(*brBB); + brBB->RemovePreds(curBB); + ftBB->RemoveSuccs(*loopHeadBB); + loopHeadBB->RemovePreds(*ftBB); + + curBB.PushBackSuccs(*loopHeadBB); + loopHeadBB->PushBackPreds(curBB); + ftBB->PushBackSuccs(*brBB); + brBB->PushBackPreds(*ftBB); } else { RelocateThrowBB(curBB); } @@ -848,6 +902,10 @@ bool DuplicateBBPattern::Optimize(BB &curBB) { /* === new pm === */ bool CgCfgo::PhaseRun(maplebe::CGFunc &f) { CFGOptimizer *cfgOptimizer = GetPhaseAllocator()->New(f, *GetPhaseMemPool()); + if (f.IsAfterRegAlloc()) { + (void)GetAnalysisInfoHook()->ForceRunAnalysisPhase, CGFunc>(&CgLoopAnalysis::id, f); + cfgOptimizer->SetPhase(CfgoPostRegAlloc); + } const std::string &funcClass = f.GetFunction().GetBaseClassName(); const std::string &funcName = f.GetFunction().GetBaseFuncName(); const std::string &name = funcClass + funcName; @@ -855,6 +913,9 @@ bool CgCfgo::PhaseRun(maplebe::CGFunc &f) { DotGenerator::GenerateDot("before-cfgo", f, f.GetMirModule()); } cfgOptimizer->Run(name); + if (f.IsAfterRegAlloc()) { + GetAnalysisInfoHook()->ForceEraseAnalysisPhase(f.GetUniqueID(), &CgLoopAnalysis::id); + } if (CFGO_DUMP_NEWPM) { DotGenerator::GenerateDot("after-cfgo", f, f.GetMirModule()); } diff --git a/src/mapleall/maple_be/src/cg/loop.cpp b/src/mapleall/maple_be/src/cg/loop.cpp index 71fb9e8edb..d37a7e0dfd 100644 --- a/src/mapleall/maple_be/src/cg/loop.cpp +++ b/src/mapleall/maple_be/src/cg/loop.cpp @@ -161,6 +161,10 @@ void CGFuncLoops::PrintLoops(const CGFuncLoops &funcLoop) const { } } +bool CGFuncLoops::IsBBLoopMember(const BB *bb) const { + return (*(std::find(loopMembers.begin(), loopMembers.end(), bb)) == bb); +} + // partial loop body found with formLoop is NOT really needed in down stream // It should be simplied later void LoopFinder::formLoop(BB* headBB, BB* backBB) { -- Gitee