From 5dc53578195669da270af46435a885fb41277b44 Mon Sep 17 00:00:00 2001 From: William Chen Date: Mon, 22 Aug 2022 14:48:07 -0700 Subject: [PATCH] Use attribute 'noreturn' instead hard code abort and exit names Front-end must support library functions such as abort() and exit() and mark their attribute as 'noreturn'. Blindly matching common function name is incorrect as they can be a user written function --- src/mapleall/maple_be/include/cg/cgbb.h | 1 + src/mapleall/maple_be/include/cg/cgfunc.h | 5 +++ .../src/cg/aarch64/aarch64_cgfunc.cpp | 4 ++ .../maple_be/src/cg/aarch64/aarch64_ico.cpp | 8 ++++ src/mapleall/maple_be/src/cg/cfgo.cpp | 14 ++++-- src/mapleall/maple_be/src/cg/cg_cfg.cpp | 44 ++++++++++++++++++- src/mapleall/maple_be/src/cg/cg_dominance.cpp | 2 + src/mapleall/maple_be/src/cg/cgbb.cpp | 8 ++++ src/mapleall/maple_be/src/cg/cgfunc.cpp | 27 +++++++++--- src/mapleall/maple_be/src/cg/eh_func.cpp | 1 + 10 files changed, 104 insertions(+), 10 deletions(-) diff --git a/src/mapleall/maple_be/include/cg/cgbb.h b/src/mapleall/maple_be/include/cg/cgbb.h index 5996b8937e..44c98537ee 100644 --- a/src/mapleall/maple_be/include/cg/cgbb.h +++ b/src/mapleall/maple_be/include/cg/cgbb.h @@ -83,6 +83,7 @@ class BB { kBBGoto, /* unconditional branch */ kBBIgoto, kBBReturn, + kBBNoReturn, kBBIntrinsic, /* BB created by inlining intrinsics; shares a lot with BB_if */ kBBRangeGoto, kBBThrow, /* For call __java_throw_* and call exit, which will run out of function. */ diff --git a/src/mapleall/maple_be/include/cg/cgfunc.h b/src/mapleall/maple_be/include/cg/cgfunc.h index 483f684893..28e2c4e7fc 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -803,6 +803,10 @@ class CGFunc { return exitBBVec.at(index); } + void PushBackNoReturnCallBBsVec(BB &bb) { + noReturnCallBBVec.emplace_back(&bb); + } + void SetLab2BBMap(int32 index, BB &bb) { lab2BBMap[index] = &bb; } @@ -1285,6 +1289,7 @@ class CGFunc { BB *commonExitBB = nullptr; /* this post-dominate all BBs */ Insn *volReleaseInsn = nullptr; /* use to record the release insn for volatile strore */ MapleVector exitBBVec; + MapleVector noReturnCallBBVec; MapleSet extendSet; /* use to mark regs which spilled 32 bits but loaded 64 bits. */ MapleUnorderedMap lab2BBMap; BECommon &beCommon; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp index 23e9b572ae..670a4c92ee 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8826,6 +8826,10 @@ void AArch64CGFunc::SelectCall(CallNode &callNode) { GetCurBB()->ClearInsns(); GetCurBB()->SetUnreachable(true); } + if (fn->GetAttr(FUNCATTR_noreturn)) { + GetCurBB()->SetKind(BB::kBBNoReturn); + PushBackNoReturnCallBBsVec(*GetCurBB()); + } return; } if ((fsym->GetName() == "MCC_ThrowException") || (fsym->GetName() == "MCC_RethrowException") || diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_ico.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_ico.cpp index 9ace92c06d..9163da2fbb 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_ico.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_ico.cpp @@ -628,10 +628,18 @@ bool AArch64ICOIfThenElsePattern::DoOpt(BB &cmpBB, BB *ifBB, BB *elseBB, BB &joi /* Remove branches and merge join */ if (ifBB != nullptr) { + BB *prevLast = ifBB->GetPrev(); cgFunc->GetTheCFG()->RemoveBB(*ifBB); + if (ifBB->GetId() == cgFunc->GetLastBB()->GetId()) { + cgFunc->SetLastBB(*prevLast); + } } if (elseBB != nullptr) { + BB *prevLast = elseBB->GetPrev(); cgFunc->GetTheCFG()->RemoveBB(*elseBB); + if (elseBB->GetId() == cgFunc->GetLastBB()->GetId()) { + cgFunc->SetLastBB(*prevLast); + } } /* maintain won't exit bb info. */ if ((ifBB != nullptr && ifBB->IsWontExit()) || (elseBB != nullptr && elseBB->IsWontExit())) { diff --git a/src/mapleall/maple_be/src/cg/cfgo.cpp b/src/mapleall/maple_be/src/cg/cfgo.cpp index 491ab5cd56..de744217b2 100644 --- a/src/mapleall/maple_be/src/cg/cfgo.cpp +++ b/src/mapleall/maple_be/src/cg/cfgo.cpp @@ -129,8 +129,14 @@ bool ChainingPattern::MoveSuccBBAsCurBBNext(BB &curBB, BB &sucBB) { sucBB.GetNext()->SetPrev(sucBB.GetPrev()); } sucBB.SetNext(curBB.GetNext()); - ASSERT(curBB.GetNext() != nullptr, "current goto BB will not be the last bb"); - curBB.GetNext()->SetPrev(&sucBB); + if (curBB.GetNext() != nullptr) { + curBB.GetNext()->SetPrev(&sucBB); + } + if (sucBB.GetId() == cgFunc->GetLastBB()->GetId()) { + cgFunc->SetLastBB(*(sucBB.GetPrev())); + } else if (curBB.GetId() == cgFunc->GetLastBB()->GetId()) { + cgFunc->SetLastBB(sucBB); + } sucBB.SetPrev(&curBB); curBB.SetNext(&sucBB); curBB.RemoveInsn(*curBB.GetLastInsn()); @@ -728,7 +734,7 @@ bool UnreachBBPattern::Optimize(BB &curBB) { } /* if curBB in exitbbsvec,return false. */ if (cgFunc->IsExitBB(curBB)) { - curBB.SetUnreachable(false); + curBB.SetUnreachable(cgFunc->GetMirModule().GetSrcLang() == kSrcLangC); return false; } @@ -767,6 +773,8 @@ bool UnreachBBPattern::Optimize(BB &curBB) { } if (curBB.GetNext() != nullptr) { curBB.GetNext()->SetPrev(curBB.GetPrev()); + } else { + cgFunc->SetLastBB(*(curBB.GetPrev())); } /* flush after remove; */ diff --git a/src/mapleall/maple_be/src/cg/cg_cfg.cpp b/src/mapleall/maple_be/src/cg/cg_cfg.cpp index 35b77b3be3..d01f87563d 100644 --- a/src/mapleall/maple_be/src/cg/cg_cfg.cpp +++ b/src/mapleall/maple_be/src/cg/cg_cfg.cpp @@ -147,6 +147,25 @@ void CGCFG::BuildCFG() { } } } + FindAndMarkUnreachable(*cgFunc); +#if 0 + for (BB *bb = firstBB; bb != nullptr; bb = bb->GetNext()) { + if (bb->IsUnreachable()) { + FOR_BB_INSNS_SAFE(insn, bb, ninsn) { + bb->RemoveInsn(*insn); + } + if (bb->GetKind() != BB::kBBReturn) { + bb->SetKind(BB::kBBFallthru); + } + } + } +#else + //CFGOptimizer *cfgOptimizer = GetPhaseAllocator()->New(*cgFunc, *GetPhaseMemPool()); +// OptimizationPattern *pattern = memPool->New(*cgFunc); +// for (BB *bb = firstBB; bb != nullptr; bb = bb->GetNext()) { +// pattern->Optimize(*curBB); +// } +#endif } void CGCFG::CheckCFG() { @@ -300,7 +319,11 @@ bool CGCFG::AreCommentAllPreds(const BB &bb) { /* Merge sucBB into curBB. */ void CGCFG::MergeBB(BB &merger, BB &mergee, CGFunc &func) { + BB *prevLast = mergee.GetPrev(); MergeBB(merger, mergee); + if (func.GetLastBB()->GetId() == mergee.GetId()) { + func.SetLastBB(*prevLast); + } if (mergee.GetKind() == BB::kBBReturn) { for (size_t i = 0; i < func.ExitBBsVecSize(); ++i) { if (func.GetExitBB(i) == &mergee) { @@ -405,6 +428,18 @@ void CGCFG::FindAndMarkUnreachable(CGFunc &func) { } } } + FOR_ALL_BB(bb, &func) { + for (MapleList::iterator predIt = bb->GetPredsBegin(); predIt != bb->GetPredsEnd(); ++predIt) { + if ((*predIt)->IsUnreachable()) { + bb->ErasePreds(predIt); + } + } + for (MapleList::iterator predIt = bb->GetEhPredsBegin(); predIt != bb->GetEhPredsEnd(); ++predIt) { + if ((*predIt)->IsUnreachable()) { + bb->ErasePreds(predIt); + } + } + } } /* @@ -521,9 +556,11 @@ void CGCFG::RemoveBB(BB &curBB, bool isGotoIf) const { for (BB *ehPred : curBB.GetEhPreds()) { ehPred->RemoveEhSuccs(curBB); } - curBB.GetNext()->RemovePreds(curBB); + if (curBB.GetNext()) { + curBB.GetNext()->RemovePreds(curBB); + curBB.GetNext()->SetPrev(curBB.GetPrev()); + } curBB.GetPrev()->SetNext(curBB.GetNext()); - curBB.GetNext()->SetPrev(curBB.GetPrev()); cgFunc->ClearBBInVec(curBB.GetId()); /* remove callsite */ EHFunc *ehFunc = cgFunc->GetEHFunc(); @@ -871,6 +908,9 @@ void CGCFG::BreakCriticalEdge(BB &pred, BB &succ) { cgFunc->SetLastBB(*newBB); } else { exitBB->AppendBB(*newBB); + if (cgFunc->GetLastBB() == exitBB) { + cgFunc->SetLastBB(*newBB); + } } newBB->AppendInsn( cgFunc->GetInsnBuilder()->BuildInsn(MOP_xuncond, cgFunc->GetOrCreateLabelOperand(succ.GetLabIdx()))); diff --git a/src/mapleall/maple_be/src/cg/cg_dominance.cpp b/src/mapleall/maple_be/src/cg/cg_dominance.cpp index f90d95282b..42a045833e 100644 --- a/src/mapleall/maple_be/src/cg/cg_dominance.cpp +++ b/src/mapleall/maple_be/src/cg/cg_dominance.cpp @@ -16,6 +16,7 @@ #include #include "cg_option.h" #include "cgfunc.h" +#include "optimize_common.h" /* * This phase build dominance @@ -478,6 +479,7 @@ bool CgPostDomAnalysis::PhaseRun(maplebe::CGFunc &f) { MemPool *pdomMemPool = GetPhaseMemPool(); pdomAnalysis = pdomMemPool->New(f, *pdomMemPool, *pdomMemPool, f.GetAllBBs(), *f.GetFirstBB(), *f.GetCommonExitBB()); +//DotGenerator::GenerateDot("pdom", f, f.GetMirModule(), true, f.GetName()); pdomAnalysis->Compute(); if (CG_DEBUG_FUNC(f)) { pdomAnalysis->Dump(); diff --git a/src/mapleall/maple_be/src/cg/cgbb.cpp b/src/mapleall/maple_be/src/cg/cgbb.cpp index 37b59177e3..b22e34d5ea 100644 --- a/src/mapleall/maple_be/src/cg/cgbb.cpp +++ b/src/mapleall/maple_be/src/cg/cgbb.cpp @@ -317,6 +317,14 @@ void BB::Dump() const { if (unreachable) { LogInfo::MapleLogger() << "[unreachable] "; } + LogInfo::MapleLogger() << "succs "; + for (auto *bb : succs) { + LogInfo::MapleLogger() << bb->id << " "; + } + LogInfo::MapleLogger() << "preds "; + for (auto *bb : preds) { + LogInfo::MapleLogger() << bb->id << " "; + } LogInfo::MapleLogger() << "frequency:" << frequency << "===\n"; Insn *insn = firstInsn; diff --git a/src/mapleall/maple_be/src/cg/cgfunc.cpp b/src/mapleall/maple_be/src/cg/cgfunc.cpp index 020701201c..4ff101961c 100644 --- a/src/mapleall/maple_be/src/cg/cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/cgfunc.cpp @@ -22,6 +22,7 @@ #include "mir_builder.h" #include "factory.h" #include "debug_info.h" +#include "cfgo.h" #include "optimize_common.h" #include "me_function.h" @@ -1426,6 +1427,7 @@ CGFunc::CGFunc(MIRModule &mod, CG &cg, MIRFunction &mirFunc, BECommon &beCommon, stackMp(stackMp), func(mirFunc), exitBBVec(allocator.Adapter()), + noReturnCallBBVec(allocator.Adapter()), extendSet(allocator.Adapter()), lab2BBMap(allocator.Adapter()), beCommon(beCommon), @@ -2079,11 +2081,6 @@ void CGFunc::ProcessExitBBVec() { } void CGFunc::AddCommonExitBB() { - uint32 i = 0; - while (exitBBVec[i]->IsUnreachable() && i < exitBBVec.size()) { - i++; - } - ASSERT(i < exitBBVec.size(), "all exit BBs are unreachable"); // create fake commonExitBB commonExitBB = CreateNewBB(true, BB::kBBFallthru, 0); ASSERT(commonExitBB != nullptr, "cannot create fake commonExitBB"); @@ -2092,6 +2089,22 @@ void CGFunc::AddCommonExitBB() { commonExitBB->PushBackPreds(*cgbb); } } + for (BB *cgbb : noReturnCallBBVec) { + commonExitBB->PushBackPreds(*cgbb); + } +#if 0 + std::cout << "--->commonExit bb " << commonExitBB->GetId() << "\n"; + commonExitBB->Dump(); + if (mirModule.GetSrcLang() == kSrcLangC) { + BB *oldLastBB = GetLastBB(); + oldLastBB->SetNext(commonExitBB); + commonExitBB->SetPrev(oldLastBB); + commonExitBB->SetNext(nullptr); + /* fake commonExitBB only has preds, no succs, so it is not reachable */ + commonExitBB->SetUnreachable(true); + SetLastBB(*commonExitBB); + } +#endif } void CGFunc::UpdateCallBBFrequency() { @@ -2131,6 +2144,10 @@ void CGFunc::HandleFunction() { /* build control flow graph */ theCFG = memPool->New(*this); theCFG->BuildCFG(); +OptimizationPattern *pattern = memPool->New(*this); +for (BB *bb = firstBB; bb != nullptr; bb = bb->GetNext()) { + pattern->Optimize(*bb); +} AddCommonExitBB(); if (mirModule.GetSrcLang() != kSrcLangC) { MarkCatchBBs(); diff --git a/src/mapleall/maple_be/src/cg/eh_func.cpp b/src/mapleall/maple_be/src/cg/eh_func.cpp index ea3f5c54e1..d761e65c26 100644 --- a/src/mapleall/maple_be/src/cg/eh_func.cpp +++ b/src/mapleall/maple_be/src/cg/eh_func.cpp @@ -512,6 +512,7 @@ void EHFunc::InsertDefaultLabelAndAbortFunc(BlockNode &blkNode, SwitchNode &swit StmtNode *dfLabStmt = mirModule.GetMIRBuilder()->CreateStmtLabel(dfLabIdx); blkNode.InsertAfter(&beforeEndLabel, dfLabStmt); MIRFunction *calleeFunc = mirModule.GetMIRBuilder()->GetOrCreateFunction("abort", static_cast(PTY_void)); + calleeFunc->SetAttr(FUNCATTR_noreturn); cgFunc->GetBecommon().UpdateTypeTable(*calleeFunc->GetMIRFuncType()); MapleVector args(mirModule.GetMIRBuilder()->GetCurrentFuncCodeMpAllocator()->Adapter()); CallNode *callExit = mirModule.GetMIRBuilder()->CreateStmtCall(calleeFunc->GetPuidx(), args); -- Gitee