[llvm-commits] [poolalloc] r114897 - in /poolalloc/trunk: include/poolalloc/Heuristic.h lib/PoolAllocate/Heuristic.cpp lib/PoolAllocate/PoolAllocate.cpp test/TEST.poolalloc.Makefile

John Criswell criswell at uiuc.edu
Mon Sep 27 14:48:46 PDT 2010


Author: criswell
Date: Mon Sep 27 16:48:45 2010
New Revision: 114897

URL: http://llvm.org/viewvc/llvm-project?rev=114897&view=rev
Log:
Made the Heuristic pass a proper LLVM pass, able to query other analysis
passes.  A downside of this refactoring is that the
-paheur-AllButUnreachableFromMemory must be given explicitly on the opt command
line now to appease the LLVM PassManager (which seems to require that the
default analysis pass in an analysis group be an ImmutablePass).
There are no functionality changes beyond the requirement to specify the
heuristic explicitly.

Modified:
    poolalloc/trunk/include/poolalloc/Heuristic.h
    poolalloc/trunk/lib/PoolAllocate/Heuristic.cpp
    poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp
    poolalloc/trunk/test/TEST.poolalloc.Makefile

Modified: poolalloc/trunk/include/poolalloc/Heuristic.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/poolalloc/Heuristic.h?rev=114897&r1=114896&r2=114897&view=diff
==============================================================================
--- poolalloc/trunk/include/poolalloc/Heuristic.h (original)
+++ poolalloc/trunk/include/poolalloc/Heuristic.h Mon Sep 27 16:48:45 2010
@@ -34,31 +34,28 @@
   class Type;
 
 namespace PA {
-  class Heuristic : public ImmutablePass {
+  // Type for a container of DSNodes
+  typedef std::vector<const DSNode*> DSNodeList_t;
+
+  //
+  // Class: Heuristic
+  //
+  // Description:
+  //  This class is a base class for passes implementing a policy for automatic
+  //  pool allocation.
+  //
+  class Heuristic {
   protected:
     Module *M;
     PoolAllocate *PA;
 
   public:
-    //
-    // Pass methods and members.
-    //
-    static char ID;
-    Heuristic (intptr_t IDp = (intptr_t) (&ID)) : ImmutablePass (IDp) { }
-    virtual ~Heuristic () {return;}
-    virtual bool runOnModule (Module & M);
-
-    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
-      // We require DSA while this pass is still responding to queries
-      AU.addRequiredTransitive<EQTDDataStructures>();
-
-      // This pass does not modify anything when it runs
-      AU.setPreservesAll();
-    }
+    // Virtual Destructor
+    virtual ~Heuristic() {}
 
-    //
-    // Other methods.
-    //
+    // Need by passes that inherit from this class.  This is needed even though
+    // this class is not an LLVM pass in and of itself.
+    static char ID;
     void Initialize (PoolAllocate &pa) {
       PA = &pa;
     }
@@ -99,13 +96,13 @@
     /// AssignToPools - Partition NodesToPA into a set of disjoint pools,
     /// returning the result in ResultPools.  If this is a function being pool
     /// allocated, F will not be null.
-    virtual void AssignToPools(const std::vector<const DSNode*> &NodesToPA,
+    virtual void AssignToPools(const DSNodeList_t & NodesToPA,
                                Function *F, DSGraph* G,
-                               std::vector<OnePool> &ResultPools) = 0;
+                               std::vector<OnePool> &ResultPools) { }
 
     // Hacks for the OnlyOverhead heuristic.
     virtual void HackFunctionBody(Function &F,
-                                  std::map<const DSNode*, Value*> &PDs) {}
+                                  std::map<const DSNode*, Value*> &PDs) { }
 
     /// getRecommendedSize - Return the recommended pool size for this DSNode.
     ///
@@ -118,7 +115,270 @@
     static unsigned getRecommendedAlignment(const Type *Ty,
                                             const TargetData &TD);
   };
