summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Nemet <anemet@apple.com>2015-03-10 18:54:23 +0000
committerAdam Nemet <anemet@apple.com>2015-03-10 18:54:23 +0000
commitc320ed14d22f300f001662cd8c3d1538524f0e25 (patch)
tree4b4a86f6e685dce9f2ce0df113ed48064812f270
parent17c9aca8564235e939f23205839776f54082f8da (diff)
downloadllvm-c320ed14d22f300f001662cd8c3d1538524f0e25.tar.gz
[LAA-memchecks 2/3] Move number of memcheck threshold checking to LV
Now the analysis won't "fail" if the memchecks exceed the threshold. It is the transform pass' responsibility to perform the check. This allows the transform pass to further analyze/eliminate the memchecks. E.g. in Loop distribution we only need to check pointers that end up in different partitions. Note that there is a slight change of functionality here. The logic in analyzeLoop is that if dependence checking fails due to non-constant distance between the pointers, another attempt is made to prove safety of the dependences purely using run-time checks. Before this patch we could fail the loop due to exceeding the memcheck threshold after the first step, now we only check the threshold in the client after the full analysis. There is no measurable compile-time effect but I wanted to record this here. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@231817 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Analysis/LoopAccessAnalysis.h8
-rw-r--r--lib/Analysis/LoopAccessAnalysis.cpp30
-rw-r--r--lib/Transforms/Vectorize/LoopVectorize.cpp14
3 files changed, 24 insertions, 28 deletions
diff --git a/include/llvm/Analysis/LoopAccessAnalysis.h b/include/llvm/Analysis/LoopAccessAnalysis.h
index 31b0b8eb21dd..d188327fbf4f 100644
--- a/include/llvm/Analysis/LoopAccessAnalysis.h
+++ b/include/llvm/Analysis/LoopAccessAnalysis.h
@@ -362,6 +362,10 @@ public:
return &PtrRtCheck;
}
+ /// \brief Number of memchecks required to prove independence of otherwise
+ /// may-alias pointers.
+ unsigned getNumRuntimePointerChecks() const { return NumComparisons; }
+
/// Return true if the block BB needs to be predicated in order for the loop
/// to be vectorized.
static bool blockNeedsPredication(BasicBlock *BB, Loop *TheLoop,
@@ -416,6 +420,10 @@ private:
/// loop-independent and loop-carried dependences between memory accesses.
MemoryDepChecker DepChecker;
+ /// \brief Number of memchecks required to prove independence of otherwise
+ /// may-alias pointers
+ unsigned NumComparisons;
+
Loop *TheLoop;
ScalarEvolution *SE;
const DataLayout &DL;
diff --git a/lib/Analysis/LoopAccessAnalysis.cpp b/lib/Analysis/LoopAccessAnalysis.cpp
index 27ccd66541fc..d044bb008e99 100644
--- a/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/lib/Analysis/LoopAccessAnalysis.cpp
@@ -1072,7 +1072,6 @@ void LoopAccessInfo::analyzeLoop(const ValueToValueMap &Strides) {
// Find pointers with computable bounds. We are going to use this information
// to place a runtime bound check.
- unsigned NumComparisons = 0;
bool CanDoRT = false;
if (NeedRTCheck)
CanDoRT = Accesses.canCheckPtrAtRT(PtrRtCheck, NumComparisons, SE, TheLoop,
@@ -1098,17 +1097,6 @@ void LoopAccessInfo::analyzeLoop(const ValueToValueMap &Strides) {
return;
}
- if (NumComparisons > RuntimeMemoryCheckThreshold) {
- emitAnalysis(LoopAccessReport()
- << NumComparisons << " exceeds limit of "
- << RuntimeMemoryCheckThreshold
- << " dependent memory operations checked at runtime");
- DEBUG(dbgs() << "LAA: Too many memory checks needed.\n");
- PtrRtCheck.reset();
- CanVecMem = false;
- return;
- }
-
PtrRtCheck.Need = NeedRTCheck;
CanVecMem = true;
@@ -1140,18 +1128,6 @@ void LoopAccessInfo::analyzeLoop(const ValueToValueMap &Strides) {
return;
}
- // Check that we did not collect too many pointers.
- if (NumComparisons > RuntimeMemoryCheckThreshold) {
- emitAnalysis(LoopAccessReport()
- << NumComparisons << " exceeds limit of "
- << RuntimeMemoryCheckThreshold
- << " dependent memory operations checked at runtime");
- DEBUG(dbgs() << "LAA: Can't vectorize with memory checks\n");
- PtrRtCheck.reset();
- CanVecMem = false;
- return;
- }
-
CanVecMem = true;
}
}
@@ -1283,9 +1259,9 @@ LoopAccessInfo::LoopAccessInfo(Loop *L, ScalarEvolution *SE,
const TargetLibraryInfo *TLI, AliasAnalysis *AA,
DominatorTree *DT,
const ValueToValueMap &Strides)
- : DepChecker(SE, L), TheLoop(L), SE(SE), DL(DL), TLI(TLI), AA(AA),
- DT(DT), NumLoads(0), NumStores(0), MaxSafeDepDistBytes(-1U),
- CanVecMem(false) {
+ : DepChecker(SE, L), NumComparisons(0), TheLoop(L), SE(SE), DL(DL),
+ TLI(TLI), AA(AA), DT(DT), NumLoads(0), NumStores(0),
+ MaxSafeDepDistBytes(-1U), CanVecMem(false) {
if (canAnalyzeLoop())
analyzeLoop(Strides);
}
diff --git a/lib/Transforms/Vectorize/LoopVectorize.cpp b/lib/Transforms/Vectorize/LoopVectorize.cpp
index 18a456f611ae..1abefd75c97a 100644
--- a/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -3874,7 +3874,19 @@ bool LoopVectorizationLegality::canVectorizeMemory() {
auto &OptionalReport = LAI->getReport();
if (OptionalReport)
emitAnalysis(VectorizationReport(*OptionalReport));
- return LAI->canVectorizeMemory();
+ if (!LAI->canVectorizeMemory())
+ return false;
+
+ if (LAI->getNumRuntimePointerChecks() >
+ VectorizerParams::RuntimeMemoryCheckThreshold) {
+ emitAnalysis(VectorizationReport()
+ << LAI->getNumRuntimePointerChecks() << " exceeds limit of "
+ << VectorizerParams::RuntimeMemoryCheckThreshold
+ << " dependent memory operations checked at runtime");
+ DEBUG(dbgs() << "LV: Too many memory checks needed.\n");
+ return false;
+ }
+ return true;
}
static bool hasMultipleUsesOf(Instruction *I,