[llvm-commits] CVS: llvm-poolalloc/lib/DSA/StdLibPass.cpp BottomUpClosure.cpp Local.cpp Printer.cpp TopDownClosure.cpp

Andrew Lenharth alenhar2 at cs.uiuc.edu
Thu Apr 19 09:02:40 PDT 2007



Changes in directory llvm-poolalloc/lib/DSA:

StdLibPass.cpp added (r1.1)
BottomUpClosure.cpp updated: 1.132 -> 1.133
Local.cpp updated: 1.170 -> 1.171
Printer.cpp updated: 1.94 -> 1.95
TopDownClosure.cpp updated: 1.100 -> 1.101
---
Log message:

First algorithmic change.

This is partially to make kernel work easier, and partially to make poolalloc
better.

All functions, even externals (but not intrinsics) get graphs.  Graphs for
externals are such that they cause similar behavior to what is happening now,
namely that the args are marked as external, and no type inference happens, etc.

Then, recognizing libc functions is split into its own pass.  A similar pass
could be written for any work involving a set of known externals (aka the 
llva linux kernel work).  Thus the core DSA only knows about what is in llvm
proper.  (there is some regressions here, I didn't carry all the libc stuff over
into the new pass).

This helps PA, since inlining during BU is just dependent on the completeness
of the function pointer, not on the completeness and having no externals around.
One of the major problems with PA, functionality wise, is hitting functions that
haven't been resolved.  Inlining earlier tends to put enough information in each
node that BU based transforms get things right more often.  Still some issues here.

As a bonus, special case logic gets removed from some passes.

Also, externals like qsort can have graphs fabricated for them that
reflect their calls back into the program.



---
Diffs of the changes:  (+234 -759)

 BottomUpClosure.cpp |   43 ---
 Local.cpp           |  665 +++-------------------------------------------------
 Printer.cpp         |    9 
 StdLibPass.cpp      |  159 ++++++++++++
 TopDownClosure.cpp  |  117 +--------
 5 files changed, 234 insertions(+), 759 deletions(-)


Index: llvm-poolalloc/lib/DSA/StdLibPass.cpp
diff -c /dev/null llvm-poolalloc/lib/DSA/StdLibPass.cpp:1.1
*** /dev/null	Thu Apr 19 11:02:29 2007
--- llvm-poolalloc/lib/DSA/StdLibPass.cpp	Thu Apr 19 11:02:19 2007
***************
*** 0 ****
--- 1,159 ----
+ //                     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.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // Recognize common standard c library functions and generate graphs for them
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #include "llvm/ADT/Statistic.h"
+ #include "dsa/DataStructure.h"
+ #include "dsa/DSGraph.h"
+ #include "llvm/Constants.h"
+ #include "llvm/DerivedTypes.h"
+ #include "llvm/Instructions.h"
+ #include "llvm/Intrinsics.h"
+ #include "llvm/Support/GetElementPtrTypeIterator.h"
+ #include "llvm/Target/TargetData.h"
+ #include "llvm/Support/CommandLine.h"
+ #include "llvm/Support/Debug.h"
+ #include "llvm/Support/Timer.h"
+ #include <iostream>
+ #include "llvm/Module.h"
+ 
+ using namespace llvm;
+ 
+ static RegisterPass<StdLibDataStructures>
+ X("dsa-stdlib", "Standard Library Local Data Structure Analysis");
+ 
+ bool StdLibDataStructures::runOnModule(Module &M) {
+   LocalDataStructures &LocalDSA = getAnalysis<LocalDataStructures>();
+   setGraphSource(&LocalDSA);
+   setTargetData(LocalDSA.getTargetData());
+   setGraphClone(false);
+   GlobalECs = LocalDSA.getGlobalECs();
+ 
+   GlobalsGraph = new DSGraph(LocalDSA.getGlobalsGraph(), GlobalECs);
+   GlobalsGraph->setPrintAuxCalls();
+ 
+   // Calculate all of the graphs...
+   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
+     DSGraph &Graph = getOrCreateGraph(&*I);
+     //If this is an true external, check it out
+     if (I->isDeclaration() && !I->isIntrinsic()) {
+       const std::string& Name = I->getName();
+       if (Name == "calloc" ||
+           Name == "malloc" ||
+           Name == "valloc" ||
+           Name == "memalign") {
+         Graph.getReturnNodeFor(*I).getNode()->clearNodeFlags()
+           ->setHeapMarker()->setModifiedMarker();
+       } else if (Name == "realloc") {
+         Graph.getReturnNodeFor(*I).getNode()->clearNodeFlags()
+           ->setHeapMarker()->setModifiedMarker();
+         Graph.getNodeForValue(I->arg_begin()).getNode()->clearNodeFlags()
+           ->mergeWith(Graph.getReturnNodeFor(*I), 0);
+       } else if (Name == "free") {
+         Graph.getNodeForValue(&*I->arg_begin()).getNode()->clearNodeFlags()
+           ->setHeapMarker()->setModifiedMarker();
+       } else if (Name == "atoi"     || Name == "atof"    ||
+                  Name == "atol"     || Name == "atoll"   ||
+                  Name == "remove"   || Name == "unlink"  ||
+                  Name == "rename"   || Name == "memcmp"  ||
+                  Name == "strcmp"   || Name == "strncmp" ||
+                  Name == "execl"    || Name == "execlp"  ||
+                  Name == "execle"   || Name == "execv"   ||
+                  Name == "execvp"   || Name == "chmod"   ||
+                  Name == "puts"     || Name == "write"   ||
+                  Name == "open"     || Name == "create"  ||
+                  Name == "truncate" || Name == "chdir"   ||
+                  Name == "mkdir"    || Name == "rmdir"   ||
+                  Name == "strlen") {
+         for (Function::arg_iterator AI = I->arg_begin(), E = I->arg_end();
+              AI != E; ++AI) {
+           if (isa<PointerType>(AI->getType()))
+             Graph.getNodeForValue(&*AI).getNode()->clearNodeFlags()
+               ->setReadMarker();
+         }
+       } else if (Name == "read" || Name == "pipe" ||
+                  Name == "wait" || Name == "time" ||
+                  Name == "getrusage") {
+         for (Function::arg_iterator AI = I->arg_begin(), E = I->arg_end();
+              AI != E; ++AI) {
+           if (isa<PointerType>(AI->getType()))
+             Graph.getNodeForValue(&*AI).getNode()->clearNodeFlags()
+               ->setModifiedMarker();
+         }
+       } else if (Name == "memchr" || Name == "memrchr") {
+         DSNodeHandle RetNH = Graph.getReturnNodeFor(*I);
+         DSNodeHandle Result = Graph.getNodeForValue(&*I->arg_begin());
+         RetNH.mergeWith(Result);
+         RetNH.getNode()->clearNodeFlags()->setReadMarker();
+       } else if (Name == "memmove") {
+         // Merge the first & second arguments, and mark the memory read and
+         // modified.
+         DSNodeHandle& RetNH = Graph.getNodeForValue(&*I->arg_begin());
+         RetNH.mergeWith(Graph.getNodeForValue(&*(++(I->arg_begin()))));
+         RetNH.getNode()->clearNodeFlags()->setModifiedMarker()->setReadMarker();
+       } else if (Name == "stat" || Name == "fstat" || Name == "lstat") {
+         // These functions read their first operand if its a pointer.
+         Function::arg_iterator AI = I->arg_begin();
+         if (isa<PointerType>(AI->getType()))
+           Graph.getNodeForValue(&*AI).getNode()
+             ->clearNodeFlags()->setReadMarker();
+         // Then they write into the stat buffer.
+         DSNodeHandle StatBuf = Graph.getNodeForValue(&*++AI);
+         DSNode *N = StatBuf.getNode();
+         N->setModifiedMarker();
+         const Type *StatTy = I->getFunctionType()->getParamType(1);
+         if (const PointerType *PTy = dyn_cast<PointerType>(StatTy))
+           N->mergeTypeInfo(PTy->getElementType(), StatBuf.getOffset());
+       } else if (Name == "strtod" || Name == "strtof" || Name == "strtold") {
+         // These functions read the first pointer
+         DSNodeHandle& Str = Graph.getNodeForValue(&*I->arg_begin());
+         Str.getNode()->clearNodeFlags()->setReadMarker();
+         // If the second parameter is passed, it will point to the first
+         // argument node.
+         DSNodeHandle& EndNH = Graph.getNodeForValue(&*(++(I->arg_begin())));
+         EndNH.getNode()->clearNodeFlags()->setModifiedMarker();
+         EndNH.getNode()->mergeTypeInfo(PointerType::get(Type::Int8Ty),
+                                        EndNH.getOffset(), false);
+         DSNodeHandle &Link = EndNH.getLink(0);
+         Link.mergeWith(Str);
+       } else {
+         //ignore pointer free functions
+         bool hasPtr = isa<PointerType>(I->getReturnType());
+         for (Function::const_arg_iterator AI = I->arg_begin(), AE = I->arg_end();
+              AI != AE && !hasPtr; ++AI)
+           if (isa<PointerType>(AI->getType()))
+             hasPtr = true;
+         if (hasPtr)
+           std::cerr << "Unhandled External: " << Name << "\n";
+       }
+     }
+   }
+ 
+   return false;
+ }
+ 
+ // releaseMemory - If the pass pipeline is done with this pass, we can release
+ // our memory... here...
+ //
+ void StdLibDataStructures::releaseMemory() {
+   for (hash_map<Function*, DSGraph*>::iterator I = DSInfo.begin(),
+          E = DSInfo.end(); I != E; ++I) {
+     I->second->getReturnNodes().erase(I->first);
+     if (I->second->getReturnNodes().empty())
+       delete I->second;
+   }
+ 
+   // Empty map so next time memory is released, data structures are not
+   // re-deleted.
+   DSInfo.clear();
+   delete GlobalsGraph;
+   GlobalsGraph = 0;
+ }
+ 


