Fix bug with prior checkin
[oota-llvm.git] / lib / Analysis / DataStructure / DataStructure.cpp
1 //===- DataStructure.cpp - Implement the core data structure analysis -----===//
2 //
3 // This file implements the core data structure functionality.
4 //
5 //===----------------------------------------------------------------------===//
6
7 #include "llvm/Analysis/DSGraph.h"
8 #include "llvm/Function.h"
9 #include "llvm/iOther.h"
10 #include "llvm/DerivedTypes.h"
11 #include "llvm/Target/TargetData.h"
12 #include "Support/STLExtras.h"
13 #include "Support/Statistic.h"
14 #include <algorithm>
15 #include <set>
16
17 using std::vector;
18
19 // TODO: FIXME
20 namespace DataStructureAnalysis {
21   // isPointerType - Return true if this first class type is big enough to hold
22   // a pointer.
23   //
24   bool isPointerType(const Type *Ty);
25   extern TargetData TD;
26 }
27 using namespace DataStructureAnalysis;
28
29 //===----------------------------------------------------------------------===//
30 // DSNode Implementation
31 //===----------------------------------------------------------------------===//
32
33 DSNode::DSNode(enum NodeTy NT, const Type *T) : NodeType(NT) {
34   // If this node is big enough to have pointer fields, add space for them now.
35   if (T != Type::VoidTy && !isa<FunctionType>(T)) { // Avoid TargetData assert's
36     MergeMap.resize(TD.getTypeSize(T));
37
38     // Assign unique values to all of the elements of MergeMap
39     if (MergeMap.size() < 128) {
40       // Handle the common case of reasonable size structures...
41       for (unsigned i = 0, e = MergeMap.size(); i != e; ++i)
42         MergeMap[i] = -1-i;   // Assign -1, -2, -3, ...
43     } else {
44       // It's possible that we have something really big here.  In this case,
45       // divide the object into chunks until it will fit into 128 elements.
46       unsigned Multiple = MergeMap.size()/128;
47
48       // It's probably an array, and probably some power of two in size.
49       // Because of this, find the biggest power of two that is bigger than
50       // multiple to use as our real Multiple.
51       unsigned RealMultiple = 2;
52       while (RealMultiple <= Multiple) RealMultiple <<= 1;
53
54       unsigned RealBound = MergeMap.size()/RealMultiple;
55       assert(RealBound <= 128 && "Math didn't work out right");
56
57       // Now go through and assign indexes that are between -1 and -128
58       // inclusive
59       //
60       for (unsigned i = 0, e = MergeMap.size(); i != e; ++i)
61         MergeMap[i] = -1-(i % RealBound);   // Assign -1, -2, -3...
62     }
63   }
64
65   TypeEntries.push_back(TypeRec(T, 0));
66 }
67
68 // DSNode copy constructor... do not copy over the referrers list!
69 DSNode::DSNode(const DSNode &N)
70   : Links(N.Links), MergeMap(N.MergeMap),
71     TypeEntries(N.TypeEntries), Globals(N.Globals), NodeType(N.NodeType) {
72 }
73
74 void DSNode::removeReferrer(DSNodeHandle *H) {
75   // Search backwards, because we depopulate the list from the back for
76   // efficiency (because it's a vector).
77   vector<DSNodeHandle*>::reverse_iterator I =
78     std::find(Referrers.rbegin(), Referrers.rend(), H);
79   assert(I != Referrers.rend() && "Referrer not pointing to node!");
80   Referrers.erase(I.base()-1);
81 }
82
83 // addGlobal - Add an entry for a global value to the Globals list.  This also
84 // marks the node with the 'G' flag if it does not already have it.
85 //
86 void DSNode::addGlobal(GlobalValue *GV) {
87   // Keep the list sorted.
88   vector<GlobalValue*>::iterator I =
89     std::lower_bound(Globals.begin(), Globals.end(), GV);
90
91   if (I == Globals.end() || *I != GV) {
92     //assert(GV->getType()->getElementType() == Ty);
93     Globals.insert(I, GV);
94     NodeType |= GlobalNode;
95   }
96 }
97
98
99 /// setLink - Set the link at the specified offset to the specified
100 /// NodeHandle, replacing what was there.  It is uncommon to use this method,
101 /// instead one of the higher level methods should be used, below.
102 ///
103 void DSNode::setLink(unsigned i, const DSNodeHandle &NH) {
104   // Create a new entry in the Links vector to hold a new element for offset.
105   if (!hasLink(i)) {
106     signed char NewIdx = Links.size();
107     // Check to see if we allocate more than 128 distinct links for this node.
108     // If so, just merge with the last one.  This really shouldn't ever happen,
109     // but it should work regardless of whether it does or not.
110     //
111     if (NewIdx >= 0) {
112       Links.push_back(NH);             // Allocate space: common case
113     } else {                           // Wrap around?  Too many links?
114       NewIdx--;                        // Merge with whatever happened last
115       assert(NewIdx > 0 && "Should wrap back around");
116       std::cerr << "\n*** DSNode found that requires more than 128 "
117                 << "active links at once!\n\n";
118     } 
119
120     signed char OldIdx = MergeMap[i];
121     assert (OldIdx < 0 && "Shouldn't contain link!");
122
123     // Make sure that anything aliasing this field gets updated to point to the
124     // new link field.
125     rewriteMergeMap(OldIdx, NewIdx);
126     assert(MergeMap[i] == NewIdx && "Field not replaced!");
127   } else {
128     Links[MergeMap[i]] = NH;
129   }
130 }
131
132 // addEdgeTo - Add an edge from the current node to the specified node.  This
133 // can cause merging of nodes in the graph.
134 //
135 void DSNode::addEdgeTo(unsigned Offset, const DSNodeHandle &NH) {
136   assert(Offset < getSize() && "Offset out of range!");
137   if (NH.getNode() == 0) return;       // Nothing to do
138
139   if (DSNodeHandle *ExistingNH = getLink(Offset)) {
140     // Merge the two nodes...
141     ExistingNH->mergeWith(NH);
142   } else {                             // No merging to perform...
143     setLink(Offset, NH);               // Just force a link in there...
144   }
145 }
146
147 /// mergeMappedValues - This is the higher level form of rewriteMergeMap.  It is
148 /// fully capable of merging links together if neccesary as well as simply
149 /// rewriting the map entries.
150 ///
151 void DSNode::mergeMappedValues(signed char V1, signed char V2) {
152   assert(V1 != V2 && "Cannot merge two identical mapped values!");
153   
154   if (V1 < 0) {  // If there is no outgoing link from V1, merge it with V2
155     if (V2 < 0 && V1 > V2)
156        // If both are not linked, merge to the field closer to 0
157       rewriteMergeMap(V2, V1);
158     else
159       rewriteMergeMap(V1, V2);
160   } else if (V2 < 0) {           // Is V2 < 0 && V1 >= 0?
161     rewriteMergeMap(V2, V1);     // Merge into the one with the link...
162   } else {                       // Otherwise, links exist at both locations
163     // Merge Links[V1] with Links[V2] so they point to the same place now...
164     Links[V1].mergeWith(Links[V2]);
165
166     // Merge the V2 link into V1 so that we reduce the overall value of the
167     // links are reduced...
168     //
169     if (V2 < V1) std::swap(V1, V2);     // Ensure V1 < V2
170     rewriteMergeMap(V2, V1);            // After this, V2 is "dead"
171
172     // Change the user of the last link to use V2 instead
173     if ((unsigned)V2 != Links.size()-1) {
174       rewriteMergeMap(Links.size()-1, V2);  // Point to V2 instead of last el...
175       // Make sure V2 points the right DSNode
176       Links[V2] = Links.back();
177     }
178
179     // Reduce the number of distinct outgoing links...
180     Links.pop_back();
181   }
182 }
183
184
185 // MergeSortedVectors - Efficiently merge a vector into another vector where
186 // duplicates are not allowed and both are sorted.  This assumes that 'T's are
187 // efficiently copyable and have sane comparison semantics.
188 //
189 template<typename T>
190 void MergeSortedVectors(vector<T> &Dest, const vector<T> &Src) {
191   // By far, the most common cases will be the simple ones.  In these cases,
192   // avoid having to allocate a temporary vector...
193   //
194   if (Src.empty()) {             // Nothing to merge in...
195     return;
196   } else if (Dest.empty()) {     // Just copy the result in...
197     Dest = Src;
198   } else if (Src.size() == 1) {  // Insert a single element...
199     const T &V = Src[0];
200     typename vector<T>::iterator I =
201       std::lower_bound(Dest.begin(), Dest.end(), V);
202     if (I == Dest.end() || *I != Src[0])  // If not already contained...
203       Dest.insert(I, Src[0]);
204   } else if (Dest.size() == 1) {
205     T Tmp = Dest[0];                      // Save value in temporary...
206     Dest = Src;                           // Copy over list...
207     typename vector<T>::iterator I =
208       std::lower_bound(Dest.begin(), Dest.end(),Tmp);
209     if (I == Dest.end() || *I != Src[0])  // If not already contained...
210       Dest.insert(I, Src[0]);
211
212   } else {
213     // Make a copy to the side of Dest...
214     vector<T> Old(Dest);
215     
216     // Make space for all of the type entries now...
217     Dest.resize(Dest.size()+Src.size());
218     
219     // Merge the two sorted ranges together... into Dest.
220     std::merge(Old.begin(), Old.end(), Src.begin(), Src.end(), Dest.begin());
221     
222     // Now erase any duplicate entries that may have accumulated into the 
223     // vectors (because they were in both of the input sets)
224     Dest.erase(std::unique(Dest.begin(), Dest.end()), Dest.end());
225   }
226 }
227
228
229 // mergeWith - Merge this node and the specified node, moving all links to and
230 // from the argument node into the current node, deleting the node argument.
231 // Offset indicates what offset the specified node is to be merged into the
232 // current node.
233 //
234 // The specified node may be a null pointer (in which case, nothing happens).
235 //
236 void DSNode::mergeWith(const DSNodeHandle &NH, unsigned Offset) {
237   DSNode *N = NH.getNode();
238   if (N == 0 || (N == this && NH.getOffset() == Offset))
239       return;  // Noop
240
241   assert(NH.getNode() != this &&
242          "Cannot merge two portions of the same node yet!");
243
244   // If both nodes are not at offset 0, make sure that we are merging the node
245   // at an later offset into the node with the zero offset.
246   //
247   if (Offset > NH.getOffset()) {
248     N->mergeWith(DSNodeHandle(this, Offset), NH.getOffset());
249     return;
250   }
251
252 #if 0
253   std::cerr << "\n\nMerging:\n";
254   N->print(std::cerr, 0);
255   std::cerr << " and:\n";
256   print(std::cerr, 0);
257 #endif
258
259   // Now we know that Offset <= NH.Offset, so convert it so our "Offset" (with
260   // respect to NH.Offset) is now zero.
261   //
262   unsigned NOffset = NH.getOffset()-Offset;
263
264   unsigned NSize = N->getSize();
265   assert(NSize+NOffset <= getSize() &&
266          "Don't know how to merge extend a merged nodes size yet!");
267
268   // Remove all edges pointing at N, causing them to point to 'this' instead.
269   // Make sure to adjust their offset, not just the node pointer.
270   //
271   while (!N->Referrers.empty()) {
272     DSNodeHandle &Ref = *N->Referrers.back();
273     Ref = DSNodeHandle(this, NOffset+Ref.getOffset());
274   }
275
276   // We must merge fields in this node due to nodes merged in the source node.
277   // In order to handle this we build a map that converts from the source node's
278   // MergeMap values to our MergeMap values.  This map is indexed by the
279   // expression: MergeMap[SMM+SourceNodeSize] so we need to allocate at least
280   // 2*SourceNodeSize elements of space for the mapping.  We can do this because
281   // we know that there are at most SourceNodeSize outgoing links in the node
282   // (thus that many positive values) and at most SourceNodeSize distinct fields
283   // (thus that many negative values).
284   //
285   std::vector<signed char> MergeMapMap(NSize*2, 127);
286
287   // Loop through the structures, merging them together...
288   for (unsigned i = 0, e = NSize; i != e; ++i) {
289     // Get what this byte of N maps to...
290     signed char NElement = N->MergeMap[i];
291
292     // Get what we map this byte to...
293     signed char Element = MergeMap[i+NOffset];
294     // We use 127 as a sentinal and don't check for it's existence yet...
295     assert(Element != 127 && "MergeMapMap doesn't permit 127 values yet!");
296
297     signed char CurMappedVal = MergeMapMap[NElement+NSize];
298     if (CurMappedVal == 127) {               // Haven't seen this NElement yet?
299       MergeMapMap[NElement+NSize] = Element; // Map the two together...
300     } else if (CurMappedVal != Element) {
301       // If we are mapping two different fields together this means that we need
302       // to merge fields in the current node due to merging in the source node.
303       //
304       mergeMappedValues(CurMappedVal, Element);
305       MergeMapMap[NElement+NSize] = MergeMap[i+NOffset];
306     }
307   }
308
309   // Make all of the outgoing links of N now be outgoing links of this.  This
310   // can cause recursive merging!
311   //
312   for (unsigned i = 0, e = NSize; i != e; ++i)
313     if (DSNodeHandle *Link = N->getLink(i)) {
314       addEdgeTo(i+NOffset, *Link);
315       N->MergeMap[i] = -1;  // Kill outgoing edge
316     }
317
318   // Now that there are no outgoing edges, all of the Links are dead.
319   N->Links.clear();
320
321   // Merge the node types
322   NodeType |= N->NodeType;
323   N->NodeType = 0;   // N is now a dead node.
324
325   // If this merging into node has more than just void nodes in it, merge!
326   assert(!N->TypeEntries.empty() && "TypeEntries is empty for a node?");
327   if (N->TypeEntries.size() != 1 || N->TypeEntries[0].Ty != Type::VoidTy) {
328     // If the current node just has a Void entry in it, remove it.
329     if (TypeEntries.size() == 1 && TypeEntries[0].Ty == Type::VoidTy)
330       TypeEntries.clear();
331
332     // Adjust all of the type entries we are merging in by the offset... and add
333     // them to the TypeEntries list.
334     //
335     if (NOffset != 0) {  // This case is common enough to optimize for
336       // Offset all of the TypeEntries in N with their new offset
337       for (unsigned i = 0, e = N->TypeEntries.size(); i != e; ++i)
338         N->TypeEntries[i].Offset += NOffset;
339     }
340
341     MergeSortedVectors(TypeEntries, N->TypeEntries);
342
343     N->TypeEntries.clear();
344   }
345
346   // Merge the globals list...
347   if (!N->Globals.empty()) {
348     MergeSortedVectors(Globals, N->Globals);
349
350     // Delete the globals from the old node...
351     N->Globals.clear();
352   }
353 }
354
355 //===----------------------------------------------------------------------===//
356 // DSCallSite Implementation
357 //===----------------------------------------------------------------------===//
358
359 // Define here to avoid including iOther.h and BasicBlock.h in DSGraph.h
360 Function &DSCallSite::getCaller() const {
361   return *Inst->getParent()->getParent();
362 }
363
364 template <typename CopyFunctor>
365 DSCallSite::DSCallSite(const DSCallSite &FromCall, CopyFunctor nodeCopier)
366   : Inst(FromCall.Inst) {
367
368   RetVal = nodeCopier(&FromCall.RetVal);
369   Callee = nodeCopier(&FromCall.Callee);
370
371   CallArgs.reserve(FromCall.CallArgs.size());
372   for (unsigned j = 0, ej = FromCall.CallArgs.size(); j != ej; ++j)
373     CallArgs.push_back(nodeCopier(&FromCall.CallArgs[j]));
374 }
375
376
377 //===----------------------------------------------------------------------===//
378 // DSGraph Implementation
379 //===----------------------------------------------------------------------===//
380
381 DSGraph::DSGraph(const DSGraph &G) : Func(G.Func) {
382   std::map<const DSNode*, DSNode*> NodeMap;
383   RetNode = cloneInto(G, ValueMap, NodeMap);
384 }
385
386 DSGraph::~DSGraph() {
387   FunctionCalls.clear();
388   ValueMap.clear();
389   RetNode = 0;
390
391 #ifndef NDEBUG
392   // Drop all intra-node references, so that assertions don't fail...
393   std::for_each(Nodes.begin(), Nodes.end(),
394                 std::mem_fun(&DSNode::dropAllReferences));
395 #endif
396
397   // Delete all of the nodes themselves...
398   std::for_each(Nodes.begin(), Nodes.end(), deleter<DSNode>);
399 }
400
401 // dump - Allow inspection of graph in a debugger.
402 void DSGraph::dump() const { print(std::cerr); }
403
404
405 static DSNodeHandle copyHelper(const DSNodeHandle* fromNode,
406                                std::map<const DSNode*, DSNode*> *NodeMap) {
407   return DSNodeHandle((*NodeMap)[fromNode->getNode()], fromNode->getOffset());
408 }
409
410 // Helper function used to clone a function list.
411 // 
412 static void CopyFunctionCallsList(const vector<DSCallSite>& fromCalls,
413                                   vector<DSCallSite> &toCalls,
414                                   std::map<const DSNode*, DSNode*> &NodeMap) {
415   unsigned FC = toCalls.size();  // FirstCall
416   toCalls.reserve(FC+fromCalls.size());
417   for (unsigned i = 0, ei = fromCalls.size(); i != ei; ++i)
418     toCalls.push_back(DSCallSite(fromCalls[i], 
419                          std::bind2nd(std::ptr_fun(&copyHelper), &NodeMap)));
420 }
421
422 /// remapLinks - Change all of the Links in the current node according to the
423 /// specified mapping.
424 void DSNode::remapLinks(std::map<const DSNode*, DSNode*> &OldNodeMap) {
425   for (unsigned i = 0, e = Links.size(); i != e; ++i) 
426     Links[i].setNode(OldNodeMap[Links[i].getNode()]);
427 }
428
429
430 // cloneInto - Clone the specified DSGraph into the current graph, returning the
431 // Return node of the graph.  The translated ValueMap for the old function is
432 // filled into the OldValMap member.  If StripLocals is set to true, Scalar and
433 // Alloca markers are removed from the graph, as the graph is being cloned into
434 // a calling function's graph.
435 //
436 DSNodeHandle DSGraph::cloneInto(const DSGraph &G, 
437                                 std::map<Value*, DSNodeHandle> &OldValMap,
438                                 std::map<const DSNode*, DSNode*> &OldNodeMap,
439                                 bool StripScalars, bool StripAllocas,
440                                 bool CopyCallers, bool CopyOrigCalls) {
441   assert(OldNodeMap.empty() && "Returned OldNodeMap should be empty!");
442
443   unsigned FN = Nodes.size();           // First new node...
444
445   // Duplicate all of the nodes, populating the node map...
446   Nodes.reserve(FN+G.Nodes.size());
447   for (unsigned i = 0, e = G.Nodes.size(); i != e; ++i) {
448     DSNode *Old = G.Nodes[i];
449     DSNode *New = new DSNode(*Old);
450     Nodes.push_back(New);
451     OldNodeMap[Old] = New;
452   }
453
454   // Rewrite the links in the new nodes to point into the current graph now.
455   for (unsigned i = FN, e = Nodes.size(); i != e; ++i)
456     Nodes[i]->remapLinks(OldNodeMap);
457
458   // Remove local markers as specified
459   unsigned char StripBits = (StripScalars ? DSNode::ScalarNode : 0) |
460                             (StripAllocas ? DSNode::AllocaNode : 0);
461   if (StripBits)
462     for (unsigned i = FN, e = Nodes.size(); i != e; ++i)
463       Nodes[i]->NodeType &= ~StripBits;
464
465   // Copy the value map... and merge all of the global nodes...
466   for (std::map<Value*, DSNodeHandle>::const_iterator I = G.ValueMap.begin(),
467          E = G.ValueMap.end(); I != E; ++I) {
468     DSNodeHandle &H = OldValMap[I->first];
469     H = DSNodeHandle(OldNodeMap[I->second.getNode()], I->second.getOffset());
470
471     if (isa<GlobalValue>(I->first)) {  // Is this a global?
472       std::map<Value*, DSNodeHandle>::iterator GVI = ValueMap.find(I->first);
473       if (GVI != ValueMap.end()) {   // Is the global value in this fun already?
474         GVI->second.mergeWith(H);
475       } else {
476         ValueMap[I->first] = H;      // Add global pointer to this graph
477       }
478     }
479   }
480   // Copy the function calls list...
481   CopyFunctionCallsList(G.FunctionCalls, FunctionCalls, OldNodeMap);
482
483
484   // Return the returned node pointer...
485   return DSNodeHandle(OldNodeMap[G.RetNode.getNode()], G.RetNode.getOffset());
486 }
487
488 #if 0
489 // cloneGlobalInto - Clone the given global node and all its target links
490 // (and all their llinks, recursively).
491 // 
492 DSNode *DSGraph::cloneGlobalInto(const DSNode *GNode) {
493   if (GNode == 0 || GNode->getGlobals().size() == 0) return 0;
494
495   // If a clone has already been created for GNode, return it.
496   DSNodeHandle& ValMapEntry = ValueMap[GNode->getGlobals()[0]];
497   if (ValMapEntry != 0)
498     return ValMapEntry;
499
500   // Clone the node and update the ValMap.
501   DSNode* NewNode = new DSNode(*GNode);
502   ValMapEntry = NewNode;                // j=0 case of loop below!
503   Nodes.push_back(NewNode);
504   for (unsigned j = 1, N = NewNode->getGlobals().size(); j < N; ++j)
505     ValueMap[NewNode->getGlobals()[j]] = NewNode;
506
507   // Rewrite the links in the new node to point into the current graph.
508   for (unsigned j = 0, e = GNode->getNumLinks(); j != e; ++j)
509     NewNode->setLink(j, cloneGlobalInto(GNode->getLink(j)));
510
511   return NewNode;
512 }
513 #endif
514
515
516 // markIncompleteNodes - Mark the specified node as having contents that are not
517 // known with the current analysis we have performed.  Because a node makes all
518 // of the nodes it can reach imcomplete if the node itself is incomplete, we
519 // must recursively traverse the data structure graph, marking all reachable
520 // nodes as incomplete.
521 //
522 static void markIncompleteNode(DSNode *N) {
523   // Stop recursion if no node, or if node already marked...
524   if (N == 0 || (N->NodeType & DSNode::Incomplete)) return;
525
526   // Actually mark the node
527   N->NodeType |= DSNode::Incomplete;
528
529   // Recusively process children...
530   for (unsigned i = 0, e = N->getSize(); i != e; ++i)
531     if (DSNodeHandle *DSNH = N->getLink(i))
532       markIncompleteNode(DSNH->getNode());
533 }
534
535
536 // markIncompleteNodes - Traverse the graph, identifying nodes that may be
537 // modified by other functions that have not been resolved yet.  This marks
538 // nodes that are reachable through three sources of "unknownness":
539 //
540 //  Global Variables, Function Calls, and Incoming Arguments
541 //
542 // For any node that may have unknown components (because something outside the
543 // scope of current analysis may have modified it), the 'Incomplete' flag is
544 // added to the NodeType.
545 //
546 void DSGraph::markIncompleteNodes(bool markFormalArgs) {
547   // Mark any incoming arguments as incomplete...
548   if (markFormalArgs && Func)
549     for (Function::aiterator I = Func->abegin(), E = Func->aend(); I != E; ++I)
550       if (isPointerType(I->getType()) && ValueMap.find(I) != ValueMap.end()) {
551         DSNodeHandle &INH = ValueMap[I];
552         if (INH.getNode() && INH.hasLink(0))
553           markIncompleteNode(ValueMap[I].getLink(0)->getNode());
554       }
555
556   // Mark stuff passed into functions calls as being incomplete...
557   for (unsigned i = 0, e = FunctionCalls.size(); i != e; ++i) {
558     DSCallSite &Call = FunctionCalls[i];
559     // Then the return value is certainly incomplete!
560     markIncompleteNode(Call.getRetVal().getNode());
561
562     // The call does not make the function argument incomplete...
563  
564     // All arguments to the function call are incomplete though!
565     for (unsigned i = 0, e = Call.getNumPtrArgs(); i != e; ++i)
566       markIncompleteNode(Call.getPtrArg(i).getNode());
567   }
568
569   // Mark all of the nodes pointed to by global or cast nodes as incomplete...
570   for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
571     if (Nodes[i]->NodeType & DSNode::GlobalNode) {
572       DSNode *N = Nodes[i];
573       for (unsigned i = 0, e = N->getSize(); i != e; ++i)
574         if (DSNodeHandle *DSNH = N->getLink(i))
575           markIncompleteNode(DSNH->getNode());
576     }
577 }
578
579 // removeRefsToGlobal - Helper function that removes globals from the
580 // ValueMap so that the referrer count will go down to zero.
581 static void removeRefsToGlobal(DSNode* N,
582                                std::map<Value*, DSNodeHandle> &ValueMap) {
583   while (!N->getGlobals().empty()) {
584     GlobalValue *GV = N->getGlobals().back();
585     N->getGlobals().pop_back();      
586     ValueMap.erase(GV);
587   }
588 }
589
590
591 // isNodeDead - This method checks to see if a node is dead, and if it isn't, it
592 // checks to see if there are simple transformations that it can do to make it
593 // dead.
594 //
595 bool DSGraph::isNodeDead(DSNode *N) {
596   // Is it a trivially dead shadow node...
597   if (N->getReferrers().empty() && N->NodeType == 0)
598     return true;
599
600   // Is it a function node or some other trivially unused global?
601   if (N->NodeType != 0 &&
602       (N->NodeType & ~DSNode::GlobalNode) == 0 && 
603       N->getSize() == 0 &&
604       N->getReferrers().size() == N->getGlobals().size()) {
605
606     // Remove the globals from the ValueMap, so that the referrer count will go
607     // down to zero.
608     removeRefsToGlobal(N, ValueMap);
609     assert(N->getReferrers().empty() && "Referrers should all be gone now!");
610     return true;
611   }
612
613   return false;
614 }
615
616 static void removeIdenticalCalls(vector<DSCallSite> &Calls,
617                                  const std::string &where) {
618   // Remove trivially identical function calls
619   unsigned NumFns = Calls.size();
620   std::sort(Calls.begin(), Calls.end());
621   Calls.erase(std::unique(Calls.begin(), Calls.end()),
622               Calls.end());
623
624   DEBUG(if (NumFns != Calls.size())
625           std::cerr << "Merged " << (NumFns-Calls.size())
626                     << " call nodes in " << where << "\n";);
627 }
628
629 // removeTriviallyDeadNodes - After the graph has been constructed, this method
630 // removes all unreachable nodes that are created because they got merged with
631 // other nodes in the graph.  These nodes will all be trivially unreachable, so
632 // we don't have to perform any non-trivial analysis here.
633 //
634 void DSGraph::removeTriviallyDeadNodes(bool KeepAllGlobals) {
635   for (unsigned i = 0; i != Nodes.size(); ++i)
636     if (!KeepAllGlobals || !(Nodes[i]->NodeType & DSNode::GlobalNode))
637       if (isNodeDead(Nodes[i])) {               // This node is dead!
638         delete Nodes[i];                        // Free memory...
639         Nodes.erase(Nodes.begin()+i--);         // Remove from node list...
640       }
641
642   removeIdenticalCalls(FunctionCalls, Func ? Func->getName() : "");
643 }
644
645
646 // markAlive - Simple graph walker that recursively traverses the graph, marking
647 // stuff to be alive.
648 //
649 static void markAlive(DSNode *N, std::set<DSNode*> &Alive) {
650   if (N == 0) return;
651
652   Alive.insert(N);
653   for (unsigned i = 0, e = N->getSize(); i != e; ++i)
654     if (DSNodeHandle *DSNH = N->getLink(i))
655       if (!Alive.count(DSNH->getNode()))
656         markAlive(DSNH->getNode(), Alive);
657 }
658
659 static bool checkGlobalAlive(DSNode *N, std::set<DSNode*> &Alive,
660                              std::set<DSNode*> &Visiting) {
661   if (N == 0) return false;
662
663   if (Visiting.count(N)) return false; // terminate recursion on a cycle
664   Visiting.insert(N);
665
666   // If any immediate successor is alive, N is alive
667   for (unsigned i = 0, e = N->getSize(); i != e; ++i)
668     if (DSNodeHandle *DSNH = N->getLink(i))
669       if (Alive.count(DSNH->getNode())) {
670         Visiting.erase(N);
671         return true;
672       }
673
674   // Else if any successor reaches a live node, N is alive
675   for (unsigned i = 0, e = N->getSize(); i != e; ++i)
676     if (DSNodeHandle *DSNH = N->getLink(i))
677       if (checkGlobalAlive(DSNH->getNode(), Alive, Visiting)) {
678         Visiting.erase(N); return true;
679       }
680
681   Visiting.erase(N);
682   return false;
683 }
684
685
686 // markGlobalsIteration - Recursive helper function for markGlobalsAlive().
687 // This would be unnecessary if function calls were real nodes!  In that case,
688 // the simple iterative loop in the first few lines below suffice.
689 // 
690 static void markGlobalsIteration(std::set<DSNode*>& GlobalNodes,
691                                  vector<DSCallSite> &Calls,
692                                  std::set<DSNode*> &Alive,
693                                  bool FilterCalls) {
694
695   // Iterate, marking globals or cast nodes alive until no new live nodes
696   // are added to Alive
697   std::set<DSNode*> Visiting;           // Used to identify cycles 
698   std::set<DSNode*>::iterator I = GlobalNodes.begin(), E = GlobalNodes.end();
699   for (size_t liveCount = 0; liveCount < Alive.size(); ) {
700     liveCount = Alive.size();
701     for ( ; I != E; ++I)
702       if (Alive.count(*I) == 0) {
703         Visiting.clear();
704         if (checkGlobalAlive(*I, Alive, Visiting))
705           markAlive(*I, Alive);
706       }
707   }
708
709   // Find function calls with some dead and some live nodes.
710   // Since all call nodes must be live if any one is live, we have to mark
711   // all nodes of the call as live and continue the iteration (via recursion).
712   if (FilterCalls) {
713     bool Recurse = false;
714     for (unsigned i = 0, ei = Calls.size(); i < ei; ++i) {
715       bool CallIsDead = true, CallHasDeadArg = false;
716       DSCallSite &CS = Calls[i];
717       for (unsigned j = 0, ej = CS.getNumPtrArgs(); j != ej; ++j)
718         if (DSNode *N = CS.getPtrArg(j).getNode()) {
719           bool ArgIsDead  = !Alive.count(N);
720           CallHasDeadArg |= ArgIsDead;
721           CallIsDead     &= ArgIsDead;
722         }
723
724       if (DSNode *N = CS.getRetVal().getNode()) {
725         bool RetIsDead  = !Alive.count(N);
726         CallHasDeadArg |= RetIsDead;
727         CallIsDead     &= RetIsDead;
728       }
729
730       DSNode *N = CS.getCallee().getNode();
731       bool FnIsDead  = !Alive.count(N);
732       CallHasDeadArg |= FnIsDead;
733       CallIsDead     &= FnIsDead;
734
735       if (!CallIsDead && CallHasDeadArg) {
736         // Some node in this call is live and another is dead.
737         // Mark all nodes of call as live and iterate once more.
738         Recurse = true;
739         for (unsigned j = 0, ej = CS.getNumPtrArgs(); j != ej; ++j)
740           markAlive(CS.getPtrArg(j).getNode(), Alive);
741         markAlive(CS.getRetVal().getNode(), Alive);
742         markAlive(CS.getCallee().getNode(), Alive);
743       }
744     }
745     if (Recurse)
746       markGlobalsIteration(GlobalNodes, Calls, Alive, FilterCalls);
747   }
748 }
749
750
751 // markGlobalsAlive - Mark global nodes and cast nodes alive if they
752 // can reach any other live node.  Since this can produce new live nodes,
753 // we use a simple iterative algorithm.
754 // 
755 static void markGlobalsAlive(DSGraph &G, std::set<DSNode*> &Alive,
756                              bool FilterCalls) {
757   // Add global and cast nodes to a set so we don't walk all nodes every time
758   std::set<DSNode*> GlobalNodes;
759   for (unsigned i = 0, e = G.getNodes().size(); i != e; ++i)
760     if (G.getNodes()[i]->NodeType & DSNode::GlobalNode)
761       GlobalNodes.insert(G.getNodes()[i]);
762
763   // Add all call nodes to the same set
764   vector<DSCallSite> &Calls = G.getFunctionCalls();
765   if (FilterCalls) {
766     for (unsigned i = 0, e = Calls.size(); i != e; ++i) {
767       for (unsigned j = 0, e = Calls[i].getNumPtrArgs(); j != e; ++j)
768         if (DSNode *N = Calls[i].getPtrArg(j).getNode())
769           GlobalNodes.insert(N);
770       if (DSNode *N = Calls[i].getRetVal().getNode())
771         GlobalNodes.insert(N);
772       if (DSNode *N = Calls[i].getCallee().getNode())
773         GlobalNodes.insert(N);
774     }
775   }
776
777   // Iterate and recurse until no new live node are discovered.
778   // This would be a simple iterative loop if function calls were real nodes!
779   markGlobalsIteration(GlobalNodes, Calls, Alive, FilterCalls);
780
781   // Free up references to dead globals from the ValueMap
782   std::set<DSNode*>::iterator I=GlobalNodes.begin(), E=GlobalNodes.end();
783   for( ; I != E; ++I)
784     if (Alive.count(*I) == 0)
785       removeRefsToGlobal(*I, G.getValueMap());
786
787   // Delete dead function calls
788   if (FilterCalls)
789     for (int ei = Calls.size(), i = ei-1; i >= 0; --i) {
790       bool CallIsDead = true;
791       for (unsigned j = 0, ej = Calls[i].getNumPtrArgs();
792            CallIsDead && j != ej; ++j)
793         CallIsDead = Alive.count(Calls[i].getPtrArg(j).getNode()) == 0;
794       if (CallIsDead)
795         Calls.erase(Calls.begin() + i); // remove the call entirely
796     }
797 }
798
799 // removeDeadNodes - Use a more powerful reachability analysis to eliminate
800 // subgraphs that are unreachable.  This often occurs because the data
801 // structure doesn't "escape" into it's caller, and thus should be eliminated
802 // from the caller's graph entirely.  This is only appropriate to use when
803 // inlining graphs.
804 //
805 void DSGraph::removeDeadNodes(bool KeepAllGlobals, bool KeepCalls) {
806   assert((!KeepAllGlobals || KeepCalls) &&
807          "KeepAllGlobals without KeepCalls is meaningless");
808
809   // Reduce the amount of work we have to do...
810   removeTriviallyDeadNodes(KeepAllGlobals);
811
812   // FIXME: Merge nontrivially identical call nodes...
813
814   // Alive - a set that holds all nodes found to be reachable/alive.
815   std::set<DSNode*> Alive;
816
817   // If KeepCalls, mark all nodes reachable by call nodes as alive...
818   if (KeepCalls)
819     for (unsigned i = 0, e = FunctionCalls.size(); i != e; ++i) {
820       for (unsigned j = 0, e = FunctionCalls[i].getNumPtrArgs(); j != e; ++j)
821         markAlive(FunctionCalls[i].getPtrArg(j).getNode(), Alive);
822       markAlive(FunctionCalls[i].getRetVal().getNode(), Alive);
823       markAlive(FunctionCalls[i].getCallee().getNode(), Alive);
824     }
825
826 #if 0
827   for (unsigned i = 0, e = OrigFunctionCalls.size(); i != e; ++i)
828     for (unsigned j = 0, e = OrigFunctionCalls[i].size(); j != e; ++j)
829       markAlive(OrigFunctionCalls[i][j].getNode(), Alive);
830 #endif
831
832   // Mark all nodes reachable by scalar nodes (and global nodes, if
833   // keeping them was specified) as alive...
834   unsigned char keepBits = DSNode::ScalarNode |
835                            (KeepAllGlobals ? DSNode::GlobalNode : 0);
836   for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
837     if (Nodes[i]->NodeType & keepBits)
838       markAlive(Nodes[i], Alive);
839
840   // The return value is alive as well...
841   markAlive(RetNode.getNode(), Alive);
842
843   // Mark all globals or cast nodes that can reach a live node as alive.
844   // This also marks all nodes reachable from such nodes as alive.
845   // Of course, if KeepAllGlobals is specified, they would be live already.
846   if (!KeepAllGlobals)
847     markGlobalsAlive(*this, Alive, ! KeepCalls);
848
849   // Loop over all unreachable nodes, dropping their references...
850   vector<DSNode*> DeadNodes;
851   DeadNodes.reserve(Nodes.size());     // Only one allocation is allowed.
852   for (unsigned i = 0; i != Nodes.size(); ++i)
853     if (!Alive.count(Nodes[i])) {
854       DSNode *N = Nodes[i];
855       Nodes.erase(Nodes.begin()+i--);  // Erase node from alive list.
856       DeadNodes.push_back(N);          // Add node to our list of dead nodes
857       N->dropAllReferences();          // Drop all outgoing edges
858     }
859   
860   // Delete all dead nodes...
861   std::for_each(DeadNodes.begin(), DeadNodes.end(), deleter<DSNode>);
862 }
863
864
865
866 // maskNodeTypes - Apply a mask to all of the node types in the graph.  This
867 // is useful for clearing out markers like Scalar or Incomplete.
868 //
869 void DSGraph::maskNodeTypes(unsigned char Mask) {
870   for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
871     Nodes[i]->NodeType &= Mask;
872 }
873
874
875 #if 0
876 //===----------------------------------------------------------------------===//
877 // GlobalDSGraph Implementation
878 //===----------------------------------------------------------------------===//
879
880 GlobalDSGraph::GlobalDSGraph() : DSGraph(*(Function*)0, this) {
881 }
882
883 GlobalDSGraph::~GlobalDSGraph() {
884   assert(Referrers.size() == 0 &&
885          "Deleting global graph while references from other graphs exist");
886 }
887
888 void GlobalDSGraph::addReference(const DSGraph* referrer) {
889   if (referrer != this)
890     Referrers.insert(referrer);
891 }
892
893 void GlobalDSGraph::removeReference(const DSGraph* referrer) {
894   if (referrer != this) {
895     assert(Referrers.find(referrer) != Referrers.end() && "This is very bad!");
896     Referrers.erase(referrer);
897     if (Referrers.size() == 0)
898       delete this;
899   }
900 }
901
902 // Bits used in the next function
903 static const char ExternalTypeBits = DSNode::GlobalNode | DSNode::NewNode;
904
905 #if 0
906 // GlobalDSGraph::cloneNodeInto - Clone a global node and all its externally
907 // visible target links (and recursively their such links) into this graph.
908 // NodeCache maps the node being cloned to its clone in the Globals graph,
909 // in order to track cycles.
910 // GlobalsAreFinal is a flag that says whether it is safe to assume that
911 // an existing global node is complete.  This is important to avoid
912 // reinserting all globals when inserting Calls to functions.
913 // This is a helper function for cloneGlobals and cloneCalls.
914 // 
915 DSNode* GlobalDSGraph::cloneNodeInto(DSNode *OldNode,
916                                     std::map<const DSNode*, DSNode*> &NodeCache,
917                                     bool GlobalsAreFinal) {
918   if (OldNode == 0) return 0;
919
920   // The caller should check this is an external node.  Just more  efficient...
921   assert((OldNode->NodeType & ExternalTypeBits) && "Non-external node");
922
923   // If a clone has already been created for OldNode, return it.
924   DSNode*& CacheEntry = NodeCache[OldNode];
925   if (CacheEntry != 0)
926     return CacheEntry;
927
928   // The result value...
929   DSNode* NewNode = 0;
930
931   // If nodes already exist for any of the globals of OldNode,
932   // merge all such nodes together since they are merged in OldNode.
933   // If ValueCacheIsFinal==true, look for an existing node that has
934   // an identical list of globals and return it if it exists.
935   //
936   for (unsigned j = 0, N = OldNode->getGlobals().size(); j != N; ++j)
937     if (DSNode *PrevNode = ValueMap[OldNode->getGlobals()[j]].getNode()) {
938       if (NewNode == 0) {
939         NewNode = PrevNode;             // first existing node found
940         if (GlobalsAreFinal && j == 0)
941           if (OldNode->getGlobals() == PrevNode->getGlobals()) {
942             CacheEntry = NewNode;
943             return NewNode;
944           }
945       }
946       else if (NewNode != PrevNode) {   // found another, different from prev
947         // update ValMap *before* merging PrevNode into NewNode
948         for (unsigned k = 0, NK = PrevNode->getGlobals().size(); k < NK; ++k)
949           ValueMap[PrevNode->getGlobals()[k]] = NewNode;
950         NewNode->mergeWith(PrevNode);
951       }
952     } else if (NewNode != 0) {
953       ValueMap[OldNode->getGlobals()[j]] = NewNode; // add the merged node
954     }
955
956   // If no existing node was found, clone the node and update the ValMap.
957   if (NewNode == 0) {
958     NewNode = new DSNode(*OldNode);
959     Nodes.push_back(NewNode);
960     for (unsigned j = 0, e = NewNode->getNumLinks(); j != e; ++j)
961       NewNode->setLink(j, 0);
962     for (unsigned j = 0, N = NewNode->getGlobals().size(); j < N; ++j)
963       ValueMap[NewNode->getGlobals()[j]] = NewNode;
964   }
965   else
966     NewNode->NodeType |= OldNode->NodeType; // Markers may be different!
967
968   // Add the entry to NodeCache
969   CacheEntry = NewNode;
970
971   // Rewrite the links in the new node to point into the current graph,
972   // but only for links to external nodes.  Set other links to NULL.
973   for (unsigned j = 0, e = OldNode->getNumLinks(); j != e; ++j) {
974     DSNode* OldTarget = OldNode->getLink(j);
975     if (OldTarget && (OldTarget->NodeType & ExternalTypeBits)) {
976       DSNode* NewLink = this->cloneNodeInto(OldTarget, NodeCache);
977       if (NewNode->getLink(j))
978         NewNode->getLink(j)->mergeWith(NewLink);
979       else
980         NewNode->setLink(j, NewLink);
981     }
982   }
983
984   // Remove all local markers
985   NewNode->NodeType &= ~(DSNode::AllocaNode | DSNode::ScalarNode);
986
987   return NewNode;
988 }
989
990
991 // GlobalDSGraph::cloneGlobals - Clone global nodes and all their externally
992 // visible target links (and recursively their such links) into this graph.
993 // 
994 void GlobalDSGraph::cloneGlobals(DSGraph& Graph, bool CloneCalls) {
995   std::map<const DSNode*, DSNode*> NodeCache;
996 #if 0
997   for (unsigned i = 0, N = Graph.Nodes.size(); i < N; ++i)
998     if (Graph.Nodes[i]->NodeType & DSNode::GlobalNode)
999       GlobalsGraph->cloneNodeInto(Graph.Nodes[i], NodeCache, false);
1000   if (CloneCalls)
1001     GlobalsGraph->cloneCalls(Graph);
1002
1003   GlobalsGraph->removeDeadNodes(/*KeepAllGlobals*/ true, /*KeepCalls*/ true);
1004 #endif
1005 }
1006
1007
1008 // GlobalDSGraph::cloneCalls - Clone function calls and their visible target
1009 // links (and recursively their such links) into this graph.
1010 // 
1011 void GlobalDSGraph::cloneCalls(DSGraph& Graph) {
1012   std::map<const DSNode*, DSNode*> NodeCache;
1013   vector<DSCallSite >& FromCalls =Graph.FunctionCalls;
1014
1015   FunctionCalls.reserve(FunctionCalls.size() + FromCalls.size());
1016
1017   for (int i = 0, ei = FromCalls.size(); i < ei; ++i) {
1018     DSCallSite& callCopy = FunctionCalls.back();
1019     callCopy.reserve(FromCalls[i].size());
1020     for (unsigned j = 0, ej = FromCalls[i].size(); j != ej; ++j)
1021       callCopy.push_back
1022         ((FromCalls[i][j] && (FromCalls[i][j]->NodeType & ExternalTypeBits))
1023          ? cloneNodeInto(FromCalls[i][j], NodeCache, true)
1024          : 0);
1025   }
1026
1027   // remove trivially identical function calls
1028   removeIdenticalCalls(FunctionCalls, "Globals Graph");
1029 }
1030 #endif
1031
1032 #endif