//===- AliasSetTracker.cpp - Alias Sets Tracker implementation-------------===//
-//
+//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
// This file implements the AliasSetTracker and AliasSet classes.
-//
+//
//===----------------------------------------------------------------------===//
#include "llvm/Analysis/AliasSetTracker.h"
#include "llvm/Type.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Assembly/Writer.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/InstIterator.h"
-#include <iostream>
+#include "llvm/Support/Streams.h"
using namespace llvm;
/// mergeSetIn - Merge the specified alias set into this alias set.
CallSites.insert(CallSites.end(), AS.CallSites.begin(), AS.CallSites.end());
AS.CallSites.clear();
}
-
+
AS.Forward = this; // Forward across AS now...
addRef(); // AS is now pointing to us...
// Loop over all of the pointers in this alias set...
AliasSet::iterator I = AS.begin(), E = AS.end();
bool X;
- for (; I != E; ++I)
- addPointer(I.getPointer(), I.getSize(),
- (AliasSet::AccessType)AS.AccessTy, X);
+ for (; I != E; ++I) {
+ AliasSet &NewAS = addPointer(I.getPointer(), I.getSize(),
+ (AliasSet::AccessType)AS.AccessTy, X);
+ if (AS.isVolatile()) NewAS.setVolatile();
+ }
}
}
/// remove - Remove the specified (potentially non-empty) alias set from the
/// tracker.
void AliasSetTracker::remove(AliasSet &AS) {
- bool SetDead;
- do {
- AliasSet::iterator I = AS.begin();
- Value *Ptr = I.getPointer(); ++I;
-
- // deleteValue will delete the set automatically when the last pointer
- // reference is destroyed. "Predict" when this will happen.
- SetDead = I == AS.end();
- deleteValue(Ptr); // Delete all of the pointers from the set
- } while (!SetDead);
+ // Drop all call sites.
+ AS.CallSites.clear();
+
+ // Clear the alias set.
+ unsigned NumRefs = 0;
+ while (!AS.empty()) {
+ AliasSet::HashNodePair *P = AS.PtrList;
+
+ // Unlink from the list of values.
+ P->second.removeFromList();
+
+ // Remember how many references need to be dropped.
+ ++NumRefs;
+
+ // Finally, remove the entry.
+ Value *Remove = P->first; // Take a copy because it is invalid to pass
+ PointerMap.erase(Remove); // a reference to the data being erased.
+ }
+
+ // Stop using the alias set, removing it.
+ AS.RefCount -= NumRefs;
+ if (AS.RefCount == 0)
+ AS.removeFromTracker(*this);
}
bool AliasSetTracker::remove(Value *Ptr, unsigned Size) {
// Notify the alias analysis implementation that this value is gone.
AA.deleteValue(PtrVal);
+ // If this is a call instruction, remove the callsite from the appropriate
+ // AliasSet.
+ CallSite CS = CallSite::get(PtrVal);
+ if (CS.getInstruction()) {
+ Function *F = CS.getCalledFunction();
+ if (!F || !AA.doesNotAccessMemory(F)) {
+ if (AliasSet *AS = findAliasSetForCallSite(CS))
+ AS->removeCallSite(CS);
+ }
+ }
+
// First, look up the PointerRec for this pointer.
hash_map<Value*, AliasSet::PointerRec>::iterator I = PointerMap.find(PtrVal);
if (I == PointerMap.end()) return; // Noop
for (unsigned i = 0, e = CallSites.size(); i != e; ++i) {
if (i) OS << ", ";
WriteAsOperand(OS, CallSites[i].getCalledValue());
- }
+ }
}
OS << "\n";
}
OS << "\n";
}
-void AliasSet::dump() const { print (std::cerr); }
-void AliasSetTracker::dump() const { print(std::cerr); }
+void AliasSet::dump() const { print (cerr); }
+void AliasSetTracker::dump() const { print(cerr); }
//===----------------------------------------------------------------------===//
// AliasSetPrinter Pass
//===----------------------------------------------------------------------===//
namespace {
- class AliasSetPrinter : public FunctionPass {
+ class VISIBILITY_HIDDEN AliasSetPrinter : public FunctionPass {
AliasSetTracker *Tracker;
public:
+ static char ID; // Pass identification, replacement for typeid
+ AliasSetPrinter() : FunctionPass((intptr_t)&ID) {}
+
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<AliasAnalysis>();
for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
Tracker->add(&*I);
- return false;
- }
-
- /// print - Convert to human readable form
- virtual void print(std::ostream &OS, const Module* = 0) const {
- Tracker->print(OS);
- }
-
- virtual void releaseMemory() {
+ Tracker->print(cerr);
delete Tracker;
+ return false;
}
};
- RegisterPass<AliasSetPrinter> X("print-alias-sets", "Alias Set Printer",
- PassInfo::Analysis | PassInfo::Optimization);
+ char AliasSetPrinter::ID = 0;
+ RegisterPass<AliasSetPrinter> X("print-alias-sets", "Alias Set Printer");
}