[llvm-commits] [poolalloc] r56847 - in /poolalloc/trunk: include/dsa/DSGraph.h include/dsa/DSNode.h include/dsa/DataStructure.h lib/DSA/BottomUpClosure.cpp lib/DSA/DataStructure.cpp lib/DSA/Local.cpp lib/DSA/StdLibPass.cpp lib/DSA/TopDownClosure.cpp

Andrew Lenharth alenhar2 at cs.uiuc.edu
Tue Sep 30 08:28:27 PDT 2008


Author: alenhar2
Date: Tue Sep 30 10:28:27 2008
New Revision: 56847

URL: http://llvm.org/viewvc/llvm-project?rev=56847&view=rev
Log:
fix recent bug on mailing list

Modified:
    poolalloc/trunk/include/dsa/DSGraph.h
    poolalloc/trunk/include/dsa/DSNode.h
    poolalloc/trunk/include/dsa/DataStructure.h
    poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
    poolalloc/trunk/lib/DSA/DataStructure.cpp
    poolalloc/trunk/lib/DSA/Local.cpp
    poolalloc/trunk/lib/DSA/StdLibPass.cpp
    poolalloc/trunk/lib/DSA/TopDownClosure.cpp

Modified: poolalloc/trunk/include/dsa/DSGraph.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSGraph.h?rev=56847&r1=56846&r2=56847&view=diff

==============================================================================
--- poolalloc/trunk/include/dsa/DSGraph.h (original)
+++ poolalloc/trunk/include/dsa/DSGraph.h Tue Sep 30 10:28:27 2008
@@ -305,6 +305,10 @@
     return AuxFunctionCalls;
   }
 
+  /// removeFunction - Specify that all call sites to the function have been
+  /// fully specified by a pass such as StdLibPass.
+  void removeFunctionCalls(Function& F);
+
   // Function Call iteration
   typedef std::list<DSCallSite>::const_iterator fc_iterator;
   fc_iterator fc_begin() const { return FunctionCalls.begin(); }

Modified: poolalloc/trunk/include/dsa/DSNode.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSNode.h?rev=56847&r1=56846&r2=56847&view=diff

==============================================================================
--- poolalloc/trunk/include/dsa/DSNode.h (original)
+++ poolalloc/trunk/include/dsa/DSNode.h Tue Sep 30 10:28:27 2008
@@ -462,7 +462,7 @@
 }
 
 inline void DSNodeHandle::setTo(DSNode *n, unsigned NewOffset) const {
-  assert(!n || !n->isForwarding() && "Cannot set node to a forwarded node!");
+  assert((!n || !n->isForwarding()) && "Cannot set node to a forwarded node!");
   if (N) getNode()->NumReferrers--;
   N = n;
   Offset = NewOffset;

Modified: poolalloc/trunk/include/dsa/DataStructure.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DataStructure.h?rev=56847&r1=56846&r2=56847&view=diff

==============================================================================
--- poolalloc/trunk/include/dsa/DataStructure.h (original)
+++ poolalloc/trunk/include/dsa/DataStructure.h Tue Sep 30 10:28:27 2008
@@ -189,8 +189,6 @@
 
   virtual bool runOnModule(Module &M);
 
-  DSGraph &CreateGraphForExternalFunction(const Function &F);
-
   /// deleteValue/copyValue - Interfaces to update the DSGraphs in the program.
   /// These correspond to the interfaces defined in the AliasAnalysis class.
   void deleteValue(Value *V);

Modified: poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/BottomUpClosure.cpp?rev=56847&r1=56846&r2=56847&view=diff

==============================================================================
--- poolalloc/trunk/lib/DSA/BottomUpClosure.cpp (original)
+++ poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Tue Sep 30 10:28:27 2008
@@ -121,10 +121,19 @@
 static void GetAllCallees(const DSCallSite &CS,
                           std::vector<Function*> &Callees) {
   if (CS.isDirectCall()) {
-    Callees.push_back(CS.getCalleeFunc());
+    if (!CS.getCalleeFunc()->isDeclaration())
+      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 (Callees[i]->isDeclaration()) {
+        Callees.erase(Callees.begin()+OldSize, Callees.end());
+        return;
+      }
   }
 }
 
@@ -145,6 +154,16 @@
   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.
@@ -269,31 +288,6 @@
   GlobalsGraph = 0;
 }
 