+
+  ////////////////////////////////////////////////////////////////////////////
+  // Define specific instances of this analysis and make them analysis passes
+  ////////////////////////////////////////////////////////////////////////////
+
+  //
+  // Class: AllNodesHeuristic 
+  //
+  // Description:
+  //  This class provides a pool allocation heuristic that forces all DSNodes
+  //  to be pool allocated.
+  //
+  class AllNodesHeuristic: public Heuristic, public ModulePass {
+    public:
+      // Pass ID
+      static char ID;
+
+      // Method used to implement analysis groups without C++ inheritance
+      virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) {
+        if (PI->isPassID(&Heuristic::ID))
+          return (Heuristic*)this;
+        return this;
+      }
+
+      AllNodesHeuristic (intptr_t IDp = (intptr_t) (&ID)): ModulePass (&IDp) { }
+      virtual ~AllNodesHeuristic () {return;}
+      virtual bool runOnModule (Module & M);
+
+      virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+        // We require DSA while this pass is still responding to queries
+        AU.addRequiredTransitive<EQTDDataStructures>();
+
+        // Make PassManager happy be requiring the default implementation of
+        // this analysis group
+        AU.addRequiredTransitive<Heuristic>();
+
+        // This pass does not modify anything when it runs
+        AU.setPreservesAll();
+      }
+
+      //
+      // Interface methods
+      //
+      virtual void AssignToPools (const DSNodeList_t & NodesToPA,
+                                  Function *F, DSGraph* G,
+                                  std::vector<OnePool> &ResultPools);
+  };
+
+  //===-- AllButUnreachableFromMemoryHeuristic Heuristic ------------------===//
+  //
+  // This heuristic pool allocates everything possible into separate pools,
+  // unless the pool is not reachable by other memory objects.  This filters
+  // out objects that are not cyclic and are only pointed to by scalars: these
+  // tend to be singular memory allocations for which it is not worth creating
+  // a whole pool.
+  //
+  class AllButUnreachableFromMemoryHeuristic : public Heuristic,
+                                               public ModulePass {
+    public:
+      static char ID;
+      virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) {
+        if (PI->isPassID(&Heuristic::ID))
+          return (Heuristic*)this;
+        return this;
+      }
+
+      AllButUnreachableFromMemoryHeuristic (intptr_t IDp = (intptr_t) (&ID)) :
+        ModulePass (IDp) { }
+      virtual ~AllButUnreachableFromMemoryHeuristic () {return;}
+      virtual bool runOnModule (Module & M);
+
+      virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+        // We require DSA while this pass is still responding to queries
+        AU.addRequiredTransitive<EQTDDataStructures>();
+
+        // Make PassManager happy be requiring the default implementation of
+        // this analysis group
+        AU.addRequiredTransitive<Heuristic>();
+
+        // This pass does not modify anything when it runs
+        AU.setPreservesAll();
+      }
+
+      virtual void AssignToPools(const DSNodeList_t &NodesToPA,
+                                 Function *F, DSGraph* G,
+                                 std::vector<OnePool> &ResultPools);
+  };
+
+  //===-- CyclicNodes Heuristic -------------------------------------------===//
+  //
+  // This heuristic only pool allocates nodes in an SCC in the DSGraph.
+  //
+  class CyclicNodesHeuristic : public Heuristic, public ModulePass {
+    public:
+      static char ID;
+      virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) {
+        if (PI->isPassID(&Heuristic::ID))
+          return (Heuristic*)this;
+        return this;
+      }
+
+
+      CyclicNodesHeuristic (intptr_t IDp=(intptr_t) (&ID)): ModulePass (IDp) { }
+      virtual ~CyclicNodesHeuristic () {return;}
+      virtual bool runOnModule (Module & M);
+
+      virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+        // We require DSA while this pass is still responding to queries
+        AU.addRequiredTransitive<EQTDDataStructures>();
+
+        // Make PassManager happy be requiring the default implementation of
+        // this analysis group
+        AU.addRequiredTransitive<Heuristic>();
+
+        // This pass does not modify anything when it runs
+        AU.setPreservesAll();
+      }
+
+      virtual void AssignToPools(const DSNodeList_t &NodesToPA,
+                                 Function *F, DSGraph* G,
+                                 std::vector<OnePool> &ResultPools);
+  };
+
+  //===-- SmartCoallesceNodes Heuristic------------------------------------===//
+  //
+  // This heuristic attempts to be smart and coallesce nodes at times.  In
+  // practice, it doesn't work very well.
+  //
+  class SmartCoallesceNodesHeuristic : public Heuristic, public ModulePass {
+    public:
+      static char ID;
+      virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) {
+        if (PI->isPassID(&Heuristic::ID))
+          return (Heuristic*)this;
+        return this;
+      }
+
+      SmartCoallesceNodesHeuristic (intptr_t IDp = (intptr_t) (&ID)) :
+        ModulePass (IDp) { }
+      virtual ~SmartCoallesceNodesHeuristic () {return;}
+      virtual bool runOnModule (Module & M);
+
+      virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+        // We require DSA while this pass is still responding to queries
+        AU.addRequiredTransitive<EQTDDataStructures>();
+
+        // Make PassManager happy be requiring the default implementation of
+        // this analysis group
+        AU.addRequiredTransitive<Heuristic>();
+
+        // This pass does not modify anything when it runs
+        AU.setPreservesAll();
+      }
+
+      virtual void AssignToPools(const DSNodeList_t & NodesToPA,
+                                 Function *F, DSGraph* G,
+                                 std::vector<OnePool> &ResultPools);
+  };
+
+  //===-- AllInOneGlobalPool Heuristic ------------------------------------===//
+  //
+  // This heuristic puts all memory in the whole program into a single global
+  // pool.  This is not safe, and is not good for performance, but can be used
+  // to evaluate how good the pool allocator runtime works as a "malloc
+  // replacement".
+  //
+  class AllInOneGlobalPoolHeuristic : public Heuristic, public ModulePass {
+    private:
+      // TheGlobalPD - This global pool is the one and only one used when
+      // running with Heuristic=AllInOneGlobalPool.
+      GlobalVariable *TheGlobalPD;
+
+    public:
+      static char ID;
+      virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) {
+        if (PI->isPassID(&Heuristic::ID))
+          return (Heuristic*)this;
+        return this;
+      }
+
+      AllInOneGlobalPoolHeuristic(intptr_t IDp = (intptr_t) (&ID)) :
+        ModulePass (IDp), TheGlobalPD(0) {}
+
+      virtual bool runOnModule (Module & M);
+      virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+        // We require DSA while this pass is still responding to queries
+        AU.addRequiredTransitive<EQTDDataStructures>();
+
+        // Make PassManager happy be requiring the default implementation of
+        // this analysis group
+        AU.addRequiredTransitive<Heuristic>();
+
+        // This pass does not modify anything when it runs
+        AU.setPreservesAll();
+      }
+
+      virtual void AssignToPools(const DSNodeList_t &NodesToPA,
+                                 Function *F, DSGraph* G,
+                                 std::vector<OnePool> &ResultPools);
+  };
+
+  //===-- OnlyOverhead Heuristic ------------------------------------------===//
+  //
+  // This heuristic is a hack to evaluate how much overhead pool allocation adds
+  // to a program.  It adds all of the arguments, poolinits and pool destroys to
+  // the program, but dynamically only passes null into the pool alloc/free
+  // functions, causing them to allocate from the heap.
+  //
+  class OnlyOverheadHeuristic : public Heuristic, public ModulePass {
+    public:
+      static char ID;
+      virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) {
+        if (PI->isPassID(&Heuristic::ID))
+          return (Heuristic*)this;
+        return this;
+      }
+
+      OnlyOverheadHeuristic(intptr_t IDp = (intptr_t) (&ID)) :
+        ModulePass (IDp) {}
+
+      virtual bool runOnModule (Module & M);
+      virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+        // We require DSA while this pass is still responding to queries
+        AU.addRequiredTransitive<EQTDDataStructures>();
+
+        // Make PassManager happy be requiring the default implementation of
+        // this analysis group
+        AU.addRequiredTransitive<Heuristic>();
+
+        // This pass does not modify anything when it runs
+        AU.setPreservesAll();
+      }
+
+      virtual void AssignToPools(const DSNodeList_t &NodesToPA,
+                                 Function *F, DSGraph* G,
+                                 std::vector<OnePool> &ResultPools);
+
+      virtual void HackFunctionBody(Function &F, std::map<const DSNode*, Value*> &PDs);
+  };
+
+  //===-- NoNodes Heuristic -----------------------------------------------===//
+  //
+  // This dummy heuristic chooses to not pool allocate anything.
+  //
+  class NoNodesHeuristic : public Heuristic, public ImmutablePass {
+    public:
+      static char ID;
+      virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) {
+        if (PI->isPassID(&Heuristic::ID))
+          return (Heuristic*)this;
+        return this;
+      }
+
+      NoNodesHeuristic(intptr_t IDp = (intptr_t) (&ID)) : ImmutablePass (IDp) {}
+
+      virtual bool runOnModule (Module & M);
+      virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+        // This pass does not modify anything when it runs
+        AU.setPreservesAll();
+      }
+      virtual void AssignToPools(const DSNodeList_t &NodesToPA,
+                                 Function *F, DSGraph* G,
+                                 std::vector<OnePool> &ResultPools) { }
+  };
 }
 }
