[llvm-commits] [parallel] CVS: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp DataStructure.cpp Local.cpp Printer.cpp

Misha Brukman brukman at cs.uiuc.edu
Wed Mar 10 19:29:01 PST 2004


Changes in directory llvm/lib/Analysis/DataStructure:

BottomUpClosure.cpp updated: 1.70.4.1 -> 1.70.4.2
DataStructure.cpp updated: 1.131.4.1 -> 1.131.4.2
Local.cpp updated: 1.74.4.1 -> 1.74.4.2
Printer.cpp updated: 1.62.4.1 -> 1.62.4.2

---
Log message:

Merge from trunk.

---
Diffs of the changes:  (+288 -34)

Index: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp
diff -u llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.70.4.1 llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.70.4.2
--- llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.70.4.1	Mon Mar  1 17:58:12 2004
+++ llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp	Wed Mar 10 19:28:21 2004
@@ -100,6 +100,9 @@
   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->isExternal()) {   // sprintf, fprintf, sscanf, etc...
     // No callees!
     Stack.pop_back();
@@ -167,6 +170,8 @@
       // graph sizes.
       DSGraph &NFGraph = getDSGraph(*NF);
       SCCGraphs.insert(&NFGraph);
+      // FIXME: If we used a better way of cloning graphs (ie, just splice all
+      // of the nodes into the new graph), this would be completely unneeded!
       if (!SCCGraph || SCCGraph->getGraphSize() < NFGraph.getGraphSize())
         SCCGraph = &NFGraph;
     } while (NF != F);
