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