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

Chris Lattner lattner at cs.uiuc.edu
Fri Nov 5 13:02:37 PST 2004



Changes in directory poolalloc/lib/PoolAllocate:

PoolAllocate.cpp updated: 1.81 -> 1.82

---
Log message:

Hack in a "fix" for the 20x slowdown we used to induce in povray and the
4x slowdown in eon


---
Diffs of the changes:  (+176 -161)

Index: poolalloc/lib/PoolAllocate/PoolAllocate.cpp
diff -u poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.81 poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.82
--- poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.81	Thu Nov  4 14:13:00 2004
+++ poolalloc/lib/PoolAllocate/PoolAllocate.cpp	Fri Nov  5 15:02:26 2004
@@ -205,7 +205,7 @@
     }
   }
 
-  // Marked the returned node as alive...
+  // Marked the returned node as needing to be passed in.
   if (DSNode *RetNode = G.getReturnNodeFor(F).getNode())
     RetNode->markReachableNodes(MarkedNodes);
 
@@ -754,176 +754,191 @@
 
   std::set<AllocaInst*> AllocasHandled;
 
-  // Insert all of the poolalloc calls in the start of the function.
+  // Insert all of the poolinit/destroy calls into the function.
   for (unsigned i = 0, e = NodesToPA.size(); i != e; ++i) {
     DSNode *Node = NodesToPA[i];
-    if (AllocaInst *PD = dyn_cast<AllocaInst>(PoolDescriptors[Node]))
-      if (AllocasHandled.insert(PD).second) {
-        // Convert the PoolUses/PoolFrees sets into something specific to this
-        // pool.
-        std::set<BasicBlock*> UsingBlocks;
+    assert(isa<AllocaInst>(PoolDescriptors[Node]) && "Why pool allocate this?");
+    AllocaInst *PD = cast<AllocaInst>(PoolDescriptors[Node]);
+    
+    bool HasUse = false;
+    std::set<std::pair<AllocaInst*, Instruction*> >::iterator XUI =
+      PoolUses.lower_bound(std::make_pair(PD, (Instruction*)0));
+    HasUse |= XUI != PoolUses.end() && XUI->first == PD;
+
+    std::set<std::pair<AllocaInst*, CallInst*> >::iterator XUI2 =
+      PoolFrees.lower_bound(std::make_pair(PD, (CallInst*)0));
+    HasUse |= XUI2 != PoolFrees.end() && XUI2->first == PD;
+
+    // FIXME: Turn this into an assert and fix the problem!!
+    //assert(HasUse && "Pool is not used, but is marked heap?!");
+    if (!HasUse) continue;
+           
+    if (!AllocasHandled.insert(PD).second) continue;
+
+    // Convert the PoolUses/PoolFrees sets into something specific to this
+    // pool.
+    std::set<BasicBlock*> UsingBlocks;
+
+    std::set<std::pair<AllocaInst*, Instruction*> >::iterator PUI =
+      PoolUses.lower_bound(std::make_pair(PD, (Instruction*)0));
+    if (PUI != PoolUses.end() && PUI->first < PD) ++PUI;
+    for (; PUI != PoolUses.end() && PUI->first == PD; ++PUI)
+      UsingBlocks.insert(PUI->second->getParent());
+
+    // To calculate all of the basic blocks which require the pool to be
+    // initialized before, do a depth first search on the CFG from the using
+    // blocks.
+    std::set<BasicBlock*> InitializedBefore;
+    std::set<BasicBlock*> DestroyedAfter;
+    for (std::set<BasicBlock*>::iterator I = UsingBlocks.begin(),
+           E = UsingBlocks.end(); I != E; ++I) {
+      for (df_ext_iterator<BasicBlock*, std::set<BasicBlock*> >
+             DI = df_ext_begin(*I, InitializedBefore),
+             DE = df_ext_end(*I, InitializedBefore); DI != DE; ++DI)
+        /* empty */;
 
-        std::set<std::pair<AllocaInst*, Instruction*> >::iterator PUI =
-          PoolUses.lower_bound(std::make_pair(PD, (Instruction*)0));
-        if (PUI != PoolUses.end() && PUI->first < PD) ++PUI;
-        for (; PUI != PoolUses.end() && PUI->first == PD; ++PUI)
-          UsingBlocks.insert(PUI->second->getParent());
-
-        // To calculate all of the basic blocks which require the pool to be
-        // initialized before, do a depth first search on the CFG from the using
-        // blocks.
-        std::set<BasicBlock*> InitializedBefore;
-        std::set<BasicBlock*> DestroyedAfter;
-        for (std::set<BasicBlock*>::iterator I = UsingBlocks.begin(),
-               E = UsingBlocks.end(); I != E; ++I) {
-          for (df_ext_iterator<BasicBlock*, std::set<BasicBlock*> >
-                 DI = df_ext_begin(*I, InitializedBefore),
-                 DE = df_ext_end(*I, InitializedBefore); DI != DE; ++DI)
-            /* empty */;
-
-          for (idf_ext_iterator<BasicBlock*, std::set<BasicBlock*> >
-                 DI = idf_ext_begin(*I, DestroyedAfter),
-                 DE = idf_ext_end(*I, DestroyedAfter); DI != DE; ++DI)
-            /* empty */;
-        }
-        // Now that we have created the sets, intersect them.
-        std::set<BasicBlock*> LiveBlocks;
-        std::set_intersection(InitializedBefore.begin(),InitializedBefore.end(),
-                              DestroyedAfter.begin(), DestroyedAfter.end(),
-                              std::inserter(LiveBlocks, LiveBlocks.end()));
-        InitializedBefore.clear();
-        DestroyedAfter.clear();
-
-        // Keep track of the blocks we have inserted poolinit/destroy in
-        std::set<BasicBlock*> PoolInitInsertedBlocks, PoolDestroyInsertedBlocks;
-
-        DEBUG(std::cerr << "POOL: " << PD->getName() << " information:\n");
-        DEBUG(std::cerr << "  Live in blocks: ");
-        for (std::set<BasicBlock*>::iterator I = LiveBlocks.begin(),
-               E = LiveBlocks.end(); I != E; ++I) {
-          BasicBlock *BB = *I;
-          TerminatorInst *Term = BB->getTerminator();
-          DEBUG(std::cerr << BB->getName() << " ");
+      for (idf_ext_iterator<BasicBlock*, std::set<BasicBlock*> >
+             DI = idf_ext_begin(*I, DestroyedAfter),
+             DE = idf_ext_end(*I, DestroyedAfter); DI != DE; ++DI)
+        /* empty */;
+    }
+    // Now that we have created the sets, intersect them.
+    std::set<BasicBlock*> LiveBlocks;
+    std::set_intersection(InitializedBefore.begin(),InitializedBefore.end(),
+                          DestroyedAfter.begin(), DestroyedAfter.end(),
+                          std::inserter(LiveBlocks, LiveBlocks.end()));
+    InitializedBefore.clear();
+    DestroyedAfter.clear();
+
+    // Keep track of the blocks we have inserted poolinit/destroy in
+    std::set<BasicBlock*> PoolInitInsertedBlocks, PoolDestroyInsertedBlocks;
+
+    DEBUG(std::cerr << "POOL: " << PD->getName() << " information:\n");
+    DEBUG(std::cerr << "  Live in blocks: ");
+    for (std::set<BasicBlock*>::iterator I = LiveBlocks.begin(),
+           E = LiveBlocks.end(); I != E; ++I) {
+      BasicBlock *BB = *I;
+      TerminatorInst *Term = BB->getTerminator();
+      DEBUG(std::cerr << BB->getName() << " ");
       
-          // Check the predecessors of this block.  If any preds are not in the
-          // set, or if there are no preds, insert a pool init.
-          bool AllIn, NoneIn;
-          AllOrNoneInSet(pred_begin(BB), pred_end(BB), LiveBlocks, AllIn,
-                         NoneIn);
-
-          if (NoneIn) {
-            if (!PoolInitInsertedBlocks.count(BB)) {
-              BasicBlock::iterator It = BB->begin();
-              // Move through all of the instructions not in the pool
-              while (!PoolUses.count(std::make_pair(PD, It)))
-                // Advance past non-users deleting any pool frees that we run
-                // across.
-                DeleteIfIsPoolFree(It++, PD, PoolFrees);
-              if (!DisableInitDestroyOpt)
-                PoolInitPoints.push_back(It);
-              PoolInitInsertedBlocks.insert(BB);
-            }
-          } else if (!AllIn) {
-          TryAgainPred:
-            for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E;
-                 ++PI)
-              if (!LiveBlocks.count(*PI) && !PoolInitInsertedBlocks.count(*PI)){
-                if (SplitCriticalEdge(BB, PI))
-                  // If the critical edge was split, *PI was invalidated
-                  goto TryAgainPred;
-
-                // Insert at the end of the predecessor, before the terminator.
-                if (!DisableInitDestroyOpt)
-                  PoolInitPoints.push_back((*PI)->getTerminator());
-                PoolInitInsertedBlocks.insert(*PI);
-              }
+      // Check the predecessors of this block.  If any preds are not in the
+      // set, or if there are no preds, insert a pool init.
+      bool AllIn, NoneIn;
+      AllOrNoneInSet(pred_begin(BB), pred_end(BB), LiveBlocks, AllIn,
+                     NoneIn);
+
+      if (NoneIn) {
+        if (!PoolInitInsertedBlocks.count(BB)) {
+          BasicBlock::iterator It = BB->begin();
+          // Move through all of the instructions not in the pool
+          while (!PoolUses.count(std::make_pair(PD, It)))
+            // Advance past non-users deleting any pool frees that we run
+            // across.
+            DeleteIfIsPoolFree(It++, PD, PoolFrees);
+          if (!DisableInitDestroyOpt)
+            PoolInitPoints.push_back(It);
+          PoolInitInsertedBlocks.insert(BB);
+        }
+      } else if (!AllIn) {
+      TryAgainPred:
+        for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E;
+             ++PI)
+          if (!LiveBlocks.count(*PI) && !PoolInitInsertedBlocks.count(*PI)){
+            if (SplitCriticalEdge(BB, PI))
+              // If the critical edge was split, *PI was invalidated
+              goto TryAgainPred;
+
+            // Insert at the end of the predecessor, before the terminator.
+            if (!DisableInitDestroyOpt)
+              PoolInitPoints.push_back((*PI)->getTerminator());
+            PoolInitInsertedBlocks.insert(*PI);
           }
-          // Check the successors of this block.  If some succs are not in the
-          // set, insert destroys on those successor edges.  If all succs are
-          // not in the set, insert a destroy in this block.
-          AllOrNoneInSet(succ_begin(BB), succ_end(BB), LiveBlocks,
-                         AllIn, NoneIn);
-
-          if (NoneIn) {
-            // Insert before the terminator.
-            if (!PoolDestroyInsertedBlocks.count(BB)) {
-              BasicBlock::iterator It = Term;
+      }
+      // Check the successors of this block.  If some succs are not in the
+      // set, insert destroys on those successor edges.  If all succs are
+      // not in the set, insert a destroy in this block.
+      AllOrNoneInSet(succ_begin(BB), succ_end(BB), LiveBlocks,
+                     AllIn, NoneIn);
+
+      if (NoneIn) {
+        // Insert before the terminator.
+        if (!PoolDestroyInsertedBlocks.count(BB)) {
+          BasicBlock::iterator It = Term;
           
-              // Rewind to the first using insruction
-              while (!PoolUses.count(std::make_pair(PD, It)))
-                DeleteIfIsPoolFree(It--, PD, PoolFrees);
-
-              // Insert after the first using instruction
-              if (!DisableInitDestroyOpt)
-                PoolDestroyPoints.push_back(++It);
-              PoolDestroyInsertedBlocks.insert(BB);
-            }
-          } else if (!AllIn) {
-            for (succ_iterator SI = succ_begin(BB), E = succ_end(BB);
-                 SI != E; ++SI)
-              if (!LiveBlocks.count(*SI) &&
-                  !PoolDestroyInsertedBlocks.count(*SI)) {
-                // If this edge is critical, split it.
-                SplitCriticalEdge(BB, SI);
-
-                // Insert at entry to the successor, but after any PHI nodes.
-                BasicBlock::iterator It = (*SI)->begin();
-                while (isa<PHINode>(It)) ++It;
-                if (!DisableInitDestroyOpt)
-                  PoolDestroyPoints.push_back(It);
-                PoolDestroyInsertedBlocks.insert(*SI);
-              }
-          }
+          // Rewind to the first using insruction
+          while (!PoolUses.count(std::make_pair(PD, It)))
+            DeleteIfIsPoolFree(It--, PD, PoolFrees);
+
+          // Insert after the first using instruction
+          if (!DisableInitDestroyOpt)
+            PoolDestroyPoints.push_back(++It);
+          PoolDestroyInsertedBlocks.insert(BB);
         }
-        DEBUG(std::cerr << "\n  Init in blocks: ");
+      } else if (!AllIn) {
+        for (succ_iterator SI = succ_begin(BB), E = succ_end(BB);
+             SI != E; ++SI)
+          if (!LiveBlocks.count(*SI) &&
+              !PoolDestroyInsertedBlocks.count(*SI)) {
+            // If this edge is critical, split it.
+            SplitCriticalEdge(BB, SI);
+
+            // Insert at entry to the successor, but after any PHI nodes.
+            BasicBlock::iterator It = (*SI)->begin();
+            while (isa<PHINode>(It)) ++It;
+            if (!DisableInitDestroyOpt)
+              PoolDestroyPoints.push_back(It);
+            PoolDestroyInsertedBlocks.insert(*SI);
+          }
+      }
+    }
+    DEBUG(std::cerr << "\n  Init in blocks: ");
 
-        // Insert the calls to initialize the pool.
-        unsigned ElSizeV = 0;
-        if (Node->getType()->isSized())
-          ElSizeV = TD.getTypeSize(Node->getType());
-        Value *ElSize = ConstantUInt::get(Type::UIntTy, ElSizeV);
-
-        for (unsigned i = 0, e = PoolInitPoints.size(); i != e; ++i) {
-          new CallInst(PoolInit, make_vector((Value*)PD, ElSize, 0), "",
-                       PoolInitPoints[i]);
-          DEBUG(std::cerr << PoolInitPoints[i]->getParent()->getName() << " ");
-        }
-        if (!DisableInitDestroyOpt)
-          PoolInitPoints.clear();
+    // Insert the calls to initialize the pool.
+    unsigned ElSizeV = 0;
+    if (Node->getType()->isSized())
+      ElSizeV = TD.getTypeSize(Node->getType());
+    Value *ElSize = ConstantUInt::get(Type::UIntTy, ElSizeV);
+
+    for (unsigned i = 0, e = PoolInitPoints.size(); i != e; ++i) {
+      new CallInst(PoolInit, make_vector((Value*)PD, ElSize, 0), "",
+                   PoolInitPoints[i]);
+      DEBUG(std::cerr << PoolInitPoints[i]->getParent()->getName() << " ");
+    }
+    if (!DisableInitDestroyOpt)
+      PoolInitPoints.clear();
 
-        DEBUG(std::cerr << "\n  Destroy in blocks: ");
+    DEBUG(std::cerr << "\n  Destroy in blocks: ");
 
-        // Loop over all of the places to insert pooldestroy's...
-        for (unsigned i = 0, e = PoolDestroyPoints.size(); i != e; ++i) {
-          // Insert the pooldestroy call for this pool.
-          new CallInst(PoolDestroy, make_vector((Value*)PD, 0), "",
-                       PoolDestroyPoints[i]);
-          DEBUG(std::cerr << PoolDestroyPoints[i]->getParent()->getName()<<" ");
-        }
-        DEBUG(std::cerr << "\n\n");
+    // Loop over all of the places to insert pooldestroy's...
+    for (unsigned i = 0, e = PoolDestroyPoints.size(); i != e; ++i) {
+      // Insert the pooldestroy call for this pool.
+      new CallInst(PoolDestroy, make_vector((Value*)PD, 0), "",
+                   PoolDestroyPoints[i]);
+      DEBUG(std::cerr << PoolDestroyPoints[i]->getParent()->getName()<<" ");
+    }
+    DEBUG(std::cerr << "\n\n");
 
-        // We are allowed to delete any poolfree's which occur between the last
-        // call to poolalloc, and the call to pooldestroy.  Figure out which
-        // basic blocks have this property for this pool.
-        std::set<BasicBlock*> PoolFreeLiveBlocks;
-        if (!DisablePoolFreeOpt)
-          CalculateLivePoolFreeBlocks(PoolFreeLiveBlocks, PD);
-        else
-          PoolFreeLiveBlocks = LiveBlocks;
-
-        if (!DisableInitDestroyOpt)
-          PoolDestroyPoints.clear();
-
-        // Delete any pool frees which are not in live blocks, for correctness.
-        std::set<std::pair<AllocaInst*, CallInst*> >::iterator PFI =
-          PoolFrees.lower_bound(std::make_pair(PD, (CallInst*)0));
-        if (PFI != PoolFrees.end() && PFI->first < PD) ++PFI;
-        for (; PFI != PoolFrees.end() && PFI->first == PD; ) {
-          CallInst *PoolFree = (PFI++)->second;
-          if (!LiveBlocks.count(PoolFree->getParent()) ||
-              !PoolFreeLiveBlocks.count(PoolFree->getParent()))
-            DeleteIfIsPoolFree(PoolFree, PD, PoolFrees);
-        }
-      }
+    // We are allowed to delete any poolfree's which occur between the last
+    // call to poolalloc, and the call to pooldestroy.  Figure out which
+    // basic blocks have this property for this pool.
+    std::set<BasicBlock*> PoolFreeLiveBlocks;
+    if (!DisablePoolFreeOpt)
+      CalculateLivePoolFreeBlocks(PoolFreeLiveBlocks, PD);
+    else
+      PoolFreeLiveBlocks = LiveBlocks;
+
+    if (!DisableInitDestroyOpt)
+      PoolDestroyPoints.clear();
+
+    // Delete any pool frees which are not in live blocks, for correctness.
+    std::set<std::pair<AllocaInst*, CallInst*> >::iterator PFI =
+      PoolFrees.lower_bound(std::make_pair(PD, (CallInst*)0));
+    if (PFI != PoolFrees.end() && PFI->first < PD) ++PFI;
+    for (; PFI != PoolFrees.end() && PFI->first == PD; ) {
+      CallInst *PoolFree = (PFI++)->second;
+      if (!LiveBlocks.count(PoolFree->getParent()) ||
+          !PoolFreeLiveBlocks.count(PoolFree->getParent()))
+        DeleteIfIsPoolFree(PoolFree, PD, PoolFrees);
+    }
   }
 }





More information about the llvm-commits mailing list