-DSGraph &BUDataStructures::CreateGraphForExternalFunction(const Function &Fn) {
-  Function *F = const_cast<Function*>(&Fn);
-  DSGraph *DSG = new DSGraph(GlobalECs, GlobalsGraph->getTargetData());
-  DSInfo[F] = DSG;
-  DSG->setGlobalsGraph(GlobalsGraph);
-  DSG->setPrintAuxCalls();
-
-  // Add function to the graph.
-  DSG->getReturnNodes().insert(std::make_pair(F, DSNodeHandle()));
-
-  if (F->getName() == "free") { // Taking the address of free.
-
-    // Free should take a single pointer argument, mark it as heap memory.
-    DSNodeHandle N(new DSNode(0, DSG));
-    N.getNode()->setHeapMarker();
-    DSG->getNodeForValue(F->arg_begin()).mergeWith(N);
-
-  } else {
-    cerr << "Unrecognized external function: " << F->getName() << "\n";
-    abort();
-  }
-
-  return *DSG;
-}
-
 void BUDataStructures::calculateGraph(DSGraph &Graph) {
   // If this graph contains the main function, clone the globals graph into this
   // graph before we inline callees and other fun stuff.

Modified: poolalloc/trunk/lib/DSA/DataStructure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DataStructure.cpp?rev=56847&r1=56846&r2=56847&view=diff

==============================================================================
--- poolalloc/trunk/lib/DSA/DataStructure.cpp (original)
+++ poolalloc/trunk/lib/DSA/DataStructure.cpp Tue Sep 30 10:28:27 2008
@@ -186,8 +186,8 @@
 
 void DSNode::assertOK() const {
   assert((Ty != Type::VoidTy ||
-          Ty == Type::VoidTy && (Size == 0 ||
-                                 (NodeType & DSNode::ArrayNode))) &&
+          (Ty == Type::VoidTy && (Size == 0 ||
+                                  (NodeType & DSNode::ArrayNode)))) &&
          "Node not OK!");
 
   assert(ParentGraph && "Node has no parent?");
@@ -756,8 +756,8 @@
     // Check to see if we have a pointer & integer mismatch going on here,
     // loading a pointer as a long, for example.
     //
-    if (SubType->isInteger() && isa<PointerType>(NewTy) ||
-        NewTy->isInteger() && isa<PointerType>(SubType))
+    if ((SubType->isInteger() && isa<PointerType>(NewTy)) ||
+        (NewTy->isInteger() && isa<PointerType>(SubType)))
       return false;
   } else if (NewTySize > SubTypeSize && NewTySize <= PadSize) {
     // We are accessing the field, plus some structure padding.  Ignore the
@@ -1490,6 +1490,22 @@
     }
 }
 
+void DSGraph::removeFunctionCalls(Function& F) {
+  for (std::list<DSCallSite>::iterator I = FunctionCalls.begin(),
+         E = FunctionCalls.end(); I != E; ++I)
+    if (I->isDirectCall() && &I->getCaller() == &F) {
+      FunctionCalls.erase(I);
+      break;
+    }
+
+  for (std::list<DSCallSite>::iterator I = AuxFunctionCalls.begin(),
+         E = AuxFunctionCalls.end(); I != E; ++I)
+    if (I->isDirectCall() && &I->getCaller() == &F) {
+      AuxFunctionCalls.erase(I);
+      break;
+    }
+}
+
 /// addObjectToGraph - This method can be used to add global, stack, and heap
 /// objects to the graph.  This can be used when updating DSGraphs due to the
 /// introduction of new temporary objects.  The new object is not pointed to
