[llvm-commits] CVS: poolalloc/lib/PoolAllocate/PoolAllocate.cpp TransformFunctionBody.cpp

Chris Lattner lattner at cs.uiuc.edu
Sun Feb 29 15:24:01 PST 2004


Changes in directory poolalloc/lib/PoolAllocate:

PoolAllocate.cpp updated: 1.61 -> 1.62
TransformFunctionBody.cpp updated: 1.21 -> 1.22

---
Log message:

Instead of pool allocating EVERY heap node, provide hooks to implement
heuristics for choosing which pools to allocate.  We initially support
three heuristics:

1. All nodes  (what we had before)
2. No nodes   (aka no pool allocation)
3. Cyclic nodes (those which there is a path in the dsgraph from the node to itself).



---
Diffs of the changes:  (+50 -9)

Index: poolalloc/lib/PoolAllocate/PoolAllocate.cpp
diff -u poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.61 poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.62
--- poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.61	Fri Feb 27 13:59:53 2004
+++ poolalloc/lib/PoolAllocate/PoolAllocate.cpp	Sun Feb 29 15:23:34 2004
@@ -13,6 +13,7 @@
 #include "llvm/Module.h"
 #include "llvm/Analysis/DataStructure.h"
 #include "llvm/Analysis/DSGraph.h"
+#include "llvm/Analysis/DSGraphTraits.h"
 #include "llvm/Support/CFG.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
@@ -32,6 +33,9 @@
 const Type *PoolAllocate::PoolDescPtrTy = 0;
 
 namespace {
+  RegisterOpt<PoolAllocate>
+  X("poolalloc", "Pool allocate disjoint data structures");
+
   Statistic<> NumArgsAdded("poolalloc", "Number of function arguments added");
   Statistic<> NumCloned   ("poolalloc", "Number of functions cloned");
   Statistic<> NumPools    ("poolalloc", "Number of pools allocated");
@@ -46,12 +50,24 @@
   // unsigned FreeablePool (are slabs in the pool freeable upon calls to 
   //                        poolfree?)
   const Type *PoolDescType;
-  
-  RegisterOpt<PoolAllocate>
-  X("poolalloc", "Pool allocate disjoint data structures");
 
-  cl::opt<bool> DisableInitDestroyOpt("poolalloc-force-simple-pool-init",
-                                      cl::desc("Always insert poolinit/pooldestroy calls at start and exit of functions"), cl::init(true));
+  enum PoolAllocHeuristic {
+    AllPools,
+    CyclicPools,
+    NoPools
+  };
+  cl::opt<PoolAllocHeuristic>
+  Heuristic("poolalloc-heuristic",
+            cl::desc("Heuristic to choose which nodes to pool allocate"),
+            cl::values(clEnumVal(AllPools, "  Pool allocate all nodes"),
+                       clEnumVal(CyclicPools, "  Pool allocate nodes with cycles"),
+                       clEnumVal(NoPools, "  Do not pool allocate anything"),
+                       0),
+            cl::init(AllPools));
+  
+  cl::opt<bool>
+  DisableInitDestroyOpt("poolalloc-force-simple-pool-init",
+                        cl::desc("Always insert poolinit/pooldestroy calls at start and exit of functions"), cl::init(true));
 }
 
 void PoolAllocate::getAnalysisUsage(AnalysisUsage &AU) const {
@@ -207,7 +223,6 @@
 // unify the N functions together in the FuncECs set.
 //
 void PoolAllocate::BuildIndirectFunctionSets(Module &M) {
-
   const CompleteBUDataStructures::ActualCalleesTy AC = BU->getActualCallees();
 
   // Loop over all of the indirect calls in the program.  If a call site can
@@ -543,7 +558,22 @@
   }
 }
 
-
+/// ProfitableToPoolAllocate - Return true if we think it's useful to ACTUALLY
+/// pool allocate the specified DSNode.  If this returns false, the memory for
+/// the node will be managed by malloc/free.
+static bool ProfitableToPoolAllocate(DSNode *N) {
+  switch (Heuristic) {
+  default:
+  case AllPools: return true;
+  case NoPools: return false;
+  case CyclicPools:
+    // Look for a path back to this node.
+    for (DSNode::iterator I = N->begin(), E = N->end(); I != E; ++I)
+      if (*I && std::find(df_begin(*I), df_end(*I), N) != df_end(*I))
+        return true;
+    return false;  // No cycle found!
+  }
+}
 
 // processFunction - Pool allocate any data structures which are contained in
 // the specified function...
@@ -585,6 +615,17 @@
         // be a local pool!
         NodesToPA.push_back(*I);
       }
+
+  // Now that we have a list of all of the nodes that CAN be pool allocated, use
+  // a heuristic to filter out nodes which are not profitable to pool allocate.
+  for (unsigned i = 0; i != NodesToPA.size(); ++i)
+    if (!ProfitableToPoolAllocate(NodesToPA[i])) {
+      FI.PoolDescriptors[NodesToPA[i]] =
+        Constant::getNullValue(PointerType::get(PoolDescType));
+      std::swap(NodesToPA[i], NodesToPA.back());
+      NodesToPA.pop_back();
+      --i;
+    }
   
   std::cerr << "[" << F.getName() << "] Pool Allocating "
             << NodesToPA.size() << " nodes\n";


Index: poolalloc/lib/PoolAllocate/TransformFunctionBody.cpp
diff -u poolalloc/lib/PoolAllocate/TransformFunctionBody.cpp:1.21 poolalloc/lib/PoolAllocate/TransformFunctionBody.cpp:1.22
--- poolalloc/lib/PoolAllocate/TransformFunctionBody.cpp:1.21	Fri Feb 27 14:00:19 2004
+++ poolalloc/lib/PoolAllocate/TransformFunctionBody.cpp	Sun Feb 29 15:23:34 2004
@@ -171,7 +171,7 @@
 void FuncTransform::visitMallocInst(MallocInst &MI) {
   // Get the pool handle for the node that this contributes to...
   Value *PH = getPoolHandle(&MI);
-  if (PH == 0) return;
+  if (PH == 0 || isa<ConstantPointerNull>(PH)) return;
 
   TargetData &TD = PAInfo.getAnalysis<TargetData>();
   Value *AllocSize =
@@ -187,7 +187,7 @@
 
 Instruction *FuncTransform::InsertPoolFreeInstr(Value *Arg, Instruction *Where){
   Value *PH = getPoolHandle(Arg);  // Get the pool handle for this DSNode...
-  if (PH == 0) return 0;
+  if (PH == 0 || isa<ConstantPointerNull>(PH)) return 0;
 
   // Insert a cast and a call to poolfree...
   Value *Casted = Arg;





More information about the llvm-commits mailing list