mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
Fix AliasSetTracker so that it doesn't make any assumptions about instructions it doesn't know about (like the atomic instructions I'm adding).
llvm-svn: 136198
This commit is contained in:
parent
bff9934d9a
commit
2da127e60a
@ -111,8 +111,8 @@ class AliasSet : public ilist_node<AliasSet> {
|
||||
AliasSet *Forward; // Forwarding pointer.
|
||||
AliasSet *Next, *Prev; // Doubly linked list of AliasSets.
|
||||
|
||||
// All calls & invokes in this alias set.
|
||||
std::vector<AssertingVH<Instruction> > CallSites;
|
||||
// All instructions without a specific address in this alias set.
|
||||
std::vector<AssertingVH<Instruction> > UnknownInsts;
|
||||
|
||||
// RefCount - Number of nodes pointing to this AliasSet plus the number of
|
||||
// AliasSets forwarding to it.
|
||||
@ -147,9 +147,9 @@ class AliasSet : public ilist_node<AliasSet> {
|
||||
removeFromTracker(AST);
|
||||
}
|
||||
|
||||
CallSite getCallSite(unsigned i) const {
|
||||
assert(i < CallSites.size());
|
||||
return CallSite(CallSites[i]);
|
||||
Instruction *getUnknownInst(unsigned i) const {
|
||||
assert(i < UnknownInsts.size());
|
||||
return UnknownInsts[i];
|
||||
}
|
||||
|
||||
public:
|
||||
@ -253,12 +253,12 @@ private:
|
||||
void addPointer(AliasSetTracker &AST, PointerRec &Entry, uint64_t Size,
|
||||
const MDNode *TBAAInfo,
|
||||
bool KnownMustAlias = false);
|
||||
void addCallSite(CallSite CS, AliasAnalysis &AA);
|
||||
void removeCallSite(CallSite CS) {
|
||||
for (size_t i = 0, e = CallSites.size(); i != e; ++i)
|
||||
if (CallSites[i] == CS.getInstruction()) {
|
||||
CallSites[i] = CallSites.back();
|
||||
CallSites.pop_back();
|
||||
void addUnknownInst(Instruction *I, AliasAnalysis &AA);
|
||||
void removeUnknownInst(Instruction *I) {
|
||||
for (size_t i = 0, e = UnknownInsts.size(); i != e; ++i)
|
||||
if (UnknownInsts[i] == I) {
|
||||
UnknownInsts[i] = UnknownInsts.back();
|
||||
UnknownInsts.pop_back();
|
||||
--i; --e; // Revisit the moved entry.
|
||||
}
|
||||
}
|
||||
@ -269,7 +269,7 @@ private:
|
||||
///
|
||||
bool aliasesPointer(const Value *Ptr, uint64_t Size, const MDNode *TBAAInfo,
|
||||
AliasAnalysis &AA) const;
|
||||
bool aliasesCallSite(CallSite CS, AliasAnalysis &AA) const;
|
||||
bool aliasesUnknownInst(Instruction *Inst, AliasAnalysis &AA) const;
|
||||
};
|
||||
|
||||
inline raw_ostream& operator<<(raw_ostream &OS, const AliasSet &AS) {
|
||||
@ -326,12 +326,10 @@ public:
|
||||
bool add(LoadInst *LI);
|
||||
bool add(StoreInst *SI);
|
||||
bool add(VAArgInst *VAAI);
|
||||
bool add(CallSite CS); // Call/Invoke instructions
|
||||
bool add(CallInst *CI) { return add(CallSite(CI)); }
|
||||
bool add(InvokeInst *II) { return add(CallSite(II)); }
|
||||
bool add(Instruction *I); // Dispatch to one of the other add methods...
|
||||
void add(BasicBlock &BB); // Add all instructions in basic block
|
||||
void add(const AliasSetTracker &AST); // Add alias relations from another AST
|
||||
bool addUnknown(Instruction *I);
|
||||
|
||||
/// remove methods - These methods are used to remove all entries that might
|
||||
/// be aliased by the specified instruction. These methods return true if any
|
||||
@ -341,11 +339,9 @@ public:
|
||||
bool remove(LoadInst *LI);
|
||||
bool remove(StoreInst *SI);
|
||||
bool remove(VAArgInst *VAAI);
|
||||
bool remove(CallSite CS);
|
||||
bool remove(CallInst *CI) { return remove(CallSite(CI)); }
|
||||
bool remove(InvokeInst *II) { return remove(CallSite(II)); }
|
||||
bool remove(Instruction *I);
|
||||
void remove(AliasSet &AS);
|
||||
bool removeUnknown(Instruction *I);
|
||||
|
||||
void clear();
|
||||
|
||||
@ -429,7 +425,7 @@ private:
|
||||
AliasSet *findAliasSetForPointer(const Value *Ptr, uint64_t Size,
|
||||
const MDNode *TBAAInfo);
|
||||
|
||||
AliasSet *findAliasSetForCallSite(CallSite CS);
|
||||
AliasSet *findAliasSetForUnknownInst(Instruction *Inst);
|
||||
};
|
||||
|
||||
inline raw_ostream& operator<<(raw_ostream &OS, const AliasSetTracker &AST) {
|
||||
|
@ -223,6 +223,13 @@ public:
|
||||
///
|
||||
bool mayReadFromMemory() const;
|
||||
|
||||
/// mayReadOrWriteMemory - Return true if this instruction may read or
|
||||
/// write memory.
|
||||
///
|
||||
bool mayReadOrWriteMemory() const {
|
||||
return mayReadFromMemory() || mayWriteToMemory();
|
||||
}
|
||||
|
||||
/// mayThrow - Return true if this instruction may throw an exception.
|
||||
///
|
||||
bool mayThrow() const;
|
||||
|
@ -56,12 +56,12 @@ void AliasSet::mergeSetIn(AliasSet &AS, AliasSetTracker &AST) {
|
||||
AliasTy = MayAlias;
|
||||
}
|
||||
|
||||
if (CallSites.empty()) { // Merge call sites...
|
||||
if (!AS.CallSites.empty())
|
||||
std::swap(CallSites, AS.CallSites);
|
||||
} else if (!AS.CallSites.empty()) {
|
||||
CallSites.insert(CallSites.end(), AS.CallSites.begin(), AS.CallSites.end());
|
||||
AS.CallSites.clear();
|
||||
if (UnknownInsts.empty()) { // Merge call sites...
|
||||
if (!AS.UnknownInsts.empty())
|
||||
std::swap(UnknownInsts, AS.UnknownInsts);
|
||||
} else if (!AS.UnknownInsts.empty()) {
|
||||
UnknownInsts.insert(UnknownInsts.end(), AS.UnknownInsts.begin(), AS.UnknownInsts.end());
|
||||
AS.UnknownInsts.clear();
|
||||
}
|
||||
|
||||
AS.Forward = this; // Forward across AS now...
|
||||
@ -123,13 +123,12 @@ void AliasSet::addPointer(AliasSetTracker &AST, PointerRec &Entry,
|
||||
addRef(); // Entry points to alias set.
|
||||
}
|
||||
|
||||
void AliasSet::addCallSite(CallSite CS, AliasAnalysis &AA) {
|
||||
CallSites.push_back(CS.getInstruction());
|
||||
void AliasSet::addUnknownInst(Instruction *I, AliasAnalysis &AA) {
|
||||
UnknownInsts.push_back(I);
|
||||
|
||||
AliasAnalysis::ModRefBehavior Behavior = AA.getModRefBehavior(CS);
|
||||
if (Behavior == AliasAnalysis::DoesNotAccessMemory)
|
||||
if (!I->mayReadOrWriteMemory())
|
||||
return;
|
||||
if (AliasAnalysis::onlyReadsMemory(Behavior)) {
|
||||
if (!I->mayWriteToMemory()) {
|
||||
AliasTy = MayAlias;
|
||||
AccessTy |= Refs;
|
||||
return;
|
||||
@ -147,7 +146,7 @@ bool AliasSet::aliasesPointer(const Value *Ptr, uint64_t Size,
|
||||
const MDNode *TBAAInfo,
|
||||
AliasAnalysis &AA) const {
|
||||
if (AliasTy == MustAlias) {
|
||||
assert(CallSites.empty() && "Illegal must alias set!");
|
||||
assert(UnknownInsts.empty() && "Illegal must alias set!");
|
||||
|
||||
// If this is a set of MustAliases, only check to see if the pointer aliases
|
||||
// SOME value in the set.
|
||||
@ -167,10 +166,10 @@ bool AliasSet::aliasesPointer(const Value *Ptr, uint64_t Size,
|
||||
I.getTBAAInfo())))
|
||||
return true;
|
||||
|
||||
// Check the call sites list and invoke list...
|
||||
if (!CallSites.empty()) {
|
||||
for (unsigned i = 0, e = CallSites.size(); i != e; ++i)
|
||||
if (AA.getModRefInfo(CallSites[i],
|
||||
// Check the unknown instructions...
|
||||
if (!UnknownInsts.empty()) {
|
||||
for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i)
|
||||
if (AA.getModRefInfo(UnknownInsts[i],
|
||||
AliasAnalysis::Location(Ptr, Size, TBAAInfo)) !=
|
||||
AliasAnalysis::NoModRef)
|
||||
return true;
|
||||
@ -179,18 +178,20 @@ bool AliasSet::aliasesPointer(const Value *Ptr, uint64_t Size,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AliasSet::aliasesCallSite(CallSite CS, AliasAnalysis &AA) const {
|
||||
if (AA.doesNotAccessMemory(CS))
|
||||
bool AliasSet::aliasesUnknownInst(Instruction *Inst, AliasAnalysis &AA) const {
|
||||
if (!Inst->mayReadOrWriteMemory())
|
||||
return false;
|
||||
|
||||
for (unsigned i = 0, e = CallSites.size(); i != e; ++i) {
|
||||
if (AA.getModRefInfo(getCallSite(i), CS) != AliasAnalysis::NoModRef ||
|
||||
AA.getModRefInfo(CS, getCallSite(i)) != AliasAnalysis::NoModRef)
|
||||
for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) {
|
||||
CallSite C1 = getUnknownInst(i), C2 = Inst;
|
||||
if (!C1 || !C2 ||
|
||||
AA.getModRefInfo(getUnknownInst(i), Inst) != AliasAnalysis::NoModRef ||
|
||||
AA.getModRefInfo(Inst, getUnknownInst(i)) != AliasAnalysis::NoModRef)
|
||||
return true;
|
||||
}
|
||||
|
||||
for (iterator I = begin(), E = end(); I != E; ++I)
|
||||
if (AA.getModRefInfo(CS, I.getPointer(), I.getSize()) !=
|
||||
if (AA.getModRefInfo(Inst, I.getPointer(), I.getSize()) !=
|
||||
AliasAnalysis::NoModRef)
|
||||
return true;
|
||||
|
||||
@ -244,10 +245,10 @@ bool AliasSetTracker::containsPointer(Value *Ptr, uint64_t Size,
|
||||
|
||||
|
||||
|
||||
AliasSet *AliasSetTracker::findAliasSetForCallSite(CallSite CS) {
|
||||
AliasSet *AliasSetTracker::findAliasSetForUnknownInst(Instruction *Inst) {
|
||||
AliasSet *FoundSet = 0;
|
||||
for (iterator I = begin(), E = end(); I != E; ++I) {
|
||||
if (I->Forward || !I->aliasesCallSite(CS, AA))
|
||||
if (I->Forward || !I->aliasesUnknownInst(Inst, AA))
|
||||
continue;
|
||||
|
||||
if (FoundSet == 0) // If this is the first alias set ptr can go into.
|
||||
@ -325,20 +326,20 @@ bool AliasSetTracker::add(VAArgInst *VAAI) {
|
||||
}
|
||||
|
||||
|
||||
bool AliasSetTracker::add(CallSite CS) {
|
||||
if (isa<DbgInfoIntrinsic>(CS.getInstruction()))
|
||||
bool AliasSetTracker::addUnknown(Instruction *Inst) {
|
||||
if (isa<DbgInfoIntrinsic>(Inst))
|
||||
return true; // Ignore DbgInfo Intrinsics.
|
||||
if (AA.doesNotAccessMemory(CS))
|
||||
if (!Inst->mayReadOrWriteMemory())
|
||||
return true; // doesn't alias anything
|
||||
|
||||
AliasSet *AS = findAliasSetForCallSite(CS);
|
||||
AliasSet *AS = findAliasSetForUnknownInst(Inst);
|
||||
if (AS) {
|
||||
AS->addCallSite(CS, AA);
|
||||
AS->addUnknownInst(Inst, AA);
|
||||
return false;
|
||||
}
|
||||
AliasSets.push_back(new AliasSet());
|
||||
AS = &AliasSets.back();
|
||||
AS->addCallSite(CS, AA);
|
||||
AS->addUnknownInst(Inst, AA);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -348,13 +349,9 @@ bool AliasSetTracker::add(Instruction *I) {
|
||||
return add(LI);
|
||||
if (StoreInst *SI = dyn_cast<StoreInst>(I))
|
||||
return add(SI);
|
||||
if (CallInst *CI = dyn_cast<CallInst>(I))
|
||||
return add(CI);
|
||||
if (InvokeInst *II = dyn_cast<InvokeInst>(I))
|
||||
return add(II);
|
||||
if (VAArgInst *VAAI = dyn_cast<VAArgInst>(I))
|
||||
return add(VAAI);
|
||||
return true;
|
||||
return addUnknown(I);
|
||||
}
|
||||
|
||||
void AliasSetTracker::add(BasicBlock &BB) {
|
||||
@ -375,8 +372,8 @@ void AliasSetTracker::add(const AliasSetTracker &AST) {
|
||||
AliasSet &AS = const_cast<AliasSet&>(*I);
|
||||
|
||||
// If there are any call sites in the alias set, add them to this AST.
|
||||
for (unsigned i = 0, e = AS.CallSites.size(); i != e; ++i)
|
||||
add(AS.CallSites[i]);
|
||||
for (unsigned i = 0, e = AS.UnknownInsts.size(); i != e; ++i)
|
||||
add(AS.UnknownInsts[i]);
|
||||
|
||||
// Loop over all of the pointers in this alias set.
|
||||
bool X;
|
||||
@ -393,7 +390,7 @@ void AliasSetTracker::add(const AliasSetTracker &AST) {
|
||||
/// tracker.
|
||||
void AliasSetTracker::remove(AliasSet &AS) {
|
||||
// Drop all call sites.
|
||||
AS.CallSites.clear();
|
||||
AS.UnknownInsts.clear();
|
||||
|
||||
// Clear the alias set.
|
||||
unsigned NumRefs = 0;
|
||||
@ -453,11 +450,11 @@ bool AliasSetTracker::remove(VAArgInst *VAAI) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AliasSetTracker::remove(CallSite CS) {
|
||||
if (AA.doesNotAccessMemory(CS))
|
||||
bool AliasSetTracker::removeUnknown(Instruction *I) {
|
||||
if (!I->mayReadOrWriteMemory())
|
||||
return false; // doesn't alias anything
|
||||
|
||||
AliasSet *AS = findAliasSetForCallSite(CS);
|
||||
AliasSet *AS = findAliasSetForUnknownInst(I);
|
||||
if (!AS) return false;
|
||||
remove(*AS);
|
||||
return true;
|
||||
@ -469,11 +466,9 @@ bool AliasSetTracker::remove(Instruction *I) {
|
||||
return remove(LI);
|
||||
if (StoreInst *SI = dyn_cast<StoreInst>(I))
|
||||
return remove(SI);
|
||||
if (CallInst *CI = dyn_cast<CallInst>(I))
|
||||
return remove(CI);
|
||||
if (VAArgInst *VAAI = dyn_cast<VAArgInst>(I))
|
||||
return remove(VAAI);
|
||||
return true;
|
||||
return removeUnknown(I);
|
||||
}
|
||||
|
||||
|
||||
@ -488,13 +483,13 @@ void AliasSetTracker::deleteValue(Value *PtrVal) {
|
||||
|
||||
// If this is a call instruction, remove the callsite from the appropriate
|
||||
// AliasSet (if present).
|
||||
if (CallSite CS = PtrVal) {
|
||||
if (!AA.doesNotAccessMemory(CS)) {
|
||||
if (Instruction *Inst = dyn_cast<Instruction>(PtrVal)) {
|
||||
if (Inst->mayReadOrWriteMemory()) {
|
||||
// Scan all the alias sets to see if this call site is contained.
|
||||
for (iterator I = begin(), E = end(); I != E; ++I) {
|
||||
if (I->Forward) continue;
|
||||
|
||||
I->removeCallSite(CS);
|
||||
I->removeUnknownInst(Inst);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -571,11 +566,11 @@ void AliasSet::print(raw_ostream &OS) const {
|
||||
OS << ", " << I.getSize() << ")";
|
||||
}
|
||||
}
|
||||
if (!CallSites.empty()) {
|
||||
OS << "\n " << CallSites.size() << " Call Sites: ";
|
||||
for (unsigned i = 0, e = CallSites.size(); i != e; ++i) {
|
||||
if (!UnknownInsts.empty()) {
|
||||
OS << "\n " << UnknownInsts.size() << " Unknown instructions: ";
|
||||
for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) {
|
||||
if (i) OS << ", ";
|
||||
WriteAsOperand(OS, CallSites[i]);
|
||||
WriteAsOperand(OS, UnknownInsts[i]);
|
||||
}
|
||||
}
|
||||
OS << "\n";
|
||||
|
Loading…
Reference in New Issue
Block a user