Fix AliasSetTracker so that it doesn't make any assumptions about instructions it doesn't know about (like the atomic instructions I'm adding).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@136198 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eli Friedman 2011-07-27 00:46:46 +00:00
parent bd27f5adbd
commit 6f3ba37ebb
3 changed files with 68 additions and 70 deletions

View File

@ -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) {

View File

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

View File

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