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

Chris Lattner lattner at cs.uiuc.edu
Fri Mar 4 12:19:18 PST 2005



Changes in directory llvm-poolalloc/lib/PoolAllocate:

PointerCompress.cpp updated: 1.41 -> 1.42
---
Log message:

Move some code around, first attempt to handle compressing pools pointed to by globals.


---
Diffs of the changes:  (+159 -79)

 PointerCompress.cpp |  238 ++++++++++++++++++++++++++++++++++------------------
 1 files changed, 159 insertions(+), 79 deletions(-)


Index: llvm-poolalloc/lib/PoolAllocate/PointerCompress.cpp
diff -u llvm-poolalloc/lib/PoolAllocate/PointerCompress.cpp:1.41 llvm-poolalloc/lib/PoolAllocate/PointerCompress.cpp:1.42
--- llvm-poolalloc/lib/PoolAllocate/PointerCompress.cpp:1.41	Fri Mar  4 10:45:34 2005
+++ llvm-poolalloc/lib/PoolAllocate/PointerCompress.cpp	Fri Mar  4 14:19:05 2005
@@ -102,12 +102,20 @@
     /// a clone came from.
     std::map<Function*, FunctionCloneRecord> ClonedFunctionInfoMap;
     
+    /// CompressedGlobalPools - Keep track of which DSNodes in the globals graph
+    /// are both pool allocated and should be compressed, and which GlobalValue
+    /// their pool descriptor is.
+    std::map<const DSNode*, GlobalValue*> CompressedGlobalPools;
+
   public:
     Function *PoolInitPC, *PoolDestroyPC, *PoolAllocPC;
     typedef std::map<const DSNode*, CompressedPoolInfo> PoolInfoMap;
 
     bool runOnModule(Module &M);
 
+    void HandleGlobalPools(Module &M);
+
+
     void getAnalysisUsage(AnalysisUsage &AU) const;
 
     PoolAllocate *getPoolAlloc() const { return PoolAlloc; }
@@ -276,83 +284,9 @@
 
 
 //===----------------------------------------------------------------------===//
-//                    PointerCompress Implementation
+//                    InstructionRewriter Implementation
 //===----------------------------------------------------------------------===//
 
-void PointerCompress::getAnalysisUsage(AnalysisUsage &AU) const {
-  // Need information about how pool allocation happened.
-  AU.addRequired<PoolAllocatePassAllPools>();
-
-  // Need information from DSA.
-  AU.addRequired<PA::EquivClassGraphs>();
-}
-
-/// PoolIsCompressible - Return true if we can pointer compress this node.
-/// If not, we should DEBUG print out why.
-static bool PoolIsCompressible(const DSNode *N, Function &F) {
-  assert(!N->isForwarding() && "Should not be dealing with merged nodes!");
-  if (N->isNodeCompletelyFolded()) {
-    DEBUG(std::cerr << "Node is not type-safe:\n");
-    return false;
-  }
-
-  // FIXME: If any non-type-safe nodes point to this one, we cannot compress it.
-#if 0
-  bool HasFields = false;
-  for (DSNode::const_edge_iterator I = N->edge_begin(), E = N->edge_end();
-       I != E; ++I)
-    if (!I->isNull()) {
-      HasFields = true;
-      if (I->getNode() != N) {
-        // We currently only handle trivially self cyclic DS's right now.
-        DEBUG(std::cerr << "Node points to nodes other than itself:\n");
-        return false;
-      }        
-    }
-
-  if (!HasFields) {
-    DEBUG(std::cerr << "Node does not contain any pointers to compress:\n");
-    return false;
-  }
-#endif
-
-  if (N->isArray()) {
-    DEBUG(std::cerr << "Node is an array (not yet handled!):\n");
-    return false;
-  }
-
-  if ((N->getNodeFlags() & DSNode::Composition) != DSNode::HeapNode) {
-    DEBUG(std::cerr << "Node contains non-heap values:\n");
-    return false;
-  }
-
-  return true;
-}
-
-/// FindPoolsToCompress - Inspect the specified function and find pools that are
-/// compressible that are homed in that function.  Return those pools in the
-/// Pools set.
-void PointerCompress::FindPoolsToCompress(std::set<const DSNode*> &Pools,
-                                          Function &F, DSGraph &DSG,
-                                          PA::FuncInfo *FI) {
-  DEBUG(std::cerr << "In function '" << F.getName() << "':\n");
-  for (unsigned i = 0, e = FI->NodesToPA.size(); i != e; ++i) {
-    const DSNode *N = FI->NodesToPA[i];
-
-    // Ignore potential pools that the pool allocation heuristic decided not to
-    // pool allocated.
-    if (!isa<ConstantPointerNull>(FI->PoolDescriptors[N]))
-      if (PoolIsCompressible(N, F)) {
-        Pools.insert(N);
-        ++NumCompressed;
-      } else {
-        DEBUG(std::cerr << "PCF: "; N->dump());
-        ++NumNotCompressed;
-      }
-  }
-}
-
-
 namespace {
   /// InstructionRewriter - This class implements the rewriting neccesary to
   /// transform a function body from normal pool allocation to pointer
@@ -674,6 +608,20 @@
   // Get the base index.
   Value *Val = getTransformedValue(GEPI.getOperand(0));
 
+  bool AllZeros = true;
+  for (unsigned i = 1, e = GEPI.getNumOperands(); i != e; ++i)
+    if (!isa<Constant>(GEPI.getOperand(i)) ||
+        !cast<Constant>(GEPI.getOperand(i))->isNullValue()) {
+      AllZeros = false;
+      break;
+    }
+  if (AllZeros) {
+    // We occasionally get non-type-matching GEP instructions with zeros.  These
+    // are effectively pointer casts, so treat them as such.
+    setTransformedValue(GEPI, Val);
+    return;
+  }
+
   // The compressed type for the pool.  FIXME: NOTE: This only works if 'Val'
   // pointed to the start of a node!
   const Type *NTy = PointerType::get(PI->getNewType());
@@ -1027,6 +975,112 @@
 }
 
 