@@ -1891,11 +1907,12 @@
 
   // Calculate the arguments vector...
   for (CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end(); I != E; ++I)
-    if (isa<PointerType>((*I)->getType()))
+    if (isa<PointerType>((*I)->getType())) {
       if (isa<ConstantPointerNull>(*I))
         Args.push_back(DSNodeHandle());
       else
         Args.push_back(getNodeForValue(*I));
+    }
 
   // Add a new function call entry...
   if (Function *F = CS.getCalledFunction())
@@ -2730,7 +2747,7 @@
     //Clone or Steal the Source Graph
     DSGraph &BaseGraph = GraphSource->getDSGraph(*F);
     if (Clone) {
-      G = new DSGraph(BaseGraph, GlobalECs, DSGraph::DontCloneAuxCallNodes);
+      G = new DSGraph(BaseGraph, GlobalECs);
     } else {
       G = new DSGraph(GlobalECs, GraphSource->getTargetData());
       G->spliceFrom(BaseGraph);

Modified: poolalloc/trunk/lib/DSA/Local.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/Local.cpp?rev=56847&r1=56846&r2=56847&view=diff

==============================================================================
--- poolalloc/trunk/lib/DSA/Local.cpp (original)
+++ poolalloc/trunk/lib/DSA/Local.cpp Tue Sep 30 10:28:27 2008
@@ -137,37 +137,27 @@
         if (isa<PointerType>(I->getType())) {
           DSNode * Node = getValueDest(*I).getNode();
 
-          if (!f.hasInternalLinkage() || f.isDeclaration()) {
+          if (!f.hasInternalLinkage())
             Node->setExternalMarker();
-            //pecimistic assumptions on externals
-            if (f.isDeclaration())
-              Node->setReadMarker()->setModifiedMarker();
-          }
+
         }
       }
 
       // Create an entry for the return, which tracks which functions are in the graph
       g.getOrCreateReturnNodeFor(f);
 
-      if (!f.isDeclaration()) {
-        visit(f);  // Single pass over the function
+      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));
-        }
-      } 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());
+      // 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));
       }
       
       g.markIncompleteNodes(DSGraph::MarkFormalArgs);
@@ -762,11 +752,12 @@
   formGlobalECs();
 
   // Calculate all of the graphs...
-  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));
-  }
+  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));
+    }
 
   GlobalsGraph->removeTriviallyDeadNodes();
   GlobalsGraph->markIncompleteNodes(DSGraph::MarkFormalArgs);

Modified: poolalloc/trunk/lib/DSA/StdLibPass.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/StdLibPass.cpp?rev=56847&r1=56846&r2=56847&view=diff

==============================================================================
--- poolalloc/trunk/lib/DSA/StdLibPass.cpp (original)
+++ poolalloc/trunk/lib/DSA/StdLibPass.cpp Tue Sep 30 10:28:27 2008
@@ -31,6 +31,69 @@
 
 char StdLibDataStructures::ID;
 