Index: llvm-poolalloc/lib/DSA/BottomUpClosure.cpp
diff -u llvm-poolalloc/lib/DSA/BottomUpClosure.cpp:1.132 llvm-poolalloc/lib/DSA/BottomUpClosure.cpp:1.133
--- llvm-poolalloc/lib/DSA/BottomUpClosure.cpp:1.132	Tue Apr 17 18:41:06 2007
+++ llvm-poolalloc/lib/DSA/BottomUpClosure.cpp	Thu Apr 19 11:02:19 2007
@@ -38,7 +38,7 @@
 // program.
 //
 bool BUDataStructures::runOnModule(Module &M) {
-  LocalDataStructures &LocalDSA = getAnalysis<LocalDataStructures>();
+  StdLibDataStructures &LocalDSA = getAnalysis<StdLibDataStructures>();
   setGraphSource(&LocalDSA);
   setTargetData(LocalDSA.getTargetData());
   setGraphClone(false);
@@ -116,34 +116,13 @@
   return false;
 }
 
-static bool isVAHackFn(const Function *F) {
-  return F->getName() == "printf"  || F->getName() == "sscanf" ||
-    F->getName() == "fprintf" || F->getName() == "open" ||
-    F->getName() == "sprintf" || F->getName() == "fputs" ||
-    F->getName() == "fscanf" || F->getName() == "malloc" ||
-    F->getName() == "free";
-}
-
-static bool isResolvableFunc(const Function* callee) {
-  return !callee->isDeclaration() || isVAHackFn(callee);
-}
-
 static void GetAllCallees(const DSCallSite &CS,
                           std::vector<Function*> &Callees) {
   if (CS.isDirectCall()) {
-    if (isResolvableFunc(CS.getCalleeFunc()))
-      Callees.push_back(CS.getCalleeFunc());
+    Callees.push_back(CS.getCalleeFunc());
   } else if (!CS.getCalleeNode()->isIncompleteNode()) {
     // Get all callees.
-    unsigned OldSize = Callees.size();
     CS.getCalleeNode()->addFullFunctionList(Callees);
-
-    // If any of the callees are unresolvable, remove the whole batch!
-    for (unsigned i = OldSize, e = Callees.size(); i != e; ++i)
-      if (!isResolvableFunc(Callees[i])) {
-        Callees.erase(Callees.begin()+OldSize, Callees.end());
-        return;
-      }
   }
 }
 
@@ -164,16 +143,6 @@
   ValMap[F] = Min;
   Stack.push_back(F);
 
-  // FIXME!  This test should be generalized to be any function that we have
-  // already processed, in the case when there isn't a main or there are
-  // unreachable functions!
-  if (F->isDeclaration()) {   // sprintf, fprintf, sscanf, etc...
-    // No callees!
-    Stack.pop_back();
-    ValMap[F] = ~0;
-    return Min;
-  }
-
   DSGraph &Graph = getOrCreateGraph(F);
 
   // Find all callee functions.
@@ -202,11 +171,10 @@
     DOUT << "Visiting single node SCC #: " << MyID << " fn: "
          << F->getName() << "\n";
     Stack.pop_back();
-    DSGraph &G = getDSGraph(*F);
     DOUT << "  [BU] Calculating graph for: " << F->getName()<< "\n";
-    calculateGraph(G);
+    calculateGraph(Graph);
     DOUT << "  [BU] Done inlining: " << F->getName() << " ["
-         << G.getGraphSize() << "+" << G.getAuxFunctionCalls().size()
+         << Graph.getGraphSize() << "+" << Graph.getAuxFunctionCalls().size()
          << "]\n";
 
     if (MaxSCC < 1) MaxSCC = 1;
@@ -373,9 +341,6 @@
     if (CS.getRetVal().isNull() && CS.getNumPtrArgs() == 0) {
       TempFCs.erase(TempFCs.begin());
       continue;
-    } else if (CS.isDirectCall() && isVAHackFn(CS.getCalleeFunc())) {
-      TempFCs.erase(TempFCs.begin());
-      continue;
     }
 
     GetAllCallees(CS, CalledFuncs);


