[llvm-commits] [parallel] CVS: llvm/include/llvm/Analysis/ProfileInfo.h ProfileInfoLoader.h AliasAnalysis.h DSGraph.h DSGraphTraits.h DSNode.h DSSupport.h LoopInfo.h PostDominators.h

Misha Brukman brukman at cs.uiuc.edu
Mon Mar 1 17:58:46 PST 2004


Changes in directory llvm/include/llvm/Analysis:

ProfileInfo.h added (r1.2.2.1)
ProfileInfoLoader.h added (r1.1.2.1)
AliasAnalysis.h updated: 1.8 -> 1.8.4.1
DSGraph.h updated: 1.64 -> 1.64.4.1
DSGraphTraits.h updated: 1.18 -> 1.18.4.1
DSNode.h updated: 1.33 -> 1.33.4.1
DSSupport.h updated: 1.26 -> 1.26.4.1
LoopInfo.h updated: 1.30 -> 1.30.2.1
PostDominators.h updated: 1.7 -> 1.7.4.1

---
Log message:

Merge from trunk

---
Diffs of the changes:  (+381 -89)

Index: llvm/include/llvm/Analysis/ProfileInfo.h
diff -c /dev/null llvm/include/llvm/Analysis/ProfileInfo.h:1.2.2.1
*** /dev/null	Mon Mar  1 17:57:29 2004
--- llvm/include/llvm/Analysis/ProfileInfo.h	Mon Mar  1 17:57:19 2004
***************
*** 0 ****
--- 1,51 ----
+ //===- llvm/Analysis/ProfileInfo.h - Profile Info Interface -----*- C++ -*-===//
+ // 
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by the LLVM research group and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for details.
+ // 
+ //===----------------------------------------------------------------------===//
+ //
+ // This file defines the generic ProfileInfo interface, which is used as the
+ // common interface used by all clients of profiling information, and
+ // implemented either by making static guestimations, or by actually reading in
+ // profiling information gathered by running the program.
+ //
+ // Note that to be useful, all profile-based optimizations should preserve
+ // ProfileInfo, which requires that they notify it when changes to the CFG are
+ // made.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #ifndef LLVM_ANALYSIS_PROFILEINFO_H
+ #define LLVM_ANALYSIS_PROFILEINFO_H
+ 
+ #include <string>
+ 
+ namespace llvm {
+   class BasicBlock;
+   class Pass;
+ 
+   /// createProfileLoaderPass - This function returns a Pass that loads the
+   /// profiling information for the module from the specified filename, making
+   /// it available to the optimizers.
+   Pass *createProfileLoaderPass(const std::string &Filename);
+ 
+   struct ProfileInfo {
+     virtual ~ProfileInfo();  // We want to be subclassed
+     
+     //===------------------------------------------------------------------===//
+     /// Profile Information Queries
+     ///
+     virtual unsigned getExecutionCount(BasicBlock *BB) = 0;
+     
+     //===------------------------------------------------------------------===//
+     /// Analysis Update Methods
+     ///
+ 
+   };
+ 
+ } // End llvm namespace
+ 
+ #endif


Index: llvm/include/llvm/Analysis/ProfileInfoLoader.h
diff -c /dev/null llvm/include/llvm/Analysis/ProfileInfoLoader.h:1.1.2.1
*** /dev/null	Mon Mar  1 17:57:29 2004
--- llvm/include/llvm/Analysis/ProfileInfoLoader.h	Mon Mar  1 17:57:19 2004
***************
*** 0 ****
--- 1,65 ----
+ //===- ProfileInfoLoader.h - Load & convert profile information -*- C++ -*-===//
+ // 
+ //                      The LLVM Compiler Infrastructure
+ //
+ // This file was developed by the LLVM research group and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for details.
+ // 
+ //===----------------------------------------------------------------------===//
+ //
+ // The ProfileInfoLoader class is used to load and represent profiling
+ // information read in from the dump file.  If conversions between formats are
+ // needed, it can also do this.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #ifndef LLVM_ANALYSIS_PROFILEINFOLOADER_H
+ #define LLVM_ANALYSIS_PROFILEINFOLOADER_H
+ 
+ #include <vector>
+ #include <string>
+ #include <utility>
+ 
+ namespace llvm {
+ 
+ class Module;
+ class Function;
+ class BasicBlock;
+ 
+ class ProfileInfoLoader {
+   Module &M;
+   std::vector<std::string> CommandLines;
+   std::vector<unsigned>    FunctionCounts;
+   std::vector<unsigned>    BlockCounts;
+ public:
+   // ProfileInfoLoader ctor - Read the specified profiling data file, exiting
+   // the program if the file is invalid or broken.
+   ProfileInfoLoader(const char *ToolName, const std::string &Filename,
+                     Module &M);
+ 
+   unsigned getNumExecutions() const { return CommandLines.size(); }
+   const std::string &getExecution(unsigned i) const { return CommandLines[i]; }
+ 
+   // getFunctionCounts - This method is used by consumers of function counting
+   // information.  If we do not directly have function count information, we
+   // compute it from other, more refined, types of profile information.
+   //
+   void getFunctionCounts(std::vector<std::pair<Function*, unsigned> > &Counts);
+ 
+   // hasAccurateBlockCounts - Return true if we can synthesize accurate block
+   // frequency information from whatever we have.
+   //
+   bool hasAccurateBlockCounts() const {
+     return !BlockCounts.empty();
+   }
+ 
+   // getBlockCounts - This method is used by consumers of block counting
+   // information.  If we do not directly have block count information, we
+   // compute it from other, more refined, types of profile information.
+   //
+   void getBlockCounts(std::vector<std::pair<BasicBlock*, unsigned> > &Counts);
+ };
+ 
+ } // End llvm namespace
+ 
+ #endif


