diff options
Diffstat (limited to 'llvm/lib/Transforms/Utils/SimplifyCFG.cpp')
| -rw-r--r-- | llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 89 | 
1 files changed, 60 insertions, 29 deletions
| diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index c537be5c..b03fb62 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -1866,10 +1866,19 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(Instruction *TI,    // If either of the blocks has it's address taken, then we can't do this fold,    // because the code we'd hoist would no longer run when we jump into the block    // by it's address. -  for (auto *Succ : successors(BB)) -    if (Succ->hasAddressTaken() || !Succ->getSinglePredecessor()) +  for (auto *Succ : successors(BB)) { +    if (Succ->hasAddressTaken())        return false; - +    if (Succ->getSinglePredecessor()) +      continue; +    // If Succ has >1 predecessors, continue to check if the Succ contains only +    // one `unreachable` inst. Since executing `unreachable` inst is an UB, we +    // can relax the condition based on the assumptiom that the program would +    // never enter Succ and trigger such an UB. +    if (isa<UnreachableInst>(*Succ->begin())) +      continue; +    return false; +  }    // The second of pair is a SkipFlags bitmask.    using SuccIterPair = std::pair<BasicBlock::iterator, unsigned>;    SmallVector<SuccIterPair, 8> SuccIterPairs; @@ -5228,32 +5237,52 @@ bool SimplifyCFGOpt::simplifyBranchOnICmpChain(BranchInst *BI,          CompVal, DL.getIntPtrType(CompVal->getType()), "magicptr");    } -  // Create the new switch instruction now. -  SwitchInst *New = Builder.CreateSwitch(CompVal, DefaultBB, Values.size()); -  if (HasProfile) { -    // We know the weight of the default case. We don't know the weight of the -    // other cases, but rather than completely lose profiling info, we split -    // the remaining probability equally over them. -    SmallVector<uint32_t> NewWeights(Values.size() + 1); -    NewWeights[0] = BranchWeights[1]; // this is the default, and we swapped if -                                      // TrueWhenEqual. -    for (auto &V : drop_begin(NewWeights)) -      V = BranchWeights[0] / Values.size(); -    setBranchWeights(*New, NewWeights, /*IsExpected=*/false); -  } - -  // Add all of the 'cases' to the switch instruction. -  for (ConstantInt *Val : Values) -    New->addCase(Val, EdgeBB); +  // Check if we can represent the values as a contiguous range. If so, we use a +  // range check + conditional branch instead of a switch. +  if (Values.front()->getValue() - Values.back()->getValue() == +      Values.size() - 1) { +    ConstantRange RangeToCheck = ConstantRange::getNonEmpty( +        Values.back()->getValue(), Values.front()->getValue() + 1); +    APInt Offset, RHS; +    ICmpInst::Predicate Pred; +    RangeToCheck.getEquivalentICmp(Pred, RHS, Offset); +    Value *X = CompVal; +    if (!Offset.isZero()) +      X = Builder.CreateAdd(X, ConstantInt::get(CompVal->getType(), Offset)); +    Value *Cond = +        Builder.CreateICmp(Pred, X, ConstantInt::get(CompVal->getType(), RHS)); +    BranchInst *NewBI = Builder.CreateCondBr(Cond, EdgeBB, DefaultBB); +    if (HasProfile) +      setBranchWeights(*NewBI, BranchWeights, /*IsExpected=*/false); +    // We don't need to update PHI nodes since we don't add any new edges. +  } else { +    // Create the new switch instruction now. +    SwitchInst *New = Builder.CreateSwitch(CompVal, DefaultBB, Values.size()); +    if (HasProfile) { +      // We know the weight of the default case. We don't know the weight of the +      // other cases, but rather than completely lose profiling info, we split +      // the remaining probability equally over them. +      SmallVector<uint32_t> NewWeights(Values.size() + 1); +      NewWeights[0] = BranchWeights[1]; // this is the default, and we swapped +                                        // if TrueWhenEqual. +      for (auto &V : drop_begin(NewWeights)) +        V = BranchWeights[0] / Values.size(); +      setBranchWeights(*New, NewWeights, /*IsExpected=*/false); +    } -  // We added edges from PI to the EdgeBB.  As such, if there were any -  // PHI nodes in EdgeBB, they need entries to be added corresponding to -  // the number of edges added. -  for (BasicBlock::iterator BBI = EdgeBB->begin(); isa<PHINode>(BBI); ++BBI) { -    PHINode *PN = cast<PHINode>(BBI); -    Value *InVal = PN->getIncomingValueForBlock(BB); -    for (unsigned i = 0, e = Values.size() - 1; i != e; ++i) -      PN->addIncoming(InVal, BB); +    // Add all of the 'cases' to the switch instruction. +    for (ConstantInt *Val : Values) +      New->addCase(Val, EdgeBB); + +    // We added edges from PI to the EdgeBB.  As such, if there were any +    // PHI nodes in EdgeBB, they need entries to be added corresponding to +    // the number of edges added. +    for (BasicBlock::iterator BBI = EdgeBB->begin(); isa<PHINode>(BBI); ++BBI) { +      PHINode *PN = cast<PHINode>(BBI); +      Value *InVal = PN->getIncomingValueForBlock(BB); +      for (unsigned i = 0, e = Values.size() - 1; i != e; ++i) +        PN->addIncoming(InVal, BB); +    }    }    // Erase the old branch instruction. @@ -7603,7 +7632,9 @@ static bool simplifySwitchOfPowersOfTwo(SwitchInst *SI, IRBuilder<> &Builder,      auto *DefaultCaseBB = SI->getDefaultDest();      BasicBlock *SplitBB = SplitBlock(OrigBB, SI, DTU);      auto It = OrigBB->getTerminator()->getIterator(); -    BranchInst::Create(SplitBB, DefaultCaseBB, IsPow2, It); +    auto *BI = BranchInst::Create(SplitBB, DefaultCaseBB, IsPow2, It); +    // BI is handling the default case for SI, and so should share its DebugLoc. +    BI->setDebugLoc(SI->getDebugLoc());      It->eraseFromParent();      addPredecessorToBlock(DefaultCaseBB, OrigBB, SplitBB); | 
