blob: ebc7e6ef87af3f87431e959fd5ae7241d6ffbb17 [file] [log] [blame]
Owen Anderson5e72db32007-07-11 00:46:18 +00001//===- DeadStoreElimination.cpp - Dead Store Elimination ------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Owen Andersonbf971aa2007-07-11 19:03:09 +00005// This file was developed by Owen Anderson and is distributed under
Owen Anderson5e72db32007-07-11 00:46:18 +00006// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements a trivial dead store elimination that only considers
11// basic-block local redundant stores.
12//
13// FIXME: This should eventually be extended to be a post-dominator tree
14// traversal. Doing so would be pretty trivial.
15//
16//===----------------------------------------------------------------------===//
17
18#define DEBUG_TYPE "fdse"
19#include "llvm/Transforms/Scalar.h"
20#include "llvm/Function.h"
21#include "llvm/Instructions.h"
22#include "llvm/Pass.h"
23#include "llvm/ADT/SetVector.h"
24#include "llvm/ADT/SmallPtrSet.h"
25#include "llvm/ADT/Statistic.h"
Owen Andersonaa071722007-07-11 23:19:17 +000026#include "llvm/Analysis/AliasAnalysis.h"
Owen Anderson5e72db32007-07-11 00:46:18 +000027#include "llvm/Analysis/MemoryDependenceAnalysis.h"
Owen Andersonaa071722007-07-11 23:19:17 +000028#include "llvm/Target/TargetData.h"
Owen Anderson5e72db32007-07-11 00:46:18 +000029#include "llvm/Transforms/Utils/Local.h"
30#include "llvm/Support/Compiler.h"
31using namespace llvm;
32
33STATISTIC(NumFastStores, "Number of stores deleted");
34STATISTIC(NumFastOther , "Number of other instrs removed");
35
36namespace {
37 struct VISIBILITY_HIDDEN FDSE : public FunctionPass {
38 static char ID; // Pass identification, replacement for typeid
39 FDSE() : FunctionPass((intptr_t)&ID) {}
40
41 virtual bool runOnFunction(Function &F) {
42 bool Changed = false;
43 for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
44 Changed |= runOnBasicBlock(*I);
45 return Changed;
46 }
47
48 bool runOnBasicBlock(BasicBlock &BB);
Owen Andersond4451de2007-07-12 18:08:51 +000049 bool handleFreeWithNonTrivialDependency(FreeInst* F, Instruction* dependency,
Owen Andersonaa071722007-07-11 23:19:17 +000050 SetVector<Instruction*>& possiblyDead);
Owen Anderson5e72db32007-07-11 00:46:18 +000051 void DeleteDeadInstructionChains(Instruction *I,
52 SetVector<Instruction*> &DeadInsts);
53
54 // getAnalysisUsage - We require post dominance frontiers (aka Control
55 // Dependence Graph)
56 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
57 AU.setPreservesCFG();
Owen Andersonaa071722007-07-11 23:19:17 +000058 AU.addRequired<TargetData>();
59 AU.addRequired<AliasAnalysis>();
Owen Anderson5e72db32007-07-11 00:46:18 +000060 AU.addRequired<MemoryDependenceAnalysis>();
Owen Andersonaa071722007-07-11 23:19:17 +000061 AU.addPreserved<AliasAnalysis>();
Owen Anderson5e72db32007-07-11 00:46:18 +000062 AU.addPreserved<MemoryDependenceAnalysis>();
63 }
64 };
65 char FDSE::ID = 0;
66 RegisterPass<FDSE> X("fdse", "Fast Dead Store Elimination");
67}
68
69FunctionPass *llvm::createFastDeadStoreEliminationPass() { return new FDSE(); }
70
71bool FDSE::runOnBasicBlock(BasicBlock &BB) {
72 MemoryDependenceAnalysis& MD = getAnalysis<MemoryDependenceAnalysis>();
73
Owen Andersonbf971aa2007-07-11 19:03:09 +000074 // Record the last-seen store to this pointer
Owen Anderson5e72db32007-07-11 00:46:18 +000075 DenseMap<Value*, StoreInst*> lastStore;
Owen Andersonbf971aa2007-07-11 19:03:09 +000076 // Record instructions possibly made dead by deleting a store
Owen Anderson5e72db32007-07-11 00:46:18 +000077 SetVector<Instruction*> possiblyDead;
78
79 bool MadeChange = false;
80
81 // Do a top-down walk on the BB
82 for (BasicBlock::iterator BBI = BB.begin(), BBE = BB.end(); BBI != BBE; ++BBI) {
Owen Anderson14414702007-07-11 21:06:56 +000083 // If we find a store or a free...
Owen Andersone7201442007-07-11 20:38:34 +000084 if (isa<StoreInst>(BBI) || isa<FreeInst>(BBI)) {
85 Value* pointer = 0;
86 if (StoreInst* S = dyn_cast<StoreInst>(BBI))
87 pointer = S->getPointerOperand();
88 else if (FreeInst* F = dyn_cast<FreeInst>(BBI))
89 pointer = F->getPointerOperand();
90 assert(pointer && "Not a free or a store?");
91
92 StoreInst*& last = lastStore[pointer];
Owen Andersond4451de2007-07-12 18:08:51 +000093 bool deletedStore = false;
Owen Anderson5e72db32007-07-11 00:46:18 +000094
95 // ... to a pointer that has been stored to before...
Owen Andersonbf971aa2007-07-11 19:03:09 +000096 if (last) {
Owen Anderson5e72db32007-07-11 00:46:18 +000097
98 // ... and no other memory dependencies are between them....
Owen Andersone7201442007-07-11 20:38:34 +000099 if (MD.getDependency(BBI) == last) {
100
Owen Anderson5e72db32007-07-11 00:46:18 +0000101 // Remove it!
102 MD.removeInstruction(last);
103
104 // DCE instructions only used to calculate that store
105 if (Instruction* D = dyn_cast<Instruction>(last->getOperand(0)))
106 possiblyDead.insert(D);
107
108 last->eraseFromParent();
109 NumFastStores++;
Owen Andersond4451de2007-07-12 18:08:51 +0000110 deletedStore = true;
Owen Anderson5e72db32007-07-11 00:46:18 +0000111 MadeChange = true;
Owen Andersond4451de2007-07-12 18:08:51 +0000112 }
Owen Anderson5e72db32007-07-11 00:46:18 +0000113 }
114
Owen Andersond4451de2007-07-12 18:08:51 +0000115 // Handle frees whose dependencies are non-trivial
116 if (FreeInst* F = dyn_cast<FreeInst>(BBI))
117 if (!deletedStore)
118 MadeChange |= handleFreeWithNonTrivialDependency(F, MD.getDependency(F),
119 possiblyDead);
120
Owen Anderson5e72db32007-07-11 00:46:18 +0000121 // Update our most-recent-store map
Owen Andersone7201442007-07-11 20:38:34 +0000122 if (StoreInst* S = dyn_cast<StoreInst>(BBI))
123 last = S;
124 else
125 last = 0;
Owen Anderson5e72db32007-07-11 00:46:18 +0000126 }
127 }
128
129 // Do a trivial DCE
130 while (!possiblyDead.empty()) {
131 Instruction *I = possiblyDead.back();
132 possiblyDead.pop_back();
133 DeleteDeadInstructionChains(I, possiblyDead);
134 }
135
136 return MadeChange;
137}
138
Owen Andersonaa071722007-07-11 23:19:17 +0000139/// handleFreeWithNonTrivialDependency - Handle frees of entire structures whose
140/// dependency is a store to a field of that structure
Owen Andersond4451de2007-07-12 18:08:51 +0000141bool FDSE::handleFreeWithNonTrivialDependency(FreeInst* F, Instruction* dep,
Owen Andersonaa071722007-07-11 23:19:17 +0000142 SetVector<Instruction*>& possiblyDead) {
143 TargetData &TD = getAnalysis<TargetData>();
144 AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
145 MemoryDependenceAnalysis& MD = getAnalysis<MemoryDependenceAnalysis>();
146
Owen Andersond4451de2007-07-12 18:08:51 +0000147 if (dep == MemoryDependenceAnalysis::None ||
148 dep == MemoryDependenceAnalysis::NonLocal)
149 return false;
150
151 StoreInst* dependency = dyn_cast<StoreInst>(dep);
152 if (!dependency)
153 return false;
154
Owen Andersonaa071722007-07-11 23:19:17 +0000155 Value* depPointer = dependency->getPointerOperand();
156 unsigned depPointerSize = TD.getTypeSize(dependency->getOperand(0)->getType());
157
158 // Check for aliasing
159 AliasAnalysis::AliasResult A = AA.alias(F->getPointerOperand(), ~0UL,
160 depPointer, depPointerSize);
161
162 if (A == AliasAnalysis::MustAlias) {
163 // Remove it!
164 MD.removeInstruction(dependency);
Owen Andersonaa071722007-07-11 23:19:17 +0000165
166 // DCE instructions only used to calculate that store
167 if (Instruction* D = dyn_cast<Instruction>(dependency->getOperand(0)))
168 possiblyDead.insert(D);
169
170 dependency->eraseFromParent();
171 NumFastStores++;
172 return true;
173 }
174
175 return false;
176}
177
Owen Anderson5e72db32007-07-11 00:46:18 +0000178void FDSE::DeleteDeadInstructionChains(Instruction *I,
179 SetVector<Instruction*> &DeadInsts) {
180 // Instruction must be dead.
181 if (!I->use_empty() || !isInstructionTriviallyDead(I)) return;
182
183 // Let the memory dependence know
184 getAnalysis<MemoryDependenceAnalysis>().removeInstruction(I);
185
186 // See if this made any operands dead. We do it this way in case the
187 // instruction uses the same operand twice. We don't want to delete a
188 // value then reference it.
189 for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
Owen Andersonbf971aa2007-07-11 19:03:09 +0000190 if (I->getOperand(i)->hasOneUse())
191 if (Instruction* Op = dyn_cast<Instruction>(I->getOperand(i)))
192 DeadInsts.insert(Op); // Attempt to nuke it later.
193
Owen Anderson5e72db32007-07-11 00:46:18 +0000194 I->setOperand(i, 0); // Drop from the operand list.
195 }
196
197 I->eraseFromParent();
198 ++NumFastOther;
199}