mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-17 04:24:00 +00:00
LoopVectorizer: Pack MemAccessInfo pairs.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@185263 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -2864,7 +2864,8 @@ namespace {
|
|||||||
class AccessAnalysis {
|
class AccessAnalysis {
|
||||||
public:
|
public:
|
||||||
/// \brief Read or write access location.
|
/// \brief Read or write access location.
|
||||||
typedef std::pair<Value*, char> MemAccessInfo;
|
typedef PointerIntPair<Value *, 1, bool> MemAccessInfo;
|
||||||
|
typedef SmallPtrSet<MemAccessInfo, 8> MemAccessInfoSet;
|
||||||
|
|
||||||
/// \brief Set of potential dependent memory accesses.
|
/// \brief Set of potential dependent memory accesses.
|
||||||
typedef EquivalenceClasses<MemAccessInfo> DepCandidates;
|
typedef EquivalenceClasses<MemAccessInfo> DepCandidates;
|
||||||
@ -2875,14 +2876,14 @@ public:
|
|||||||
|
|
||||||
/// \brief Register a load and whether it is only read from.
|
/// \brief Register a load and whether it is only read from.
|
||||||
void addLoad(Value *Ptr, bool IsReadOnly) {
|
void addLoad(Value *Ptr, bool IsReadOnly) {
|
||||||
Accesses.insert(std::make_pair(Ptr, false));
|
Accesses.insert(MemAccessInfo(Ptr, false));
|
||||||
if (IsReadOnly)
|
if (IsReadOnly)
|
||||||
ReadOnlyPtr.insert(Ptr);
|
ReadOnlyPtr.insert(Ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Register a store.
|
/// \brief Register a store.
|
||||||
void addStore(Value *Ptr) {
|
void addStore(Value *Ptr) {
|
||||||
Accesses.insert(std::make_pair(Ptr, true));
|
Accesses.insert(MemAccessInfo(Ptr, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Check whether we can check the pointers at runtime for
|
/// \brief Check whether we can check the pointers at runtime for
|
||||||
@ -2904,7 +2905,7 @@ public:
|
|||||||
|
|
||||||
bool isDependencyCheckNeeded() { return !CheckDeps.empty(); }
|
bool isDependencyCheckNeeded() { return !CheckDeps.empty(); }
|
||||||
|
|
||||||
DenseSet<MemAccessInfo> &getDependenciesToCheck() { return CheckDeps; }
|
MemAccessInfoSet &getDependenciesToCheck() { return CheckDeps; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef SetVector<MemAccessInfo> PtrAccessSet;
|
typedef SetVector<MemAccessInfo> PtrAccessSet;
|
||||||
@ -2925,7 +2926,7 @@ private:
|
|||||||
UnderlyingObjToAccessMap ObjToLastAccess;
|
UnderlyingObjToAccessMap ObjToLastAccess;
|
||||||
|
|
||||||
/// Set of accesses that need a further dependence check.
|
/// Set of accesses that need a further dependence check.
|
||||||
DenseSet<MemAccessInfo> CheckDeps;
|
MemAccessInfoSet CheckDeps;
|
||||||
|
|
||||||
/// Set of pointers that are read only.
|
/// Set of pointers that are read only.
|
||||||
SmallPtrSet<Value*, 16> ReadOnlyPtr;
|
SmallPtrSet<Value*, 16> ReadOnlyPtr;
|
||||||
@ -2976,11 +2977,11 @@ bool AccessAnalysis::canCheckPtrAtRT(
|
|||||||
for (PtrAccessSet::iterator AI = Accesses.begin(), AE = Accesses.end();
|
for (PtrAccessSet::iterator AI = Accesses.begin(), AE = Accesses.end();
|
||||||
AI != AE; ++AI) {
|
AI != AE; ++AI) {
|
||||||
const MemAccessInfo &Access = *AI;
|
const MemAccessInfo &Access = *AI;
|
||||||
Value *Ptr = Access.first;
|
Value *Ptr = Access.getPointer();
|
||||||
bool IsWrite = Access.second;
|
bool IsWrite = Access.getInt();
|
||||||
|
|
||||||
// Just add write checks if we have both.
|
// Just add write checks if we have both.
|
||||||
if (!IsWrite && Accesses.count(std::make_pair(Ptr, true)))
|
if (!IsWrite && Accesses.count(MemAccessInfo(Ptr, true)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (IsWrite)
|
if (IsWrite)
|
||||||
@ -2993,7 +2994,7 @@ bool AccessAnalysis::canCheckPtrAtRT(
|
|||||||
unsigned DepId;
|
unsigned DepId;
|
||||||
|
|
||||||
if (IsDepCheckNeeded) {
|
if (IsDepCheckNeeded) {
|
||||||
Value *Leader = DepCands.getLeaderValue(Access).first;
|
Value *Leader = DepCands.getLeaderValue(Access).getPointer();
|
||||||
unsigned &LeaderId = DepSetId[Leader];
|
unsigned &LeaderId = DepSetId[Leader];
|
||||||
if (!LeaderId)
|
if (!LeaderId)
|
||||||
LeaderId = RunningDepId++;
|
LeaderId = RunningDepId++;
|
||||||
@ -3030,8 +3031,8 @@ void AccessAnalysis::processMemAccesses(bool UseDeferred) {
|
|||||||
PtrAccessSet &S = UseDeferred ? DeferredAccesses : Accesses;
|
PtrAccessSet &S = UseDeferred ? DeferredAccesses : Accesses;
|
||||||
for (PtrAccessSet::iterator AI = S.begin(), AE = S.end(); AI != AE; ++AI) {
|
for (PtrAccessSet::iterator AI = S.begin(), AE = S.end(); AI != AE; ++AI) {
|
||||||
const MemAccessInfo &Access = *AI;
|
const MemAccessInfo &Access = *AI;
|
||||||
Value *Ptr = Access.first;
|
Value *Ptr = Access.getPointer();
|
||||||
bool IsWrite = Access.second;
|
bool IsWrite = Access.getInt();
|
||||||
|
|
||||||
DepCands.insert(Access);
|
DepCands.insert(Access);
|
||||||
|
|
||||||
@ -3140,7 +3141,8 @@ namespace {
|
|||||||
///
|
///
|
||||||
class MemoryDepChecker {
|
class MemoryDepChecker {
|
||||||
public:
|
public:
|
||||||
typedef std::pair<Value*, char> MemAccessInfo;
|
typedef PointerIntPair<Value *, 1, bool> MemAccessInfo;
|
||||||
|
typedef SmallPtrSet<MemAccessInfo, 8> MemAccessInfoSet;
|
||||||
|
|
||||||
MemoryDepChecker(ScalarEvolution *Se, DataLayout *Dl, const Loop *L) :
|
MemoryDepChecker(ScalarEvolution *Se, DataLayout *Dl, const Loop *L) :
|
||||||
SE(Se), DL(Dl), InnermostLoop(L), AccessIdx(0) {}
|
SE(Se), DL(Dl), InnermostLoop(L), AccessIdx(0) {}
|
||||||
@ -3149,7 +3151,7 @@ public:
|
|||||||
/// of a write access.
|
/// of a write access.
|
||||||
void addAccess(StoreInst *SI) {
|
void addAccess(StoreInst *SI) {
|
||||||
Value *Ptr = SI->getPointerOperand();
|
Value *Ptr = SI->getPointerOperand();
|
||||||
Accesses[std::make_pair(Ptr, true)].push_back(AccessIdx);
|
Accesses[MemAccessInfo(Ptr, true)].push_back(AccessIdx);
|
||||||
InstMap.push_back(SI);
|
InstMap.push_back(SI);
|
||||||
++AccessIdx;
|
++AccessIdx;
|
||||||
}
|
}
|
||||||
@ -3158,7 +3160,7 @@ public:
|
|||||||
/// of a write access.
|
/// of a write access.
|
||||||
void addAccess(LoadInst *LI) {
|
void addAccess(LoadInst *LI) {
|
||||||
Value *Ptr = LI->getPointerOperand();
|
Value *Ptr = LI->getPointerOperand();
|
||||||
Accesses[std::make_pair(Ptr, false)].push_back(AccessIdx);
|
Accesses[MemAccessInfo(Ptr, false)].push_back(AccessIdx);
|
||||||
InstMap.push_back(LI);
|
InstMap.push_back(LI);
|
||||||
++AccessIdx;
|
++AccessIdx;
|
||||||
}
|
}
|
||||||
@ -3167,7 +3169,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// Only checks sets with elements in \p CheckDeps.
|
/// Only checks sets with elements in \p CheckDeps.
|
||||||
bool areDepsSafe(AccessAnalysis::DepCandidates &AccessSets,
|
bool areDepsSafe(AccessAnalysis::DepCandidates &AccessSets,
|
||||||
DenseSet<MemAccessInfo> &CheckDeps);
|
MemAccessInfoSet &CheckDeps);
|
||||||
|
|
||||||
/// \brief The maximum number of bytes of a vector register we can vectorize
|
/// \brief The maximum number of bytes of a vector register we can vectorize
|
||||||
/// the accesses safely with.
|
/// the accesses safely with.
|
||||||
@ -3331,10 +3333,10 @@ bool MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
|
|||||||
const MemAccessInfo &B, unsigned BIdx) {
|
const MemAccessInfo &B, unsigned BIdx) {
|
||||||
assert (AIdx < BIdx && "Must pass arguments in program order");
|
assert (AIdx < BIdx && "Must pass arguments in program order");
|
||||||
|
|
||||||
Value *APtr = A.first;
|
Value *APtr = A.getPointer();
|
||||||
Value *BPtr = B.first;
|
Value *BPtr = B.getPointer();
|
||||||
bool AIsWrite = A.second;
|
bool AIsWrite = A.getInt();
|
||||||
bool BIsWrite = B.second;
|
bool BIsWrite = B.getInt();
|
||||||
|
|
||||||
// Two reads are independent.
|
// Two reads are independent.
|
||||||
if (!AIsWrite && !BIsWrite)
|
if (!AIsWrite && !BIsWrite)
|
||||||
@ -3450,7 +3452,7 @@ bool MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
MemoryDepChecker::areDepsSafe(AccessAnalysis::DepCandidates &AccessSets,
|
MemoryDepChecker::areDepsSafe(AccessAnalysis::DepCandidates &AccessSets,
|
||||||
DenseSet<MemAccessInfo> &CheckDeps) {
|
MemAccessInfoSet &CheckDeps) {
|
||||||
|
|
||||||
MaxSafeDepDistBytes = -1U;
|
MaxSafeDepDistBytes = -1U;
|
||||||
while (!CheckDeps.empty()) {
|
while (!CheckDeps.empty()) {
|
||||||
@ -3492,11 +3494,6 @@ bool LoopVectorizationLegality::canVectorizeMemory() {
|
|||||||
typedef SmallVector<Value*, 16> ValueVector;
|
typedef SmallVector<Value*, 16> ValueVector;
|
||||||
typedef SmallPtrSet<Value*, 16> ValueSet;
|
typedef SmallPtrSet<Value*, 16> ValueSet;
|
||||||
|
|
||||||
// Stores a pair of memory access location and whether the access is a store
|
|
||||||
// (true) or a load (false).
|
|
||||||
typedef std::pair<Value*, char> MemAccessInfo;
|
|
||||||
typedef DenseSet<MemAccessInfo> PtrAccessSet;
|
|
||||||
|
|
||||||
// Holds the Load and Store *instructions*.
|
// Holds the Load and Store *instructions*.
|
||||||
ValueVector Loads;
|
ValueVector Loads;
|
||||||
ValueVector Stores;
|
ValueVector Stores;
|
||||||
|
Reference in New Issue
Block a user