summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/LoopAccessAnalysis.cpp
diff options
context:
space:
mode:
authorAdam Nemet <anemet@apple.com>2015-03-10 18:54:26 +0000
committerAdam Nemet <anemet@apple.com>2015-03-10 18:54:26 +0000
commitec1e2bb6a495e87fc59226b5c00fcf8d1b139919 (patch)
treef2ad91c3e91810febedebc075a42f8933a892df2 /llvm/lib/Analysis/LoopAccessAnalysis.cpp
parent98c4c5dd78f48542fb0712632fe9f4ebc0ae6da6 (diff)
downloadbcm5719-llvm-ec1e2bb6a495e87fc59226b5c00fcf8d1b139919.tar.gz
bcm5719-llvm-ec1e2bb6a495e87fc59226b5c00fcf8d1b139919.zip
[LAA-memchecks 3/3] Introduce pointer partitions for memchecks
This is the final patch that actually introduces the new parameter of partition mapping to RuntimePointerCheck::needsChecking. Another API (LAI::getInstructionsForAccess) is also exposed that helps to map pointers to instructions because ultimately we partition instructions. The WIP version of the Loop Distribution pass in D6930 has been adapted to use all this. See for example, how InstrPartitionContainer::computePartitionSetForPointers sets up the partitions using the above API and then calls to LAI::addRuntimeCheck with the pointer partitions. llvm-svn: 231818
Diffstat (limited to 'llvm/lib/Analysis/LoopAccessAnalysis.cpp')
-rw-r--r--llvm/lib/Analysis/LoopAccessAnalysis.cpp46
1 files changed, 36 insertions, 10 deletions
diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
index d044bb008e9..4bedccf8d01 100644
--- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -127,8 +127,8 @@ void LoopAccessInfo::RuntimePointerCheck::insert(
AliasSetId.push_back(ASId);
}
-bool LoopAccessInfo::RuntimePointerCheck::needsChecking(unsigned I,
- unsigned J) const {
+bool LoopAccessInfo::RuntimePointerCheck::needsChecking(
+ unsigned I, unsigned J, const SmallVectorImpl<int> *PtrPartition) const {
// No need to check if two readonly pointers intersect.
if (!IsWritePtr[I] && !IsWritePtr[J])
return false;
@@ -141,11 +141,19 @@ bool LoopAccessInfo::RuntimePointerCheck::needsChecking(unsigned I,
if (AliasSetId[I] != AliasSetId[J])
return false;
+ // If PtrPartition is set omit checks between pointers of the same partition.
+ // Partition number -1 means that the pointer is used in multiple partitions.
+ // In this case we can't omit the check.
+ if (PtrPartition && (*PtrPartition)[I] != -1 &&
+ (*PtrPartition)[I] == (*PtrPartition)[J])
+ return false;
+
return true;
}
-void LoopAccessInfo::RuntimePointerCheck::print(raw_ostream &OS,
- unsigned Depth) const {
+void LoopAccessInfo::RuntimePointerCheck::print(
+ raw_ostream &OS, unsigned Depth,
+ const SmallVectorImpl<int> *PtrPartition) const {
unsigned NumPointers = Pointers.size();
if (NumPointers == 0)
return;
@@ -154,10 +162,16 @@ void LoopAccessInfo::RuntimePointerCheck::print(raw_ostream &OS,
unsigned N = 0;
for (unsigned I = 0; I < NumPointers; ++I)
for (unsigned J = I + 1; J < NumPointers; ++J)
- if (needsChecking(I, J)) {
+ if (needsChecking(I, J, PtrPartition)) {
OS.indent(Depth) << N++ << ":\n";
- OS.indent(Depth + 2) << *Pointers[I] << "\n";
- OS.indent(Depth + 2) << *Pointers[J] << "\n";
+ OS.indent(Depth + 2) << *Pointers[I];
+ if (PtrPartition)
+ OS << " (Partition: " << (*PtrPartition)[I] << ")";
+ OS << "\n";
+ OS.indent(Depth + 2) << *Pointers[J];
+ if (PtrPartition)
+ OS << " (Partition: " << (*PtrPartition)[J] << ")";
+ OS << "\n";
}
}
@@ -835,6 +849,18 @@ bool MemoryDepChecker::areDepsSafe(DepCandidates &AccessSets,
return SafeForVectorization;
}
+SmallVector<Instruction *, 4>
+MemoryDepChecker::getInstructionsForAccess(Value *Ptr, bool isWrite) const {
+ MemAccessInfo Access(Ptr, isWrite);
+ auto &IndexVector = Accesses.find(Access)->second;
+
+ SmallVector<Instruction *, 4> Insts;
+ std::transform(IndexVector.begin(), IndexVector.end(),
+ std::back_inserter(Insts),
+ [&](unsigned Idx) { return this->InstMap[Idx]; });
+ return Insts;
+}
+
const char *MemoryDepChecker::Dependence::DepName[] = {
"NoDep", "Unknown", "Forward", "ForwardButPreventsForwarding", "Backward",
"BackwardVectorizable", "BackwardVectorizableButPreventsForwarding"};
@@ -1169,8 +1195,8 @@ static Instruction *getFirstInst(Instruction *FirstInst, Value *V,
return nullptr;
}
-std::pair<Instruction *, Instruction *>
-LoopAccessInfo::addRuntimeCheck(Instruction *Loc) const {
+std::pair<Instruction *, Instruction *> LoopAccessInfo::addRuntimeCheck(
+ Instruction *Loc, const SmallVectorImpl<int> *PtrPartition) const {
Instruction *tnullptr = nullptr;
if (!PtrRtCheck.Need)
return std::pair<Instruction *, Instruction *>(tnullptr, tnullptr);
@@ -1211,7 +1237,7 @@ LoopAccessInfo::addRuntimeCheck(Instruction *Loc) const {
Value *MemoryRuntimeCheck = nullptr;
for (unsigned i = 0; i < NumPointers; ++i) {
for (unsigned j = i+1; j < NumPointers; ++j) {
- if (!PtrRtCheck.needsChecking(i, j))
+ if (!PtrRtCheck.needsChecking(i, j, PtrPartition))
continue;
unsigned AS0 = Starts[i]->getType()->getPointerAddressSpace();
OpenPOWER on IntegriCloud