[llvm-commits] [llvm] r39762 - /llvm/trunk/lib/Transforms/Scalar/FastDSE.cpp

Owen Anderson resistor at mac.com
Wed Jul 11 16:19:17 PDT 2007


Author: resistor
Date: Wed Jul 11 18:19:17 2007
New Revision: 39762

URL: http://llvm.org/viewvc/llvm-project?rev=39762&view=rev
Log:
Handle the case where an entire structure is freed, and its dependency is a store to a field within
that structure.

Also, refactor the runOnBasicBlock() function, splitting some of the special cases into separate functions.

Modified:
    llvm/trunk/lib/Transforms/Scalar/FastDSE.cpp

Modified: llvm/trunk/lib/Transforms/Scalar/FastDSE.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/FastDSE.cpp?rev=39762&r1=39761&r2=39762&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/FastDSE.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/FastDSE.cpp Wed Jul 11 18:19:17 2007
@@ -23,7 +23,9 @@
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/AliasAnalysis.h"
 #include "llvm/Analysis/MemoryDependenceAnalysis.h"
+#include "llvm/Target/TargetData.h"
 #include "llvm/Transforms/Utils/Local.h"
 #include "llvm/Support/Compiler.h"
 using namespace llvm;
@@ -44,6 +46,9 @@
     }
 
     bool runOnBasicBlock(BasicBlock &BB);
+    bool handleFreeWithNonTrivialDependency(FreeInst* F, StoreInst* dependency,
+                                            SetVector<Instruction*>& possiblyDead);
+    bool handleEndBlock(BasicBlock& BB, SetVector<Instruction*>& possiblyDead);
     void DeleteDeadInstructionChains(Instruction *I,
                                      SetVector<Instruction*> &DeadInsts);
 
@@ -51,7 +56,10 @@
     // Dependence Graph)
     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
       AU.setPreservesCFG();
+      AU.addRequired<TargetData>();
+      AU.addRequired<AliasAnalysis>();
       AU.addRequired<MemoryDependenceAnalysis>();
+      AU.addPreserved<AliasAnalysis>();
       AU.addPreserved<MemoryDependenceAnalysis>();
     }
   };
@@ -62,6 +70,7 @@
 FunctionPass *llvm::createFastDeadStoreEliminationPass() { return new FDSE(); }
 
 bool FDSE::runOnBasicBlock(BasicBlock &BB) {
+  AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
   MemoryDependenceAnalysis& MD = getAnalysis<MemoryDependenceAnalysis>();
   
   // Record the last-seen store to this pointer
@@ -92,6 +101,7 @@
           
           // Remove it!
           MD.removeInstruction(last);
+          AA.deleteValue(last);
           
           // DCE instructions only used to calculate that store
           if (Instruction* D = dyn_cast<Instruction>(last->getOperand(0)))
@@ -100,7 +110,10 @@
           last->eraseFromParent();
           NumFastStores++;
           MadeChange = true;
-        }
+        
+        // If this is a free, check for a non-trivial dependency
+        } else if (FreeInst* F = dyn_cast<FreeInst>(BBI))
+          MadeChange |= handleFreeWithNonTrivialDependency(F, last, possiblyDead);
       }
       
       // Update our most-recent-store map
@@ -113,47 +126,8 @@
   
   // If this block ends in a return, unwind, unreachable, and eventually
   // tailcall, then all allocas are dead at its end.
-  if (BB.getTerminator()->getNumSuccessors() == 0) {
-    // Pointers alloca'd in this function are dead in the end block
-    SmallPtrSet<AllocaInst*, 4> deadPointers;
-    
-    // Find all of the alloca'd pointers in the entry block
-    BasicBlock *Entry = BB.getParent()->begin();
-    for (BasicBlock::iterator I = Entry->begin(), E = Entry->end(); I != E; ++I)
-      if (AllocaInst *AI = dyn_cast<AllocaInst>(I))
-        deadPointers.insert(AI);
-    
-    // Scan the basic block backwards
-    for (BasicBlock::iterator BBI = BB.end(); BBI != BB.begin(); ){
-      --BBI;
-      
-      if (deadPointers.empty())
-        break;
-      
-      // If we find a store whose pointer is dead...
-      if (StoreInst* S = dyn_cast<StoreInst>(BBI)) {
-        if (deadPointers.count(S->getPointerOperand())){
-          // Remove it!
-          MD.removeInstruction(S);
-          
-          // DCE instructions only used to calculate that store
-          if (Instruction* D = dyn_cast<Instruction>(S->getOperand(0)))
-            possiblyDead.insert(D);
-          
-          BBI++;
-          S->eraseFromParent();
-          NumFastStores++;
-          MadeChange = true;
-        }
-      
-      // If we encounter a use of the pointer, it is no longer considered dead
-      } else if (LoadInst* L = dyn_cast<LoadInst>(BBI)) {
-        deadPointers.erase(L->getPointerOperand());
-      } else if (VAArgInst* V = dyn_cast<VAArgInst>(BBI)) {
-        deadPointers.erase(V->getOperand(0));
-    }
-    }
-  }
+  if (BB.getTerminator()->getNumSuccessors() == 0)
+    MadeChange |= handleEndBlock(BB, possiblyDead);
   
   // Do a trivial DCE
   while (!possiblyDead.empty()) {
@@ -165,6 +139,90 @@
   return MadeChange;
 }
 