+struct libAction {
+  bool ret_read, ret_write, ret_heap;
+  bool args_read, args_write, args_heap;
+  bool mergeAllArgs;
+  bool mergeWithRet;
+  bool collapse;
+};
+
+const struct {
+  const char* name;
+  libAction action;
+} recFuncs[] = {
+  {"calloc",   {false,  true,  true, false, false, false, false, false, false}},
+  {"malloc",   {false,  true,  true, false, false, false, false, false, false}},
+  {"valloc",   {false,  true,  true, false, false, false, false, false, false}},
+  {"memalign", {false,  true,  true, false, false, false, false, false, false}},
+  {"strdup",   {false,  true,  true, false, false, false, false, false,  true}},
+  {"wcsdup",   {false,  true,  true, false, false, false, false, false,  true}},
+  {"free",     {false, false, false, false,  true,  true, false, false, false}},
+  {"realloc",  {false,  true,  true, false,  true,  true, false,  true,  true}},
+  {"atoi",     {false, false, false,  true, false, false, false, false, false}},
+  {"atof",     {false, false, false,  true, false, false, false, false, false}},
+  {"atol",     {false, false, false,  true, false, false, false, false, false}},
+  {"atoll",    {false, false, false,  true, false, false, false, false, false}},
+  {"remove",   {false, false, false,  true, false, false, false, false, false}},
+  {"unlink",   {false, false, false,  true, false, false, false, false, false}},
+  {"rename",   {false, false, false,  true, false, false, false, false, false}},
+  {"memcmp",   {false, false, false,  true, false, false, false, false, false}},
+  {"strcmp",   {false, false, false,  true, false, false, false, false, false}},
+  {"strncmp",  {false, false, false,  true, false, false, false, false, false}},
+  {"execl",    {false, false, false,  true, false, false, false, false, false}},
+  {"execlp",   {false, false, false,  true, false, false, false, false, false}},
+  {"execle",   {false, false, false,  true, false, false, false, false, false}},
+  {"execv",    {false, false, false,  true, false, false, false, false, false}},
+  {"execvp",   {false, false, false,  true, false, false, false, false, false}},
+  {"chmod",    {false, false, false,  true, false, false, false, false, false}},
+  {"puts",     {false, false, false,  true, false, false, false, false, false}},
+  {"write",    {false, false, false,  true, false, false, false, false, false}},
+  {"open",     {false, false, false,  true, false, false, false, false, false}},
+  {"create",   {false, false, false,  true, false, false, false, false, false}},
+  {"truncate", {false, false, false,  true, false, false, false, false, false}},
+  {"chdir",    {false, false, false,  true, false, false, false, false, false}},
+  {"mkdir",    {false, false, false,  true, false, false, false, false, false}},
+  {"rmdir",    {false, false, false,  true, false, false, false, false, false}},
+  {"strlen",   {false, false, false,  true, false, false, false, false, false}},
+  {"read",     {false, false, false, false,  true, false, false, false, false}},
+  {"pipe",     {false, false, false, false,  true, false, false, false, false}},
+  {"wait",     {false, false, false, false,  true, false, false, false, false}},
+  {"time",     {false, false, false, false,  true, false, false, false, false}},
+  {"getrusage",{false, false, false, false,  true, false, false, false, false}},
+  {"memchr",   { true, false, false,  true, false, false, false,  true,  true}},
+  {"memrchr",  { true, false, false,  true, false, false, false,  true,  true}},
+  {"rawmemchr",{ true, false, false,  true, false, false, false,  true,  true}},
+  {"memmove",  {false,  true, false,  true,  true, false,  true,  true,  true}},
+  {"bcopy",    {false, false, false,  true,  true, false,  true, false,  true}},
+  {"strcpy",   {false,  true, false,  true,  true, false,  true,  true,  true}},
+  {"strncpy",  {false,  true, false,  true,  true, false,  true,  true,  true}},
+  {"memccpy",  {false,  true, false,  true,  true, false,  true,  true,  true}},
+  {"wcscpy",   {false,  true, false,  true,  true, false,  true,  true,  true}},
+  {"wcsncpy",  {false,  true, false,  true,  true, false,  true,  true,  true}},
+  {"wmemccpy", {false,  true, false,  true,  true, false,  true,  true,  true}},
+};
+
 bool StdLibDataStructures::runOnModule(Module &M) {
   LocalDataStructures &LocalDSA = getAnalysis<LocalDataStructures>();
   setGraphSource(&LocalDSA);
@@ -41,108 +104,61 @@
   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() && !(I->isVarArg())) {
-      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") {
-        if (isa<PointerType>(I->getReturnType())) {
-          Graph.getReturnNodeFor(*I).getNode()->clearNodeFlags()
-            ->setHeapMarker()->setModifiedMarker();
-          Graph.getNodeForValue(I->arg_begin()).getNode()->clearNodeFlags()
-            ->mergeWith(Graph.getReturnNodeFor(*I), 0);
-        }
-      } else if (Name == "strdup") {
-        Graph.getReturnNodeFor(*I).getNode()->clearNodeFlags()
-          ->setHeapMarker()->setModifiedMarker();
-      } 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::getUnqual(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";
-      }
-    }
-  }
-
+  //Clone Module
+  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) 
+    if (!I->isDeclaration())
+      getOrCreateGraph(&*I);
+
+  for (int x = 0; recFuncs[x].name; ++x)
+    if (Function* F = M.getFunction(recFuncs[x].name))
+      if (F->isDeclaration())
+        for (Value::use_iterator ii = F->use_begin(), ee = F->use_end();
+             ii != ee; ++ii)
+          if (CallInst* CI = dyn_cast<CallInst>(ii))
+            if (CI->getOperand(0) == F) {
+              DSGraph& Graph = getDSGraph(*CI->getParent()->getParent());
+              if (recFuncs[x].action.ret_read)
+                Graph.getNodeForValue(CI).getNode()->setReadMarker();
+              if (recFuncs[x].action.ret_write)
+                Graph.getNodeForValue(CI).getNode()->setModifiedMarker();
+              if (recFuncs[x].action.ret_heap)
+                Graph.getNodeForValue(CI).getNode()->setHeapMarker();
+
+              if (recFuncs[x].action.args_read)
+                for (unsigned y = 1; y < CI->getNumOperands(); ++y)
+                  if (isa<PointerType>(CI->getOperand(y)->getType()))
+                    Graph.getNodeForValue(CI->getOperand(y)).getNode()->setReadMarker();
+              if (recFuncs[x].action.args_write)
+                for (unsigned y = 1; y < CI->getNumOperands(); ++y)
+                  if (isa<PointerType>(CI->getOperand(y)->getType()))
+                    Graph.getNodeForValue(CI->getOperand(y)).getNode()->setModifiedMarker();
+              if (recFuncs[x].action.args_heap)
+                for (unsigned y = 1; y < CI->getNumOperands(); ++y)
+                  if (isa<PointerType>(CI->getOperand(y)->getType()))
+                    Graph.getNodeForValue(CI->getOperand(y)).getNode()->setHeapMarker();
+
+              std::vector<DSNodeHandle> toMerge;
+              if (recFuncs[x].action.mergeWithRet)
+                toMerge.push_back(Graph.getNodeForValue(CI));
+              if (recFuncs[x].action.mergeAllArgs || recFuncs[x].action.mergeWithRet)
+                for (unsigned y = 1; y < CI->getNumOperands(); ++y)
+                  if (isa<PointerType>(CI->getOperand(y)->getType()))
+                    toMerge.push_back(Graph.getNodeForValue(CI->getOperand(y)));
+              for (unsigned y = 1; y < toMerge.size(); ++y)
+                toMerge[0].mergeWith(toMerge[y]);
+
+              if (recFuncs[x].action.collapse) {
+                Graph.getNodeForValue(CI).getNode()->foldNodeCompletely();
+                for (unsigned y = 1; y < CI->getNumOperands(); ++y)
+                  if (isa<PointerType>(CI->getOperand(y)->getType()))
+                    Graph.getNodeForValue(CI->getOperand(y)).getNode()->foldNodeCompletely();
+              }
+
+              //delete the call
+              DOUT << "Removing " << F->getName() << " from " << CI->getParent()->getParent()->getName() << "\n";
+              Graph.removeFunctionCalls(*F);
+            }
+  
   return false;
 }
 