-
 #endif

Modified: poolalloc/trunk/lib/PoolAllocate/Heuristic.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/Heuristic.cpp?rev=114897&r1=114896&r2=114897&view=diff
==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/Heuristic.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/Heuristic.cpp Mon Sep 27 16:48:45 2010
@@ -206,14 +206,13 @@
   return 4;
 }
  
+//===-- AllNodes Heuristic ------------------------------------------------===//
 //
-// Method: runOnModule()
-//
-// Description:
-//  This is the entry point for this pass.
+// This heuristic pool allocates everything possible into separate pools.
 //
+
 bool
-Heuristic::runOnModule (Module & Module) {
+AllNodesHeuristic::runOnModule (Module & Module) {
   //
   // Remember which module we are analyzing.
   //
@@ -223,27 +222,13 @@
   return false;
 }
 
-//===-- AllNodes Heuristic ------------------------------------------------===//
-//
-// This heuristic pool allocates everything possible into separate pools.
-//
-class AllNodesHeuristic : public Heuristic {
-  public:
-  static char ID;
-  virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) {
-    if (PI->isPassID(&Heuristic::ID))
-      return (Heuristic*)this;
-    return this;
-  }
-
-  void AssignToPools(const std::vector<const DSNode*> &NodesToPA,
-                     Function *F, DSGraph* G,
-                     std::vector<OnePool> &ResultPools) {
+void
+AllNodesHeuristic::AssignToPools (const std::vector<const DSNode*> &NodesToPA,
+                                  Function *F, DSGraph* G,
+                                  std::vector<OnePool> &ResultPools) {
     for (unsigned i = 0, e = NodesToPA.size(); i != e; ++i)
       ResultPools.push_back(OnePool(NodesToPA[i]));
   }
-};
-
 
 //===-- AllButUnreachableFromMemoryHeuristic Heuristic --------------------===//
 //
@@ -252,80 +237,79 @@
 // that are not cyclic and are only pointed to by scalars: these tend to be
 // singular memory allocations that are not worth creating a whole pool for.
 //
-class AllButUnreachableFromMemoryHeuristic : public Heuristic {
-  public:
-  static char ID;
-  virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) {
-    if (PI->isPassID(&Heuristic::ID))
-      return (Heuristic*)this;
-    return this;
-  }
+bool
+AllButUnreachableFromMemoryHeuristic::runOnModule (Module & Module) {
+  //
+  // Remember which module we are analyzing.
+  //
+  M = &Module;
 
+  // We never modify anything in this pass
+  return false;
+}
 
-  void AssignToPools(const std::vector<const DSNode*> &NodesToPA,
-                     Function *F, DSGraph* G,
-                     std::vector<OnePool> &ResultPools) {
-    // Build a set of all nodes that are reachable from another node in the
-    // graph.  Here we ignore scalar nodes that are only globals as they are
-    // often global pointers to big arrays.
-    std::set<const DSNode*> ReachableFromMemory;
-    for (DSGraph::node_iterator I = G->node_begin(), E = G->node_end();
-         I != E; ++I) {
-      DSNode *N = I;
+void
+AllButUnreachableFromMemoryHeuristic::AssignToPools (
+                                          const DSNodeList_t &NodesToPA,
+                                          Function *F, DSGraph* G,
+                                          std::vector<OnePool> &ResultPools) {
+  // Build a set of all nodes that are reachable from another node in the
+  // graph.  Here we ignore scalar nodes that are only globals as they are
+  // often global pointers to big arrays.
+  std::set<const DSNode*> ReachableFromMemory;
+  for (DSGraph::node_iterator I = G->node_begin(), E = G->node_end();
+       I != E; ++I) {
+    DSNode *N = I;
 #if 0
-      //
-      // Ignore nodes that are just globals and not arrays.
-      //
-      if (N->isArray() || N->isHeapNode() || N->isAllocaNode() ||
-          N->isUnknownNode())
+    //
+    // Ignore nodes that are just globals and not arrays.
+    //
+    if (N->isArray() || N->isHeapNode() || N->isAllocaNode() ||
+        N->isUnknownNode())
 #endif
-      // If a node is marked, all children are too.
-      if (!ReachableFromMemory.count(N)) {
-        for (DSNode::iterator NI = N->begin(), E = N->end(); NI != E; ++NI) {
-          //
-          // Sometimes this results in a NULL DSNode.  Skip it if that is the
-          // case.
-          //
-          if (!(*NI)) continue;
-
-          //
-          // Do a depth-first iteration over the DSGraph starting with this
-          // child node.
-          //
-          for (df_ext_iterator<const DSNode*>
-                 DI = df_ext_begin(*NI, ReachableFromMemory),
-                 E = df_ext_end(*NI, ReachableFromMemory); DI != E; ++DI)
-          /*empty*/;
-        }
+    // If a node is marked, all children are too.
+    if (!ReachableFromMemory.count(N)) {
+      for (DSNode::iterator NI = N->begin(), E = N->end(); NI != E; ++NI) {
+        //
+        // Sometimes this results in a NULL DSNode.  Skip it if that is the
+        // case.
+        //
+        if (!(*NI)) continue;
+
+        //
+        // Do a depth-first iteration over the DSGraph starting with this
+        // child node.
+        //
+        for (df_ext_iterator<const DSNode*>
+               DI = df_ext_begin(*NI, ReachableFromMemory),
+               E = df_ext_end(*NI, ReachableFromMemory); DI != E; ++DI)
+        /*empty*/;
       }
     }
-
-    // Only pool allocate a node if it is reachable from a memory object (itself
-    // included).
-    for (unsigned i = 0, e = NodesToPA.size(); i != e; ++i)
-      if (ReachableFromMemory.count(NodesToPA[i]))
-        ResultPools.push_back(OnePool(NodesToPA[i]));
   }
-};
+
+  // Only pool allocate a node if it is reachable from a memory object (itself
+  // included).
+  for (unsigned i = 0, e = NodesToPA.size(); i != e; ++i)
+    if (ReachableFromMemory.count(NodesToPA[i]))
+      ResultPools.push_back(OnePool(NodesToPA[i]));
+}
 
 //===-- CyclicNodes Heuristic ---------------------------------------------===//
 //
 // This heuristic only pool allocates nodes in an SCC in the DSGraph.
 //
-class CyclicNodesHeuristic : public Heuristic {
-  public:
-  static char ID;
-  virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) {
-    if (PI->isPassID(&Heuristic::ID))
-      return (Heuristic*)this;
-    return this;
-  }
 
+bool
+CyclicNodesHeuristic::runOnModule (Module & Module) {
+  //
+  // Remember which module we are analyzing.
+  //
+  M = &Module;
 
-  void AssignToPools(const std::vector<const DSNode*> &NodesToPA,
-                     Function *F, DSGraph* G,
-                     std::vector<OnePool> &ResultPools);
-};
+  // We never modify anything in this pass
+  return false;
+}
 
 static bool NodeExistsInCycle(const DSNode *N) {
   for (DSNode::const_iterator I = N->begin(), E = N->end(); I != E; ++I)
@@ -334,48 +318,48 @@
   return false;
 }
 
-void CyclicNodesHeuristic::AssignToPools(const std::vector<const 
-                                                           DSNode*> &NodesToPA,
-                                         Function *F, DSGraph* G,
-                                         std::vector<OnePool> &ResultPools) {
+void
+CyclicNodesHeuristic::AssignToPools(const DSNodeList_t &NodesToPA,
+                                    Function *F, DSGraph* G,
+                                    std::vector<OnePool> &ResultPools) {
   for (unsigned i = 0, e = NodesToPA.size(); i != e; ++i)
     if (NodeExistsInCycle(NodesToPA[i]))
       ResultPools.push_back(OnePool(NodesToPA[i]));
 }
 
-
 //===-- SmartCoallesceNodes Heuristic -------------------------------------===//
 //
 // This heuristic attempts to be smart and coallesce nodes at times.  In
 // practice, it doesn't work very well.
 //
-class SmartCoallesceNodesHeuristic : public Heuristic {
-  public:
-  static char ID;
-  virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) {
-    if (PI->isPassID(&Heuristic::ID))
-      return (Heuristic*)this;
-    return this;
-  }
+bool
+SmartCoallesceNodesHeuristic::runOnModule (Module & Module) {
+  //
+  // Remember which module we are analyzing.
+  //
+  M = &Module;
 
+  // We never modify anything in this pass
+  return false;
+}
 
-  void AssignToPools(const std::vector<const DSNode*> &NodesToPA,
-                    Function *F, DSGraph* G,
-                    std::vector<OnePool> &ResultPools) {
-    // For globals, do not pool allocate unless the node is cyclic and not an
-    // array (unless it's collapsed).
-    if (F == 0) {
-      for (unsigned i = 0, e = NodesToPA.size(); i != e; ++i) {
-        const DSNode *Node = NodesToPA[i];
-        if ((Node->isNodeCompletelyFolded() || !Node->isArrayNode()) &&
-            NodeExistsInCycle(Node))
-          ResultPools.push_back(OnePool(Node));
-      }
-    } else {
-      // TODO
+void
+SmartCoallesceNodesHeuristic::AssignToPools(const DSNodeList_t &NodesToPA,
+                                            Function *F, DSGraph* G,
+                                            std::vector<OnePool> &ResultPools) {
+  // For globals, do not pool allocate unless the node is cyclic and not an
+  // array (unless it's collapsed).
+  if (F == 0) {
+    for (unsigned i = 0, e = NodesToPA.size(); i != e; ++i) {
+      const DSNode *Node = NodesToPA[i];
+      if ((Node->isNodeCompletelyFolded() || !Node->isArrayNode()) &&
+          NodeExistsInCycle(Node))
+        ResultPools.push_back(OnePool(Node));
     }
+  } else {
+    // TODO
   }
-};
+}
 
 #if 0
 /// NodeIsSelfRecursive - Return true if this node contains a pointer to itself.
@@ -534,37 +518,30 @@
 // pool.  This is not safe, and is not good for performance, but can be used to
 // evaluate how good the pool allocator runtime works as a "malloc replacement".
 //
-class AllInOneGlobalPoolHeuristic : public Heuristic {
-  public:
-  static char ID;
-  virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) {
-    if (PI->isPassID(&Heuristic::ID))
-      return (Heuristic*)this;
-    return this;
-  }
+bool
+AllInOneGlobalPoolHeuristic::runOnModule (Module & Module) {
+  //
+  // Remember which module we are analyzing.
+  //
+  M = &Module;
 
-  // TheGlobalPD - This global pool is the one and only one used when running
-  // with Heuristic=AllInOneGlobalPool.
-  GlobalVariable *TheGlobalPD;
-
-  AllInOneGlobalPoolHeuristic() : TheGlobalPD(0) {}
-
-
-  virtual bool IsRealHeuristic() { return false; }
-
-  void AssignToPools(const std::vector<const DSNode*> &NodesToPA,
-                    Function *F, DSGraph* G,
-                    std::vector<OnePool> &ResultPools) {
-    if (TheGlobalPD == 0)
-      TheGlobalPD = PA->CreateGlobalPool(0, 0);
-
-    // All nodes allocate from the same global pool.
-    OnePool Pool;
-    Pool.NodesInPool = NodesToPA;
-    Pool.PoolDesc = TheGlobalPD;
-    ResultPools.push_back(Pool);
-  }
-};
+  // We never modify anything in this pass
+  return false;
+}
+
+void
+AllInOneGlobalPoolHeuristic::AssignToPools(const DSNodeList_t &NodesToPA,
+                                           Function *F, DSGraph* G,
+                                           std::vector<OnePool> &ResultPools) {
+  if (TheGlobalPD == 0)
+    TheGlobalPD = PA->CreateGlobalPool(0, 0);
+
+  // All nodes allocate from the same global pool.
+  OnePool Pool;
+  Pool.NodesInPool = NodesToPA;
+  Pool.PoolDesc = TheGlobalPD;
+  ResultPools.push_back(Pool);
+}
 
 //===-- OnlyOverhead Heuristic --------------------------------------------===//
 //
@@ -573,32 +550,31 @@
 // the program, but dynamically only passes null into the pool alloc/free
 // functions, causing them to allocate from the heap.
 //
-class OnlyOverheadHeuristic : public Heuristic {
-  public:
-  static char ID;
-  virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) {
-    if (PI->isPassID(&Heuristic::ID))
-      return (Heuristic*)this;
-    return this;
-  }
-
-  virtual bool IsRealHeuristic() { return false; }
+bool
+OnlyOverheadHeuristic::runOnModule (Module & Module) {
+  //
+  // Remember which module we are analyzing.
+  //
+  M = &Module;
 
-  void AssignToPools(const std::vector<const DSNode*> &NodesToPA,
-                    Function *F, DSGraph* G,
-                    std::vector<OnePool> &ResultPools) {
-    // For this heuristic, we assign everything possible to its own pool.
-    for (unsigned i = 0, e = NodesToPA.size(); i != e; ++i)
-      ResultPools.push_back(OnePool(NodesToPA[i]));
-  }
+  // We never modify anything in this pass
+  return false;
+}
 
-  void HackFunctionBody(Function &F, std::map<const DSNode*, Value*> &PDs);
-};
+void
+OnlyOverheadHeuristic::AssignToPools(const DSNodeList_t &NodesToPA,
+                                     Function *F, DSGraph* G,
+                                     std::vector<OnePool> &ResultPools) {
+  // For this heuristic, we assign everything possible to its own pool.
+  for (unsigned i = 0, e = NodesToPA.size(); i != e; ++i)
+    ResultPools.push_back(OnePool(NodesToPA[i]));
+}
 
 /// getDynamicallyNullPool - Return a PoolDescriptor* that is always dynamically
 /// null.  Insert the code necessary to produce it before the specified
 /// instruction.
-static Value *getDynamicallyNullPool(BasicBlock::iterator I) {
+static Value *
+getDynamicallyNullPool(BasicBlock::iterator I) {
   // Arrange to dynamically pass null into all of the pool functions if we are
   // only checking for overhead.
   static Value *NullGlobal = 0;
@@ -620,9 +596,9 @@
 // HackFunctionBody - This method is called on every transformed function body.
 // Basically it replaces all uses of real pool descriptors with dynamically null
 // values.  However, it leaves pool init/destroy alone.
-void OnlyOverheadHeuristic::HackFunctionBody(Function &F,
-                                             std::map<const DSNode*,
-                                             Value*> &PDs) {
+void
+OnlyOverheadHeuristic::HackFunctionBody(Function &F,
+                                        std::map<const DSNode*, Value*> &PDs) {
   Constant *PoolInit = PA->PoolInit;
   Constant *PoolDestroy = PA->PoolDestroy;
 
@@ -648,23 +624,16 @@
 //
 // This dummy heuristic chooses to not pool allocate anything.
 //
-class NoNodesHeuristic : public Heuristic {
-  public:
-  static char ID;
-  virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) {
-    if (PI->isPassID(&Heuristic::ID))
-      return (Heuristic*)this;
-    return this;
-  }
-
-  virtual bool IsRealHeuristic() { return false; }
+bool
+NoNodesHeuristic::runOnModule (Module & Module) {
+  //
+  // Remember which module we are analyzing.
+  //
+  M = &Module;
 
-  void AssignToPools(const std::vector<const DSNode*> &NodesToPA,
-                    Function *F, DSGraph* G,
-                    std::vector<OnePool> &ResultPools) {
-    // Nothing to pool allocate here.
-  }
-};
+  // We never modify anything in this pass
+  return false;
+}
 
 //
 // Register all of the heuristic passes.
@@ -693,16 +662,16 @@
 //
 // Create the heuristic analysis group.
 //
-static RegisterAnalysisGroup<Heuristic>
-HeuristicGroup ("Pool Allocation Heuristic");
+//static RegisterAnalysisGroup<Heuristic>
+//HeuristicGroup ("Pool Allocation Heuristic");
 
 RegisterAnalysisGroup<Heuristic> Heuristic1(A);
-RegisterAnalysisGroup<Heuristic, true> Heuristic2(B);
+RegisterAnalysisGroup<Heuristic> Heuristic2(B);
 RegisterAnalysisGroup<Heuristic> Heuristic3(C);
 RegisterAnalysisGroup<Heuristic> Heuristic4(D);
 RegisterAnalysisGroup<Heuristic> Heuristic5(E);
 RegisterAnalysisGroup<Heuristic> Heuristic6(F);
-RegisterAnalysisGroup<Heuristic> Heuristic7(G);
+RegisterAnalysisGroup<Heuristic, true> Heuristic7(G);
 
 char Heuristic::ID = 0;
 char AllNodesHeuristic::ID = 0;

Modified: poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp?rev=114897&r1=114896&r2=114897&view=diff
==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp Mon Sep 27 16:48:45 2010
@@ -107,7 +107,7 @@
 
 void PoolAllocate::getAnalysisUsage(AnalysisUsage &AU) const {
   // We will need the heuristic pass to tell us what to do and how to do it
-  AU.addRequiredTransitive<Heuristic>();
+  AU.addRequired<Heuristic>();
   if (dsa_pass_to_use == PASS_EQTD) {
     AU.addRequiredTransitive<EQTDDataStructures>();
     if(lie_preserve_passes != LIE_NONE)

Modified: poolalloc/trunk/test/TEST.poolalloc.Makefile
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/test/TEST.poolalloc.Makefile?rev=114897&r1=114896&r2=114897&view=diff
==============================================================================
--- poolalloc/trunk/test/TEST.poolalloc.Makefile (original)
+++ poolalloc/trunk/test/TEST.poolalloc.Makefile Mon Sep 27 16:48:45 2010
@@ -62,7 +62,7 @@
 $(PROGRAMS_TO_TEST:%=Output/%.poolalloc.bc): \
 Output/%.poolalloc.bc: Output/%.base.bc $(PA_SO) $(LOPT)
 	- at rm -f $(CURDIR)/$@.info
-	-$(OPT_PA_STATS) -poolalloc $(EXTRA_PA_FLAGS) $(OPTZN_PASSES) -pooloptimize $< -o $@ -f 2>&1 > $@.out
+	-$(OPT_PA_STATS) -paheur-AllButUnreachableFromMemory -poolalloc $(EXTRA_PA_FLAGS) $(OPTZN_PASSES) -pooloptimize $< -o $@ -f 2>&1 > $@.out
 
 $(PROGRAMS_TO_TEST:%=Output/%.basepa.bc): \
 Output/%.basepa.bc: Output/%.base.bc $(PA_SO) $(LOPT)





More information about the llvm-commits mailing list