Index: llvm/include/llvm/Analysis/AliasAnalysis.h
diff -u llvm/include/llvm/Analysis/AliasAnalysis.h:1.8 llvm/include/llvm/Analysis/AliasAnalysis.h:1.8.4.1
--- llvm/include/llvm/Analysis/AliasAnalysis.h:1.8	Wed Dec 10 23:05:02 2003
+++ llvm/include/llvm/Analysis/AliasAnalysis.h	Mon Mar  1 17:57:19 2004
@@ -31,15 +31,13 @@
 #define LLVM_ANALYSIS_ALIAS_ANALYSIS_H
 
 #include "llvm/Support/CallSite.h"
-#include "llvm/Pass.h"
+#include "llvm/Pass.h"    // Need this for IncludeFile
 
 namespace llvm {
 
 class LoadInst;
 class StoreInst;
 class TargetData;
-class AnalysisUsage;
-class Pass;
 
 class AliasAnalysis {
   const TargetData *TD;
@@ -95,6 +93,11 @@
   ///
   virtual void getMustAliases(Value *P, std::vector<Value*> &RetVals) {}
 
+  /// pointsToConstantMemory - If the specified pointer is known to point into
+  /// constant global memory, return true.  This allows disambiguation of store
+  /// instructions from constant pointers.
+  ///
+  virtual bool pointsToConstantMemory(const Value *P) { return false; }
 
   //===--------------------------------------------------------------------===//
   /// Simple mod/ref information...
@@ -114,7 +117,9 @@
   /// pointer.
   ///
   virtual ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size) {
-    return ModRef;
+    // If P points to a constant memory location, the call definitely could not
+    // modify the memory location.
+    return pointsToConstantMemory(P) ? Ref : ModRef;
   }
 
   /// getModRefInfo - Return information about whether two call sites may refer


Index: llvm/include/llvm/Analysis/DSGraph.h
diff -u llvm/include/llvm/Analysis/DSGraph.h:1.64 llvm/include/llvm/Analysis/DSGraph.h:1.64.4.1
--- llvm/include/llvm/Analysis/DSGraph.h:1.64	Wed Nov 12 11:58:09 2003
+++ llvm/include/llvm/Analysis/DSGraph.h	Mon Mar  1 17:57:19 2004
@@ -7,7 +7,8 @@
 // 
 //===----------------------------------------------------------------------===//
 //
-// This header defines the data structure graph.
+// This header defines the data structure graph (DSGraph) and the
+// ReachabilityCloner class.
 //
 //===----------------------------------------------------------------------===//
 
@@ -21,13 +22,86 @@
 class GlobalValue;
 
 //===----------------------------------------------------------------------===//
+/// DSScalarMap - An instance of this class is used to keep track of all of 
+/// which DSNode each scalar in a function points to.  This is specialized to
+/// keep track of globals with nodes in the function, and to keep track of the 
+/// unique DSNodeHandle being used by the scalar map.
+///
+/// This class is crucial to the efficiency of DSA with some large SCC's.  In 
+/// these cases, the cost of iterating over the scalar map dominates the cost
+/// of DSA.  In all of these cases, the DSA phase is really trying to identify 
+/// globals or unique node handles active in the function.
+///
+class DSScalarMap {
+  typedef hash_map<Value*, DSNodeHandle> ValueMapTy;
+  ValueMapTy ValueMap;
+
+  typedef hash_set<GlobalValue*> GlobalSetTy;
+  GlobalSetTy GlobalSet;
+public:
+
+  // Compatibility methods: provide an interface compatible with a map of 
+  // Value* to DSNodeHandle's.
+  typedef ValueMapTy::const_iterator const_iterator;
+  typedef ValueMapTy::iterator iterator;
+  iterator begin() { return ValueMap.begin(); }
+  iterator end()   { return ValueMap.end(); }
+  const_iterator begin() const { return ValueMap.begin(); }
+  const_iterator end() const { return ValueMap.end(); }
+  iterator find(Value *V) { return ValueMap.find(V); }
+  const_iterator find(Value *V) const { return ValueMap.find(V); }
+  unsigned count(Value *V) const { return ValueMap.count(V); }
+
+  void erase(Value *V) { erase(find(V)); }
+
+  /// replaceScalar - When an instruction needs to be modified, this method can
+  /// be used to update the scalar map to remove the old and insert the new.
+  void replaceScalar(Value *Old, Value *New) {
+    iterator I = find(Old);
+    assert(I != end() && "Old value is not in the map!");
+    ValueMap.insert(std::make_pair(New, I->second));
+    erase(I);
+  }
+
+  DSNodeHandle &operator[](Value *V) {
+    std::pair<iterator,bool> IP = 
+      ValueMap.insert(std::make_pair(V, DSNodeHandle()));
+    if (IP.second) {  // Inserted the new entry into the map.
+      if (GlobalValue *GV = dyn_cast<GlobalValue>(V))
+        GlobalSet.insert(GV);
+    }
+    return IP.first->second;
+  }
+
+  void erase(iterator I) { 
+    assert(I != ValueMap.end() && "Cannot erase end!");
+    if (GlobalValue *GV = dyn_cast<GlobalValue>(I->first))
+      GlobalSet.erase(GV);
+    ValueMap.erase(I); 
+  }
+
+  void clear() {
+    ValueMap.clear();
+    GlobalSet.clear();
+  }
+
+  // Access to the global set: the set of all globals currently in the
+  // scalar map.
+  typedef GlobalSetTy::const_iterator global_iterator;
+  global_iterator global_begin() const { return GlobalSet.begin(); }
+  global_iterator global_end() const { return GlobalSet.end(); }
+};
+
+
+//===----------------------------------------------------------------------===//
 /// DSGraph - The graph that represents a function.
 ///
 struct DSGraph {
   // Public data-type declarations...
-  typedef hash_map<Value*, DSNodeHandle> ScalarMapTy;
+  typedef DSScalarMap ScalarMapTy;
   typedef hash_map<Function*, DSNodeHandle> ReturnNodesTy;
-  typedef hash_set<const GlobalValue*> GlobalSetTy;
+  typedef hash_set<GlobalValue*> GlobalSetTy;
+  typedef ilist<DSNode> NodeListTy;
 
   /// NodeMapTy - This data type is used when cloning one graph into another to
   /// keep track of the correspondence between the nodes in the old and new
@@ -37,7 +111,7 @@
   DSGraph *GlobalsGraph;   // Pointer to the common graph of global objects
   bool PrintAuxCalls;      // Should this graph print the Aux calls vector?
 
-  std::vector<DSNode*> Nodes;
+  NodeListTy Nodes;
   ScalarMapTy ScalarMap;
 
   // ReturnNodes - A return value for every function merged into this graph.
@@ -104,10 +178,14 @@
   void setPrintAuxCalls() { PrintAuxCalls = true; }
   bool shouldPrintAuxCalls() const { return PrintAuxCalls; }
 
-  /// getNodes - Get a vector of all the nodes in the graph
-  /// 
-  const std::vector<DSNode*> &getNodes() const { return Nodes; }
-        std::vector<DSNode*> &getNodes()       { return Nodes; }
+  /// node_iterator/begin/end - Iterate over all of the nodes in the graph.  Be
+  /// extremely careful with these methods because any merging of nodes could
+  /// cause the node to be removed from this list.  This means that if you are
+  /// iterating over nodes and doing something that could cause _any_ node to
+  /// merge, your node_iterators into this graph can be invalidated.
+  typedef NodeListTy::compat_iterator node_iterator;
+  node_iterator node_begin() const { return Nodes.compat_begin(); }
+  node_iterator node_end()   const { return Nodes.compat_end(); }
 
   /// getFunctionNames - Return a space separated list of the name of the
   /// functions in this graph (if any)
@@ -116,6 +194,7 @@
   /// addNode - Add a new node to the graph.
   ///
   void addNode(DSNode *N) { Nodes.push_back(N); }
+  void unlinkNode(DSNode *N) { Nodes.remove(N); }
 
   /// getScalarMap - Get a map that describes what the nodes the scalars in this
   /// function point to...
@@ -202,8 +281,8 @@
   /// is useful for clearing out markers like Incomplete.
   ///
   void maskNodeTypes(unsigned Mask) {
-    for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
-      Nodes[i]->maskNodeTypes(Mask);
+    for (node_iterator I = node_begin(), E = node_end(); I != E; ++I)
+      (*I)->maskNodeTypes(Mask);
   }
   void maskIncompleteMarkers() { maskNodeTypes(~DSNode::Incomplete); }
 
@@ -240,24 +319,11 @@
     DontCloneAuxCallNodes = 1 << 2, CloneAuxCallNodes = 0,
     StripModRefBits       = 1 << 3, KeepModRefBits    = 0,
     StripIncompleteBit    = 1 << 4, KeepIncompleteBit = 0,
+    UpdateInlinedGlobals  = 1 << 5, DontUpdateInlinedGlobals = 0,
   };
 
-private:
-  void cloneReachableNodes(const DSNode*  Node,
-                           unsigned BitsToClear,
-                           NodeMapTy& OldNodeMap,
-                           NodeMapTy& CompletedNodeMap);
-
-public:
   void updateFromGlobalGraph();
 
-  void cloneReachableSubgraph(const DSGraph& G,
-                              const hash_set<const DSNode*>& RootNodes,
-                              NodeMapTy& OldNodeMap,
-                              NodeMapTy& CompletedNodeMap,
-                              unsigned CloneFlags = 0);
-
-
   /// computeNodeMapping - Given roots in two different DSGraphs, traverse the
   /// nodes reachable from the two graphs, computing the mapping of nodes from
   /// the first to the second graph.
@@ -270,6 +336,8 @@
   /// cloneInto - Clone the specified DSGraph into the current graph.  The
   /// translated ScalarMap for the old function is filled into the OldValMap
   /// member, and the translated ReturnNodes map is returned into ReturnNodes.
+  /// OldNodeMap contains a mapping from the original nodes to the newly cloned
+  /// nodes.
   ///
   /// The CloneFlags member controls various aspects of the cloning process.
   ///
@@ -294,7 +362,7 @@
 
   // Methods for checking to make sure graphs are well formed...
   void AssertNodeInGraph(const DSNode *N) const {
-    assert((!N || find(Nodes.begin(), Nodes.end(), N) != Nodes.end()) &&
+    assert((!N || N->getParentGraph() == this) &&
            "AssertNodeInGraph: Node is not in graph!");
   }
   void AssertNodeContainsGlobal(const DSNode *N, GlobalValue *GV) const {
@@ -321,13 +389,6 @@
 
   void AssertGraphOK() const;
 
-  /// mergeInGlobalsGraph - This method is useful for clients to incorporate the
-  /// globals graph into the DS, BU or TD graph for a function.  This code
-  /// retains all globals, i.e., does not delete unreachable globals after they
-  /// are inlined.
-  ///
-  void mergeInGlobalsGraph();
-
   /// removeTriviallyDeadNodes - After the graph has been constructed, this
   /// method removes all unreachable nodes that are created because they got
   /// merged with other nodes in the graph.  This is used as the first step of
@@ -336,6 +397,49 @@
   void removeTriviallyDeadNodes();
 };
 
+
+  /// ReachabilityCloner - This class is used to incrementally clone and merge
+  /// nodes from a non-changing source graph into a potentially mutating
+  /// destination graph.  Nodes are only cloned over on demand, either in
+  /// responds to a merge() or getClonedNH() call.  When a node is cloned over,
+  /// all of the nodes reachable from it are automatically brought over as well.
+  class ReachabilityCloner {
+    DSGraph &Dest;
+    const DSGraph &Src;
+
+    /// BitsToKeep - These bits are retained from the source node when the
+    /// source nodes are merged into the destination graph.
+    unsigned BitsToKeep;
+    unsigned CloneFlags;
+
+    // NodeMap - A mapping from nodes in the source graph to the nodes that
+    // represent them in the destination graph.
+    DSGraph::NodeMapTy NodeMap;
+  public:
+    ReachabilityCloner(DSGraph &dest, const DSGraph &src, unsigned cloneFlags)
+      : Dest(dest), Src(src), CloneFlags(cloneFlags) {
+      assert(&Dest != &Src && "Cannot clone from graph to same graph!");
+      BitsToKeep = ~DSNode::DEAD;
+      if (CloneFlags & DSGraph::StripAllocaBit)
+        BitsToKeep &= ~DSNode::AllocaNode;
+      if (CloneFlags & DSGraph::StripModRefBits)
+        BitsToKeep &= ~(DSNode::Modified | DSNode::Read);
+      if (CloneFlags & DSGraph::StripIncompleteBit)
+        BitsToKeep &= ~DSNode::Incomplete;
+    }
+    
+    DSNodeHandle getClonedNH(const DSNodeHandle &SrcNH);
+
+    void merge(const DSNodeHandle &NH, const DSNodeHandle &SrcNH);
+
+    /// mergeCallSite - Merge the nodes reachable from the specified src call
+    /// site into the nodes reachable from DestCS.
+    void mergeCallSite(const DSCallSite &DestCS, const DSCallSite &SrcCS);
+
+    bool clonedNode() const { return !NodeMap.empty(); }
+
+    void destroy() { NodeMap.clear(); }
+  };
 } // End llvm namespace
 
 #endif


Index: llvm/include/llvm/Analysis/DSGraphTraits.h
diff -u llvm/include/llvm/Analysis/DSGraphTraits.h:1.18 llvm/include/llvm/Analysis/DSGraphTraits.h:1.18.4.1
--- llvm/include/llvm/Analysis/DSGraphTraits.h:1.18	Tue Nov 11 16:41:30 2003
+++ llvm/include/llvm/Analysis/DSGraphTraits.h	Mon Mar  1 17:57:19 2004
@@ -33,10 +33,14 @@
 
   DSNodeIterator(NodeTy *N) : Node(N), Offset(0) {}   // begin iterator
   DSNodeIterator(NodeTy *N, bool) : Node(N) {         // Create end iterator
-    Offset = N->getNumLinks() << DS::PointerShift;
-    if (Offset == 0 && Node->getForwardNode() &&
-        Node->isDeadNode())        // Model Forward link
-      Offset += DS::PointerSize;
+    if (N != 0) {
+      Offset = N->getNumLinks() << DS::PointerShift;
+      if (Offset == 0 && Node->getForwardNode() &&
+          Node->isDeadNode())        // Model Forward link
+        Offset += DS::PointerSize;
+    } else {
+      Offset = 0;
+    }
   }
 public:
   DSNodeIterator(const DSNodeHandle &NH)
@@ -115,13 +119,12 @@
   typedef std::pointer_to_unary_function<DSNode *, DSNode&> DerefFun;
 
   // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
-  typedef mapped_iterator<std::vector<DSNode*>::iterator,
-                          DerefFun> nodes_iterator;
+  typedef mapped_iterator<DSGraph::node_iterator, DerefFun> nodes_iterator;
   static nodes_iterator nodes_begin(DSGraph *G) {
-    return map_iterator(G->getNodes().begin(), DerefFun(dereference));
+    return map_iterator(G->node_begin(), DerefFun(dereference));
   }
   static nodes_iterator nodes_end(DSGraph *G) {
-    return map_iterator(G->getNodes().end(), DerefFun(dereference));
+    return map_iterator(G->node_end(), DerefFun(dereference));
   }
 
   static ChildIteratorType child_begin(NodeType *N) { return N->begin(); }
@@ -135,13 +138,12 @@
   typedef std::pointer_to_unary_function<const DSNode *,const DSNode&> DerefFun;
 
   // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
-  typedef mapped_iterator<std::vector<DSNode*>::const_iterator,
-                          DerefFun> nodes_iterator;
+  typedef mapped_iterator<DSGraph::node_iterator, DerefFun> nodes_iterator;
   static nodes_iterator nodes_begin(const DSGraph *G) {
-    return map_iterator(G->getNodes().begin(), DerefFun(dereferenceC));
+    return map_iterator(G->node_begin(), DerefFun(dereferenceC));
   }
   static nodes_iterator nodes_end(const DSGraph *G) {
-    return map_iterator(G->getNodes().end(), DerefFun(dereferenceC));
+    return map_iterator(G->node_end(), DerefFun(dereferenceC));
   }
 
   static ChildIteratorType child_begin(const NodeType *N) { return N->begin(); }


Index: llvm/include/llvm/Analysis/DSNode.h
diff -u llvm/include/llvm/Analysis/DSNode.h:1.33 llvm/include/llvm/Analysis/DSNode.h:1.33.4.1
--- llvm/include/llvm/Analysis/DSNode.h:1.33	Tue Nov 11 16:41:30 2003
+++ llvm/include/llvm/Analysis/DSNode.h	Mon Mar  1 17:57:19 2004
@@ -42,6 +42,11 @@
   /// null.
   DSNodeHandle ForwardNH;
 
+  /// Next, Prev - These instance variables are used to keep the node on a
+  /// doubly-linked ilist in the DSGraph.
+  DSNode *Next, *Prev;
+  friend class ilist_traits<DSNode>;
+
   /// Size - The current size of the node.  This should be equal to the size of
   /// the current type record.
   ///
@@ -97,9 +102,16 @@
 private:
   unsigned short NodeType;
 public:
-
+  
+  /// DSNode ctor - Create a node of the specified type, inserting it into the
+  /// specified graph.
   DSNode(const Type *T, DSGraph *G);
-  DSNode(const DSNode &, DSGraph *G);
+
+  /// DSNode "copy ctor" - Copy the specified node, inserting it into the
+  /// specified graph.  If NullLinks is true, then null out all of the links,
+  /// but keep the same number of them.  This can be used for efficiency if the
+  /// links are just going to be clobbered anyway.
+  DSNode(const DSNode &, DSGraph *G, bool NullLinks = false);
 
   ~DSNode() {
     dropAllReferences();
@@ -145,10 +157,20 @@
   /// getForwardNode - This method returns the node that this node is forwarded
   /// to, if any.
   DSNode *getForwardNode() const { return ForwardNH.getNode(); }
+
+  /// isForwarding - Return true if this node is forwarding to another.
+  ///
+  bool isForwarding() const { return !ForwardNH.isNull(); }
+
+  /// stopForwarding - When the last reference to this forwarding node has been
+  /// dropped, delete the node.
   void stopForwarding() {
-    assert(!ForwardNH.isNull() &&
+    assert(isForwarding() &&
            "Node isn't forwarding, cannot stopForwarding!");
     ForwardNH.setNode(0);
+    assert(ParentGraph == 0 &&
+           "Forwarding nodes must have been removed from graph!");
+    delete this;
   }
 
   /// hasLink - Return true if this memory object has a link in slot #LinkNo
@@ -241,14 +263,24 @@
   /// also marks the node with the 'G' flag if it does not already have it.
   ///
   void addGlobal(GlobalValue *GV);
+  void mergeGlobals(const std::vector<GlobalValue*> &RHS);
   const std::vector<GlobalValue*> &getGlobals() const { return Globals; }
 
+  typedef std::vector<GlobalValue*>::const_iterator global_iterator;
+  global_iterator global_begin() const { return Globals.begin(); }
+  global_iterator global_end() const { return Globals.end(); }
+
+
   /// maskNodeTypes - Apply a mask to the node types bitfield.
   ///
   void maskNodeTypes(unsigned Mask) {
     NodeType &= Mask;
   }
 
+  void mergeNodeFlags(unsigned RHS) {
+    NodeType |= RHS;
+  }
+
   /// getNodeFlags - Return all of the flags set on the node.  If the DEAD flag
   /// is set, hide it from the caller.
   unsigned getNodeFlags() const { return NodeType & ~DEAD; }
@@ -273,6 +305,7 @@
   DSNode *setIncompleteMarker() { NodeType |= Incomplete; return this; }
   DSNode *setModifiedMarker()   { NodeType |= Modified;   return this; }
   DSNode *setReadMarker()       { NodeType |= Read;       return this; }
+  DSNode *setArrayMarker()      { NodeType |= Array; return this; }
 
   void makeNodeDead() {
     Globals.clear();
@@ -292,7 +325,7 @@
 
   void dropAllReferences() {
     Links.clear();
-    if (!ForwardNH.isNull())
+    if (isForwarding())
       ForwardNH.setNode(0);
   }
 
@@ -313,22 +346,46 @@
   static void MergeNodes(DSNodeHandle& CurNodeH, DSNodeHandle& NH);
 };
 
+//===----------------------------------------------------------------------===//
+// Define the ilist_traits specialization for the DSGraph ilist.
+//
+template<>
+struct ilist_traits<DSNode> {
+  static DSNode *getPrev(const DSNode *N) { return N->Prev; }
+  static DSNode *getNext(const DSNode *N) { return N->Next; }
+
+  static void setPrev(DSNode *N, DSNode *Prev) { N->Prev = Prev; }
+  static void setNext(DSNode *N, DSNode *Next) { N->Next = Next; }
+
+  static DSNode *createNode() { return new DSNode(0,0); }
+  //static DSNode *createNode(const DSNode &V) { return new DSNode(V); }
+
+
+  void addNodeToList(DSNode *NTy) {}
+  void removeNodeFromList(DSNode *NTy) {}
+  void transferNodesFromList(iplist<DSNode, ilist_traits> &L2,
+                             ilist_iterator<DSNode> first,
+                             ilist_iterator<DSNode> last) {}
+};
+
+template<>
+struct ilist_traits<const DSNode> : public ilist_traits<DSNode> {};
 
 //===----------------------------------------------------------------------===//
 // Define inline DSNodeHandle functions that depend on the definition of DSNode
 //
 inline DSNode *DSNodeHandle::getNode() const {
   assert((!N || Offset < N->Size || (N->Size == 0 && Offset == 0) ||
-          !N->ForwardNH.isNull()) && "Node handle offset out of range!");
-  if (!N || N->ForwardNH.isNull())
+          N->isForwarding()) && "Node handle offset out of range!");
+  if (N == 0 || !N->isForwarding())
     return N;
 
   return HandleForwarding();
 }
 
-inline void DSNodeHandle::setNode(DSNode *n) {
-  assert(!n || !n->getForwardNode() && "Cannot set node to a forwarded node!");
-  if (N) N->NumReferrers--;
+inline void DSNodeHandle::setNode(DSNode *n) const {
+  assert(!n || !n->isForwarding() && "Cannot set node to a forwarded node!");
+  if (N) getNode()->NumReferrers--;
   N = n;
   if (N) {
     N->NumReferrers++;
@@ -340,7 +397,7 @@
   }
   assert(!N || ((N->NodeType & DSNode::DEAD) == 0));
   assert((!N || Offset < N->Size || (N->Size == 0 && Offset == 0) ||
-          !N->ForwardNH.isNull()) && "Node handle offset out of range!");
+          N->isForwarding()) && "Node handle offset out of range!");
 }
 
 inline bool DSNodeHandle::hasLink(unsigned Num) const {
@@ -377,11 +434,14 @@
 /// mergeWith - Merge the logical node pointed to by 'this' with the node
 /// pointed to by 'N'.
 ///
-inline void DSNodeHandle::mergeWith(const DSNodeHandle &Node) {
-  if (N != 0)
+inline void DSNodeHandle::mergeWith(const DSNodeHandle &Node) const {
+  if (!isNull())
     getNode()->mergeWith(Node, Offset);
-  else     // No node to merge with, so just point to Node
-    *this = Node;
+  else {   // No node to merge with, so just point to Node
+    Offset = 0;
+    setNode(Node.getNode());
+    Offset = Node.getOffset();
+  }
 }
 
 } // End llvm namespace


Index: llvm/include/llvm/Analysis/DSSupport.h
diff -u llvm/include/llvm/Analysis/DSSupport.h:1.26 llvm/include/llvm/Analysis/DSSupport.h:1.26.4.1
--- llvm/include/llvm/Analysis/DSSupport.h:1.26	Tue Nov 11 16:41:31 2003
+++ llvm/include/llvm/Analysis/DSSupport.h	Mon Mar  1 17:57:19 2004
@@ -28,6 +28,7 @@
 
 class DSNode;                  // Each node in the graph
 class DSGraph;                 // A graph for a function
+class ReachabilityCloner;
 
 namespace DS { // FIXME: After the paper, this should get cleaned up
   enum { PointerShift = 2,     // 64bit ptrs = 3, 32 bit ptrs = 2
@@ -76,6 +77,7 @@
   }
   bool operator>(const DSNodeHandle &H) const { return H < *this; }
   bool operator==(const DSNodeHandle &H) const { // Allow comparison
+    // getNode can change the offset, so we must call getNode() first.
     return getNode() == H.getNode() && Offset == H.Offset;
   }
   bool operator!=(const DSNodeHandle &H) const { return !operator==(H); }
@@ -93,7 +95,7 @@
   inline DSNode *getNode() const;  // Defined inline in DSNode.h
   unsigned getOffset() const { return Offset; }
 
-  inline void setNode(DSNode *N);  // Defined inline in DSNode.h
+  inline void setNode(DSNode *N) const;  // Defined inline in DSNode.h
   void setOffset(unsigned O) {
     //assert((!N || Offset < N->Size || (N->Size == 0 && Offset == 0) ||
     //       !N->ForwardNH.isNull()) && "Node handle offset out of range!");
@@ -108,7 +110,7 @@
   /// mergeWith - Merge the logical node pointed to by 'this' with the node
   /// pointed to by 'N'.
   ///
-  void mergeWith(const DSNodeHandle &N);
+  void mergeWith(const DSNodeHandle &N) const;
 
   // hasLink - Return true if there is a link at the specified offset...
   inline bool hasLink(unsigned Num) const;
@@ -127,7 +129,8 @@
 } // End llvm namespace
 
 namespace std {
-  inline void swap(llvm::DSNodeHandle &NH1, llvm::DSNodeHandle &NH2) { NH1.swap(NH2); }
+  template<>
+  inline void swap<llvm::DSNodeHandle>(llvm::DSNodeHandle &NH1, llvm::DSNodeHandle &NH2) { NH1.swap(NH2); }
 }
 
 namespace llvm {
@@ -148,7 +151,7 @@
                      const hash_map<const DSNode*, DSNode*> &NodeMap) {
     if (DSNode *N = Src.getNode()) {
       hash_map<const DSNode*, DSNode*>::const_iterator I = NodeMap.find(N);
-      assert(I != NodeMap.end() && "Not not in mapping!");
+      assert(I != NodeMap.end() && "Node not in mapping!");
 
       NH.setOffset(Src.getOffset());
       NH.setNode(I->second);
@@ -159,13 +162,17 @@
                      const hash_map<const DSNode*, DSNodeHandle> &NodeMap) {
     if (DSNode *N = Src.getNode()) {
       hash_map<const DSNode*, DSNodeHandle>::const_iterator I = NodeMap.find(N);
-      assert(I != NodeMap.end() && "Not not in mapping!");
+      assert(I != NodeMap.end() && "Node not in mapping!");
 
       NH.setOffset(Src.getOffset()+I->second.getOffset());
       NH.setNode(I->second.getNode());
     }
   }
 
+  static void InitNH(DSNodeHandle &NH, const DSNodeHandle &Src,
+                     ReachabilityCloner &RC);
+
+
   DSCallSite();                         // DO NOT IMPLEMENT
 public:
   /// Constructor.  Note - This ctor destroys the argument vector passed in.  On
@@ -193,7 +200,7 @@
   /// This is useful when moving a call site from one graph to another.
   ///
   template<typename MapTy>
-  DSCallSite(const DSCallSite &FromCall, const MapTy &NodeMap) {
+  DSCallSite(const DSCallSite &FromCall, MapTy &NodeMap) {
     Site = FromCall.Site;
     InitNH(RetVal, FromCall.RetVal, NodeMap);
     InitNH(CalleeN, FromCall.CalleeN, NodeMap);
@@ -234,7 +241,7 @@
     assert(!CalleeN.getNode() && CalleeF); return CalleeF;
   }
 
-  unsigned            getNumPtrArgs() const { return CallArgs.size(); }
+  unsigned getNumPtrArgs() const { return CallArgs.size(); }
 
   DSNodeHandle &getPtrArg(unsigned i) {
     assert(i < CallArgs.size() && "Argument to getPtrArgNode is out of range!");
@@ -255,7 +262,7 @@
     }
   }
 
-  // MergeWith - Merge the return value and parameters of the these two call
+  // mergeWith - Merge the return value and parameters of the these two call
   // sites.
   void mergeWith(DSCallSite &CS) {
     getRetVal().mergeWith(CS.getRetVal());
@@ -288,14 +295,16 @@
   }
 
   bool operator==(const DSCallSite &CS) const {
-    return RetVal == CS.RetVal && CalleeN == CS.CalleeN &&
-           CalleeF == CS.CalleeF && CallArgs == CS.CallArgs;
+    return CalleeF == CS.CalleeF && CalleeN == CS.CalleeN &&
+           RetVal == CS.RetVal && CallArgs == CS.CallArgs;
   }
 };
 
 } // End llvm namespace
 
 namespace std {
-  inline void swap(llvm::DSCallSite &CS1, llvm::DSCallSite &CS2) { CS1.swap(CS2); }
+  template<>
+  inline void swap<llvm::DSCallSite>(llvm::DSCallSite &CS1,
+                                     llvm::DSCallSite &CS2) { CS1.swap(CS2); }
 }
 #endif


Index: llvm/include/llvm/Analysis/LoopInfo.h
diff -u llvm/include/llvm/Analysis/LoopInfo.h:1.30 llvm/include/llvm/Analysis/LoopInfo.h:1.30.2.1
--- llvm/include/llvm/Analysis/LoopInfo.h:1.30	Wed Jan  7 18:08:22 2004
+++ llvm/include/llvm/Analysis/LoopInfo.h	Mon Mar  1 17:57:19 2004
@@ -54,6 +54,7 @@
   Loop *getParentLoop() const { return ParentLoop; }
 
   /// contains - Return true of the specified basic block is in this loop
+  ///
   bool contains(const BasicBlock *BB) const;
 
   /// iterator/begin/end - Return the loops contained entirely within this loop.


Index: llvm/include/llvm/Analysis/PostDominators.h
diff -u llvm/include/llvm/Analysis/PostDominators.h:1.7 llvm/include/llvm/Analysis/PostDominators.h:1.7.4.1
--- llvm/include/llvm/Analysis/PostDominators.h:1.7	Sat Dec  6 18:35:19 2003
+++ llvm/include/llvm/Analysis/PostDominators.h	Mon Mar  1 17:57:19 2004
@@ -18,7 +18,6 @@
 
 namespace llvm {
 
-
 /// PostDominatorSet Class - Concrete subclass of DominatorSetBase that is used
 /// to compute the post-dominator set.  Because there can be multiple exit nodes
 /// in an LLVM function, we calculate post dominators with a special null block
@@ -31,19 +30,17 @@
 
   virtual bool runOnFunction(Function &F);
 
-  // getAnalysisUsage - This pass does not modify the function at all.
-  //
+  /// getAnalysisUsage - This pass does not modify the function at all.
+  ///
   virtual void getAnalysisUsage(AnalysisUsage &AU) const {
     AU.setPreservesAll();
   }
 };
 
 
-
-//===-------------------------------------
-// ImmediatePostDominators Class - Concrete subclass of ImmediateDominatorsBase
-// that is used to compute the immediate post-dominators.
-//
+/// ImmediatePostDominators Class - Concrete subclass of ImmediateDominatorsBase
+/// that is used to compute the immediate post-dominators.
+///
 struct ImmediatePostDominators : public ImmediateDominatorsBase {
   ImmediatePostDominators() : ImmediateDominatorsBase(true) {}
 
@@ -64,10 +61,9 @@
 };
 
 
-//===-------------------------------------
-// PostDominatorTree Class - Concrete subclass of DominatorTree that is used to
-// compute the a post-dominator tree.
-//
+/// PostDominatorTree Class - Concrete subclass of DominatorTree that is used to
+/// compute the a post-dominator tree.
+///
 struct PostDominatorTree : public DominatorTreeBase {
   PostDominatorTree() : DominatorTreeBase(true) {}
 
@@ -88,10 +84,9 @@
 };
 
 
-//===-------------------------------------
-// PostDominanceFrontier Class - Concrete subclass of DominanceFrontier that is
-// used to compute the a post-dominance frontier.
-//
+/// PostDominanceFrontier Class - Concrete subclass of DominanceFrontier that is
+/// used to compute the a post-dominance frontier.
+///
 struct PostDominanceFrontier : public DominanceFrontierBase {
   PostDominanceFrontier() : DominanceFrontierBase(true) {}
 





More information about the llvm-commits mailing list