Index: llvm-poolalloc/lib/DSA/Local.cpp
diff -u llvm-poolalloc/lib/DSA/Local.cpp:1.170 llvm-poolalloc/lib/DSA/Local.cpp:1.171
--- llvm-poolalloc/lib/DSA/Local.cpp:1.170	Tue Apr 17 18:41:06 2007
+++ llvm-poolalloc/lib/DSA/Local.cpp	Thu Apr 19 11:02:19 2007
@@ -37,10 +37,6 @@
 static RegisterPass<LocalDataStructures>
 X("dsa-local", "Local Data Structure Analysis");
 
-static cl::opt<bool>
-IgnoreSetCC("dsa-ignore-setcc", cl::Hidden,
-         cl::desc("If this is set, do nothing at pointer comparisons"));
-
 static cl::list<std::string>
 AllocList("dsa-alloc-list",
           cl::value_desc("list"),
@@ -121,6 +117,7 @@
     void visitIntToPtrInst(IntToPtrInst &I);
     void visitPtrToIntInst(PtrToIntInst &I);
     void visitBitCastInst(BitCastInst &I);
+    void visitCmpInst(CmpInst &I);
 
     //the nasty ones
     void visitGetElementPtrInst(User &GEP);
@@ -129,7 +126,6 @@
     void visitInstruction(Instruction &I);
 
     bool visitIntrinsic(CallSite CS, Function* F);
-    bool visitExternal(llvm::CallSite, llvm::Function*);
     void visitCallSite(CallSite CS);
 
   public:
@@ -141,8 +137,11 @@
         if (isa<PointerType>(I->getType())) {
           DSNode * Node = getValueDest(*I).getNode();
 
-          if (!(f.hasInternalLinkage())) {
+          if (!f.hasInternalLinkage() || f.isDeclaration()) {
             Node->setExternalMarker();
+            //pecimistic assumptions on externals
+            if (f.isDeclaration())
+              Node->setReadMarker()->setModifiedMarker();
           }
         }
       }
@@ -150,18 +149,25 @@
       // Create an entry for the return, which tracks which functions are in the graph
       g.getOrCreateReturnNodeFor(f);
 
-      visit(f);  // Single pass over the function
+      if (!f.isDeclaration()) {
+        visit(f);  // Single pass over the function
 
-      // If there are any constant globals referenced in this function, merge their
-      // initializers into the local graph from the globals graph.
-      if (g.getScalarMap().global_begin() != g.getScalarMap().global_end()) {
-        ReachabilityCloner RC(g, *g.getGlobalsGraph(), 0);
-        
-        for (DSScalarMap::global_iterator I = g.getScalarMap().global_begin();
-             I != g.getScalarMap().global_end(); ++I)
-          if (GlobalVariable *GV = dyn_cast<GlobalVariable>(*I))
-            if (!GV->isDeclaration() && GV->isConstant())
-              RC.merge(g.getNodeForValue(GV), g.getGlobalsGraph()->getNodeForValue(GV));
+        // If there are any constant globals referenced in this function, merge their
+        // initializers into the local graph from the globals graph.
+        if (g.getScalarMap().global_begin() != g.getScalarMap().global_end()) {
+          ReachabilityCloner RC(g, *g.getGlobalsGraph(), 0);
+          
+          for (DSScalarMap::global_iterator I = g.getScalarMap().global_begin();
+               I != g.getScalarMap().global_end(); ++I)
+            if (GlobalVariable *GV = dyn_cast<GlobalVariable>(*I))
+              if (!GV->isDeclaration() && GV->isConstant())
+                RC.merge(g.getNodeForValue(GV), g.getGlobalsGraph()->getNodeForValue(GV));
+        }
+      } else {
+        DSNodeHandle& RNH = g.getOrCreateReturnNodeFor(f);
+        //Make sure return values from externals are marked as such
+        if (isa<PointerType>(f.getReturnType()))
+          RNH.mergeWith(createNode()->setReadMarker()->setModifiedMarker()->setExternalMarker());
       }
       
       g.markIncompleteNodes(DSGraph::MarkFormalArgs);
@@ -355,6 +361,10 @@
   setDestTo(I, Ptr);
 }
 
+void GraphBuilder::visitCmpInst(CmpInst &I) {
+  //Should this merge or not?  I don't think so.
+}
+
 void GraphBuilder::visitGetElementPtrInst(User &GEP) {
   DSNodeHandle Value = getValueDest(*GEP.getOperand(0));
   if (Value.isNull())
@@ -548,589 +558,23 @@
     if (DSNode *N = getValueDest(**CS.arg_begin()).getNode())
       N->setModifiedMarker();
     return true;
-  default:
+  default: {
+    //ignore pointer free intrinsics
+    if (!isa<PointerType>(F->getReturnType())) {
+      bool hasPtr = false;
+      for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end();
+           I != E && !hasPtr; ++I)
+        if (isa<PointerType>(I->getType()))
+          hasPtr = true;
+      if (!hasPtr)
+        return true;
+    }
+
+    assert(0 && "Unhandled intrinsic");
     DOUT << "[dsa:local] Unhandled intrinsic: " << F->getName() << "\n";
     return false;
   }
-}
-
-/// returns true if the external is a recognized libc function with a 
-/// known (and generated) graph
-bool GraphBuilder::visitExternal(CallSite CS, Function *F) {
-  if (F->getName() == "calloc"
-      || F->getName() == "posix_memalign"
-      || F->getName() == "memalign" || F->getName() == "valloc") {
-    setDestTo(*CS.getInstruction(),
-              createNode()->setHeapMarker()->setModifiedMarker());
-    return true;
-  } else if (F->getName() == "realloc") {
-    DSNodeHandle RetNH = getValueDest(*CS.getInstruction());
-    if (CS.arg_begin() != CS.arg_end())
-      RetNH.mergeWith(getValueDest(**CS.arg_begin()));
-    if (DSNode *N = RetNH.getNode())
-      N->setHeapMarker()->setModifiedMarker()->setReadMarker();
-    return true;
-  } else if (F->getName() == "memmove") {
-    // Merge the first & second arguments, and mark the memory read and
-    // modified.
-    DSNodeHandle RetNH = getValueDest(**CS.arg_begin());
-    RetNH.mergeWith(getValueDest(**(CS.arg_begin()+1)));
-    if (DSNode *N = RetNH.getNode())
-      N->setModifiedMarker()->setReadMarker();
-    return true;
-  } else if (F->getName() == "free") {
-    // Mark that the node is written to...
-    if (DSNode *N = getValueDest(**CS.arg_begin()).getNode())
-      N->setModifiedMarker()->setHeapMarker();
-  } else if (F->getName() == "atoi" || F->getName() == "atof" ||
-             F->getName() == "atol" || F->getName() == "atoll" ||
-             F->getName() == "remove" || F->getName() == "unlink" ||
-             F->getName() == "rename" || F->getName() == "memcmp" ||
-             F->getName() == "strcmp" || F->getName() == "strncmp" ||
-             F->getName() == "execl" || F->getName() == "execlp" ||
-             F->getName() == "execle" || F->getName() == "execv" ||
-             F->getName() == "execvp" || F->getName() == "chmod" ||
-             F->getName() == "puts" || F->getName() == "write" ||
-             F->getName() == "open" || F->getName() == "create" ||
-             F->getName() == "truncate" || F->getName() == "chdir" ||
-             F->getName() == "mkdir" || F->getName() == "rmdir" ||
-             F->getName() == "strlen") {
-    // These functions read all of their pointer operands.
-    for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
-         AI != E; ++AI) {
-      if (isa<PointerType>((*AI)->getType()))
-        if (DSNode *N = getValueDest(**AI).getNode())
-          N->setReadMarker();
-    }
-    return true;
-  } else if (F->getName() == "memchr") {
-    DSNodeHandle RetNH = getValueDest(**CS.arg_begin());
-    DSNodeHandle Result = getValueDest(*CS.getInstruction());
-    RetNH.mergeWith(Result);
-    if (DSNode *N = RetNH.getNode())
-      N->setReadMarker();
-    return true;
-  } else if (F->getName() == "read" || F->getName() == "pipe" ||
-             F->getName() == "wait" || F->getName() == "time" ||
-             F->getName() == "getrusage") {
-    // These functions write all of their pointer operands.
-    for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
-         AI != E; ++AI) {
-      if (isa<PointerType>((*AI)->getType()))
-        if (DSNode *N = getValueDest(**AI).getNode())
-          N->setModifiedMarker();
-    }
-    return true;
-  } else if (F->getName() == "stat" || F->getName() == "fstat" ||
-             F->getName() == "lstat") {
-    // These functions read their first operand if its a pointer.
-    CallSite::arg_iterator AI = CS.arg_begin();
-    if (isa<PointerType>((*AI)->getType())) {
-      DSNodeHandle Path = getValueDest(**AI);
-      if (DSNode *N = Path.getNode()) N->setReadMarker();
-    }
-    
-    // Then they write into the stat buffer.
-    DSNodeHandle StatBuf = getValueDest(**++AI);
-    if (DSNode *N = StatBuf.getNode()) {
-      N->setModifiedMarker();
-      const Type *StatTy = F->getFunctionType()->getParamType(1);
-      if (const PointerType *PTy = dyn_cast<PointerType>(StatTy))
-        N->mergeTypeInfo(PTy->getElementType(), StatBuf.getOffset());
-    }
-    return true;
-  } else if (F->getName() == "strtod" || F->getName() == "strtof" ||
-             F->getName() == "strtold") {
-    // These functions read the first pointer
-    if (DSNode *Str = getValueDest(**CS.arg_begin()).getNode()) {
-      Str->setReadMarker();
-      // If the second parameter is passed, it will point to the first
-      // argument node.
-      const DSNodeHandle &EndPtrNH = getValueDest(**(CS.arg_begin()+1));
-      if (DSNode *End = EndPtrNH.getNode()) {
-        End->mergeTypeInfo(PointerType::get(Type::Int8Ty),
-                           EndPtrNH.getOffset(), false);
-        End->setModifiedMarker();
-        DSNodeHandle &Link = getLink(EndPtrNH);
-        Link.mergeWith(getValueDest(**CS.arg_begin()));
-      }
-    }
-    return true;
-  } else if (F->getName() == "fopen" || F->getName() == "fdopen" ||
-             F->getName() == "freopen") {
-    // These functions read all of their pointer operands.
-    for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
-         AI != E; ++AI)
-      if (isa<PointerType>((*AI)->getType()))
-        if (DSNode *N = getValueDest(**AI).getNode())
-          N->setReadMarker();
-
-    // fopen allocates in an unknown way and writes to the file
-    // descriptor.  Also, merge the allocated type into the node.
-    DSNodeHandle Result = getValueDest(*CS.getInstruction());
-    if (DSNode *N = Result.getNode()) {
-      N->setModifiedMarker()->setUnknownMarker();
-      const Type *RetTy = F->getFunctionType()->getReturnType();
-      if (const PointerType *PTy = dyn_cast<PointerType>(RetTy))
-              N->mergeTypeInfo(PTy->getElementType(), Result.getOffset());
-    }
-    
-    // If this is freopen, merge the file descriptor passed in with the
-    // result.
-    if (F->getName() == "freopen") {
-      // ICC doesn't handle getting the iterator, decrementing and
-      // dereferencing it in one operation without error. Do it in 2 steps
-      CallSite::arg_iterator compit = CS.arg_end();
-      Result.mergeWith(getValueDest(**--compit));
-    }
-    return true;
-  } else if (F->getName() == "fclose" && CS.arg_end()-CS.arg_begin() ==1){
-    // fclose reads and deallocates the memory in an unknown way for the
-    // file descriptor.  It merges the FILE type into the descriptor.
-    DSNodeHandle H = getValueDest(**CS.arg_begin());
-    if (DSNode *N = H.getNode()) {
-      N->setReadMarker()->setUnknownMarker();
-      const Type *ArgTy = F->getFunctionType()->getParamType(0);
-      if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
-        N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
-    }
-    return true;
-  } else if (CS.arg_end()-CS.arg_begin() == 1 &&
-             (F->getName() == "fflush" || F->getName() == "feof" ||
-              F->getName() == "fileno" || F->getName() == "clearerr" ||
-              F->getName() == "rewind" || F->getName() == "ftell" ||
-              F->getName() == "ferror" || F->getName() == "fgetc" ||
-              F->getName() == "fgetc" || F->getName() == "_IO_getc")) {
-    // fflush reads and writes the memory for the file descriptor.  It
-    // merges the FILE type into the descriptor.
-    DSNodeHandle H = getValueDest(**CS.arg_begin());
-    if (DSNode *N = H.getNode()) {
-      N->setReadMarker()->setModifiedMarker();
-      
-      const Type *ArgTy = F->getFunctionType()->getParamType(0);
-      if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
-        N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
-    }
-    return true;
-  } else if (CS.arg_end()-CS.arg_begin() == 4 &&
-             (F->getName() == "fwrite" || F->getName() == "fread")) {
-    // fread writes the first operand, fwrite reads it.  They both
-    // read/write the FILE descriptor, and merges the FILE type.
-    CallSite::arg_iterator compit = CS.arg_end();
-    DSNodeHandle H = getValueDest(**--compit);
-    if (DSNode *N = H.getNode()) {
-      N->setReadMarker()->setModifiedMarker();
-      const Type *ArgTy = F->getFunctionType()->getParamType(3);
-      if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
-        N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
-    }
-    
-    H = getValueDest(**CS.arg_begin());
-    if (DSNode *N = H.getNode())
-      if (F->getName() == "fwrite")
-        N->setReadMarker();
-      else
-        N->setModifiedMarker();
-    return true;
-  } else if (F->getName() == "fgets" && CS.arg_end()-CS.arg_begin() == 3){
-    // fgets reads and writes the memory for the file descriptor.  It
-    // merges the FILE type into the descriptor, and writes to the
-    // argument.  It returns the argument as well.
-    CallSite::arg_iterator AI = CS.arg_begin();
-    DSNodeHandle H = getValueDest(**AI);
-    if (DSNode *N = H.getNode())
-      N->setModifiedMarker();                        // Writes buffer
-    H.mergeWith(getValueDest(*CS.getInstruction())); // Returns buffer
-    ++AI; ++AI;
-    
-    // Reads and writes file descriptor, merge in FILE type.
-    H = getValueDest(**AI);
-    if (DSNode *N = H.getNode()) {
-      N->setReadMarker()->setModifiedMarker();
-      const Type *ArgTy = F->getFunctionType()->getParamType(2);
-      if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
-        N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
-    }
-    return true;
-  } else if (F->getName() == "ungetc" || F->getName() == "fputc" ||
-             F->getName() == "fputs" || F->getName() == "putc" ||
-             F->getName() == "ftell" || F->getName() == "rewind" ||
-             F->getName() == "_IO_putc") {
-    // These functions read and write the memory for the file descriptor,
-    // which is passes as the last argument.
-    CallSite::arg_iterator compit = CS.arg_end();
-    DSNodeHandle H = getValueDest(**--compit);
-    if (DSNode *N = H.getNode()) {
-      N->setReadMarker()->setModifiedMarker();
-      FunctionType::param_iterator compit2 = F->getFunctionType()->param_end();
-      const Type *ArgTy = *--compit2;
-      if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
-        N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
-    }
-    
-    // Any pointer arguments are read.
-    for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
-         AI != E; ++AI)
-      if (isa<PointerType>((*AI)->getType()))
-        if (DSNode *N = getValueDest(**AI).getNode())
-          N->setReadMarker();
-    return true;
-  } else if (F->getName() == "fseek" || F->getName() == "fgetpos" ||
-             F->getName() == "fsetpos") {
-    // These functions read and write the memory for the file descriptor,
-    // and read/write all other arguments.
-    DSNodeHandle H = getValueDest(**CS.arg_begin());
-    if (DSNode *N = H.getNode()) {
-      FunctionType::param_iterator compit2 = F->getFunctionType()->param_end();
-      const Type *ArgTy = *--compit2;
-      if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
-        N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
-    }
-    
-    // Any pointer arguments are read.
-    for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
-         AI != E; ++AI)
-      if (isa<PointerType>((*AI)->getType()))
-        if (DSNode *N = getValueDest(**AI).getNode())
-          N->setReadMarker()->setModifiedMarker();
-    return true;
-  } else if (F->getName() == "printf" || F->getName() == "fprintf" ||
-             F->getName() == "sprintf") {
-    CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
-    
-    if (F->getName() == "fprintf") {
-      // fprintf reads and writes the FILE argument, and applies the type
-      // to it.
-      DSNodeHandle H = getValueDest(**AI);
-      if (DSNode *N = H.getNode()) {
-        N->setModifiedMarker();
-        const Type *ArgTy = (*AI)->getType();
-        if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
-          N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
-      }
-    } else if (F->getName() == "sprintf") {
-      // sprintf writes the first string argument.
-      DSNodeHandle H = getValueDest(**AI++);
-      if (DSNode *N = H.getNode()) {
-        N->setModifiedMarker();
-        const Type *ArgTy = (*AI)->getType();
-        if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
-          N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
-      }
-    }
-    
-    for (; AI != E; ++AI) {
-      // printf reads all pointer arguments.
-      if (isa<PointerType>((*AI)->getType()))
-        if (DSNode *N = getValueDest(**AI).getNode())
-          N->setReadMarker();
-    }
-    return true;
-  } else if (F->getName() == "vprintf" || F->getName() == "vfprintf" ||
-             F->getName() == "vsprintf") {
-    CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
-    
-    if (F->getName() == "vfprintf") {
-      // ffprintf reads and writes the FILE argument, and applies the type
-      // to it.
-      DSNodeHandle H = getValueDest(**AI);
-      if (DSNode *N = H.getNode()) {
-        N->setModifiedMarker()->setReadMarker();
-        const Type *ArgTy = (*AI)->getType();
-        if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
-          N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
-      }
-      ++AI;
-    } else if (F->getName() == "vsprintf") {
-      // vsprintf writes the first string argument.
-      DSNodeHandle H = getValueDest(**AI++);
-      if (DSNode *N = H.getNode()) {
-        N->setModifiedMarker();
-        const Type *ArgTy = (*AI)->getType();
-        if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
-          N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
-      }
-    }
-    
-    // Read the format
-    if (AI != E) {
-      if (isa<PointerType>((*AI)->getType()))
-        if (DSNode *N = getValueDest(**AI).getNode())
-          N->setReadMarker();
-      ++AI;
-    }
-    
-    // Read the valist, and the pointed-to objects.
-    if (AI != E && isa<PointerType>((*AI)->getType())) {
-      const DSNodeHandle &VAList = getValueDest(**AI);
-      if (DSNode *N = VAList.getNode()) {
-        N->setReadMarker();
-        N->mergeTypeInfo(PointerType::get(Type::Int8Ty),
-        		 VAList.getOffset(), false);
-	
-        DSNodeHandle &VAListObjs = getLink(VAList);
-        VAListObjs.getNode()->setReadMarker();
-      }
-    }
-    
-    return true;
-  } else if (F->getName() == "scanf" || F->getName() == "fscanf" ||
-             F->getName() == "sscanf") {
-    CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
-    
-    if (F->getName() == "fscanf") {
-      // fscanf reads and writes the FILE argument, and applies the type
-      // to it.
-      DSNodeHandle H = getValueDest(**AI);
-      if (DSNode *N = H.getNode()) {
-        N->setReadMarker();
-        const Type *ArgTy = (*AI)->getType();
-        if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
-          N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
-      }
-    } else if (F->getName() == "sscanf") {
-      // sscanf reads the first string argument.
-      DSNodeHandle H = getValueDest(**AI++);
-      if (DSNode *N = H.getNode()) {
-        N->setReadMarker();
-        const Type *ArgTy = (*AI)->getType();
-        if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
-          N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
-      }
-    }
-    
-    for (; AI != E; ++AI) {
-      // scanf writes all pointer arguments.
-      if (isa<PointerType>((*AI)->getType()))
-        if (DSNode *N = getValueDest(**AI).getNode())
-          N->setModifiedMarker();
-    }
-    return true;
-  } else if (F->getName() == "strtok") {
-    // strtok reads and writes the first argument, returning it.  It reads
-    // its second arg.  FIXME: strtok also modifies some hidden static
-    // data.  Someday this might matter.
-    CallSite::arg_iterator AI = CS.arg_begin();
-    DSNodeHandle H = getValueDest(**AI++);
-    if (DSNode *N = H.getNode()) {
-      N->setReadMarker()->setModifiedMarker();      // Reads/Writes buffer
-      const Type *ArgTy = F->getFunctionType()->getParamType(0);
-      if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
-        N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
-    }
-    H.mergeWith(getValueDest(*CS.getInstruction())); // Returns buffer
-    
-    H = getValueDest(**AI);       // Reads delimiter
-    if (DSNode *N = H.getNode()) {
-      N->setReadMarker();
-      const Type *ArgTy = F->getFunctionType()->getParamType(1);
-      if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
-        N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
-    }
-    return true;
-  } else if (F->getName() == "strchr" || F->getName() == "strrchr" ||
-             F->getName() == "strstr") {
-    // These read their arguments, and return the first one
-    DSNodeHandle H = getValueDest(**CS.arg_begin());
-    H.mergeWith(getValueDest(*CS.getInstruction())); // Returns buffer
-    
-    for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
-         AI != E; ++AI)
-      if (isa<PointerType>((*AI)->getType()))
-        if (DSNode *N = getValueDest(**AI).getNode())
-          N->setReadMarker();
-    
-    if (DSNode *N = H.getNode())
-      N->setReadMarker();
-    return true;
-  } else if (F->getName() == "__assert_fail") {
-    for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
-         AI != E; ++AI)
-      if (isa<PointerType>((*AI)->getType()))
-        if (DSNode *N = getValueDest(**AI).getNode())
-          N->setReadMarker();
-    return true;
-  } else if (F->getName() == "modf" && CS.arg_end()-CS.arg_begin() == 2) {
-    // This writes its second argument, and forces it to double.
-    CallSite::arg_iterator compit = CS.arg_end();
-    DSNodeHandle H = getValueDest(**--compit);
-    if (DSNode *N = H.getNode()) {
-      N->setModifiedMarker();
-      N->mergeTypeInfo(Type::DoubleTy, H.getOffset());
-    }
-    return true;
-  } else if (F->getName() == "strcat" || F->getName() == "strncat") {
-    //This might be making unsafe assumptions about usage
-    //Merge return and first arg
-    DSNodeHandle RetNH = getValueDest(*CS.getInstruction());
-    RetNH.mergeWith(getValueDest(**CS.arg_begin()));
-    if (DSNode *N = RetNH.getNode())
-      N->setHeapMarker()->setModifiedMarker()->setReadMarker();
-    //and read second pointer
-    if (DSNode *N = getValueDest(**(CS.arg_begin() + 1)).getNode())
-      N->setReadMarker();
-    return true;
-  } else if (F->getName() == "strcpy" || F->getName() == "strncpy") {
-    //This might be making unsafe assumptions about usage
-    //Merge return and first arg
-    DSNodeHandle RetNH = getValueDest(*CS.getInstruction());
-    RetNH.mergeWith(getValueDest(**CS.arg_begin()));
-    if (DSNode *N = RetNH.getNode())
-      N->setHeapMarker()->setModifiedMarker();
-    //and read second pointer
-    if (DSNode *N = getValueDest(**(CS.arg_begin() + 1)).getNode())
-            N->setReadMarker();
-    return true;
-#ifdef LLVA_KERNEL_0
-  } else if (F->getName() == "kmem_cache_alloc") {
-    DEBUG(std::cerr << "LLVA: kmem_cache_alloc" << std::endl);
-    // Update the statistics count
-    ++CacheAllocs;
-
-    // Create a new DSNode for this memory allocation
-    DSNode *N = createNode();
-    N->setHeapMarker();
-    setDestTo(*CS.getInstruction(), N);
-
-    // Get the pool handle
-    if (CS.arg_begin() == CS.arg_end()) {
-      abort(); //Hanlde this later
-      // Treat it as  a kmalloc
-      N->foldNodeCompletely();
-      //This becomes a kmalloc pool
-      MetaPoolHandle* tmpvh = new MetaPoolHandle(new MetaPool(KMallocPool));
-      G.getPoolDescriptorsMap()[N] = tmpvh;
-    } else {
-      Value *actualPD = *(CS.arg_begin());
-      if (!isa<GlobalValue>(actualPD)) {
-        std::cerr << "WARNING: Pool is not global.  Function = " << CS.getCaller()->getName() << "\n";
-      } else {
-        ++GlobalPools;
-      }
-      Value *TheMetaPool = actualPD;
-      if (G.getPoolDescriptorsMap().count(N)== 0) {
-        //Here we insert a global meta pool
-        //Get the Module first
-        Module * M = F->getParent();
-        //Now create a meta pool for this value, DSN Node
-        const Type * VoidPtrType = PointerType::get(Type::Int8Ty);              
-        TheMetaPool = new GlobalVariable(
-                                 /*type=*/ VoidPtrType,
-                                 /*isConstant=*/ false,
-                                 /*Linkage=*/ GlobalValue::InternalLinkage,
-                                 /*initializer=*/ Constant::getNullValue(VoidPtrType),
-                                 /*name=*/ "_metaPool_",
-                                 /*parent=*/ M );
-        //Inserted a global meta pool 
-      }
-      //Now insert a function call that takes care of adding this pool to the global pool
-      
-      //First get the Insert point
-      Instruction *InsertPoint = CS.getInstruction();
-      
-      //Assumes AddPoolDescToMetaPool is in the module
-      CastInst *CastMetaPool = 
-        CastInst::createPointerCast (TheMetaPool, 
-                     PointerType::get(Type::Int8Ty), "metapool.casted", InsertPoint);
-      CastInst *CastActualPD = 
-        CastInst::createPointerCast (actualPD, 
-                     PointerType::get(Type::Int8Ty), "poolhandle.lscasted", InsertPoint);
-      
-      // Create the call to AddPoolDescToMetaPool 
-      std::vector<Value *> args(1,CastMetaPool);
-      args.push_back(CastActualPD);
-      new CallInst(AddPoolDescToMetaPool,args,"", InsertPoint);
-      MetaPoolHandle* tmpvh = new MetaPoolHandle(new MetaPool(TheMetaPool));
-      G.getPoolDescriptorsMap()[N] = tmpvh;
-    }
-  } else if (F->getName() == "poolalloc") {
-    if (CS.getCaller()->getName() == "kmem_cache_alloc")
-      return;
-    // Update the statistics
-    ++KMallocs;
-
-    // Create a DSNode for the memory allocated by this function call
-    DSNode *N = createNode();
-    N->setHeapMarker();
-    setDestTo(*CS.getInstruction(), N);
-
-    // Get the pool handle, if possible
-    if (CS.arg_begin() == CS.arg_end()) {
-      abort(); //handle later
-      // Treat it as kmalloc
-      N->foldNodeCompletely();
-      //This becomes a kmalloc pool
-      //So get the kmalloc pool
-      MetaPoolHandle* tmpvh = new MetaPoolHandle(new MetaPool(KMallocPool));
-      G.getPoolDescriptorsMap()[N] = tmpvh;
-    } else {
-      Value *actualPD = *(CS.arg_begin());
-      if (!isa<GlobalValue>(actualPD)) {
-        std::cerr << "WARNING: Pool is not global.  Function = " << CS.getCaller()->getName() << "\n";
-      } else {
-        ++GlobalPools;
-      }
-      Value *TheMetaPool = actualPD;
-      if (G.getPoolDescriptorsMap().count(N)== 0) {
-        //Here we insert a global meta pool
-        //Get the Module first
-        Module * M = F->getParent();
-        //Now create a meta pool for this value, DSN Node
-        const Type * VoidPtrType = PointerType::get(Type::Int8Ty);              
-        TheMetaPool = new GlobalVariable(
-                                 /*type=*/ VoidPtrType,
-                                 /*isConstant=*/ false,
-                                 /*Linkage=*/ GlobalValue::InternalLinkage,
-                                 /*initializer=*/ Constant::getNullValue(VoidPtrType),
-                                 /*name=*/ "_metaPool_",
-                                 /*parent=*/ M );
-        //Inserted a global meta pool 
-      }
-      //Now insert a function call that takes care of adding this pool to the global pool
-      //First get the Insert point
-      Instruction *InsertPoint = CS.getInstruction();
-
-      //Assumes AddPoolDescToMetaPool is in the module
-      CastInst *CastMetaPool = 
-        CastInst::createPointerCast (TheMetaPool, 
-                     PointerType::get(Type::Int8Ty), "metapool.casted", InsertPoint);
-      CastInst *CastActualPD = 
-        CastInst::createPointerCast (actualPD, 
-                     PointerType::get(Type::Int8Ty), "poolhandle.lscasted", InsertPoint);
-      
-      // Create the call to AddPoolDescToMetaPool 
-      std::vector<Value *> args(1,CastMetaPool);
-      args.push_back(CastActualPD);
-      new CallInst(AddPoolDescToMetaPool,args,"", InsertPoint);
-      MetaPoolHandle* tmpvh = new MetaPoolHandle(new MetaPool(TheMetaPool));
-      G.getPoolDescriptorsMap()[N] = tmpvh;
-    }
-#endif
-#ifdef LLVA_KERNEL
-  } else if (F->getName() == "llva_memcpy") {
-    if (CS.getCaller()->getName() == "kmem_cache_alloc")
-        return false;
-    // Merge the first & second arguments, and mark the memory read and
-    // modified.
-    DSNodeHandle RetNH = getValueDest(**CS.arg_begin());
-    RetNH.mergeWith(getValueDest(**(CS.arg_begin()+1)));
-    if (DSNode *N = RetNH.getNode())
-      N->setModifiedMarker()->setReadMarker();
-    return true;
-  } else if (F->getName() == "__generic_copy_from_user") {
-    if (CS.getCaller()->getName() == "kmem_cache_alloc")
-        return false;
-    // Merge the first & second arguments, and mark the memory read and
-    // modified.
-    DSNodeHandle RetNH = getValueDest(**CS.arg_begin());
-    RetNH.mergeWith(getValueDest(**(CS.arg_begin()+1)));
-    if (DSNode *N = RetNH.getNode())
-      N->setModifiedMarker()->setReadMarker();
-    return true;
-#endif
   }
