Ensure that dump calls that are associated with asserts are removed from
[oota-llvm.git] / lib / Analysis / AliasSetTracker.cpp
index 85937adb3896bf3222a03b9e918a68fcb598cf41..16c652117f563040b23d29229cde46cb213b38d3 100644 (file)
@@ -1,20 +1,21 @@
 //===- 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/Analysis/AliasAnalysis.h"
 #include "llvm/Instructions.h"
 #include "llvm/Pass.h"
+#include "llvm/Type.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/Assembly/Writer.h"
 #include "llvm/Support/InstIterator.h"
@@ -52,7 +53,7 @@ void AliasSet::mergeSetIn(AliasSet &AS, AliasSetTracker &AST) {
     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...
 
@@ -113,9 +114,10 @@ void AliasSet::addCallSite(CallSite CS, AliasAnalysis &AA) {
   CallSites.push_back(CS);
 
   if (Function *F = CS.getCalledFunction()) {
-    if (AA.doesNotAccessMemory(F))
+    AliasAnalysis::ModRefBehavior Behavior = AA.getModRefBehavior(F, CS);
+    if (Behavior == AliasAnalysis::DoesNotAccessMemory)
       return;
-    else if (AA.onlyReadsMemory(F)) {
+    else if (Behavior == AliasAnalysis::OnlyReadsMemory) {
       AliasTy = MayAlias;
       AccessTy |= Refs;
       return;
@@ -286,6 +288,9 @@ bool AliasSetTracker::add(FreeInst *FI) {
   bool NewPtr;
   AliasSet &AS = addPointer(FI->getOperand(0), ~0,
                             AliasSet::Mods, NewPtr);
+
+  // Free operations are volatile ops (cannot be moved).
+  AS.setVolatile();
   return NewPtr;
 }
 
@@ -354,16 +359,28 @@ void AliasSetTracker::add(const AliasSetTracker &AST) {
 /// 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.
+    PointerMap.erase(P->first);
+  }
+  
+  // Stop using the alias set, removing it.
+  AS.RefCount -= NumRefs;
+  if (AS.RefCount == 0)
+    AS.removeFromTracker(*this);
 }
 
 bool AliasSetTracker::remove(Value *Ptr, unsigned Size) {
@@ -430,6 +447,17 @@ void AliasSetTracker::deleteValue(Value *PtrVal) {
   // 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
@@ -501,7 +529,7 @@ void AliasSet::print(std::ostream &OS) const {
     for (unsigned i = 0, e = CallSites.size(); i != e; ++i) {
       if (i) OS << ", ";
       WriteAsOperand(OS, CallSites[i].getCalledValue());
-    }      
+    }
   }
   OS << "\n";
 }
@@ -535,18 +563,10 @@ namespace {
 
       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(std::cerr);
       delete Tracker;
+      return false;
     }
   };
-  RegisterPass<AliasSetPrinter> X("print-alias-sets", "Alias Set Printer",
-                                  PassInfo::Analysis | PassInfo::Optimization);
+  RegisterOpt<AliasSetPrinter> X("print-alias-sets", "Alias Set Printer");
 }