[llvm-commits] [poolalloc] r106145 - in /poolalloc/trunk/lib/PoolAllocate: PoolAllocate.cpp TransformFunctionBody.cpp

John Criswell criswell at uiuc.edu
Wed Jun 16 13:41:43 PDT 2010


Author: criswell
Date: Wed Jun 16 15:41:43 2010
New Revision: 106145

URL: http://llvm.org/viewvc/llvm-project?rev=106145&view=rev
Log:
Added comments and improved formatting.

Modified:
    poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp
    poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp

Modified: poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp?rev=106145&r1=106144&r2=106145&view=diff
==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp Wed Jun 16 15:41:43 2010
@@ -138,10 +138,14 @@
   // Map that maps an original function to its clone
   std::map<Function*, Function*> FuncMap;
 
+  //
   // Now clone a function using the pool arg list obtained in the previous
   // pass over the modules.  Loop over only the function initially in the
   // program, don't traverse newly added ones.  If the function needs new
   // arguments, make its clone.
+  //
+  // FIXME: Can the code below invalidate the function iterator?
+  //
   std::set<Function*> ClonedFunctions;
   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
     if (!I->isDeclaration() && !ClonedFunctions.count(I) &&
@@ -367,10 +371,38 @@
     G->getNodeForValue(*I).getNode()->markReachableNodes(NodesFromGlobals);
 }
 
