From bf109fc8d5297242de30b629d189ad58f6b2b7da Mon Sep 17 00:00:00 2001 From: Mingwei Li Date: Sat, 22 Aug 2020 13:45:58 -0700 Subject: [PATCH] Add structural analysis by using given CFG and add _hasBackEdges flag when generating CFG This is a part of the BenefitInliner contribution. * Dominators.hpp, Dominators.cpp, StructuralAnalysis.hpp, StructuralAnalysis.cpp: add structural analysis by using given CFG. * OMRCfg.hpp: add _hasBackEdges flag to mark having loop in the CFG. Co-authored-by: Cijie Xia Signed-off-by: Mingwei Li --- compiler/infra/OMRCfg.hpp | 5 ++ compiler/optimizer/Dominators.cpp | 29 +++++++--- compiler/optimizer/Dominators.hpp | 6 ++ compiler/optimizer/StructuralAnalysis.cpp | 68 +++++++++-------------- compiler/optimizer/StructuralAnalysis.hpp | 3 + 5 files changed, 62 insertions(+), 49 deletions(-) diff --git a/compiler/infra/OMRCfg.hpp b/compiler/infra/OMRCfg.hpp index 79dde53dddb..7b70ee333fb 100644 --- a/compiler/infra/OMRCfg.hpp +++ b/compiler/infra/OMRCfg.hpp @@ -136,6 +136,7 @@ class CFG _calledFrequency = 0; _initialBlockFrequency = -1; _edgeProbabilities = NULL; + _hasBackEdges = false; } TR::CFG * self(); @@ -357,6 +358,9 @@ class CFG IsOrphanedRegion }; + void setHasBackEdges() { _hasBackEdges = true; } + bool hasBackEdges() { return _hasBackEdges; } + protected: TR::Compilation *_compilation; TR::ResolvedMethodSymbol *_method; @@ -376,6 +380,7 @@ class CFG bool _ignoreUnreachableBlocks; bool _removingUnreachableBlocks; + bool _hasBackEdges; TR::CFGNode **_forwardTraversalOrder; int32_t _forwardTraversalLength; diff --git a/compiler/optimizer/Dominators.cpp b/compiler/optimizer/Dominators.cpp index fa307bef1eb..fdc26871e65 100644 --- a/compiler/optimizer/Dominators.cpp +++ b/compiler/optimizer/Dominators.cpp @@ -44,18 +44,32 @@ TR_Dominators::TR_Dominators(TR::Compilation *c, bool post) : _info(c->getFlowGraph()->getNextNodeNumber()+1, BBInfo(_region), _region), _dfNumbers(c->getFlowGraph()->getNextNodeNumber()+1, 0, _region), _dominators(c->getFlowGraph()->getNextNodeNumber()+1, static_cast(NULL), _region) + { + construct(c->getFlowGraph(), post); + } + +TR_Dominators::TR_Dominators(TR::Compilation *c, TR::CFG* cfg, bool post) : + _region(c->trMemory()->heapMemoryRegion()), + _compilation(c), + _info(cfg->getNextNodeNumber()+1, BBInfo(_region), _region), + _dfNumbers(cfg->getNextNodeNumber()+1, 0, _region), + _dominators(cfg->getNextNodeNumber()+1, static_cast(NULL), _region) + { + construct(cfg, post); + } + +void TR_Dominators::construct(TR::CFG* cfg, bool post) { LexicalTimer tlex("TR_Dominators::TR_Dominators", _compilation->phaseTimer()); _postDominators = post; _isValid = true; + _hasUnreachableBlocks = false; _topDfNum = 0; - _visitCount = c->incOrResetVisitCount(); + _visitCount = _compilation->incOrResetVisitCount(); _trace = comp()->getOption(TR_TraceDominators); - TR::CFG *cfg = c->getFlowGraph(); - - _cfg = c->getFlowGraph(); + _cfg = cfg; _numNodes = cfg->getNumberOfNodes()+1; if (trace()) @@ -80,7 +94,7 @@ TR_Dominators::TR_Dominators(TR::Compilation *c, bool post) : _dominators[dominated->getNumber()] = dominator; if (trace()) traceMsg(comp(), " %sDominator of block_%d is block_%d\n", _postDominators ? "post-" : "", - dominated->getNumber(), dominator->getNumber()); + dominated->getNumber(), dominator->getNumber()); } // The exit block may not be reachable from the entry node. In this case just @@ -111,14 +125,15 @@ TR_Dominators::TR_Dominators(TR::Compilation *c, bool post) : return; } else + _hasUnreachableBlocks = true; TR_ASSERT(false, "Unreachable block in the CFG %d %d", _topDfNum, _numNodes-1); } #if DEBUG for (auto block = toBlock(cfg->getFirstNode()); block; block = toBlock(block->getNext())) - { + { TR_ASSERT(_dfNumbers[block->getNumber()] >= 0, "Unreachable block in the CFG"); - } + } #endif if (trace()) diff --git a/compiler/optimizer/Dominators.hpp b/compiler/optimizer/Dominators.hpp index 5696d5b08f6..d0504e33d54 100644 --- a/compiler/optimizer/Dominators.hpp +++ b/compiler/optimizer/Dominators.hpp @@ -53,11 +53,14 @@ class TR_Dominators TR_ALLOC(TR_Memory::Dominators) TR_Dominators(TR::Compilation *, bool post = false); + TR_Dominators(TR::Compilation *, TR::CFG* cfg, bool post = false); TR::Block *getDominator(TR::Block *); int dominates(TR::Block *block, TR::Block *other); TR::Compilation * comp() { return _compilation; } bool trace() { return _trace; } + bool isValid() { return _isValid; } + bool hasUnreachableBlocks() { return _hasUnreachableBlocks; } protected: @@ -113,6 +116,8 @@ class TR_Dominators int32_t parent; }; + void construct(TR::CFG* cfg, bool post); + BBInfo& getInfo(int32_t index) {return _info[index];} int32_t blockNumber(int32_t index) {return _info[index]._block->getNumber();} @@ -133,6 +138,7 @@ class TR_Dominators int32_t _numNodes; int32_t _topDfNum; vcount_t _visitCount; + bool _hasUnreachableBlocks; protected: TR::CFG * _cfg; diff --git a/compiler/optimizer/StructuralAnalysis.cpp b/compiler/optimizer/StructuralAnalysis.cpp index 24da1f7d575..ebd6be73615 100644 --- a/compiler/optimizer/StructuralAnalysis.cpp +++ b/compiler/optimizer/StructuralAnalysis.cpp @@ -171,23 +171,17 @@ void TR_RegionAnalysis::createLeafStructures(TR::CFG *cfg, TR::Region ®ion) /** * Mainline for performing Region Analysis. */ -TR_Structure *TR_RegionAnalysis::getRegions(TR::Compilation *comp, TR::ResolvedMethodSymbol* methSym) +TR_Structure *TR_RegionAnalysis::getRegionsImpl(TR::Compilation *comp, TR_Dominators& dominators, TR::CFG* cfg) { TR::StackMemoryRegion stackMemoryRegion(*comp->trMemory()); - // Calculate dominators - // This has the side-effect of renumbering the blocks in depth-first order - // - TR_Dominators dominators = TR_Dominators(comp); - #if DEBUG if (debug("verifyDominator")) - { + { TR_DominatorVerifier verifyDominator(dominators); - } + } #endif - TR::CFG *cfg = methSym->getFlowGraph(); TR_ASSERT(cfg, "cfg is NULL\n"); TR_RegionAnalysis ra(comp, dominators, cfg, stackMemoryRegion); @@ -195,10 +189,10 @@ TR_Structure *TR_RegionAnalysis::getRegions(TR::Compilation *comp, TR::ResolvedM ra._useNew = !comp->getOption(TR_DisableIterativeSA); if (ra.trace()) - { + { traceMsg(comp, "Blocks before Region Analysis:\n"); comp->getDebug()->print(comp->getOutFile(), cfg); - } + } ra.createLeafStructures(cfg, stackMemoryRegion); @@ -210,48 +204,38 @@ TR_Structure *TR_RegionAnalysis::getRegions(TR::Compilation *comp, TR::ResolvedM return result; } +TR_Structure *TR_RegionAnalysis::getRegions(TR::Compilation *comp, TR::CFG* cfg, bool acceptUnreachableBlocks) + { + // Calculate dominators + // This has the side-effect of renumbering the blocks in depth-first order + // + TR_Dominators dominators(comp, cfg); + if (!acceptUnreachableBlocks and dominators.hasUnreachableBlocks()) + return NULL; + return getRegionsImpl(comp, dominators, cfg); + } - -/** - * Mainline for performing Region Analysis. - */ -TR_Structure *TR_RegionAnalysis::getRegions(TR::Compilation *comp) +TR_Structure *TR_RegionAnalysis::getRegions(TR::Compilation *comp, TR::ResolvedMethodSymbol* methSym) { - TR::StackMemoryRegion stackMemoryRegion(*comp->trMemory()); - // Calculate dominators // This has the side-effect of renumbering the blocks in depth-first order // TR_Dominators dominators(comp); + TR::CFG *cfg = methSym->getFlowGraph(); - #if DEBUG - if (debug("verifyDominator")) - { - TR_DominatorVerifier verifyDominator(dominators); - } - #endif - - TR::CFG *cfg = comp->getFlowGraph(); - - TR_RegionAnalysis ra(comp, dominators, cfg, stackMemoryRegion); - ra._trace = comp->getOption(TR_TraceSA); - - ra._useNew = !comp->getOption(TR_DisableIterativeSA); - if (ra.trace()) - { - traceMsg(comp, "Blocks before Region Analysis:\n"); - comp->getDebug()->print(comp->getOutFile(), cfg); - } - - ra.createLeafStructures(cfg, stackMemoryRegion); + return getRegionsImpl(comp, dominators, cfg); + } - // Loop through the node set until there is only one node left - this is the - // root of the control tree. +TR_Structure *TR_RegionAnalysis::getRegions(TR::Compilation *comp) + { + // Calculate dominators + // This has the side-effect of renumbering the blocks in depth-first order // - TR_Structure *result = ra.findRegions(stackMemoryRegion); + TR_Dominators dominators(comp); + TR::CFG *cfg = comp->getFlowGraph(); - return result; + return getRegionsImpl(comp, dominators, cfg); } /** diff --git a/compiler/optimizer/StructuralAnalysis.hpp b/compiler/optimizer/StructuralAnalysis.hpp index 458e13e9312..bbb1f523d7a 100644 --- a/compiler/optimizer/StructuralAnalysis.hpp +++ b/compiler/optimizer/StructuralAnalysis.hpp @@ -52,6 +52,7 @@ class TR_RegionAnalysis static TR_Structure *getRegions(TR::Compilation *); static TR_Structure *getRegions(TR::Compilation *, TR::ResolvedMethodSymbol *); + static TR_Structure *getRegions(TR::Compilation *, TR::CFG *, bool acceptUnreachableBlocks = true); friend class TR_Debug; @@ -122,6 +123,8 @@ class TR_RegionAnalysis bool _useNew; void createLeafStructures(TR::CFG *cfg, TR::Region ®ion); + static TR_Structure *getRegionsImpl(TR::Compilation *comp, TR_Dominators& dominators, TR::CFG* cfg); + TR_Structure *findRegions(TR::Region ®ion); TR_RegionStructure *findNaturalLoop(StructInfo &node, WorkBitVector ®ionNodes,