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

Chris Lattner lattner at cs.uiuc.edu
Sun Nov 7 14:20:09 PST 2004



Changes in directory poolalloc/lib/PoolAllocate:

PoolAllocate.cpp updated: 1.85 -> 1.86
PoolAllocate.h updated: 1.27 -> 1.28

---
Log message:

Add a place to add some trivial microoptimizations


---
Diffs of the changes:  (+76 -11)

Index: poolalloc/lib/PoolAllocate/PoolAllocate.cpp
diff -u poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.85 poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.86
--- poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.85	Sat Nov  6 23:27:19 2004
+++ poolalloc/lib/PoolAllocate/PoolAllocate.cpp	Sun Nov  7 16:19:59 2004
@@ -63,12 +63,12 @@
   const Type *PoolDescType;
 
   enum PoolAllocHeuristic {
-    AllNodes,
     NoNodes,
-    CyclicNodes,
-    SmartCoallesceNodes,
-    AllInOneGlobalPool,
     OnlyOverhead,
+    AllInOneGlobalPool,
+    SmartCoallesceNodes,
+    CyclicNodes,
+    AllNodes,
   };
   cl::opt<PoolAllocHeuristic>
   Heuristic("poolalloc-heuristic",
@@ -146,14 +146,11 @@
     Function *F = I->first;
     F->replaceAllUsesWith(ConstantExpr::getCast(I->second, F->getType()));
   }
-  return true;
-}
 
-static void GetNodesReachableFromGlobals(DSGraph &G,
-                                         hash_set<DSNode*> &NodesFromGlobals) {
-  for (DSScalarMap::global_iterator I = G.getScalarMap().global_begin(), 
-         E = G.getScalarMap().global_end(); I != E; ++I)
-    G.getNodeForValue(*I).getNode()->markReachableNodes(NodesFromGlobals);
+  if (Heuristic != NoNodes && Heuristic != OnlyOverhead &&
+      Heuristic != AllInOneGlobalPool)
+    MicroOptimizePoolCalls();
+  return true;
 }
 
 // AddPoolPrototypes - Add prototypes for the pool functions to the specified
@@ -191,6 +188,70 @@
                                             PoolDescPtrTy, VoidPtrTy, 0);  
 }
 
+static void getCallsOf(Function *F, std::vector<CallInst*> &Calls) {
+  Calls.clear();
+  for (Value::use_iterator UI = F->use_begin(), E = F->use_end(); UI != E; ++UI)
+    Calls.push_back(cast<CallInst>(*UI));
+}
+
+static void OptimizePointerNotNull(Value *V) {
+  for (Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I) {
+    Instruction *User = cast<Instruction>(*I);
+    if (User->getOpcode() == Instruction::SetEQ ||
+        User->getOpcode() == Instruction::SetNE) {
+      if (isa<Constant>(User->getOperand(1)) && 
+          cast<Constant>(User->getOperand(1))->isNullValue()) {
+        bool CondIsTrue = User->getOpcode() == Instruction::SetNE;
+        User->replaceAllUsesWith(ConstantBool::get(CondIsTrue));
+      }
+    } else if (User->getOpcode() == Instruction::Cast) {
+      // Casted pointers are also not null.
+      if (isa<PointerType>(User->getType()))
+        OptimizePointerNotNull(User);
+    } else if (User->getOpcode() == Instruction::GetElementPtr) {
+      // GEP'd pointers are also not null.
+      OptimizePointerNotNull(User);
+    }
+  }
+}
+
+/// MicroOptimizePoolCalls - Apply any microoptimizations to calls to pool
+/// allocation function calls that we can.  This runs after the whole program
+/// has been transformed.
+void PoolAllocate::MicroOptimizePoolCalls() {
+  // Optimize poolalloc
+  std::vector<CallInst*> Calls;
+  getCallsOf(PoolAlloc, Calls);
+  for (unsigned i = 0, e = Calls.size(); i != e; ++i) {
+    CallInst *CI = Calls[i];
+    // poolalloc never returns null.  Loop over all uses of the call looking for
+    // set(eq|ne) X, null.
+    OptimizePointerNotNull(CI);
+
+    // poolalloc(null, X) -> malloc(X)
+    if (isa<Constant>(CI->getOperand(0)) && 
+        cast<Constant>(CI->getOperand(0))->isNullValue())
+      std::cerr << "Could turn into malloc: " << *CI;
+  }
+
+  // TODO: poolfree accepts a null pointer, so remove any check above it, like
+  // 'if (P) poolfree(P)'
+
+  // poolfree(null) -> noop
+
+  // poolrealloc(null, X) -> malloc(X)
+
+}
+
+
+
+
+static void GetNodesReachableFromGlobals(DSGraph &G,
+                                         hash_set<DSNode*> &NodesFromGlobals) {
+  for (DSScalarMap::global_iterator I = G.getScalarMap().global_begin(), 
+         E = G.getScalarMap().global_end(); I != E; ++I)
+    G.getNodeForValue(*I).getNode()->markReachableNodes(NodesFromGlobals);
+}
 
 static void printNTOMap(std::map<Value*, const Value*> &NTOM) {
   std::cerr << "NTOM MAP\n";


Index: poolalloc/lib/PoolAllocate/PoolAllocate.h
diff -u poolalloc/lib/PoolAllocate/PoolAllocate.h:1.27 poolalloc/lib/PoolAllocate/PoolAllocate.h:1.28
--- poolalloc/lib/PoolAllocate/PoolAllocate.h:1.27	Thu Nov  4 14:13:00 2004
+++ poolalloc/lib/PoolAllocate/PoolAllocate.h	Sun Nov  7 16:19:59 2004
@@ -139,6 +139,10 @@
   /// them.
   ///
   void AddPoolPrototypes();
+
+  /// MicroOptimizePoolCalls - Apply any microoptimizations to calls to pool
+  /// allocation function calls that we can.
+  void MicroOptimizePoolCalls();
   
   /// BuildIndirectFunctionSets - Iterate over the module looking for indirect
   /// calls to functions





More information about the llvm-commits mailing list