auto *ExitBlock = L->getUniqueExitBlock();
assert(ExitBlock && "Should have a unique exit block!");
+ assert(L->hasDedicatedExits() && "Loop should have dedicated exits!");
+
// Connect the preheader directly to the exit block.
// Even when the loop is never executed, we cannot remove the edge from the
// source block to the exit block. Consider the case where the unexecuted loop
// non-loop, it will be deleted in a future iteration of loop deletion pass.
Preheader->getTerminator()->replaceUsesOfWith(L->getHeader(), ExitBlock);
- SmallVector<BasicBlock *, 4> ExitingBlocks;
- L->getExitingBlocks(ExitingBlocks);
// Rewrite phis in the exit block to get their inputs from the Preheader
// instead of the exiting block.
- BasicBlock *ExitingBlock = ExitingBlocks[0];
BasicBlock::iterator BI = ExitBlock->begin();
while (PHINode *P = dyn_cast<PHINode>(BI)) {
- int j = P->getBasicBlockIndex(ExitingBlock);
- assert(j >= 0 && "Can't find exiting block in exit block's phi node!");
+ // Set the zero'th element of Phi to be from the preheader and remove all
+ // other incoming values. Given the loop has dedicated exits, all other
+ // incoming values must be from the exiting blocks.
+ int PredIndex = 0;
if (LoopIsNeverExecuted)
- P->setIncomingValue(j, UndefValue::get(P->getType()));
- P->setIncomingBlock(j, Preheader);
- for (unsigned i = 1; i < ExitingBlocks.size(); ++i)
- P->removeIncomingValue(ExitingBlocks[i]);
+ P->setIncomingValue(PredIndex, UndefValue::get(P->getType()));
+ P->setIncomingBlock(PredIndex, Preheader);
+ // Removes all incoming values from all other exiting blocks (including
+ // duplicate values from an exiting block).
+ // Nuke all entries except the zero'th entry which is the preheader entry.
+ // NOTE! We need to remove Incoming Values in the reverse order as done
+ // below, to keep the indices valid for deletion (removeIncomingValues
+ // updates getNumIncomingValues and shifts all values down into the operand
+ // being deleted).
+ for (unsigned i = 0, e = P->getNumIncomingValues() - 1; i != e; ++i)
+ P->removeIncomingValue(e-i, false);
+
+ assert((P->getNumIncomingValues() == 1 &&
+ P->getIncomingBlock(PredIndex) == Preheader) &&
+ "Should have exactly one value and that's from the preheader!");
++BI;
}
ret void
}
+
+; 2 edges from a single exiting block to the exit block.
+define i64 @test12(i64 %n){
+;CHECK-LABEL: @test12
+; CHECK-NOT: L1:
+; CHECK-NOT: L1Latch:
+; CHECK-LABEL: L1.preheader:
+; CHECK-NEXT: br label %exit
+; CHECK-LABEL: exit:
+; CHECK-NEXT: %y.phi = phi i64 [ undef, %L1.preheader ]
+; CHECK-NEXT: ret i64 %y.phi
+
+entry:
+ br i1 true, label %exit1, label %L1
+
+exit1:
+ ret i64 42
+
+L1: ; preds = %L1Latch, %entry
+ %y.next = phi i64 [ 0, %entry ], [ %y.add, %L1Latch ]
+ br i1 true, label %L1Latch, label %exit
+
+L1Latch: ; preds = %L1
+ %y = phi i64 [ %y.next, %L1 ]
+ %y.add = add i64 %y, %n
+ %cond2 = icmp eq i64 %y.add, 42
+ switch i64 %n, label %L1 [
+ i64 10, label %exit
+ i64 20, label %exit
+ ]
+
+exit: ; preds = %L1Latch, %L1Latch
+ %y.phi = phi i64 [ 10, %L1Latch ], [ 10, %L1Latch ], [ %y.next, %L1]
+ ret i64 %y.phi
+}
+
+; multiple edges to exit block from the same exiting blocks
+define i64 @test13(i64 %n) {
+; CHECK-LABEL: @test13
+; CHECK-NOT: L1:
+; CHECK-NOT: L1Latch:
+; CHECK-LABEL: L1.preheader:
+; CHECK-NEXT: br label %exit
+; CHECK-LABEL: exit:
+; CHECK-NEXT: %y.phi = phi i64 [ undef, %L1.preheader ]
+; CHECK-NEXT: ret i64 %y.phi
+
+entry:
+ br i1 true, label %exit1, label %L1
+
+exit1:
+ ret i64 42
+
+L1: ; preds = %L1Latch, %entry
+ %y.next = phi i64 [ 0, %entry ], [ %y.add, %L1Latch ]
+ br i1 true, label %L1Block, label %exit
+
+L1Block: ; preds = %L1
+ %y = phi i64 [ %y.next, %L1 ]
+ %y.add = add i64 %y, %n
+ %cond2 = icmp eq i64 %y.add, 42
+ switch i64 %n, label %L1Latch [
+ i64 10, label %exit
+ i64 20, label %exit
+ ]
+
+L1Latch:
+ switch i64 %n, label %L1 [
+ i64 30, label %exit
+ i64 40, label %exit
+ ]
+
+exit: ; preds = %L1Block, %L1, %L1Latch
+ %y.phi = phi i64 [ 10, %L1Block ], [ 10, %L1Block ], [ %y.next, %L1 ], [ 30, %L1Latch ], [ 30, %L1Latch ]
+ ret i64 %y.phi
+}