diff --git a/src/mapleall/maple_ipa/src/ipa_escape_analysis.cpp b/src/mapleall/maple_ipa/src/ipa_escape_analysis.cpp index 4496628398dc4e550b9a541d88af64670d4dcea0..94482fb10d0a2de5c13175501c9b3d567f071130 100644 --- a/src/mapleall/maple_ipa/src/ipa_escape_analysis.cpp +++ b/src/mapleall/maple_ipa/src/ipa_escape_analysis.cpp @@ -1145,13 +1145,14 @@ void IPAEscapeAnalysis::HandleParaAtFuncEntry() { void IPAEscapeAnalysis::ConstructConnGraph() { HandleParaAtFuncEntry(); - func->BuildSCC(); - const MapleVector &sccTopologicalVec = func->GetSccTopologicalVec(); + auto cfg = func->GetCfg(); + cfg->BuildSCC(); + const MapleVector &sccTopologicalVec = cfg->GetSccTopologicalVec(); for (size_t i = 0; i < sccTopologicalVec.size(); ++i) { SCCOfBBs *scc = sccTopologicalVec[i]; CHECK_FATAL(scc != nullptr, "nullptr check"); if (scc->GetBBs().size() > 1) { - func->BBTopologicalSort(*scc); + cfg->BBTopologicalSort(*scc); } cgChangedInSCC = true; bool analyzeAgain = true; @@ -1159,7 +1160,7 @@ void IPAEscapeAnalysis::ConstructConnGraph() { analyzeAgain = false; cgChangedInSCC = false; for (BB *bb : scc->GetBBs()) { - if (bb == func->GetCfg()->GetCommonEntryBB() || bb == func->GetCfg()->GetCommonExitBB()) { + if (bb == cfg->GetCommonEntryBB() || bb == cfg->GetCommonExitBB()) { continue; } UpdateEscConnGraphWithPhi(*bb); diff --git a/src/mapleall/maple_me/include/me_cfg.h b/src/mapleall/maple_me/include/me_cfg.h index b48f723257f9d95635f2e6e944ffcf27b2a48053..df8bb113cbf7508a5a7eafb5395c6b79104f276f 100644 --- a/src/mapleall/maple_me/include/me_cfg.h +++ b/src/mapleall/maple_me/include/me_cfg.h @@ -42,7 +42,10 @@ class MeCFG : public AnalysisResult { bbVec(mecfgAlloc.Adapter()), labelBBIdMap(mecfgAlloc.Adapter()), bbTryNodeMap(mecfgAlloc.Adapter()), - endTryBB2TryBB(mecfgAlloc.Adapter()) {} + endTryBB2TryBB(mecfgAlloc.Adapter()), + sccTopologicalVec(mecfgAlloc.Adapter()), + sccOfBB(mecfgAlloc.Adapter()), + backEdges(mecfgAlloc.Adapter()) {} ~MeCFG() = default; @@ -266,6 +269,12 @@ class MeCFG : public AnalysisResult { MemPool * GetMempool() const { return mp; } void CreateBasicBlocks(); + const MapleVector &GetSccTopologicalVec() const { + return sccTopologicalVec; + } + void BBTopologicalSort(SCCOfBBs &scc); + void BuildSCC(); + private: void ReplaceSwitchContainsOneCaseBranchWithBrtrue(BB &bb, MapleVector &exitBlocks); void AddCatchHandlerForTryBB(BB &bb, MapleVector &exitBlocks); @@ -277,6 +286,11 @@ class MeCFG : public AnalysisResult { void FixTryBB(BB &startBB, BB &nextBB); void SetTryBlockInfo(const StmtNode *nextStmt, StmtNode *tryStmt, BB *lastTryBB, BB *curBB, BB *newBB); + void VerifySCC(); + void SCCTopologicalSort(std::vector &sccNodes); + void BuildSCCDFS(BB &bb, uint32 &visitIndex, std::vector &sccNodes, std::vector &visitedOrder, + std::vector &lowestOrder, std::vector &inStack, std::stack &visitStack); + MemPool *mp; MapleAllocator mecfgAlloc; MeFunction &func; @@ -287,6 +301,12 @@ class MeCFG : public AnalysisResult { MapleUnorderedMap endTryBB2TryBB; // maps endtry bb to its try bb bool hasDoWhile = false; uint32 nextBBId = 0; + + // BB SCC + MapleVector sccTopologicalVec; + uint32 numOfSCCs = 0; + MapleVector sccOfBB; + MapleSet> backEdges; }; class MeDoMeCfg : public MeFuncPhase { diff --git a/src/mapleall/maple_me/include/me_function.h b/src/mapleall/maple_me/include/me_function.h index f0eb0d08fa28ed8ec34cffcfe589478d52fec7c4..ab38ee0cd13168d1de1add7a0b635c6e24ca9a7f 100644 --- a/src/mapleall/maple_me/include/me_function.h +++ b/src/mapleall/maple_me/include/me_function.h @@ -156,9 +156,6 @@ class MeFunction : public FuncEmit { mirModule(*mod), mirFunc(func), laidOutBBVec(alloc.Adapter()), - sccTopologicalVec(alloc.Adapter()), - sccOfBB(alloc.Adapter()), - backEdges(alloc.Adapter()), fileName(fileName, memPool) {} ~MeFunction() override = default; @@ -311,20 +308,10 @@ class MeFunction : public FuncEmit { void PartialInit(); - const MapleVector &GetSccTopologicalVec() const { - return sccTopologicalVec; - } - void BBTopologicalSort(SCCOfBBs &scc); - void BuildSCC(); MIRFunction *CurFunction() const { return mirModule.CurFunction(); } private: - void VerifySCC(); - void SCCTopologicalSort(std::vector &sccNodes); - void BuildSCCDFS(BB &bb, uint32 &visitIndex, std::vector &sccNodes, std::vector &visitedOrder, - std::vector &lowestOrder, std::vector &inStack, std::stack &visitStack); - MemPool *memPool; StackMemPool &stackMP; MapleAllocator alloc; @@ -337,11 +324,6 @@ class MeFunction : public FuncEmit { MeCFG *theCFG = nullptr; SSATab *meSSATab = nullptr; MeIRMap *irmap = nullptr; - // BB SCC - MapleVector sccTopologicalVec; - uint32 numOfSCCs = 0; - MapleVector sccOfBB; - MapleSet> backEdges; /* input */ MapleString fileName; uint32 regNum = 0; // count virtual registers diff --git a/src/mapleall/maple_me/src/ipa_side_effect.cpp b/src/mapleall/maple_me/src/ipa_side_effect.cpp index bf976c238c12d9abb71a501aa16731999daec221..e6d14f8c7c4e14b1bad90721c71cd26fd3029b05 100644 --- a/src/mapleall/maple_me/src/ipa_side_effect.cpp +++ b/src/mapleall/maple_me/src/ipa_side_effect.cpp @@ -1026,17 +1026,17 @@ void IpaSideEffect::DoAnalysis() { if (func->GetBody() == nullptr) { // External function from mplt, need to update effects UpdateExternalFuncSideEffects(*func); } else { - meFunc.BuildSCC(); + auto cfg = meFunc.GetCfg(); + cfg->BuildSCC(); std::set globalExprs; std::set argExprs; std::set nextLevelGlobalExprs; std::set nextLevelArgExprs; - auto cfg = meFunc.GetCfg(); - for (size_t i = 0; i < meFunc.GetSccTopologicalVec().size(); ++i) { - SCCOfBBs *scc = meFunc.GetSccTopologicalVec()[i]; + for (size_t i = 0; i < cfg->GetSccTopologicalVec().size(); ++i) { + SCCOfBBs *scc = cfg->GetSccTopologicalVec()[i]; CHECK_FATAL(scc != nullptr, "scc must not be null"); if (scc->GetBBs().size() > 1) { - meFunc.BBTopologicalSort(*scc); + cfg->BBTopologicalSort(*scc); } const uint32 maxLoopCount = 2; unsigned loopCount = scc->GetBBs().size() > 1 ? maxLoopCount : 1; // Loop count diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index 4ec7d5c8ddb50d29eb7166633d86361ea344a4c9..f14a87ba61bb54a7c137bc22b5df13ca995abd8b 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -1537,6 +1537,160 @@ void MeCFG::CreateBasicBlocks() { } } +void MeCFG::BBTopologicalSort(SCCOfBBs &scc) { + std::set inQueue; + std::vector bbs; + for (BB *bb : scc.GetBBs()) { + bbs.push_back(bb); + } + scc.Clear(); + scc.AddBBNode(scc.GetEntry()); + (void)inQueue.insert(scc.GetEntry()); + + for (size_t i = 0; i < scc.GetBBs().size(); ++i) { + BB *bb = scc.GetBBs()[i]; + for (BB *succ : bb->GetSucc()) { + if (succ == nullptr) { + continue; + } + if (inQueue.find(succ) != inQueue.end() || + std::find(bbs.begin(), bbs.end(), succ) == bbs.end()) { + continue; + } + bool predAllVisited = true; + for (BB *pred : succ->GetPred()) { + if (pred == nullptr) { + continue; + } + if (std::find(bbs.begin(), bbs.end(), pred) == bbs.end()) { + continue; + } + if (backEdges.find(std::pair(pred->UintID(), succ->UintID())) != backEdges.end()) { + continue; + } + if (inQueue.find(pred) == inQueue.end()) { + predAllVisited = false; + break; + } + } + if (predAllVisited) { + scc.AddBBNode(succ); + (void)inQueue.insert(succ); + } + } + } +} + +void MeCFG::BuildSCCDFS(BB &bb, uint32 &visitIndex, std::vector &sccNodes, + std::vector &visitedOrder, std::vector &lowestOrder, + std::vector &inStack, std::stack &visitStack) { + uint32 id = bb.UintID(); + visitedOrder[id] = visitIndex; + lowestOrder[id] = visitIndex; + ++visitIndex; + visitStack.push(id); + inStack[id] = true; + + for (BB *succ : bb.GetSucc()){ + if (succ == nullptr) { + continue; + } + uint32 succId = succ->UintID(); + if (!visitedOrder[succId]) { + BuildSCCDFS(*succ, visitIndex, sccNodes, visitedOrder, lowestOrder, inStack, visitStack); + if (lowestOrder[succId] < lowestOrder[id]) { + lowestOrder[id] = lowestOrder[succId]; + } + } else if (inStack[succId]) { + backEdges.insert(std::pair(id, succId)); + if (visitedOrder[succId] < lowestOrder[id]) { + lowestOrder[id] = visitedOrder[succId]; + } + } + } + + if (visitedOrder.at(id) == lowestOrder.at(id)) { + auto *sccNode = GetAlloc().GetMemPool()->New(numOfSCCs++, &bb, &GetAlloc()); + uint32 stackTopId; + do { + stackTopId = visitStack.top(); + visitStack.pop(); + inStack[stackTopId] = false; + auto *topBB = static_cast(GetAllBBs()[stackTopId]); + sccNode->AddBBNode(topBB); + sccOfBB[stackTopId] = sccNode; + } while (stackTopId != id); + + sccNodes.push_back(sccNode); + } +} + +void MeCFG::VerifySCC() { + for (BB *bb : GetAllBBs()) { + if (bb == nullptr || bb == GetCommonExitBB()) { + continue; + } + SCCOfBBs *scc = sccOfBB.at(bb->UintID()); + CHECK_FATAL(scc != nullptr, "bb should belong to a scc"); + } +} + +void MeCFG::SCCTopologicalSort(std::vector &sccNodes) { + std::set inQueue; + for (SCCOfBBs *node : sccNodes) { + if (!node->HasPred()) { + sccTopologicalVec.push_back(node); + (void)inQueue.insert(node); + } + } + + // Top-down iterates all nodes + for (size_t i = 0; i < sccTopologicalVec.size(); ++i) { + SCCOfBBs *sccBB = sccTopologicalVec[i]; + for (SCCOfBBs *succ : sccBB->GetSucc()) { + if (inQueue.find(succ) == inQueue.end()) { + // successor has not been visited + bool predAllVisited = true; + // check whether all predecessors of the current successor have been visited + for (SCCOfBBs *pred : succ->GetPred()) { + if (inQueue.find(pred) == inQueue.end()) { + predAllVisited = false; + break; + } + } + if (predAllVisited) { + sccTopologicalVec.push_back(succ); + (void)inQueue.insert(succ); + } + } + } + } +} + +void MeCFG::BuildSCC() { + uint32_t n = GetAllBBs().size(); + sccTopologicalVec.clear(); + sccOfBB.clear(); + sccOfBB.assign(n, nullptr); + std::vector visitedOrder(n, 0); + std::vector lowestOrder(n, 0); + std::vector inStack(n, false); + std::vector sccNodes; + uint32 visitIndex = 1; + std::stack visitStack; + + // Starting from common entry bb for DFS + BuildSCCDFS(*GetCommonEntryBB(), visitIndex, sccNodes, visitedOrder, lowestOrder, inStack, visitStack); + + for (SCCOfBBs *scc : sccNodes) { + scc->Verify(sccOfBB); + scc->SetUp(sccOfBB); + } + + VerifySCC(); + SCCTopologicalSort(sccNodes); +} + AnalysisResult *MeDoMeCfg::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResultMgr *mrm) { MemPool *meCfgMp = NewMemPool(); MeCFG *theCFG = meCfgMp->New(meCfgMp, *func); diff --git a/src/mapleall/maple_me/src/me_function.cpp b/src/mapleall/maple_me/src/me_function.cpp index da437a9a468187f74b00a194aec7c42f0107db29..7676ce76188b4cf3023c0328e6f130f25952f04e 100644 --- a/src/mapleall/maple_me/src/me_function.cpp +++ b/src/mapleall/maple_me/src/me_function.cpp @@ -156,158 +156,4 @@ LabelIdx MeFunction::GetOrCreateBBLabel(BB &bb) { theCFG->SetLabelBBAt(label, &bb); return label; } - -void MeFunction::BuildSCCDFS(BB &bb, uint32 &visitIndex, std::vector &sccNodes, - std::vector &visitedOrder, std::vector &lowestOrder, - std::vector &inStack, std::stack &visitStack) { - uint32 id = bb.UintID(); - visitedOrder[id] = visitIndex; - lowestOrder[id] = visitIndex; - ++visitIndex; - visitStack.push(id); - inStack[id] = true; - - for (BB *succ : bb.GetSucc()){ - if (succ == nullptr) { - continue; - } - uint32 succId = succ->UintID(); - if (!visitedOrder[succId]) { - BuildSCCDFS(*succ, visitIndex, sccNodes, visitedOrder, lowestOrder, inStack, visitStack); - if (lowestOrder[succId] < lowestOrder[id]) { - lowestOrder[id] = lowestOrder[succId]; - } - } else if (inStack[succId]) { - backEdges.insert(std::pair(id, succId)); - if (visitedOrder[succId] < lowestOrder[id]) { - lowestOrder[id] = visitedOrder[succId]; - } - } - } - - if (visitedOrder.at(id) == lowestOrder.at(id)) { - auto *sccNode = alloc.GetMemPool()->New(numOfSCCs++, &bb, &alloc); - uint32 stackTopId; - do { - stackTopId = visitStack.top(); - visitStack.pop(); - inStack[stackTopId] = false; - auto *topBB = static_cast(theCFG->GetAllBBs()[stackTopId]); - sccNode->AddBBNode(topBB); - sccOfBB[stackTopId] = sccNode; - } while (stackTopId != id); - - sccNodes.push_back(sccNode); - } -} - -void MeFunction::VerifySCC() { - for (BB *bb : theCFG->GetAllBBs()) { - if (bb == nullptr || bb == theCFG->GetCommonExitBB()) { - continue; - } - SCCOfBBs *scc = sccOfBB.at(bb->UintID()); - CHECK_FATAL(scc != nullptr, "bb should belong to a scc"); - } -} - -void MeFunction::BuildSCC() { - uint32_t n = theCFG->GetAllBBs().size(); - sccTopologicalVec.clear(); - sccOfBB.clear(); - sccOfBB.assign(n, nullptr); - std::vector visitedOrder(n, 0); - std::vector lowestOrder(n, 0); - std::vector inStack(n, false); - std::vector sccNodes; - uint32 visitIndex = 1; - std::stack visitStack; - - // Starting from common entry bb for DFS - BuildSCCDFS(*theCFG->GetCommonEntryBB(), visitIndex, sccNodes, visitedOrder, lowestOrder, inStack, visitStack); - - for (SCCOfBBs *scc : sccNodes) { - scc->Verify(sccOfBB); - scc->SetUp(sccOfBB); - } - - VerifySCC(); - SCCTopologicalSort(sccNodes); -} - -void MeFunction::SCCTopologicalSort(std::vector &sccNodes) { - std::set inQueue; - for (SCCOfBBs *node : sccNodes) { - if (!node->HasPred()) { - sccTopologicalVec.push_back(node); - (void)inQueue.insert(node); - } - } - - // Top-down iterates all nodes - for (size_t i = 0; i < sccTopologicalVec.size(); ++i) { - SCCOfBBs *sccBB = sccTopologicalVec[i]; - for (SCCOfBBs *succ : sccBB->GetSucc()) { - if (inQueue.find(succ) == inQueue.end()) { - // successor has not been visited - bool predAllVisited = true; - // check whether all predecessors of the current successor have been visited - for (SCCOfBBs *pred : succ->GetPred()) { - if (inQueue.find(pred) == inQueue.end()) { - predAllVisited = false; - break; - } - } - if (predAllVisited) { - sccTopologicalVec.push_back(succ); - (void)inQueue.insert(succ); - } - } - } - } -} - -void MeFunction::BBTopologicalSort(SCCOfBBs &scc) { - std::set inQueue; - std::vector bbs; - for (BB *bb : scc.GetBBs()) { - bbs.push_back(bb); - } - scc.Clear(); - scc.AddBBNode(scc.GetEntry()); - (void)inQueue.insert(scc.GetEntry()); - - for (size_t i = 0; i < scc.GetBBs().size(); ++i) { - BB *bb = scc.GetBBs()[i]; - for (BB *succ : bb->GetSucc()) { - if (succ == nullptr) { - continue; - } - if (inQueue.find(succ) != inQueue.end() || - std::find(bbs.begin(), bbs.end(), succ) == bbs.end()) { - continue; - } - bool predAllVisited = true; - for (BB *pred : succ->GetPred()) { - if (pred == nullptr) { - continue; - } - if (std::find(bbs.begin(), bbs.end(), pred) == bbs.end()) { - continue; - } - if (backEdges.find(std::pair(pred->UintID(), succ->UintID())) != backEdges.end()) { - continue; - } - if (inQueue.find(pred) == inQueue.end()) { - predAllVisited = false; - break; - } - } - if (predAllVisited) { - scc.AddBBNode(succ); - (void)inQueue.insert(succ); - } - } - } -} } // namespace maple