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

John Criswell criswell at uiuc.edu
Fri Sep 24 08:15:21 PDT 2010


Author: criswell
Date: Fri Sep 24 10:15:21 2010
New Revision: 114729

URL: http://llvm.org/viewvc/llvm-project?rev=114729&view=rev
Log:
Refactored the code to make the Heuristic classes an LLVM analysis group.  
This will eventually allow clients (such as SAFECode) to more easily tailor
Automatic Pool Allocation's behavior.

Modified:
    poolalloc/trunk/include/poolalloc/Heuristic.h
    poolalloc/trunk/include/poolalloc/PoolAllocate.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=114729&r1=114728&r2=114729&view=diff
==============================================================================
--- poolalloc/trunk/include/poolalloc/Heuristic.h (original)
+++ poolalloc/trunk/include/poolalloc/Heuristic.h Fri Sep 24 10:15:21 2010
@@ -12,8 +12,13 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef POOLALLOCATION_HEURISTIC_H
-#define POOLALLOCATION_HEURISTIC_H
+#ifndef POOLALLOC_HEURISTIC_H
+#define POOLALLOC_HEURISTIC_H
+
+#include "dsa/DataStructure.h"
+#include "dsa/DSGraph.h"
+
+#include "llvm/Pass.h"
 
 #include <vector>
 #include <map>
@@ -29,18 +34,34 @@
   class Type;
 
 namespace PA {
-  class Heuristic {
+  class Heuristic : public ImmutablePass {
   protected:
     Module *M;
-    DSGraph *GG;
     PoolAllocate *PA;
 
-    Heuristic() {}
   public:
-    void Initialize(Module &m, DSGraph* gg, PoolAllocate &pa) {
-      M = &m; GG = gg; PA = &pa;
+    //
+    // 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();
+    }
+
+    //
+    // Other methods.
+    //
+    void Initialize (PoolAllocate &pa) {
+      PA = &pa;
     }
-    virtual ~Heuristic();
 
     /// IsRealHeuristic - Return true if this is not a real pool allocation
     /// heuristic.
@@ -96,10 +117,6 @@
     static unsigned getRecommendedAlignment(const DSNode *N);
     static unsigned getRecommendedAlignment(const Type *Ty,
                                             const TargetData &TD);
-    
-    /// create - This static ctor creates the heuristic, based on the command
-    /// line argument to choose the heuristic.
-    static Heuristic *create();
   };
 }
 }

Modified: poolalloc/trunk/include/poolalloc/PoolAllocate.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/poolalloc/PoolAllocate.h?rev=114729&r1=114728&r2=114729&view=diff
==============================================================================
--- poolalloc/trunk/include/poolalloc/PoolAllocate.h (original)
+++ poolalloc/trunk/include/poolalloc/PoolAllocate.h Fri Sep 24 10:15:21 2010
@@ -32,6 +32,7 @@
 #include "dsa/DataStructure.h"
 #include "dsa/DSGraph.h"
 #include "poolalloc/Config/config.h"
+#include "poolalloc/Heuristic.h"
 
 #include <utility>
 
@@ -46,8 +47,6 @@
 
   extern cl::opt<bool>  PA_SAFECODE;
 
-  class Heuristic;
-
   /// FuncInfo - Represent the pool allocation information for one function in
   /// the program.  Note that many functions must actually be cloned in order
   /// for pool allocation to add arguments to the function signature.  In this

Modified: poolalloc/trunk/lib/PoolAllocate/Heuristic.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/Heuristic.cpp?rev=114729&r1=114728&r2=114729&view=diff
==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/Heuristic.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/Heuristic.cpp Fri Sep 24 10:15:21 2010
@@ -26,39 +26,16 @@
 #include "llvm/Support/FormattedStream.h"
 #include "llvm/Target/TargetData.h"
 #include <iostream>
+
 using namespace llvm;
 using namespace PA;
 
 namespace {
-  enum PoolAllocHeuristic {
-    NoNodes,
-    OnlyOverhead,
-    AllInOneGlobalPool,
-    SmartCoallesceNodes,
-    CyclicNodes,
-    AllButUnreachableFromMemory,
-    AllNodes
-  };
-  cl::opt<PoolAllocHeuristic>
-  TheHeuristic("poolalloc-heuristic",
-    cl::desc("Heuristic to choose which nodes to pool allocate"),
-    cl::values(clEnumVal(AllNodes, "  Pool allocate all nodes"),
-               clEnumVal(AllButUnreachableFromMemory, "  Pool allocate all reachable from memory objects"),
-               clEnumVal(CyclicNodes, "  Pool allocate nodes with cycles"),
-               clEnumVal(SmartCoallesceNodes, "  Use the smart node merging heuristic"),
-               clEnumVal(AllInOneGlobalPool, "  Use pool library as replacement for malloc/free"),
-               clEnumVal(OnlyOverhead, "  Do not pool allocate anything, but induce all overhead from it"),
-               clEnumVal(NoNodes, "  Do not pool allocate anything"),
-               clEnumValEnd),
-    cl::init(AllButUnreachableFromMemory)); 
-
   cl::opt<bool>
   DisableAlignOpt("poolalloc-disable-alignopt",
                   cl::desc("Force all pool alignment to 8 bytes"));
 }
 