@@ -186,9 +191,11 @@
            E = SCCGraphs.end(); I != E; ++I) {
       DSGraph &G = **I;
       if (&G != SCCGraph) {
-        DSGraph::NodeMapTy NodeMap;
-        SCCGraph->cloneInto(G, SCCGraph->getScalarMap(),
-                            SCCGraph->getReturnNodes(), NodeMap);
+        {
+          DSGraph::NodeMapTy NodeMap;
+          SCCGraph->cloneInto(G, SCCGraph->getScalarMap(),
+                              SCCGraph->getReturnNodes(), NodeMap);
+        }
         // Update the DSInfo map and delete the old graph...
         for (DSGraph::ReturnNodesTy::iterator I = G.getReturnNodes().begin(),
                E = G.getReturnNodes().end(); I != E; ++I)
@@ -278,16 +285,12 @@
       // Get the data structure graph for the called function.
       //
       DSGraph &GI = getDSGraph(*Callee);  // Graph to inline
-      
-      if (Callee->getName() == "bc_raise")
-        std::cerr << "HERE!\n";
 
       DEBUG(std::cerr << "    Inlining graph for " << Callee->getName()
             << "[" << GI.getGraphSize() << "+"
             << GI.getAuxFunctionCalls().size() << "] into '"
             << Graph.getFunctionNames() << "' [" << Graph.getGraphSize() << "+"
             << Graph.getAuxFunctionCalls().size() << "]\n");
-      
       Graph.mergeInGraph(CS, *Callee, GI,
                          DSGraph::KeepModRefBits | 
                          DSGraph::StripAllocaBit | DSGraph::DontCloneCallNodes);


Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp
diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.131.4.1 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.131.4.2
--- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.131.4.1	Mon Mar  1 17:58:12 2004
+++ llvm/lib/Analysis/DataStructure/DataStructure.cpp	Wed Mar 10 19:28:21 2004
@@ -11,7 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/Analysis/DSGraph.h"
+#include "llvm/Analysis/DSGraphTraits.h"
 #include "llvm/Function.h"
 #include "llvm/GlobalVariable.h"
 #include "llvm/iOther.h"
@@ -20,6 +20,7 @@
 #include "llvm/Assembly/Writer.h"
 #include "Support/CommandLine.h"
 #include "Support/Debug.h"
+#include "Support/DepthFirstIterator.h"
 #include "Support/STLExtras.h"
 #include "Support/Statistic.h"
 #include "Support/Timer.h"
@@ -80,10 +81,11 @@
 // DSNode copy constructor... do not copy over the referrers list!
 DSNode::DSNode(const DSNode &N, DSGraph *G, bool NullLinks)
   : NumReferrers(0), Size(N.Size), ParentGraph(G),
-    Ty(N.Ty), Globals(N.Globals), NodeType(N.NodeType) {
-  if (!NullLinks)
+    Ty(N.Ty), NodeType(N.NodeType) {
+  if (!NullLinks) {
     Links = N.Links;
-  else
+    Globals = N.Globals;
+  } else
     Links.resize(N.Links.size()); // Create the appropriate number of null links
   G->addNode(this);
   ++NumNodeAllocated;
@@ -630,6 +632,8 @@
 void DSNode::MergeNodes(DSNodeHandle& CurNodeH, DSNodeHandle& NH) {
   assert(CurNodeH.getOffset() >= NH.getOffset() &&
          "This should have been enforced in the caller.");
+  assert(CurNodeH.getNode()->getParentGraph()==NH.getNode()->getParentGraph() &&
+         "Cannot merge two nodes that are not in the same graph!");
 
   // Now we know that Offset >= NH.Offset, so convert it so our "Offset" (with
   // respect to NH.Offset) is now zero.  NOffset is the distance from the base
@@ -781,6 +785,23 @@
   if (!NH.isNull())    // Node already mapped?
     return DSNodeHandle(NH.getNode(), NH.getOffset()+SrcNH.getOffset());
 
+  // If SrcNH has globals and the destination graph has one of the same globals,
+  // merge this node with the destination node, which is much more efficient.
+  if (SN->global_begin() != SN->global_end()) {
+    DSScalarMap &DestSM = Dest.getScalarMap();
+    for (DSNode::global_iterator I = SN->global_begin(), E = SN->global_end();
+         I != E; ++I) {
+      GlobalValue *GV = *I;
+      DSScalarMap::iterator GI = DestSM.find(GV);
+      if (GI != DestSM.end() && !GI->second.isNull()) {
+        // We found one, use merge instead!
+        merge(GI->second, Src.getNodeForValue(GV));
+        assert(!NH.isNull() && "Didn't merge node!");
+        return DSNodeHandle(NH.getNode(), NH.getOffset()+SrcNH.getOffset());
+      }
+    }
+  }
+
   DSNode *DN = new DSNode(*SN, &Dest, true /* Null out all links */);
   DN->maskNodeTypes(BitsToKeep);
   NH = DN;
@@ -823,6 +844,7 @@
     if (CloneFlags & DSGraph::UpdateInlinedGlobals)
       Dest.getInlinedGlobals().insert(GV);
   }
+  NH.getNode()->mergeGlobals(SN->getGlobals());
 
   return DSNodeHandle(NH.getNode(), NH.getOffset()+SrcNH.getOffset());
 }
@@ -912,6 +934,7 @@
         if (CloneFlags & DSGraph::UpdateInlinedGlobals)
           Dest.getInlinedGlobals().insert(GV);
       }
+      NH.getNode()->mergeGlobals(SN->getGlobals());
     }
   } else {
     // We cannot handle this case without allocating a temporary node.  Fall
@@ -963,19 +986,25 @@
       // wrapping), but if the current node gets collapsed due to
       // recursive merging, we must make sure to merge in all remaining
       // links at offset zero.
-      unsigned MergeOffset = 0;
       DSNode *CN = SCNH.getNode();
-      if (CN->getSize() != 1)
-        MergeOffset = ((i << DS::PointerShift)+SCNH.getOffset()) %CN->getSize();
+      unsigned MergeOffset =
+        ((i << DS::PointerShift)+SCNH.getOffset()) % CN->getSize();
       
-      DSNodeHandle &Link = CN->getLink(MergeOffset);
-      if (!Link.isNull()) {
+      DSNodeHandle Tmp = CN->getLink(MergeOffset);
+      if (!Tmp.isNull()) {
         // Perform the recursive merging.  Make sure to create a temporary NH,
         // because the Link can disappear in the process of recursive merging.
-        DSNodeHandle Tmp = Link;
         merge(Tmp, SrcEdge);
       } else {
-        merge(Link, SrcEdge);
+        Tmp.mergeWith(getClonedNH(SrcEdge));
+        // Merging this could cause all kinds of recursive things to happen,
+        // culminating in the current node being eliminated.  Since this is
+        // possible, make sure to reaquire the link from 'CN'.
+
+        unsigned MergeOffset = 0;
+        CN = SCNH.getNode();
+        MergeOffset = ((i << DS::PointerShift)+SCNH.getOffset()) %CN->getSize();
+        CN->getLink(MergeOffset).mergeWith(Tmp);
       }
     }
   }
