diff options
Diffstat (limited to 'lib/Transforms/Utils/LCSSA.cpp')
-rw-r--r-- | lib/Transforms/Utils/LCSSA.cpp | 47 |
1 files changed, 39 insertions, 8 deletions
diff --git a/lib/Transforms/Utils/LCSSA.cpp b/lib/Transforms/Utils/LCSSA.cpp index 53d444b309d5..29e7c5260f46 100644 --- a/lib/Transforms/Utils/LCSSA.cpp +++ b/lib/Transforms/Utils/LCSSA.cpp @@ -1,9 +1,8 @@ //===-- LCSSA.cpp - Convert loops into loop-closed SSA form ---------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -32,11 +31,12 @@ #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/BasicAliasAnalysis.h" +#include "llvm/Analysis/BranchProbabilityInfo.h" #include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/LoopPass.h" +#include "llvm/Analysis/MemorySSA.h" #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" -#include "llvm/Transforms/Utils/Local.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Function.h" @@ -45,6 +45,7 @@ #include "llvm/IR/PredIteratorCache.h" #include "llvm/Pass.h" #include "llvm/Transforms/Utils.h" +#include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/LoopUtils.h" #include "llvm/Transforms/Utils/SSAUpdater.h" using namespace llvm; @@ -198,6 +199,17 @@ bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist, continue; } + // If we added a single PHI, it must dominate all uses and we can directly + // rename it. + if (AddedPHIs.size() == 1) { + // Tell the VHs that the uses changed. This updates SCEV's caches. + // We might call ValueIsRAUWd multiple times for the same value. + if (UseToRewrite->get()->hasValueHandle()) + ValueHandleBase::ValueIsRAUWd(*UseToRewrite, AddedPHIs[0]); + UseToRewrite->set(AddedPHIs[0]); + continue; + } + // Otherwise, do full PHI insertion. SSAUpdate.RewriteUse(*UseToRewrite); } @@ -211,9 +223,12 @@ bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist, BasicBlock *UserBB = DVI->getParent(); if (InstBB == UserBB || L->contains(UserBB)) continue; - // We currently only handle debug values residing in blocks where we have - // inserted a PHI instruction. - if (Value *V = SSAUpdate.FindValueForBlock(UserBB)) + // We currently only handle debug values residing in blocks that were + // traversed while rewriting the uses. If we inserted just a single PHI, + // we will handle all relevant debug values. + Value *V = AddedPHIs.size() == 1 ? AddedPHIs[0] + : SSAUpdate.FindValueForBlock(UserBB); + if (V) DVI->setOperand(0, MetadataAsValue::get(Ctx, ValueAsMetadata::get(V))); } @@ -306,6 +321,12 @@ bool llvm::formLCSSA(Loop &L, DominatorTree &DT, LoopInfo *LI, ScalarEvolution *SE) { bool Changed = false; +#ifdef EXPENSIVE_CHECKS + // Verify all sub-loops are in LCSSA form already. + for (Loop *SubLoop: L) + assert(SubLoop->isRecursivelyLCSSAForm(DT, *LI) && "Subloop not in LCSSA!"); +#endif + SmallVector<BasicBlock *, 8> ExitBlocks; L.getExitBlocks(ExitBlocks); if (ExitBlocks.empty()) @@ -325,6 +346,10 @@ bool llvm::formLCSSA(Loop &L, DominatorTree &DT, LoopInfo *LI, // Look at all the instructions in the loop, checking to see if they have uses // outside the loop. If so, put them into the worklist to rewrite those uses. for (BasicBlock *BB : BlocksDominatingExits) { + // Skip blocks that are part of any sub-loops, they must be in LCSSA + // already. + if (LI->getLoopFor(BB) != &L) + continue; for (Instruction &I : *BB) { // Reject two common cases fast: instructions with no uses (like stores) // and instructions with one use that is in the same block as this. @@ -419,6 +444,8 @@ struct LCSSAWrapperPass : public FunctionPass { AU.addPreserved<GlobalsAAWrapperPass>(); AU.addPreserved<ScalarEvolutionWrapperPass>(); AU.addPreserved<SCEVAAWrapperPass>(); + AU.addPreserved<BranchProbabilityInfoWrapperPass>(); + AU.addPreserved<MemorySSAWrapperPass>(); // This is needed to perform LCSSA verification inside LPPassManager AU.addRequired<LCSSAVerificationPass>(); @@ -462,5 +489,9 @@ PreservedAnalyses LCSSAPass::run(Function &F, FunctionAnalysisManager &AM) { PA.preserve<GlobalsAA>(); PA.preserve<SCEVAA>(); PA.preserve<ScalarEvolutionAnalysis>(); + // BPI maps terminators to probabilities, since we don't modify the CFG, no + // updates are needed to preserve it. + PA.preserve<BranchProbabilityAnalysis>(); + PA.preserve<MemorySSAAnalysis>(); return PA; } |