+
+//===----------------------------------------------------------------------===//
+//                    PointerCompress Implementation
+//===----------------------------------------------------------------------===//
+
+void PointerCompress::getAnalysisUsage(AnalysisUsage &AU) const {
+  // Need information about how pool allocation happened.
+  AU.addRequired<PoolAllocatePassAllPools>();
+
+  // Need information from DSA.
+  AU.addRequired<PA::EquivClassGraphs>();
+}
+
+/// PoolIsCompressible - Return true if we can pointer compress this node.
+/// If not, we should DEBUG print out why.
+static bool PoolIsCompressible(const DSNode *N) {
+  assert(!N->isForwarding() && "Should not be dealing with merged nodes!");
+  if (N->isNodeCompletelyFolded()) {
+    DEBUG(std::cerr << "Node is not type-safe:\n");
+    return false;
+  }
+
+  // FIXME: If any non-type-safe nodes point to this one, we cannot compress it.
+#if 0
+  bool HasFields = false;
+  for (DSNode::const_edge_iterator I = N->edge_begin(), E = N->edge_end();
+       I != E; ++I)
+    if (!I->isNull()) {
+      HasFields = true;
+      if (I->getNode() != N) {
+        // We currently only handle trivially self cyclic DS's right now.
+        DEBUG(std::cerr << "Node points to nodes other than itself:\n");
+        return false;
+      }        
+    }
+
+  if (!HasFields) {
+    DEBUG(std::cerr << "Node does not contain any pointers to compress:\n");
+    return false;
+  }
+#endif
+
+  if (N->isArray()) {
+    DEBUG(std::cerr << "Node is an array (not yet handled!):\n");
+    return false;
+  }
+
+  if ((N->getNodeFlags() & DSNode::Composition) != DSNode::HeapNode) {
+    DEBUG(std::cerr << "Node contains non-heap values:\n");
+    return false;
+  }
+
+  return true;
+}
+
+/// FindPoolsToCompress - Inspect the specified function and find pools that are
+/// compressible that are homed in that function.  Return those pools in the
+/// Pools set.
+void PointerCompress::FindPoolsToCompress(std::set<const DSNode*> &Pools,
+                                          Function &F, DSGraph &DSG,
+                                          PA::FuncInfo *FI) {
+  DEBUG(std::cerr << "In function '" << F.getName() << "':\n");
+  for (unsigned i = 0, e = FI->NodesToPA.size(); i != e; ++i) {
+    const DSNode *N = FI->NodesToPA[i];
+
+    // Ignore potential pools that the pool allocation heuristic decided not to
+    // pool allocated.
+    if (!isa<ConstantPointerNull>(FI->PoolDescriptors[N]))
+      if (PoolIsCompressible(N)) {
+        Pools.insert(N);
+        ++NumCompressed;
+      } else {
+        DEBUG(std::cerr << "PCF: "; N->dump());
+        ++NumNotCompressed;
+      }
+  }
+
+  // If there are no compressed global pools, don't bother to look for them.
+  if (CompressedGlobalPools.empty()) return;
+
+  // Calculate which DSNodes are reachable from globals.  If a node is reachable
+  // from a global, we check to see if the global pool is compressed.
+  DSGraph &GG = ECG->getGlobalsGraph();
+
+  DSGraph::NodeMapTy GlobalsGraphNodeMapping;
+  for (DSScalarMap::global_iterator I = DSG.getScalarMap().global_begin(),
+         E = DSG.getScalarMap().global_end(); I != E; ++I) {
+    // Map all node reachable from this global to the corresponding nodes in
+    // the globals graph.
+    DSGraph::computeNodeMapping(DSG.getNodeForValue(*I), GG.getNodeForValue(*I),
+                                GlobalsGraphNodeMapping);
+  }
+
+  // See if there are nodes in this graph that correspond to nodes in the
+  // globals graph, and if so, if it is compressed.
+  for (DSGraph::node_iterator I = DSG.node_begin(), E = DSG.node_end();
+       I != E;++I)
+    if (GlobalsGraphNodeMapping.count(*I)) {
+      // If it is a global pool, set up the pool descriptor appropriately.
+      DSNode *GGN = GlobalsGraphNodeMapping[*I].getNode();
+      if (CompressedGlobalPools.count(GGN))
+        Pools.insert(*I);
+    }
+}
+
+
 /// CompressPoolsInFunction - Find all pools that are compressible in this
 /// function and compress them.
 bool PointerCompress::
