R600/SI: SI Control Flow Annotation bug fixed

Mixing of AddAvailableValue and GetValueAtEndOfBlock methods of SSAUpdater
leaded to the endless loop generation when the nested loops annotated.

This fixes a bug in the OCL_ML/KNN OpenCV test.  The test case is too
complex for FileCheck and would be very fragile.

Patch by: Elena Denisova

llvm-svn: 211374
This commit is contained in:
Tom Stellard 2014-06-20 17:06:02 +00:00
parent c9dedb8e29
commit de16a2e59f
1 changed files with 21 additions and 25 deletions

View File

@ -65,7 +65,6 @@ class SIAnnotateControlFlow : public FunctionPass {
DominatorTree *DT;
StackVector Stack;
SSAUpdater PhiInserter;
bool isTopOfStack(BasicBlock *BB);
@ -81,7 +80,7 @@ class SIAnnotateControlFlow : public FunctionPass {
void insertElse(BranchInst *Term);
void handleLoopCondition(Value *Cond);
Value *handleLoopCondition(Value *Cond, PHINode *Broken);
void handleLoop(BranchInst *Term);
@ -177,7 +176,7 @@ bool SIAnnotateControlFlow::isElse(PHINode *Phi) {
} else {
if (Phi->getIncomingValue(i) != BoolFalse)
return false;
}
}
return true;
@ -204,20 +203,26 @@ void SIAnnotateControlFlow::insertElse(BranchInst *Term) {
}
/// \brief Recursively handle the condition leading to a loop
void SIAnnotateControlFlow::handleLoopCondition(Value *Cond) {
Value *SIAnnotateControlFlow::handleLoopCondition(Value *Cond, PHINode *Broken) {
if (PHINode *Phi = dyn_cast<PHINode>(Cond)) {
BasicBlock *Parent = Phi->getParent();
PHINode *NewPhi = PHINode::Create(Int64, 0, "", &Parent->front());
Value *Ret = NewPhi;
// Handle all non-constant incoming values first
for (unsigned i = 0, e = Phi->getNumIncomingValues(); i != e; ++i) {
Value *Incoming = Phi->getIncomingValue(i);
if (isa<ConstantInt>(Incoming))
BasicBlock *From = Phi->getIncomingBlock(i);
if (isa<ConstantInt>(Incoming)) {
NewPhi->addIncoming(Broken, From);
continue;
}
Phi->setIncomingValue(i, BoolFalse);
handleLoopCondition(Incoming);
Value *PhiArg = handleLoopCondition(Incoming, Broken);
NewPhi->addIncoming(PhiArg, From);
}
BasicBlock *Parent = Phi->getParent();
BasicBlock *IDom = DT->getNode(Parent)->getIDom()->getBlock();
for (unsigned i = 0, e = Phi->getNumIncomingValues(); i != e; ++i) {
@ -230,33 +235,28 @@ void SIAnnotateControlFlow::handleLoopCondition(Value *Cond) {
if (From == IDom) {
CallInst *OldEnd = dyn_cast<CallInst>(Parent->getFirstInsertionPt());
if (OldEnd && OldEnd->getCalledFunction() == EndCf) {
Value *Args[] = {
OldEnd->getArgOperand(0),
PhiInserter.GetValueAtEndOfBlock(Parent)
};
Value *Ret = CallInst::Create(ElseBreak, Args, "", OldEnd);
PhiInserter.AddAvailableValue(Parent, Ret);
Value *Args[] = { OldEnd->getArgOperand(0), NewPhi };
Ret = CallInst::Create(ElseBreak, Args, "", OldEnd);
continue;
}
}
TerminatorInst *Insert = From->getTerminator();
Value *Arg = PhiInserter.GetValueAtEndOfBlock(From);
Value *Ret = CallInst::Create(Break, Arg, "", Insert);
PhiInserter.AddAvailableValue(From, Ret);
Value *PhiArg = CallInst::Create(Break, Broken, "", Insert);
NewPhi->setIncomingValue(i, PhiArg);
}
eraseIfUnused(Phi);
return Ret;
} else if (Instruction *Inst = dyn_cast<Instruction>(Cond)) {
BasicBlock *Parent = Inst->getParent();
TerminatorInst *Insert = Parent->getTerminator();
Value *Args[] = { Cond, PhiInserter.GetValueAtEndOfBlock(Parent) };
Value *Ret = CallInst::Create(IfBreak, Args, "", Insert);
PhiInserter.AddAvailableValue(Parent, Ret);
Value *Args[] = { Cond, Broken };
return CallInst::Create(IfBreak, Args, "", Insert);
} else {
llvm_unreachable("Unhandled loop condition!");
}
return 0;
}
/// \brief Handle a back edge (loop)
@ -264,15 +264,11 @@ void SIAnnotateControlFlow::handleLoop(BranchInst *Term) {
BasicBlock *Target = Term->getSuccessor(1);
PHINode *Broken = PHINode::Create(Int64, 0, "", &Target->front());
PhiInserter.Initialize(Int64, "");
PhiInserter.AddAvailableValue(Target, Broken);
Value *Cond = Term->getCondition();
Term->setCondition(BoolTrue);
handleLoopCondition(Cond);
Value *Arg = handleLoopCondition(Cond, Broken);
BasicBlock *BB = Term->getParent();
Value *Arg = PhiInserter.GetValueAtEndOfBlock(BB);
for (pred_iterator PI = pred_begin(Target), PE = pred_end(Target);
PI != PE; ++PI) {