[llvm] r229650 - Revert r229622: "[LoopAccesses] Make VectorizerParams global" and others. r229622 brought cyclic dependencies between Analysis and Vector.

Adam Nemet anemet at apple.com
Wed Feb 18 10:46:33 PST 2015


OK, a BUILD_SHARED_LIBS build reproduces the problem (thanks to Quentin for the idea!):

Undefined symbols for architecture x86_64:
  "llvm::VectorizerParams::MaxVectorWidth", referenced from:
      (anonymous namespace)::MemoryDepChecker::couldPreventStoreLoadForward(unsigned int, unsigned int) in LoopAccessAnalysis.cpp.o
  "llvm::VectorizerParams::VectorizationFactor", referenced from:
      (anonymous namespace)::MemoryDepChecker::isDependent(llvm::PointerIntPair<llvm::Value*, 1u, bool, llvm::PointerLikeTypeTraits<llvm::Value*> > const&, unsigned int, llvm::PointerIntPair<llvm::Value*, 1u, bool, llvm::PointerLikeTypeTraits<llvm::Value*> > const&, unsigned int, llvm::DenseMap<llvm::Value const*, llvm::Value*, llvm::DenseMapInfo<llvm::Value const*>, llvm::detail::DenseMapPair<llvm::Value const*, llvm::Value*> >&) in LoopAccessAnalysis.cpp.o
  "llvm::VectorizerParams::VectorizationInterleave", referenced from:
      (anonymous namespace)::MemoryDepChecker::isDependent(llvm::PointerIntPair<llvm::Value*, 1u, bool, llvm::PointerLikeTypeTraits<llvm::Value*> > const&, unsigned int, llvm::PointerIntPair<llvm::Value*, 1u, bool, llvm::PointerLikeTypeTraits<llvm::Value*> > const&, unsigned int, llvm::DenseMap<llvm::Value const*, llvm::Value*, llvm::DenseMapInfo<llvm::Value const*>, llvm::detail::DenseMapPair<llvm::Value const*, llvm::Value*> >&) in LoopAccessAnalysis.cpp.o
  "llvm::VectorizerParams::RuntimeMemoryCheckThreshold", referenced from:
      llvm::LoopAccessInfo::analyzeLoop(llvm::DenseMap<llvm::Value const*, llvm::Value*, llvm::DenseMapInfo<llvm::Value const*>, llvm::detail::DenseMapPair<llvm::Value const*, llvm::Value*> >&) in LoopAccessAnalysis.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [lib/libLLVMAnalysis.dylib] Error 1

Will experiment with moving these to LAA.cpp.

BTW, did you see this with some bot?  I didn’t get any failing bot emails other than the original MSVC thing.

Adam

