blob: e2d81794d811347216921416cf9bb1350cae789c [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 Andersonaa071722007-07-11 23:19:17 +000049 bool handleFreeWithNonTrivialDependency(FreeInst* F, StoreInst* dependency,
50 SetVector<Instruction*>& possiblyDead);
51 bool handleEndBlock(BasicBlock& BB, SetVector<Instruction*>& possiblyDead);
Owen Anderson5e72db32007-07-11 00:46:18 +000052 void DeleteDeadInstructionChains(Instruction *I,
53 SetVector<Instruction*> &DeadInsts);
54
55 // getAnalysisUsage - We require post dominance frontiers (aka Control
56 // Dependence Graph)
57 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
58 AU.setPreservesCFG();
Owen Andersonaa071722007-07-11 23:19:17 +000059 AU.addRequired<TargetData>();
60 AU.addRequired<AliasAnalysis>();
Owen Anderson5e72db32007-07-11 00:46:18 +000061 AU.addRequired<MemoryDependenceAnalysis>();
Owen Andersonaa071722007-07-11 23:19:17 +000062 AU.addPreserved<AliasAnalysis>();
Owen Anderson5e72db32007-07-11 00:46:18 +000063 AU.addPreserved<MemoryDependenceAnalysis>();
64 }
65 };
66 char FDSE::ID = 0;
67 RegisterPass<FDSE> X("fdse", "Fast Dead Store Elimination");
68}
69
70FunctionPass *llvm::createFastDeadStoreEliminationPass() { return new FDSE(); }
71
72bool FDSE::runOnBasicBlock(BasicBlock &BB) {
Owen Andersonaa071722007-07-11 23:19:17 +000073 AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
Owen Anderson5e72db32007-07-11 00:46:18 +000074 MemoryDependenceAnalysis& MD = getAnalysis<MemoryDependenceAnalysis>();
75
Owen Andersonbf971aa2007-07-11 19:03:09 +000076 // Record the last-seen store to this pointer
Owen Anderson5e72db32007-07-11 00:46:18 +000077 DenseMap<Value*, StoreInst*> lastStore;
Owen Andersonbf971aa2007-07-11 19:03:09 +000078 // Record instructions possibly made dead by deleting a store
Owen Anderson5e72db32007-07-11 00:46:18 +000079 SetVector<Instruction*> possiblyDead;
80
81 bool MadeChange = false;
82
83 // Do a top-down walk on the BB
84 for (BasicBlock::iterator BBI = BB.begin(), BBE = BB.end(); BBI != BBE; ++BBI) {
Owen Anderson14414702007-07-11 21:06:56 +000085 // If we find a store or a free...
Owen Andersone7201442007-07-11 20:38:34 +000086 if (isa<StoreInst>(BBI) || isa<FreeInst>(BBI)) {
87 Value* pointer = 0;
88 if (StoreInst* S = dyn_cast<StoreInst>(BBI))
89 pointer = S->getPointerOperand();
90 else if (FreeInst* F = dyn_cast<FreeInst>(BBI))
91 pointer = F->getPointerOperand();
92 assert(pointer && "Not a free or a store?");
93
94 StoreInst*& last = lastStore[pointer];
Owen Anderson5e72db32007-07-11 00:46:18 +000095
96 // ... to a pointer that has been stored to before...
Owen Andersonbf971aa2007-07-11 19:03:09 +000097 if (last) {
Owen Anderson5e72db32007-07-11 00:46:18 +000098
99 // ... and no other memory dependencies are between them....
Owen Andersone7201442007-07-11 20:38:34 +0000100 if (MD.getDependency(BBI) == last) {
101
Owen Anderson5e72db32007-07-11 00:46:18 +0000102 // Remove it!
103 MD.removeInstruction(last);
Owen Andersonaa071722007-07-11 23:19:17 +0000104 AA.deleteValue(last);
Owen Anderson5e72db32007-07-11 00:46:18 +0000105
106 // DCE instructions only used to calculate that store
107 if (Instruction* D = dyn_cast<Instruction>(last->getOperand(0)))
108 possiblyDead.insert(D);
109
110 last->eraseFromParent();
111 NumFastStores++;
112 MadeChange = true;
Owen Andersonaa071722007-07-11 23:19:17 +0000113
114 // If this is a free, check for a non-trivial dependency
115 } else if (FreeInst* F = dyn_cast<FreeInst>(BBI))
116 MadeChange |= handleFreeWithNonTrivialDependency(F, last, possiblyDead);
Owen Anderson5e72db32007-07-11 00:46:18 +0000117 }
118
119 // Update our most-recent-store map
Owen Andersone7201442007-07-11 20:38:34 +0000120 if (StoreInst* S = dyn_cast<StoreInst>(BBI))
121 last = S;
122 else
123 last = 0;
Owen Anderson5e72db32007-07-11 00:46:18 +0000124 }
125 }
126
Owen Anderson14414702007-07-11 21:06:56 +0000127 // If this block ends in a return, unwind, unreachable, and eventually
128 // tailcall, then all allocas are dead at its end.
Owen Andersonaa071722007-07-11 23:19:17 +0000129 if (BB.getTerminator()->getNumSuccessors() == 0)
130 MadeChange |= handleEndBlock(BB, possiblyDead);
Owen Anderson14414702007-07-11 21:06:56 +0000131
Owen Anderson5e72db32007-07-11 00:46:18 +0000132 // Do a trivial DCE
133 while (!possiblyDead.empty()) {
134 Instruction *I = possiblyDead.back();
135 possiblyDead.pop_back();
136 DeleteDeadInstructionChains(I, possiblyDead);
137 }
138
139 return MadeChange;
140}
141
Owen Andersonaa071722007-07-11 23:19:17 +0000142/// handleFreeWithNonTrivialDependency - Handle frees of entire structures whose
143/// dependency is a store to a field of that structure
144bool FDSE::handleFreeWithNonTrivialDependency(FreeInst* F, StoreInst* dependency,
145 SetVector<Instruction*>& possiblyDead) {
146 TargetData &TD = getAnalysis<TargetData>();
147 AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
148 MemoryDependenceAnalysis& MD = getAnalysis<MemoryDependenceAnalysis>();
149
150 Value* depPointer = dependency->getPointerOperand();
151 unsigned depPointerSize = TD.getTypeSize(dependency->getOperand(0)->getType());
152
153 // Check for aliasing
154 AliasAnalysis::AliasResult A = AA.alias(F->getPointerOperand(), ~0UL,
155 depPointer, depPointerSize);
156
157 if (A == AliasAnalysis::MustAlias) {
158 // Remove it!
159 MD.removeInstruction(dependency);
160 AA.deleteValue(dependency);
161
162 // DCE instructions only used to calculate that store
163 if (Instruction* D = dyn_cast<Instruction>(dependency->getOperand(0)))
164 possiblyDead.insert(D);
165
166 dependency->eraseFromParent();
167 NumFastStores++;
168 return true;
169 }
170
171 return false;
172}
173
174/// handleEndBlock - Remove dead stores to stack-allocated locations in the function
175/// end block
176bool FDSE::handleEndBlock(BasicBlock& BB, SetVector<Instruction*>& possiblyDead) {
177 AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
178 MemoryDependenceAnalysis &MD = getAnalysis<MemoryDependenceAnalysis>();
179
180 bool MadeChange = false;
181
182 // Pointers alloca'd in this function are dead in the end block
183 SmallPtrSet<AllocaInst*, 4> deadPointers;
184
185 // Find all of the alloca'd pointers in the entry block
186 BasicBlock *Entry = BB.getParent()->begin();
187 for (BasicBlock::iterator I = Entry->begin(), E = Entry->end(); I != E; ++I)
188 if (AllocaInst *AI = dyn_cast<AllocaInst>(I))
189 deadPointers.insert(AI);
190
191 // Scan the basic block backwards
192 for (BasicBlock::iterator BBI = BB.end(); BBI != BB.begin(); ){
193 --BBI;
194
195 if (deadPointers.empty())
196 break;
197
198 // If we find a store whose pointer is dead...
199 if (StoreInst* S = dyn_cast<StoreInst>(BBI)) {
200 if (deadPointers.count(S->getPointerOperand())){
201 // Remove it!
202 MD.removeInstruction(S);
203 AA.deleteValue(S);
204
205 // DCE instructions only used to calculate that store
206 if (Instruction* D = dyn_cast<Instruction>(S->getOperand(0)))
207 possiblyDead.insert(D);
208
209 BBI++;
210 S->eraseFromParent();
211 NumFastStores++;
212 MadeChange = true;
213 }
214
215 // If we encounter a use of the pointer, it is no longer considered dead
216 } else if (LoadInst* L = dyn_cast<LoadInst>(BBI)) {
217 deadPointers.erase(L->getPointerOperand());
218 } else if (VAArgInst* V = dyn_cast<VAArgInst>(BBI)) {
219 deadPointers.erase(V->getOperand(0));
220 }
221 }
222
223 return MadeChange;
224}
225
Owen Anderson5e72db32007-07-11 00:46:18 +0000226void FDSE::DeleteDeadInstructionChains(Instruction *I,
227 SetVector<Instruction*> &DeadInsts) {
228 // Instruction must be dead.
229 if (!I->use_empty() || !isInstructionTriviallyDead(I)) return;
230
231 // Let the memory dependence know
232 getAnalysis<MemoryDependenceAnalysis>().removeInstruction(I);
Owen Andersonaa071722007-07-11 23:19:17 +0000233 getAnalysis<AliasAnalysis>().deleteValue(I);
Owen Anderson5e72db32007-07-11 00:46:18 +0000234
235 // See if this made any operands dead. We do it this way in case the
236 // instruction uses the same operand twice. We don't want to delete a
237 // value then reference it.
238 for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
Owen Andersonbf971aa2007-07-11 19:03:09 +0000239 if (I->getOperand(i)->hasOneUse())
240 if (Instruction* Op = dyn_cast<Instruction>(I->getOperand(i)))
241 DeadInsts.insert(Op); // Attempt to nuke it later.
242
Owen Anderson5e72db32007-07-11 00:46:18 +0000243 I->setOperand(i, 0); // Drop from the operand list.
244 }
245
246 I->eraseFromParent();
247 ++NumFastOther;
248}