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:
Benjamin Kramer
2013-06-29 17:52:08 +00:00
parent 3298179fc1
commit 97b808bf70

View File

@ -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;