@@ -1181,6 +1210,23 @@
   }
 }
 
+static bool PathExistsToClonedNode(const DSNode *N, ReachabilityCloner &RC) {
+  if (N)
+    for (df_iterator<const DSNode*> I = df_begin(N), E = df_end(N); I != E; ++I)
+      if (RC.hasClonedNode(*I))
+        return true;
+  return false;
+}
+
+static bool PathExistsToClonedNode(const DSCallSite &CS,
+                                   ReachabilityCloner &RC) {
+  if (PathExistsToClonedNode(CS.getRetVal().getNode(), RC))
+    return true;
+  for (unsigned i = 0, e = CS.getNumPtrArgs(); i != e; ++i)
+    if (PathExistsToClonedNode(CS.getPtrArg(i).getNode(), RC))
+      return true;
+  return false;
+}
 
 /// mergeInGraph - The method is used for merging graphs together.  If the
 /// argument graph is not *this, it makes a clone of the specified graph, then
@@ -1191,6 +1237,10 @@
                            const DSGraph &Graph, unsigned CloneFlags) {
   TIME_REGION(X, "mergeInGraph");
 
+  // Fastpath for a noop inline.
+  if (CS.getNumPtrArgs() == 0 && CS.getRetVal().isNull())
+    return;
+
   // If this is not a recursive call, clone the graph into this graph...
   if (&Graph != this) {
     // Clone the callee's graph into the current graph, keeping track of where
@@ -1218,29 +1268,72 @@
     // Map the return node pointer over.
     if (!CS.getRetVal().isNull())
       RC.merge(CS.getRetVal(), Graph.getReturnNodeFor(F));
-    
-    // If requested, copy the calls or aux-calls lists.
+
+    // If requested, copy all of the calls.
     if (!(CloneFlags & DontCloneCallNodes)) {
       // Copy the function calls list...
       FunctionCalls.reserve(FunctionCalls.size()+Graph.FunctionCalls.size());
       for (unsigned i = 0, ei = Graph.FunctionCalls.size(); i != ei; ++i)
         FunctionCalls.push_back(DSCallSite(Graph.FunctionCalls[i], RC));
     }
-    
+
+    // If the user has us copying aux calls (the normal case), set up a data
+    // structure to keep track of which ones we've copied over.
+    std::vector<bool> CopiedAuxCall;
     if (!(CloneFlags & DontCloneAuxCallNodes)) {
-      // Copy the auxiliary function calls list...
       AuxFunctionCalls.reserve(AuxFunctionCalls.size()+
                                Graph.AuxFunctionCalls.size());
-      for (unsigned i = 0, ei = Graph.AuxFunctionCalls.size(); i != ei; ++i)
-        AuxFunctionCalls.push_back(DSCallSite(Graph.AuxFunctionCalls[i], RC));
+      CopiedAuxCall.resize(Graph.AuxFunctionCalls.size());
     }
     
     // Clone over all globals that appear in the caller and callee graphs.
+    hash_set<GlobalVariable*> NonCopiedGlobals;
     for (DSScalarMap::global_iterator GI = Graph.getScalarMap().global_begin(),
            E = Graph.getScalarMap().global_end(); GI != E; ++GI)
       if (GlobalVariable *GV = dyn_cast<GlobalVariable>(*GI))
         if (ScalarMap.count(GV))
           RC.merge(ScalarMap[GV], Graph.getNodeForValue(GV));
+        else
+          NonCopiedGlobals.insert(GV);
+    
+    // If the global does not appear in the callers graph we generally don't
+    // want to copy the node.  However, if there is a path from the node global
+    // node to a node that we did copy in the graph, we *must* copy it to
+    // maintain the connection information.  Every time we decide to include a
+    // new global, this might make other globals live, so we must iterate
+    // unfortunately.
+    bool MadeChange = true;
+    while (MadeChange) {
+      MadeChange = false;
+      for (hash_set<GlobalVariable*>::iterator I = NonCopiedGlobals.begin();
+           I != NonCopiedGlobals.end();) {
+        DSNode *GlobalNode = Graph.getNodeForValue(*I).getNode();
+        if (RC.hasClonedNode(GlobalNode)) {
+          // Already cloned it, remove from set.
+          NonCopiedGlobals.erase(I++);
+          MadeChange = true;
+        } else if (PathExistsToClonedNode(GlobalNode, RC)) {
+          RC.getClonedNH(Graph.getNodeForValue(*I));
+          NonCopiedGlobals.erase(I++);
+          MadeChange = true;
+        } else {
+          ++I;
+        }
+      }
+
+      // If requested, copy any aux calls that can reach copied nodes.
+      if (!(CloneFlags & DontCloneAuxCallNodes)) {
+        for (unsigned i = 0, ei = Graph.AuxFunctionCalls.size(); i != ei; ++i)
+          if (!CopiedAuxCall[i] &&
+              PathExistsToClonedNode(Graph.AuxFunctionCalls[i], RC)) {
+            AuxFunctionCalls.push_back(DSCallSite(Graph.AuxFunctionCalls[i],
+                                                  RC));
+            CopiedAuxCall[i] = true;
+            MadeChange = true;
+          }
+      }
+    }
+
   } else {
     DSNodeHandle RetVal = getReturnNodeFor(F);
 
@@ -1282,6 +1375,30 @@
   return DSCallSite(CallSite(), getReturnNodeFor(F), &F, Args);
 }
 
+/// getDSCallSiteForCallSite - Given an LLVM CallSite object that is live in
+/// the context of this graph, return the DSCallSite for it.
+DSCallSite DSGraph::getDSCallSiteForCallSite(CallSite CS) const {
+  DSNodeHandle RetVal;
+  Instruction *I = CS.getInstruction();
+  if (isPointerType(I->getType()))
+    RetVal = getNodeForValue(I);
+
+  std::vector<DSNodeHandle> Args;
+  Args.reserve(CS.arg_end()-CS.arg_begin());
+
+  // Calculate the arguments vector...
+  for (CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end(); I != E; ++I)
+    if (isPointerType((*I)->getType()))
+      Args.push_back(getNodeForValue(*I));
+
+  // Add a new function call entry...
+  if (Function *F = CS.getCalledFunction())
+    return DSCallSite(CS, RetVal, F, Args);
+  else
+    return DSCallSite(CS, RetVal,
+                      getNodeForValue(CS.getCalledValue()).getNode(), Args);
+}
+
 
 
 // markIncompleteNodes - Mark the specified node as having contents that are not
@@ -1348,7 +1465,7 @@
     for (DSScalarMap::global_iterator I = ScalarMap.global_begin(),
            E = ScalarMap.global_end(); I != E; ++I)
       if (GlobalVariable *GV = dyn_cast<GlobalVariable>(*I))
-        if (!GV->isConstant())
+        if (!GV->isConstant() || !GV->hasInitializer())
           markIncompleteNode(ScalarMap[GV].getNode());
 }
 
