blob: b9006b63e102fd50fd6d08d64ec57d9b517ea967 [file] [log] [blame]
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +00001//===-- PredicateSimplifier.cpp - Path Sensitive Simplifier -----------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Nick Lewycky and is distributed under the
6// University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===------------------------------------------------------------------===//
9//
10// Path-sensitive optimizer. In a branch where x == y, replace uses of
11// x with y. Permits further optimization, such as the elimination of
12// the unreachable call:
13//
14// void test(int *p, int *q)
15// {
16// if (p != q)
17// return;
18//
19// if (*p != *q)
20// foo(); // unreachable
21// }
22//
23//===------------------------------------------------------------------===//
24//
25// This optimization works by substituting %q for %p when protected by a
Nick Lewycky5f8f9af2006-08-30 02:46:48 +000026// conditional that assures us of that fact. Properties are stored as
27// relationships between two values.
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +000028//
29//===------------------------------------------------------------------===//
30
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +000031#define DEBUG_TYPE "predsimplify"
32#include "llvm/Transforms/Scalar.h"
33#include "llvm/Constants.h"
34#include "llvm/Instructions.h"
35#include "llvm/Pass.h"
36#include "llvm/ADT/Statistic.h"
37#include "llvm/ADT/STLExtras.h"
38#include "llvm/Analysis/Dominators.h"
39#include "llvm/Support/CFG.h"
40#include "llvm/Support/Debug.h"
41#include <iostream>
42using namespace llvm;
43
Nick Lewycky9a22d7b2006-09-10 02:27:07 +000044typedef DominatorTree::Node DTNodeType;
45
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +000046namespace {
47 Statistic<>
48 NumVarsReplaced("predsimplify", "Number of argument substitutions");
49 Statistic<>
Nick Lewycky5f8f9af2006-08-30 02:46:48 +000050 NumInstruction("predsimplify", "Number of instructions removed");
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +000051
Nick Lewycky9a22d7b2006-09-10 02:27:07 +000052 /// Returns true if V1 is a better choice than V2. Note that it is
53 /// not a total ordering.
54 struct compare {
55 bool operator()(Value *V1, Value *V2) const {
Nick Lewycky51ce8d62006-09-13 19:24:01 +000056 if (isa<Constant>(V1)) {
57 if (!isa<Constant>(V2)) {
Nick Lewycky9a22d7b2006-09-10 02:27:07 +000058 return true;
59 }
Nick Lewycky51ce8d62006-09-13 19:24:01 +000060 } else if (isa<Argument>(V1)) {
61 if (!isa<Constant>(V2) && !isa<Argument>(V2)) {
Nick Lewycky9a22d7b2006-09-10 02:27:07 +000062 return true;
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +000063 }
64 }
Nick Lewycky51ce8d62006-09-13 19:24:01 +000065 if (User *U = dyn_cast<User>(V2)) {
66 for (User::const_op_iterator I = U->op_begin(), E = U->op_end();
Nick Lewycky9a22d7b2006-09-10 02:27:07 +000067 I != E; ++I) {
Nick Lewycky51ce8d62006-09-13 19:24:01 +000068 if (*I == V1) {
Nick Lewycky9a22d7b2006-09-10 02:27:07 +000069 return true;
70 }
71 }
72 }
73 return false;
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +000074 }
Nick Lewycky9a22d7b2006-09-10 02:27:07 +000075 };
76
77 /// Used for choosing the canonical Value in a synonym set.
Nick Lewycky51ce8d62006-09-13 19:24:01 +000078 /// Leaves the better choice in V1.
Nick Lewycky9a22d7b2006-09-10 02:27:07 +000079 static void order(Value *&V1, Value *&V2) {
80 static compare c;
Nick Lewycky51ce8d62006-09-13 19:24:01 +000081 if (c(V2, V1))
Nick Lewycky9a22d7b2006-09-10 02:27:07 +000082 std::swap(V1, V2);
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +000083 }
84
Nick Lewycky9a22d7b2006-09-10 02:27:07 +000085 /// Similar to EquivalenceClasses, this stores the set of equivalent
86 /// types. Beyond EquivalenceClasses, it allows the user to specify
87 /// which element will act as leader through a StrictWeakOrdering
88 /// function.
89 template<typename ElemTy, typename StrictWeak>
90 class VISIBILITY_HIDDEN Synonyms {
91 std::map<ElemTy, unsigned> mapping;
92 std::vector<ElemTy> leaders;
93 StrictWeak swo;
94
95 public:
96 typedef unsigned iterator;
97 typedef const unsigned const_iterator;
98
99 // Inspection
100
101 bool empty() const {
102 return leaders.empty();
103 }
104
Nick Lewycky12efffc2006-09-13 19:32:53 +0000105 unsigned countLeaders() const {
106 return leaders.size();
107 }
108
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000109 iterator findLeader(ElemTy e) {
110 typename std::map<ElemTy, unsigned>::iterator MI = mapping.find(e);
111 if (MI == mapping.end()) return 0;
112
113 return MI->second;
114 }
115
116 const_iterator findLeader(ElemTy e) const {
117 typename std::map<ElemTy, unsigned>::const_iterator MI =
118 mapping.find(e);
119 if (MI == mapping.end()) return 0;
120
121 return MI->second;
122 }
123
124 ElemTy &getLeader(iterator I) {
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000125 assert(I && I <= leaders.size() && "Illegal leader to get.");
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000126 return leaders[I-1];
127 }
128
129 const ElemTy &getLeader(const_iterator I) const {
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000130 assert(I && I <= leaders.size() && "Illegal leaders to get.");
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000131 return leaders[I-1];
132 }
133
134#ifdef DEBUG
135 void debug(std::ostream &os) const {
136 for (unsigned i = 1, e = leaders.size()+1; i != e; ++i) {
Nick Lewycky12efffc2006-09-13 19:32:53 +0000137 os << i << ". " << *getLeader(i) << ": [";
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000138 for (std::map<Value *, unsigned>::const_iterator
139 I = mapping.begin(), E = mapping.end(); I != E; ++I) {
140 if ((*I).second == i && (*I).first != leaders[i-1]) {
141 os << *(*I).first << " ";
Nick Lewycky51ce8d62006-09-13 19:24:01 +0000142 }
143 }
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000144 os << "]\n";
145 }
146 }
147#endif
148
149 // Mutators
150
151 /// Combine two sets referring to the same element, inserting the
152 /// elements as needed. Returns a valid iterator iff two already
153 /// existing disjoint synonym sets were combined. The iterator
154 /// points to the removed element.
155 iterator unionSets(ElemTy E1, ElemTy E2) {
Nick Lewycky51ce8d62006-09-13 19:24:01 +0000156 if (swo(E2, E1)) std::swap(E1, E2);
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000157
Nick Lewycky51ce8d62006-09-13 19:24:01 +0000158 iterator I1 = findLeader(E1),
159 I2 = findLeader(E2);
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000160
161 if (!I1 && !I2) { // neither entry is in yet
162 leaders.push_back(E1);
163 I1 = leaders.size();
164 mapping[E1] = I1;
165 mapping[E2] = I1;
Nick Lewycky51ce8d62006-09-13 19:24:01 +0000166 return 0;
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000167 }
168
169 if (!I1 && I2) {
170 mapping[E1] = I2;
Nick Lewycky51ce8d62006-09-13 19:24:01 +0000171 std::swap(getLeader(I2), E1);
172 return 0;
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000173 }
174
175 if (I1 && !I2) {
176 mapping[E2] = I1;
Nick Lewycky51ce8d62006-09-13 19:24:01 +0000177 return 0;
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000178 }
179
Nick Lewycky51ce8d62006-09-13 19:24:01 +0000180 if (I1 == I2) return 0;
181
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000182 // This is the case where we have two sets, [%a1, %a2, %a3] and
183 // [%p1, %p2, %p3] and someone says that %a2 == %p3. We need to
184 // combine the two synsets.
185
Nick Lewycky51ce8d62006-09-13 19:24:01 +0000186 if (I1 > I2) --I1;
187
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000188 for (std::map<Value *, unsigned>::iterator I = mapping.begin(),
189 E = mapping.end(); I != E; ++I) {
190 if (I->second == I2) I->second = I1;
191 else if (I->second > I2) --I->second;
192 }
193
194 leaders.erase(leaders.begin() + I2 - 1);
195
Nick Lewycky51ce8d62006-09-13 19:24:01 +0000196 return I2;
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000197 }
198
199 /// Returns an iterator pointing to the synonym set containing
200 /// element e. If none exists, a new one is created and returned.
201 iterator findOrInsert(ElemTy e) {
202 iterator I = findLeader(e);
203 if (I) return I;
204
205 leaders.push_back(e);
206 I = leaders.size();
207 mapping[e] = I;
208 return I;
209 }
210 };
211
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000212 /// Represents the set of equivalent Value*s and provides insertion
213 /// and fast lookup. Also stores the set of inequality relationships.
214 class PropertySet {
215 struct Property;
216 public:
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000217 class Synonyms<Value *, compare> union_find;
218
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000219 typedef std::vector<Property>::iterator PropertyIterator;
220 typedef std::vector<Property>::const_iterator ConstPropertyIterator;
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000221 typedef Synonyms<Value *, compare>::iterator SynonymIterator;
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000222
223 enum Ops {
224 EQ,
225 NE
226 };
227
228 Value *canonicalize(Value *V) const {
229 Value *C = lookup(V);
230 return C ? C : V;
231 }
232
233 Value *lookup(Value *V) const {
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000234 Synonyms<Value *, compare>::iterator SI = union_find.findLeader(V);
235 if (!SI) return NULL;
236 return union_find.getLeader(SI);
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000237 }
238
239 bool empty() const {
Nick Lewycky5f8f9af2006-08-30 02:46:48 +0000240 return union_find.empty();
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000241 }
242
243 void addEqual(Value *V1, Value *V2) {
Nick Lewycky8e559932006-09-02 19:40:38 +0000244 // If %x = 0. and %y = -0., seteq %x, %y is true, but
245 // copysign(%x) is not the same as copysign(%y).
Nick Lewycky51ce8d62006-09-13 19:24:01 +0000246 if (V1->getType()->isFloatingPoint()) return;
Nick Lewycky8e559932006-09-02 19:40:38 +0000247
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000248 order(V1, V2);
249 if (isa<Constant>(V2)) return; // refuse to set false == true.
250
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000251 SynonymIterator deleted = union_find.unionSets(V1, V2);
252 if (deleted) {
253 SynonymIterator replacement = union_find.findLeader(V1);
254 // Move Properties
255 for (PropertyIterator I = Properties.begin(), E = Properties.end();
256 I != E; ++I) {
257 if (I->I1 == deleted) I->I1 = replacement;
258 else if (I->I1 > deleted) --I->I1;
259 if (I->I2 == deleted) I->I2 = replacement;
260 else if (I->I2 > deleted) --I->I2;
261 }
262 }
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000263 addImpliedProperties(EQ, V1, V2);
264 }
265
266 void addNotEqual(Value *V1, Value *V2) {
Nick Lewycky8e559932006-09-02 19:40:38 +0000267 // If %x = NAN then seteq %x, %x is false.
Nick Lewycky51ce8d62006-09-13 19:24:01 +0000268 if (V1->getType()->isFloatingPoint()) return;
269
270 // For example, %x = setne int 0, 0 causes "0 != 0".
271 if (isa<Constant>(V1) && isa<Constant>(V2)) return;
Nick Lewycky8e559932006-09-02 19:40:38 +0000272
Nick Lewycky08674ab2006-08-31 00:39:16 +0000273 if (findProperty(NE, V1, V2) != Properties.end())
274 return; // found.
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000275
276 // Add the property.
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000277 SynonymIterator I1 = union_find.findOrInsert(V1),
278 I2 = union_find.findOrInsert(V2);
Nick Lewycky51ce8d62006-09-13 19:24:01 +0000279
280 // Technically this means that the block is unreachable.
281 if (I1 == I2) return;
282
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000283 Properties.push_back(Property(NE, I1, I2));
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000284 addImpliedProperties(NE, V1, V2);
285 }
286
287 PropertyIterator findProperty(Ops Opcode, Value *V1, Value *V2) {
288 assert(Opcode != EQ && "Can't findProperty on EQ."
289 "Use the lookup method instead.");
290
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000291 SynonymIterator I1 = union_find.findLeader(V1),
292 I2 = union_find.findLeader(V2);
293 if (!I1 || !I2) return Properties.end();
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000294
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000295 return
296 find(Properties.begin(), Properties.end(), Property(Opcode, I1, I2));
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000297 }
298
299 ConstPropertyIterator
300 findProperty(Ops Opcode, Value *V1, Value *V2) const {
301 assert(Opcode != EQ && "Can't findProperty on EQ."
302 "Use the lookup method instead.");
303
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000304 SynonymIterator I1 = union_find.findLeader(V1),
305 I2 = union_find.findLeader(V2);
306 if (!I1 || !I2) return Properties.end();
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000307
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000308 return
309 find(Properties.begin(), Properties.end(), Property(Opcode, I1, I2));
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000310 }
311
312 private:
313 // Represents Head OP [Tail1, Tail2, ...]
314 // For example: %x != %a, %x != %b.
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000315 struct VISIBILITY_HIDDEN Property {
316 typedef Synonyms<Value *, compare>::iterator Iter;
317
318 Property(Ops opcode, Iter i1, Iter i2)
319 : Opcode(opcode), I1(i1), I2(i2)
Nick Lewycky8e559932006-09-02 19:40:38 +0000320 { assert(opcode != EQ && "Equality belongs in the synonym set, "
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000321 "not a property."); }
322
323 bool operator==(const Property &P) const {
324 return (Opcode == P.Opcode) &&
325 ((I1 == P.I1 && I2 == P.I2) ||
326 (I1 == P.I2 && I2 == P.I1));
327 }
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000328
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000329 Ops Opcode;
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000330 Iter I1, I2;
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000331 };
332
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000333 void add(Ops Opcode, Value *V1, Value *V2, bool invert) {
334 switch (Opcode) {
335 case EQ:
336 if (invert) addNotEqual(V1, V2);
337 else addEqual(V1, V2);
338 break;
339 case NE:
340 if (invert) addEqual(V1, V2);
341 else addNotEqual(V1, V2);
342 break;
343 default:
344 assert(0 && "Unknown property opcode.");
345 }
346 }
347
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000348 // Finds the properties implied by an equivalence and adds them too.
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000349 // Example: ("seteq %a, %b", true, EQ) --> (%a, %b, EQ)
350 // ("seteq %a, %b", false, EQ) --> (%a, %b, NE)
351 void addImpliedProperties(Ops Opcode, Value *V1, Value *V2) {
352 order(V1, V2);
353
354 if (BinaryOperator *BO = dyn_cast<BinaryOperator>(V2)) {
355 switch (BO->getOpcode()) {
356 case Instruction::SetEQ:
357 if (V1 == ConstantBool::True)
358 add(Opcode, BO->getOperand(0), BO->getOperand(1), false);
359 if (V1 == ConstantBool::False)
360 add(Opcode, BO->getOperand(0), BO->getOperand(1), true);
361 break;
362 case Instruction::SetNE:
363 if (V1 == ConstantBool::True)
364 add(Opcode, BO->getOperand(0), BO->getOperand(1), true);
365 if (V1 == ConstantBool::False)
366 add(Opcode, BO->getOperand(0), BO->getOperand(1), false);
367 break;
368 case Instruction::SetLT:
369 case Instruction::SetGT:
370 if (V1 == ConstantBool::True)
371 add(Opcode, BO->getOperand(0), BO->getOperand(1), true);
372 break;
373 case Instruction::SetLE:
374 case Instruction::SetGE:
375 if (V1 == ConstantBool::False)
376 add(Opcode, BO->getOperand(0), BO->getOperand(1), true);
377 break;
378 case Instruction::And:
379 if (V1 == ConstantBool::True) {
380 add(Opcode, ConstantBool::True, BO->getOperand(0), false);
381 add(Opcode, ConstantBool::True, BO->getOperand(1), false);
382 }
383 break;
384 case Instruction::Or:
385 if (V1 == ConstantBool::False) {
386 add(Opcode, ConstantBool::False, BO->getOperand(0), false);
387 add(Opcode, ConstantBool::False, BO->getOperand(1), false);
388 }
389 break;
390 case Instruction::Xor:
391 if (V1 == ConstantBool::True) {
392 if (BO->getOperand(0) == ConstantBool::True)
393 add(Opcode, ConstantBool::False, BO->getOperand(1), false);
394 if (BO->getOperand(1) == ConstantBool::True)
395 add(Opcode, ConstantBool::False, BO->getOperand(0), false);
396 }
397 if (V1 == ConstantBool::False) {
398 if (BO->getOperand(0) == ConstantBool::True)
399 add(Opcode, ConstantBool::True, BO->getOperand(1), false);
400 if (BO->getOperand(1) == ConstantBool::True)
401 add(Opcode, ConstantBool::True, BO->getOperand(0), false);
402 }
403 break;
404 default:
405 break;
406 }
Nick Lewycky8e559932006-09-02 19:40:38 +0000407 } else if (SelectInst *SI = dyn_cast<SelectInst>(V2)) {
408 if (Opcode != EQ && Opcode != NE) return;
409
410 ConstantBool *True = (Opcode==EQ) ? ConstantBool::True
411 : ConstantBool::False,
412 *False = (Opcode==EQ) ? ConstantBool::False
413 : ConstantBool::True;
414
415 if (V1 == SI->getTrueValue())
416 addEqual(SI->getCondition(), True);
417 else if (V1 == SI->getFalseValue())
418 addEqual(SI->getCondition(), False);
419 else if (Opcode == EQ)
420 assert("Result of select not equal to either value.");
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000421 }
422 }
423
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000424 public:
Nick Lewycky8e559932006-09-02 19:40:38 +0000425#ifdef DEBUG
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000426 void debug(std::ostream &os) const {
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000427 static const char *OpcodeTable[] = { "EQ", "NE" };
428
Nick Lewycky12efffc2006-09-13 19:32:53 +0000429 unsigned int size = union_find.countLeaders();
430
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000431 union_find.debug(os);
432 for (std::vector<Property>::const_iterator I = Properties.begin(),
433 E = Properties.end(); I != E; ++I) {
434 os << (*I).I1 << " " << OpcodeTable[(*I).Opcode] << " "
435 << (*I).I2 << "\n";
Nick Lewycky08674ab2006-08-31 00:39:16 +0000436 }
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000437 os << "\n";
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000438 }
Nick Lewycky8e559932006-09-02 19:40:38 +0000439#endif
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000440
441 std::vector<Property> Properties;
442 };
443
444 /// PredicateSimplifier - This class is a simplifier that replaces
445 /// one equivalent variable with another. It also tracks what
446 /// can't be equal and will solve setcc instructions when possible.
447 class PredicateSimplifier : public FunctionPass {
448 public:
449 bool runOnFunction(Function &F);
450 virtual void getAnalysisUsage(AnalysisUsage &AU) const;
451
452 private:
453 // Try to replace the Use of the instruction with something simpler.
454 Value *resolve(SetCondInst *SCI, const PropertySet &);
455 Value *resolve(BinaryOperator *BO, const PropertySet &);
Nick Lewycky5f8f9af2006-08-30 02:46:48 +0000456 Value *resolve(SelectInst *SI, const PropertySet &);
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000457 Value *resolve(Value *V, const PropertySet &);
458
459 // Used by terminator instructions to proceed from the current basic
460 // block to the next. Verifies that "current" dominates "next",
461 // then calls visitBasicBlock.
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000462 void proceedToSuccessor(TerminatorInst *TI, unsigned edge,
463 PropertySet &CurrentPS, PropertySet &NextPS);
464 void proceedToSuccessors(PropertySet &CurrentPS, BasicBlock *Current);
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000465
466 // Visits each instruction in the basic block.
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000467 void visitBasicBlock(BasicBlock *Block, PropertySet &KnownProperties);
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000468
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000469 // Tries to simplify each Instruction and add new properties to
470 // the PropertySet. Returns true if it erase the instruction.
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000471 void visitInstruction(Instruction *I, PropertySet &);
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000472 // For each instruction, add the properties to KnownProperties.
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000473
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000474 void visit(TerminatorInst *TI, PropertySet &);
475 void visit(BranchInst *BI, PropertySet &);
476 void visit(SwitchInst *SI, PropertySet);
477 void visit(LoadInst *LI, PropertySet &);
478 void visit(StoreInst *SI, PropertySet &);
479 void visit(BinaryOperator *BO, PropertySet &);
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000480
481 DominatorTree *DT;
482 bool modified;
483 };
484
485 RegisterPass<PredicateSimplifier> X("predsimplify",
486 "Predicate Simplifier");
487}
488
489FunctionPass *llvm::createPredicateSimplifierPass() {
490 return new PredicateSimplifier();
491}
492
493bool PredicateSimplifier::runOnFunction(Function &F) {
494 DT = &getAnalysis<DominatorTree>();
495
496 modified = false;
497 PropertySet KnownProperties;
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000498 visitBasicBlock(DT->getRootNode()->getBlock(), KnownProperties);
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000499 return modified;
500}
501
502void PredicateSimplifier::getAnalysisUsage(AnalysisUsage &AU) const {
503 AU.addRequired<DominatorTree>();
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000504 AU.setPreservesCFG();
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000505}
506
507// resolve catches cases addProperty won't because it wasn't used as a
508// condition in the branch, and that visit won't, because the instruction
Nick Lewycky8e559932006-09-02 19:40:38 +0000509// was defined outside of the scope that the properties apply to.
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000510Value *PredicateSimplifier::resolve(SetCondInst *SCI,
511 const PropertySet &KP) {
512 // Attempt to resolve the SetCondInst to a boolean.
513
Nick Lewycky8e559932006-09-02 19:40:38 +0000514 Value *SCI0 = resolve(SCI->getOperand(0), KP),
515 *SCI1 = resolve(SCI->getOperand(1), KP);
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000516
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000517 ConstantIntegral *CI1 = dyn_cast<ConstantIntegral>(SCI0),
518 *CI2 = dyn_cast<ConstantIntegral>(SCI1);
519
Nick Lewyckye94f42a2006-09-11 17:23:34 +0000520 if (!CI1 || !CI2) {
521 PropertySet::ConstPropertyIterator NE =
522 KP.findProperty(PropertySet::NE, SCI0, SCI1);
523
524 if (NE != KP.Properties.end()) {
525 switch (SCI->getOpcode()) {
526 case Instruction::SetEQ:
527 return ConstantBool::False;
528 case Instruction::SetNE:
529 return ConstantBool::True;
530 case Instruction::SetLE:
531 case Instruction::SetGE:
532 case Instruction::SetLT:
533 case Instruction::SetGT:
534 break;
535 default:
536 assert(0 && "Unknown opcode in SetCondInst.");
537 break;
538 }
539 }
540 return SCI;
541 }
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000542
543 switch(SCI->getOpcode()) {
544 case Instruction::SetLE:
545 case Instruction::SetGE:
546 case Instruction::SetEQ:
547 if (CI1->getRawValue() == CI2->getRawValue())
548 return ConstantBool::True;
549 else
550 return ConstantBool::False;
551 case Instruction::SetLT:
552 case Instruction::SetGT:
553 case Instruction::SetNE:
554 if (CI1->getRawValue() == CI2->getRawValue())
555 return ConstantBool::False;
556 else
557 return ConstantBool::True;
558 default:
559 assert(0 && "Unknown opcode in SetContInst.");
560 break;
561 }
562}
563
564Value *PredicateSimplifier::resolve(BinaryOperator *BO,
565 const PropertySet &KP) {
566 if (SetCondInst *SCI = dyn_cast<SetCondInst>(BO))
567 return resolve(SCI, KP);
568
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000569 Value *lhs = resolve(BO->getOperand(0), KP),
570 *rhs = resolve(BO->getOperand(1), KP);
571 ConstantIntegral *CI1 = dyn_cast<ConstantIntegral>(lhs);
572 ConstantIntegral *CI2 = dyn_cast<ConstantIntegral>(rhs);
573
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000574 if (!CI1 || !CI2) return BO;
575
576 Value *V = ConstantExpr::get(BO->getOpcode(), CI1, CI2);
577 if (V) return V;
578 return BO;
579}
580
Nick Lewycky5f8f9af2006-08-30 02:46:48 +0000581Value *PredicateSimplifier::resolve(SelectInst *SI, const PropertySet &KP) {
582 Value *Condition = resolve(SI->getCondition(), KP);
583 if (Condition == ConstantBool::True)
584 return resolve(SI->getTrueValue(), KP);
585 else if (Condition == ConstantBool::False)
586 return resolve(SI->getFalseValue(), KP);
587 return SI;
588}
589
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000590Value *PredicateSimplifier::resolve(Value *V, const PropertySet &KP) {
591 if (isa<Constant>(V) || isa<BasicBlock>(V) || KP.empty()) return V;
592
593 V = KP.canonicalize(V);
594
595 if (BinaryOperator *BO = dyn_cast<BinaryOperator>(V))
596 return resolve(BO, KP);
Nick Lewycky5f8f9af2006-08-30 02:46:48 +0000597 else if (SelectInst *SI = dyn_cast<SelectInst>(V))
598 return resolve(SI, KP);
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000599
600 return V;
601}
602
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000603void PredicateSimplifier::visitBasicBlock(BasicBlock *BB,
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000604 PropertySet &KnownProperties) {
Nick Lewycky3a4dc7b2006-09-13 18:55:37 +0000605 for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E;) {
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000606 visitInstruction(I++, KnownProperties);
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000607 }
608}
609
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000610void PredicateSimplifier::visitInstruction(Instruction *I,
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000611 PropertySet &KnownProperties) {
Nick Lewycky9a22d7b2006-09-10 02:27:07 +0000612 // Try to replace the whole instruction.
Nick Lewycky8e559932006-09-02 19:40:38 +0000613 Value *V = resolve(I, KnownProperties);
Nick Lewycky8e559932006-09-02 19:40:38 +0000614 if (V != I) {
615 modified = true;
616 ++NumInstruction;
617 I->replaceAllUsesWith(V);
Nick Lewycky3a4dc7b2006-09-13 18:55:37 +0000618 I->eraseFromParent();
Nick Lewycky8e559932006-09-02 19:40:38 +0000619 return;
620 }
621
622 // Try to substitute operands.
623 for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000624 Value *Oper = I->getOperand(i);
625 Value *V = resolve(Oper, KnownProperties);
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000626 if (V != Oper) {
627 modified = true;
628 ++NumVarsReplaced;
629 DEBUG(std::cerr << "resolving " << *I);
630 I->setOperand(i, V);
631 DEBUG(std::cerr << "into " << *I);
632 }
633 }
634
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000635 if (TerminatorInst *TI = dyn_cast<TerminatorInst>(I))
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000636 visit(TI, KnownProperties);
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000637 else if (LoadInst *LI = dyn_cast<LoadInst>(I))
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000638 visit(LI, KnownProperties);
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000639 else if (StoreInst *SI = dyn_cast<StoreInst>(I))
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000640 visit(SI, KnownProperties);
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000641 else if (BinaryOperator *BO = dyn_cast<BinaryOperator>(I))
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000642 visit(BO, KnownProperties);
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000643}
644
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000645// The basic block on the target of the specified edge must be known
646// to be immediately dominated by the parent of the TerminatorInst.
647void PredicateSimplifier::proceedToSuccessor(TerminatorInst *TI,
648 unsigned edge,
649 PropertySet &CurrentPS,
650 PropertySet &NextPS) {
651 assert(edge < TI->getNumSuccessors() && "Invalid index for edge.");
652
653 BasicBlock *BB = TI->getParent(),
654 *BBNext = TI->getSuccessor(edge);
655
656 if (BBNext->getSinglePredecessor() == BB)
657 visitBasicBlock(BBNext, NextPS);
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000658 else
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000659 visitBasicBlock(BBNext, CurrentPS);
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000660}
661
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000662void PredicateSimplifier::proceedToSuccessors(PropertySet &KP,
663 BasicBlock *BBCurrent) {
664 DTNodeType *Current = DT->getNode(BBCurrent);
665 for (DTNodeType::iterator I = Current->begin(), E = Current->end();
666 I != E; ++I) {
667 PropertySet Copy(KP);
668 visitBasicBlock((*I)->getBlock(), Copy);
669 }
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000670}
671
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000672void PredicateSimplifier::visit(TerminatorInst *TI, PropertySet &KP) {
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000673 if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000674 visit(BI, KP);
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000675 return;
676 }
677 if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000678 visit(SI, KP);
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000679 return;
680 }
681
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000682 proceedToSuccessors(KP, TI->getParent());
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000683}
684
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000685void PredicateSimplifier::visit(BranchInst *BI, PropertySet &KP) {
686 BasicBlock *BB = BI->getParent();
687
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000688 if (BI->isUnconditional()) {
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000689 proceedToSuccessors(KP, BB);
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000690 return;
691 }
692
693 Value *Condition = BI->getCondition();
694
Nick Lewycky5f8f9af2006-08-30 02:46:48 +0000695 BasicBlock *TrueDest = BI->getSuccessor(0),
696 *FalseDest = BI->getSuccessor(1);
697
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000698 if (Condition == ConstantBool::True || TrueDest == FalseDest) {
699 proceedToSuccessors(KP, BB);
Nick Lewycky5f8f9af2006-08-30 02:46:48 +0000700 return;
701 } else if (Condition == ConstantBool::False) {
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000702 proceedToSuccessors(KP, BB);
Nick Lewycky5f8f9af2006-08-30 02:46:48 +0000703 return;
704 }
705
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000706 DTNodeType *Node = DT->getNode(BB);
707 for (DTNodeType::iterator I = Node->begin(), E = Node->end(); I != E; ++I) {
708 if ((*I)->getBlock() == TrueDest) {
709 PropertySet TrueProperties(KP);
710 TrueProperties.addEqual(ConstantBool::True, Condition);
711 proceedToSuccessor(BI, 0, KP, TrueProperties);
712 continue;
713 }
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000714
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000715 if ((*I)->getBlock() == FalseDest) {
716 PropertySet FalseProperties(KP);
717 FalseProperties.addEqual(ConstantBool::False, Condition);
718 proceedToSuccessor(BI, 1, KP, FalseProperties);
719 continue;
720 }
721
722 visitBasicBlock((*I)->getBlock(), KP);
723 }
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000724}
725
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000726void PredicateSimplifier::visit(SwitchInst *SI, PropertySet KP) {
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000727 Value *Condition = SI->getCondition();
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000728
729 // Set the EQProperty in each of the cases BBs,
730 // and the NEProperties in the default BB.
731 PropertySet DefaultProperties(KP);
732
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000733 DTNodeType *Node = DT->getNode(SI->getParent());
734 for (DTNodeType::iterator I = Node->begin(), E = Node->end(); I != E; ++I) {
735 BasicBlock *BB = (*I)->getBlock();
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000736
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000737 PropertySet Copy(KP);
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000738
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000739 if (BB == SI->getDefaultDest()) {
740 PropertySet NewProperties(KP);
741 for (unsigned i = 1, e = SI->getNumCases(); i < e; ++i)
742 NewProperties.addNotEqual(Condition, SI->getCaseValue(i));
743
744 proceedToSuccessor(SI, 0, Copy, NewProperties);
745 } else if (ConstantInt *CI = SI->findCaseDest(BB)) {
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000746 PropertySet NewProperties(KP);
747 NewProperties.addEqual(Condition, CI);
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000748 proceedToSuccessor(SI, SI->findCaseValue(CI), Copy, NewProperties);
749 } else
750 visitBasicBlock(BB, Copy);
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000751 }
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000752}
753
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000754void PredicateSimplifier::visit(LoadInst *LI, PropertySet &KP) {
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000755 Value *Ptr = LI->getPointerOperand();
756 KP.addNotEqual(Constant::getNullValue(Ptr->getType()), Ptr);
757}
758
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000759void PredicateSimplifier::visit(StoreInst *SI, PropertySet &KP) {
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000760 Value *Ptr = SI->getPointerOperand();
761 KP.addNotEqual(Constant::getNullValue(Ptr->getType()), Ptr);
762}
763
Nick Lewyckyb9c54832006-09-18 21:09:35 +0000764void PredicateSimplifier::visit(BinaryOperator *BO, PropertySet &KP) {
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000765 Instruction::BinaryOps ops = BO->getOpcode();
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000766
Nick Lewycky5f8f9af2006-08-30 02:46:48 +0000767 switch (ops) {
768 case Instruction::Div:
769 case Instruction::Rem: {
770 Value *Divisor = BO->getOperand(1);
771 KP.addNotEqual(Constant::getNullValue(Divisor->getType()), Divisor);
772 break;
773 }
774 default:
775 break;
776 }
Nick Lewyckyb2e8ae12006-08-28 22:44:55 +0000777}