blob: ecc3005541e4c3ef07cd8f8bf2ce550471ef632c [file] [log] [blame]
Owen Anderson5fba6c12007-05-29 21:53:49 +00001//===- GVNPRE.cpp - Eliminate redundant values and expressions ------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by the Owen Anderson and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This pass performs a hybrid of global value numbering and partial redundancy
11// elimination, known as GVN-PRE. It performs partial redundancy elimination on
12// values, rather than lexical expressions, allowing a more comprehensive view
13// the optimization. It replaces redundant values with uses of earlier
14// occurences of the same value. While this is beneficial in that it eliminates
15// unneeded computation, it also increases register pressure by creating large
16// live ranges, and should be used with caution on platforms that a very
17// sensitive to register pressure.
18//
19//===----------------------------------------------------------------------===//
20
21#define DEBUG_TYPE "gvnpre"
22#include "llvm/Value.h"
23#include "llvm/Transforms/Scalar.h"
24#include "llvm/Instructions.h"
25#include "llvm/Function.h"
26#include "llvm/Analysis/Dominators.h"
27#include "llvm/Analysis/PostDominators.h"
28#include "llvm/ADT/DepthFirstIterator.h"
29#include "llvm/ADT/Statistic.h"
Owen Andersonbe802402007-06-08 01:03:01 +000030#include "llvm/Support/CFG.h"
Owen Anderson5fba6c12007-05-29 21:53:49 +000031#include "llvm/Support/Compiler.h"
Owen Anderson4a6ec8f2007-05-29 23:15:21 +000032#include "llvm/Support/Debug.h"
Owen Anderson5fba6c12007-05-29 21:53:49 +000033#include <algorithm>
Owen Anderson331bf6a2007-05-31 22:44:11 +000034#include <deque>
Owen Anderson5fba6c12007-05-29 21:53:49 +000035#include <map>
Owen Anderson331bf6a2007-05-31 22:44:11 +000036#include <vector>
Owen Anderson5fba6c12007-05-29 21:53:49 +000037#include <set>
Owen Anderson5fba6c12007-05-29 21:53:49 +000038using namespace llvm;
39
Owen Anderson0b68cda2007-06-03 05:55:58 +000040struct ExprLT {
41 bool operator()(Value* left, Value* right) {
42 if (!isa<BinaryOperator>(left) || !isa<BinaryOperator>(right))
43 return left < right;
44
45 BinaryOperator* BO1 = cast<BinaryOperator>(left);
46 BinaryOperator* BO2 = cast<BinaryOperator>(right);
47
Owen Anderson55994f22007-06-08 20:44:02 +000048 if (BO1->getOpcode() != BO2->getOpcode())
49 return BO1->getOpcode() < BO2->getOpcode();
50 else if ((*this)(BO1->getOperand(0), BO2->getOperand(0)))
Owen Anderson0b68cda2007-06-03 05:55:58 +000051 return true;
52 else if ((*this)(BO2->getOperand(0), BO1->getOperand(0)))
53 return false;
54 else
55 return (*this)(BO1->getOperand(1), BO2->getOperand(1));
56 }
57};
58
Owen Anderson5fba6c12007-05-29 21:53:49 +000059namespace {
60
61 class VISIBILITY_HIDDEN GVNPRE : public FunctionPass {
62 bool runOnFunction(Function &F);
63 public:
64 static char ID; // Pass identification, replacement for typeid
65 GVNPRE() : FunctionPass((intptr_t)&ID) { nextValueNumber = 0; }
66
67 private:
68 uint32_t nextValueNumber;
Owen Anderson0b68cda2007-06-03 05:55:58 +000069 typedef std::map<Value*, uint32_t, ExprLT> ValueTable;
Owen Andersonbe802402007-06-08 01:03:01 +000070 ValueTable VN;
71 std::set<Value*, ExprLT> MS;
72 std::set<Instruction*> createdExpressions;
Owen Anderson81d156e2007-05-31 00:42:15 +000073
Owen Anderson5fba6c12007-05-29 21:53:49 +000074 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
75 AU.setPreservesCFG();
76 AU.addRequired<DominatorTree>();
77 AU.addRequired<PostDominatorTree>();
78 }
79
80 // Helper fuctions
81 // FIXME: eliminate or document these better
Owen Anderson2e5efc32007-06-08 01:52:45 +000082 void dump(const std::set<Value*>& s) const;
83 void dump_unique(const std::set<Value*, ExprLT>& s) const;
Owen Andersonbe802402007-06-08 01:03:01 +000084 void clean(std::set<Value*, ExprLT>& set);
85 bool add(Value* V, uint32_t number);
86 Value* find_leader(std::set<Value*, ExprLT>& vals,
87 Value* v);
88 Value* phi_translate(std::set<Value*, ExprLT>& set,
Owen Anderson38b6b222007-06-04 18:05:26 +000089 Value* V, BasicBlock* pred);
Owen Andersonbe802402007-06-08 01:03:01 +000090 void phi_translate_set(std::set<Value*, ExprLT>& anticIn, BasicBlock* B,
Owen Anderson0b68cda2007-06-03 05:55:58 +000091 std::set<Value*, ExprLT>& out);
Owen Anderson5fba6c12007-05-29 21:53:49 +000092
Owen Andersonbe802402007-06-08 01:03:01 +000093 void topo_sort(std::set<Value*, ExprLT>& set,
Owen Anderson0b68cda2007-06-03 05:55:58 +000094 std::vector<Value*>& vec);
Owen Anderson331bf6a2007-05-31 22:44:11 +000095
Owen Anderson5fba6c12007-05-29 21:53:49 +000096 // For a given block, calculate the generated expressions, temporaries,
97 // and the AVAIL_OUT set
Owen Andersonbe802402007-06-08 01:03:01 +000098 void CalculateAvailOut(DomTreeNode* DI,
Owen Anderson0b68cda2007-06-03 05:55:58 +000099 std::set<Value*, ExprLT>& currExps,
Owen Anderson5fba6c12007-05-29 21:53:49 +0000100 std::set<PHINode*>& currPhis,
Owen Anderson0eca9aa2007-06-03 22:02:14 +0000101 std::set<Value*>& currTemps,
Owen Anderson0b68cda2007-06-03 05:55:58 +0000102 std::set<Value*, ExprLT>& currAvail,
103 std::map<BasicBlock*, std::set<Value*, ExprLT> > availOut);
Owen Anderson5fba6c12007-05-29 21:53:49 +0000104
105 };
106
107 char GVNPRE::ID = 0;
108
109}
110
111FunctionPass *llvm::createGVNPREPass() { return new GVNPRE(); }
112
113RegisterPass<GVNPRE> X("gvnpre",
114 "Global Value Numbering/Partial Redundancy Elimination");
115
Owen Anderson5fba6c12007-05-29 21:53:49 +0000116
Owen Anderson0b68cda2007-06-03 05:55:58 +0000117
Owen Andersonbe802402007-06-08 01:03:01 +0000118bool GVNPRE::add(Value* V, uint32_t number) {
119 std::pair<ValueTable::iterator, bool> ret = VN.insert(std::make_pair(V, number));
Owen Anderson0b68cda2007-06-03 05:55:58 +0000120 if (isa<BinaryOperator>(V) || isa<PHINode>(V))
121 MS.insert(V);
122 return ret.second;
Owen Anderson5fba6c12007-05-29 21:53:49 +0000123}
124
Owen Andersonbe802402007-06-08 01:03:01 +0000125Value* GVNPRE::find_leader(std::set<Value*, ExprLT>& vals, Value* v) {
Owen Anderson0b68cda2007-06-03 05:55:58 +0000126 for (std::set<Value*, ExprLT>::iterator I = vals.begin(), E = vals.end();
Owen Andersonbe802402007-06-08 01:03:01 +0000127 I != E; ++I) {
128 assert(VN.find(v) != VN.end() && "Value not numbered?");
129 assert(VN.find(*I) != VN.end() && "Value not numbered?");
130 if (VN[v] == VN[*I])
Owen Anderson0b68cda2007-06-03 05:55:58 +0000131 return *I;
Owen Andersonbe802402007-06-08 01:03:01 +0000132 }
Owen Anderson5fba6c12007-05-29 21:53:49 +0000133
Owen Anderson0b68cda2007-06-03 05:55:58 +0000134 return 0;
Owen Anderson5fba6c12007-05-29 21:53:49 +0000135}
136
Owen Andersonbe802402007-06-08 01:03:01 +0000137Value* GVNPRE::phi_translate(std::set<Value*, ExprLT>& set,
Owen Anderson38b6b222007-06-04 18:05:26 +0000138 Value* V, BasicBlock* pred) {
139 if (V == 0)
140 return 0;
141
142 if (BinaryOperator* BO = dyn_cast<BinaryOperator>(V)) {
Owen Anderson3df52992007-06-04 23:28:33 +0000143 Value* newOp1 = isa<Instruction>(BO->getOperand(0))
Owen Andersonbe802402007-06-08 01:03:01 +0000144 ? phi_translate(set,
Owen Anderson634a0632007-06-06 01:27:49 +0000145 find_leader(set, BO->getOperand(0)),
Owen Anderson3df52992007-06-04 23:28:33 +0000146 pred)
147 : BO->getOperand(0);
Owen Anderson38b6b222007-06-04 18:05:26 +0000148 if (newOp1 == 0)
149 return 0;
150
Owen Anderson3df52992007-06-04 23:28:33 +0000151 Value* newOp2 = isa<Instruction>(BO->getOperand(1))
Owen Andersonbe802402007-06-08 01:03:01 +0000152 ? phi_translate(set,
Owen Anderson634a0632007-06-06 01:27:49 +0000153 find_leader(set, BO->getOperand(1)),
Owen Anderson3df52992007-06-04 23:28:33 +0000154 pred)
155 : BO->getOperand(1);
Owen Anderson38b6b222007-06-04 18:05:26 +0000156 if (newOp2 == 0)
157 return 0;
158
159 if (newOp1 != BO->getOperand(0) || newOp2 != BO->getOperand(1)) {
Owen Andersonbe802402007-06-08 01:03:01 +0000160 Instruction* newVal = BinaryOperator::create(BO->getOpcode(),
Owen Anderson38b6b222007-06-04 18:05:26 +0000161 newOp1, newOp2,
162 BO->getName()+".gvnpre");
Owen Anderson55994f22007-06-08 20:44:02 +0000163
Owen Andersonbe802402007-06-08 01:03:01 +0000164 if (add(newVal, nextValueNumber))
165 nextValueNumber++;
Owen Anderson634a0632007-06-06 01:27:49 +0000166 if (!find_leader(set, newVal)) {
Owen Andersonbe802402007-06-08 01:03:01 +0000167 DOUT << "Creating value: " << std::hex << newVal << std::dec << "\n";
168 createdExpressions.insert(newVal);
Owen Anderson38b6b222007-06-04 18:05:26 +0000169 return newVal;
Owen Andersonc8472092007-06-05 22:11:49 +0000170 } else {
Owen Anderson55994f22007-06-08 20:44:02 +0000171 ValueTable::iterator I = VN.find(newVal);
172 if (I->first == newVal)
173 VN.erase(newVal);
174
175 std::set<Value*, ExprLT>::iterator F = MS.find(newVal);
176 if (*F == newVal)
177 MS.erase(newVal);
178
Owen Andersonc8472092007-06-05 22:11:49 +0000179 delete newVal;
Owen Anderson38b6b222007-06-04 18:05:26 +0000180 return 0;
Owen Andersonc8472092007-06-05 22:11:49 +0000181 }
Owen Anderson38b6b222007-06-04 18:05:26 +0000182 }
183 } else if (PHINode* P = dyn_cast<PHINode>(V)) {
184 if (P->getParent() == pred->getTerminator()->getSuccessor(0))
185 return P->getIncomingValueForBlock(pred);
186 }
187
188 return V;
189}
190
Owen Andersonbe802402007-06-08 01:03:01 +0000191void GVNPRE::phi_translate_set(std::set<Value*, ExprLT>& anticIn, BasicBlock* B,
Owen Anderson0b68cda2007-06-03 05:55:58 +0000192 std::set<Value*, ExprLT>& out) {
Owen Anderson38b6b222007-06-04 18:05:26 +0000193 for (std::set<Value*, ExprLT>::iterator I = anticIn.begin(),
194 E = anticIn.end(); I != E; ++I) {
Owen Andersonbe802402007-06-08 01:03:01 +0000195 Value* V = phi_translate(anticIn, *I, B);
Owen Anderson38b6b222007-06-04 18:05:26 +0000196 if (V != 0)
197 out.insert(V);
Owen Anderson5fba6c12007-05-29 21:53:49 +0000198 }
199}
200
201// Remove all expressions whose operands are not themselves in the set
Owen Andersonbe802402007-06-08 01:03:01 +0000202void GVNPRE::clean(std::set<Value*, ExprLT>& set) {
Owen Anderson0b68cda2007-06-03 05:55:58 +0000203 std::vector<Value*> worklist;
Owen Andersonbe802402007-06-08 01:03:01 +0000204 topo_sort(set, worklist);
Owen Anderson5fba6c12007-05-29 21:53:49 +0000205
Owen Andersonbe802402007-06-08 01:03:01 +0000206 for (unsigned i = 0; i < worklist.size(); ++i) {
207 Value* v = worklist[i];
Owen Anderson5fba6c12007-05-29 21:53:49 +0000208
Owen Anderson0b68cda2007-06-03 05:55:58 +0000209 if (BinaryOperator* BO = dyn_cast<BinaryOperator>(v)) {
Owen Andersonbe802402007-06-08 01:03:01 +0000210 bool lhsValid = !isa<Instruction>(BO->getOperand(0));
211 if (!lhsValid)
212 for (std::set<Value*, ExprLT>::iterator I = set.begin(), E = set.end();
213 I != E; ++I)
214 if (VN[*I] == VN[BO->getOperand(0)]) {
215 lhsValid = true;
216 break;
217 }
Owen Anderson0b68cda2007-06-03 05:55:58 +0000218
Owen Andersonbe802402007-06-08 01:03:01 +0000219 bool rhsValid = !isa<Instruction>(BO->getOperand(1));
220 if (!rhsValid)
Owen Anderson0b68cda2007-06-03 05:55:58 +0000221 for (std::set<Value*, ExprLT>::iterator I = set.begin(), E = set.end();
222 I != E; ++I)
Owen Andersonbe802402007-06-08 01:03:01 +0000223 if (VN[*I] == VN[BO->getOperand(1)]) {
Owen Anderson0b68cda2007-06-03 05:55:58 +0000224 rhsValid = true;
Owen Andersonbe802402007-06-08 01:03:01 +0000225 break;
226 }
Owen Anderson5fba6c12007-05-29 21:53:49 +0000227
Owen Anderson0b68cda2007-06-03 05:55:58 +0000228 if (!lhsValid || !rhsValid)
229 set.erase(BO);
230 }
Owen Anderson5fba6c12007-05-29 21:53:49 +0000231 }
232}
233
Owen Andersonbe802402007-06-08 01:03:01 +0000234void GVNPRE::topo_sort(std::set<Value*, ExprLT>& set,
Owen Anderson0b68cda2007-06-03 05:55:58 +0000235 std::vector<Value*>& vec) {
Owen Andersonbe802402007-06-08 01:03:01 +0000236 std::set<Value*, ExprLT> toErase;
Owen Anderson0b68cda2007-06-03 05:55:58 +0000237 for (std::set<Value*, ExprLT>::iterator I = set.begin(), E = set.end();
Owen Anderson331bf6a2007-05-31 22:44:11 +0000238 I != E; ++I) {
Owen Anderson0b68cda2007-06-03 05:55:58 +0000239 if (BinaryOperator* BO = dyn_cast<BinaryOperator>(*I))
240 for (std::set<Value*, ExprLT>::iterator SI = set.begin(); SI != E; ++SI) {
Owen Andersonbe802402007-06-08 01:03:01 +0000241 if (VN[BO->getOperand(0)] == VN[*SI] ||
242 VN[BO->getOperand(1)] == VN[*SI]) {
243 toErase.insert(*SI);
Owen Anderson0b68cda2007-06-03 05:55:58 +0000244 }
Owen Anderson331bf6a2007-05-31 22:44:11 +0000245 }
246 }
247
Owen Anderson0b68cda2007-06-03 05:55:58 +0000248 std::vector<Value*> Q;
Owen Andersonbe802402007-06-08 01:03:01 +0000249 for (std::set<Value*, ExprLT>::iterator I = set.begin(), E = set.end();
250 I != E; ++I) {
251 if (toErase.find(*I) == toErase.end())
252 Q.push_back(*I);
253 }
Owen Anderson331bf6a2007-05-31 22:44:11 +0000254
Owen Andersonddbe4302007-06-05 23:46:12 +0000255 std::set<Value*> visited;
Owen Anderson331bf6a2007-05-31 22:44:11 +0000256 while (!Q.empty()) {
Owen Anderson0b68cda2007-06-03 05:55:58 +0000257 Value* e = Q.back();
258
259 if (BinaryOperator* BO = dyn_cast<BinaryOperator>(e)) {
Owen Anderson634a0632007-06-06 01:27:49 +0000260 Value* l = find_leader(set, BO->getOperand(0));
261 Value* r = find_leader(set, BO->getOperand(1));
Owen Anderson0b68cda2007-06-03 05:55:58 +0000262
Owen Andersonddbe4302007-06-05 23:46:12 +0000263 if (l != 0 && isa<Instruction>(l) &&
264 visited.find(l) == visited.end())
Owen Anderson0b68cda2007-06-03 05:55:58 +0000265 Q.push_back(l);
Owen Andersonddbe4302007-06-05 23:46:12 +0000266 else if (r != 0 && isa<Instruction>(r) &&
267 visited.find(r) == visited.end())
Owen Anderson0b68cda2007-06-03 05:55:58 +0000268 Q.push_back(r);
269 else {
270 vec.push_back(e);
271 visited.insert(e);
272 Q.pop_back();
273 }
274 } else {
Owen Anderson331bf6a2007-05-31 22:44:11 +0000275 visited.insert(e);
276 vec.push_back(e);
277 Q.pop_back();
Owen Anderson331bf6a2007-05-31 22:44:11 +0000278 }
279 }
280}
281
Owen Anderson0eca9aa2007-06-03 22:02:14 +0000282
Owen Anderson2e5efc32007-06-08 01:52:45 +0000283void GVNPRE::dump(const std::set<Value*>& s) const {
Owen Anderson4a6ec8f2007-05-29 23:15:21 +0000284 DOUT << "{ ";
Owen Anderson0eca9aa2007-06-03 22:02:14 +0000285 for (std::set<Value*>::iterator I = s.begin(), E = s.end();
286 I != E; ++I) {
287 DEBUG((*I)->dump());
288 }
289 DOUT << "}\n\n";
290}
291
Owen Anderson2e5efc32007-06-08 01:52:45 +0000292void GVNPRE::dump_unique(const std::set<Value*, ExprLT>& s) const {
Owen Anderson0eca9aa2007-06-03 22:02:14 +0000293 DOUT << "{ ";
294 for (std::set<Value*>::iterator I = s.begin(), E = s.end();
Owen Anderson331bf6a2007-05-31 22:44:11 +0000295 I != E; ++I) {
Owen Anderson0b68cda2007-06-03 05:55:58 +0000296 DEBUG((*I)->dump());
Owen Anderson5fba6c12007-05-29 21:53:49 +0000297 }
Owen Anderson4a6ec8f2007-05-29 23:15:21 +0000298 DOUT << "}\n\n";
Owen Anderson5fba6c12007-05-29 21:53:49 +0000299}
300
Owen Andersonbe802402007-06-08 01:03:01 +0000301void GVNPRE::CalculateAvailOut(DomTreeNode* DI,
Owen Anderson0b68cda2007-06-03 05:55:58 +0000302 std::set<Value*, ExprLT>& currExps,
Owen Anderson5fba6c12007-05-29 21:53:49 +0000303 std::set<PHINode*>& currPhis,
Owen Anderson0eca9aa2007-06-03 22:02:14 +0000304 std::set<Value*>& currTemps,
Owen Anderson0b68cda2007-06-03 05:55:58 +0000305 std::set<Value*, ExprLT>& currAvail,
306 std::map<BasicBlock*, std::set<Value*, ExprLT> > availOut) {
Owen Anderson5fba6c12007-05-29 21:53:49 +0000307
308 BasicBlock* BB = DI->getBlock();
309
310 // A block inherits AVAIL_OUT from its dominator
311 if (DI->getIDom() != 0)
312 currAvail.insert(availOut[DI->getIDom()->getBlock()].begin(),
313 availOut[DI->getIDom()->getBlock()].end());
314
315
316 for (BasicBlock::iterator BI = BB->begin(), BE = BB->end();
317 BI != BE; ++BI) {
318
319 // Handle PHI nodes...
320 if (PHINode* p = dyn_cast<PHINode>(BI)) {
Owen Andersonbe802402007-06-08 01:03:01 +0000321 if (add(p, nextValueNumber))
322 nextValueNumber++;
Owen Anderson5fba6c12007-05-29 21:53:49 +0000323 currPhis.insert(p);
324
325 // Handle binary ops...
326 } else if (BinaryOperator* BO = dyn_cast<BinaryOperator>(BI)) {
Owen Anderson0b68cda2007-06-03 05:55:58 +0000327 Value* leftValue = BO->getOperand(0);
328 Value* rightValue = BO->getOperand(1);
Owen Anderson5fba6c12007-05-29 21:53:49 +0000329
Owen Andersonbe802402007-06-08 01:03:01 +0000330 if (add(BO, nextValueNumber))
331 nextValueNumber++;
Owen Anderson5fba6c12007-05-29 21:53:49 +0000332
Owen Anderson3df52992007-06-04 23:28:33 +0000333 if (isa<Instruction>(leftValue))
334 currExps.insert(leftValue);
335 if (isa<Instruction>(rightValue))
336 currExps.insert(rightValue);
Owen Anderson0b68cda2007-06-03 05:55:58 +0000337 currExps.insert(BO);
Owen Anderson5fba6c12007-05-29 21:53:49 +0000338
Owen Anderson5fba6c12007-05-29 21:53:49 +0000339 // Handle unsupported ops
Owen Anderson0b68cda2007-06-03 05:55:58 +0000340 } else if (!BI->isTerminator()){
Owen Andersonbe802402007-06-08 01:03:01 +0000341 if (add(BI, nextValueNumber))
342 nextValueNumber++;
Owen Anderson0b68cda2007-06-03 05:55:58 +0000343 currTemps.insert(BI);
Owen Anderson5fba6c12007-05-29 21:53:49 +0000344 }
Owen Anderson0b68cda2007-06-03 05:55:58 +0000345
346 if (!BI->isTerminator())
347 currAvail.insert(BI);
Owen Anderson5fba6c12007-05-29 21:53:49 +0000348 }
349}
350
351bool GVNPRE::runOnFunction(Function &F) {
Owen Andersonbe802402007-06-08 01:03:01 +0000352 VN.clear();
353 MS.clear();
354 createdExpressions.clear();
Owen Anderson5fba6c12007-05-29 21:53:49 +0000355
Owen Anderson0b68cda2007-06-03 05:55:58 +0000356 std::map<BasicBlock*, std::set<Value*, ExprLT> > generatedExpressions;
Owen Anderson5fba6c12007-05-29 21:53:49 +0000357 std::map<BasicBlock*, std::set<PHINode*> > generatedPhis;
Owen Anderson0eca9aa2007-06-03 22:02:14 +0000358 std::map<BasicBlock*, std::set<Value*> > generatedTemporaries;
Owen Anderson0b68cda2007-06-03 05:55:58 +0000359 std::map<BasicBlock*, std::set<Value*, ExprLT> > availableOut;
360 std::map<BasicBlock*, std::set<Value*, ExprLT> > anticipatedIn;
Owen Anderson5fba6c12007-05-29 21:53:49 +0000361
362 DominatorTree &DT = getAnalysis<DominatorTree>();
363
Owen Anderson634a0632007-06-06 01:27:49 +0000364 // Phase 1: BuildSets
365
366 // Phase 1, Part 1: calculate AVAIL_OUT
Owen Anderson5fba6c12007-05-29 21:53:49 +0000367
368 // Top-down walk of the dominator tree
Devang Patelbdd1aae2007-06-04 00:32:22 +0000369 for (df_iterator<DomTreeNode*> DI = df_begin(DT.getRootNode()),
Owen Anderson5fba6c12007-05-29 21:53:49 +0000370 E = df_end(DT.getRootNode()); DI != E; ++DI) {
371
372 // Get the sets to update for this block
Owen Anderson0b68cda2007-06-03 05:55:58 +0000373 std::set<Value*, ExprLT>& currExps = generatedExpressions[DI->getBlock()];
Owen Anderson5fba6c12007-05-29 21:53:49 +0000374 std::set<PHINode*>& currPhis = generatedPhis[DI->getBlock()];
Owen Anderson0eca9aa2007-06-03 22:02:14 +0000375 std::set<Value*>& currTemps = generatedTemporaries[DI->getBlock()];
Owen Anderson0b68cda2007-06-03 05:55:58 +0000376 std::set<Value*, ExprLT>& currAvail = availableOut[DI->getBlock()];
Owen Anderson5fba6c12007-05-29 21:53:49 +0000377
Owen Andersonbe802402007-06-08 01:03:01 +0000378 CalculateAvailOut(*DI, currExps, currPhis,
Owen Anderson5fba6c12007-05-29 21:53:49 +0000379 currTemps, currAvail, availableOut);
380 }
381
Owen Anderson9b89e4b2007-06-05 17:31:23 +0000382 DOUT << "Maximal Set: ";
Owen Andersonbe802402007-06-08 01:03:01 +0000383 dump_unique(MS);
Owen Anderson9b89e4b2007-06-05 17:31:23 +0000384 DOUT << "\n";
385
Owen Anderson5fba6c12007-05-29 21:53:49 +0000386 PostDominatorTree &PDT = getAnalysis<PostDominatorTree>();
387
Owen Anderson634a0632007-06-06 01:27:49 +0000388 // Phase 1, Part 2: calculate ANTIC_IN
Owen Anderson5fba6c12007-05-29 21:53:49 +0000389
Owen Anderson0c423072007-05-29 23:26:30 +0000390 std::set<BasicBlock*> visited;
391
Owen Anderson5fba6c12007-05-29 21:53:49 +0000392 bool changed = true;
393 unsigned iterations = 0;
394 while (changed) {
395 changed = false;
Owen Anderson0b68cda2007-06-03 05:55:58 +0000396 std::set<Value*, ExprLT> anticOut;
Owen Anderson5fba6c12007-05-29 21:53:49 +0000397
398 // Top-down walk of the postdominator tree
Devang Patelbdd1aae2007-06-04 00:32:22 +0000399 for (df_iterator<DomTreeNode*> PDI =
Owen Andersonbe802402007-06-08 01:03:01 +0000400 df_begin(PDT.getRootNode()), E = df_end(PDT.getRootNode());
Owen Anderson5fba6c12007-05-29 21:53:49 +0000401 PDI != E; ++PDI) {
402 BasicBlock* BB = PDI->getBlock();
Owen Anderson3df52992007-06-04 23:28:33 +0000403 DOUT << "Block: " << BB->getName() << "\n";
404 DOUT << "TMP_GEN: ";
Owen Andersonbe802402007-06-08 01:03:01 +0000405 dump(generatedTemporaries[BB]);
Owen Anderson3df52992007-06-04 23:28:33 +0000406 DOUT << "\n";
407
408 DOUT << "EXP_GEN: ";
Owen Andersonbe802402007-06-08 01:03:01 +0000409 dump_unique(generatedExpressions[BB]);
Owen Anderson0c423072007-05-29 23:26:30 +0000410 visited.insert(BB);
411
Owen Anderson0b68cda2007-06-03 05:55:58 +0000412 std::set<Value*, ExprLT>& anticIn = anticipatedIn[BB];
413 std::set<Value*, ExprLT> old (anticIn.begin(), anticIn.end());
Owen Anderson5fba6c12007-05-29 21:53:49 +0000414
415 if (BB->getTerminator()->getNumSuccessors() == 1) {
Owen Anderson9b89e4b2007-06-05 17:31:23 +0000416 if (visited.find(BB->getTerminator()->getSuccessor(0)) ==
417 visited.end())
Owen Andersonbe802402007-06-08 01:03:01 +0000418 phi_translate_set(MS, BB, anticOut);
Owen Anderson81d156e2007-05-31 00:42:15 +0000419 else
Owen Andersonbe802402007-06-08 01:03:01 +0000420 phi_translate_set(
Owen Anderson9b89e4b2007-06-05 17:31:23 +0000421 anticipatedIn[BB->getTerminator()->getSuccessor(0)], BB, anticOut);
Owen Anderson5fba6c12007-05-29 21:53:49 +0000422 } else if (BB->getTerminator()->getNumSuccessors() > 1) {
Owen Anderson3df52992007-06-04 23:28:33 +0000423 BasicBlock* first = BB->getTerminator()->getSuccessor(0);
424 anticOut.insert(anticipatedIn[first].begin(),
425 anticipatedIn[first].end());
426 for (unsigned i = 1; i < BB->getTerminator()->getNumSuccessors(); ++i) {
Owen Anderson5fba6c12007-05-29 21:53:49 +0000427 BasicBlock* currSucc = BB->getTerminator()->getSuccessor(i);
Owen Anderson3df52992007-06-04 23:28:33 +0000428 std::set<Value*, ExprLT>& succAnticIn = anticipatedIn[currSucc];
429
Owen Anderson0b68cda2007-06-03 05:55:58 +0000430 std::set<Value*, ExprLT> temp;
Owen Anderson3df52992007-06-04 23:28:33 +0000431 std::insert_iterator<std::set<Value*, ExprLT> > temp_ins(temp,
432 temp.begin());
433 std::set_intersection(anticOut.begin(), anticOut.end(),
434 succAnticIn.begin(), succAnticIn.end(),
435 temp_ins, ExprLT());
436
437 anticOut.clear();
438 anticOut.insert(temp.begin(), temp.end());
Owen Anderson5fba6c12007-05-29 21:53:49 +0000439 }
440 }
441
Owen Anderson3df52992007-06-04 23:28:33 +0000442 DOUT << "ANTIC_OUT: ";
Owen Andersonbe802402007-06-08 01:03:01 +0000443 dump_unique(anticOut);
Owen Anderson3df52992007-06-04 23:28:33 +0000444 DOUT << "\n";
445
Owen Anderson0b68cda2007-06-03 05:55:58 +0000446 std::set<Value*, ExprLT> S;
447 std::insert_iterator<std::set<Value*, ExprLT> > s_ins(S, S.begin());
Owen Anderson5fba6c12007-05-29 21:53:49 +0000448 std::set_union(anticOut.begin(), anticOut.end(),
449 generatedExpressions[BB].begin(),
450 generatedExpressions[BB].end(),
Owen Anderson0b68cda2007-06-03 05:55:58 +0000451 s_ins, ExprLT());
Owen Anderson5fba6c12007-05-29 21:53:49 +0000452
453 anticIn.clear();
Owen Anderson3c9d8ee2007-06-04 23:34:56 +0000454
455 for (std::set<Value*, ExprLT>::iterator I = S.begin(), E = S.end();
456 I != E; ++I) {
457 if (generatedTemporaries[BB].find(*I) == generatedTemporaries[BB].end())
458 anticIn.insert(*I);
459 }
Owen Anderson5fba6c12007-05-29 21:53:49 +0000460
Owen Andersonbe802402007-06-08 01:03:01 +0000461 clean(anticIn);
Owen Anderson5fba6c12007-05-29 21:53:49 +0000462
Owen Anderson3df52992007-06-04 23:28:33 +0000463 DOUT << "ANTIC_IN: ";
Owen Andersonbe802402007-06-08 01:03:01 +0000464 dump_unique(anticIn);
Owen Anderson3df52992007-06-04 23:28:33 +0000465 DOUT << "\n";
466
Owen Andersonddbe4302007-06-05 23:46:12 +0000467 if (old.size() != anticIn.size())
Owen Anderson5fba6c12007-05-29 21:53:49 +0000468 changed = true;
469
470 anticOut.clear();
471 }
Owen Anderson38b6b222007-06-04 18:05:26 +0000472
Owen Anderson5fba6c12007-05-29 21:53:49 +0000473 iterations++;
474 }
475
Owen Anderson4a6ec8f2007-05-29 23:15:21 +0000476 DOUT << "Iterations: " << iterations << "\n";
Owen Anderson5fba6c12007-05-29 21:53:49 +0000477
478 for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) {
Owen Anderson4a6ec8f2007-05-29 23:15:21 +0000479 DOUT << "Name: " << I->getName().c_str() << "\n";
480
481 DOUT << "TMP_GEN: ";
Owen Andersonbe802402007-06-08 01:03:01 +0000482 dump(generatedTemporaries[I]);
Owen Anderson4a6ec8f2007-05-29 23:15:21 +0000483 DOUT << "\n";
484
485 DOUT << "EXP_GEN: ";
Owen Andersonbe802402007-06-08 01:03:01 +0000486 dump_unique(generatedExpressions[I]);
Owen Anderson4a6ec8f2007-05-29 23:15:21 +0000487 DOUT << "\n";
488
489 DOUT << "ANTIC_IN: ";
Owen Andersonbe802402007-06-08 01:03:01 +0000490 dump_unique(anticipatedIn[I]);
Owen Anderson4a6ec8f2007-05-29 23:15:21 +0000491 DOUT << "\n";
Owen Anderson0b68cda2007-06-03 05:55:58 +0000492
493 DOUT << "AVAIL_OUT: ";
Owen Andersonbe802402007-06-08 01:03:01 +0000494 dump_unique(availableOut[I]);
Owen Anderson0b68cda2007-06-03 05:55:58 +0000495 DOUT << "\n";
Owen Anderson4a6ec8f2007-05-29 23:15:21 +0000496 }
Owen Anderson5fba6c12007-05-29 21:53:49 +0000497
Owen Anderson634a0632007-06-06 01:27:49 +0000498
499 // Phase 2: Insert
Owen Andersonbe802402007-06-08 01:03:01 +0000500 DOUT<< "\nPhase 2: Insertion\n";
501
502 std::map<BasicBlock*, std::set<Value*, ExprLT> > new_sets;
503 unsigned i_iterations = 0;
504 bool new_stuff = true;
505 while (new_stuff) {
506 new_stuff = false;
507 DOUT << "Iteration: " << i_iterations << "\n\n";
508 for (df_iterator<DomTreeNode*> DI = df_begin(DT.getRootNode()),
509 E = df_end(DT.getRootNode()); DI != E; ++DI) {
510 BasicBlock* BB = DI->getBlock();
511
512 std::set<Value*, ExprLT>& new_set = new_sets[BB];
513 std::set<Value*, ExprLT>& availOut = availableOut[BB];
514 std::set<Value*, ExprLT>& anticIn = anticipatedIn[BB];
515
Owen Anderson55994f22007-06-08 20:44:02 +0000516 new_set.clear();
517
Owen Andersonbe802402007-06-08 01:03:01 +0000518 // Replace leaders with leaders inherited from dominator
519 if (DI->getIDom() != 0) {
520 std::set<Value*, ExprLT>& dom_set = new_sets[DI->getIDom()->getBlock()];
521 for (std::set<Value*, ExprLT>::iterator I = dom_set.begin(),
522 E = dom_set.end(); I != E; ++I) {
523 new_set.insert(*I);
524
Owen Anderson55994f22007-06-08 20:44:02 +0000525 Value* val = find_leader(availOut, *I);
526 while (val != 0) {
Owen Anderson2e5efc32007-06-08 01:52:45 +0000527 availOut.erase(val);
Owen Anderson55994f22007-06-08 20:44:02 +0000528 val = find_leader(availOut, *I);
529 }
Owen Anderson2e5efc32007-06-08 01:52:45 +0000530 availOut.insert(*I);
Owen Andersonbe802402007-06-08 01:03:01 +0000531 }
532 }
533
534 // If there is more than one predecessor...
535 if (pred_begin(BB) != pred_end(BB) && ++pred_begin(BB) != pred_end(BB)) {
536 std::vector<Value*> workList;
537 topo_sort(anticIn, workList);
538
539 DOUT << "Merge Block: " << BB->getName() << "\n";
540 DOUT << "ANTIC_IN: ";
541 dump_unique(anticIn);
542 DOUT << "\n";
543
544 while (!workList.empty()) {
545 Value* e = workList.back();
546 workList.pop_back();
547
548 if (isa<BinaryOperator>(e)) {
549 if (find_leader(availableOut[DI->getIDom()->getBlock()], e) != 0)
550 continue;
551
552 std::map<BasicBlock*, Value*> avail;
553 bool by_some = false;
554 int num_avail = 0;
555
556 for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE;
557 ++PI) {
558 Value *e2 = phi_translate(anticIn, e, *PI);
559 Value *e3 = find_leader(availableOut[*PI], e2);
560
561 if (e3 == 0) {
562 std::map<BasicBlock*, Value*>::iterator av = avail.find(*PI);
563 if (av != avail.end())
564 avail.erase(av);
565 avail.insert(std::make_pair(*PI, e2));
566 } else {
567 std::map<BasicBlock*, Value*>::iterator av = avail.find(*PI);
568 if (av != avail.end())
569 avail.erase(av);
570 avail.insert(std::make_pair(*PI, e3));
571
572 by_some = true;
573 num_avail++;
574 }
575 }
576
577 if (by_some &&
578 num_avail < std::distance(pred_begin(BB), pred_end(BB))) {
579 DOUT << "Processing Value: ";
580 DEBUG(e->dump());
581 DOUT << "\n\n";
582
583 for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB);
584 PI != PE; ++PI) {
585 Value* e2 = avail[*PI];
586 if (!find_leader(availableOut[*PI], e2)) {
587 BinaryOperator* BO = cast<BinaryOperator>(e2);
588
589 Value* s1 = 0;
590 if (isa<Instruction>(BO->getOperand(0)))
591 s1 = find_leader(availableOut[*PI], BO->getOperand(0));
592 else
593 s1 = BO->getOperand(0);
594
595 Value* s2 = 0;
596 if (isa<Instruction>(BO->getOperand(1)))
597 s2 = find_leader(availableOut[*PI], BO->getOperand(1));
598 else
599 s2 = BO->getOperand(1);
600
601 Value* newVal = BinaryOperator::create(BO->getOpcode(),
602 s1, s2,
603 BO->getName()+".gvnpre",
604 (*PI)->getTerminator());
605 add(newVal, VN[BO]);
Owen Anderson55994f22007-06-08 20:44:02 +0000606
607 std::set<Value*, ExprLT>& predAvail = availableOut[*PI];
608 Value* val = find_leader(predAvail, newVal);
609 while (val != 0) {
610 predAvail.erase(val);
611 val = find_leader(predAvail, newVal);
612 }
613 predAvail.insert(newVal);
Owen Andersonbe802402007-06-08 01:03:01 +0000614
615 DOUT << "Creating value: " << std::hex << newVal << std::dec << "\n";
616
617 std::map<BasicBlock*, Value*>::iterator av = avail.find(*PI);
618 if (av != avail.end())
619 avail.erase(av);
620 avail.insert(std::make_pair(*PI, newVal));
621 }
622 }
623
624 PHINode* p = 0;
625
626 for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB);
627 PI != PE; ++PI) {
628 if (p == 0)
629 p = new PHINode(avail[*PI]->getType(), "gvnpre-join",
630 BB->begin());
631
632 p->addIncoming(avail[*PI], *PI);
633 }
634
635 add(p, VN[e]);
636 DOUT << "Creating value: " << std::hex << p << std::dec << "\n";
637
Owen Anderson55994f22007-06-08 20:44:02 +0000638 Value* val = find_leader(availOut, p);
639 while (val != 0) {
640 availOut.erase(val);
641 val = find_leader(availOut, p);
642 }
Owen Andersonbe802402007-06-08 01:03:01 +0000643 availOut.insert(p);
Owen Anderson55994f22007-06-08 20:44:02 +0000644
Owen Andersonbe802402007-06-08 01:03:01 +0000645 new_stuff = true;
646
647 DOUT << "Preds After Processing: ";
648 for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB);
649 PI != PE; ++PI)
650 DEBUG((*PI)->dump());
651 DOUT << "\n\n";
652
653 DOUT << "Merge Block After Processing: ";
654 DEBUG(BB->dump());
655 DOUT << "\n\n";
656
657 new_set.insert(p);
658 }
659 }
660 }
661 }
662 }
663 i_iterations++;
664 }
Owen Anderson634a0632007-06-06 01:27:49 +0000665
666 // Phase 3: Eliminate
Owen Anderson55994f22007-06-08 20:44:02 +0000667 DOUT << "\n\nPhase 3: Elimination\n\n";
668
669 std::vector<std::pair<Instruction*, Value*> > replace;
670 std::vector<Instruction*> erase;
671
Owen Anderson634a0632007-06-06 01:27:49 +0000672 for (df_iterator<DomTreeNode*> DI = df_begin(DT.getRootNode()),
673 E = df_end(DT.getRootNode()); DI != E; ++DI) {
674 BasicBlock* BB = DI->getBlock();
675
Owen Anderson55994f22007-06-08 20:44:02 +0000676 DOUT << "Block: " << BB->getName() << "\n";
677 dump_unique(availableOut[BB]);
678 DOUT << "\n\n";
Owen Anderson634a0632007-06-06 01:27:49 +0000679
680 for (BasicBlock::iterator BI = BB->begin(), BE = BB->end();
681 BI != BE; ++BI) {
Owen Anderson55994f22007-06-08 20:44:02 +0000682
683 if (isa<BinaryOperator>(BI)) {
684 Value *leader = find_leader(availableOut[BB], BI);
685
Owen Andersonbe802402007-06-08 01:03:01 +0000686 if (leader != 0)
687 if (Instruction* Instr = dyn_cast<Instruction>(leader))
688 if (Instr->getParent() != 0 && Instr != BI) {
Owen Anderson55994f22007-06-08 20:44:02 +0000689 replace.push_back(std::make_pair(BI, leader));
Owen Andersonbe802402007-06-08 01:03:01 +0000690 erase.push_back(BI);
691 }
692 }
Owen Anderson634a0632007-06-06 01:27:49 +0000693 }
Owen Anderson634a0632007-06-06 01:27:49 +0000694 }
695
Owen Anderson55994f22007-06-08 20:44:02 +0000696 while (!replace.empty()) {
697 std::pair<Instruction*, Value*> rep = replace.back();
698 replace.pop_back();
699
700 rep.first->replaceAllUsesWith(rep.second);
701 }
702
703 for (std::vector<Instruction*>::iterator I = erase.begin(), E = erase.end();
704 I != E; ++I)
705 (*I)->eraseFromParent();
706
Owen Andersonbe802402007-06-08 01:03:01 +0000707 // Phase 4: Cleanup
708 for (std::set<Instruction*>::iterator I = createdExpressions.begin(),
709 E = createdExpressions.end(); I != E; ++I) {
710 delete *I;
711 }
712
Owen Anderson5fba6c12007-05-29 21:53:49 +0000713 return false;
714}