@@ -1799,6 +1916,29 @@
   DEBUG(AssertGraphOK(); GlobalsGraph->AssertGraphOK());
 }
 
+void DSGraph::AssertCallSiteInGraph(const DSCallSite &CS) const {
+  if (CS.isIndirectCall()) {
+    AssertNodeInGraph(CS.getCalleeNode());
+#if 0
+    if (CS.getNumPtrArgs() && CS.getCalleeNode() == CS.getPtrArg(0).getNode() &&
+        CS.getCalleeNode() && CS.getCalleeNode()->getGlobals().empty())
+      std::cerr << "WARNING: WIERD CALL SITE FOUND!\n";      
+#endif
+  }
+  AssertNodeInGraph(CS.getRetVal().getNode());
+  for (unsigned j = 0, e = CS.getNumPtrArgs(); j != e; ++j)
+    AssertNodeInGraph(CS.getPtrArg(j).getNode());
+}
+
+void DSGraph::AssertCallNodesInGraph() const {
+  for (unsigned i = 0, e = FunctionCalls.size(); i != e; ++i)
+    AssertCallSiteInGraph(FunctionCalls[i]);
+}
+void DSGraph::AssertAuxCallNodesInGraph() const {
+  for (unsigned i = 0, e = AuxFunctionCalls.size(); i != e; ++i)
+    AssertCallSiteInGraph(AuxFunctionCalls[i]);
+}
+
 void DSGraph::AssertGraphOK() const {
   for (node_iterator NI = node_begin(), E = node_end(); NI != E; ++NI)
     (*NI)->assertOK();
@@ -1847,4 +1987,7 @@
   for (unsigned i = 0, e = N1->getSize(); i < e; i += DS::PointerSize)
     if (unsigned(N2Idx)+i < N2Size)
       computeNodeMapping(N1->getLink(i), N2->getLink(N2Idx+i), NodeMap);
+    else
+      computeNodeMapping(N1->getLink(i),
+                         N2->getLink(unsigned(N2Idx+i) % N2Size), NodeMap);
 }