Modified: poolalloc/trunk/lib/DSA/TopDownClosure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/TopDownClosure.cpp?rev=56847&r1=56846&r2=56847&view=diff

==============================================================================
--- poolalloc/trunk/lib/DSA/TopDownClosure.cpp (original)
+++ poolalloc/trunk/lib/DSA/TopDownClosure.cpp Tue Sep 30 10:28:27 2008
@@ -95,7 +95,7 @@
 
   // Functions without internal linkage also have unknown incoming arguments!
   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
-    if (!I->hasInternalLinkage())
+    if (!I->isDeclaration() && !I->hasInternalLinkage())
       ArgsRemainIncomplete.insert(I);
 
   // We want to traverse the call graph in reverse post-order.  To do this, we
@@ -108,7 +108,8 @@
 
   // Visit each of the graphs in reverse post-order now!
   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
-    getOrCreateGraph(*I);
+    if (!I->isDeclaration(*I)
+        getOrCreateGraph(*I);
   return false;
 }
 #endif
@@ -153,6 +154,7 @@
 
 void TDDataStructures::ComputePostOrder(Function &F,hash_set<DSGraph*> &Visited,
                                         std::vector<DSGraph*> &PostOrder) {
+  if (F.isDeclaration()) return;
   DSGraph &G = getOrCreateGraph(&F);
   if (Visited.count(&G)) return;
   Visited.insert(&G);
@@ -297,7 +299,8 @@
 
     // Handle direct calls efficiently.
     if (CI->isDirectCall()) {
-      if (!DSG.getReturnNodes().count(CI->getCalleeFunc()))
+      if (!CI->getCalleeFunc()->isDeclaration() &&
+          !DSG.getReturnNodes().count(CI->getCalleeFunc()))
         CallerEdges[&getOrCreateGraph(CI->getCalleeFunc())]
           .push_back(CallerCallEdge(&DSG, &*CI, CI->getCalleeFunc()));
       continue;
@@ -309,7 +312,7 @@
       BUInfo->callee_begin(CallI), IPE = BUInfo->callee_end(CallI);
 
     // Skip over all calls to this graph (SCC calls).
-    while (IPI != IPE && &getOrCreateGraph(IPI->second) == &DSG)
+    while (IPI != IPE && &getDSGraph(*IPI->second) == &DSG)
       ++IPI;
 
     // All SCC calls?
@@ -319,14 +322,15 @@
     ++IPI;
 
     // Skip over more SCC calls.
-    while (IPI != IPE && &getOrCreateGraph(IPI->second) == &DSG)
+    while (IPI != IPE && &getDSGraph(*IPI->second) == &DSG)
       ++IPI;
 
     // If there is exactly one callee from this call site, remember the edge in
     // CallerEdges.
     if (IPI == IPE) {
-      CallerEdges[&getOrCreateGraph(FirstCallee)]
-        .push_back(CallerCallEdge(&DSG, &*CI, FirstCallee));
+      if (!FirstCallee->isDeclaration())
+        CallerEdges[&getOrCreateGraph(FirstCallee)]
+          .push_back(CallerCallEdge(&DSG, &*CI, FirstCallee));
       continue;
     }
 
@@ -339,7 +343,8 @@
     for (BUDataStructures::ActualCalleesTy::const_iterator I =
            BUInfo->callee_begin(CallI), E = BUInfo->callee_end(CallI);
          I != E; ++I)
-      Callees.push_back(I->second);
+      if (!I->second->isDeclaration())
+        Callees.push_back(I->second);
     std::sort(Callees.begin(), Callees.end());
 
     std::map<std::vector<Function*>, DSGraph*>::iterator IndCallRecI =
@@ -370,7 +375,7 @@
       // exactly once.
       DSCallSite *NCS = &IndCallGraph->getFunctionCalls().front();
       for (unsigned i = 0, e = Callees.size(); i != e; ++i) {
-        DSGraph& CalleeGraph = getOrCreateGraph(Callees[i]);
+        DSGraph& CalleeGraph = getDSGraph(*Callees[i]);
         if (&CalleeGraph != &DSG)
           CallerEdges[&CalleeGraph].push_back(CallerCallEdge(IndCallGraph, NCS,
                                                              Callees[i]));





More information about the llvm-commits mailing list