blob: 4f11ca9525836cd037624a7c06a4f833866920d4 [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
26// conditional that assures us of that fact. Equivalent variables are
27// called SynSets; sets of synonyms. We maintain a mapping from Value *
28// to the SynSet, and the SynSet maintains the best canonical form of the
29// Value.
30//
31// Properties are stored as relationships between two SynSets.
32//
33//===------------------------------------------------------------------===//
34
35// TODO:
36// * Handle SelectInst
37// * Switch to EquivalenceClasses ADT
38// * Check handling of NAN in floating point types
39// * Don't descend into false side of branches with ConstantBool condition.
40
41#define DEBUG_TYPE "predsimplify"
42#include "llvm/Transforms/Scalar.h"
43#include "llvm/Constants.h"
44#include "llvm/Instructions.h"
45#include "llvm/Pass.h"
46#include "llvm/ADT/Statistic.h"
47#include "llvm/ADT/STLExtras.h"
48#include "llvm/Analysis/Dominators.h"
49#include "llvm/Support/CFG.h"
50#include "llvm/Support/Debug.h"
51#include <iostream>
52using namespace llvm;
53
54namespace {
55 Statistic<>
56 NumVarsReplaced("predsimplify", "Number of argument substitutions");
57 Statistic<>
58 NumResolved("predsimplify", "Number of instruction substitutions");
59 Statistic<>
60 NumSwitchCases("predsimplify", "Number of switch cases removed");
61
62 /// Used for choosing the canonical Value in a synonym set.
63 /// Leaves the better one in V1. Returns whether a swap took place.
64 static void order(Value *&V1, Value *&V2) {
65 if (isa<Constant>(V2)) {
66 if (!isa<Constant>(V1)) {
67 std::swap(V1, V2);
68 return;
69 }
70 } else if (isa<Argument>(V2)) {
71 if (!isa<Constant>(V1) && !isa<Argument>(V1)) {
72 std::swap(V1, V2);
73 return;
74 }
75 }
76 if (User *U1 = dyn_cast<User>(V1)) {
77 for (User::const_op_iterator I = U1->op_begin(), E = U1->op_end();
78 I != E; ++I) {
79 if (*I == V2) {
80 std::swap(V1, V2);
81 return;
82 }
83 }
84 }
85 return;
86 }
87
88 /// Represents the set of equivalent Value*s and provides insertion
89 /// and fast lookup. Also stores the set of inequality relationships.
90 class PropertySet {
91 struct Property;
92 public:
93 typedef unsigned SynSet;
94 typedef std::map<Value*, unsigned>::iterator SynonymIterator;
95 typedef std::map<Value*, unsigned>::const_iterator ConstSynonymIterator;
96 typedef std::vector<Property>::iterator PropertyIterator;
97 typedef std::vector<Property>::const_iterator ConstPropertyIterator;
98
99 enum Ops {
100 EQ,
101 NE
102 };
103
104 Value *canonicalize(Value *V) const {
105 Value *C = lookup(V);
106 return C ? C : V;
107 }
108
109 Value *lookup(Value *V) const {
110 ConstSynonymIterator SI = SynonymMap.find(V);
111 if (SI == SynonymMap.end()) return NULL;
112
113 return Synonyms[SI->second];
114 }
115
116 Value *lookup(SynSet SS) const {
117 assert(SS < Synonyms.size());
118 return Synonyms[SS];
119 }
120
121 // Find a SynSet for a given Value.
122 //
123 // Given the Value *V sets SS to a valid SynSet. Returns true if it
124 // found it.
125 bool findSynSet(Value *V, SynSet &SS) const {
126 ConstSynonymIterator SI = SynonymMap.find(V);
127 if (SI != SynonymMap.end()) {
128 SS = SI->second;
129 return true;
130 }
131
132 std::vector<Value *>::const_iterator I =
133 std::find(Synonyms.begin(), Synonyms.end(), V);
134 if (I != Synonyms.end()) {
135 SS = I-Synonyms.begin();
136 return true;
137 }
138
139 return false;
140 }
141
142 bool empty() const {
143 return Synonyms.empty();
144 }
145
146 void addEqual(Value *V1, Value *V2) {
147 order(V1, V2);
148 if (isa<Constant>(V2)) return; // refuse to set false == true.
149
150 V1 = canonicalize(V1);
151 V2 = canonicalize(V2);
152
153 if (V1 == V2) return; // already equivalent.
154
155 SynSet I1, I2;
156 bool F1 = findSynSet(V1, I1),
157 F2 = findSynSet(V2, I2);
158
159 DEBUG(std::cerr << "V1: " << *V1 << " I1: " << I1
160 << " F1: " << F1 << "\n");
161 DEBUG(std::cerr << "V2: " << *V2 << " I2: " << I2
162 << " F2: " << F2 << "\n");
163
164 if (!F1 && !F2) {
165 SynSet SS = addSynSet(V1);
166 SynonymMap[V1] = SS;
167 SynonymMap[V2] = SS;
168 }
169
170 else if (!F1 && F2) {
171 SynonymMap[V1] = I2;
172 }
173
174 else if (F1 && !F2) {
175 SynonymMap[V2] = I1;
176 }
177
178 else {
179 // This is the case where we have two sets, [%a1, %a2, %a3] and
180 // [%p1, %p2, %p3] and someone says that %a2 == %p3. We need to
181 // combine the two synsets.
182
183 // Collapse synonyms of V2 into V1.
184 for (SynonymIterator I = SynonymMap.begin(), E = SynonymMap.end();
185 I != E; ++I) {
186 if (I->second == I2) I->second = I1;
187 else if (I->second > I2) --I->second;
188 }
189
190 // Move Properties
191 for (PropertyIterator I = Properties.begin(), E = Properties.end();
192 I != E; ++I) {
193 if (I->S1 == I2) I->S1 = I1;
194 else if (I->S1 > I2) --I->S1;
195 if (I->S2 == I2) I->S2 = I1;
196 else if (I->S2 > I2) --I->S2;
197 }
198
199 // Remove the synonym
200 Synonyms.erase(Synonyms.begin() + I2);
201 }
202
203 addImpliedProperties(EQ, V1, V2);
204 }
205
206 void addNotEqual(Value *V1, Value *V2) {
207 DEBUG(std::cerr << "not equal: " << *V1 << " and " << *V2 << "\n");
208 bool skip_search = false;
209 V1 = canonicalize(V1);
210 V2 = canonicalize(V2);
211
212 SynSet S1, S2;
213 if (!findSynSet(V1, S1)) {
214 skip_search = true;
215 S1 = addSynSet(V1);
216 }
217 if (!findSynSet(V2, S2)) {
218 skip_search = true;
219 S2 = addSynSet(V2);
220 }
221
222 if (!skip_search) {
223 // Does the property already exist?
224 for (PropertyIterator I = Properties.begin(), E = Properties.end();
225 I != E; ++I) {
226 if (I->Opcode != NE) continue;
227
228 if ((I->S1 == S1 && I->S2 == S2) ||
229 (I->S1 == S2 && I->S2 == S1)) {
230 return; // Found.
231 }
232 }
233 }
234
235 // Add the property.
236 Properties.push_back(Property(NE, S1, S2));
237 addImpliedProperties(NE, V1, V2);
238 }
239
240 PropertyIterator findProperty(Ops Opcode, Value *V1, Value *V2) {
241 assert(Opcode != EQ && "Can't findProperty on EQ."
242 "Use the lookup method instead.");
243
244 SynSet S1, S2;
245 if (!findSynSet(V1, S1)) return Properties.end();
246 if (!findSynSet(V2, S2)) return Properties.end();
247
248 // Does the property already exist?
249 for (PropertyIterator I = Properties.begin(), E = Properties.end();
250 I != E; ++I) {
251 if (I->Opcode != Opcode) continue;
252
253 if ((I->S1 == S1 && I->S2 == S2) ||
254 (I->S1 == S2 && I->S2 == S1)) {
255 return I; // Found.
256 }
257 }
258 return Properties.end();
259 }
260
261 ConstPropertyIterator
262 findProperty(Ops Opcode, Value *V1, Value *V2) const {
263 assert(Opcode != EQ && "Can't findProperty on EQ."
264 "Use the lookup method instead.");
265
266 SynSet S1, S2;
267 if (!findSynSet(V1, S1)) return Properties.end();
268 if (!findSynSet(V2, S2)) return Properties.end();
269
270 // Does the property already exist?
271 for (ConstPropertyIterator I = Properties.begin(),
272 E = Properties.end(); I != E; ++I) {
273 if (I->Opcode != Opcode) continue;
274
275 if ((I->S1 == S1 && I->S2 == S2) ||
276 (I->S1 == S2 && I->S2 == S1)) {
277 return I; // Found.
278 }
279 }
280 return Properties.end();
281 }
282
283 private:
284 // Represents Head OP [Tail1, Tail2, ...]
285 // For example: %x != %a, %x != %b.
286 struct Property {
287 Property(Ops opcode, SynSet s1, SynSet s2)
288 : Opcode(opcode), S1(s1), S2(s2)
289 { assert(opcode != EQ && "Equality belongs in the synonym set,"
290 "not a property."); }
291
292 bool operator<(const Property &rhs) const {
293 if (Opcode != rhs.Opcode) return Opcode < rhs.Opcode;
294 if (S1 != rhs.S1) return S1 < rhs.S1;
295 return S2 < rhs.S2;
296 }
297
298 Ops Opcode;
299 SynSet S1, S2;
300 };
301
302 SynSet addSynSet(Value *V) {
303 Synonyms.push_back(V);
304 return Synonyms.size()-1;
305 }
306
307 void add(Ops Opcode, Value *V1, Value *V2, bool invert) {
308 switch (Opcode) {
309 case EQ:
310 if (invert) addNotEqual(V1, V2);
311 else addEqual(V1, V2);
312 break;
313 case NE:
314 if (invert) addEqual(V1, V2);
315 else addNotEqual(V1, V2);
316 break;
317 default:
318 assert(0 && "Unknown property opcode.");
319 }
320 }
321
322 // Finds the properties implied by a synonym and adds them too.
323 // Example: ("seteq %a, %b", true, EQ) --> (%a, %b, EQ)
324 // ("seteq %a, %b", false, EQ) --> (%a, %b, NE)
325 void addImpliedProperties(Ops Opcode, Value *V1, Value *V2) {
326 order(V1, V2);
327
328 if (BinaryOperator *BO = dyn_cast<BinaryOperator>(V2)) {
329 switch (BO->getOpcode()) {
330 case Instruction::SetEQ:
331 if (V1 == ConstantBool::True)
332 add(Opcode, BO->getOperand(0), BO->getOperand(1), false);
333 if (V1 == ConstantBool::False)
334 add(Opcode, BO->getOperand(0), BO->getOperand(1), true);
335 break;
336 case Instruction::SetNE:
337 if (V1 == ConstantBool::True)
338 add(Opcode, BO->getOperand(0), BO->getOperand(1), true);
339 if (V1 == ConstantBool::False)
340 add(Opcode, BO->getOperand(0), BO->getOperand(1), false);
341 break;
342 case Instruction::SetLT:
343 case Instruction::SetGT:
344 if (V1 == ConstantBool::True)
345 add(Opcode, BO->getOperand(0), BO->getOperand(1), true);
346 break;
347 case Instruction::SetLE:
348 case Instruction::SetGE:
349 if (V1 == ConstantBool::False)
350 add(Opcode, BO->getOperand(0), BO->getOperand(1), true);
351 break;
352 case Instruction::And:
353 if (V1 == ConstantBool::True) {
354 add(Opcode, ConstantBool::True, BO->getOperand(0), false);
355 add(Opcode, ConstantBool::True, BO->getOperand(1), false);
356 }
357 break;
358 case Instruction::Or:
359 if (V1 == ConstantBool::False) {
360 add(Opcode, ConstantBool::False, BO->getOperand(0), false);
361 add(Opcode, ConstantBool::False, BO->getOperand(1), false);
362 }
363 break;
364 case Instruction::Xor:
365 if (V1 == ConstantBool::True) {
366 if (BO->getOperand(0) == ConstantBool::True)
367 add(Opcode, ConstantBool::False, BO->getOperand(1), false);
368 if (BO->getOperand(1) == ConstantBool::True)
369 add(Opcode, ConstantBool::False, BO->getOperand(0), false);
370 }
371 if (V1 == ConstantBool::False) {
372 if (BO->getOperand(0) == ConstantBool::True)
373 add(Opcode, ConstantBool::True, BO->getOperand(1), false);
374 if (BO->getOperand(1) == ConstantBool::True)
375 add(Opcode, ConstantBool::True, BO->getOperand(0), false);
376 }
377 break;
378 default:
379 break;
380 }
381 }
382 }
383
384 std::map<Value *, unsigned> SynonymMap;
385 std::vector<Value *> Synonyms;
386
387 public:
388 void debug(std::ostream &os) const {
389 os << Synonyms.size() << " synsets:\n";
390 for (unsigned I = 0, E = Synonyms.size(); I != E; ++I) {
391 os << I << ". " << *Synonyms[I] << "\n";
392 }
393 for (ConstSynonymIterator I = SynonymMap.begin(),E = SynonymMap.end();
394 I != E; ++I) {
395 os << *I->first << "-> #" << I->second << "\n";
396 }
397 os << Properties.size() << " properties:\n";
398 for (unsigned I = 0, E = Properties.size(); I != E; ++I) {
399 os << I << ". (" << Properties[I].Opcode << ","
400 << Properties[I].S1 << "," << Properties[I].S2 << ")\n";
401 }
402 }
403
404 std::vector<Property> Properties;
405 };
406
407 /// PredicateSimplifier - This class is a simplifier that replaces
408 /// one equivalent variable with another. It also tracks what
409 /// can't be equal and will solve setcc instructions when possible.
410 class PredicateSimplifier : public FunctionPass {
411 public:
412 bool runOnFunction(Function &F);
413 virtual void getAnalysisUsage(AnalysisUsage &AU) const;
414
415 private:
416 // Try to replace the Use of the instruction with something simpler.
417 Value *resolve(SetCondInst *SCI, const PropertySet &);
418 Value *resolve(BinaryOperator *BO, const PropertySet &);
419 Value *resolve(Value *V, const PropertySet &);
420
421 // Used by terminator instructions to proceed from the current basic
422 // block to the next. Verifies that "current" dominates "next",
423 // then calls visitBasicBlock.
424 void proceedToSuccessor(PropertySet &CurrentPS, PropertySet &NextPS,
425 DominatorTree::Node *Current, DominatorTree::Node *Next);
426 void proceedToSuccessor(PropertySet &CurrentPS,
427 DominatorTree::Node *Current, DominatorTree::Node *Next);
428
429 // Visits each instruction in the basic block.
430 void visitBasicBlock(DominatorTree::Node *DTNode,
431 PropertySet &KnownProperties);
432
433 // For each instruction, add the properties to KnownProperties.
434 void visit(Instruction *I, DominatorTree::Node *, PropertySet &);
435 void visit(TerminatorInst *TI, DominatorTree::Node *, PropertySet &);
436 void visit(BranchInst *BI, DominatorTree::Node *, PropertySet &);
437 void visit(SwitchInst *SI, DominatorTree::Node *, PropertySet);
438 void visit(LoadInst *LI, DominatorTree::Node *, PropertySet &);
439 void visit(StoreInst *SI, DominatorTree::Node *, PropertySet &);
440 void visit(BinaryOperator *BO, DominatorTree::Node *, PropertySet &);
441
442 DominatorTree *DT;
443 bool modified;
444 };
445
446 RegisterPass<PredicateSimplifier> X("predsimplify",
447 "Predicate Simplifier");
448}
449
450FunctionPass *llvm::createPredicateSimplifierPass() {
451 return new PredicateSimplifier();
452}
453
454bool PredicateSimplifier::runOnFunction(Function &F) {
455 DT = &getAnalysis<DominatorTree>();
456
457 modified = false;
458 PropertySet KnownProperties;
459 visitBasicBlock(DT->getRootNode(), KnownProperties);
460 return modified;
461}
462
463void PredicateSimplifier::getAnalysisUsage(AnalysisUsage &AU) const {
464 AU.addRequired<DominatorTree>();
465}
466
467// resolve catches cases addProperty won't because it wasn't used as a
468// condition in the branch, and that visit won't, because the instruction
469// was defined outside of the range that the properties apply to.
470Value *PredicateSimplifier::resolve(SetCondInst *SCI,
471 const PropertySet &KP) {
472 // Attempt to resolve the SetCondInst to a boolean.
473
474 Value *SCI0 = SCI->getOperand(0),
475 *SCI1 = SCI->getOperand(1);
476 PropertySet::ConstPropertyIterator NE =
477 KP.findProperty(PropertySet::NE, SCI0, SCI1);
478
479 if (NE != KP.Properties.end()) {
480 switch (SCI->getOpcode()) {
481 case Instruction::SetEQ:
482 return ConstantBool::False;
483 case Instruction::SetNE:
484 return ConstantBool::True;
485 case Instruction::SetLE:
486 case Instruction::SetGE:
487 case Instruction::SetLT:
488 case Instruction::SetGT:
489 break;
490 default:
491 assert(0 && "Unknown opcode in SetCondInst.");
492 break;
493 }
494 }
495
496 SCI0 = KP.canonicalize(SCI0);
497 SCI1 = KP.canonicalize(SCI1);
498
499 ConstantIntegral *CI1 = dyn_cast<ConstantIntegral>(SCI0),
500 *CI2 = dyn_cast<ConstantIntegral>(SCI1);
501
502 if (!CI1 || !CI2) return SCI;
503
504 switch(SCI->getOpcode()) {
505 case Instruction::SetLE:
506 case Instruction::SetGE:
507 case Instruction::SetEQ:
508 if (CI1->getRawValue() == CI2->getRawValue())
509 return ConstantBool::True;
510 else
511 return ConstantBool::False;
512 case Instruction::SetLT:
513 case Instruction::SetGT:
514 case Instruction::SetNE:
515 if (CI1->getRawValue() == CI2->getRawValue())
516 return ConstantBool::False;
517 else
518 return ConstantBool::True;
519 default:
520 assert(0 && "Unknown opcode in SetContInst.");
521 break;
522 }
523}
524
525Value *PredicateSimplifier::resolve(BinaryOperator *BO,
526 const PropertySet &KP) {
527 if (SetCondInst *SCI = dyn_cast<SetCondInst>(BO))
528 return resolve(SCI, KP);
529
530 DEBUG(std::cerr << "BO->getOperand(1) = " << *BO->getOperand(1) << "\n");
531
532 Value *lhs = resolve(BO->getOperand(0), KP),
533 *rhs = resolve(BO->getOperand(1), KP);
534 ConstantIntegral *CI1 = dyn_cast<ConstantIntegral>(lhs);
535 ConstantIntegral *CI2 = dyn_cast<ConstantIntegral>(rhs);
536
537 DEBUG(std::cerr << "resolveBO: lhs = " << *lhs
538 << ", rhs = " << *rhs << "\n");
539 if (CI1) DEBUG(std::cerr << "CI1 = " << *CI1);
540 if (CI2) DEBUG(std::cerr << "CI2 = " << *CI2);
541
542 if (!CI1 || !CI2) return BO;
543
544 Value *V = ConstantExpr::get(BO->getOpcode(), CI1, CI2);
545 if (V) return V;
546 return BO;
547}
548
549Value *PredicateSimplifier::resolve(Value *V, const PropertySet &KP) {
550 if (isa<Constant>(V) || isa<BasicBlock>(V) || KP.empty()) return V;
551
552 V = KP.canonicalize(V);
553
554 if (BinaryOperator *BO = dyn_cast<BinaryOperator>(V))
555 return resolve(BO, KP);
556
557 return V;
558}
559
560void PredicateSimplifier::visitBasicBlock(DominatorTree::Node *DTNode,
561 PropertySet &KnownProperties) {
562 BasicBlock *BB = DTNode->getBlock();
563 for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
564 visit(I, DTNode, KnownProperties);
565 }
566}
567
568void PredicateSimplifier::visit(Instruction *I, DominatorTree::Node *DTNode,
569 PropertySet &KnownProperties) {
570 DEBUG(std::cerr << "Considering instruction " << *I << "\n");
571 DEBUG(KnownProperties.debug(std::cerr));
572
573 // Substitute values known to be equal.
574 for (unsigned i = 0, E = I->getNumOperands(); i != E; ++i) {
575 Value *Oper = I->getOperand(i);
576 Value *V = resolve(Oper, KnownProperties);
577 assert(V && "resolve not supposed to return NULL.");
578 if (V != Oper) {
579 modified = true;
580 ++NumVarsReplaced;
581 DEBUG(std::cerr << "resolving " << *I);
582 I->setOperand(i, V);
583 DEBUG(std::cerr << "into " << *I);
584 }
585 }
586
587 Value *V = resolve(I, KnownProperties);
588 assert(V && "resolve not supposed to return NULL.");
589 if (V != I) {
590 modified = true;
591 ++NumResolved;
592 I->replaceAllUsesWith(V);
593 I->eraseFromParent();
594 }
595
596 if (TerminatorInst *TI = dyn_cast<TerminatorInst>(I))
597 visit(TI, DTNode, KnownProperties);
598 else if (LoadInst *LI = dyn_cast<LoadInst>(I))
599 visit(LI, DTNode, KnownProperties);
600 else if (StoreInst *SI = dyn_cast<StoreInst>(I))
601 visit(SI, DTNode, KnownProperties);
602 else if (BinaryOperator *BO = dyn_cast<BinaryOperator>(I))
603 visit(BO, DTNode, KnownProperties);
604}
605
606void PredicateSimplifier::proceedToSuccessor(PropertySet &CurrentPS,
607 PropertySet &NextPS, DominatorTree::Node *Current,
608 DominatorTree::Node *Next) {
609 if (Next->getBlock()->getSinglePredecessor() == Current->getBlock())
610 proceedToSuccessor(NextPS, Current, Next);
611 else
612 proceedToSuccessor(CurrentPS, Current, Next);
613}
614
615void PredicateSimplifier::proceedToSuccessor(PropertySet &KP,
616 DominatorTree::Node *Current, DominatorTree::Node *Next) {
617 if (Current->properlyDominates(Next))
618 visitBasicBlock(Next, KP);
619}
620
621void PredicateSimplifier::visit(TerminatorInst *TI,
622 DominatorTree::Node *Node, PropertySet &KP){
623 if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
624 visit(BI, Node, KP);
625 return;
626 }
627 if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
628 visit(SI, Node, KP);
629 return;
630 }
631
632 for (unsigned i = 0, E = TI->getNumSuccessors(); i != E; ++i) {
633 BasicBlock *BB = TI->getSuccessor(i);
634 PropertySet KPcopy(KP);
635 proceedToSuccessor(KPcopy, Node, DT->getNode(TI->getSuccessor(i)));
636 }
637}
638
639void PredicateSimplifier::visit(BranchInst *BI,
640 DominatorTree::Node *Node, PropertySet &KP){
641 if (BI->isUnconditional()) {
642 proceedToSuccessor(KP, Node, DT->getNode(BI->getSuccessor(0)));
643 return;
644 }
645
646 Value *Condition = BI->getCondition();
647
648 PropertySet TrueProperties(KP), FalseProperties(KP);
649 DEBUG(std::cerr << "true set:\n");
650 TrueProperties.addEqual(ConstantBool::True, Condition);
651 DEBUG(std::cerr << "false set:\n");
652 FalseProperties.addEqual(ConstantBool::False, Condition);
653
654 BasicBlock *TrueDest = BI->getSuccessor(0),
655 *FalseDest = BI->getSuccessor(1);
656
657 PropertySet KPcopy(KP);
658 proceedToSuccessor(KP, TrueProperties, Node, DT->getNode(TrueDest));
659 proceedToSuccessor(KPcopy, FalseProperties, Node, DT->getNode(FalseDest));
660}
661
662void PredicateSimplifier::visit(SwitchInst *SI,
663 DominatorTree::Node *DTNode, PropertySet KP) {
664 Value *Condition = SI->getCondition();
665
666 // If there's an NEProperty covering this SwitchInst, we may be able to
667 // eliminate one of the cases.
668 PropertySet::SynSet S;
669
670 if (KP.findSynSet(Condition, S)) {
671 for (PropertySet::ConstPropertyIterator I = KP.Properties.begin(),
672 E = KP.Properties.end(); I != E; ++I) {
673 if (I->Opcode != PropertySet::NE) continue;
674 if (I->S1 != S && I->S2 != S) continue;
675
676 // Is one side a number?
677 ConstantInt *CI = dyn_cast<ConstantInt>(KP.lookup(I->S1));
678 if (!CI) CI = dyn_cast<ConstantInt>(KP.lookup(I->S2));
679
680 if (CI) {
681 unsigned i = SI->findCaseValue(CI);
682 if (i != 0) {
683 SI->getSuccessor(i)->removePredecessor(SI->getParent());
684 SI->removeCase(i);
685 modified = true;
686 ++NumSwitchCases;
687 }
688 }
689 }
690 }
691
692 // Set the EQProperty in each of the cases BBs,
693 // and the NEProperties in the default BB.
694 PropertySet DefaultProperties(KP);
695
696 DominatorTree::Node *Node = DT->getNode(SI->getParent()),
697 *DefaultNode = DT->getNode(SI->getSuccessor(0));
698 if (!Node->dominates(DefaultNode)) DefaultNode = NULL;
699
700 for (unsigned I = 1, E = SI->getNumCases(); I < E; ++I) {
701 ConstantInt *CI = SI->getCaseValue(I);
702
703 BasicBlock *SuccBB = SI->getSuccessor(I);
704 PropertySet copy(KP);
705 if (SuccBB->getSinglePredecessor()) {
706 PropertySet NewProperties(KP);
707 NewProperties.addEqual(Condition, CI);
708 proceedToSuccessor(copy, NewProperties, DTNode, DT->getNode(SuccBB));
709 } else
710 proceedToSuccessor(copy, DTNode, DT->getNode(SuccBB));
711
712 if (DefaultNode)
713 DefaultProperties.addNotEqual(Condition, CI);
714 }
715
716 if (DefaultNode)
717 proceedToSuccessor(DefaultProperties, DTNode, DefaultNode);
718}
719
720void PredicateSimplifier::visit(LoadInst *LI,
721 DominatorTree::Node *, PropertySet &KP) {
722 Value *Ptr = LI->getPointerOperand();
723 KP.addNotEqual(Constant::getNullValue(Ptr->getType()), Ptr);
724}
725
726void PredicateSimplifier::visit(StoreInst *SI,
727 DominatorTree::Node *, PropertySet &KP) {
728 Value *Ptr = SI->getPointerOperand();
729 KP.addNotEqual(Constant::getNullValue(Ptr->getType()), Ptr);
730}
731
732void PredicateSimplifier::visit(BinaryOperator *BO,
733 DominatorTree::Node *, PropertySet &KP) {
734 Instruction::BinaryOps ops = BO->getOpcode();
735 if (ops != Instruction::Div && ops != Instruction::Rem) return;
736
737 Value *Divisor = BO->getOperand(1);
738 const Type *Ty = cast<Type>(Divisor->getType());
739 KP.addNotEqual(Constant::getNullValue(Ty), Divisor);
740
741 // Some other things we could do:
742 // In f=x*y, if x != 1 && y != 1 then f != x && f != y.
743 // In f=x+y, if x != 0 then f != y and if y != 0 then f != x.
744}