diff --git a/src/mapleall/maple_be/include/cg/cgbb.h b/src/mapleall/maple_be/include/cg/cgbb.h index 5996b8937e604be774171a15756381d704d9c84d..44c98537ee9c4c44483ace846fbbcb92fee65d60 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 281c496a6034b3c2a69623e1ced9b518bb38d238..f281d420cca6d308aeb98111c053a6c193f612bb 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -163,6 +163,7 @@ class CGFunc { virtual void AssignLmbcFormalParams() = 0; LmbcFormalParamInfo *GetLmbcFormalParamInfo(uint32 offset); virtual void LmbcGenSaveSpForAlloca() = 0; + void RemoveUnreachableBB(); void GenerateLoc(StmtNode *stmt, SrcPosition &lastSrcPos, SrcPosition &lastMplPos); void GenerateScopeLabel(StmtNode *stmt, SrcPosition &lastSrcPos, bool &posDone); int32 GetFreqFromStmt(uint32 stmtId); @@ -803,6 +804,10 @@ class CGFunc { return exitBBVec.at(index); } + void PushBackNoReturnCallBBsVec(BB &bb) { + noReturnCallBBVec.emplace_back(&bb); + } + void SetLab2BBMap(int32 index, BB &bb) { lab2BBMap[index] = &bb; } @@ -1335,6 +1340,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 a8ba4ddc1b38b97cd7b3bce217d344cc741f5af4..3c6639a2f8ee28ede3af884486de395767ce04e9 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8874,6 +8874,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 727cac2df3e9ef556890428b863461f476cb3486..631cb484dfa5790f38b18b80b4c2bb3f4dcc1001 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 48cbaba2d6b64482a29d549bd62fbf8572ec4f1c..4e738f74245024514dfd50f2c9698b9c42bfdad0 100644 --- a/src/mapleall/maple_be/src/cg/cfgo.cpp +++ b/src/mapleall/maple_be/src/cg/cfgo.cpp @@ -129,7 +129,14 @@ bool ChainingPattern::MoveSuccBBAsCurBBNext(BB &curBB, BB &sucBB) { sucBB.GetNext()->SetPrev(sucBB.GetPrev()); } sucBB.SetNext(curBB.GetNext()); - 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()); @@ -717,7 +724,8 @@ bool UnreachBBPattern::Optimize(BB &curBB) { } /* if curBB in exitbbsvec,return false. */ if (cgFunc->IsExitBB(curBB)) { - curBB.SetUnreachable(false); + /* In C some bb follow noreturn calls should remain unreachable */ + curBB.SetUnreachable(cgFunc->GetMirModule().GetSrcLang() == kSrcLangC); return false; } @@ -751,6 +759,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 021b8562e5c816dfe049cd238e44510dc8e2dbb9..41b1754f95fda798b20679ee9fda16f03028349c 100644 --- a/src/mapleall/maple_be/src/cg/cg_cfg.cpp +++ b/src/mapleall/maple_be/src/cg/cg_cfg.cpp @@ -147,6 +147,7 @@ void CGCFG::BuildCFG() { } } } + FindAndMarkUnreachable(*cgFunc); } void CGCFG::CheckCFG() { @@ -300,7 +301,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) { @@ -406,6 +411,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); + } + } + } } /* @@ -867,6 +884,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/cgbb.cpp b/src/mapleall/maple_be/src/cg/cgbb.cpp index a15d7c656764e9d9af04138c5c1100ef1eca3e41..b1f11d9ef324ae830dec09a691110494bdc2b71c 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 10512f35ef956972ab08a40040cad425effe16f1..8b6eb8c2b62f903ebf8595229e8ce1765fb1c07b 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), @@ -1535,6 +1537,19 @@ bool CGFunc::CheckSkipMembarOp(const StmtNode &stmt) { return false; } +void CGFunc::RemoveUnreachableBB() { + OptimizationPattern *pattern = memPool->New(*this); + for (BB *bb = firstBB; bb != nullptr; bb = bb->GetNext()) { + pattern->Optimize(*bb); + if (bb->GetPreds().size() == 0 && bb->GetSuccs().size() == 0) { + auto it = find(noReturnCallBBVec.begin(), noReturnCallBBVec.end(), bb); + if (it != noReturnCallBBVec.end()) { + noReturnCallBBVec.erase(it); + } + } + } +} + void CGFunc::GenerateLoc(StmtNode *stmt, SrcPosition &lastSrcPos, SrcPosition &lastMplPos) { /* insert Insn for .loc before cg for the stmt */ if (cg->GetCGOptions().WithLoc() && stmt->op != OP_label && stmt->op != OP_comment) { @@ -2091,11 +2106,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"); @@ -2104,6 +2114,9 @@ void CGFunc::AddCommonExitBB() { commonExitBB->PushBackPreds(*cgbb); } } + for (BB *cgbb : noReturnCallBBVec) { + commonExitBB->PushBackPreds(*cgbb); + } } void CGFunc::UpdateCallBBFrequency() { @@ -2143,6 +2156,7 @@ void CGFunc::HandleFunction() { /* build control flow graph */ theCFG = memPool->New(*this); theCFG->BuildCFG(); + RemoveUnreachableBB(); 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 ea3f5c54e167db91741c4deb86faa8f59d1ade49..d761e65c26e8aba3d5c39eea883a2c4091447768 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);