@@ -333,17 +333,17 @@ void ModuleToCfa::createAutomata()
333
333
loopGenInfo.addBlockToLocationsMapping (bb, entry, exit );
334
334
}
335
335
336
- // If the loop has multiple exits, add a selector output to disambiguate between these.
337
- llvm::SmallVector<llvm::BasicBlock* , 4 > exitBlocks ;
338
- loop->getUniqueExitBlocks (exitBlocks );
336
+ // Store which block was the exiting block inside the loop
337
+ llvm::SmallVector<llvm::Loop::Edge , 4 > exitEdges ;
338
+ loop->getExitEdges (exitEdges );
339
339
340
- if (exitBlocks .size () != 1 ) {
340
+ if (exitEdges .size () != 1 ) {
341
341
Type& selectorTy = getExitSelectorType (mSettings .ints , mContext );
342
342
loopGenInfo.ExitVariable = nested->createLocal (LoopOutputSelectorName, selectorTy);
343
343
nested->addOutput (loopGenInfo.ExitVariable );
344
- for (size_t i = 0 ; i < exitBlocks .size (); ++i) {
345
- LLVM_DEBUG (llvm::dbgs () << " Registering exit block " << exitBlocks [i]->getName () << " \n " );
346
- loopGenInfo.ExitBlocks [exitBlocks [i]] = selectorTy.isBvType ()
344
+ for (size_t i = 0 ; i < exitEdges .size (); ++i) {
345
+ LLVM_DEBUG (llvm::dbgs () << " Registering exit edge " << exitEdges [i]. first -> getName () << " --> " << exitEdges[i]. second ->getName () << " \n " );
346
+ loopGenInfo.ExitEdges [exitEdges [i]] = selectorTy.isBvType ()
347
347
? expr_cast<LiteralExpr>(mExprBuilder ->BvLit (i, 8 ))
348
348
: mExprBuilder ->IntLit (i);
349
349
}
@@ -736,15 +736,15 @@ bool BlocksToCfa::tryToEliminate(ValueOrMemoryObject val, Variable* variable, co
736
736
return true ;
737
737
}
738
738
739
- void BlocksToCfa::createExitTransition (const BasicBlock* target, Location* pred, const ExprPtr& succCondition)
739
+ void BlocksToCfa::createExitTransition (const BasicBlock* source, const BasicBlock* target, Location* pred, const ExprPtr& succCondition)
740
740
{
741
741
LLVM_DEBUG (llvm::dbgs () << " Building exit transition for block " << target->getName () << " \n " );
742
742
743
743
// If the target is outside of our region, create a simple edge to the exit.
744
744
std::vector<VariableAssignment> exitAssigns;
745
745
if (mGenInfo .ExitVariable != nullptr ) {
746
746
// If there are multiple exits, create an assignment to indicate which one to take.
747
- ExprPtr exitVal = mGenInfo .ExitBlocks [ target];
747
+ ExprPtr exitVal = mGenInfo .ExitEdges [{source, target} ];
748
748
assert (exitVal != nullptr && " An exit block must be present in the exit blocks map!" );
749
749
750
750
exitAssigns.emplace_back (mGenInfo .ExitVariable , exitVal);
@@ -759,13 +759,13 @@ void BlocksToCfa::createExitTransition(const BasicBlock* target, Location* pred,
759
759
mCfa ->createAssignTransition (pred, mCfa ->getExit (), succCondition, exitAssigns);
760
760
}
761
761
762
- ExprPtr BlocksToCfa::getExitCondition (const llvm::BasicBlock* target, Variable* exitSelector, CfaGenInfo& nestedInfo)
762
+ ExprPtr BlocksToCfa::getExitCondition (const llvm::BasicBlock* source, const llvm::BasicBlock* target, Variable* exitSelector, CfaGenInfo& nestedInfo)
763
763
{
764
764
if (nestedInfo.ExitVariable == nullptr ) {
765
765
return mExprBuilder .True ();
766
766
}
767
767
768
- ExprPtr exitVal = nestedInfo.ExitBlocks [ target];
768
+ ExprPtr exitVal = nestedInfo.ExitEdges [{source, target} ];
769
769
assert (exitVal != nullptr && " An exit block must be present in the exit blocks map!" );
770
770
771
771
return mExprBuilder .Eq (exitSelector->getRefExpr (), exitVal);
@@ -776,7 +776,7 @@ void BlocksToCfa::handleSuccessor(const BasicBlock* succ, const ExprPtr& succCon
776
776
{
777
777
LLVM_DEBUG (llvm::dbgs () << " Translating CFG edge " << parent->getName () << " " << succ->getName () << " \n " );
778
778
if (succ == mEntryBlock ) {
779
- // If the target is the loop header (entry block), create a call to this same automaton.
779
+ // If the target is the loop header (entry block), create a call to this same automaton.
780
780
auto loc = mCfa ->createLocation ();
781
781
mCfa ->createAssignTransition (exit , loc, succCondition);
782
782
@@ -821,7 +821,7 @@ void BlocksToCfa::handleSuccessor(const BasicBlock* succ, const ExprPtr& succCon
821
821
} else if (auto loop = getNestedLoopOf (mGenCtx , mGenInfo , succ)) {
822
822
this ->createCallToLoop (loop, parent, succ, succCondition, exit );
823
823
} else {
824
- createExitTransition (succ, exit , succCondition);
824
+ createExitTransition (parent, succ, exit , succCondition);
825
825
}
826
826
}
827
827
@@ -848,7 +848,7 @@ void BlocksToCfa::createCallToLoop(
848
848
}
849
849
}
850
850
851
- for (auto & [valueOrMemObj, variable] : nestedLoopInfo.Inputs ) {
851
+ for (auto & [valueOrMemObj, variable] : nestedLoopInfo.Inputs ) {
852
852
LLVM_DEBUG (llvm::dbgs () << " Translating loop input argument " << *variable << " " << valueOrMemObj << " \n " );
853
853
ExprPtr argExpr = operand (valueOrMemObj);
854
854
loopArgs.emplace_back (variable, argExpr);
@@ -889,11 +889,11 @@ void BlocksToCfa::createCallToLoop(
889
889
// simply create an assign transition to represent the exit jump.
890
890
mCfa ->createAssignTransition (
891
891
loc, result->second .first ,
892
- getExitCondition (exitBlock, exitSelector, nestedLoopInfo),
892
+ getExitCondition (inBlock, exitBlock, exitSelector, nestedLoopInfo),
893
893
phiAssignments
894
894
);
895
895
} else {
896
- createExitTransition (exitBlock, exit , condition);
896
+ createExitTransition (inBlock, exitBlock, exit , condition);
897
897
}
898
898
}
899
899
}
0 commit comments