mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-21 21:29:41 +00:00
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@231818 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c320ed14d2
commit
86dbc2b6d3
@ -231,6 +231,10 @@ public:
|
|||||||
return InstMap;
|
return InstMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Find the set of instructions that read or write via \p Ptr.
|
||||||
|
SmallVector<Instruction *, 4> getInstructionsForAccess(Value *Ptr,
|
||||||
|
bool isWrite) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ScalarEvolution *SE;
|
ScalarEvolution *SE;
|
||||||
const Loop *InnermostLoop;
|
const Loop *InnermostLoop;
|
||||||
@ -328,10 +332,20 @@ public:
|
|||||||
|
|
||||||
/// \brief Decide whether we need to issue a run-time check for pointer at
|
/// \brief Decide whether we need to issue a run-time check for pointer at
|
||||||
/// index \p I and \p J to prove their independence.
|
/// index \p I and \p J to prove their independence.
|
||||||
bool needsChecking(unsigned I, unsigned J) const;
|
///
|
||||||
|
/// If \p PtrPartition is set, it contains the partition number for
|
||||||
|
/// pointers (-1 if the pointer belongs to multiple partitions). In this
|
||||||
|
/// case omit checks between pointers belonging to the same partition.
|
||||||
|
bool needsChecking(unsigned I, unsigned J,
|
||||||
|
const SmallVectorImpl<int> *PtrPartition) const;
|
||||||
|
|
||||||
/// \brief Print the list run-time memory checks necessary.
|
/// \brief Print the list run-time memory checks necessary.
|
||||||
void print(raw_ostream &OS, unsigned Depth = 0) const;
|
///
|
||||||
|
/// If \p PtrPartition is set, it contains the partition number for
|
||||||
|
/// pointers (-1 if the pointer belongs to multiple partitions). In this
|
||||||
|
/// case omit checks between pointers belonging to the same partition.
|
||||||
|
void print(raw_ostream &OS, unsigned Depth = 0,
|
||||||
|
const SmallVectorImpl<int> *PtrPartition = nullptr) const;
|
||||||
|
|
||||||
/// This flag indicates if we need to add the runtime check.
|
/// This flag indicates if we need to add the runtime check.
|
||||||
bool Need;
|
bool Need;
|
||||||
@ -383,8 +397,13 @@ public:
|
|||||||
/// Returns a pair of instructions where the first element is the first
|
/// Returns a pair of instructions where the first element is the first
|
||||||
/// instruction generated in possibly a sequence of instructions and the
|
/// instruction generated in possibly a sequence of instructions and the
|
||||||
/// second value is the final comparator value or NULL if no check is needed.
|
/// second value is the final comparator value or NULL if no check is needed.
|
||||||
|
///
|
||||||
|
/// If \p PtrPartition is set, it contains the partition number for pointers
|
||||||
|
/// (-1 if the pointer belongs to multiple partitions). In this case omit
|
||||||
|
/// checks between pointers belonging to the same partition.
|
||||||
std::pair<Instruction *, Instruction *>
|
std::pair<Instruction *, Instruction *>
|
||||||
addRuntimeCheck(Instruction *Loc) const;
|
addRuntimeCheck(Instruction *Loc,
|
||||||
|
const SmallVectorImpl<int> *PtrPartition = nullptr) const;
|
||||||
|
|
||||||
/// \brief The diagnostics report generated for the analysis. E.g. why we
|
/// \brief The diagnostics report generated for the analysis. E.g. why we
|
||||||
/// couldn't analyze the loop.
|
/// couldn't analyze the loop.
|
||||||
@ -394,6 +413,13 @@ public:
|
|||||||
/// loop-independent and loop-carried dependences between memory accesses.
|
/// loop-independent and loop-carried dependences between memory accesses.
|
||||||
const MemoryDepChecker &getDepChecker() const { return DepChecker; }
|
const MemoryDepChecker &getDepChecker() const { return DepChecker; }
|
||||||
|
|
||||||
|
/// \brief Return the list of instructions that use \p Ptr to read or write
|
||||||
|
/// memory.
|
||||||
|
SmallVector<Instruction *, 4> getInstructionsForAccess(Value *Ptr,
|
||||||
|
bool isWrite) const {
|
||||||
|
return DepChecker.getInstructionsForAccess(Ptr, isWrite);
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief Print the information about the memory accesses in the loop.
|
/// \brief Print the information about the memory accesses in the loop.
|
||||||
void print(raw_ostream &OS, unsigned Depth = 0) const;
|
void print(raw_ostream &OS, unsigned Depth = 0) const;
|
||||||
|
|
||||||
|
@ -127,8 +127,8 @@ void LoopAccessInfo::RuntimePointerCheck::insert(
|
|||||||
AliasSetId.push_back(ASId);
|
AliasSetId.push_back(ASId);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LoopAccessInfo::RuntimePointerCheck::needsChecking(unsigned I,
|
bool LoopAccessInfo::RuntimePointerCheck::needsChecking(
|
||||||
unsigned J) const {
|
unsigned I, unsigned J, const SmallVectorImpl<int> *PtrPartition) const {
|
||||||
// No need to check if two readonly pointers intersect.
|
// No need to check if two readonly pointers intersect.
|
||||||
if (!IsWritePtr[I] && !IsWritePtr[J])
|
if (!IsWritePtr[I] && !IsWritePtr[J])
|
||||||
return false;
|
return false;
|
||||||
@ -141,11 +141,19 @@ bool LoopAccessInfo::RuntimePointerCheck::needsChecking(unsigned I,
|
|||||||
if (AliasSetId[I] != AliasSetId[J])
|
if (AliasSetId[I] != AliasSetId[J])
|
||||||
return false;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoopAccessInfo::RuntimePointerCheck::print(raw_ostream &OS,
|
void LoopAccessInfo::RuntimePointerCheck::print(
|
||||||
unsigned Depth) const {
|
raw_ostream &OS, unsigned Depth,
|
||||||
|
const SmallVectorImpl<int> *PtrPartition) const {
|
||||||
unsigned NumPointers = Pointers.size();
|
unsigned NumPointers = Pointers.size();
|
||||||
if (NumPointers == 0)
|
if (NumPointers == 0)
|
||||||
return;
|
return;
|
||||||
@ -154,10 +162,16 @@ void LoopAccessInfo::RuntimePointerCheck::print(raw_ostream &OS,
|
|||||||
unsigned N = 0;
|
unsigned N = 0;
|
||||||
for (unsigned I = 0; I < NumPointers; ++I)
|
for (unsigned I = 0; I < NumPointers; ++I)
|
||||||
for (unsigned J = I + 1; J < NumPointers; ++J)
|
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) << N++ << ":\n";
|
||||||
OS.indent(Depth + 2) << *Pointers[I] << "\n";
|
OS.indent(Depth + 2) << *Pointers[I];
|
||||||
OS.indent(Depth + 2) << *Pointers[J] << "\n";
|
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;
|
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[] = {
|
const char *MemoryDepChecker::Dependence::DepName[] = {
|
||||||
"NoDep", "Unknown", "Forward", "ForwardButPreventsForwarding", "Backward",
|
"NoDep", "Unknown", "Forward", "ForwardButPreventsForwarding", "Backward",
|
||||||
"BackwardVectorizable", "BackwardVectorizableButPreventsForwarding"};
|
"BackwardVectorizable", "BackwardVectorizableButPreventsForwarding"};
|
||||||
@ -1169,8 +1195,8 @@ static Instruction *getFirstInst(Instruction *FirstInst, Value *V,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<Instruction *, Instruction *>
|
std::pair<Instruction *, Instruction *> LoopAccessInfo::addRuntimeCheck(
|
||||||
LoopAccessInfo::addRuntimeCheck(Instruction *Loc) const {
|
Instruction *Loc, const SmallVectorImpl<int> *PtrPartition) const {
|
||||||
Instruction *tnullptr = nullptr;
|
Instruction *tnullptr = nullptr;
|
||||||
if (!PtrRtCheck.Need)
|
if (!PtrRtCheck.Need)
|
||||||
return std::pair<Instruction *, Instruction *>(tnullptr, tnullptr);
|
return std::pair<Instruction *, Instruction *>(tnullptr, tnullptr);
|
||||||
@ -1211,7 +1237,7 @@ LoopAccessInfo::addRuntimeCheck(Instruction *Loc) const {
|
|||||||
Value *MemoryRuntimeCheck = nullptr;
|
Value *MemoryRuntimeCheck = nullptr;
|
||||||
for (unsigned i = 0; i < NumPointers; ++i) {
|
for (unsigned i = 0; i < NumPointers; ++i) {
|
||||||
for (unsigned j = i+1; j < NumPointers; ++j) {
|
for (unsigned j = i+1; j < NumPointers; ++j) {
|
||||||
if (!PtrRtCheck.needsChecking(i, j))
|
if (!PtrRtCheck.needsChecking(i, j, PtrPartition))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
unsigned AS0 = Starts[i]->getType()->getPointerAddressSpace();
|
unsigned AS0 = Starts[i]->getType()->getPointerAddressSpace();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user