+/// handleFreeWithNonTrivialDependency - Handle frees of entire structures whose
+/// dependency is a store to a field of that structure
+bool FDSE::handleFreeWithNonTrivialDependency(FreeInst* F, StoreInst* dependency,
+                                              SetVector<Instruction*>& possiblyDead) {
+  TargetData &TD = getAnalysis<TargetData>();
+  AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
+  MemoryDependenceAnalysis& MD = getAnalysis<MemoryDependenceAnalysis>();
+  
+  Value* depPointer = dependency->getPointerOperand();
+  unsigned depPointerSize = TD.getTypeSize(dependency->getOperand(0)->getType());
+    
+  // Check for aliasing
+  AliasAnalysis::AliasResult A = AA.alias(F->getPointerOperand(), ~0UL,
+                                          depPointer, depPointerSize);
+    
+  if (A == AliasAnalysis::MustAlias) {
+    // Remove it!
+    MD.removeInstruction(dependency);
+    AA.deleteValue(dependency);
+
+    // DCE instructions only used to calculate that store
+    if (Instruction* D = dyn_cast<Instruction>(dependency->getOperand(0)))
+      possiblyDead.insert(D);
+
+    dependency->eraseFromParent();
+    NumFastStores++;
+    return true;
+  }
+  
+  return false;
+}
+
+/// handleEndBlock - Remove dead stores to stack-allocated locations in the function
+/// end block
+bool FDSE::handleEndBlock(BasicBlock& BB, SetVector<Instruction*>& possiblyDead) {
+  AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
+  MemoryDependenceAnalysis &MD = getAnalysis<MemoryDependenceAnalysis>();
+  
+  bool MadeChange = false;
+  
+  // Pointers alloca'd in this function are dead in the end block
+  SmallPtrSet<AllocaInst*, 4> deadPointers;
+  
+  // Find all of the alloca'd pointers in the entry block
+  BasicBlock *Entry = BB.getParent()->begin();
+  for (BasicBlock::iterator I = Entry->begin(), E = Entry->end(); I != E; ++I)
+    if (AllocaInst *AI = dyn_cast<AllocaInst>(I))
+      deadPointers.insert(AI);
+  
+  // Scan the basic block backwards
+  for (BasicBlock::iterator BBI = BB.end(); BBI != BB.begin(); ){
+    --BBI;
+    
+    if (deadPointers.empty())
+      break;
+    
+    // If we find a store whose pointer is dead...
+    if (StoreInst* S = dyn_cast<StoreInst>(BBI)) {
+      if (deadPointers.count(S->getPointerOperand())){
+        // Remove it!
+        MD.removeInstruction(S);
+        AA.deleteValue(S);
+        
+        // DCE instructions only used to calculate that store
+        if (Instruction* D = dyn_cast<Instruction>(S->getOperand(0)))
+          possiblyDead.insert(D);
+        
+        BBI++;
+        S->eraseFromParent();
+        NumFastStores++;
+        MadeChange = true;
+      }
+    
+    // If we encounter a use of the pointer, it is no longer considered dead
+    } else if (LoadInst* L = dyn_cast<LoadInst>(BBI)) {
+      deadPointers.erase(L->getPointerOperand());
+    } else if (VAArgInst* V = dyn_cast<VAArgInst>(BBI)) {
+      deadPointers.erase(V->getOperand(0));
+    }
+  }
+  
+  return MadeChange;
+}
+
 void FDSE::DeleteDeadInstructionChains(Instruction *I,
                                       SetVector<Instruction*> &DeadInsts) {
   // Instruction must be dead.
@@ -172,6 +230,7 @@
 
   // Let the memory dependence know
   getAnalysis<MemoryDependenceAnalysis>().removeInstruction(I);
+  getAnalysis<AliasAnalysis>().deleteValue(I);
 
   // See if this made any operands dead.  We do it this way in case the
   // instruction uses the same operand twice.  We don't want to delete a





More information about the llvm-commits mailing list