-
-  return false;
 }
 
 void GraphBuilder::visitCallSite(CallSite CS) {
@@ -1159,24 +603,6 @@
             N->setModifiedMarker()->setHeapMarker();
           return;
         }
-
-        if (visitExternal(CS,F))
-          return;
-
-        // Unknown function, warn if it returns a pointer type or takes a
-        // pointer argument.
-        bool Warn = isa<PointerType>(CS.getInstruction()->getType());
-        if (!Warn)
-          for (CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end();
-               I != E; ++I)
-            if (isa<PointerType>((*I)->getType())) {
-              Warn = true;
-              break;
-            }
-        if (Warn) {
-          DOUT << "WARNING: Call to unknown external function '"
-               << F->getName() << "' will cause pessimistic results!\n";
-        }
       }
 
   // Set up the return value...
@@ -1301,12 +727,11 @@
   formGlobalECs();
 
   // Calculate all of the graphs...
-  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
-    if (!I->isDeclaration()) {
-      DSGraph* G = new DSGraph(GlobalECs, getTargetData(), GlobalsGraph);
-      GraphBuilder GGB(*I, *G);
-      DSInfo.insert(std::make_pair(I, G));
-    }
+  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
+    DSGraph* G = new DSGraph(GlobalECs, getTargetData(), GlobalsGraph);
+    GraphBuilder GGB(*I, *G);
+    DSInfo.insert(std::make_pair(I, G));
+  }
 
   GlobalsGraph->removeTriviallyDeadNodes();
   GlobalsGraph->markIncompleteNodes(DSGraph::MarkFormalArgs);