@@ -1059,10 +1113,6 @@
   if (FI->Clone && &FI->F == &F)
     return false;
 
-  // If there are no pools in this function, exit early.
-  if (FI->NodesToPA.empty() && CloneSource == 0)
-    return false;
-
   // Get the DSGraph for this function.
   DSGraph &DSG = ECG->getDSGraph(FI->F);
 
@@ -1261,6 +1311,33 @@
 }
 
 
+// Handle all pools pointed to by global variables.
+void PointerCompress::HandleGlobalPools(Module &M) {
+  if (PoolAlloc->GlobalNodes.empty()) return;
+
+  DEBUG(std::cerr << "Inspecting global nodes:\n");
+
+  // Loop over all of the global nodes identified by the pool allocator.
+  for (std::map<const DSNode*, Value*>::iterator I =
+         PoolAlloc->GlobalNodes.begin(), E = PoolAlloc->GlobalNodes.end();
+       I != E; ++I) {
+    const DSNode *N = I->first;
+
+    // Ignore potential pools that the pool allocation heuristic decided not to
+    // pool allocated.
+    if (!isa<ConstantPointerNull>(I->second))
+      if (PoolIsCompressible(N)) {
+        CompressedGlobalPools.insert(std::make_pair(N, 
+                                             cast<GlobalValue>(I->second)));
+        ++NumCompressed;
+      } else {
+        DEBUG(std::cerr << "PCF: "; N->dump());
+        ++NumNotCompressed;
+      }
+  }
+}
+
+
 /// InitializePoolLibraryFunctions - Create the function prototypes for pointer
 /// compress runtime library functions.
 void PointerCompress::InitializePoolLibraryFunctions(Module &M) {
@@ -1292,6 +1369,9 @@
   // functions.
   InitializePoolLibraryFunctions(M);
 
+  // Handle all pools pointed to by global variables.
+  HandleGlobalPools(M);
+
   // Iterate over all functions in the module, looking for compressible data
   // structures.
   bool Changed = false;






More information about the llvm-commits mailing list