diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:50:12 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:50:12 +0000 | 
| commit | e6d1592492a3a379186bfb02bd0f4eda0669c0d5 (patch) | |
| tree | 599ab169a01f1c86eda9adc774edaedde2f2db5b /lib/Transforms/Utils/LCSSA.cpp | |
| parent | 1a56a5ead7a2e84bee8240f5f6b033b5f1707154 (diff) | |
Notes
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;  }  | 