Index: llvm-poolalloc/lib/DSA/Printer.cpp
diff -u llvm-poolalloc/lib/DSA/Printer.cpp:1.94 llvm-poolalloc/lib/DSA/Printer.cpp:1.95
--- llvm-poolalloc/lib/DSA/Printer.cpp:1.94	Tue Apr 17 18:41:06 2007
+++ llvm-poolalloc/lib/DSA/Printer.cpp	Thu Apr 19 11:02:19 2007
@@ -71,6 +71,10 @@
     if (NodeType & DSNode::IncompleteNode ) OS << "I";
     if (NodeType & DSNode::ModifiedNode   ) OS << "M";
     if (NodeType & DSNode::ReadNode       ) OS << "R";
+    if (NodeType & DSNode::ExternalNode   ) OS << "E";
+    if (NodeType & DSNode::IntToPtrNode   ) OS << "P";
+    if (NodeType & DSNode::PtrToIntNode   ) OS << "2";
+
 #ifndef NDEBUG
     if (NodeType & DSNode::DeadNode       ) OS << "<dead>";
 #endif
@@ -333,6 +337,11 @@
   printCollection(*this, O, M, "ds.");
 }
 
+void StdLibDataStructures::print(std::ostream &O, const Module *M) const {
+  if (DontPrintAnything) return;
+  printCollection(*this, O, M, "ds.");
+}
+
 void BUDataStructures::print(std::ostream &O, const Module *M) const {
   if (DontPrintAnything) return;
   printCollection(*this, O, M, "bu.");


Index: llvm-poolalloc/lib/DSA/TopDownClosure.cpp
diff -u llvm-poolalloc/lib/DSA/TopDownClosure.cpp:1.100 llvm-poolalloc/lib/DSA/TopDownClosure.cpp:1.101
--- llvm-poolalloc/lib/DSA/TopDownClosure.cpp:1.100	Tue Apr 17 18:41:06 2007
+++ llvm-poolalloc/lib/DSA/TopDownClosure.cpp	Thu Apr 19 11:02:19 2007
@@ -60,6 +60,10 @@
 //
 bool TDDataStructures::runOnModule(Module &M) {
   BUInfo = &getAnalysis<BUDataStructures>();
+  setGraphSource(BUInfo);
+  setTargetData(BUInfo->getTargetData());
+  setGraphClone(true);
+
   GlobalECs = BUInfo->getGlobalECs();
   GlobalsGraph = new DSGraph(BUInfo->getGlobalsGraph(), GlobalECs);
   GlobalsGraph->setPrintAuxCalls();
@@ -89,7 +93,7 @@
 
   // Functions without internal linkage also have unknown incoming arguments!
   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
-    if (!I->isDeclaration() && !I->hasInternalLinkage())
+    if (!I->hasInternalLinkage())
       ArgsRemainIncomplete.insert(I);
 
   // We want to traverse the call graph in reverse post-order.  To do this, we
@@ -102,8 +106,7 @@
 
   // Visit each of the graphs in reverse post-order now!
   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
-    if (!I->isDeclaration())
-      getOrCreateDSGraph(*I);
+    getOrCreateGraph(*I);
   return false;
 }
 #endif
@@ -117,7 +120,8 @@
 
   // Next calculate the graphs for each unreachable function...
   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
-    ComputePostOrder(*I, VisitedGraph, PostOrder);
+    if (!I->isDeclaration())
+      ComputePostOrder(*I, VisitedGraph, PostOrder);
 
   VisitedGraph.clear();   // Release memory!
 }
