/// memory (and not any particular access), whether it modifies or references
/// the memory, or whether it does both. The lattice goes from "NoAccess" to
/// either RefAccess or ModAccess, then to ModRefAccess as necessary.
- enum AccessLattice {
- NoAccess = 0,
- RefAccess = 1,
- ModAccess = 2,
- ModRefAccess = RefAccess | ModAccess
- };
+ typedef ModRefInfo AccessLattice;
unsigned Access : 2;
/// The kind of alias relationship between pointers of the set.
public:
/// Accessors...
- bool isRef() const { return Access & RefAccess; }
- bool isMod() const { return Access & ModAccess; }
+ bool isRef() const { return Access & MRI_Ref; }
+ bool isMod() const { return Access & MRI_Mod; }
bool isMustAlias() const { return Alias == SetMustAlias; }
bool isMayAlias() const { return Alias == SetMayAlias; }
friend struct ilist_sentinel_traits<AliasSet>;
AliasSet()
: PtrList(nullptr), PtrListEnd(&PtrList), Forward(nullptr), RefCount(0),
- Access(NoAccess), Alias(SetMustAlias), Volatile(false) {
+ Access(MRI_NoModRef), Alias(SetMustAlias), Volatile(false) {
}
AliasSet(const AliasSet &AS) = delete;
void removeFromTracker(AliasSetTracker &AST);
void addPointer(AliasSetTracker &AST, PointerRec &Entry, uint64_t Size,
- const AAMDNodes &AAInfo,
+ const AAMDNodes &AAInfo, ModRefInfo MR,
bool KnownMustAlias = false);
- void addUnknownInst(Instruction *I, AliasAnalysis &AA);
+ void addUnknownInst(Instruction *I, AliasAnalysis &AA, ModRefInfo MR);
void removeUnknownInst(AliasSetTracker &AST, Instruction *I) {
bool WasEmpty = UnknownInsts.empty();
for (size_t i = 0, e = UnknownInsts.size(); i != e; ++i)
public:
/// aliasesPointer - Return true if the specified pointer "may" (or must)
/// alias one of the members in the set.
- ///
+ /// MRcommon - if Ptr is aliased by existing UnknownInsts,
+ /// then not-null MRcommon will be set to the worst ModRefInfo met
+ ///
bool aliasesPointer(const Value *Ptr, uint64_t Size, const AAMDNodes &AAInfo,
- AliasAnalysis &AA) const;
- bool aliasesUnknownInst(const Instruction *Inst, AliasAnalysis &AA) const;
+ AliasAnalysis &AA, ModRefInfo* MRcommon = nullptr) const;
+ /// aliasesUnknownInst - Return true if the specified UnknownInst
+ /// has not-null ModRefInfo (not MRI_NoModRef) with some
+ /// pointer or UnknownInst already existing in AliasSet
+ /// MRcommon - not-null MRcommon will be set to the worst ModRefInfo met
+ ///
+ bool aliasesUnknownInst(const Instruction *Inst, AliasAnalysis &AA,
+ ModRefInfo* MRcommon = nullptr) const;
};
inline raw_ostream& operator<<(raw_ostream &OS, const AliasSet &AS) {
return AS;
}
AliasSet *findAliasSetForPointer(const Value *Ptr, uint64_t Size,
- const AAMDNodes &AAInfo);
+ const AAMDNodes &AAInfo,
+ ModRefInfo* MRcommonPtr = nullptr);
- AliasSet *findAliasSetForUnknownInst(Instruction *Inst);
+ AliasSet *findAliasSetForUnknownInst(Instruction *Inst,
+ ModRefInfo* MRcommonPtr = nullptr);
};
inline raw_ostream& operator<<(raw_ostream &OS, const AliasSetTracker &AST) {
void AliasSet::addPointer(AliasSetTracker &AST, PointerRec &Entry,
uint64_t Size, const AAMDNodes &AAInfo,
- bool KnownMustAlias) {
+ ModRefInfo MR, bool KnownMustAlias) {
assert(!Entry.hasAliasSet() && "Entry already in set!");
// Check to see if we have to downgrade to _may_ alias.
assert(Result != NoAlias && "Cannot be part of must set!");
}
+ // upgrading access if existing UnknownInst has ModRef with new pointer
+ Access |= MR;
+
Entry.setAliasSet(this);
Entry.updateSizeAndAAInfo(Size, AAInfo);
addRef(); // Entry points to alias set.
}
-void AliasSet::addUnknownInst(Instruction *I, AliasAnalysis &AA) {
+void AliasSet::addUnknownInst(Instruction *I, AliasAnalysis &AA,
+ ModRefInfo MR) {
if (UnknownInsts.empty())
addRef();
UnknownInsts.emplace_back(I);
if (!I->mayWriteToMemory()) {
Alias = SetMayAlias;
- Access |= RefAccess;
+ Access |= MRI_Ref;
return;
}
- // FIXME: This should use mod/ref information to make this not suck so bad
Alias = SetMayAlias;
- Access = ModRefAccess;
+ Access |= MR;
+}
+
+namespace {
+ /// returns true if there is no request of worst ModRefInfo
+ /// (MRcommonPtr is null)
+ /// or when achieved maximum ModRefInfo (MRI_ModRef).
+ bool processMR(ModRefInfo MR, ModRefInfo* MRcommonPtr, ModRefInfo& MRcommon) {
+ MRcommon = ModRefInfo(MRcommon | MR);
+ return !MRcommonPtr || (MRcommon == MRI_ModRef);
+ }
+ bool fillExitMR(ModRefInfo* MRcommonPtr, ModRefInfo& MRcommon) {
+ if (MRcommonPtr) *MRcommonPtr = MRcommon;
+ return MRcommon != MRI_NoModRef;
+ }
}
/// aliasesPointer - Return true if the specified pointer "may" (or must)
///
bool AliasSet::aliasesPointer(const Value *Ptr, uint64_t Size,
const AAMDNodes &AAInfo,
- AliasAnalysis &AA) const {
+ AliasAnalysis &AA,
+ ModRefInfo* MRcommonPtr) const {
if (Alias == SetMustAlias) {
assert(UnknownInsts.empty() && "Illegal must alias set!");
MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo())))
return true;
+ // to gather worst ModRefInfo
+ ModRefInfo MRcommon = MRI_NoModRef;
+
// Check the unknown instructions...
if (!UnknownInsts.empty()) {
for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i)
- if (AA.getModRefInfo(UnknownInsts[i],
- MemoryLocation(Ptr, Size, AAInfo)) != MRI_NoModRef)
- return true;
+ if (processMR(AA.getModRefInfo(UnknownInsts[i],
+ MemoryLocation(Ptr, Size, AAInfo)), MRcommonPtr, MRcommon))
+ return fillExitMR(MRcommonPtr, MRcommon);
}
- return false;
+ return fillExitMR(MRcommonPtr, MRcommon);
}
bool AliasSet::aliasesUnknownInst(const Instruction *Inst,
- AliasAnalysis &AA) const {
+ AliasAnalysis &AA,
+ ModRefInfo* MRcommonPtr) const {
if (!Inst->mayReadOrWriteMemory())
return false;
+ // to gather worst ModRefInfo
+ ModRefInfo MRcommon = MRI_NoModRef;
+
for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) {
ImmutableCallSite C1(getUnknownInst(i)), C2(Inst);
- if (!C1 || !C2 || AA.getModRefInfo(C1, C2) != MRI_NoModRef ||
- AA.getModRefInfo(C2, C1) != MRI_NoModRef)
- return true;
+ if (!C1 || !C2 ||
+ processMR(AA.getModRefInfo(C1, C2), MRcommonPtr, MRcommon) ||
+ processMR(AA.getModRefInfo(C2, C1), MRcommonPtr, MRcommon))
+ return fillExitMR(MRcommonPtr, MRcommon);
}
- for (iterator I = begin(), E = end(); I != E; ++I)
- if (AA.getModRefInfo(Inst, MemoryLocation(I.getPointer(), I.getSize(),
- I.getAAInfo())) != MRI_NoModRef)
- return true;
-
- return false;
+ for (iterator I = begin(), E = end(); I != E; ++I) {
+ ModRefInfo MR = AA.getModRefInfo(
+ Inst, MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo()));
+ if (processMR(MR, MRcommonPtr, MRcommon))
+ return fillExitMR(MRcommonPtr, MRcommon);
+ }
+ return fillExitMR(MRcommonPtr, MRcommon);
}
void AliasSetTracker::clear() {
///
AliasSet *AliasSetTracker::findAliasSetForPointer(const Value *Ptr,
uint64_t Size,
- const AAMDNodes &AAInfo) {
+ const AAMDNodes &AAInfo,
+ ModRefInfo* MRcommonPtr) {
AliasSet *FoundSet = nullptr;
for (iterator I = begin(), E = end(); I != E;) {
iterator Cur = I++;
- if (Cur->Forward || !Cur->aliasesPointer(Ptr, Size, AAInfo, AA)) continue;
+ ModRefInfo MR = MRI_NoModRef;
+ if (Cur->Forward || !Cur->aliasesPointer(Ptr, Size, AAInfo, AA, &MR))
+ continue;
+ *MRcommonPtr = ModRefInfo(*MRcommonPtr | MR);
if (!FoundSet) { // If this is the first alias set ptr can go into.
FoundSet = &*Cur; // Remember it.
return false;
}
-AliasSet *AliasSetTracker::findAliasSetForUnknownInst(Instruction *Inst) {
+AliasSet *AliasSetTracker::findAliasSetForUnknownInst(Instruction *Inst,
+ ModRefInfo* MRcommonPtr) {
AliasSet *FoundSet = nullptr;
for (iterator I = begin(), E = end(); I != E;) {
iterator Cur = I++;
- if (Cur->Forward || !Cur->aliasesUnknownInst(Inst, AA))
+ ModRefInfo MR = MRI_NoModRef;
+ if (Cur->Forward || !Cur->aliasesUnknownInst(Inst, AA, &MR))
continue;
+ *MRcommonPtr = ModRefInfo(*MRcommonPtr | MR);
if (!FoundSet) // If this is the first alias set ptr can go into.
FoundSet = &*Cur; // Remember it.
else if (!Cur->Forward) // Otherwise, we must merge the sets.
return *Entry.getAliasSet(*this)->getForwardedTarget(*this);
}
- if (AliasSet *AS = findAliasSetForPointer(Pointer, Size, AAInfo)) {
+ ModRefInfo MR = MRI_NoModRef;
+ if (AliasSet *AS = findAliasSetForPointer(Pointer, Size, AAInfo, &MR)) {
// Add it to the alias set it aliases.
- AS->addPointer(*this, Entry, Size, AAInfo);
+ AS->addPointer(*this, Entry, Size, AAInfo, MR);
return *AS;
}
if (New) *New = true;
// Otherwise create a new alias set to hold the loaded pointer.
AliasSets.push_back(new AliasSet());
- AliasSets.back().addPointer(*this, Entry, Size, AAInfo);
+ AliasSets.back().addPointer(*this, Entry, Size, AAInfo, MRI_NoModRef);
return AliasSets.back();
}
bool AliasSetTracker::add(Value *Ptr, uint64_t Size, const AAMDNodes &AAInfo) {
bool NewPtr;
- addPointer(Ptr, Size, AAInfo, AliasSet::NoAccess, NewPtr);
+ addPointer(Ptr, Size, AAInfo, MRI_NoModRef, NewPtr);
return NewPtr;
}
AAMDNodes AAInfo;
LI->getAAMetadata(AAInfo);
- AliasSet::AccessLattice Access = AliasSet::RefAccess;
+ AliasSet::AccessLattice Access = MRI_Ref;
bool NewPtr;
const DataLayout &DL = LI->getModule()->getDataLayout();
AliasSet &AS = addPointer(LI->getOperand(0),
AAMDNodes AAInfo;
SI->getAAMetadata(AAInfo);
- AliasSet::AccessLattice Access = AliasSet::ModAccess;
+ AliasSet::AccessLattice Access = MRI_Mod;
bool NewPtr;
const DataLayout &DL = SI->getModule()->getDataLayout();
Value *Val = SI->getOperand(0);
bool NewPtr;
addPointer(VAAI->getOperand(0), MemoryLocation::UnknownSize, AAInfo,
- AliasSet::ModRefAccess, NewPtr);
+ MRI_ModRef, NewPtr);
return NewPtr;
}
if (!Inst->mayReadOrWriteMemory())
return true; // doesn't alias anything
- AliasSet *AS = findAliasSetForUnknownInst(Inst);
+ ModRefInfo MR = MRI_NoModRef;
+ AliasSet *AS = findAliasSetForUnknownInst(Inst, &MR);
if (AS) {
- AS->addUnknownInst(Inst, AA);
+ AS->addUnknownInst(Inst, AA, MR);
return false;
}
AliasSets.push_back(new AliasSet());
AS = &AliasSets.back();
- AS->addUnknownInst(Inst, AA);
+ AS->addUnknownInst(Inst, AA, MR);
return true;
}
I = PointerMap.find_as(From);
AliasSet *AS = I->second->getAliasSet(*this);
AS->addPointer(*this, Entry, I->second->getSize(),
- I->second->getAAInfo(),
+ I->second->getAAInfo(), MRI_NoModRef,
true);
}
OS << " AliasSet[" << (const void*)this << ", " << RefCount << "] ";
OS << (Alias == SetMustAlias ? "must" : "may") << " alias, ";
switch (Access) {
- case NoAccess: OS << "No access "; break;
- case RefAccess: OS << "Ref "; break;
- case ModAccess: OS << "Mod "; break;
- case ModRefAccess: OS << "Mod/Ref "; break;
+ case MRI_NoModRef: OS << "No access "; break;
+ case MRI_Ref: OS << "Ref "; break;
+ case MRI_Mod: OS << "Mod "; break;
+ case MRI_ModRef: OS << "Mod/Ref "; break;
default: llvm_unreachable("Bad value for Access!");
}
if (isVolatile()) OS << "[volatile] ";