summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/lib/Transforms/Utils/LoopSimplify.cpp
diff options
context:
space:
mode:
authorpatrick <patrick@openbsd.org>2017-01-14 19:55:43 +0000
committerpatrick <patrick@openbsd.org>2017-01-14 19:55:43 +0000
commitbd3306aecb3a15e8967143b8cdbbccf2b1b19b74 (patch)
tree309a8132b44564b9e634c0da6815187ce8eab27c /gnu/llvm/lib/Transforms/Utils/LoopSimplify.cpp
parentkillp -a should not kill the window if only one pane. (diff)
downloadwireguard-openbsd-bd3306aecb3a15e8967143b8cdbbccf2b1b19b74.tar.xz
wireguard-openbsd-bd3306aecb3a15e8967143b8cdbbccf2b1b19b74.zip
Import LLVM 3.9.1 including clang and lld.
Diffstat (limited to 'gnu/llvm/lib/Transforms/Utils/LoopSimplify.cpp')
-rw-r--r--gnu/llvm/lib/Transforms/Utils/LoopSimplify.cpp150
1 files changed, 110 insertions, 40 deletions
diff --git a/gnu/llvm/lib/Transforms/Utils/LoopSimplify.cpp b/gnu/llvm/lib/Transforms/Utils/LoopSimplify.cpp
index 1fa469595d1..2846e8f235b 100644
--- a/gnu/llvm/lib/Transforms/Utils/LoopSimplify.cpp
+++ b/gnu/llvm/lib/Transforms/Utils/LoopSimplify.cpp
@@ -37,6 +37,7 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/Transforms/Utils/LoopSimplify.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/SetOperations.h"
@@ -326,6 +327,8 @@ 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) {
@@ -333,12 +336,53 @@ 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;
}
@@ -489,14 +533,9 @@ ReprocessLoop:
DEBUG(dbgs() << "LoopSimplify: Deleting edge from dead predecessor "
<< P->getName() << "\n");
- // Inform each successor of each dead pred.
- for (succ_iterator SI = succ_begin(P), SE = succ_end(P); SI != SE; ++SI)
- (*SI)->removePredecessor(P);
// Zap the dead pred's terminator and replace it with unreachable.
TerminatorInst *TI = P->getTerminator();
- TI->replaceAllUsesWith(UndefValue::get(TI->getType()));
- P->getTerminator()->eraseFromParent();
- new UnreachableInst(P->getContext(), P);
+ changeToUnreachable(TI, /*UseLLVMTrap=*/false);
Changed = true;
}
}
@@ -506,14 +545,13 @@ ReprocessLoop:
// trip count computations.
SmallVector<BasicBlock*, 8> ExitingBlocks;
L->getExitingBlocks(ExitingBlocks);
- for (SmallVectorImpl<BasicBlock *>::iterator I = ExitingBlocks.begin(),
- E = ExitingBlocks.end(); I != E; ++I)
- if (BranchInst *BI = dyn_cast<BranchInst>((*I)->getTerminator()))
+ for (BasicBlock *ExitingBlock : ExitingBlocks)
+ if (BranchInst *BI = dyn_cast<BranchInst>(ExitingBlock->getTerminator()))
if (BI->isConditional()) {
if (UndefValue *Cond = dyn_cast<UndefValue>(BI->getCondition())) {
DEBUG(dbgs() << "LoopSimplify: Resolving \"br i1 undef\" to exit in "
- << (*I)->getName() << "\n");
+ << ExitingBlock->getName() << "\n");
BI->setCondition(ConstantInt::get(Cond->getType(),
!L->contains(BI->getSuccessor(0))));
@@ -545,20 +583,13 @@ ReprocessLoop:
SmallSetVector<BasicBlock *, 8> ExitBlockSet(ExitBlocks.begin(),
ExitBlocks.end());
- for (SmallSetVector<BasicBlock *, 8>::iterator I = ExitBlockSet.begin(),
- E = ExitBlockSet.end(); I != E; ++I) {
- BasicBlock *ExitBlock = *I;
- 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;
- }
+ 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;
+ }
}
// If the header has more than two predecessors at this point (from the
@@ -691,8 +722,10 @@ ReprocessLoop:
}
DT->eraseNode(ExitingBlock);
- BI->getSuccessor(0)->removePredecessor(ExitingBlock);
- BI->getSuccessor(1)->removePredecessor(ExitingBlock);
+ BI->getSuccessor(0)->removePredecessor(
+ ExitingBlock, /* DontDeleteUselessPHIs */ PreserveLCSSA);
+ BI->getSuccessor(1)->removePredecessor(
+ ExitingBlock, /* DontDeleteUselessPHIs */ PreserveLCSSA);
ExitingBlock->eraseFromParent();
}
}
@@ -731,11 +764,6 @@ namespace {
initializeLoopSimplifyPass(*PassRegistry::getPassRegistry());
}
- DominatorTree *DT;
- LoopInfo *LI;
- ScalarEvolution *SE;
- AssumptionCache *AC;
-
bool runOnFunction(Function &F) override;
void getAnalysisUsage(AnalysisUsage &AU) const override {
@@ -753,7 +781,8 @@ namespace {
AU.addPreserved<GlobalsAAWrapperPass>();
AU.addPreserved<ScalarEvolutionWrapperPass>();
AU.addPreserved<SCEVAAWrapperPass>();
- AU.addPreserved<DependenceAnalysis>();
+ AU.addPreservedID(LCSSAID);
+ AU.addPreserved<DependenceAnalysisWrapperPass>();
AU.addPreservedID(BreakCriticalEdgesID); // No critical edges added.
}
@@ -768,9 +797,6 @@ INITIALIZE_PASS_BEGIN(LoopSimplify, "loop-simplify",
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(BasicAAWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(SCEVAAWrapperPass)
INITIALIZE_PASS_END(LoopSimplify, "loop-simplify",
"Canonicalize natural loops", false, false)
@@ -783,20 +809,64 @@ Pass *llvm::createLoopSimplifyPass() { return new LoopSimplify(); }
///
bool LoopSimplify::runOnFunction(Function &F) {
bool Changed = false;
- LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
- DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+ LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
+ DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
auto *SEWP = getAnalysisIfAvailable<ScalarEvolutionWrapperPass>();
- SE = SEWP ? &SEWP->getSE() : nullptr;
- AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
+ ScalarEvolution *SE = SEWP ? &SEWP->getSE() : nullptr;
+ AssumptionCache *AC =
+ &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
+
bool PreserveLCSSA = mustPreserveAnalysisID(LCSSAID);
+#ifndef NDEBUG
+ if (PreserveLCSSA) {
+ assert(DT && "DT not available.");
+ assert(LI && "LI not available.");
+ bool InLCSSA =
+ all_of(*LI, [&](Loop *L) { return L->isRecursivelyLCSSAForm(*DT); });
+ assert(InLCSSA && "Requested to preserve LCSSA, but it's already broken.");
+ }
+#endif
// Simplify each loop nest in the function.
for (LoopInfo::iterator I = LI->begin(), E = LI->end(); I != E; ++I)
Changed |= simplifyLoop(*I, DT, LI, SE, AC, PreserveLCSSA);
+#ifndef NDEBUG
+ if (PreserveLCSSA) {
+ bool InLCSSA =
+ all_of(*LI, [&](Loop *L) { return L->isRecursivelyLCSSAForm(*DT); });
+ assert(InLCSSA && "LCSSA is broken after loop-simplify.");
+ }
+#endif
return Changed;
}
+PreservedAnalyses LoopSimplifyPass::run(Function &F,
+ AnalysisManager<Function> &AM) {
+ bool Changed = false;
+ LoopInfo *LI = &AM.getResult<LoopAnalysis>(F);
+ DominatorTree *DT = &AM.getResult<DominatorTreeAnalysis>(F);
+ ScalarEvolution *SE = AM.getCachedResult<ScalarEvolutionAnalysis>(F);
+ AssumptionCache *AC = &AM.getResult<AssumptionAnalysis>(F);
+
+ // FIXME: This pass should verify that the loops on which it's operating
+ // are in canonical SSA form, and that the pass itself preserves this form.
+ for (LoopInfo::iterator I = LI->begin(), E = LI->end(); I != E; ++I)
+ Changed |= simplifyLoop(*I, DT, LI, SE, AC, true /* PreserveLCSSA */);
+
+ if (!Changed)
+ return PreservedAnalyses::all();
+ PreservedAnalyses PA;
+ PA.preserve<DominatorTreeAnalysis>();
+ PA.preserve<LoopAnalysis>();
+ PA.preserve<BasicAA>();
+ PA.preserve<GlobalsAA>();
+ PA.preserve<SCEVAA>();
+ PA.preserve<ScalarEvolutionAnalysis>();
+ PA.preserve<DependenceAnalysis>();
+ return PA;
+}
+
// FIXME: Restore this code when we re-enable verification in verifyAnalysis
// below.
#if 0