-static void MarkNodesWhichMustBePassedIn(DenseSet<const DSNode*> &MarkedNodes,
-                                         Function &F, DSGraph* G,
-                                         bool PassAllArguments) {
+//
+// Function: MarkNodesWhichMustBePassedIn()
+//
+// Description:
+//  Given a function and its DSGraph, determine which values will need to have
+//  their pools passed in from the caller.
+//
+// Inputs:
+//  F                - A reference to the function to analyze.
+//  G                - The DSGraph of the function F.
+//  PassAllArguments - Flags whether all arguments should have their pool
+//                     handles passed into the function.
+//
+// Outputs:
+//  MarkedNodes      - A set of DSNodes whose associated pools should be
+//                     passed into the function when it is called.
+//
+static void
+MarkNodesWhichMustBePassedIn (DenseSet<const DSNode*> &MarkedNodes,
+                              Function &F, DSGraph* G,
+                              bool PassAllArguments) {
   // Mark globals and incomplete nodes as live... (this handles arguments)
+
+  //
+  // Scan through all of the function's arguments.  If they have an associated
+  // DSNode, then we need to pass the argument's pool handle into the function.
+  // We also need to pass in pools for any value that is reachable via a
+  // function argument.
+  //
+  // Of course, skip this is this function is the main() function.  We can't
+  // really add pools to main().  :)
+  //
   if (F.getName() != "main") {
     // All DSNodes reachable from arguments must be passed in.
     for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end();
@@ -382,20 +414,30 @@
     }
   }
 
-  // Marked the returned node as needing to be passed in.
+  //
+  // Mark the returned node as needing to be passed in.
+  //
   if (DSNode *RetNode = G->getReturnNodeFor(F).getNode())
     RetNode->markReachableNodes(MarkedNodes);
 
+  //
   // Calculate which DSNodes are reachable from globals.  If a node is reachable
   // from a global, we will create a global pool for it, so no argument passage
   // is required.
+  //
   DenseSet<const DSNode*> NodesFromGlobals;
   GetNodesReachableFromGlobals(G, NodesFromGlobals);
 
+  //
   // Remove any nodes reachable from a global.  These nodes will be put into
   // global pools, which do not require arguments to be passed in.  Also, erase
   // any marked node that is not a heap node.  Since no allocations or frees
   // will be done with it, it needs no argument.
+  //
+  // FIXME:
+  //  1) PassAllArguments seems to be ignored here.  Why is that?
+  //  2) Why is the heap node check part of the PassAllArguments check?
+  //
   for (DenseSet<const DSNode*>::iterator I = MarkedNodes.begin(),
          E = MarkedNodes.end(); I != E; ) {
     const DSNode *N = *I; ++I;
@@ -449,13 +491,14 @@
   if (MaxArgsAdded < FI.ArgNodes.size()) MaxArgsAdded = FI.ArgNodes.size();
   ++NumCloned;
  
-      
-  // Figure out what the arguments are to be for the new version of the
-  // function
-  const FunctionType *OldFuncTy = F.getFunctionType();
+  //
+  // Determine the type of the new function.  We will insert new parameters
+  // for the pools to pass into the function, and then we will insert the
+  // original parameter values after that.
+  //
   std::vector<const Type*> ArgTys(FI.ArgNodes.size(), PoolDescPtrTy);
+  const FunctionType *OldFuncTy = F.getFunctionType();
   ArgTys.reserve(OldFuncTy->getNumParams() + FI.ArgNodes.size());
-
   ArgTys.insert(ArgTys.end(), OldFuncTy->param_begin(), OldFuncTy->param_end());
 
   // Create the new function prototype
@@ -471,7 +514,6 @@
   // pool descriptors map
   std::map<const DSNode*, Value*> &PoolDescriptors = FI.PoolDescriptors;
   Function::arg_iterator NI = New->arg_begin();
-  
   for (unsigned i = 0, e = FI.ArgNodes.size(); i != e; ++i, ++NI) {
     NI->setName("PDa");
     PoolDescriptors[FI.ArgNodes[i]] = NI;
@@ -500,6 +542,10 @@
   // verbatim.  This is incorrect; each attribute should be shifted one so
   // that the pool descriptor has no attributes.
   //
+  // FIXME: I believe the code below assumes that we've only added one pool
+  //        handle.  We actually add one pool handle per incoming argument
+  //        that needs a pool handle.
+  //
   const AttrListPtr OldAttrs = New->getAttributes();
   if (!OldAttrs.isEmpty()) {
     AttrListPtr NewAttrsVector;
@@ -519,9 +565,10 @@
     New->setAttributes (NewAttrsVector);
   }
 
-  // Invert the ValueMap into the NewToOldValueMap
+  //
+  // Invert the ValueMap into the NewToOldValueMap.
+  //
   std::map<Value*, const Value*> &NewToOldValueMap = FI.NewToOldValueMap;
-
   for (DenseMap<const Value*, Value*>::iterator I = ValueMap.begin(),
          E = ValueMap.end(); I != E; ++I)
     NewToOldValueMap.insert(std::make_pair(I->second, I->first));
@@ -661,10 +708,16 @@
 // the DSNodes specified by the NodesToPA list.  This adds an entry to the
 // PoolDescriptors map for each DSNode.
 //
-void PoolAllocate::CreatePools(Function &F, DSGraph* DSG,
-                               const std::vector<const DSNode*> &NodesToPA,
-                               std::map<const DSNode*,
-                                        Value*> &PoolDescriptors) {
+// Note that this method does not insert calls to poolinit() or pooldestroy().
+// Those are added later.
+//
+void
+PoolAllocate::CreatePools (Function &F, DSGraph* DSG,
+                           const std::vector<const DSNode*> &NodesToPA,
+                           std::map<const DSNode*, Value*> &PoolDescriptors) {
+  //
+  // If there are no pools to create, then do nothing.
+  //
   if (NodesToPA.empty()) return;
 
   std::vector<Heuristic::OnePool> ResultPools;
@@ -679,13 +732,18 @@
   // vars.
   bool IsMain = F.getNameStr() == "main" && F.hasExternalLinkage();
 
-  // Perform all global assignments as specified.
+  //
+  // Create each pool and update the DSGraph to account for the new pool.
+  // Additionally, update the mapping between DSNodes and pools.
+  //
   for (unsigned i = 0, e = ResultPools.size(); i != e; ++i) {
     Heuristic::OnePool &Pool = ResultPools[i];
     Value *PoolDesc = Pool.PoolDesc;
     if (PoolDesc == 0) {
+      //
       // Create a pool descriptor for the pool.  The poolinit will be inserted
       // later.
+      //
       if (!IsMain) {
         PoolDesc = new AllocaInst(PoolDescType, 0, "PD", InsertPoint);
 
@@ -705,13 +763,22 @@
           ++NumTSPools;
       }
     }
+
+    //
+    // Update the mapping of DSNodes to pool descriptors.
+    //
+    // FIXME:
+    //  What are unallocated DSNodes?
+    //
     for (unsigned N = 0, e = Pool.NodesInPool.size(); N != e; ++N) {
       PoolDescriptors[Pool.NodesInPool[N]] = PoolDesc;
       UnallocatedNodes.erase(Pool.NodesInPool[N]);  // Handled!
     }
   }
 
+  //
   // Any unallocated DSNodes get null pool descriptor pointers.
+  //
   for (std::set<const DSNode*>::iterator I = UnallocatedNodes.begin(),
          E = UnallocatedNodes.end(); I != E; ++I) {
     PoolDescriptors[*I] = ConstantPointerNull::get(PointerType::getUnqual(PoolDescType));
@@ -740,10 +807,20 @@
   DSGraph::NodeMapTy GlobalsGraphNodeMapping;
   G->computeGToGGMapping(GlobalsGraphNodeMapping);
 
+  //
   // Loop over all of the nodes which are non-escaping, adding pool-allocatable
-  // ones to the NodesToPA vector.
-  for (DSGraph::node_iterator I = G->node_begin(), E = G->node_end(); I != E;++I){
-    // We only need to make a pool if there is a heap object in it...
+  // ones to the NodesToPA vector.  In other words, scan over the DSGraph and
+  // find nodes for which a new pool must be created within this function.
+  //
+  for (DSGraph::node_iterator I = G->node_begin(), E = G->node_end();
+       I != E;
+       ++I){
+    //
+    // Only the following nodes are pool allocated:
+    //  1) Heap nodes
+    //  2) Array nodes when bounds checking is enabled.
+    //  3) Nodes which are mirrored in the globals graph and are heap nodes.
+    //
     DSNode *N = I;
     if ((N->isHeapNode()) || (BoundsChecksEnabled && (N->isArrayNode())) ||
     	(GlobalsGraphNodeMapping.count(N) && GlobalsGraphNodeMapping[N].getNode()->isHeapNode())) {
@@ -761,6 +838,9 @@
     }
   }
 
+  //
+  // Add code to create the pools that are local to this function.
+  //
   if (!FI.NodesToPA.empty()) {
     errs() << "[" << F.getNameStr() << "] " << FI.NodesToPA.size()
               << " nodes pool allocatable\n";
@@ -1040,6 +1120,9 @@
     assert(isa<AllocaInst>(PoolDescriptors[Node]) && "Why pool allocate this?");
     AllocaInst *PD = cast<AllocaInst>(PoolDescriptors[Node]);
     
+    //
+    // FIXME: What is the purpose of the PoolUses and AllocasHandled code
+    //        below?
     // FIXME: Turn this into an assert and fix the problem!!
     //assert(PoolUses.count(PD) && "Pool is not used, but is marked heap?!");
     if (!PoolUses.count(PD) && !PoolFrees.count(PD)) continue;

Modified: poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp?rev=106145&r1=106144&r2=106145&view=diff
==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp Wed Jun 16 15:41:43 2010
@@ -50,7 +50,8 @@
     // PoolUses - For each pool (identified by the pool descriptor) keep track
     // of which blocks require the memory in the pool to not be freed.  This
     // does not include poolfree's.  Note that this is only tracked for pools
-    // which this is the home of, ie, they are Alloca instructions.
+    // for which the given function is the pool's home i.e., the pool is an
+    // alloca instruction because it is allocated within the current function.
     std::multimap<AllocaInst*, Instruction*> &PoolUses;
 
     // PoolDestroys - For each pool, keep track of the actual poolfree calls
@@ -96,6 +97,14 @@
     Instruction *TransformAllocationInstr(Instruction *I, Value *Size);
     Instruction *InsertPoolFreeInstr(Value *V, Instruction *Where);
 
+    //
+    // Method: UpdateNewToOldValueMap()
+    //
+    // Description:
+    //  This method removes the old mapping indexed by OldVal and inserts one
+    //  or two new mappings mapping NewV1 and NewV2 to the value that was
+    //  indexed by OldVal.
+    //
     void UpdateNewToOldValueMap(Value *OldVal, Value *NewV1, Value *NewV2 = 0) {
       std::map<Value*, const Value*>::iterator I =
         FI.NewToOldValueMap.find(OldVal);
@@ -132,10 +141,11 @@
   };
 }
 
-void PoolAllocate::TransformBody(DSGraph* g, PA::FuncInfo &fi,
-                              std::multimap<AllocaInst*,Instruction*> &poolUses,
-                              std::multimap<AllocaInst*, CallInst*> &poolFrees,
-                                 Function &F) {
+void
+PoolAllocate::TransformBody (DSGraph* g, PA::FuncInfo &fi,
+                             std::multimap<AllocaInst*,Instruction*> &poolUses,
+                             std::multimap<AllocaInst*, CallInst*> &poolFrees,
+                             Function &F) {
   FuncTransform(*this, g, fi, poolUses, poolFrees).visit(F);
 }
 





More information about the llvm-commits mailing list