diff options
-rw-r--r-- | llvm/lib/Transforms/Utils/LCSSA.cpp | 11 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/LoopSimplify.cpp | 62 | ||||
-rw-r--r-- | llvm/test/Transforms/LCSSA/pr28424.ll | 87 | ||||
-rw-r--r-- | llvm/test/Transforms/LoopSimplify/pr28272.ll | 76 |
4 files changed, 13 insertions, 223 deletions
diff --git a/llvm/lib/Transforms/Utils/LCSSA.cpp b/llvm/lib/Transforms/Utils/LCSSA.cpp index bee6e24d25a..9658966779b 100644 --- a/llvm/lib/Transforms/Utils/LCSSA.cpp +++ b/llvm/lib/Transforms/Utils/LCSSA.cpp @@ -115,8 +115,7 @@ bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist, SmallVector<PHINode *, 16> AddedPHIs; SmallVector<PHINode *, 8> PostProcessPHIs; - SmallVector<PHINode *, 4> InsertedPHIs; - SSAUpdater SSAUpdate(&InsertedPHIs); + SSAUpdater SSAUpdate; SSAUpdate.Initialize(I->getType(), I->getName()); // Insert the LCSSA phi's into all of the exit blocks dominated by the @@ -185,14 +184,6 @@ bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist, // Otherwise, do full PHI insertion. SSAUpdate.RewriteUse(*UseToRewrite); - - // SSAUpdater might have inserted phi-nodes inside other loops. We'll need - // to post-process them to keep LCSSA form. - for (PHINode *InsertedPN : InsertedPHIs) { - if (auto *OtherLoop = LI.getLoopFor(InsertedPN->getParent())) - if (!L->contains(OtherLoop)) - PostProcessPHIs.push_back(InsertedPN); - } } // Post process PHI instructions that were inserted into another disjoint diff --git a/llvm/lib/Transforms/Utils/LoopSimplify.cpp b/llvm/lib/Transforms/Utils/LoopSimplify.cpp index 2846e8f235b..b3a928bf775 100644 --- a/llvm/lib/Transforms/Utils/LoopSimplify.cpp +++ b/llvm/lib/Transforms/Utils/LoopSimplify.cpp @@ -327,8 +327,6 @@ static Loop *separateNestedLoop(Loop *L, BasicBlock *Preheader, else NewOuter->addChildLoop(L->removeChildLoop(SubLoops.begin() + I)); - SmallVector<BasicBlock *, 8> OuterLoopBlocks; - OuterLoopBlocks.push_back(NewBB); // Now that we know which blocks are in L and which need to be moved to // OuterLoop, move any blocks that need it. for (unsigned i = 0; i != L->getBlocks().size(); ++i) { @@ -336,53 +334,12 @@ static Loop *separateNestedLoop(Loop *L, BasicBlock *Preheader, if (!BlocksInL.count(BB)) { // Move this block to the parent, updating the exit blocks sets L->removeBlockFromLoop(BB); - if ((*LI)[BB] == L) { + if ((*LI)[BB] == L) LI->changeLoopFor(BB, NewOuter); - OuterLoopBlocks.push_back(BB); - } --i; } } - // Split edges to exit blocks from the inner loop, if they emerged in the - // process of separating the outer one. - SmallVector<BasicBlock *, 8> ExitBlocks; - L->getExitBlocks(ExitBlocks); - SmallSetVector<BasicBlock *, 8> ExitBlockSet(ExitBlocks.begin(), - ExitBlocks.end()); - for (BasicBlock *ExitBlock : ExitBlockSet) { - if (any_of(predecessors(ExitBlock), - [L](BasicBlock *BB) { return !L->contains(BB); })) { - rewriteLoopExitBlock(L, ExitBlock, DT, LI, PreserveLCSSA); - } - } - - if (PreserveLCSSA) { - // Fix LCSSA form for L. Some values, which previously were only used inside - // L, can now be used in NewOuter loop. We need to insert phi-nodes for them - // in corresponding exit blocks. - - // Go through all instructions in OuterLoopBlocks and check if they are - // using operands from the inner loop. In this case we'll need to fix LCSSA - // for these instructions. - SmallSetVector<Instruction *, 8> WorklistSet; - for (BasicBlock *OuterBB: OuterLoopBlocks) { - for (Instruction &I : *OuterBB) { - for (Value *Op : I.operands()) { - Instruction *OpI = dyn_cast<Instruction>(Op); - if (!OpI || !L->contains(OpI)) - continue; - WorklistSet.insert(OpI); - } - } - } - SmallVector<Instruction *, 8> Worklist(WorklistSet.begin(), - WorklistSet.end()); - formLCSSAForInstructions(Worklist, *DT, *LI); - assert(NewOuter->isRecursivelyLCSSAForm(*DT) && - "LCSSA is broken after separating nested loops!"); - } - return NewOuter; } @@ -584,12 +541,17 @@ ReprocessLoop: SmallSetVector<BasicBlock *, 8> ExitBlockSet(ExitBlocks.begin(), ExitBlocks.end()); for (BasicBlock *ExitBlock : ExitBlockSet) { - if (any_of(predecessors(ExitBlock), - [L](BasicBlock *BB) { return !L->contains(BB); })) { - rewriteLoopExitBlock(L, ExitBlock, DT, LI, PreserveLCSSA); - ++NumInserted; - Changed = true; - } + for (pred_iterator PI = pred_begin(ExitBlock), PE = pred_end(ExitBlock); + PI != PE; ++PI) + // Must be exactly this loop: no subloops, parent loops, or non-loop preds + // allowed. + if (!L->contains(*PI)) { + if (rewriteLoopExitBlock(L, ExitBlock, DT, LI, PreserveLCSSA)) { + ++NumInserted; + Changed = true; + } + break; + } } // If the header has more than two predecessors at this point (from the diff --git a/llvm/test/Transforms/LCSSA/pr28424.ll b/llvm/test/Transforms/LCSSA/pr28424.ll deleted file mode 100644 index cd7969009fb..00000000000 --- a/llvm/test/Transforms/LCSSA/pr28424.ll +++ /dev/null @@ -1,87 +0,0 @@ -; RUN: opt < %s -lcssa -S -o - | FileCheck %s -target triple = "x86_64-unknown-linux-gnu" - -; PR28424 -; Here LCSSA adds phi-nodes for %x into the loop exits. Then, SSAUpdater needs -; to insert phi-nodes to merge these values. That creates a new def, which in -; its turn needs another LCCSA phi-node, and this test ensures that we insert -; it. - -; CHECK-LABEL: @foo1 -define internal i32 @foo1() { -entry: - br label %header - -header: - %x = add i32 0, 1 - br i1 undef, label %if, label %loopexit1 - -if: - br i1 undef, label %latch, label %loopexit2 - -latch: - br i1 undef, label %header, label %loopexit3 - -; CHECK: loopexit1: -; CHECK: %x.lcssa = phi i32 [ %x, %header ] -loopexit1: - br label %loop_with_insert_point - -; CHECK: loopexit2: -; CHECK: %x.lcssa1 = phi i32 [ %x, %if ] -loopexit2: - br label %exit - -; CHECK: loopexit3: -; CHECK: %x.lcssa2 = phi i32 [ %x, %latch ] -loopexit3: - br label %loop_with_insert_point - -; CHECK: loop_with_insert_point: -; CHECK: %x4 = phi i32 [ %x4, %loop_with_insert_point ], [ %x.lcssa2, %loopexit3 ], [ %x.lcssa, %loopexit1 ] -loop_with_insert_point: - br i1 undef, label %loop_with_insert_point, label %bb - -; CHECK: bb: -; CHECK: %x4.lcssa = phi i32 [ %x4, %loop_with_insert_point ] -bb: - br label %exit - -; CHECK: exit: -; CHECK: %x3 = phi i32 [ %x4.lcssa, %bb ], [ %x.lcssa1, %loopexit2 ] -exit: - ret i32 %x -} - -; CHECK-LABEL: @foo2 -define internal i32 @foo2() { -entry: - br label %header - -header: - %x = add i32 0, 1 - br i1 undef, label %latch, label %loopexit1 - -latch: - br i1 undef, label %header, label %loopexit2 - -; CHECK: loopexit1: -; CHECK: %x.lcssa = phi i32 [ %x, %header ] -loopexit1: - br label %loop_with_insert_point - -; CHECK: loopexit2: -; CHECK: %x.lcssa1 = phi i32 [ %x, %latch ] -loopexit2: - br label %loop_with_insert_point - -; CHECK: loop_with_insert_point: -; CHECK: %x2 = phi i32 [ %x2, %loop_with_insert_point ], [ %x.lcssa1, %loopexit2 ], [ %x.lcssa, %loopexit1 ] -loop_with_insert_point: - br i1 undef, label %loop_with_insert_point, label %exit - -; CHECK: exit: -; CHECK: %x2.lcssa = phi i32 [ %x2, %loop_with_insert_point ] -exit: - ret i32 %x -} diff --git a/llvm/test/Transforms/LoopSimplify/pr28272.ll b/llvm/test/Transforms/LoopSimplify/pr28272.ll deleted file mode 100644 index 49990f92cab..00000000000 --- a/llvm/test/Transforms/LoopSimplify/pr28272.ll +++ /dev/null @@ -1,76 +0,0 @@ -; RUN: opt < %s -lcssa -loop-unroll -S | FileCheck %s -target triple = "x86_64-unknown-linux-gnu" - -; PR28272 -; When LoopSimplify separates nested loops, it might break LCSSA form: values -; from the original loop might be used in the outer loop. This test invokes -; loop-unroll, which calls loop-simplify before itself. If LCSSA is broken -; after loop-simplify, we crash on assertion. - -; CHECK-LABEL: @foo -define void @foo() { -entry: - br label %header - -header: - br label %loop1 - -loop1: - br i1 true, label %loop1, label %bb43 - -bb43: - %a = phi i32 [ undef, %loop1 ], [ 0, %bb45 ], [ %a, %bb54 ] - %b = phi i32 [ 0, %loop1 ], [ 1, %bb54 ], [ %c, %bb45 ] - br i1 true, label %bb114, label %header - -bb114: - %c = add i32 0, 1 - %d = add i32 0, 1 - br i1 true, label %bb45, label %bb54 - -bb45: - %x = add i32 %d, 0 - br label %bb43 - -bb54: - br label %bb43 -} - -; CHECK-LABEL: @foo2 -define void @foo2() { -entry: - br label %outer - -outer.loopexit: - br label %outer - -outer: - br label %loop1 - -loop1: - br i1 true, label %loop1, label %loop2.preheader - -loop2.preheader: - %a.ph = phi i32 [ undef, %loop1 ] - %b.ph = phi i32 [ 0, %loop1 ] - br label %loop2 - -loop2: - %a = phi i32 [ 0, %loop2.if.true ], [ %a, %loop2.if.false ], [ %a.ph, %loop2.preheader ], [0, %bb] - %b = phi i32 [ 1, %loop2.if.false ], [ %c, %loop2.if.true ], [ %b.ph, %loop2.preheader ], [%c, %bb] - br i1 true, label %loop2.if, label %outer.loopexit - -loop2.if: - %c = add i32 0, 1 - switch i32 undef, label %loop2.if.false [i32 0, label %loop2.if.true - i32 1, label %bb] - -loop2.if.true: - br i1 undef, label %loop2, label %bb - -loop2.if.false: - br label %loop2 - -bb: - br label %loop2 -} |