diff --git a/src/mapleall/maple_me/include/me_bb_layout.h b/src/mapleall/maple_me/include/me_bb_layout.h index 6a8369587abbd20140d7cfa5ab0ec7a51ec6f8a8..4a5815fbf2a08b706b28d15b4ce8cf9482dba411 100644 --- a/src/mapleall/maple_me/include/me_bb_layout.h +++ b/src/mapleall/maple_me/include/me_bb_layout.h @@ -70,6 +70,8 @@ class BBLayout{ BB *CreateGotoBBAfterCondBB(BB &bb, BB &fallthru); bool ChooseTargetAsFallthru(const BB &bb, const BB &targetBB, const BB &oldFallThru, const BB &fallThru) const; + void ChangeToFallthruFromCondGoto(BB &bb); + void OptimizeEmptyFallThruBB(BB &bb); const MapleVector &GetBBs() const { return layoutBBs; } diff --git a/src/mapleall/maple_me/src/me_bb_layout.cpp b/src/mapleall/maple_me/src/me_bb_layout.cpp index 3125b26bd9573088edc58fc4bf0c08f24ca13f60..b37d54a67f9d3eca00668e71ecd144027dff9fdd 100644 --- a/src/mapleall/maple_me/src/me_bb_layout.cpp +++ b/src/mapleall/maple_me/src/me_bb_layout.cpp @@ -298,6 +298,7 @@ void BBLayout::OptimizeBranchTarget(BB &bb) { do { ASSERT(!bb.GetSucc().empty(), "container check"); BB *brTargetBB = bb.GetKind() == kBBCondGoto ? bb.GetSucc().back() : bb.GetSucc().front(); + CHECK_FATAL((bb.GetKind() != kBBCondGoto || bb.GetSucc().back() != bb.GetSucc().front()), "target is same as fallthru"); if (brTargetBB->GetAttributes(kBBAttrWontExit)) { return; } @@ -449,6 +450,16 @@ void BBLayout::ChangeToFallthruFromGoto(BB &bb) { bb.SetKind(kBBFallthru); } +void BBLayout::ChangeToFallthruFromCondGoto(BB &bb) { + ASSERT(bb.GetKind() == kBBCondGoto, "ChangeToFallthruFromCondGoto: unexpected BB kind"); + if (func.GetIRMap() != nullptr) { + bb.RemoveMeStmt(to_ptr(bb.GetMeStmts().rbegin())); + } else { + bb.RemoveLastStmt(); + } + bb.SetKind(kBBFallthru); +} + // bb does not end with a branch statement; if its fallthru is not nextBB, // perform the fix by either laying out the fallthru immediately or adding a goto void BBLayout::ResolveUnconditionalFallThru(BB &bb, BB &nextBB) { @@ -643,6 +654,23 @@ BB *BBLayout::CreateGotoBBAfterCondBB(BB &bb, BB &fallthru) { return newFallthru; } +void BBLayout::OptimizeEmptyFallThruBB(BB &bb) { + if (needDealWithTryBB) { return; } + auto *fallthru = bb.GetSucc().front(); + if (fallthru && fallthru->GetBBLabel() == 0 && + (BBEmptyAndFallthru(*fallthru) || BBContainsOnlyGoto(*fallthru))) { + if (fallthru->GetSucc().front() == bb.GetSucc().back()) { + bb.ReplaceSucc(fallthru, bb.GetSucc().back()); + ASSERT(fallthru->GetPred().empty(), "fallthru should not has other pred"); + ChangeToFallthruFromCondGoto(bb); + bb.GetSucc().pop_back(); // resize succ to 1 + laidOut[fallthru->GetBBId()] = true; + RemoveUnreachable(*fallthru); + } + } + return; +} + void BBLayout::DumpBBPhyOrder() const { LogInfo::MapleLogger() << func.GetName() << " final BB order " << '\n'; for (auto bb : layoutBBs) { @@ -663,6 +691,16 @@ void BBLayout::OptimiseCFG() { auto *bb = *bIt; if (bb->GetKind() == kBBCondGoto || bb->GetKind() == kBBGoto) { OptimizeBranchTarget(*bb); + // check fallthru is empty without label, delete fallthru and + // make fallthrSucc as the only succ of bb + // bb + // / \ + // fallthru | + // \ / + // fallthruSucc + if (bb->GetKind() == kBBCondGoto) { + OptimizeEmptyFallThruBB(*bb); + } } } cfg->UnreachCodeAnalysis(true); @@ -795,15 +833,14 @@ void BBLayout::AddBBProf(BB &bb) { BB *targetBB = curBB->GetSucc().front(); if (curBB->GetKind() == kBBFallthru && (&bb != targetBB)) { CreateGoto(*curBB, func, *targetBB); - } - if (curBB->GetKind() == kBBGoto && (&bb == targetBB)) { + } else if (curBB->GetKind() == kBBGoto && (&bb == targetBB)) { // delete the goto stmt ChangeToFallthruFromGoto(*curBB); } - } - if (curBB->GetKind() == kBBCondGoto) { + } else if (curBB->GetKind() == kBBCondGoto) { BB *fallthru = curBB->GetSucc(0); BB *targetBB = curBB->GetSucc(1); + CHECK_FATAL(targetBB != fallthru, "condbb targetBB is same as fallthru"); if (targetBB == &bb) { LabelIdx fallthruLabel = func.GetOrCreateBBLabel(*fallthru); if (func.GetIRMap() != nullptr) {