diff options
Diffstat (limited to 'lib/Transforms/Scalar')
| -rw-r--r-- | lib/Transforms/Scalar/ConstantHoisting.cpp | 95 | ||||
| -rw-r--r-- | lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp | 6 | ||||
| -rw-r--r-- | lib/Transforms/Scalar/LoopUnrollPass.cpp | 30 | ||||
| -rw-r--r-- | lib/Transforms/Scalar/NewGVN.cpp | 3 | ||||
| -rw-r--r-- | lib/Transforms/Scalar/Reassociate.cpp | 2 | ||||
| -rw-r--r-- | lib/Transforms/Scalar/RewriteStatepointsForGC.cpp | 2 | ||||
| -rw-r--r-- | lib/Transforms/Scalar/SROA.cpp | 20 | 
7 files changed, 99 insertions, 59 deletions
diff --git a/lib/Transforms/Scalar/ConstantHoisting.cpp b/lib/Transforms/Scalar/ConstantHoisting.cpp index c3810366bf22..a49c9b68c97d 100644 --- a/lib/Transforms/Scalar/ConstantHoisting.cpp +++ b/lib/Transforms/Scalar/ConstantHoisting.cpp @@ -38,6 +38,7 @@  #include "llvm/ADT/SmallVector.h"  #include "llvm/ADT/Statistic.h"  #include "llvm/IR/Constants.h" +#include "llvm/IR/GetElementPtrTypeIterator.h"  #include "llvm/IR/IntrinsicInst.h"  #include "llvm/Pass.h"  #include "llvm/Support/Debug.h" @@ -340,6 +341,49 @@ void ConstantHoistingPass::collectConstantCandidates(    }  } + +/// \brief Check the operand for instruction Inst at index Idx. +void ConstantHoistingPass::collectConstantCandidates( +    ConstCandMapType &ConstCandMap, Instruction *Inst, unsigned Idx) { +  Value *Opnd = Inst->getOperand(Idx); + +  // Visit constant integers. +  if (auto ConstInt = dyn_cast<ConstantInt>(Opnd)) { +    collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt); +    return; +  } + +  // Visit cast instructions that have constant integers. +  if (auto CastInst = dyn_cast<Instruction>(Opnd)) { +    // Only visit cast instructions, which have been skipped. All other +    // instructions should have already been visited. +    if (!CastInst->isCast()) +      return; + +    if (auto *ConstInt = dyn_cast<ConstantInt>(CastInst->getOperand(0))) { +      // Pretend the constant is directly used by the instruction and ignore +      // the cast instruction. +      collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt); +      return; +    } +  } + +  // Visit constant expressions that have constant integers. +  if (auto ConstExpr = dyn_cast<ConstantExpr>(Opnd)) { +    // Only visit constant cast expressions. +    if (!ConstExpr->isCast()) +      return; + +    if (auto ConstInt = dyn_cast<ConstantInt>(ConstExpr->getOperand(0))) { +      // Pretend the constant is directly used by the instruction and ignore +      // the constant expression. +      collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt); +      return; +    } +  } +} + +  /// \brief Scan the instruction for expensive integer constants and record them  /// in the constant candidate vector.  void ConstantHoistingPass::collectConstantCandidates( @@ -365,44 +409,25 @@ void ConstantHoistingPass::collectConstantCandidates(    if (AI && AI->isStaticAlloca())      return; -  // Scan all operands. -  for (unsigned Idx = 0, E = Inst->getNumOperands(); Idx != E; ++Idx) { -    Value *Opnd = Inst->getOperand(Idx); - -    // Visit constant integers. -    if (auto ConstInt = dyn_cast<ConstantInt>(Opnd)) { -      collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt); -      continue; -    } - -    // Visit cast instructions that have constant integers. -    if (auto CastInst = dyn_cast<Instruction>(Opnd)) { -      // Only visit cast instructions, which have been skipped. All other -      // instructions should have already been visited. -      if (!CastInst->isCast()) -        continue; - -      if (auto *ConstInt = dyn_cast<ConstantInt>(CastInst->getOperand(0))) { -        // Pretend the constant is directly used by the instruction and ignore -        // the cast instruction. -        collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt); -        continue; +  // Constants in GEPs that index into a struct type should not be hoisted. +  if (isa<GetElementPtrInst>(Inst)) { +    gep_type_iterator GTI = gep_type_begin(Inst); + +    // Collect constant for first operand. +    collectConstantCandidates(ConstCandMap, Inst, 0); +    // Scan rest operands. +    for (unsigned Idx = 1, E = Inst->getNumOperands(); Idx != E; ++Idx, ++GTI) { +      // Only collect constants that index into a non struct type. +      if (!GTI.isStruct()) { +        collectConstantCandidates(ConstCandMap, Inst, Idx);        }      } +    return; +  } -    // Visit constant expressions that have constant integers. -    if (auto ConstExpr = dyn_cast<ConstantExpr>(Opnd)) { -      // Only visit constant cast expressions. -      if (!ConstExpr->isCast()) -        continue; - -      if (auto ConstInt = dyn_cast<ConstantInt>(ConstExpr->getOperand(0))) { -        // Pretend the constant is directly used by the instruction and ignore -        // the constant expression. -        collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt); -        continue; -      } -    } +  // Scan all operands. +  for (unsigned Idx = 0, E = Inst->getNumOperands(); Idx != E; ++Idx) { +    collectConstantCandidates(ConstCandMap, Inst, Idx);    } // end of for all operands  } diff --git a/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp b/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp index 2f96c3064b86..a40c22c3fce9 100644 --- a/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp +++ b/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp @@ -917,7 +917,6 @@ LoopConstrainer::calculateSubRanges() const {    // I think we can be more aggressive here and make this nuw / nsw if the    // addition that feeds into the icmp for the latch's terminating branch is nuw    // / nsw.  In any case, a wrapping 2's complement addition is safe. -  ConstantInt *One = ConstantInt::get(Ty, 1);    const SCEV *Start = SE.getSCEV(MainLoopStructure.IndVarStart);    const SCEV *End = SE.getSCEV(MainLoopStructure.LoopExitAt); @@ -948,8 +947,9 @@ LoopConstrainer::calculateSubRanges() const {      //    will be an empty range.  Returning an empty range is always safe.      // -    Smallest = SE.getAddExpr(End, SE.getSCEV(One)); -    Greatest = SE.getAddExpr(Start, SE.getSCEV(One)); +    const SCEV *One = SE.getOne(Ty); +    Smallest = SE.getAddExpr(End, One); +    Greatest = SE.getAddExpr(Start, One);    }    auto Clamp = [this, Smallest, Greatest](const SCEV *S) { diff --git a/lib/Transforms/Scalar/LoopUnrollPass.cpp b/lib/Transforms/Scalar/LoopUnrollPass.cpp index 62aa6ee48069..530a68424d5c 100644 --- a/lib/Transforms/Scalar/LoopUnrollPass.cpp +++ b/lib/Transforms/Scalar/LoopUnrollPass.cpp @@ -131,7 +131,7 @@ static const unsigned NoThreshold = UINT_MAX;  /// Gather the various unrolling parameters based on the defaults, compiler  /// flags, TTI overrides and user specified parameters.  static TargetTransformInfo::UnrollingPreferences gatherUnrollingPreferences( -    Loop *L, const TargetTransformInfo &TTI, int OptLevel, +    Loop *L, ScalarEvolution &SE, const TargetTransformInfo &TTI, int OptLevel,      Optional<unsigned> UserThreshold, Optional<unsigned> UserCount,      Optional<bool> UserAllowPartial, Optional<bool> UserRuntime,      Optional<bool> UserUpperBound) { @@ -158,7 +158,7 @@ static TargetTransformInfo::UnrollingPreferences gatherUnrollingPreferences(    UP.AllowPeeling = true;    // Override with any target specific settings -  TTI.getUnrollingPreferences(L, UP); +  TTI.getUnrollingPreferences(L, SE, UP);    // Apply size attributes    if (L->getHeader()->getParent()->optForSize()) { @@ -699,7 +699,7 @@ static uint64_t getUnrolledLoopSize(  // Calculates unroll count and writes it to UP.Count.  static bool computeUnrollCount(      Loop *L, const TargetTransformInfo &TTI, DominatorTree &DT, LoopInfo *LI, -    ScalarEvolution *SE, OptimizationRemarkEmitter *ORE, unsigned &TripCount, +    ScalarEvolution &SE, OptimizationRemarkEmitter *ORE, unsigned &TripCount,      unsigned MaxTripCount, unsigned &TripMultiple, unsigned LoopSize,      TargetTransformInfo::UnrollingPreferences &UP, bool &UseUpperBound) {    // Check for explicit Count. @@ -770,7 +770,7 @@ static bool computeUnrollCount(        // helps to remove a significant number of instructions.        // To check that, run additional analysis on the loop.        if (Optional<EstimatedUnrollCost> Cost = analyzeLoopUnrollCost( -              L, FullUnrollTripCount, DT, *SE, TTI, +              L, FullUnrollTripCount, DT, SE, TTI,                UP.Threshold * UP.MaxPercentThresholdBoost / 100)) {          unsigned Boost =              getFullUnrollBoostingFactor(*Cost, UP.MaxPercentThresholdBoost); @@ -836,6 +836,8 @@ static bool computeUnrollCount(      } else {        UP.Count = TripCount;      } +    if (UP.Count > UP.MaxCount) +      UP.Count = UP.MaxCount;      if ((PragmaFullUnroll || PragmaEnableUnroll) && TripCount &&          UP.Count != TripCount)        ORE->emit( @@ -926,7 +928,7 @@ static bool computeUnrollCount(  }  static bool tryToUnrollLoop(Loop *L, DominatorTree &DT, LoopInfo *LI, -                            ScalarEvolution *SE, const TargetTransformInfo &TTI, +                            ScalarEvolution &SE, const TargetTransformInfo &TTI,                              AssumptionCache &AC, OptimizationRemarkEmitter &ORE,                              bool PreserveLCSSA, int OptLevel,                              Optional<unsigned> ProvidedCount, @@ -948,8 +950,8 @@ static bool tryToUnrollLoop(Loop *L, DominatorTree &DT, LoopInfo *LI,    bool NotDuplicatable;    bool Convergent;    TargetTransformInfo::UnrollingPreferences UP = gatherUnrollingPreferences( -      L, TTI, OptLevel, ProvidedThreshold, ProvidedCount, ProvidedAllowPartial, -      ProvidedRuntime, ProvidedUpperBound); +      L, SE, TTI, OptLevel, ProvidedThreshold, ProvidedCount, +      ProvidedAllowPartial, ProvidedRuntime, ProvidedUpperBound);    // Exit early if unrolling is disabled.    if (UP.Threshold == 0 && (!UP.Partial || UP.PartialThreshold == 0))      return false; @@ -977,8 +979,8 @@ static bool tryToUnrollLoop(Loop *L, DominatorTree &DT, LoopInfo *LI,    if (!ExitingBlock || !L->isLoopExiting(ExitingBlock))      ExitingBlock = L->getExitingBlock();    if (ExitingBlock) { -    TripCount = SE->getSmallConstantTripCount(L, ExitingBlock); -    TripMultiple = SE->getSmallConstantTripMultiple(L, ExitingBlock); +    TripCount = SE.getSmallConstantTripCount(L, ExitingBlock); +    TripMultiple = SE.getSmallConstantTripMultiple(L, ExitingBlock);    }    // If the loop contains a convergent operation, the prelude we'd add @@ -1000,8 +1002,8 @@ static bool tryToUnrollLoop(Loop *L, DominatorTree &DT, LoopInfo *LI,    // count.    bool MaxOrZero = false;    if (!TripCount) { -    MaxTripCount = SE->getSmallConstantMaxTripCount(L); -    MaxOrZero = SE->isBackedgeTakenCountMaxOrZero(L); +    MaxTripCount = SE.getSmallConstantMaxTripCount(L); +    MaxOrZero = SE.isBackedgeTakenCountMaxOrZero(L);      // We can unroll by the upper bound amount if it's generally allowed or if      // we know that the loop is executed either the upper bound or zero times.      // (MaxOrZero unrolling keeps only the first loop test, so the number of @@ -1030,7 +1032,7 @@ static bool tryToUnrollLoop(Loop *L, DominatorTree &DT, LoopInfo *LI,    // Unroll the loop.    if (!UnrollLoop(L, UP.Count, TripCount, UP.Force, UP.Runtime,                    UP.AllowExpensiveTripCount, UseUpperBound, MaxOrZero, -                  TripMultiple, UP.PeelCount, LI, SE, &DT, &AC, &ORE, +                  TripMultiple, UP.PeelCount, LI, &SE, &DT, &AC, &ORE,                    PreserveLCSSA))      return false; @@ -1073,7 +1075,7 @@ public:      auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();      LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); -    ScalarEvolution *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE(); +    ScalarEvolution &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();      const TargetTransformInfo &TTI =          getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);      auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F); @@ -1157,7 +1159,7 @@ PreservedAnalyses LoopUnrollPass::run(Loop &L, LoopAnalysisManager &AM,    if (!AllowPartialUnrolling)      AllowPartialParam = RuntimeParam = UpperBoundParam = false;    bool Changed = tryToUnrollLoop( -      &L, AR.DT, &AR.LI, &AR.SE, AR.TTI, AR.AC, *ORE, +      &L, AR.DT, &AR.LI, AR.SE, AR.TTI, AR.AC, *ORE,        /*PreserveLCSSA*/ true, OptLevel, /*Count*/ None,        /*Threshold*/ None, AllowPartialParam, RuntimeParam, UpperBoundParam);    if (!Changed) diff --git a/lib/Transforms/Scalar/NewGVN.cpp b/lib/Transforms/Scalar/NewGVN.cpp index 7a7624f77542..9cf01c6582b5 100644 --- a/lib/Transforms/Scalar/NewGVN.cpp +++ b/lib/Transforms/Scalar/NewGVN.cpp @@ -2423,8 +2423,7 @@ void NewGVN::addPhiOfOps(PHINode *Op, BasicBlock *BB,    AllTempInstructions.insert(Op);    PHIOfOpsPHIs[BB].push_back(Op);    TempToBlock[Op] = BB; -  if (ExistingValue) -    RealToTemp[ExistingValue] = Op; +  RealToTemp[ExistingValue] = Op;  }  static bool okayForPHIOfOps(const Instruction *I) { diff --git a/lib/Transforms/Scalar/Reassociate.cpp b/lib/Transforms/Scalar/Reassociate.cpp index 6da551bd7efd..cdba0062953f 100644 --- a/lib/Transforms/Scalar/Reassociate.cpp +++ b/lib/Transforms/Scalar/Reassociate.cpp @@ -1894,6 +1894,8 @@ void ReassociatePass::EraseInst(Instruction *I) {          Op = Op->user_back();        RedoInsts.insert(Op);      } + +  MadeChange = true;  }  // Canonicalize expressions of the following form: diff --git a/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp b/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp index a52739bb76f7..a73e9aec0617 100644 --- a/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp +++ b/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp @@ -1954,7 +1954,7 @@ static void rematerializeLiveValues(CallSite CS,        // to identify the newly generated AlternateRootPhi (.base version of phi)        // and RootOfChain (the original phi node itself) are the same, so that we        // can rematerialize the gep and casts. This is a workaround for the -      // deficieny in the findBasePointer algorithm. +      // deficiency in the findBasePointer algorithm.        if (!AreEquivalentPhiNodes(*OrigRootPhi, *AlternateRootPhi))          continue;        // Now that the phi nodes are proved to be the same, assert that diff --git a/lib/Transforms/Scalar/SROA.cpp b/lib/Transforms/Scalar/SROA.cpp index 80fbbeb6829b..4729f4ef5956 100644 --- a/lib/Transforms/Scalar/SROA.cpp +++ b/lib/Transforms/Scalar/SROA.cpp @@ -2402,9 +2402,20 @@ private:        if (LI.isVolatile())          NewLI->setAtomic(LI.getOrdering(), LI.getSynchScope()); +      // Any !nonnull metadata or !range metadata on the old load is also valid +      // on the new load. This is even true in some cases even when the loads +      // are different types, for example by mapping !nonnull metadata to +      // !range metadata by modeling the null pointer constant converted to the +      // integer type. +      // FIXME: Add support for range metadata here. Currently the utilities +      // for this don't propagate range metadata in trivial cases from one +      // integer load to another, don't handle non-addrspace-0 null pointers +      // correctly, and don't have any support for mapping ranges as the +      // integer type becomes winder or narrower. +      if (MDNode *N = LI.getMetadata(LLVMContext::MD_nonnull)) +        copyNonnullMetadata(LI, N, *NewLI); +        // Try to preserve nonnull metadata -      if (TargetTy->isPointerTy()) -        NewLI->copyMetadata(LI, LLVMContext::MD_nonnull);        V = NewLI;        // If this is an integer load past the end of the slice (which means the @@ -3580,10 +3591,11 @@ bool SROA::presplitLoadsAndStores(AllocaInst &AI, AllocaSlices &AS) {      int Idx = 0, Size = Offsets.Splits.size();      for (;;) {        auto *PartTy = Type::getIntNTy(Ty->getContext(), PartSize * 8); -      auto *PartPtrTy = PartTy->getPointerTo(LI->getPointerAddressSpace()); +      auto AS = LI->getPointerAddressSpace(); +      auto *PartPtrTy = PartTy->getPointerTo(AS);        LoadInst *PLoad = IRB.CreateAlignedLoad(            getAdjustedPtr(IRB, DL, BasePtr, -                         APInt(DL.getPointerSizeInBits(), PartOffset), +                         APInt(DL.getPointerSizeInBits(AS), PartOffset),                           PartPtrTy, BasePtr->getName() + "."),            getAdjustedAlignment(LI, PartOffset, DL), /*IsVolatile*/ false,            LI->getName());  | 
