1
0
mirror of https://github.com/c64scene-ar/llvm-6502.git synced 2025-03-21 03:32:29 +00:00

two changes: 1) make AliasSet hold the list of call sites with an

assertingvh so we get a violent explosion if the pointer dangles.

2) Fix AliasSetTracker::deleteValue to remove call sites with
   by-pointer comparisons instead of by-alias queries.  Using
   findAliasSetForCallSite can cause alias sets to get merged
   when they shouldn't, and can also miss alias sets when the
   call is readonly.

 fixes PR6889, which only repros with a .c file :(


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112452 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2010-08-29 18:42:23 +00:00
parent 0de5cad74d
commit cb7f653422
3 changed files with 29 additions and 16 deletions
include/llvm/Analysis
lib
Analysis
Transforms/Scalar

@ -92,7 +92,8 @@ class AliasSet : public ilist_node<AliasSet> {
AliasSet *Forward; // Forwarding pointer.
AliasSet *Next, *Prev; // Doubly linked list of AliasSets.
std::vector<CallSite> CallSites; // All calls & invokes in this alias set.
// All calls & invokes in this alias set.
std::vector<AssertingVH<Instruction> > CallSites;
// RefCount - Number of nodes pointing to this AliasSet plus the number of
// AliasSets forwarding to it.
@ -127,6 +128,11 @@ class AliasSet : public ilist_node<AliasSet> {
removeFromTracker(AST);
}
CallSite getCallSite(unsigned i) const {
assert(i < CallSites.size());
return CallSite(CallSites[i]);
}
public:
/// Accessors...
bool isRef() const { return AccessTy & Refs; }
@ -229,7 +235,7 @@ private:
void addCallSite(CallSite CS, AliasAnalysis &AA);
void removeCallSite(CallSite CS) {
for (size_t i = 0, e = CallSites.size(); i != e; ++i)
if (CallSites[i].getInstruction() == CS.getInstruction()) {
if (CallSites[i] == CS.getInstruction()) {
CallSites[i] = CallSites.back();
CallSites.pop_back();
}

@ -116,7 +116,7 @@ void AliasSet::addPointer(AliasSetTracker &AST, PointerRec &Entry,
}
void AliasSet::addCallSite(CallSite CS, AliasAnalysis &AA) {
CallSites.push_back(CS);
CallSites.push_back(CS.getInstruction());
AliasAnalysis::ModRefBehavior Behavior = AA.getModRefBehavior(CS);
if (Behavior == AliasAnalysis::DoesNotAccessMemory)
@ -167,10 +167,11 @@ bool AliasSet::aliasesCallSite(CallSite CS, AliasAnalysis &AA) const {
if (AA.doesNotAccessMemory(CS))
return false;
for (unsigned i = 0, e = CallSites.size(); i != e; ++i)
if (AA.getModRefInfo(CallSites[i], CS) != AliasAnalysis::NoModRef ||
AA.getModRefInfo(CS, CallSites[i]) != AliasAnalysis::NoModRef)
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)
return true;
}
for (iterator I = begin(), E = end(); I != E; ++I)
if (AA.getModRefInfo(CS, I.getPointer(), I.getSize()) !=
@ -231,11 +232,10 @@ AliasSet *AliasSetTracker::findAliasSetForCallSite(CallSite CS) {
if (I->Forward || !I->aliasesCallSite(CS, AA))
continue;
if (FoundSet == 0) { // If this is the first alias set ptr can go into.
FoundSet = I; // Remember it.
} else if (!I->Forward) { // Otherwise, we must merge the sets.
if (FoundSet == 0) // If this is the first alias set ptr can go into.
FoundSet = I; // Remember it.
else if (!I->Forward) // Otherwise, we must merge the sets.
FoundSet->mergeSetIn(*I, *this); // Merge in contents.
}
}
return FoundSet;
}
@ -458,11 +458,17 @@ void AliasSetTracker::deleteValue(Value *PtrVal) {
AA.deleteValue(PtrVal);
// If this is a call instruction, remove the callsite from the appropriate
// AliasSet.
if (CallSite CS = PtrVal)
if (!AA.doesNotAccessMemory(CS))
if (AliasSet *AS = findAliasSetForCallSite(CS))
AS->removeCallSite(CS);
// AliasSet (if present).
if (CallSite CS = PtrVal) {
if (!AA.doesNotAccessMemory(CS)) {
// 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);
}
}
}
// First, look up the PointerRec for this pointer.
PointerMapType::iterator I = PointerMap.find(PtrVal);
@ -538,7 +544,7 @@ void AliasSet::print(raw_ostream &OS) const {
OS << "\n " << CallSites.size() << " Call Sites: ";
for (unsigned i = 0, e = CallSites.size(); i != e; ++i) {
if (i) OS << ", ";
WriteAsOperand(OS, CallSites[i].getCalledValue());
WriteAsOperand(OS, CallSites[i]);
}
}
OS << "\n";

@ -315,6 +315,7 @@ void LICM::SinkRegion(DomTreeNode *N) {
// If the instruction is dead, we would try to sink it because it isn't used
// in the loop, instead, just delete it.
if (isInstructionTriviallyDead(&I)) {
DEBUG(dbgs() << "LICM deleting dead inst: " << I << '\n');
++II;
CurAST->deleteValue(&I);
I.eraseFromParent();