[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