diff options
| -rw-r--r-- | llvm/include/llvm/Transforms/Scalar.h | 2 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Scalar/SROA.cpp | 206 | ||||
| -rw-r--r-- | llvm/test/Transforms/SROA/basictest.ll | 1 | ||||
| -rw-r--r-- | llvm/test/Transforms/SROA/big-endian.ll | 1 | ||||
| -rw-r--r-- | llvm/test/Transforms/SROA/fca.ll | 1 | 
5 files changed, 9 insertions, 202 deletions
diff --git a/llvm/include/llvm/Transforms/Scalar.h b/llvm/include/llvm/Transforms/Scalar.h index 0a37d838a93..5c703966eb1 100644 --- a/llvm/include/llvm/Transforms/Scalar.h +++ b/llvm/include/llvm/Transforms/Scalar.h @@ -93,7 +93,7 @@ FunctionPass *createBitTrackingDCEPass();  //  // SROA - Replace aggregates or pieces of aggregates with scalar SSA values.  // -FunctionPass *createSROAPass(bool RequiresDomTree = true); +FunctionPass *createSROAPass();  //===----------------------------------------------------------------------===//  // diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp index 9c69b6c7558..d37d1e753eb 100644 --- a/llvm/lib/Transforms/Scalar/SROA.cpp +++ b/llvm/lib/Transforms/Scalar/SROA.cpp @@ -55,7 +55,6 @@  #include "llvm/Support/raw_ostream.h"  #include "llvm/Transforms/Utils/Local.h"  #include "llvm/Transforms/Utils/PromoteMemToReg.h" -#include "llvm/Transforms/Utils/SSAUpdater.h"  #if __cplusplus >= 201103L && !defined(NDEBUG)  // We only use this for a debug check in C++11 @@ -77,11 +76,6 @@ STATISTIC(NumLoadsSpeculated, "Number of loads speculated to allow promotion");  STATISTIC(NumDeleted, "Number of instructions deleted");  STATISTIC(NumVectorized, "Number of vectorized aggregates"); -/// Hidden option to force the pass to not use DomTree and mem2reg, instead -/// forming SSA values through the SSAUpdater infrastructure. -static cl::opt<bool> ForceSSAUpdater("force-ssa-updater", cl::init(false), -                                     cl::Hidden); -  /// Hidden option to enable randomly shuffling the slices to help uncover  /// instability in their order.  static cl::opt<bool> SROARandomShuffleSlices("sroa-random-shuffle-slices", @@ -1074,109 +1068,6 @@ LLVM_DUMP_METHOD void AllocaSlices::dump() const { print(dbgs()); }  #endif // !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)  namespace { -/// \brief Implementation of LoadAndStorePromoter for promoting allocas. -/// -/// This subclass of LoadAndStorePromoter adds overrides to handle promoting -/// the loads and stores of an alloca instruction, as well as updating its -/// debug information. This is used when a domtree is unavailable and thus -/// mem2reg in its full form can't be used to handle promotion of allocas to -/// scalar values. -class AllocaPromoter : public LoadAndStorePromoter { -  AllocaInst &AI; -  DIBuilder &DIB; - -  SmallVector<DbgDeclareInst *, 4> DDIs; -  SmallVector<DbgValueInst *, 4> DVIs; - -public: -  AllocaPromoter(ArrayRef<const Instruction *> Insts, -                 SSAUpdater &S, -                 AllocaInst &AI, DIBuilder &DIB) -      : LoadAndStorePromoter(Insts, S), AI(AI), DIB(DIB) {} - -  void run(const SmallVectorImpl<Instruction *> &Insts) { -    // Retain the debug information attached to the alloca for use when -    // rewriting loads and stores. -    if (auto *L = LocalAsMetadata::getIfExists(&AI)) { -      if (auto *DINode = MetadataAsValue::getIfExists(AI.getContext(), L)) { -        for (User *U : DINode->users()) -          if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(U)) -            DDIs.push_back(DDI); -          else if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(U)) -            DVIs.push_back(DVI); -      } -    } - -    LoadAndStorePromoter::run(Insts); - -    // While we have the debug information, clear it off of the alloca. The -    // caller takes care of deleting the alloca. -    while (!DDIs.empty()) -      DDIs.pop_back_val()->eraseFromParent(); -    while (!DVIs.empty()) -      DVIs.pop_back_val()->eraseFromParent(); -  } - -  bool -  isInstInList(Instruction *I, -               const SmallVectorImpl<Instruction *> &Insts) const override { -    Value *Ptr; -    if (LoadInst *LI = dyn_cast<LoadInst>(I)) -      Ptr = LI->getOperand(0); -    else -      Ptr = cast<StoreInst>(I)->getPointerOperand(); - -    // Only used to detect cycles, which will be rare and quickly found as -    // we're walking up a chain of defs rather than down through uses. -    SmallPtrSet<Value *, 4> Visited; - -    do { -      if (Ptr == &AI) -        return true; - -      if (BitCastInst *BCI = dyn_cast<BitCastInst>(Ptr)) -        Ptr = BCI->getOperand(0); -      else if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(Ptr)) -        Ptr = GEPI->getPointerOperand(); -      else -        return false; - -    } while (Visited.insert(Ptr).second); - -    return false; -  } - -  void updateDebugInfo(Instruction *Inst) const override { -    for (DbgDeclareInst *DDI : DDIs) -      if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) -        ConvertDebugDeclareToDebugValue(DDI, SI, DIB); -      else if (LoadInst *LI = dyn_cast<LoadInst>(Inst)) -        ConvertDebugDeclareToDebugValue(DDI, LI, DIB); -    for (DbgValueInst *DVI : DVIs) { -      Value *Arg = nullptr; -      if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) { -        // If an argument is zero extended then use argument directly. The ZExt -        // may be zapped by an optimization pass in future. -        if (ZExtInst *ZExt = dyn_cast<ZExtInst>(SI->getOperand(0))) -          Arg = dyn_cast<Argument>(ZExt->getOperand(0)); -        else if (SExtInst *SExt = dyn_cast<SExtInst>(SI->getOperand(0))) -          Arg = dyn_cast<Argument>(SExt->getOperand(0)); -        if (!Arg) -          Arg = SI->getValueOperand(); -      } else if (LoadInst *LI = dyn_cast<LoadInst>(Inst)) { -        Arg = LI->getPointerOperand(); -      } else { -        continue; -      } -      DIB.insertDbgValueIntrinsic(Arg, 0, DVI->getVariable(), -                                  DVI->getExpression(), DVI->getDebugLoc(), -                                  Inst); -    } -  } -}; -} // end anon namespace - -namespace {  /// \brief An optimization pass providing Scalar Replacement of Aggregates.  ///  /// This pass takes allocations which can be completely analyzed (that is, they @@ -1196,8 +1087,6 @@ namespace {  ///    this form. By doing so, it will enable promotion of vector aggregates to  ///    SSA vector values.  class SROA : public FunctionPass { -  const bool RequiresDomTree; -    LLVMContext *C;    DominatorTree *DT;    AssumptionCache *AC; @@ -1245,9 +1134,7 @@ class SROA : public FunctionPass {    SetVector<SelectInst *, SmallVector<SelectInst *, 2>> SpeculatableSelects;  public: -  SROA(bool RequiresDomTree = true) -      : FunctionPass(ID), RequiresDomTree(RequiresDomTree), C(nullptr), -        DT(nullptr) { +  SROA() : FunctionPass(ID), C(nullptr), DT(nullptr) {      initializeSROAPass(*PassRegistry::getPassRegistry());    }    bool runOnFunction(Function &F) override; @@ -1273,8 +1160,8 @@ private:  char SROA::ID = 0; -FunctionPass *llvm::createSROAPass(bool RequiresDomTree) { -  return new SROA(RequiresDomTree); +FunctionPass *llvm::createSROAPass() { +  return new SROA();  }  INITIALIZE_PASS_BEGIN(SROA, "sroa", "Scalar Replacement Of Aggregates", false, @@ -4389,93 +4276,19 @@ void SROA::deleteDeadInstructions(    }  } -static void enqueueUsersInWorklist(Instruction &I, -                                   SmallVectorImpl<Instruction *> &Worklist, -                                   SmallPtrSetImpl<Instruction *> &Visited) { -  for (User *U : I.users()) -    if (Visited.insert(cast<Instruction>(U)).second) -      Worklist.push_back(cast<Instruction>(U)); -} -  /// \brief Promote the allocas, using the best available technique.  ///  /// This attempts to promote whatever allocas have been identified as viable in  /// the PromotableAllocas list. If that list is empty, there is nothing to do. -/// If there is a domtree available, we attempt to promote using the full power -/// of mem2reg. Otherwise, we build and use the AllocaPromoter above which is -/// based on the SSAUpdater utilities. This function returns whether any -/// promotion occurred. +/// This function returns whether any promotion occurred.  bool SROA::promoteAllocas(Function &F) {    if (PromotableAllocas.empty())      return false;    NumPromoted += PromotableAllocas.size(); -  if (DT && !ForceSSAUpdater) { -    DEBUG(dbgs() << "Promoting allocas with mem2reg...\n"); -    PromoteMemToReg(PromotableAllocas, *DT, nullptr, AC); -    PromotableAllocas.clear(); -    return true; -  } - -  DEBUG(dbgs() << "Promoting allocas with SSAUpdater...\n"); -  SSAUpdater SSA; -  DIBuilder DIB(*F.getParent(), /*AllowUnresolved*/ false); -  SmallVector<Instruction *, 64> Insts; - -  // We need a worklist to walk the uses of each alloca. -  SmallVector<Instruction *, 8> Worklist; -  SmallPtrSet<Instruction *, 8> Visited; -  SmallVector<Instruction *, 32> DeadInsts; - -  for (unsigned Idx = 0, Size = PromotableAllocas.size(); Idx != Size; ++Idx) { -    AllocaInst *AI = PromotableAllocas[Idx]; -    Insts.clear(); -    Worklist.clear(); -    Visited.clear(); - -    enqueueUsersInWorklist(*AI, Worklist, Visited); - -    while (!Worklist.empty()) { -      Instruction *I = Worklist.pop_back_val(); - -      // FIXME: Currently the SSAUpdater infrastructure doesn't reason about -      // lifetime intrinsics and so we strip them (and the bitcasts+GEPs -      // leading to them) here. Eventually it should use them to optimize the -      // scalar values produced. -      if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) { -        assert(II->getIntrinsicID() == Intrinsic::lifetime_start || -               II->getIntrinsicID() == Intrinsic::lifetime_end); -        II->eraseFromParent(); -        continue; -      } - -      // Push the loads and stores we find onto the list. SROA will already -      // have validated that all loads and stores are viable candidates for -      // promotion. -      if (LoadInst *LI = dyn_cast<LoadInst>(I)) { -        assert(LI->getType() == AI->getAllocatedType()); -        Insts.push_back(LI); -        continue; -      } -      if (StoreInst *SI = dyn_cast<StoreInst>(I)) { -        assert(SI->getValueOperand()->getType() == AI->getAllocatedType()); -        Insts.push_back(SI); -        continue; -      } - -      // For everything else, we know that only no-op bitcasts and GEPs will -      // make it this far, just recurse through them and recall them for later -      // removal. -      DeadInsts.push_back(I); -      enqueueUsersInWorklist(*I, Worklist, Visited); -    } -    AllocaPromoter(Insts, SSA, *AI, DIB).run(Insts); -    while (!DeadInsts.empty()) -      DeadInsts.pop_back_val()->eraseFromParent(); -    AI->eraseFromParent(); -  } - +  DEBUG(dbgs() << "Promoting allocas with mem2reg...\n"); +  PromoteMemToReg(PromotableAllocas, *DT, nullptr, AC);    PromotableAllocas.clear();    return true;  } @@ -4486,9 +4299,7 @@ bool SROA::runOnFunction(Function &F) {    DEBUG(dbgs() << "SROA function: " << F.getName() << "\n");    C = &F.getContext(); -  DominatorTreeWrapperPass *DTWP = -      getAnalysisIfAvailable<DominatorTreeWrapperPass>(); -  DT = DTWP ? &DTWP->getDomTree() : nullptr; +  DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();    AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);    BasicBlock &EntryBB = F.getEntryBlock(); @@ -4533,7 +4344,6 @@ bool SROA::runOnFunction(Function &F) {  void SROA::getAnalysisUsage(AnalysisUsage &AU) const {    AU.addRequired<AssumptionCacheTracker>(); -  if (RequiresDomTree) -    AU.addRequired<DominatorTreeWrapperPass>(); +  AU.addRequired<DominatorTreeWrapperPass>();    AU.setPreservesCFG();  } diff --git a/llvm/test/Transforms/SROA/basictest.ll b/llvm/test/Transforms/SROA/basictest.ll index ad2794167a5..009f16a80bb 100644 --- a/llvm/test/Transforms/SROA/basictest.ll +++ b/llvm/test/Transforms/SROA/basictest.ll @@ -1,5 +1,4 @@  ; RUN: opt < %s -sroa -S | FileCheck %s -; RUN: opt < %s -sroa -force-ssa-updater -S | FileCheck %s  target datalayout = "e-p:64:64:64-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64" diff --git a/llvm/test/Transforms/SROA/big-endian.ll b/llvm/test/Transforms/SROA/big-endian.ll index 4de7bfcb898..ea41a20fd38 100644 --- a/llvm/test/Transforms/SROA/big-endian.ll +++ b/llvm/test/Transforms/SROA/big-endian.ll @@ -1,5 +1,4 @@  ; RUN: opt < %s -sroa -S | FileCheck %s -; RUN: opt < %s -sroa -force-ssa-updater -S | FileCheck %s  target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64" diff --git a/llvm/test/Transforms/SROA/fca.ll b/llvm/test/Transforms/SROA/fca.ll index 6eaa73f5318..707f680e64e 100644 --- a/llvm/test/Transforms/SROA/fca.ll +++ b/llvm/test/Transforms/SROA/fca.ll @@ -1,5 +1,4 @@  ; RUN: opt < %s -sroa -S | FileCheck %s -; RUN: opt < %s -sroa -force-ssa-updater -S | FileCheck %s  target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64"  define { i32, i32 } @test0(i32 %x, i32 %y) {  | 