> On Feb 18, 2015, at 10:02 AM, Adam Nemet <anemet at apple.com> wrote:
> 
> Hi,
> 
> Sorry about that.  I think I understand why this is happening and how to fix it: we should probably move the defs for the shared parameters into LAA.cpp.  My question is whether we have a way then to check for cyclic dependence (I wasn’t getting any failure during testing).
> 
> Thanks,
> Adam 
> 
>> On Feb 18, 2015, at 12:34 AM, NAKAMURA Takumi <geek4civic at gmail.com> wrote:
>> 
>> Author: chapuni
>> Date: Wed Feb 18 02:34:47 2015
>> New Revision: 229650
>> 
>> URL: http://llvm.org/viewvc/llvm-project?rev=229650&view=rev
>> Log:
>> Revert r229622: "[LoopAccesses] Make VectorizerParams global" and others. r229622 brought cyclic dependencies between Analysis and Vector.
>> 
>> r229622: "[LoopAccesses] Make VectorizerParams global"
>> r229623: "[LoopAccesses] Stash the report from the analysis rather than emitting it"
>> r229624: "[LoopAccesses] Cache the result of canVectorizeMemory"
>> r229626: "[LoopAccesses] Create the analysis pass"
>> r229628: "[LoopAccesses] Change debug messages from LV to LAA"
>> r229630: "[LoopAccesses] Add canAnalyzeLoop"
>> r229631: "[LoopAccesses] Add missing const to APIs in VectorizationReport"
>> r229632: "[LoopAccesses] Split out LoopAccessReport from VectorizerReport"
>> r229633: "[LoopAccesses] Add -analyze support"
>> r229634: "[LoopAccesses] Change LAA:getInfo to return a constant reference"
>> r229638: "Analysis: fix buildbots"
>> 
>> Removed:
>>   llvm/trunk/test/Analysis/LoopAccessAnalysis/unsafe-and-rt-checks-no-dbg.ll
>>   llvm/trunk/test/Analysis/LoopAccessAnalysis/unsafe-and-rt-checks.ll
>> Modified:
>>   llvm/trunk/include/llvm/Analysis/LoopAccessAnalysis.h
>>   llvm/trunk/include/llvm/InitializePasses.h
>>   llvm/trunk/lib/Analysis/LoopAccessAnalysis.cpp
>>   llvm/trunk/lib/Transforms/Scalar/Scalar.cpp
>>   llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp
>> 
>> Modified: llvm/trunk/include/llvm/Analysis/LoopAccessAnalysis.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LoopAccessAnalysis.h?rev=229650&r1=229649&r2=229650&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/Analysis/LoopAccessAnalysis.h (original)
>> +++ llvm/trunk/include/llvm/Analysis/LoopAccessAnalysis.h Wed Feb 18 02:34:47 2015
>> @@ -16,13 +16,11 @@
>> #define LLVM_ANALYSIS_LOOPACCESSANALYSIS_H
>> 
>> #include "llvm/ADT/EquivalenceClasses.h"
>> -#include "llvm/ADT/Optional.h"
>> #include "llvm/ADT/SetVector.h"
>> #include "llvm/Analysis/AliasAnalysis.h"
>> #include "llvm/Analysis/AliasSetTracker.h"
>> #include "llvm/Analysis/ScalarEvolutionExpressions.h"
>> #include "llvm/IR/ValueHandle.h"
>> -#include "llvm/Pass.h"
>> #include "llvm/Support/raw_ostream.h"
>> 
>> namespace llvm {
>> @@ -36,52 +34,30 @@ class SCEV;
>> 
>> /// Optimization analysis message produced during vectorization. Messages inform
>> /// the user why vectorization did not occur.
>> -class LoopAccessReport {
>> +class VectorizationReport {
>>  std::string Message;
>> -  const Instruction *Instr;
>> -
>> -protected:
>> -  LoopAccessReport(const Twine &Message, const Instruction *I)
>> -      : Message(Message.str()), Instr(I) {}
>> +  Instruction *Instr;
>> 
>> public:
>> -  LoopAccessReport(const Instruction *I = nullptr) : Instr(I) {}
>> +  VectorizationReport(Instruction *I = nullptr)
>> +      : Message("loop not vectorized: "), Instr(I) {}
>> 
>> -  template <typename A> LoopAccessReport &operator<<(const A &Value) {
>> +  template <typename A> VectorizationReport &operator<<(const A &Value) {
>>    raw_string_ostream Out(Message);
>>    Out << Value;
>>    return *this;
>>  }
>> 
>> -  const Instruction *getInstr() const { return Instr; }
>> +  Instruction *getInstr() { return Instr; }
>> 
>>  std::string &str() { return Message; }
>> -  const std::string &str() const { return Message; }
>>  operator Twine() { return Message; }
>> 
>> -  /// \brief Emit an analysis note for \p PassName with the debug location from
>> -  /// the instruction in \p Message if available.  Otherwise use the location of
>> -  /// \p TheLoop.
>> -  static void emitAnalysis(const LoopAccessReport &Message,
>> +  /// \brief Emit an analysis note with the debug location from the instruction
>> +  /// in \p Message if available.  Otherwise use the location of \p TheLoop.
>> +  static void emitAnalysis(VectorizationReport &Message,
>>                           const Function *TheFunction,
>> -                           const Loop *TheLoop,
>> -                           const char *PassName);
>> -};
>> -
>> -/// \brief Collection of parameters shared beetween the Loop Vectorizer and the
>> -/// Loop Access Analysis.
>> -struct VectorizerParams {
>> -  /// \brief Maximum SIMD width.
>> -  static const unsigned MaxVectorWidth;
>> -
>> -  /// \brief VF as overridden by the user.
>> -  static unsigned VectorizationFactor;
>> -  /// \brief Interleave factor as overridden by the user.
>> -  static unsigned VectorizationInterleave;
>> -
>> -  /// \\brief When performing memory disambiguation checks at runtime do not
>> -  /// make more than this number of comparisons.
>> -  static const unsigned RuntimeMemoryCheckThreshold;
>> +                           const Loop *TheLoop);
>> };
>> 
>> /// \brief Drive the analysis of memory accesses in the loop
>> @@ -100,6 +76,30 @@ struct VectorizerParams {
>> /// RuntimePointerCheck class.
>> class LoopAccessInfo {
>> public:
>> +  /// \brief Collection of parameters used from the vectorizer.
>> +  struct VectorizerParams {
>> +    /// \brief Maximum simd width.
>> +    unsigned MaxVectorWidth;
>> +
>> +    /// \brief VF as overridden by the user.
>> +    unsigned VectorizationFactor;
>> +    /// \brief Interleave factor as overridden by the user.
>> +    unsigned VectorizationInterleave;
>> +
>> +    /// \\brief When performing memory disambiguation checks at runtime do not
>> +    /// make more than this number of comparisons.
>> +    unsigned RuntimeMemoryCheckThreshold;
>> +
>> +    VectorizerParams(unsigned MaxVectorWidth,
>> +                     unsigned VectorizationFactor,
>> +                     unsigned VectorizationInterleave,
>> +                     unsigned RuntimeMemoryCheckThreshold) :
>> +        MaxVectorWidth(MaxVectorWidth),
>> +        VectorizationFactor(VectorizationFactor),
>> +        VectorizationInterleave(VectorizationInterleave),
>> +        RuntimeMemoryCheckThreshold(RuntimeMemoryCheckThreshold) {}
>> +  };
>> +
>>  /// This struct holds information about the memory runtime legality check that
>>  /// a group of pointers do not overlap.
>>  struct RuntimePointerCheck {
>> @@ -120,16 +120,10 @@ public:
>>    void insert(ScalarEvolution *SE, Loop *Lp, Value *Ptr, bool WritePtr,
>>                unsigned DepSetId, unsigned ASId, ValueToValueMap &Strides);
>> 
>> -    /// \brief No run-time memory checking is necessary.
>> -    bool empty() const { return Pointers.empty(); }
>> -
>>    /// \brief Decide whether we need to issue a run-time check for pointer at
>>    /// index \p I and \p J to prove their independence.
>>    bool needsChecking(unsigned I, unsigned J) const;
>> 
>> -    /// \brief Print the list run-time memory checks necessary.
>> -    void print(raw_ostream &OS, unsigned Depth = 0) const;
>> -
>>    /// This flag indicates if we need to add the runtime check.
>>    bool Need;
>>    /// Holds the pointers that we need to check.
>> @@ -147,17 +141,19 @@ public:
>>    SmallVector<unsigned, 2> AliasSetId;
>>  };
>> 
>> -  LoopAccessInfo(Loop *L, ScalarEvolution *SE, const DataLayout *DL,
>> -                 const TargetLibraryInfo *TLI, AliasAnalysis *AA,
>> -                 DominatorTree *DT, ValueToValueMap &Strides);
>> +  LoopAccessInfo(Function *F, Loop *L, ScalarEvolution *SE,
>> +                 const DataLayout *DL, const TargetLibraryInfo *TLI,
>> +                 AliasAnalysis *AA, DominatorTree *DT,
>> +                 const VectorizerParams &VectParams) :
>> +      TheFunction(F), TheLoop(L), SE(SE), DL(DL), TLI(TLI), AA(AA), DT(DT),
>> +      NumLoads(0), NumStores(0), MaxSafeDepDistBytes(-1U),
>> +      VectParams(VectParams) {}
>> 
>>  /// Return true we can analyze the memory accesses in the loop and there are
>> -  /// no memory dependence cycles.
>> -  bool canVectorizeMemory() const { return CanVecMem; }
>> +  /// no memory dependence cycles.  Replaces symbolic strides using Strides.
>> +  bool canVectorizeMemory(ValueToValueMap &Strides);
>> 
>> -  const RuntimePointerCheck *getRuntimePointerCheck() const {
>> -    return &PtrRtCheck;
>> -  }
>> +  RuntimePointerCheck *getRuntimePointerCheck() { return &PtrRtCheck; }
>> 
>>  /// Return true if the block BB needs to be predicated in order for the loop
>>  /// to be vectorized.
>> @@ -165,7 +161,7 @@ public:
>>                                    DominatorTree *DT);
>> 
>>  /// Returns true if the value V is uniform within the loop.
>> -  bool isUniform(Value *V) const;
>> +  bool isUniform(Value *V);
>> 
>>  unsigned getMaxSafeDepDistBytes() const { return MaxSafeDepDistBytes; }
>>  unsigned getNumStores() const { return NumStores; }
>> @@ -176,34 +172,15 @@ public:
>>  /// Returns a pair of instructions where the first element is the first
>>  /// instruction generated in possibly a sequence of instructions and the
>>  /// second value is the final comparator value or NULL if no check is needed.
>> -  std::pair<Instruction *, Instruction *>
>> -    addRuntimeCheck(Instruction *Loc) const;
>> -
>> -  /// \brief The diagnostics report generated for the analysis.  E.g. why we
>> -  /// couldn't analyze the loop.
>> -  const Optional<LoopAccessReport> &getReport() const { return Report; }
>> -
>> -  /// \brief Print the information about the memory accesses in the loop.
>> -  void print(raw_ostream &OS, unsigned Depth = 0) const;
>> -
>> -  /// \brief Used to ensure that if the analysis was run with speculating the
>> -  /// value of symbolic strides, the client queries it with the same assumption.
>> -  /// Only used in DEBUG build but we don't want NDEBUG-depedent ABI.
>> -  unsigned NumSymbolicStrides;
>> +  std::pair<Instruction *, Instruction *> addRuntimeCheck(Instruction *Loc);
>> 
>> private:
>> -  /// \brief Analyze the loop.  Substitute symbolic strides using Strides.
>> -  void analyzeLoop(ValueToValueMap &Strides);
>> -
>> -  /// \brief Check if the structure of the loop allows it to be analyzed by this
>> -  /// pass.
>> -  bool canAnalyzeLoop();
>> -
>> -  void emitAnalysis(LoopAccessReport &Message);
>> +  void emitAnalysis(VectorizationReport &Message);
>> 
>>  /// We need to check that all of the pointers in this list are disjoint
>>  /// at runtime.
>>  RuntimePointerCheck PtrRtCheck;
>> +  Function *TheFunction;
>>  Loop *TheLoop;
>>  ScalarEvolution *SE;
>>  const DataLayout *DL;
>> @@ -216,12 +193,8 @@ private:
>> 
>>  unsigned MaxSafeDepDistBytes;
>> 
>> -  /// \brief Cache the result of analyzeLoop.
>> -  bool CanVecMem;
>> -
>> -  /// \brief The diagnostics report generated for the analysis.  E.g. why we
>> -  /// couldn't analyze the loop.
>> -  Optional<LoopAccessReport> Report;
>> +  /// \brief Vectorizer parameters used by the analysis.
>> +  VectorizerParams VectParams;
>> };
>> 
>> Value *stripIntegerCast(Value *V);
>> @@ -236,52 +209,6 @@ const SCEV *replaceSymbolicStrideSCEV(Sc
>>                                      ValueToValueMap &PtrToStride,
>>                                      Value *Ptr, Value *OrigPtr = nullptr);
>> 
>> -/// \brief This analysis provides dependence information for the memory accesses
>> -/// of a loop.
>> -///
>> -/// It runs the analysis for a loop on demand.  This can be initiated by
>> -/// querying the loop access info via LAA::getInfo.  getInfo return a
>> -/// LoopAccessInfo object.  See this class for the specifics of what information
>> -/// is provided.
>> -class LoopAccessAnalysis : public FunctionPass {
>> -public:
>> -  static char ID;
>> -
>> -  LoopAccessAnalysis() : FunctionPass(ID) {
>> -    initializeLoopAccessAnalysisPass(*PassRegistry::getPassRegistry());
>> -  }
>> -
>> -  bool runOnFunction(Function &F) override;
>> -
>> -  void getAnalysisUsage(AnalysisUsage &AU) const override;
>> -
>> -  /// \brief Query the result of the loop access information for the loop \p L.
>> -  ///
>> -  /// If the client speculates (and then issues run-time checks) for the values
>> -  /// of symbolic strides, \p Strides provides the mapping (see
>> -  /// replaceSymbolicStrideSCEV).  If there is no cached result available run
>> -  /// the analysis.
>> -  const LoopAccessInfo &getInfo(Loop *L, ValueToValueMap &Strides);
>> -
>> -  void releaseMemory() override {
>> -    // Invalidate the cache when the pass is freed.
>> -    LoopAccessInfoMap.clear();
>> -  }
>> -
>> -  /// \brief Print the result of the analysis when invoked with -analyze.
>> -  void print(raw_ostream &OS, const Module *M = nullptr) const override;
>> -
>> -private:
>> -  /// \brief The cache.
>> -  DenseMap<Loop *, std::unique_ptr<LoopAccessInfo>> LoopAccessInfoMap;
>> -
>> -  // The used analysis passes.
>> -  ScalarEvolution *SE;
>> -  const DataLayout *DL;
>> -  const TargetLibraryInfo *TLI;
>> -  AliasAnalysis *AA;
>> -  DominatorTree *DT;
>> -};
>> } // End llvm namespace
>> 
>> #endif
>> 
>> Modified: llvm/trunk/include/llvm/InitializePasses.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=229650&r1=229649&r2=229650&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/InitializePasses.h (original)
>> +++ llvm/trunk/include/llvm/InitializePasses.h Wed Feb 18 02:34:47 2015
>> @@ -281,7 +281,6 @@ void initializeVirtRegRewriterPass(PassR
>> void initializeInstSimplifierPass(PassRegistry&);
>> void initializeUnpackMachineBundlesPass(PassRegistry&);
>> void initializeFinalizeMachineBundlesPass(PassRegistry&);
>> -void initializeLoopAccessAnalysisPass(PassRegistry&);
>> void initializeLoopVectorizePass(PassRegistry&);
>> void initializeSLPVectorizerPass(PassRegistry&);
>> void initializeBBVectorizePass(PassRegistry&);
>> 
>> Modified: llvm/trunk/lib/Analysis/LoopAccessAnalysis.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LoopAccessAnalysis.cpp?rev=229650&r1=229649&r2=229650&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Analysis/LoopAccessAnalysis.cpp (original)
>> +++ llvm/trunk/lib/Analysis/LoopAccessAnalysis.cpp Wed Feb 18 02:34:47 2015
>> @@ -23,16 +23,15 @@
>> #include "llvm/Transforms/Utils/VectorUtils.h"
>> using namespace llvm;
>> 
>> -#define DEBUG_TYPE "loop-accesses"
>> +#define DEBUG_TYPE "loop-vectorize"
>> 
>> -void LoopAccessReport::emitAnalysis(const LoopAccessReport &Message,
>> -                                    const Function *TheFunction,
>> -                                    const Loop *TheLoop,
>> -                                    const char *PassName) {
>> +void VectorizationReport::emitAnalysis(VectorizationReport &Message,
>> +                                       const Function *TheFunction,
>> +                                       const Loop *TheLoop) {
>>  DebugLoc DL = TheLoop->getStartLoc();
>> -  if (const Instruction *I = Message.getInstr())
>> +  if (Instruction *I = Message.getInstr())
>>    DL = I->getDebugLoc();
>> -  emitOptimizationRemarkAnalysis(TheFunction->getContext(), PassName,
>> +  emitOptimizationRemarkAnalysis(TheFunction->getContext(), DEBUG_TYPE,
>>                                 *TheFunction, DL, Message.str());
>> }
>> 
>> @@ -65,7 +64,7 @@ const SCEV *llvm::replaceSymbolicStrideS
>> 
>>    const SCEV *ByOne =
>>        SCEVParameterRewriter::rewrite(OrigSCEV, *SE, RewriteMap, true);
>> -    DEBUG(dbgs() << "LAA: Replacing SCEV: " << *OrigSCEV << " by: " << *ByOne
>> +    DEBUG(dbgs() << "LV: Replacing SCEV: " << *OrigSCEV << " by: " << *ByOne
>>                 << "\n");
>>    return ByOne;
>>  }
>> @@ -110,23 +109,6 @@ bool LoopAccessInfo::RuntimePointerCheck
>>  return true;
>> }
>> 
>> -void LoopAccessInfo::RuntimePointerCheck::print(raw_ostream &OS,
>> -                                                unsigned Depth) const {
>> -  unsigned NumPointers = Pointers.size();
>> -  if (NumPointers == 0)
>> -    return;
>> -
>> -  OS.indent(Depth) << "Run-time memory checks:\n";
>> -  unsigned N = 0;
>> -  for (unsigned I = 0; I < NumPointers; ++I)
>> -    for (unsigned J = I + 1; J < NumPointers; ++J)
>> -      if (needsChecking(I, J)) {
>> -        OS.indent(Depth) << N++ << ":\n";
>> -        OS.indent(Depth + 2) << *Pointers[I] << "\n";
>> -        OS.indent(Depth + 2) << *Pointers[J] << "\n";
>> -      }
>> -}
>> -
>> namespace {
>> /// \brief Analyses memory accesses in a loop.
>> ///
>> @@ -282,7 +264,7 @@ bool AccessAnalysis::canCheckPtrAtRT(
>> 
>>        RtCheck.insert(SE, TheLoop, Ptr, IsWrite, DepId, ASId, StridesMap);
>> 
>> -        DEBUG(dbgs() << "LAA: Found a runtime check ptr:" << *Ptr << '\n');
>> +        DEBUG(dbgs() << "LV: Found a runtime check ptr:" << *Ptr << '\n');
>>      } else {
>>        CanDoRT = false;
>>      }
>> @@ -319,7 +301,7 @@ bool AccessAnalysis::canCheckPtrAtRT(
>>      unsigned ASi = PtrI->getType()->getPointerAddressSpace();
>>      unsigned ASj = PtrJ->getType()->getPointerAddressSpace();
>>      if (ASi != ASj) {
>> -        DEBUG(dbgs() << "LAA: Runtime check would require comparison between"
>> +        DEBUG(dbgs() << "LV: Runtime check would require comparison between"
>>                       " different address spaces\n");
>>        return false;
>>      }
>> @@ -334,9 +316,9 @@ void AccessAnalysis::processMemAccesses(
>>  // process read-only pointers. This allows us to skip dependence tests for
>>  // read-only pointers.
>> 
>> -  DEBUG(dbgs() << "LAA: Processing memory accesses...\n");
>> +  DEBUG(dbgs() << "LV: Processing memory accesses...\n");
>>  DEBUG(dbgs() << "  AST: "; AST.dump());
>> -  DEBUG(dbgs() << "LAA:   Accesses:\n");
>> +  DEBUG(dbgs() << "LV:   Accesses:\n");
>>  DEBUG({
>>    for (auto A : Accesses)
>>      dbgs() << "\t" << *A.getPointer() << " (" <<
>> @@ -472,9 +454,10 @@ public:
>>  typedef PointerIntPair<Value *, 1, bool> MemAccessInfo;
>>  typedef SmallPtrSet<MemAccessInfo, 8> MemAccessInfoSet;
>> 
>> -  MemoryDepChecker(ScalarEvolution *Se, const DataLayout *Dl, const Loop *L)
>> +  MemoryDepChecker(ScalarEvolution *Se, const DataLayout *Dl, const Loop *L,
>> +                   const LoopAccessInfo::VectorizerParams &VectParams)
>>      : SE(Se), DL(Dl), InnermostLoop(L), AccessIdx(0),
>> -        ShouldRetryWithRuntimeCheck(false) {}
>> +        ShouldRetryWithRuntimeCheck(false), VectParams(VectParams) {}
>> 
>>  /// \brief Register the location (instructions are given increasing numbers)
>>  /// of a write access.
>> @@ -529,6 +512,9 @@ private:
>>  /// vectorize this loop with runtime checks.
>>  bool ShouldRetryWithRuntimeCheck;
>> 
>> +  /// \brief Vectorizer parameters used by the analysis.
>> +  LoopAccessInfo::VectorizerParams VectParams;
>> +
>>  /// \brief Check whether there is a plausible dependence between the two
>>  /// accesses.
>>  ///
>> @@ -567,8 +553,8 @@ static int isStridedPtr(ScalarEvolution
>>  // Make sure that the pointer does not point to aggregate types.
>>  const PointerType *PtrTy = cast<PointerType>(Ty);
>>  if (PtrTy->getElementType()->isAggregateType()) {
>> -    DEBUG(dbgs() << "LAA: Bad stride - Not a pointer to a scalar type"
>> -          << *Ptr << "\n");
>> +    DEBUG(dbgs() << "LV: Bad stride - Not a pointer to a scalar type" << *Ptr <<
>> +          "\n");
>>    return 0;
>>  }
>> 
>> @@ -576,14 +562,14 @@ static int isStridedPtr(ScalarEvolution
>> 
>>  const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(PtrScev);
>>  if (!AR) {
>> -    DEBUG(dbgs() << "LAA: Bad stride - Not an AddRecExpr pointer "
>> +    DEBUG(dbgs() << "LV: Bad stride - Not an AddRecExpr pointer "
>>          << *Ptr << " SCEV: " << *PtrScev << "\n");
>>    return 0;
>>  }
>> 
>>  // The accesss function must stride over the innermost loop.
>>  if (Lp != AR->getLoop()) {
>> -    DEBUG(dbgs() << "LAA: Bad stride - Not striding over innermost loop " <<
>> +    DEBUG(dbgs() << "LV: Bad stride - Not striding over innermost loop " <<
>>          *Ptr << " SCEV: " << *PtrScev << "\n");
>>  }
>> 
>> @@ -598,7 +584,7 @@ static int isStridedPtr(ScalarEvolution
>>  bool IsNoWrapAddRec = AR->getNoWrapFlags(SCEV::NoWrapMask);
>>  bool IsInAddressSpaceZero = PtrTy->getAddressSpace() == 0;
>>  if (!IsNoWrapAddRec && !IsInBoundsGEP && !IsInAddressSpaceZero) {
>> -    DEBUG(dbgs() << "LAA: Bad stride - Pointer may wrap in the address space "
>> +    DEBUG(dbgs() << "LV: Bad stride - Pointer may wrap in the address space "
>>          << *Ptr << " SCEV: " << *PtrScev << "\n");
>>    return 0;
>>  }
>> @@ -609,7 +595,7 @@ static int isStridedPtr(ScalarEvolution
>>  // Calculate the pointer stride and check if it is consecutive.
>>  const SCEVConstant *C = dyn_cast<SCEVConstant>(Step);
>>  if (!C) {
>> -    DEBUG(dbgs() << "LAA: Bad stride - Not a constant strided " << *Ptr <<
>> +    DEBUG(dbgs() << "LV: Bad stride - Not a constant strided " << *Ptr <<
>>          " SCEV: " << *PtrScev << "\n");
>>    return 0;
>>  }
>> @@ -652,8 +638,7 @@ bool MemoryDepChecker::couldPreventStore
>>  // Store-load forwarding distance.
>>  const unsigned NumCyclesForStoreLoadThroughMemory = 8*TypeByteSize;
>>  // Maximum vector factor.
>> -  unsigned MaxVFWithoutSLForwardIssues =
>> -    VectorizerParams::MaxVectorWidth * TypeByteSize;
>> +  unsigned MaxVFWithoutSLForwardIssues = VectParams.MaxVectorWidth*TypeByteSize;
>>  if(MaxSafeDepDistBytes < MaxVFWithoutSLForwardIssues)
>>    MaxVFWithoutSLForwardIssues = MaxSafeDepDistBytes;
>> 
>> @@ -666,14 +651,13 @@ bool MemoryDepChecker::couldPreventStore
>>  }
>> 
>>  if (MaxVFWithoutSLForwardIssues< 2*TypeByteSize) {
>> -    DEBUG(dbgs() << "LAA: Distance " << Distance <<
>> +    DEBUG(dbgs() << "LV: Distance " << Distance <<
>>          " that could cause a store-load forwarding conflict\n");
>>    return true;
>>  }
>> 
>>  if (MaxVFWithoutSLForwardIssues < MaxSafeDepDistBytes &&
>> -      MaxVFWithoutSLForwardIssues !=
>> -      VectorizerParams::MaxVectorWidth * TypeByteSize)
>> +      MaxVFWithoutSLForwardIssues != VectParams.MaxVectorWidth*TypeByteSize)
>>    MaxSafeDepDistBytes = MaxVFWithoutSLForwardIssues;
>>  return false;
>> }
>> @@ -720,9 +704,9 @@ bool MemoryDepChecker::isDependent(const
>> 
>>  const SCEV *Dist = SE->getMinusSCEV(Sink, Src);
>> 
>> -  DEBUG(dbgs() << "LAA: Src Scev: " << *Src << "Sink Scev: " << *Sink
>> +  DEBUG(dbgs() << "LV: Src Scev: " << *Src << "Sink Scev: " << *Sink
>>        << "(Induction step: " << StrideAPtr <<  ")\n");
>> -  DEBUG(dbgs() << "LAA: Distance for " << *InstMap[AIdx] << " to "
>> +  DEBUG(dbgs() << "LV: Distance for " << *InstMap[AIdx] << " to "
>>        << *InstMap[BIdx] << ": " << *Dist << "\n");
>> 
>>  // Need consecutive accesses. We don't want to vectorize
>> @@ -735,7 +719,7 @@ bool MemoryDepChecker::isDependent(const
>> 
>>  const SCEVConstant *C = dyn_cast<SCEVConstant>(Dist);
>>  if (!C) {
>> -    DEBUG(dbgs() << "LAA: Dependence because of non-constant distance\n");
>> +    DEBUG(dbgs() << "LV: Dependence because of non-constant distance\n");
>>    ShouldRetryWithRuntimeCheck = true;
>>    return true;
>>  }
>> @@ -753,7 +737,7 @@ bool MemoryDepChecker::isDependent(const
>>         ATy != BTy))
>>      return true;
>> 
>> -    DEBUG(dbgs() << "LAA: Dependence is negative: NoDep\n");
>> +    DEBUG(dbgs() << "LV: Dependence is negative: NoDep\n");
>>    return false;
>>  }
>> 
>> @@ -762,7 +746,7 @@ bool MemoryDepChecker::isDependent(const
>>  if (Val == 0) {
>>    if (ATy == BTy)
>>      return false;
>> -    DEBUG(dbgs() << "LAA: Zero dependence difference but different types\n");
>> +    DEBUG(dbgs() << "LV: Zero dependence difference but different types\n");
>>    return true;
>>  }
>> 
>> @@ -771,17 +755,17 @@ bool MemoryDepChecker::isDependent(const
>>  // Positive distance bigger than max vectorization factor.
>>  if (ATy != BTy) {
>>    DEBUG(dbgs() <<
>> -          "LAA: ReadWrite-Write positive dependency with different types\n");
>> +          "LV: ReadWrite-Write positive dependency with different types\n");
>>    return false;
>>  }
>> 
>>  unsigned Distance = (unsigned) Val.getZExtValue();
>> 
>>  // Bail out early if passed-in parameters make vectorization not feasible.
>> -  unsigned ForcedFactor = (VectorizerParams::VectorizationFactor ?
>> -                           VectorizerParams::VectorizationFactor : 1);
>> -  unsigned ForcedUnroll = (VectorizerParams::VectorizationInterleave ?
>> -                           VectorizerParams::VectorizationInterleave : 1);
>> +  unsigned ForcedFactor = (VectParams.VectorizationFactor ?
>> +                           VectParams.VectorizationFactor : 1);
>> +  unsigned ForcedUnroll = (VectParams.VectorizationInterleave ?
>> +                           VectParams.VectorizationInterleave : 1);
>> 
>>  // The distance must be bigger than the size needed for a vectorized version
>>  // of the operation and the size of the vectorized operation must not be
>> @@ -789,7 +773,7 @@ bool MemoryDepChecker::isDependent(const
>>  if (Distance < 2*TypeByteSize ||
>>      2*TypeByteSize > MaxSafeDepDistBytes ||
>>      Distance < TypeByteSize * ForcedUnroll * ForcedFactor) {
>> -    DEBUG(dbgs() << "LAA: Failure because of Positive distance "
>> +    DEBUG(dbgs() << "LV: Failure because of Positive distance "
>>        << Val.getSExtValue() << '\n');
>>    return true;
>>  }
>> @@ -802,7 +786,7 @@ bool MemoryDepChecker::isDependent(const
>>      couldPreventStoreLoadForward(Distance, TypeByteSize))
>>     return true;
>> 
>> -  DEBUG(dbgs() << "LAA: Positive distance " << Val.getSExtValue() <<
>> +  DEBUG(dbgs() << "LV: Positive distance " << Val.getSExtValue() <<
>>        " with max VF = " << MaxSafeDepDistBytes / TypeByteSize << '\n');
>> 
>>  return false;
>> @@ -847,56 +831,7 @@ bool MemoryDepChecker::areDepsSafe(Acces
>>  return true;
>> }
>> 
>> -bool LoopAccessInfo::canAnalyzeLoop() {
>> -    // We can only analyze innermost loops.
>> -  if (!TheLoop->empty()) {
>> -    emitAnalysis(LoopAccessReport() << "loop is not the innermost loop");
>> -    return false;
>> -  }
>> -
>> -  // We must have a single backedge.
>> -  if (TheLoop->getNumBackEdges() != 1) {
>> -    emitAnalysis(
>> -        LoopAccessReport() <<
>> -        "loop control flow is not understood by analyzer");
>> -    return false;
>> -  }
>> -
>> -  // We must have a single exiting block.
>> -  if (!TheLoop->getExitingBlock()) {
>> -    emitAnalysis(
>> -        LoopAccessReport() <<
>> -        "loop control flow is not understood by analyzer");
>> -    return false;
>> -  }
>> -
>> -  // We only handle bottom-tested loops, i.e. loop in which the condition is
>> -  // checked at the end of each iteration. With that we can assume that all
>> -  // instructions in the loop are executed the same number of times.
>> -  if (TheLoop->getExitingBlock() != TheLoop->getLoopLatch()) {
>> -    emitAnalysis(
>> -        LoopAccessReport() <<
>> -        "loop control flow is not understood by analyzer");
>> -    return false;
>> -  }
>> -
>> -  // We need to have a loop header.
>> -  DEBUG(dbgs() << "LAA: Found a loop: " <<
>> -        TheLoop->getHeader()->getName() << '\n');
>> -
>> -  // ScalarEvolution needs to be able to find the exit count.
>> -  const SCEV *ExitCount = SE->getBackedgeTakenCount(TheLoop);
>> -  if (ExitCount == SE->getCouldNotCompute()) {
>> -    emitAnalysis(LoopAccessReport() <<
>> -                 "could not determine number of loop iterations");
>> -    DEBUG(dbgs() << "LAA: SCEV could not compute the loop exit count.\n");
>> -    return false;
>> -  }
>> -
>> -  return true;
>> -}
>> -
>> -void LoopAccessInfo::analyzeLoop(ValueToValueMap &Strides) {
>> +bool LoopAccessInfo::canVectorizeMemory(ValueToValueMap &Strides) {
>> 
>>  typedef SmallVector<Value*, 16> ValueVector;
>>  typedef SmallPtrSet<Value*, 16> ValueSet;
>> @@ -913,7 +848,7 @@ void LoopAccessInfo::analyzeLoop(ValueTo
>>  PtrRtCheck.Need = false;
>> 
>>  const bool IsAnnotatedParallel = TheLoop->isAnnotatedParallel();
>> -  MemoryDepChecker DepChecker(SE, DL, TheLoop);
>> +  MemoryDepChecker DepChecker(SE, DL, TheLoop, VectParams);
>> 
>>  // For each block.
>>  for (Loop::block_iterator bb = TheLoop->block_begin(),
>> @@ -936,11 +871,10 @@ void LoopAccessInfo::analyzeLoop(ValueTo
>> 
>>        LoadInst *Ld = dyn_cast<LoadInst>(it);
>>        if (!Ld || (!Ld->isSimple() && !IsAnnotatedParallel)) {
>> -          emitAnalysis(LoopAccessReport(Ld)
>> +          emitAnalysis(VectorizationReport(Ld)
>>                       << "read with atomic ordering or volatile read");
>> -          DEBUG(dbgs() << "LAA: Found a non-simple load.\n");
>> -          CanVecMem = false;
>> -          return;
>> +          DEBUG(dbgs() << "LV: Found a non-simple load.\n");
>> +          return false;
>>        }
>>        NumLoads++;
>>        Loads.push_back(Ld);
>> @@ -952,17 +886,15 @@ void LoopAccessInfo::analyzeLoop(ValueTo
>>      if (it->mayWriteToMemory()) {
>>        StoreInst *St = dyn_cast<StoreInst>(it);
>>        if (!St) {
>> -          emitAnalysis(LoopAccessReport(it) <<
>> +          emitAnalysis(VectorizationReport(it) <<
>>                       "instruction cannot be vectorized");
>> -          CanVecMem = false;
>> -          return;
>> +          return false;
>>        }
>>        if (!St->isSimple() && !IsAnnotatedParallel) {
>> -          emitAnalysis(LoopAccessReport(St)
>> +          emitAnalysis(VectorizationReport(St)
>>                       << "write with atomic ordering or volatile write");
>> -          DEBUG(dbgs() << "LAA: Found a non-simple store.\n");
>> -          CanVecMem = false;
>> -          return;
>> +          DEBUG(dbgs() << "LV: Found a non-simple store.\n");
>> +          return false;
>>        }
>>        NumStores++;
>>        Stores.push_back(St);
>> @@ -977,9 +909,8 @@ void LoopAccessInfo::analyzeLoop(ValueTo
>>  // Check if we see any stores. If there are no stores, then we don't
>>  // care if the pointers are *restrict*.
>>  if (!Stores.size()) {
>> -    DEBUG(dbgs() << "LAA: Found a read-only loop!\n");
>> -    CanVecMem = true;
>> -    return;
>> +    DEBUG(dbgs() << "LV: Found a read-only loop!\n");
>> +    return true;
>>  }
>> 
>>  AccessAnalysis::DepCandidates DependentAccesses;
>> @@ -999,11 +930,10 @@ void LoopAccessInfo::analyzeLoop(ValueTo
>> 
>>    if (isUniform(Ptr)) {
>>      emitAnalysis(
>> -          LoopAccessReport(ST)
>> +          VectorizationReport(ST)
>>          << "write to a loop invariant address could not be vectorized");
>> -      DEBUG(dbgs() << "LAA: We don't allow storing to uniform addresses\n");
>> -      CanVecMem = false;
>> -      return;
>> +      DEBUG(dbgs() << "LV: We don't allow storing to uniform addresses\n");
>> +      return false;
>>    }
>> 
>>    // If we did *not* see this pointer before, insert it to  the read-write
>> @@ -1024,10 +954,9 @@ void LoopAccessInfo::analyzeLoop(ValueTo
>> 
>>  if (IsAnnotatedParallel) {
>>    DEBUG(dbgs()
>> -          << "LAA: A loop annotated parallel, ignore memory dependency "
>> +          << "LV: A loop annotated parallel, ignore memory dependency "
>>          << "checks.\n");
>> -    CanVecMem = true;
>> -    return;
>> +    return true;
>>  }
>> 
>>  for (I = Loads.begin(), IE = Loads.end(); I != IE; ++I) {
>> @@ -1061,9 +990,8 @@ void LoopAccessInfo::analyzeLoop(ValueTo
>>  // If we write (or read-write) to a single destination and there are no
>>  // other reads in this loop then is it safe to vectorize.
>>  if (NumReadWrites == 1 && NumReads == 0) {
>> -    DEBUG(dbgs() << "LAA: Found a write-only loop!\n");
>> -    CanVecMem = true;
>> -    return;
>> +    DEBUG(dbgs() << "LV: Found a write-only loop!\n");
>> +    return true;
>>  }
>> 
>>  // Build dependence sets and check whether we need a runtime pointer bounds
>> @@ -1079,7 +1007,7 @@ void LoopAccessInfo::analyzeLoop(ValueTo
>>    CanDoRT = Accesses.canCheckPtrAtRT(PtrRtCheck, NumComparisons, SE, TheLoop,
>>                                       Strides);
>> 
>> -  DEBUG(dbgs() << "LAA: We need to do " << NumComparisons <<
>> +  DEBUG(dbgs() << "LV: We need to do " << NumComparisons <<
>>        " pointer comparisons.\n");
>> 
>>  // If we only have one set of dependences to check pointers among we don't
>> @@ -1089,36 +1017,34 @@ void LoopAccessInfo::analyzeLoop(ValueTo
>> 
>>  // Check that we did not collect too many pointers or found an unsizeable
>>  // pointer.
>> -  if (!CanDoRT ||
>> -      NumComparisons > VectorizerParams::RuntimeMemoryCheckThreshold) {
>> +  if (!CanDoRT || NumComparisons > VectParams.RuntimeMemoryCheckThreshold) {
>>    PtrRtCheck.reset();
>>    CanDoRT = false;
>>  }
>> 
>>  if (CanDoRT) {
>> -    DEBUG(dbgs() << "LAA: We can perform a memory runtime check if needed.\n");
>> +    DEBUG(dbgs() << "LV: We can perform a memory runtime check if needed.\n");
>>  }
>> 
>>  if (NeedRTCheck && !CanDoRT) {
>> -    emitAnalysis(LoopAccessReport() << "cannot identify array bounds");
>> -    DEBUG(dbgs() << "LAA: We can't vectorize because we can't find " <<
>> +    emitAnalysis(VectorizationReport() << "cannot identify array bounds");
>> +    DEBUG(dbgs() << "LV: We can't vectorize because we can't find " <<
>>          "the array bounds.\n");
>>    PtrRtCheck.reset();
>> -    CanVecMem = false;
>> -    return;
>> +    return false;
>>  }
>> 
>>  PtrRtCheck.Need = NeedRTCheck;
>> 
>> -  CanVecMem = true;
>> +  bool CanVecMem = true;
>>  if (Accesses.isDependencyCheckNeeded()) {
>> -    DEBUG(dbgs() << "LAA: Checking memory dependencies\n");
>> +    DEBUG(dbgs() << "LV: Checking memory dependencies\n");
>>    CanVecMem = DepChecker.areDepsSafe(
>>        DependentAccesses, Accesses.getDependenciesToCheck(), Strides);
>>    MaxSafeDepDistBytes = DepChecker.getMaxSafeDepDistBytes();
>> 
>>    if (!CanVecMem && DepChecker.shouldRetryWithRuntimeCheck()) {
>> -      DEBUG(dbgs() << "LAA: Retrying with memory checks\n");
>> +      DEBUG(dbgs() << "LV: Retrying with memory checks\n");
>>      NeedRTCheck = true;
>> 
>>      // Clear the dependency checks. We assume they are not needed.
>> @@ -1131,20 +1057,18 @@ void LoopAccessInfo::analyzeLoop(ValueTo
>>                                         TheLoop, Strides, true);
>>      // Check that we did not collect too many pointers or found an unsizeable
>>      // pointer.
>> -      if (!CanDoRT ||
>> -          NumComparisons > VectorizerParams::RuntimeMemoryCheckThreshold) {
>> +      if (!CanDoRT || NumComparisons > VectParams.RuntimeMemoryCheckThreshold) {
>>        if (!CanDoRT && NumComparisons > 0)
>> -          emitAnalysis(LoopAccessReport()
>> +          emitAnalysis(VectorizationReport()
>>                       << "cannot check memory dependencies at runtime");
>>        else
>> -          emitAnalysis(LoopAccessReport()
>> +          emitAnalysis(VectorizationReport()
>>                       << NumComparisons << " exceeds limit of "
>> -                       << VectorizerParams::RuntimeMemoryCheckThreshold
>> +                       << VectParams.RuntimeMemoryCheckThreshold
>>                       << " dependent memory operations checked at runtime");
>> -        DEBUG(dbgs() << "LAA: Can't vectorize with memory checks\n");
>> +        DEBUG(dbgs() << "LV: Can't vectorize with memory checks\n");
>>        PtrRtCheck.reset();
>> -        CanVecMem = false;
>> -        return;
>> +        return false;
>>      }
>> 
>>      CanVecMem = true;
>> @@ -1152,11 +1076,13 @@ void LoopAccessInfo::analyzeLoop(ValueTo
>>  }
>> 
>>  if (!CanVecMem)
>> -    emitAnalysis(LoopAccessReport() <<
>> +    emitAnalysis(VectorizationReport() <<
>>                 "unsafe dependent memory operations in loop");
>> 
>> -  DEBUG(dbgs() << "LAA: We" << (NeedRTCheck ? "" : " don't") <<
>> +  DEBUG(dbgs() << "LV: We" << (NeedRTCheck ? "" : " don't") <<
>>        " need a runtime memory check.\n");
>> +
>> +  return CanVecMem;
>> }
>> 
>> bool LoopAccessInfo::blockNeedsPredication(BasicBlock *BB, Loop *TheLoop,
>> @@ -1168,12 +1094,11 @@ bool LoopAccessInfo::blockNeedsPredicati
>>  return !DT->dominates(BB, Latch);
>> }
>> 
>> -void LoopAccessInfo::emitAnalysis(LoopAccessReport &Message) {
>> -  assert(!Report && "Multiple report generated");
>> -  Report = Message;
>> +void LoopAccessInfo::emitAnalysis(VectorizationReport &Message) {
>> +  VectorizationReport::emitAnalysis(Message, TheFunction, TheLoop);
>> }
>> 
>> -bool LoopAccessInfo::isUniform(Value *V) const {
>> +bool LoopAccessInfo::isUniform(Value *V) {
>>  return (SE->isLoopInvariant(SE->getSCEV(V), TheLoop));
>> }
>> 
>> @@ -1189,7 +1114,7 @@ static Instruction *getFirstInst(Instruc
>> }
>> 
>> std::pair<Instruction *, Instruction *>
>> -LoopAccessInfo::addRuntimeCheck(Instruction *Loc) const {
>> +LoopAccessInfo::addRuntimeCheck(Instruction *Loc) {
>>  Instruction *tnullptr = nullptr;
>>  if (!PtrRtCheck.Need)
>>    return std::pair<Instruction *, Instruction *>(tnullptr, tnullptr);
>> @@ -1207,12 +1132,12 @@ LoopAccessInfo::addRuntimeCheck(Instruct
>>    const SCEV *Sc = SE->getSCEV(Ptr);
>> 
>>    if (SE->isLoopInvariant(Sc, TheLoop)) {
>> -      DEBUG(dbgs() << "LAA: Adding RT check for a loop invariant ptr:" <<
>> +      DEBUG(dbgs() << "LV: Adding RT check for a loop invariant ptr:" <<
>>            *Ptr <<"\n");
>>      Starts.push_back(Ptr);
>>      Ends.push_back(Ptr);
>>    } else {
>> -      DEBUG(dbgs() << "LAA: Adding RT check for range:" << *Ptr << '\n');
>> +      DEBUG(dbgs() << "LV: Adding RT check for range:" << *Ptr << '\n');
>>      unsigned AS = Ptr->getType()->getPointerAddressSpace();
>> 
>>      // Use this type for pointer arithmetic.
>> @@ -1272,100 +1197,3 @@ LoopAccessInfo::addRuntimeCheck(Instruct
>>  FirstInst = getFirstInst(FirstInst, Check, Loc);
>>  return std::make_pair(FirstInst, Check);
>> }
>> -
>> -LoopAccessInfo::LoopAccessInfo(Loop *L, ScalarEvolution *SE,
>> -                               const DataLayout *DL,
>> -                               const TargetLibraryInfo *TLI, AliasAnalysis *AA,
>> -                               DominatorTree *DT, ValueToValueMap &Strides)
>> -    : TheLoop(L), SE(SE), DL(DL), TLI(TLI), AA(AA), DT(DT), NumLoads(0),
>> -      NumStores(0), MaxSafeDepDistBytes(-1U), CanVecMem(false) {
>> -  if (canAnalyzeLoop())
>> -    analyzeLoop(Strides);
>> -}
>> -
>> -void LoopAccessInfo::print(raw_ostream &OS, unsigned Depth) const {
>> -  if (CanVecMem) {
>> -    if (PtrRtCheck.empty())
>> -      OS.indent(Depth) << "Memory dependences are safe\n";
>> -    else
>> -      OS.indent(Depth) << "Memory dependences are safe with run-time checks\n";
>> -  }
>> -
>> -  if (Report)
>> -    OS.indent(Depth) << "Report: " << Report->str() << "\n";
>> -
>> -  // FIXME: Print unsafe dependences
>> -
>> -  // List the pair of accesses need run-time checks to prove independence.
>> -  PtrRtCheck.print(OS, Depth);
>> -  OS << "\n";
>> -}
>> -
>> -const LoopAccessInfo &LoopAccessAnalysis::getInfo(Loop *L,
>> -                                                  ValueToValueMap &Strides) {
>> -  auto &LAI = LoopAccessInfoMap[L];
>> -
>> -#ifndef NDEBUG
>> -  assert((!LAI || LAI->NumSymbolicStrides == Strides.size()) &&
>> -         "Symbolic strides changed for loop");
>> -#endif
>> -
>> -  if (!LAI) {
>> -    LAI = llvm::make_unique<LoopAccessInfo>(L, SE, DL, TLI, AA, DT, Strides);
>> -#ifndef NDEBUG
>> -    LAI->NumSymbolicStrides = Strides.size();
>> -#endif
>> -  }
>> -  return *LAI.get();
>> -}
>> -
>> -void LoopAccessAnalysis::print(raw_ostream &OS, const Module *M) const {
>> -  LoopAccessAnalysis &LAA = *const_cast<LoopAccessAnalysis *>(this);
>> -
>> -  LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
>> -  ValueToValueMap NoSymbolicStrides;
>> -
>> -  for (Loop *TopLevelLoop : *LI)
>> -    for (Loop *L : depth_first(TopLevelLoop)) {
>> -      OS.indent(2) << L->getHeader()->getName() << ":\n";
>> -      auto &LAI = LAA.getInfo(L, NoSymbolicStrides);
>> -      LAI.print(OS, 4);
>> -    }
>> -}
>> -
>> -bool LoopAccessAnalysis::runOnFunction(Function &F) {
>> -  SE = &getAnalysis<ScalarEvolution>();
>> -  DL = F.getParent()->getDataLayout();
>> -  auto *TLIP = getAnalysisIfAvailable<TargetLibraryInfoWrapperPass>();
>> -  TLI = TLIP ? &TLIP->getTLI() : nullptr;
>> -  AA = &getAnalysis<AliasAnalysis>();
>> -  DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
>> -
>> -  return false;
>> -}
>> -
>> -void LoopAccessAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
>> -    AU.addRequired<ScalarEvolution>();
>> -    AU.addRequired<AliasAnalysis>();
>> -    AU.addRequired<DominatorTreeWrapperPass>();
>> -    AU.addRequired<LoopInfoWrapperPass>();
>> -
>> -    AU.setPreservesAll();
>> -}
>> -
>> -char LoopAccessAnalysis::ID = 0;
>> -static const char laa_name[] = "Loop Access Analysis";
>> -#define LAA_NAME "loop-accesses"
>> -
>> -INITIALIZE_PASS_BEGIN(LoopAccessAnalysis, LAA_NAME, laa_name, false, true)
>> -INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
>> -INITIALIZE_PASS_DEPENDENCY(ScalarEvolution)
>> -INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
>> -INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
>> -INITIALIZE_PASS_END(LoopAccessAnalysis, LAA_NAME, laa_name, false, true)
>> -
>> -namespace llvm {
>> -  Pass *createLAAPass() {
>> -    return new LoopAccessAnalysis();
>> -  }
>> -}
>> 
>> Modified: llvm/trunk/lib/Transforms/Scalar/Scalar.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/Scalar.cpp?rev=229650&r1=229649&r2=229650&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Transforms/Scalar/Scalar.cpp (original)
>> +++ llvm/trunk/lib/Transforms/Scalar/Scalar.cpp Wed Feb 18 02:34:47 2015
>> @@ -46,7 +46,6 @@ void llvm::initializeScalarOpts(PassRegi
>>  initializeJumpThreadingPass(Registry);
>>  initializeLICMPass(Registry);
>>  initializeLoopDeletionPass(Registry);
>> -  initializeLoopAccessAnalysisPass(Registry);
>>  initializeLoopInstSimplifyPass(Registry);
>>  initializeLoopRotatePass(Registry);
>>  initializeLoopStrengthReducePass(Registry);
>> 
>> Modified: llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp?rev=229650&r1=229649&r2=229650&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp (original)
>> +++ llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp Wed Feb 18 02:34:47 2015
>> @@ -106,19 +106,14 @@ using namespace llvm::PatternMatch;
>> STATISTIC(LoopsVectorized, "Number of loops vectorized");
>> STATISTIC(LoopsAnalyzed, "Number of loops analyzed for vectorization");
>> 
>> -static cl::opt<unsigned, true>
>> -VectorizationFactor("force-vector-width", cl::Hidden,
>> -                    cl::desc("Sets the SIMD width. Zero is autoselect."),
>> -                    cl::location(VectorizerParams::VectorizationFactor));
>> -unsigned VectorizerParams::VectorizationFactor = 0;
>> -
>> -static cl::opt<unsigned, true>
>> -VectorizationInterleave("force-vector-interleave", cl::Hidden,
>> -                        cl::desc("Sets the vectorization interleave count. "
>> -                                 "Zero is autoselect."),
>> -                        cl::location(
>> -                            VectorizerParams::VectorizationInterleave));
>> -unsigned VectorizerParams::VectorizationInterleave = 0;
>> +static cl::opt<unsigned>
>> +VectorizationFactor("force-vector-width", cl::init(0), cl::Hidden,
>> +                    cl::desc("Sets the SIMD width. Zero is autoselect."));
>> +
>> +static cl::opt<unsigned>
>> +VectorizationInterleave("force-vector-interleave", cl::init(0), cl::Hidden,
>> +                    cl::desc("Sets the vectorization interleave count. "
>> +                             "Zero is autoselect."));
>> 
>> static cl::opt<bool>
>> EnableIfConversion("enable-if-conversion", cl::init(true), cl::Hidden,
>> @@ -152,10 +147,10 @@ static const unsigned TinyTripCountUnrol
>> 
>> /// When performing memory disambiguation checks at runtime do not make more
>> /// than this number of comparisons.
>> -const unsigned VectorizerParams::RuntimeMemoryCheckThreshold = 8;
>> +static const unsigned RuntimeMemoryCheckThreshold = 8;
>> 
>> /// Maximum simd width.
>> -const unsigned VectorizerParams::MaxVectorWidth = 64;
>> +static const unsigned MaxVectorWidth = 64;
>> 
>> static cl::opt<unsigned> ForceTargetNumScalarRegs(
>>    "force-target-num-scalar-regs", cl::init(0), cl::Hidden,
>> @@ -224,21 +219,6 @@ class LoopVectorizationLegality;
>> class LoopVectorizationCostModel;
>> class LoopVectorizeHints;
>> 
>> -/// \brief This modifies LoopAccessReport to initialize message with
>> -/// loop-vectorizer-specific part.
>> -class VectorizationReport : public LoopAccessReport {
>> -public:
>> -  VectorizationReport(Instruction *I = nullptr)
>> -      : LoopAccessReport("loop not vectorized: ", I) {}
>> -
>> -  /// \brief This allows promotion of the loop-access analysis report into the
>> -  /// loop-vectorizer report.  It modifies the message to add the
>> -  /// loop-vectorizer-specific part of the message.
>> -  explicit VectorizationReport(const LoopAccessReport &R)
>> -      : LoopAccessReport(Twine("loop not vectorized: ") + R.str(),
>> -                         R.getInstr()) {}
>> -};
>> -
>> /// InnerLoopVectorizer vectorizes loops which contain only one basic
>> /// block to a specified vectorization factor (VF).
>> /// This class performs the widening of scalars into vectors, or multiple
>> @@ -567,11 +547,15 @@ public:
>>  LoopVectorizationLegality(Loop *L, ScalarEvolution *SE, const DataLayout *DL,
>>                            DominatorTree *DT, TargetLibraryInfo *TLI,
>>                            AliasAnalysis *AA, Function *F,
>> -                            const TargetTransformInfo *TTI,
>> -                            LoopAccessAnalysis *LAA)
>> +                            const TargetTransformInfo *TTI)
>>      : NumPredStores(0), TheLoop(L), SE(SE), DL(DL),
>> -        TLI(TLI), TheFunction(F), TTI(TTI), DT(DT), LAA(LAA), LAI(nullptr),
>> -        Induction(nullptr), WidestIndTy(nullptr), HasFunNoNaNAttr(false) {}
>> +        TLI(TLI), TheFunction(F), TTI(TTI), DT(DT), Induction(nullptr),
>> +        WidestIndTy(nullptr),
>> +        LAI(F, L, SE, DL, TLI, AA, DT,
>> +            LoopAccessInfo::VectorizerParams(
>> +                MaxVectorWidth, VectorizationFactor, VectorizationInterleave,
>> +                RuntimeMemoryCheckThreshold)),
>> +        HasFunNoNaNAttr(false) {}
>> 
>>  /// This enum represents the kinds of reductions that we support.
>>  enum ReductionKind {
>> @@ -756,19 +740,19 @@ public:
>>  bool isUniformAfterVectorization(Instruction* I) { return Uniforms.count(I); }
>> 
>>  /// Returns the information that we collected about runtime memory check.
>> -  const LoopAccessInfo::RuntimePointerCheck *getRuntimePointerCheck() const {
>> -    return LAI->getRuntimePointerCheck();
>> +  LoopAccessInfo::RuntimePointerCheck *getRuntimePointerCheck() {
>> +    return LAI.getRuntimePointerCheck();
>>  }
>> 
>> -  const LoopAccessInfo *getLAI() const {
>> -    return LAI;
>> +  LoopAccessInfo *getLAI() {
>> +    return &LAI;
>>  }
>> 
>>  /// This function returns the identity element (or neutral element) for
>>  /// the operation K.
>>  static Constant *getReductionIdentity(ReductionKind K, Type *Tp);
>> 
>> -  unsigned getMaxSafeDepDistBytes() { return LAI->getMaxSafeDepDistBytes(); }
>> +  unsigned getMaxSafeDepDistBytes() { return LAI.getMaxSafeDepDistBytes(); }
>> 
>>  bool hasStride(Value *V) { return StrideSet.count(V); }
>>  bool mustCheckStrides() { return !StrideSet.empty(); }
>> @@ -793,10 +777,10 @@ public:
>>    return (MaskedOp.count(I) != 0);
>>  }
>>  unsigned getNumStores() const {
>> -    return LAI->getNumStores();
>> +    return LAI.getNumStores();
>>  }
>>  unsigned getNumLoads() const {
>> -    return LAI->getNumLoads();
>> +    return LAI.getNumLoads();
>>  }
>>  unsigned getNumPredStores() const {
>>    return NumPredStores;
>> @@ -850,11 +834,9 @@ private:
>>  void collectStridedAccess(Value *LoadOrStoreInst);
>> 
>>  /// Report an analysis message to assist the user in diagnosing loops that are
>> -  /// not vectorized.  These are handled as LoopAccessReport rather than
>> -  /// VectorizationReport because the << operator of VectorizationReport returns
>> -  /// LoopAccessReport.
>> -  void emitAnalysis(const LoopAccessReport &Message) {
>> -    LoopAccessReport::emitAnalysis(Message, TheFunction, TheLoop, LV_NAME);
>> +  /// not vectorized.
>> +  void emitAnalysis(VectorizationReport &Message) {
>> +    VectorizationReport::emitAnalysis(Message, TheFunction, TheLoop);
>>  }
>> 
>>  unsigned NumPredStores;
>> @@ -873,11 +855,6 @@ private:
>>  const TargetTransformInfo *TTI;
>>  /// Dominator Tree.
>>  DominatorTree *DT;
>> -  // LoopAccess analysis.
>> -  LoopAccessAnalysis *LAA;
>> -  // And the loop-accesses info corresponding to this loop.  This pointer is
>> -  // null until canVectorizeMemory sets it up.
>> -  const LoopAccessInfo *LAI;
>> 
>>  //  ---  vectorization state --- //
>> 
>> @@ -899,7 +876,7 @@ private:
>>  /// This set holds the variables which are known to be uniform after
>>  /// vectorization.
>>  SmallPtrSet<Instruction*, 4> Uniforms;
>> -
>> +  LoopAccessInfo LAI;
>>  /// Can we assume the absence of NaNs.
>>  bool HasFunNoNaNAttr;
>> 
>> @@ -989,11 +966,9 @@ private:
>>  bool isConsecutiveLoadOrStore(Instruction *I);
>> 
>>  /// Report an analysis message to assist the user in diagnosing loops that are
>> -  /// not vectorized.  These are handled as LoopAccessReport rather than
>> -  /// VectorizationReport because the << operator of VectorizationReport returns
>> -  /// LoopAccessReport.
>> -  void emitAnalysis(const LoopAccessReport &Message) {
>> -    LoopAccessReport::emitAnalysis(Message, TheFunction, TheLoop, LV_NAME);
>> +  /// not vectorized.
>> +  void emitAnalysis(VectorizationReport &Message) {
>> +    VectorizationReport::emitAnalysis(Message, TheFunction, TheLoop);
>>  }
>> 
>>  /// Values used only by @llvm.assume calls.
>> @@ -1046,7 +1021,7 @@ class LoopVectorizeHints {
>>    bool validate(unsigned Val) {
>>      switch (Kind) {
>>      case HK_WIDTH:
>> -        return isPowerOf2_32(Val) && Val <= VectorizerParams::MaxVectorWidth;
>> +        return isPowerOf2_32(Val) && Val <= MaxVectorWidth;
>>      case HK_UNROLL:
>>        return isPowerOf2_32(Val) && Val <= MaxInterleaveFactor;
>>      case HK_FORCE:
>> @@ -1282,7 +1257,6 @@ struct LoopVectorize : public FunctionPa
>>  TargetLibraryInfo *TLI;
>>  AliasAnalysis *AA;
>>  AssumptionCache *AC;
>> -  LoopAccessAnalysis *LAA;
>>  bool DisableUnrolling;
>>  bool AlwaysVectorize;
>> 
>> @@ -1300,7 +1274,6 @@ struct LoopVectorize : public FunctionPa
>>    TLI = TLIP ? &TLIP->getTLI() : nullptr;
>>    AA = &getAnalysis<AliasAnalysis>();
>>    AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
>> -    LAA = &getAnalysis<LoopAccessAnalysis>();
>> 
>>    // Compute some weights outside of the loop over the loops. Compute this
>>    // using a BranchProbability to re-use its scaling math.
>> @@ -1411,7 +1384,7 @@ struct LoopVectorize : public FunctionPa
>>    }
>> 
>>    // Check if it is legal to vectorize the loop.
>> -    LoopVectorizationLegality LVL(L, SE, DL, DT, TLI, AA, F, TTI, LAA);
>> +    LoopVectorizationLegality LVL(L, SE, DL, DT, TLI, AA, F, TTI);
>>    if (!LVL.canVectorize()) {
>>      DEBUG(dbgs() << "LV: Not vectorizing: Cannot prove legality.\n");
>>      emitMissedWarning(F, L, Hints);
>> @@ -1516,7 +1489,6 @@ struct LoopVectorize : public FunctionPa
>>    AU.addRequired<ScalarEvolution>();
>>    AU.addRequired<TargetTransformInfoWrapperPass>();
>>    AU.addRequired<AliasAnalysis>();
>> -    AU.addRequired<LoopAccessAnalysis>();
>>    AU.addPreserved<LoopInfoWrapperPass>();
>>    AU.addPreserved<DominatorTreeWrapperPass>();
>>    AU.addPreserved<AliasAnalysis>();
>> @@ -1688,7 +1660,7 @@ int LoopVectorizationLegality::isConsecu
>> }
>> 
>> bool LoopVectorizationLegality::isUniform(Value *V) {
>> -  return LAI->isUniform(V);
>> +  return LAI.isUniform(V);
>> }
>> 
>> InnerLoopVectorizer::VectorParts&
>> @@ -3428,7 +3400,7 @@ bool LoopVectorizationLegality::canVecto
>>  collectLoopUniforms();
>> 
>>  DEBUG(dbgs() << "LV: We can vectorize this loop" <<
>> -        (LAI->getRuntimePointerCheck()->Need ? " (with a runtime bound check)" :
>> +        (LAI.getRuntimePointerCheck()->Need ? " (with a runtime bound check)" :
>>         "")
>>        <<"!\n");
>> 
>> @@ -3853,11 +3825,7 @@ void LoopVectorizationLegality::collectL
>> }
>> 
>> bool LoopVectorizationLegality::canVectorizeMemory() {
>> -  LAI = &LAA->getInfo(TheLoop, Strides);
>> -  auto &OptionalReport = LAI->getReport();
>> -  if (OptionalReport)
>> -    emitAnalysis(VectorizationReport(*OptionalReport));
>> -  return LAI->canVectorizeMemory();
>> +  return LAI.canVectorizeMemory(Strides);
>> }
>> 
>> static bool hasMultipleUsesOf(Instruction *I,
>> @@ -5032,7 +5000,6 @@ INITIALIZE_PASS_DEPENDENCY(ScalarEvoluti
>> INITIALIZE_PASS_DEPENDENCY(LCSSA)
>> INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
>> INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
>> -INITIALIZE_PASS_DEPENDENCY(LoopAccessAnalysis)
>> INITIALIZE_PASS_END(LoopVectorize, LV_NAME, lv_name, false, false)
>> 
>> namespace llvm {
>> 
>> Removed: llvm/trunk/test/Analysis/LoopAccessAnalysis/unsafe-and-rt-checks-no-dbg.ll
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/LoopAccessAnalysis/unsafe-and-rt-checks-no-dbg.ll?rev=229649&view=auto
>> ==============================================================================
>> --- llvm/trunk/test/Analysis/LoopAccessAnalysis/unsafe-and-rt-checks-no-dbg.ll (original)
>> +++ llvm/trunk/test/Analysis/LoopAccessAnalysis/unsafe-and-rt-checks-no-dbg.ll (removed)
>> @@ -1,60 +0,0 @@
>> -; RUN: opt -loop-accesses -analyze < %s | FileCheck %s
>> -
>> -; FIXME: This is the non-debug version of unsafe-and-rt-checks.ll not
>> -; requiring "asserts".  Once we can check memory dependences without -debug,
>> -; we should remove this test.
>> -
>> -; Analyze this loop:
>> -;   for (i = 0; i < n; i++)
>> -;    A[i + 1] = A[i] * B[i] * C[i];
>> -
>> -target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
>> -target triple = "x86_64-apple-macosx10.10.0"
>> -
>> -; CHECK: Report: unsafe dependent memory operations in loop
>> -
>> -; CHECK: Run-time memory checks:
>> -; CHECK-NEXT: 0:
>> -; CHECK-NEXT:   %arrayidxA_plus_2 = getelementptr inbounds i16* %a, i64 %add
>> -; CHECK-NEXT:   %arrayidxB = getelementptr inbounds i16* %b, i64 %storemerge3
>> -; CHECK-NEXT: 1:
>> -; CHECK-NEXT:   %arrayidxA_plus_2 = getelementptr inbounds i16* %a, i64 %add
>> -; CHECK-NEXT:   %arrayidxC = getelementptr inbounds i16* %c, i64 %storemerge3
>> -
>> - at n = global i32 20, align 4
>> - at B = common global i16* null, align 8
>> - at A = common global i16* null, align 8
>> - at C = common global i16* null, align 8
>> -
>> -define void @f() {
>> -entry:
>> -  %a = load i16** @A, align 8
>> -  %b = load i16** @B, align 8
>> -  %c = load i16** @C, align 8
>> -  br label %for.body
>> -
>> -for.body:                                         ; preds = %for.body, %entry
>> -  %storemerge3 = phi i64 [ 0, %entry ], [ %add, %for.body ]
>> -
>> -  %arrayidxA = getelementptr inbounds i16* %a, i64 %storemerge3
>> -  %loadA = load i16* %arrayidxA, align 2
>> -
>> -  %arrayidxB = getelementptr inbounds i16* %b, i64 %storemerge3
>> -  %loadB = load i16* %arrayidxB, align 2
>> -
>> -  %arrayidxC = getelementptr inbounds i16* %c, i64 %storemerge3
>> -  %loadC = load i16* %arrayidxC, align 2
>> -
>> -  %mul = mul i16 %loadB, %loadA
>> -  %mul1 = mul i16 %mul, %loadC
>> -
>> -  %add = add nuw nsw i64 %storemerge3, 1
>> -  %arrayidxA_plus_2 = getelementptr inbounds i16* %a, i64 %add
>> -  store i16 %mul1, i16* %arrayidxA_plus_2, align 2
>> -
>> -  %exitcond = icmp eq i64 %add, 20
>> -  br i1 %exitcond, label %for.end, label %for.body
>> -
>> -for.end:                                          ; preds = %for.body
>> -  ret void
>> -}
>> 
>> Removed: llvm/trunk/test/Analysis/LoopAccessAnalysis/unsafe-and-rt-checks.ll
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/LoopAccessAnalysis/unsafe-and-rt-checks.ll?rev=229649&view=auto
>> ==============================================================================
>> --- llvm/trunk/test/Analysis/LoopAccessAnalysis/unsafe-and-rt-checks.ll (original)
>> +++ llvm/trunk/test/Analysis/LoopAccessAnalysis/unsafe-and-rt-checks.ll (removed)
>> @@ -1,61 +0,0 @@
>> -; RUN: opt -loop-accesses -analyze < %s | FileCheck %s
>> -; RUN: opt -loop-accesses -analyze -debug-only=loop-accesses < %s 2>&1 | FileCheck %s --check-prefix=DEBUG
>> -; REQUIRES: asserts
>> -
>> -; Analyze this loop:
>> -;   for (i = 0; i < n; i++)
>> -;    A[i + 1] = A[i] * B[i] * C[i];
>> -
>> -target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
>> -target triple = "x86_64-apple-macosx10.10.0"
>> -
>> -; CHECK: Report: unsafe dependent memory operations in loop
>> -
>> -; DEBUG: LAA: Distance for   %loadA = load i16* %arrayidxA, align 2 to   store i16 %mul1, i16* %arrayidxA_plus_2, align 2: 2
>> -; DEBUG-NEXT: LAA: Failure because of Positive distance 2
>> -
>> -; CHECK: Run-time memory checks:
>> -; CHECK-NEXT: 0:
>> -; CHECK-NEXT:   %arrayidxA_plus_2 = getelementptr inbounds i16* %a, i64 %add
>> -; CHECK-NEXT:   %arrayidxB = getelementptr inbounds i16* %b, i64 %storemerge3
>> -; CHECK-NEXT: 1:
>> -; CHECK-NEXT:   %arrayidxA_plus_2 = getelementptr inbounds i16* %a, i64 %add
>> -; CHECK-NEXT:   %arrayidxC = getelementptr inbounds i16* %c, i64 %storemerge3
>> -
>> - at n = global i32 20, align 4
>> - at B = common global i16* null, align 8
>> - at A = common global i16* null, align 8
>> - at C = common global i16* null, align 8
>> -
>> -define void @f() {
>> -entry:
>> -  %a = load i16** @A, align 8
>> -  %b = load i16** @B, align 8
>> -  %c = load i16** @C, align 8
>> -  br label %for.body
>> -
>> -for.body:                                         ; preds = %for.body, %entry
>> -  %storemerge3 = phi i64 [ 0, %entry ], [ %add, %for.body ]
>> -
>> -  %arrayidxA = getelementptr inbounds i16* %a, i64 %storemerge3
>> -  %loadA = load i16* %arrayidxA, align 2
>> -
>> -  %arrayidxB = getelementptr inbounds i16* %b, i64 %storemerge3
>> -  %loadB = load i16* %arrayidxB, align 2
>> -
>> -  %arrayidxC = getelementptr inbounds i16* %c, i64 %storemerge3
>> -  %loadC = load i16* %arrayidxC, align 2
>> -
>> -  %mul = mul i16 %loadB, %loadA
>> -  %mul1 = mul i16 %mul, %loadC
>> -
>> -  %add = add nuw nsw i64 %storemerge3, 1
>> -  %arrayidxA_plus_2 = getelementptr inbounds i16* %a, i64 %add
>> -  store i16 %mul1, i16* %arrayidxA_plus_2, align 2
>> -
>> -  %exitcond = icmp eq i64 %add, 20
>> -  br i1 %exitcond, label %for.end, label %for.body
>> -
>> -for.end:                                          ; preds = %for.body
>> -  ret void
>> -}
>> 
>> 
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
> 





More information about the llvm-commits mailing list