diff --git a/src/mapleall/maple_be/include/cg/cg_cfg.h b/src/mapleall/maple_be/include/cg/cg_cfg.h index c5fc2053dbbb3be386518afe3c53b86aefa33838..d20097d958fef02610da70b7ee6d70844931b4f3 100644 --- a/src/mapleall/maple_be/include/cg/cg_cfg.h +++ b/src/mapleall/maple_be/include/cg/cg_cfg.h @@ -106,6 +106,7 @@ class CGCFG { Insn *FindLastCondBrInsn(BB &bb) const; static void FindAndMarkUnreachable(CGFunc &func); void FlushUnReachableStatusAndRemoveRelations(BB &curBB, const CGFunc &func) const; + void MarkLabelTakenBB(); void UnreachCodeAnalysis(); BB *FindLastRetBB(); /* cgcfgvisitor */ diff --git a/src/mapleall/maple_be/include/cg/cgbb.h b/src/mapleall/maple_be/include/cg/cgbb.h index 6c350fde7067017628ad216be87301e7e4fe341b..81cd7bc733c5b4621b88a9c042073731c402f760 100644 --- a/src/mapleall/maple_be/include/cg/cgbb.h +++ b/src/mapleall/maple_be/include/cg/cgbb.h @@ -518,6 +518,12 @@ class BB { void SetIsProEpilog(bool arg) { isProEpilog = arg; } + bool IsLabelTaken() const { + return labelTaken; + } + void SetLabelTaken() { + labelTaken = true; + } long GetInternalFlag1() const { return internalFlag1; } @@ -683,6 +689,7 @@ class BB { */ bool isCleanup = false; /* true if the bb is cleanup bb. otherwise, false. */ bool isProEpilog = false; /* Temporary tag for modifying prolog/epilog bb. */ + bool labelTaken = false; /* Block label is taken indirectly and can be used to jump to it. */ /* * Different meaning for each data flow analysis. * For aarchregalloc.cpp, the bb is part of cleanup at end of function. diff --git a/src/mapleall/maple_be/include/cg/cgfunc.h b/src/mapleall/maple_be/include/cg/cgfunc.h index 00853febc8634f2c1b02248e5fba9f711226fe5a..c7e461c0fc771e033fb243664fec59cda23c33bb 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -801,6 +801,14 @@ class CGFunc { return lSymSize; } + bool HasTakenLabel() { + return hasTakenLabel; + } + + void SetHasTakenLabel() { + hasTakenLabel = true; + } + virtual InsnVisitor *NewInsnModifier() = 0; protected: @@ -827,6 +835,7 @@ class CGFunc { bool isVolStore = false; bool isAfterRegAlloc = false; bool isAggParamInReg = false; + bool hasTakenLabel = false; uint32 frequency = 0; DebugInfo *debugInfo = nullptr; /* debugging info */ RegOperand *aggParamReg = nullptr; diff --git a/src/mapleall/maple_be/src/cg/cg_cfg.cpp b/src/mapleall/maple_be/src/cg/cg_cfg.cpp index 3a9d97b5a3ddc2deeb8c74d0dcbb7007cd8f386d..d795028c5c5bf01d687d2cf84fbe79426abf8058 100644 --- a/src/mapleall/maple_be/src/cg/cg_cfg.cpp +++ b/src/mapleall/maple_be/src/cg/cg_cfg.cpp @@ -277,7 +277,7 @@ void CGCFG::FindAndMarkUnreachable(CGFunc &func) { if (bb->GetFirstStmt() == func.GetCleanupLabel() || InSwitchTable(bb->GetLabIdx(), func) || bb == func.GetFirstBB() || bb == func.GetLastBB()) { toBeAnalyzedBBs.push(bb); - } else { + } else if (bb->IsLabelTaken() == false) { bb->SetUnreachable(true); } bb = bb->GetNext(); @@ -336,7 +336,8 @@ void CGCFG::FlushUnReachableStatusAndRemoveRelations(BB &bb, const CGFunc &func) (it->GetPreds().empty() || (it->GetPreds().size() == 1 && it->GetEhPreds().front() == it)) && it->GetEhPreds().empty() && !InSwitchTable(it->GetLabIdx(), *cgFunc) && - !cgFunc->IsExitBB(*it); + !cgFunc->IsExitBB(*it) && + (it->IsLabelTaken() == false); if (!needFlush) { continue; } @@ -500,11 +501,29 @@ Insn *CGCFG::FindLastCondBrInsn(BB &bb) const { return nullptr; } +void CGCFG::MarkLabelTakenBB() { + if (cgFunc->GetMirModule().GetSrcLang() != kSrcLangC) { + return; + } + for (BB *bb = cgFunc->GetFirstBB(); bb != nullptr; bb = bb->GetNext()) { + if (cgFunc->GetFunction().GetLabelTab()->GetAddrTakenLabels().find(bb->GetLabIdx()) != + cgFunc->GetFunction().GetLabelTab()->GetAddrTakenLabels().end()) { + cgFunc->SetHasTakenLabel(); + bb->SetLabelTaken(); + } + } +} + /* * analyse the CFG to find the BBs that are not reachable from function entries * and delete them */ void CGCFG::UnreachCodeAnalysis() { + if (cgFunc->GetMirModule().GetSrcLang() == kSrcLangC && + (cgFunc->HasTakenLabel() || + (cgFunc->GetEHFunc() && cgFunc->GetEHFunc()->GetLSDAHeader()))) { + return; + } /* * Find all reachable BBs by dfs in cgfunc and mark their field false, * then all other bbs should be unreachable. @@ -524,7 +543,9 @@ void CGCFG::UnreachCodeAnalysis() { } else { (void)unreachBBs.insert(bb); } - bb->SetUnreachable(true); + if (bb->IsLabelTaken() == false) { + bb->SetUnreachable(true); + } bb = bb->GetNext(); } diff --git a/src/mapleall/maple_be/src/cg/cgbb.cpp b/src/mapleall/maple_be/src/cg/cgbb.cpp index 767eb7ca2753d45070b1e1ad857302f61f0680f3..95fb3c9d4cbba08d13aad0fffe5e8f18574ec074 100644 --- a/src/mapleall/maple_be/src/cg/cgbb.cpp +++ b/src/mapleall/maple_be/src/cg/cgbb.cpp @@ -189,6 +189,9 @@ void BB::Dump() const { LogInfo::MapleLogger() << "=== BB " << this << " <" << GetKindName(); if (labIdx) { LogInfo::MapleLogger() << "[labeled with " << labIdx << "]"; + if (labelTaken) { + LogInfo::MapleLogger() << " taken"; + } } LogInfo::MapleLogger() << "> <" << id << "> "; if (isCleanup) { diff --git a/src/mapleall/maple_be/src/cg/cgfunc.cpp b/src/mapleall/maple_be/src/cg/cgfunc.cpp index f7302199b8a7b42381e3fa3ae5708c8bfe13d3c0..25244fe5c8428b8d4bb9fd355a98d223a24f4820 100644 --- a/src/mapleall/maple_be/src/cg/cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/cgfunc.cpp @@ -1119,6 +1119,7 @@ void CGFunc::HandleFunction() { } MarkCleanupEntryBB(); DetermineReturnTypeofCall(); + theCFG->MarkLabelTakenBB(); theCFG->UnreachCodeAnalysis(); SplitStrLdrPair(); if (CGOptions::IsLazyBinding() && !GetCG()->IsLibcore()) {