blob: a43d4254c3aa977bfb85d9f70803cd014caaf92b [file] [log] [blame]
Chris Lattner12be9362011-01-02 21:47:05 +00001//===- EarlyCSE.cpp - Simple and fast CSE pass ----------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This pass performs a simple dominator tree walk that eliminates trivially
11// redundant instructions.
12//
13//===----------------------------------------------------------------------===//
14
15#define DEBUG_TYPE "early-cse"
16#include "llvm/Transforms/Scalar.h"
Chris Lattner12be9362011-01-02 21:47:05 +000017#include "llvm/Pass.h"
Chris Lattnercc9eab22011-01-02 23:04:14 +000018#include "llvm/Analysis/Dominators.h"
19#include "llvm/Analysis/InstructionSimplify.h"
20#include "llvm/Analysis/InstructionSimplify.h"
21#include "llvm/Target/TargetData.h"
22#include "llvm/Transforms/Utils/Local.h"
23#include "llvm/ADT/ScopedHashTable.h"
Chris Lattner12be9362011-01-02 21:47:05 +000024using namespace llvm;
25
26namespace {
Chris Lattnercc9eab22011-01-02 23:04:14 +000027 /// InstValue - Instances of this struct represent available values in the
28 /// scoped hash table.
29 struct InstValue {
30 Instruction *Inst;
31
32 bool isSentinel() const {
33 return Inst == DenseMapInfo<Instruction*>::getEmptyKey() ||
34 Inst == DenseMapInfo<Instruction*>::getTombstoneKey();
35 }
36
37 static bool canHandle(Instruction *Inst) {
38 return isa<CastInst>(Inst);
39 }
40
41 static InstValue get(Instruction *I) {
42 InstValue X; X.Inst = I;
43 assert((X.isSentinel() || canHandle(I)) && "Inst can't be handled!");
44 return X;
45 }
46 };
47}
48
49namespace llvm {
50// InstValue is POD.
51template<> struct isPodLike<InstValue> {
52 static const bool value = true;
53};
54
55template<> struct DenseMapInfo<InstValue> {
56 static inline InstValue getEmptyKey() {
57 return InstValue::get(DenseMapInfo<Instruction*>::getEmptyKey());
58 }
59 static inline InstValue getTombstoneKey() {
60 return InstValue::get(DenseMapInfo<Instruction*>::getTombstoneKey());
61 }
62 static unsigned getHashValue(InstValue Val);
63 static bool isEqual(InstValue LHS, InstValue RHS);
64};
65}
66
67unsigned getHash(const void *V) {
68 return DenseMapInfo<const void*>::getHashValue(V);
69}
70
71unsigned DenseMapInfo<InstValue>::getHashValue(InstValue Val) {
72 Instruction *Inst = Val.Inst;
73 unsigned Res = 0;
74 if (CastInst *CI = dyn_cast<CastInst>(Inst))
75 Res = getHash(CI->getOperand(0)) ^ getHash(CI->getType());
76 else
77 assert(0 && "Unhandled instruction kind");
78
79 return (Res << 1) ^ Inst->getOpcode();
80}
81
82bool DenseMapInfo<InstValue>::isEqual(InstValue LHS, InstValue RHS) {
83 Instruction *LHSI = LHS.Inst, *RHSI = RHS.Inst;
84
85 if (LHS.isSentinel() || RHS.isSentinel())
86 return LHSI == RHSI;
87
88 if (LHSI->getOpcode() != RHSI->getOpcode()) return false;
89 return LHSI->isIdenticalTo(RHSI);
90}
91
92
93namespace {
94
Chris Lattner12be9362011-01-02 21:47:05 +000095/// EarlyCSE - This pass does a simple depth-first walk over the dominator
96/// tree, eliminating trivially redundant instructions and using instsimplify
97/// to canonicalize things as it goes. It is intended to be fast and catch
98/// obvious cases so that instcombine and other passes are more effective. It
99/// is expected that a later pass of GVN will catch the interesting/hard
100/// cases.
101class EarlyCSE : public FunctionPass {
102public:
Chris Lattnercc9eab22011-01-02 23:04:14 +0000103 const TargetData *TD;
104 DominatorTree *DT;
105 ScopedHashTable<InstValue, Instruction*> *AvailableValues;
106
Chris Lattner12be9362011-01-02 21:47:05 +0000107 static char ID;
108 explicit EarlyCSE()
109 : FunctionPass(ID) {
110 initializeEarlyCSEPass(*PassRegistry::getPassRegistry());
111 }
112
113 bool runOnFunction(Function &F);
114
115private:
Chris Lattnercc9eab22011-01-02 23:04:14 +0000116
117 bool processNode(DomTreeNode *Node);
118
Chris Lattner12be9362011-01-02 21:47:05 +0000119 // This transformation requires dominator postdominator info
120 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
121 AU.addRequired<DominatorTree>();
122 AU.setPreservesCFG();
123 }
124};
125}
126
127char EarlyCSE::ID = 0;
128
129// createEarlyCSEPass - The public interface to this file.
130FunctionPass *llvm::createEarlyCSEPass() {
131 return new EarlyCSE();
132}
133
134INITIALIZE_PASS_BEGIN(EarlyCSE, "early-cse", "Early CSE", false, false)
135INITIALIZE_PASS_DEPENDENCY(DominatorTree)
136INITIALIZE_PASS_END(EarlyCSE, "early-cse", "Early CSE", false, false)
137
Chris Lattnercc9eab22011-01-02 23:04:14 +0000138// FIXME: Should bump pointer allocate entries in scoped hash table.
139
140bool EarlyCSE::processNode(DomTreeNode *Node) {
141 // Define a scope in the scoped hash table.
142 ScopedHashTableScope<InstValue, Instruction*> Scope(*AvailableValues);
143
144 BasicBlock *BB = Node->getBlock();
145
146 bool Changed = false;
147
148 // See if any instructions in the block can be eliminated. If so, do it. If
149 // not, add them to AvailableValues.
150 for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
151 Instruction *Inst = I++;
152
153 // Dead instructions should just be removed.
154 if (isInstructionTriviallyDead(Inst)) {
155 Inst->eraseFromParent();
156 Changed = true;
157 continue;
158 }
159
160 // If the instruction can be simplified (e.g. X+0 = X) then replace it with
161 // its simpler value.
162 if (Value *V = SimplifyInstruction(Inst, TD, DT)) {
163 Inst->replaceAllUsesWith(V);
164 Inst->eraseFromParent();
165 Changed = true;
166 continue;
167 }
168
169 // If this instruction is something that we can't value number, ignore it.
170 if (!InstValue::canHandle(Inst))
171 continue;
172
173 // See if the instruction has an available value. If so, use it.
174 if (Instruction *V = AvailableValues->lookup(InstValue::get(Inst))) {
175 Inst->replaceAllUsesWith(V);
176 Inst->eraseFromParent();
177 Changed = true;
178 continue;
179 }
180
181 // Otherwise, just remember that this value is available.
182 AvailableValues->insert(InstValue::get(Inst), Inst);
183 }
184
185
186 for (DomTreeNode::iterator I = Node->begin(), E = Node->end(); I != E; ++I)
187 Changed |= processNode(*I);
188 return Changed;
Chris Lattner12be9362011-01-02 21:47:05 +0000189}
Chris Lattnercc9eab22011-01-02 23:04:14 +0000190
191
192bool EarlyCSE::runOnFunction(Function &F) {
193 TD = getAnalysisIfAvailable<TargetData>();
194 DT = &getAnalysis<DominatorTree>();
195 ScopedHashTable<InstValue, Instruction*> AVTable;
196 AvailableValues = &AVTable;
197 return processNode(DT->getRootNode());
198}
199