Index: llvm/lib/Analysis/DataStructure/Local.cpp
diff -u llvm/lib/Analysis/DataStructure/Local.cpp:1.74.4.1 llvm/lib/Analysis/DataStructure/Local.cpp:1.74.4.2
--- llvm/lib/Analysis/DataStructure/Local.cpp:1.74.4.1	Mon Mar  1 17:58:12 2004
+++ llvm/lib/Analysis/DataStructure/Local.cpp	Wed Mar 10 19:28:21 2004
@@ -117,6 +117,8 @@
     void visitInstruction(Instruction &I);
 
     void visitCallSite(CallSite CS);
+    void visitVANextInst(VANextInst &I);
+    void visitVAArgInst(VAArgInst   &I);
 
     void MergeConstantInitIntoNode(DSNodeHandle &NH, Constant *C);
   private:
@@ -185,7 +187,7 @@
     for (DSScalarMap::global_iterator I = ScalarMap.global_begin();
          I != ScalarMap.global_end(); ++I)
       if (GlobalVariable *GV = dyn_cast<GlobalVariable>(*I))
-        if (GV->isConstant())
+        if (!GV->isExternal() && GV->isConstant())
           RC.merge(ScalarMap[GV], GG->ScalarMap[GV]);
   }
 
@@ -281,11 +283,7 @@
 /// merge the two destinations together.
 ///
 void GraphBuilder::setDestTo(Value &V, const DSNodeHandle &NH) {
-  DSNodeHandle &AINH = ScalarMap[&V];
-  if (AINH.getNode() == 0)   // Not pointing to anything yet?
-    AINH = NH;               // Just point directly to NH
-  else
-    AINH.mergeWith(NH);
+  ScalarMap[&V].mergeWith(NH);
 }
 
 
@@ -442,7 +440,7 @@
 void GraphBuilder::visitStoreInst(StoreInst &SI) {
   const Type *StoredTy = SI.getOperand(0)->getType();
   DSNodeHandle Dest = getValueDest(*SI.getOperand(1));
-  if (Dest.getNode() == 0) return;
+  if (Dest.isNull()) return;
 
   // Mark that the node is written to...
   Dest.getNode()->setModifiedMarker();
@@ -460,6 +458,25 @@
     RetNode->mergeWith(getValueDest(*RI.getOperand(0)));
 }
 
+void GraphBuilder::visitVANextInst(VANextInst &I) {
+  getValueDest(*I.getOperand(0)).mergeWith(getValueDest(I));
+}
+
+void GraphBuilder::visitVAArgInst(VAArgInst &I) {
+  DSNodeHandle Ptr = getValueDest(*I.getOperand(0));
+  if (Ptr.isNull()) return;
+
+  // Make that the node is read from.
+  Ptr.getNode()->setReadMarker();
+
+  // Ensure a typerecord exists...
+  Ptr.getNode()->mergeTypeInfo(I.getType(), Ptr.getOffset(), false);
+
+  if (isPointerType(I.getType()))
+    setDestTo(I, getLink(Ptr));
+}
+
+
 void GraphBuilder::visitCallInst(CallInst &CI) {
   visitCallSite(&CI);
 }
