@@ -69,6 +69,7 @@ typedef llvm::DenseSet<std::pair<GlobalVariable*, uint32_t> > NewAlignmentData;
6969namespace cheerp {
7070
7171const uint32_t MAX_NUMBER_OF_VISITS_PER_BB = 100u ;
72+ const uint32_t CHECK_STALE_FREQUENCY = 10u ;
7273
7374class FunctionData ;
7475class ModuleData ;
@@ -882,11 +883,13 @@ class FunctionData
882883 {
883884 }
884885 };
886+
885887 llvm::Function& F;
886888 std::vector<std::pair<llvm::BasicBlock*, llvm::BasicBlock*>> existingEdges;
887889 typedef std::vector<Value*> VectorOfArgs;
888890
889891 llvm::DenseMap<const llvm::BasicBlock*, int > visitCounter;
892+ llvm::DenseMap<const llvm::BasicBlock*, int > iterationsWithoutProgress;
890893 llvm::DenseSet<std::pair<const llvm::BasicBlock*, const llvm::BasicBlock*> > visitedEdges;
891894 llvm::DenseMap<llvm::Instruction*, KnownValue> knownValues;
892895 ModuleData& moduleData;
@@ -966,15 +969,30 @@ class FunctionData
966969 currentEE->addAlignmentRequirement (moduleData.alignmentToBeBumped );
967970
968971 }
972+
969973public:
970974 explicit FunctionData (llvm::Function& F, ModuleData& moduleData)
971975 : F(F), moduleData(moduleData), currentEE(nullptr )
972976 {
973977 }
978+ size_t countReplaceableInstructions () const
979+ {
980+ size_t count = 0 ;
981+ for (const auto & kv: knownValues) {
982+ if (!kv.second .everSkipped )
983+ count++;
984+ }
985+ return count;
986+ }
987+ size_t countVisitedEdges () const
988+ {
989+ return visitedEdges.size ();
990+ }
974991 llvm::Function* getFunction ()
975992 {
976993 return &F;
977994 }
995+
978996 uint32_t getVisitCounter (const llvm::BasicBlock* BB )
979997 {
980998 return visitCounter[BB ];
@@ -983,6 +1001,18 @@ class FunctionData
9831001 {
9841002 visitCounter[BB ]++;
9851003 }
1004+ uint32_t getIterationsWithoutProgress (const llvm::BasicBlock* BB )
1005+ {
1006+ return iterationsWithoutProgress[BB ];
1007+ }
1008+ void incrementIterationsWithoutProgress (const llvm::BasicBlock* BB )
1009+ {
1010+ iterationsWithoutProgress[BB ]++;
1011+ }
1012+ void resetIterationsWithoutProgress (const llvm::BasicBlock* BB )
1013+ {
1014+ iterationsWithoutProgress[BB ] = 0 ;
1015+ }
9861016 PartialInterpreter& getInterpreter ()
9871017 {
9881018 // currentEE will be non-null while visiting a Call Equivalent
@@ -1114,6 +1144,7 @@ class FunctionData
11141144 for (const FunctionData::VectorOfArgs& toBeVisited : callEquivalentQueue)
11151145 {
11161146 visitCounter.clear ();
1147+ iterationsWithoutProgress.clear ();
11171148 visitCallEquivalent (toBeVisited);
11181149 }
11191150 }
@@ -1373,6 +1404,8 @@ class BasicBlockGroupNode
13731404 llvm::BasicBlock* start;
13741405 llvm::BasicBlock* from;
13751406 uint32_t currIter;
1407+ size_t prevValues;
1408+ size_t prevEdges;
13761409 llvm::DenseMap<llvm::BasicBlock*, uint32_t > minVisitIndex;
13771410 // TODO(carlo): an optmization might be having from be a set<BasicBlock>, conserving the phi that are equals
13781411
@@ -1395,9 +1428,28 @@ class BasicBlockGroupNode
13951428 return set;
13961429 }
13971430 void splitIntoSCCs (std::list<BasicBlockGroupNode>& queueToBePopulated, ReverseMapBBToGroup& blockToGroupMap);
1431+
1432+ bool hasProgressed (size_t currValues, size_t currEdges)
1433+ {
1434+ if (currValues > prevValues || currEdges > prevEdges)
1435+ {
1436+ prevValues = currValues;
1437+ prevEdges = currEdges;
1438+ data.resetIterationsWithoutProgress (start);
1439+ return true ;
1440+ }
1441+ data.incrementIterationsWithoutProgress (start);
1442+ return false ;
1443+ }
1444+ bool hasStaled () const
1445+ {
1446+ return data.getIterationsWithoutProgress (start) >= CHECK_STALE_FREQUENCY ;
1447+ }
1448+
13981449public:
13991450 BasicBlockGroupNode (FunctionData& data, BasicBlockGroupNode* parentBBGNode, const DeterministicBBSet& OWNEDblocks, llvm::BasicBlock* start = nullptr )
1400- : parentNode(parentBBGNode), data(data), ownedBlocks(OWNEDblocks), blocks(ownedBlocks), isMultiHead(false ), isReachable(parentNode == nullptr ), start(start), from(nullptr ), visitingAll(false )
1451+ : parentNode(parentBBGNode), data(data), ownedBlocks(OWNEDblocks), blocks(ownedBlocks), isMultiHead(false ), isReachable(parentNode == nullptr ), start(start), from(nullptr ), visitingAll(false ),
1452+ prevValues (data.countReplaceableInstructions()), prevEdges(data.countVisitedEdges())
14011453 {
14021454 if (start)
14031455 assert (start->getParent () == data.getFunction ());
@@ -1407,9 +1459,11 @@ class BasicBlockGroupNode
14071459 {
14081460 }
14091461 BasicBlockGroupNode (BasicBlockGroupNode& BBGNode)
1410- : parentNode(&BBGNode), data(BBGNode.data), blocks(BBGNode.blocks), isMultiHead(false ), isReachable(false ), start(nullptr ), from(nullptr ), visitingAll(false )
1462+ : parentNode(&BBGNode), data(BBGNode.data), blocks(BBGNode.blocks), isMultiHead(false ), isReachable(false ), start(nullptr ), from(nullptr ), visitingAll(false ),
1463+ prevValues(data.countReplaceableInstructions()), prevEdges(data.countVisitedEdges())
14111464 {
14121465 }
1466+
14131467 void addIncomingEdge (llvm::BasicBlock* comingFrom, uint32_t currIter, llvm::BasicBlock* target)
14141468 {
14151469 isReachable = true ;
@@ -1550,15 +1604,31 @@ class BasicBlockGroupNode
15501604 }
15511605 }
15521606 data.incrementVisitCounter (start);
1553-
1607+
15541608 splitIntoSCCs (childrenNodes, reverseMappingBBToGroup); // These should be partially ordered with the last one possibly being the replica of the current one
1555-
1609+
15561610 llvm::SmallVector<llvm::BasicBlock*, 4 > visitNext;
1557-
1611+
15581612 // Do the actual visit for start, while populating visitNext
15591613 runVisitBasicBlock (data, *start, visitNext);
15601614 for (llvm::BasicBlock* succ : visitNext)
15611615 registerEdge (start, succ);
1616+
1617+
1618+ if (currIter > 0 )
1619+ {
1620+ size_t currentGlobalValues = data.countReplaceableInstructions ();
1621+ size_t currentGlobalEdges = data.countVisitedEdges ();
1622+
1623+ if (!hasProgressed (currentGlobalValues, currentGlobalEdges))
1624+ {
1625+ if (hasStaled ())
1626+ {
1627+ visitAll ();
1628+ return ;
1629+ }
1630+ }
1631+ }
15621632
15631633 // First has been already done
15641634 childrenNodes.pop_back ();
0 commit comments