Free and vaarg are not really volatile.
[oota-llvm.git] / lib / Analysis / AliasSetTracker.cpp
index 852def0b76736b0585ad1942df4ad021aa3178c1..398bf5aca5b4371ee5251711611e37466856b059 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     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 is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
@@ -18,8 +18,9 @@
 #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.
@@ -113,15 +114,13 @@ void AliasSet::addPointer(AliasSetTracker &AST, HashNodePair &Entry,
 void AliasSet::addCallSite(CallSite CS, AliasAnalysis &AA) {
   CallSites.push_back(CS);
 
-  if (Function *F = CS.getCalledFunction()) {
-    AliasAnalysis::ModRefBehavior Behavior = AA.getModRefBehavior(F, CS);
-    if (Behavior == AliasAnalysis::DoesNotAccessMemory)
-      return;
-    else if (Behavior == AliasAnalysis::OnlyReadsMemory) {
-      AliasTy = MayAlias;
-      AccessTy |= Refs;
-      return;
-    }
+  AliasAnalysis::ModRefBehavior Behavior = AA.getModRefBehavior(CS);
+  if (Behavior == AliasAnalysis::DoesNotAccessMemory)
+    return;
+  else if (Behavior == AliasAnalysis::OnlyReadsMemory) {
+    AliasTy = MayAlias;
+    AccessTy |= Refs;
+    return;
   }
 
   // FIXME: This should use mod/ref information to make this not suck so bad
@@ -165,9 +164,8 @@ bool AliasSet::aliasesPointer(const Value *Ptr, unsigned Size,
 }
 
 bool AliasSet::aliasesCallSite(CallSite CS, AliasAnalysis &AA) const {
-  if (Function *F = CS.getCalledFunction())
-    if (AA.doesNotAccessMemory(F))
-      return false;
+  if (AA.doesNotAccessMemory(CS))
+    return false;
 
   if (AA.hasNoModRefInfoForCalls())
     return true;
@@ -268,7 +266,7 @@ bool AliasSetTracker::add(Value *Ptr, unsigned Size) {
 bool AliasSetTracker::add(LoadInst *LI) {
   bool NewPtr;
   AliasSet &AS = addPointer(LI->getOperand(0),
-                            AA.getTargetData().getTypeSize(LI->getType()),
+                            AA.getTargetData().getTypeStoreSize(LI->getType()),
                             AliasSet::Refs, NewPtr);
   if (LI->isVolatile()) AS.setVolatile();
   return NewPtr;
@@ -278,7 +276,7 @@ bool AliasSetTracker::add(StoreInst *SI) {
   bool NewPtr;
   Value *Val = SI->getOperand(0);
   AliasSet &AS = addPointer(SI->getOperand(1),
-                            AA.getTargetData().getTypeSize(Val->getType()),
+                            AA.getTargetData().getTypeStoreSize(Val->getType()),
                             AliasSet::Mods, NewPtr);
   if (SI->isVolatile()) AS.setVolatile();
   return NewPtr;
@@ -286,19 +284,20 @@ bool AliasSetTracker::add(StoreInst *SI) {
 
 bool AliasSetTracker::add(FreeInst *FI) {
   bool NewPtr;
-  AliasSet &AS = addPointer(FI->getOperand(0), ~0,
-                            AliasSet::Mods, NewPtr);
+  addPointer(FI->getOperand(0), ~0, AliasSet::Mods, NewPtr);
+  return NewPtr;
+}
 
-  // Free operations are volatile ops (cannot be moved).
-  AS.setVolatile();
+bool AliasSetTracker::add(VAArgInst *VAAI) {
+  bool NewPtr;
+  addPointer(VAAI->getOperand(0), ~0, AliasSet::ModRef, NewPtr);
   return NewPtr;
 }
 
 
 bool AliasSetTracker::add(CallSite CS) {
-  if (Function *F = CS.getCalledFunction())
-    if (AA.doesNotAccessMemory(F))
-      return true; // doesn't alias anything
+  if (AA.doesNotAccessMemory(CS))
+    return true; // doesn't alias anything
 
   AliasSet *AS = findAliasSetForCallSite(CS);
   if (!AS) {
@@ -324,6 +323,8 @@ bool AliasSetTracker::add(Instruction *I) {
     return add(II);
   else if (FreeInst *FI = dyn_cast<FreeInst>(I))
     return add(FI);
+  else if (VAArgInst *VAAI = dyn_cast<VAArgInst>(I))
+    return add(VAAI);
   return true;
 }
 
@@ -350,9 +351,11 @@ void AliasSetTracker::add(const AliasSetTracker &AST) {
       // 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();
+      }
     }
 }
 
@@ -392,7 +395,7 @@ bool AliasSetTracker::remove(Value *Ptr, unsigned Size) {
 }
 
 bool AliasSetTracker::remove(LoadInst *LI) {
-  unsigned Size = AA.getTargetData().getTypeSize(LI->getType());
+  unsigned Size = AA.getTargetData().getTypeStoreSize(LI->getType());
   AliasSet *AS = findAliasSetForPointer(LI->getOperand(0), Size);
   if (!AS) return false;
   remove(*AS);
@@ -400,7 +403,8 @@ bool AliasSetTracker::remove(LoadInst *LI) {
 }
 
 bool AliasSetTracker::remove(StoreInst *SI) {
-  unsigned Size = AA.getTargetData().getTypeSize(SI->getOperand(0)->getType());
+  unsigned Size =
+    AA.getTargetData().getTypeStoreSize(SI->getOperand(0)->getType());
   AliasSet *AS = findAliasSetForPointer(SI->getOperand(1), Size);
   if (!AS) return false;
   remove(*AS);
@@ -414,10 +418,16 @@ bool AliasSetTracker::remove(FreeInst *FI) {
   return true;
 }
 
+bool AliasSetTracker::remove(VAArgInst *VAAI) {
+  AliasSet *AS = findAliasSetForPointer(VAAI->getOperand(0), ~0);
+  if (!AS) return false;
+  remove(*AS);
+  return true;
+}
+
 bool AliasSetTracker::remove(CallSite CS) {
-  if (Function *F = CS.getCalledFunction())
-    if (AA.doesNotAccessMemory(F))
-      return false; // doesn't alias anything
+  if (AA.doesNotAccessMemory(CS))
+    return false; // doesn't alias anything
 
   AliasSet *AS = findAliasSetForCallSite(CS);
   if (!AS) return false;
@@ -435,6 +445,8 @@ bool AliasSetTracker::remove(Instruction *I) {
     return remove(CI);
   else if (FreeInst *FI = dyn_cast<FreeInst>(I))
     return remove(FI);
+  else if (VAArgInst *VAAI = dyn_cast<VAArgInst>(I))
+    return remove(VAAI);
   return true;
 }
 
@@ -451,13 +463,10 @@ void AliasSetTracker::deleteValue(Value *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 (CS.getInstruction())
+    if (!AA.doesNotAccessMemory(CS))
       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);
@@ -504,7 +513,7 @@ void AliasSetTracker::copyValue(Value *From, Value *To) {
 
 void AliasSet::print(std::ostream &OS) const {
   OS << "  AliasSet[" << (void*)this << "," << RefCount << "] ";
-  OS << (AliasTy == MustAlias ? "must" : "may ") << " alias, ";
+  OS << (AliasTy == MustAlias ? "must" : "may") << " alias, ";
   switch (AccessTy) {
   case NoModRef: OS << "No access "; break;
   case Refs    : OS << "Ref       "; break;
@@ -517,7 +526,7 @@ void AliasSet::print(std::ostream &OS) const {
     OS << " forwarding to " << (void*)Forward;
 
 
-  if (begin() != end()) {
+  if (!empty()) {
     OS << "Pointers: ";
     for (iterator I = begin(), E = end(); I != E; ++I) {
       if (I != begin()) OS << ", ";
@@ -543,17 +552,20 @@ void AliasSetTracker::print(std::ostream &OS) const {
   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>();
@@ -564,10 +576,13 @@ namespace {
 
       for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
         Tracker->add(&*I);
-      Tracker->print(std::cerr);
+      Tracker->print(cerr);
       delete Tracker;
       return false;
     }
   };
-  RegisterPass<AliasSetPrinter> X("print-alias-sets", "Alias Set Printer");
 }
+
+char AliasSetPrinter::ID = 0;
+static RegisterPass<AliasSetPrinter>
+X("print-alias-sets", "Alias Set Printer", false, true);