@@ -477,6 +494,17 @@
   if (Function *F = dyn_cast<Function>(Callee))
     if (F->isExternal())
       switch (F->getIntrinsicID()) {
+      case Intrinsic::va_start:
+        getValueDest(*CS.getInstruction()).getNode()->setAllocaNodeMarker();
+        return;
+      case Intrinsic::va_copy:
+        getValueDest(*CS.getInstruction()).
+          mergeWith(getValueDest(**(CS.arg_begin())));
+        return;
+        // FIXME: the #undef is a quick fix for compilation on Sparc
+#undef va_end
+      case Intrinsic::va_end:
+        return;  // noop
       case Intrinsic::memmove:
       case Intrinsic::memcpy: {
         // Merge the first & second arguments, and mark the memory read and
@@ -560,6 +588,24 @@
               N->mergeTypeInfo(PTy->getElementType(), StatBuf.getOffset());
           }
           return;
+        } 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::SByteTy),
+                                 EndPtrNH.getOffset(), false);
+              End->setModifiedMarker();
+              DSNodeHandle &Link = getLink(EndPtrNH);
+              Link.mergeWith(getValueDest(**CS.arg_begin()));
+            }
+          }
+
+          return;
         } else if (F->getName() == "fopen" || F->getName() == "fdopen" ||
                    F->getName() == "freopen") {
           // These functions read all of their pointer operands.
@@ -581,7 +627,8 @@
 
           // If this is freopen, merge the file descriptor passed in with the
           // result.
-          Result.mergeWith(getValueDest(**--CS.arg_end()));
+          if (F->getName() == "freopen")
+            Result.mergeWith(getValueDest(**--CS.arg_end()));
 
           return;
         } else if (F->getName() == "fclose" && CS.arg_end()-CS.arg_begin() ==1){
@@ -721,6 +768,54 @@
               if (DSNode *N = getValueDest(**AI).getNode())
                 N->setReadMarker();   
           }
+          return;
+        } 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 (isPointerType((*AI)->getType()))
+              if (DSNode *N = getValueDest(**AI).getNode())
+                N->setReadMarker();
+            ++AI;
+          }
+          
+          // Read the valist, and the pointed-to objects.
+          if (AI != E && isPointerType((*AI)->getType())) {
+            const DSNodeHandle &VAList = getValueDest(**AI);
+            if (DSNode *N = VAList.getNode()) {
+              N->setReadMarker();
+              N->mergeTypeInfo(PointerType::get(Type::SByteTy),
+                               VAList.getOffset(), false);
+
+              DSNodeHandle &VAListObjs = getLink(VAList);
+              VAListObjs.getNode()->setReadMarker();
+            }
+          }
+
           return;
         } else if (F->getName() == "scanf" || F->getName() == "fscanf" ||
                    F->getName() == "sscanf") {


Index: llvm/lib/Analysis/DataStructure/Printer.cpp
diff -u llvm/lib/Analysis/DataStructure/Printer.cpp:1.62.4.1 llvm/lib/Analysis/DataStructure/Printer.cpp:1.62.4.2
--- llvm/lib/Analysis/DataStructure/Printer.cpp:1.62.4.1	Mon Mar  1 17:58:12 2004
+++ llvm/lib/Analysis/DataStructure/Printer.cpp	Wed Mar 10 19:28:21 2004
@@ -40,11 +40,17 @@
   std::stringstream OS;
   Module *M = 0;
 
-  if (G) G = N->getParentGraph();
+  if (!G) G = N->getParentGraph();
 
   // Get the module from ONE of the functions in the graph it is available.
   if (G && !G->getReturnNodes().empty())
     M = G->getReturnNodes().begin()->first->getParent();
+  if (M == 0 && G) {
+    // If there is a global in the graph, we can use it to find the module.
+    const DSScalarMap &SM = G->getScalarMap();
+    if (SM.global_begin() != SM.global_end())
+      M = (*SM.global_begin())->getParent();
+  }
 
   if (N->isNodeCompletelyFolded())
     OS << "COLLAPSED";
@@ -108,6 +114,13 @@
     Module *CurMod = 0;
     if (!G->getReturnNodes().empty())
       CurMod = G->getReturnNodes().begin()->first->getParent();
+    else {
+      // If there is a global in the graph, we can use it to find the module.
+      const DSScalarMap &SM = G->getScalarMap();
+      if (SM.global_begin() != SM.global_end())
+        CurMod = (*SM.global_begin())->getParent();
+    }
+
 
     // Add scalar nodes to the graph...
     const DSGraph::ScalarMapTy &VM = G->getScalarMap();





More information about the llvm-commits mailing list