diff options
Diffstat (limited to 'lib/Transforms')
| -rw-r--r-- | lib/Transforms/Scalar/JumpThreading.cpp | 28 | ||||
| -rw-r--r-- | lib/Transforms/Utils/LoopUtils.cpp | 27 | ||||
| -rw-r--r-- | lib/Transforms/Utils/SimplifyCFG.cpp | 16 | 
3 files changed, 46 insertions, 25 deletions
| diff --git a/lib/Transforms/Scalar/JumpThreading.cpp b/lib/Transforms/Scalar/JumpThreading.cpp index 4056cc5cb346..dc9143bebc45 100644 --- a/lib/Transforms/Scalar/JumpThreading.cpp +++ b/lib/Transforms/Scalar/JumpThreading.cpp @@ -64,6 +64,11 @@ ImplicationSearchThreshold(             "condition to use to thread over a weaker condition"),    cl::init(3), cl::Hidden); +static cl::opt<bool> PrintLVIAfterJumpThreading( +    "print-lvi-after-jump-threading", +    cl::desc("Print the LazyValueInfo cache after JumpThreading"), cl::init(false), +    cl::Hidden); +  namespace {    /// This pass performs 'jump threading', which looks at blocks that have    /// multiple predecessors and multiple successors.  If one or more of the @@ -93,9 +98,10 @@ namespace {      bool runOnFunction(Function &F) override;      void getAnalysisUsage(AnalysisUsage &AU) const override { +      if (PrintLVIAfterJumpThreading) +        AU.addRequired<DominatorTreeWrapperPass>();        AU.addRequired<AAResultsWrapperPass>();        AU.addRequired<LazyValueInfoWrapperPass>(); -      AU.addPreserved<LazyValueInfoWrapperPass>();        AU.addPreserved<GlobalsAAWrapperPass>();        AU.addRequired<TargetLibraryInfoWrapperPass>();      } @@ -137,8 +143,14 @@ bool JumpThreading::runOnFunction(Function &F) {      BFI.reset(new BlockFrequencyInfo(F, *BPI, LI));    } -  return Impl.runImpl(F, TLI, LVI, AA, HasProfileData, std::move(BFI), -                      std::move(BPI)); +  bool Changed = Impl.runImpl(F, TLI, LVI, AA, HasProfileData, std::move(BFI), +                              std::move(BPI)); +  if (PrintLVIAfterJumpThreading) { +    dbgs() << "LVI for function '" << F.getName() << "':\n"; +    LVI->printLVI(F, getAnalysis<DominatorTreeWrapperPass>().getDomTree(), +                  dbgs()); +  } +  return Changed;  }  PreservedAnalyses JumpThreadingPass::run(Function &F, @@ -231,13 +243,15 @@ bool JumpThreadingPass::runImpl(Function &F, TargetLibraryInfo *TLI_,        // Can't thread an unconditional jump, but if the block is "almost        // empty", we can replace uses of it with uses of the successor and make        // this dead. -      // We should not eliminate the loop header either, because eliminating -      // a loop header might later prevent LoopSimplify from transforming nested -      // loops into simplified form. +      // We should not eliminate the loop header or latch either, because +      // eliminating a loop header or latch might later prevent LoopSimplify +      // from transforming nested loops into simplified form. We will rely on +      // later passes in backend to clean up empty blocks.        if (BI && BI->isUnconditional() &&            BB != &BB->getParent()->getEntryBlock() &&            // If the terminator is the only non-phi instruction, try to nuke it. -          BB->getFirstNonPHIOrDbg()->isTerminator() && !LoopHeaders.count(BB)) { +          BB->getFirstNonPHIOrDbg()->isTerminator() && !LoopHeaders.count(BB) && +          !LoopHeaders.count(BI->getSuccessor(0))) {          // FIXME: It is always conservatively correct to drop the info          // for a block even if it doesn't get erased.  This isn't totally          // awesome, but it allows us to use AssertingVH to prevent nasty diff --git a/lib/Transforms/Utils/LoopUtils.cpp b/lib/Transforms/Utils/LoopUtils.cpp index 58b70be95d99..3c522786641a 100644 --- a/lib/Transforms/Utils/LoopUtils.cpp +++ b/lib/Transforms/Utils/LoopUtils.cpp @@ -1376,16 +1376,21 @@ Value *llvm::createTargetReduction(IRBuilder<> &Builder,    }  } -void llvm::propagateIRFlags(Value *I, ArrayRef<Value *> VL) { -  if (auto *VecOp = dyn_cast<Instruction>(I)) { -    if (auto *I0 = dyn_cast<Instruction>(VL[0])) { -      // VecOVp is initialized to the 0th scalar, so start counting from index -      // '1'. -      VecOp->copyIRFlags(I0); -      for (int i = 1, e = VL.size(); i < e; ++i) { -        if (auto *Scalar = dyn_cast<Instruction>(VL[i])) -          VecOp->andIRFlags(Scalar); -      } -    } +void llvm::propagateIRFlags(Value *I, ArrayRef<Value *> VL, Value *OpValue) { +  auto *VecOp = dyn_cast<Instruction>(I); +  if (!VecOp) +    return; +  auto *Intersection = (OpValue == nullptr) ? dyn_cast<Instruction>(VL[0]) +                                            : dyn_cast<Instruction>(OpValue); +  if (!Intersection) +    return; +  const unsigned Opcode = Intersection->getOpcode(); +  VecOp->copyIRFlags(Intersection); +  for (auto *V : VL) { +    auto *Instr = dyn_cast<Instruction>(V); +    if (!Instr) +      continue; +    if (OpValue == nullptr || Opcode == Instr->getOpcode()) +      VecOp->andIRFlags(V);    }  } diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp index dee658f98393..8784b9702141 100644 --- a/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/lib/Transforms/Utils/SimplifyCFG.cpp @@ -5656,20 +5656,22 @@ static bool TryToMergeLandingPad(LandingPadInst *LPad, BranchInst *BI,  bool SimplifyCFGOpt::SimplifyUncondBranch(BranchInst *BI,                                            IRBuilder<> &Builder) {    BasicBlock *BB = BI->getParent(); +  BasicBlock *Succ = BI->getSuccessor(0);    if (SinkCommon && SinkThenElseCodeToEnd(BI))      return true;    // If the Terminator is the only non-phi instruction, simplify the block. -  // if LoopHeader is provided, check if the block is a loop header -  // (This is for early invocations before loop simplify and vectorization -  // to keep canonical loop forms for nested loops. -  // These blocks can be eliminated when the pass is invoked later -  // in the back-end.) +  // if LoopHeader is provided, check if the block or its successor is a loop +  // header (This is for early invocations before loop simplify and +  // vectorization to keep canonical loop forms for nested loops. These blocks +  // can be eliminated when the pass is invoked later in the back-end.) +  bool NeedCanonicalLoop = +      !LateSimplifyCFG && +      (LoopHeaders && (LoopHeaders->count(BB) || LoopHeaders->count(Succ)));    BasicBlock::iterator I = BB->getFirstNonPHIOrDbg()->getIterator();    if (I->isTerminator() && BB != &BB->getParent()->getEntryBlock() && -      (!LoopHeaders || !LoopHeaders->count(BB)) && -      TryToSimplifyUncondBranchFromEmptyBlock(BB)) +      !NeedCanonicalLoop && TryToSimplifyUncondBranchFromEmptyBlock(BB))      return true;    // If the only instruction in the block is a seteq/setne comparison | 
