Index: include/llvm/Analysis/LoopAccessAnalysis.h =================================================================== --- include/llvm/Analysis/LoopAccessAnalysis.h +++ include/llvm/Analysis/LoopAccessAnalysis.h @@ -118,11 +118,14 @@ const TargetLibraryInfo *TLI, AliasAnalysis *AA, DominatorTree *DT) : TheLoop(L), SE(SE), DL(DL), TLI(TLI), AA(AA), DT(DT), NumLoads(0), - NumStores(0), MaxSafeDepDistBytes(-1U) {} + NumStores(0), MaxSafeDepDistBytes(-1U), CanVecMem(false) {} + + /// \brief Analyze the loop. Replaces symbolic strides using Strides. + void analyzeLoop(ValueToValueMap &Strides); /// Return true we can analyze the memory accesses in the loop and there are - /// no memory dependence cycles. Replaces symbolic strides using Strides. - bool canVectorizeMemory(ValueToValueMap &Strides); + /// no memory dependence cycles. + bool canVectorizeMemory() { return CanVecMem; } RuntimePointerCheck *getRuntimePointerCheck() { return &PtrRtCheck; } @@ -166,6 +169,9 @@ 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 Report; Index: lib/Analysis/LoopAccessAnalysis.cpp =================================================================== --- lib/Analysis/LoopAccessAnalysis.cpp +++ lib/Analysis/LoopAccessAnalysis.cpp @@ -812,7 +812,7 @@ return true; } -bool LoopAccessInfo::canVectorizeMemory(ValueToValueMap &Strides) { +void LoopAccessInfo::analyzeLoop(ValueToValueMap &Strides) { typedef SmallVector ValueVector; typedef SmallPtrSet ValueSet; @@ -855,7 +855,8 @@ emitAnalysis(VectorizationReport(Ld) << "read with atomic ordering or volatile read"); DEBUG(dbgs() << "LV: Found a non-simple load.\n"); - return false; + CanVecMem = false; + return; } NumLoads++; Loads.push_back(Ld); @@ -869,13 +870,15 @@ if (!St) { emitAnalysis(VectorizationReport(it) << "instruction cannot be vectorized"); - return false; + CanVecMem = false; + return; } if (!St->isSimple() && !IsAnnotatedParallel) { emitAnalysis(VectorizationReport(St) << "write with atomic ordering or volatile write"); DEBUG(dbgs() << "LV: Found a non-simple store.\n"); - return false; + CanVecMem = false; + return; } NumStores++; Stores.push_back(St); @@ -891,7 +894,8 @@ // care if the pointers are *restrict*. if (!Stores.size()) { DEBUG(dbgs() << "LV: Found a read-only loop!\n"); - return true; + CanVecMem = true; + return; } AccessAnalysis::DepCandidates DependentAccesses; @@ -914,7 +918,8 @@ VectorizationReport(ST) << "write to a loop invariant address could not be vectorized"); DEBUG(dbgs() << "LV: We don't allow storing to uniform addresses\n"); - return false; + CanVecMem = false; + return; } // If we did *not* see this pointer before, insert it to the read-write @@ -937,7 +942,8 @@ DEBUG(dbgs() << "LV: A loop annotated parallel, ignore memory dependency " << "checks.\n"); - return true; + CanVecMem = true; + return; } for (I = Loads.begin(), IE = Loads.end(); I != IE; ++I) { @@ -972,7 +978,8 @@ // other reads in this loop then is it safe to vectorize. if (NumReadWrites == 1 && NumReads == 0) { DEBUG(dbgs() << "LV: Found a write-only loop!\n"); - return true; + CanVecMem = true; + return; } // Build dependence sets and check whether we need a runtime pointer bounds @@ -1013,12 +1020,13 @@ DEBUG(dbgs() << "LV: We can't vectorize because we can't find " << "the array bounds.\n"); PtrRtCheck.reset(); - return false; + CanVecMem = false; + return; } PtrRtCheck.Need = NeedRTCheck; - bool CanVecMem = true; + CanVecMem = true; if (Accesses.isDependencyCheckNeeded()) { DEBUG(dbgs() << "LV: Checking memory dependencies\n"); CanVecMem = DepChecker.areDepsSafe( @@ -1051,7 +1059,8 @@ << " dependent memory operations checked at runtime"); DEBUG(dbgs() << "LV: Can't vectorize with memory checks\n"); PtrRtCheck.reset(); - return false; + CanVecMem = false; + return; } CanVecMem = true; @@ -1064,8 +1073,6 @@ DEBUG(dbgs() << "LV: We" << (NeedRTCheck ? "" : " don't") << " need a runtime memory check.\n"); - - return CanVecMem; } bool LoopAccessInfo::blockNeedsPredication(BasicBlock *BB) { Index: lib/Transforms/Vectorize/LoopVectorize.cpp =================================================================== --- lib/Transforms/Vectorize/LoopVectorize.cpp +++ lib/Transforms/Vectorize/LoopVectorize.cpp @@ -3826,11 +3826,11 @@ } bool LoopVectorizationLegality::canVectorizeMemory() { - bool Success = LAI.canVectorizeMemory(Strides); + LAI.analyzeLoop(Strides); auto &OptionalReport = LAI.getReport(); if (OptionalReport) emitAnalysis(*OptionalReport); - return Success; + return LAI.canVectorizeMemory(); } static bool hasMultipleUsesOf(Instruction *I,