@@ -68,12 +68,13 @@ typedef llvm::DenseSet<std::pair<GlobalVariable*, uint32_t> > NewAlignmentData;
6868
6969namespace cheerp {
7070
71- const uint32_t MAX_NUMBER_OF_VISITS_PER_BB = 100u ;
7271const uint32_t MAX_INSTRUCTIONS_PER_FUNCTION = 3000u ;
72+ const uint32_t MAX_INSTRUCTIONS_PER_SCC = 2300u ;
7373const uint32_t MAX_CALL_SITES = 100u ;
7474
7575class FunctionData ;
7676class ModuleData ;
77+ class BasicBlockGroupNode ;
7778
7879class PartialInterpreter : public llvm ::Interpreter {
7980 friend FunctionData;
@@ -303,7 +304,7 @@ class PartialInterpreter : public llvm::Interpreter {
303304 }
304305 return nullptr ;
305306 }
306- llvm::BasicBlock* visitBasicBlock (FunctionData& data, llvm::BasicBlock& BB, bool & BBProgress);
307+ llvm::BasicBlock* visitBasicBlock (FunctionData& data, BasicBlockGroupNode& BBGN, llvm::BasicBlock& BB, bool & BBProgress);
307308 explicit PartialInterpreter (std::unique_ptr<llvm::Module> M)
308309 : llvm::Interpreter(std::move(M), /* preExecute*/ false)
309310 {
@@ -632,7 +633,7 @@ class PartialInterpreter : public llvm::Interpreter {
632633 }
633634 return nullptr ;
634635 }
635- void visitOuter (FunctionData& data, llvm::Instruction& I, bool & BBProgress);
636+ void visitOuter (FunctionData& data, BasicBlockGroupNode& BBGN, llvm::Instruction& I, bool & BBProgress);
636637 bool replaceKnownCEs ()
637638 {
638639 if (fullyKnownCEs.empty ())
@@ -787,7 +788,7 @@ static void removeEdgeBetweenBlocks(llvm::BasicBlock* from, llvm::BasicBlock* to
787788 }
788789}
789790
790- llvm::BasicBlock* PartialInterpreter::visitBasicBlock (FunctionData& data, llvm::BasicBlock& BB, bool & BBProgress)
791+ llvm::BasicBlock* PartialInterpreter::visitBasicBlock (FunctionData& data, BasicBlockGroupNode& BBGN, llvm::BasicBlock& BB, bool & BBProgress)
791792{
792793 ExecutionContext& executionContext = getTopCallFrame ();
793794 executionContext.CurBB = &BB;
@@ -798,7 +799,7 @@ llvm::BasicBlock* PartialInterpreter::visitBasicBlock(FunctionData& data, llvm::
798799 // Note that here we could also execute a Call, and that implies adding a CallFrame
799800 // executing there (possibly also in depth)
800801 // So getTopCallFrame() has to be called since it will possibly change
801- visitOuter (data, *getTopCallFrame ().CurInst ++, BBProgress);
802+ visitOuter (data, BBGN, *getTopCallFrame ().CurInst ++, BBProgress);
802803 }
803804
804805 // Find (if there are enough information) the next BB to be visited
@@ -1402,6 +1403,7 @@ class BasicBlockGroupNode
14021403 llvm::BasicBlock* start;
14031404 llvm::BasicBlock* from;
14041405 uint32_t currIter;
1406+ uint32_t sccInstructionCounter;
14051407 llvm::DenseMap<llvm::BasicBlock*, uint32_t > minVisitIndex;
14061408 // TODO(carlo): an optmization might be having from be a set<BasicBlock>, conserving the phi that are equals
14071409
@@ -1426,7 +1428,7 @@ class BasicBlockGroupNode
14261428 void splitIntoSCCs (std::list<BasicBlockGroupNode>& queueToBePopulated, ReverseMapBBToGroup& blockToGroupMap);
14271429public:
14281430 BasicBlockGroupNode (FunctionData& data, BasicBlockGroupNode* parentBBGNode, const DeterministicBBSet& OWNEDblocks, llvm::BasicBlock* start = nullptr )
1429- : parentNode(parentBBGNode), data(data), ownedBlocks(OWNEDblocks), blocks(ownedBlocks), isMultiHead(false ), isReachable(parentNode == nullptr ), SCCProgress(false ), start(start), from(nullptr ), visitingAll(false )
1431+ : parentNode(parentBBGNode), data(data), ownedBlocks(OWNEDblocks), blocks(ownedBlocks), isMultiHead(false ), isReachable(parentNode == nullptr ), SCCProgress(false ), start(start), from(nullptr ), sccInstructionCounter( 0 ), visitingAll(false )
14301432 {
14311433 if (start)
14321434 assert (start->getParent () == data.getFunction ());
@@ -1436,7 +1438,7 @@ class BasicBlockGroupNode
14361438 {
14371439 }
14381440 BasicBlockGroupNode (BasicBlockGroupNode& BBGNode)
1439- : parentNode(&BBGNode), data(BBGNode.data), blocks(BBGNode.blocks), isMultiHead(false ), isReachable(false ), SCCProgress(false ), start(nullptr ), from(nullptr ), visitingAll(false )
1441+ : parentNode(&BBGNode), data(BBGNode.data), blocks(BBGNode.blocks), isMultiHead(false ), isReachable(false ), SCCProgress(false ), start(nullptr ), from(nullptr ), sccInstructionCounter( 0 ), visitingAll(false )
14401442 {
14411443 }
14421444 void addIncomingEdge (llvm::BasicBlock* comingFrom, uint32_t currIter, llvm::BasicBlock* target)
@@ -1473,7 +1475,7 @@ class BasicBlockGroupNode
14731475
14741476 PartialInterpreter& interpreter = data.getInterpreter ();
14751477 interpreter.incomingBB = from;
1476- BasicBlock* ret = interpreter.visitBasicBlock (data, BB, BBProgress);
1478+ BasicBlock* ret = interpreter.visitBasicBlock (data, * this , BB, BBProgress);
14771479
14781480 if (ret)
14791481 {
@@ -1551,6 +1553,28 @@ class BasicBlockGroupNode
15511553 interpreter.removeFromMaps (&I);
15521554 }
15531555 }
1556+ BasicBlockGroupNode* getParent ()
1557+ {
1558+ return parentNode;
1559+ }
1560+ void incrementSCCInstructionCounter ()
1561+ {
1562+ sccInstructionCounter++;
1563+ if (parentNode)
1564+ parentNode->incrementSCCInstructionCounter ();
1565+ }
1566+ uint32_t getSCCInstructionCounter ()
1567+ {
1568+ if (parentNode)
1569+ return parentNode->getSCCInstructionCounter ();
1570+ return sccInstructionCounter;
1571+ }
1572+ void resetSCCInstructionCounter ()
1573+ {
1574+ sccInstructionCounter = 0 ;
1575+ if (parentNode)
1576+ parentNode->resetSCCInstructionCounter ();
1577+ }
15541578 // Visit the tree of BasicBlockGroupNodes, starting from the root and visiting children depth-first
15551579 bool recursiveVisit ()
15561580 {
@@ -1562,23 +1586,22 @@ class BasicBlockGroupNode
15621586 return false ;
15631587 }
15641588
1589+ assert (start); // isReachable && !isMultiHead implies start being defined
1590+ currIter = data.getVisitCounter (start);
1591+
15651592 if (data.getFunctionInstructionCounter () >= MAX_INSTRUCTIONS_PER_FUNCTION)
15661593 {
15671594 visitAll ();
15681595 return false ;
15691596 }
15701597
1571- assert (start); // isReachable && !isMultiHead implies start being defined
1572- currIter = data.getVisitCounter (start);
1573-
1574- if (currIter >= MAX_NUMBER_OF_VISITS_PER_BB)
1598+ if (parentNode && parentNode->getSCCInstructionCounter () >= MAX_INSTRUCTIONS_PER_SCC)
15751599 {
1576- // We are visiting a given BasicBlock many times
1577- // Since terminability is basically unprovable in general, we give up with the visit
1578- // --> Mark everything as reachable
15791600 visitAll ();
1601+ resetSCCInstructionCounter ();
15801602 return false ;
15811603 }
1604+
15821605 if (parentNode)
15831606 {
15841607 for (auto & p : minVisitIndex)
@@ -1688,9 +1711,10 @@ void FunctionData::actualVisit()
16881711 groupData.recursiveVisit ();
16891712}
16901713
1691- void PartialInterpreter::visitOuter (FunctionData& data, llvm::Instruction& I, bool & BBProgress)
1714+ void PartialInterpreter::visitOuter (FunctionData& data, BasicBlockGroupNode& BBGN, llvm::Instruction& I, bool & BBProgress)
16921715{
16931716 data.incrementFunctionInstructionCounter ();
1717+ BBGN.incrementSCCInstructionCounter ();
16941718
16951719 if (PHINode* phi = dyn_cast<PHINode>(&I))
16961720 {
@@ -1770,7 +1794,7 @@ void PartialInterpreter::visitOuter(FunctionData& data, llvm::Instruction& I, bo
17701794 {
17711795 BasicBlock* next = findNextBasicBlock (I);
17721796
1773- if (next && data. getVisitCounter (next) < MAX_NUMBER_OF_VISITS_PER_BB )
1797+ if (next && BBGN. getParent () && BBGN. getParent ()-> getSCCInstructionCounter () < MAX_INSTRUCTIONS_PER_SCC )
17741798 {
17751799 data.incrementVisitCounter (next);
17761800
0 commit comments