@@ -145,30 +149,9 @@
 }
 
 
-DSGraph &TDDataStructures::getOrCreateDSGraph(Function &F) {
-  DSGraph *&G = DSInfo[&F];
-  if (G == 0) { // Not created yet?  Clone BU graph...
-    G = new DSGraph(getAnalysis<BUDataStructures>().getDSGraph(F), GlobalECs,
-                    DSGraph::DontCloneAuxCallNodes);
-    assert(G->getAuxFunctionCalls().empty() && "Cloned aux calls?");
-    G->setPrintAuxCalls();
-    G->setGlobalsGraph(GlobalsGraph);
-
-    // Note that this graph is the graph for ALL of the function in the SCC, not
-    // just F.
-    for (DSGraph::retnodes_iterator RI = G->retnodes_begin(),
-           E = G->retnodes_end(); RI != E; ++RI)
-      if (RI->first != &F)
-        DSInfo[RI->first] = G;
-  }
-  return *G;
-}
-
-
 void TDDataStructures::ComputePostOrder(Function &F,hash_set<DSGraph*> &Visited,
                                         std::vector<DSGraph*> &PostOrder) {
-  if (F.isDeclaration()) return;
-  DSGraph &G = getOrCreateDSGraph(F);
+  DSGraph &G = getOrCreateGraph(&F);
   if (Visited.count(&G)) return;
   Visited.insert(&G);
 
@@ -312,9 +295,8 @@
 
     // Handle direct calls efficiently.
     if (CI->isDirectCall()) {
-      if (!CI->getCalleeFunc()->isDeclaration() &&
-          !DSG.getReturnNodes().count(CI->getCalleeFunc()))
-        CallerEdges[&getDSGraph(*CI->getCalleeFunc())]
+      if (!DSG.getReturnNodes().count(CI->getCalleeFunc()))
+        CallerEdges[&getOrCreateGraph(CI->getCalleeFunc())]
           .push_back(CallerCallEdge(&DSG, &*CI, CI->getCalleeFunc()));
       continue;
     }
@@ -325,7 +307,7 @@
       BUInfo->callee_begin(CallI), IPE = BUInfo->callee_end(CallI);
 
     // Skip over all calls to this graph (SCC calls).
-    while (IPI != IPE && &getDSGraph(*IPI->second) == &DSG)
+    while (IPI != IPE && &getOrCreateGraph(IPI->second) == &DSG)
       ++IPI;
 
     // All SCC calls?
@@ -335,15 +317,14 @@
     ++IPI;
 
     // Skip over more SCC calls.
-    while (IPI != IPE && &getDSGraph(*IPI->second) == &DSG)
+    while (IPI != IPE && &getOrCreateGraph(IPI->second) == &DSG)
       ++IPI;
 
     // If there is exactly one callee from this call site, remember the edge in
     // CallerEdges.
     if (IPI == IPE) {
-      if (!FirstCallee->isDeclaration())
-        CallerEdges[&getDSGraph(*FirstCallee)]
-          .push_back(CallerCallEdge(&DSG, &*CI, FirstCallee));
+      CallerEdges[&getOrCreateGraph(FirstCallee)]
+        .push_back(CallerCallEdge(&DSG, &*CI, FirstCallee));
       continue;
     }
 
@@ -356,8 +337,7 @@
     for (BUDataStructures::ActualCalleesTy::const_iterator I =
            BUInfo->callee_begin(CallI), E = BUInfo->callee_end(CallI);
          I != E; ++I)
-      if (!I->second->isDeclaration())
-        Callees.push_back(I->second);
+      Callees.push_back(I->second);
     std::sort(Callees.begin(), Callees.end());
 
     std::map<std::vector<Function*>, DSGraph*>::iterator IndCallRecI =
@@ -388,7 +368,7 @@
       // exactly once.
       DSCallSite *NCS = &IndCallGraph->getFunctionCalls().front();
       for (unsigned i = 0, e = Callees.size(); i != e; ++i) {
-        DSGraph& CalleeGraph = getDSGraph(*Callees[i]);
+        DSGraph& CalleeGraph = getOrCreateGraph(Callees[i]);
         if (&CalleeGraph != &DSG)
           CallerEdges[&CalleeGraph].push_back(CallerCallEdge(IndCallGraph, NCS,
                                                              Callees[i]));
@@ -401,66 +381,3 @@
     RC.mergeCallSite(IndCallGraph->getFunctionCalls().front(), *CI);
   }
 }