-Heuristic::~Heuristic() {}
-
 //
 // Function: getRecommendedSize()
 //
@@ -229,12 +206,35 @@
   return 4;
 }
  
+//
+// Method: runOnModule()
+//
+// Description:
+//  This is the entry point for this pass.
+//
+bool
+Heuristic::runOnModule (Module & Module) {
+  //
+  // Remember which module we are analyzing.
+  //
+  M = &Module;
+
+  // We never modify anything in this pass
+  return false;
+}
 
 //===-- AllNodes Heuristic ------------------------------------------------===//
 //
 // This heuristic pool allocates everything possible into separate pools.
 //
-struct AllNodesHeuristic : public Heuristic {
+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,
@@ -252,7 +252,15 @@
 // 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.
 //
-struct AllButUnreachableFromMemoryHeuristic : public Heuristic {
+class AllButUnreachableFromMemoryHeuristic : 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,
@@ -304,7 +312,15 @@
 //
 // This heuristic only pool allocates nodes in an SCC in the DSGraph.
 //
-struct CyclicNodesHeuristic : public Heuristic {
+class CyclicNodesHeuristic : 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,
@@ -333,7 +349,15 @@
 // This heuristic attempts to be smart and coallesce nodes at times.  In
 // practice, it doesn't work very well.
 //
-struct SmartCoallesceNodesHeuristic : public Heuristic {
+class SmartCoallesceNodesHeuristic : 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,
@@ -510,7 +534,15 @@
 // 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".
 //
-struct AllInOneGlobalPoolHeuristic : public Heuristic {
+class AllInOneGlobalPoolHeuristic : public Heuristic {
+  public:
+  static char ID;
+  virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) {
+    if (PI->isPassID(&Heuristic::ID))
+      return (Heuristic*)this;
+    return this;
+  }
+
   // TheGlobalPD - This global pool is the one and only one used when running
   // with Heuristic=AllInOneGlobalPool.
   GlobalVariable *TheGlobalPD;
@@ -541,7 +573,15 @@
 // the program, but dynamically only passes null into the pool alloc/free
 // functions, causing them to allocate from the heap.
 //
-struct OnlyOverheadHeuristic : public Heuristic {
+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; }
 
   void AssignToPools(const std::vector<const DSNode*> &NodesToPA,
@@ -608,7 +648,15 @@
 //
 // This dummy heuristic chooses to not pool allocate anything.
 //
-struct NoNodesHeuristic : public Heuristic {
+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; }
 
   void AssignToPools(const std::vector<const DSNode*> &NodesToPA,
@@ -618,20 +666,51 @@
   }
 };
 
-//===----------------------------------------------------------------------===//
-// Heuristic dispatch support
 //
+// Register all of the heuristic passes.
+//
+static RegisterPass<AllNodesHeuristic>
+A ("paheur-AllNodes", "Pool allocate all nodes");
+
+static RegisterPass<AllButUnreachableFromMemoryHeuristic>
+B ("paheur-AllButUnreachableFromMemory", "Pool allocate all reachable from memory objects");
+
+static RegisterPass<CyclicNodesHeuristic>
+C ("paheur-CyclicNodes", "Pool allocate nodes with cycles");
+
+static RegisterPass<SmartCoallesceNodesHeuristic>
+D ("paheur-SmartCoallesceNodes", "Pool allocate using the smart node merging heuristic ");
+
+static RegisterPass<AllInOneGlobalPoolHeuristic>
+E ("paheur-AllInOneGlobalPool", "Pool allocate using the pool library to replace malloc/free");
+
+static RegisterPass<OnlyOverheadHeuristic>
+F ("paheur-OnlyOverhead", "Do not pool allocate anything, but induce all overhead from it");
+
+static RegisterPass<NoNodesHeuristic>
+G ("paheur-NoNodes", "Pool allocate nothing");
+
+//
+// Create the heuristic analysis group.
+//
+static RegisterAnalysisGroup<Heuristic>
+HeuristicGroup ("Pool Allocation Heuristic");
+
+RegisterAnalysisGroup<Heuristic> Heuristic1(A);
+RegisterAnalysisGroup<Heuristic, true> Heuristic2(B);
+RegisterAnalysisGroup<Heuristic> Heuristic3(C);
+RegisterAnalysisGroup<Heuristic> Heuristic4(D);
+RegisterAnalysisGroup<Heuristic> Heuristic5(E);
+RegisterAnalysisGroup<Heuristic> Heuristic6(F);
+RegisterAnalysisGroup<Heuristic> Heuristic7(G);
+
+char Heuristic::ID = 0;
+char AllNodesHeuristic::ID = 0;
+char AllButUnreachableFromMemoryHeuristic::ID = 0;
+char CyclicNodesHeuristic::ID = 0;
+char SmartCoallesceNodesHeuristic::ID = 0;
+char AllInOneGlobalPoolHeuristic::ID = 0;
+char OnlyOverheadHeuristic::ID = 0;
+char NoNodesHeuristic::ID = 0;
+
 
-PA::Heuristic *Heuristic::create() {
-  switch (TheHeuristic) {
-  default: assert(0 && "Unknown heuristic!");
-  case AllNodes: return new AllNodesHeuristic();
-  case AllButUnreachableFromMemory:
-    return new AllButUnreachableFromMemoryHeuristic();
-  case CyclicNodes: return new CyclicNodesHeuristic();
-  case SmartCoallesceNodes: return new SmartCoallesceNodesHeuristic();
-  case AllInOneGlobalPool: return new AllInOneGlobalPoolHeuristic();
-  case OnlyOverhead: return new OnlyOverheadHeuristic();
-  case NoNodes: return new NoNodesHeuristic();
-  }
-}

Modified: poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp?rev=114729&r1=114728&r2=114729&view=diff
==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp Fri Sep 24 10:15:21 2010
@@ -106,6 +106,8 @@
 }
 
 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>();
   if (dsa_pass_to_use == PASS_EQTD) {
     AU.addRequiredTransitive<EQTDDataStructures>();
     if(lie_preserve_passes != LIE_NONE)
@@ -146,8 +148,11 @@
   else
     Graphs = &getAnalysis<EquivBUDataStructures>();
 
-  CurHeuristic = Heuristic::create();
-  CurHeuristic->Initialize(M, Graphs->getGlobalsGraph(), *this);
+  //
+  // Get the heuristic pass and then tell it who we are.
+  //
+  CurHeuristic = &getAnalysis<Heuristic>();
+  CurHeuristic->Initialize (*this);
 
   // Add the pool* prototypes to the module
   AddPoolPrototypes(&M);
@@ -325,7 +330,6 @@
     MicroOptimizePoolCalls();
   #endif
  
-  delete CurHeuristic;
   return true;
 }
 

Modified: poolalloc/trunk/test/TEST.poolalloc.Makefile
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/test/TEST.poolalloc.Makefile?rev=114729&r1=114728&r2=114729&view=diff
==============================================================================
--- poolalloc/trunk/test/TEST.poolalloc.Makefile (original)
+++ poolalloc/trunk/test/TEST.poolalloc.Makefile Fri Sep 24 10:15:21 2010
@@ -67,18 +67,18 @@
 $(PROGRAMS_TO_TEST:%=Output/%.basepa.bc): \
 Output/%.basepa.bc: Output/%.base.bc $(PA_SO) $(LOPT)
 	- at rm -f $(CURDIR)/$@.info
-	-$(OPT_PA_STATS) -poolalloc -poolalloc-disable-alignopt -poolalloc-force-all-poolfrees -poolalloc-heuristic=AllNodes $(OPTZN_PASSES) $< -o $@ -f 2>&1 > $@.out
+	-$(OPT_PA_STATS) -paheur-AllNodes -poolalloc -poolalloc-disable-alignopt -poolalloc-force-all-poolfrees $(OPTZN_PASSES) $< -o $@ -f 2>&1 > $@.out
 
 
 $(PROGRAMS_TO_TEST:%=Output/%.mallocrepl.bc): \
 Output/%.mallocrepl.bc: Output/%.base.bc $(PA_SO) $(LOPT)
 	- at rm -f $(CURDIR)/$@.info
-	-$(OPT_PA_STATS) -poolalloc -poolalloc-heuristic=AllInOneGlobalPool $(OPTZN_PASSES) $< -o $@ -f 2>&1 > $@.out
+	-$(OPT_PA_STATS) -paheur-AllInOneGlobalPool -poolalloc $(OPTZN_PASSES) $< -o $@ -f 2>&1 > $@.out
 
 $(PROGRAMS_TO_TEST:%=Output/%.onlyoverhead.bc): \
 Output/%.onlyoverhead.bc: Output/%.base.bc $(PA_SO) $(LOPT)
 	- at rm -f $(CURDIR)/$@.info
-	-$(OPT_PA_STATS) -poolalloc -poolalloc-heuristic=OnlyOverhead $(OPTZN_PASSES) $< -o $@ -f 2>&1 > $@.out
+	-$(OPT_PA_STATS) -paheur-OnlyOverhead -poolalloc $(OPTZN_PASSES) $< -o $@ -f 2>&1 > $@.out
 
 $(PROGRAMS_TO_TEST:%=Output/%.nonpa.bc): \
 Output/%.nonpa.bc: Output/%.base.bc $(LOPT)





More information about the llvm-commits mailing list