-
-
-static const Function *getFnForValue(const Value *V) {
-  if (const Instruction *I = dyn_cast<Instruction>(V))
-    return I->getParent()->getParent();
-  else if (const Argument *A = dyn_cast<Argument>(V))
-    return A->getParent();
-  else if (const BasicBlock *BB = dyn_cast<BasicBlock>(V))
-    return BB->getParent();
-  return 0;
-}
-
-void TDDataStructures::deleteValue(Value *V) {
-  if (const Function *F = getFnForValue(V)) {  // Function local value?
-    // If this is a function local value, just delete it from the scalar map!
-    getDSGraph(*F).getScalarMap().eraseIfExists(V);
-    return;
-  }
-
-  if (Function *F = dyn_cast<Function>(V)) {
-    assert(getDSGraph(*F).getReturnNodes().size() == 1 &&
-           "cannot handle scc's");
-    delete DSInfo[F];
-    DSInfo.erase(F);
-    return;
-  }
-
-  assert(!isa<GlobalVariable>(V) && "Do not know how to delete GV's yet!");
-}
-
-void TDDataStructures::copyValue(Value *From, Value *To) {
-  if (From == To) return;
-  if (const Function *F = getFnForValue(From)) {  // Function local value?
-    // If this is a function local value, just delete it from the scalar map!
-    getDSGraph(*F).getScalarMap().copyScalarIfExists(From, To);
-    return;
-  }
-
-  if (Function *FromF = dyn_cast<Function>(From)) {
-    Function *ToF = cast<Function>(To);
-    assert(!DSInfo.count(ToF) && "New Function already exists!");
-    DSGraph *NG = new DSGraph(getDSGraph(*FromF), GlobalECs);
-    DSInfo[ToF] = NG;
-    assert(NG->getReturnNodes().size() == 1 && "Cannot copy SCC's yet!");
-
-    // Change the Function* is the returnnodes map to the ToF.
-    DSNodeHandle Ret = NG->retnodes_begin()->second;
-    NG->getReturnNodes().clear();
-    NG->getReturnNodes()[ToF] = Ret;
-    return;
-  }
-
-  if (const Function *F = getFnForValue(To)) {
-    DSGraph &G = getDSGraph(*F);
-    G.getScalarMap().copyScalarIfExists(From, To);
-    return;
-  }
-
-  DOUT << *From;
-  DOUT << *To;
-  assert(0 && "Do not know how to copy this yet!");
-  abort();
-}






More information about the llvm-commits mailing list