LLVM API Documentation
00001 //===-- PredicateSimplifier.cpp - Path Sensitive Simplifier ---------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // Path-sensitive optimizer. In a branch where x == y, replace uses of 00011 // x with y. Permits further optimization, such as the elimination of 00012 // the unreachable call: 00013 // 00014 // void test(int *p, int *q) 00015 // { 00016 // if (p != q) 00017 // return; 00018 // 00019 // if (*p != *q) 00020 // foo(); // unreachable 00021 // } 00022 // 00023 //===----------------------------------------------------------------------===// 00024 // 00025 // The InequalityGraph focusses on four properties; equals, not equals, 00026 // less-than and less-than-or-equals-to. The greater-than forms are also held 00027 // just to allow walking from a lesser node to a greater one. These properties 00028 // are stored in a lattice; LE can become LT or EQ, NE can become LT or GT. 00029 // 00030 // These relationships define a graph between values of the same type. Each 00031 // Value is stored in a map table that retrieves the associated Node. This 00032 // is how EQ relationships are stored; the map contains pointers from equal 00033 // Value to the same node. The node contains a most canonical Value* form 00034 // and the list of known relationships with other nodes. 00035 // 00036 // If two nodes are known to be inequal, then they will contain pointers to 00037 // each other with an "NE" relationship. If node getNode(%x) is less than 00038 // getNode(%y), then the %x node will contain <%y, GT> and %y will contain 00039 // <%x, LT>. This allows us to tie nodes together into a graph like this: 00040 // 00041 // %a < %b < %c < %d 00042 // 00043 // with four nodes representing the properties. The InequalityGraph provides 00044 // querying with "isRelatedBy" and mutators "addEquality" and "addInequality". 00045 // To find a relationship, we start with one of the nodes any binary search 00046 // through its list to find where the relationships with the second node start. 00047 // Then we iterate through those to find the first relationship that dominates 00048 // our context node. 00049 // 00050 // To create these properties, we wait until a branch or switch instruction 00051 // implies that a particular value is true (or false). The VRPSolver is 00052 // responsible for analyzing the variable and seeing what new inferences 00053 // can be made from each property. For example: 00054 // 00055 // %P = icmp ne i32* %ptr, null 00056 // %a = and i1 %P, %Q 00057 // br i1 %a label %cond_true, label %cond_false 00058 // 00059 // For the true branch, the VRPSolver will start with %a EQ true and look at 00060 // the definition of %a and find that it can infer that %P and %Q are both 00061 // true. From %P being true, it can infer that %ptr NE null. For the false 00062 // branch it can't infer anything from the "and" instruction. 00063 // 00064 // Besides branches, we can also infer properties from instruction that may 00065 // have undefined behaviour in certain cases. For example, the dividend of 00066 // a division may never be zero. After the division instruction, we may assume 00067 // that the dividend is not equal to zero. 00068 // 00069 //===----------------------------------------------------------------------===// 00070 // 00071 // The ValueRanges class stores the known integer bounds of a Value. When we 00072 // encounter i8 %a u< %b, the ValueRanges stores that %a = [1, 255] and 00073 // %b = [0, 254]. 00074 // 00075 // It never stores an empty range, because that means that the code is 00076 // unreachable. It never stores a single-element range since that's an equality 00077 // relationship and better stored in the InequalityGraph, nor an empty range 00078 // since that is better stored in UnreachableBlocks. 00079 // 00080 //===----------------------------------------------------------------------===// 00081 00082 #define DEBUG_TYPE "predsimplify" 00083 #include "llvm/Transforms/Scalar.h" 00084 #include "llvm/Constants.h" 00085 #include "llvm/DerivedTypes.h" 00086 #include "llvm/Instructions.h" 00087 #include "llvm/Pass.h" 00088 #include "llvm/ADT/DepthFirstIterator.h" 00089 #include "llvm/ADT/SetOperations.h" 00090 #include "llvm/ADT/SetVector.h" 00091 #include "llvm/ADT/Statistic.h" 00092 #include "llvm/ADT/STLExtras.h" 00093 #include "llvm/Analysis/Dominators.h" 00094 #include "llvm/Assembly/Writer.h" 00095 #include "llvm/Support/CFG.h" 00096 #include "llvm/Support/Compiler.h" 00097 #include "llvm/Support/ConstantRange.h" 00098 #include "llvm/Support/Debug.h" 00099 #include "llvm/Support/InstVisitor.h" 00100 #include "llvm/Target/TargetData.h" 00101 #include "llvm/Transforms/Utils/Local.h" 00102 #include <algorithm> 00103 #include <deque> 00104 #include <stack> 00105 using namespace llvm; 00106 00107 STATISTIC(NumVarsReplaced, "Number of argument substitutions"); 00108 STATISTIC(NumInstruction , "Number of instructions removed"); 00109 STATISTIC(NumSimple , "Number of simple replacements"); 00110 STATISTIC(NumBlocks , "Number of blocks marked unreachable"); 00111 STATISTIC(NumSnuggle , "Number of comparisons snuggled"); 00112 00113 namespace { 00114 class DomTreeDFS { 00115 public: 00116 class Node { 00117 friend class DomTreeDFS; 00118 public: 00119 typedef std::vector<Node *>::iterator iterator; 00120 typedef std::vector<Node *>::const_iterator const_iterator; 00121 00122 unsigned getDFSNumIn() const { return DFSin; } 00123 unsigned getDFSNumOut() const { return DFSout; } 00124 00125 BasicBlock *getBlock() const { return BB; } 00126 00127 iterator begin() { return Children.begin(); } 00128 iterator end() { return Children.end(); } 00129 00130 const_iterator begin() const { return Children.begin(); } 00131 const_iterator end() const { return Children.end(); } 00132 00133 bool dominates(const Node *N) const { 00134 return DFSin <= N->DFSin && DFSout >= N->DFSout; 00135 } 00136 00137 bool DominatedBy(const Node *N) const { 00138 return N->dominates(this); 00139 } 00140 00141 /// Sorts by the number of descendants. With this, you can iterate 00142 /// through a sorted list and the first matching entry is the most 00143 /// specific match for your basic block. The order provided is stable; 00144 /// DomTreeDFS::Nodes with the same number of descendants are sorted by 00145 /// DFS in number. 00146 bool operator<(const Node &N) const { 00147 unsigned spread = DFSout - DFSin; 00148 unsigned N_spread = N.DFSout - N.DFSin; 00149 if (spread == N_spread) return DFSin < N.DFSin; 00150 return spread < N_spread; 00151 } 00152 bool operator>(const Node &N) const { return N < *this; } 00153 00154 private: 00155 unsigned DFSin, DFSout; 00156 BasicBlock *BB; 00157 00158 std::vector<Node *> Children; 00159 }; 00160 00161 // XXX: this may be slow. Instead of using "new" for each node, consider 00162 // putting them in a vector to keep them contiguous. 00163 explicit DomTreeDFS(DominatorTree *DT) { 00164 std::stack<std::pair<Node *, DomTreeNode *> > S; 00165 00166 Entry = new Node; 00167 Entry->BB = DT->getRootNode()->getBlock(); 00168 S.push(std::make_pair(Entry, DT->getRootNode())); 00169 00170 NodeMap[Entry->BB] = Entry; 00171 00172 while (!S.empty()) { 00173 std::pair<Node *, DomTreeNode *> &Pair = S.top(); 00174 Node *N = Pair.first; 00175 DomTreeNode *DTNode = Pair.second; 00176 S.pop(); 00177 00178 for (DomTreeNode::iterator I = DTNode->begin(), E = DTNode->end(); 00179 I != E; ++I) { 00180 Node *NewNode = new Node; 00181 NewNode->BB = (*I)->getBlock(); 00182 N->Children.push_back(NewNode); 00183 S.push(std::make_pair(NewNode, *I)); 00184 00185 NodeMap[NewNode->BB] = NewNode; 00186 } 00187 } 00188 00189 renumber(); 00190 00191 #ifndef NDEBUG 00192 DEBUG(dump()); 00193 #endif 00194 } 00195 00196 #ifndef NDEBUG 00197 virtual 00198 #endif 00199 ~DomTreeDFS() { 00200 std::stack<Node *> S; 00201 00202 S.push(Entry); 00203 while (!S.empty()) { 00204 Node *N = S.top(); S.pop(); 00205 00206 for (Node::iterator I = N->begin(), E = N->end(); I != E; ++I) 00207 S.push(*I); 00208 00209 delete N; 00210 } 00211 } 00212 00213 /// getRootNode - This returns the entry node for the CFG of the function. 00214 Node *getRootNode() const { return Entry; } 00215 00216 /// getNodeForBlock - return the node for the specified basic block. 00217 Node *getNodeForBlock(BasicBlock *BB) const { 00218 if (!NodeMap.count(BB)) return 0; 00219 return const_cast<DomTreeDFS*>(this)->NodeMap[BB]; 00220 } 00221 00222 /// dominates - returns true if the basic block for I1 dominates that of 00223 /// the basic block for I2. If the instructions belong to the same basic 00224 /// block, the instruction first instruction sequentially in the block is 00225 /// considered dominating. 00226 bool dominates(Instruction *I1, Instruction *I2) { 00227 BasicBlock *BB1 = I1->getParent(), 00228 *BB2 = I2->getParent(); 00229 if (BB1 == BB2) { 00230 if (isa<TerminatorInst>(I1)) return false; 00231 if (isa<TerminatorInst>(I2)) return true; 00232 if ( isa<PHINode>(I1) && !isa<PHINode>(I2)) return true; 00233 if (!isa<PHINode>(I1) && isa<PHINode>(I2)) return false; 00234 00235 for (BasicBlock::const_iterator I = BB2->begin(), E = BB2->end(); 00236 I != E; ++I) { 00237 if (&*I == I1) return true; 00238 else if (&*I == I2) return false; 00239 } 00240 assert(!"Instructions not found in parent BasicBlock?"); 00241 } else { 00242 Node *Node1 = getNodeForBlock(BB1), 00243 *Node2 = getNodeForBlock(BB2); 00244 return Node1 && Node2 && Node1->dominates(Node2); 00245 } 00246 return false; // Not reached 00247 } 00248 00249 private: 00250 /// renumber - calculates the depth first search numberings and applies 00251 /// them onto the nodes. 00252 void renumber() { 00253 std::stack<std::pair<Node *, Node::iterator> > S; 00254 unsigned n = 0; 00255 00256 Entry->DFSin = ++n; 00257 S.push(std::make_pair(Entry, Entry->begin())); 00258 00259 while (!S.empty()) { 00260 std::pair<Node *, Node::iterator> &Pair = S.top(); 00261 Node *N = Pair.first; 00262 Node::iterator &I = Pair.second; 00263 00264 if (I == N->end()) { 00265 N->DFSout = ++n; 00266 S.pop(); 00267 } else { 00268 Node *Next = *I++; 00269 Next->DFSin = ++n; 00270 S.push(std::make_pair(Next, Next->begin())); 00271 } 00272 } 00273 } 00274 00275 #ifndef NDEBUG 00276 virtual void dump() const { 00277 dump(*cerr.stream()); 00278 } 00279 00280 void dump(std::ostream &os) const { 00281 os << "Predicate simplifier DomTreeDFS: \n"; 00282 dump(Entry, 0, os); 00283 os << "\n\n"; 00284 } 00285 00286 void dump(Node *N, int depth, std::ostream &os) const { 00287 ++depth; 00288 for (int i = 0; i < depth; ++i) { os << " "; } 00289 os << "[" << depth << "] "; 00290 00291 os << N->getBlock()->getName() << " (" << N->getDFSNumIn() 00292 << ", " << N->getDFSNumOut() << ")\n"; 00293 00294 for (Node::iterator I = N->begin(), E = N->end(); I != E; ++I) 00295 dump(*I, depth, os); 00296 } 00297 #endif 00298 00299 Node *Entry; 00300 std::map<BasicBlock *, Node *> NodeMap; 00301 }; 00302 00303 // SLT SGT ULT UGT EQ 00304 // 0 1 0 1 0 -- GT 10 00305 // 0 1 0 1 1 -- GE 11 00306 // 0 1 1 0 0 -- SGTULT 12 00307 // 0 1 1 0 1 -- SGEULE 13 00308 // 0 1 1 1 0 -- SGT 14 00309 // 0 1 1 1 1 -- SGE 15 00310 // 1 0 0 1 0 -- SLTUGT 18 00311 // 1 0 0 1 1 -- SLEUGE 19 00312 // 1 0 1 0 0 -- LT 20 00313 // 1 0 1 0 1 -- LE 21 00314 // 1 0 1 1 0 -- SLT 22 00315 // 1 0 1 1 1 -- SLE 23 00316 // 1 1 0 1 0 -- UGT 26 00317 // 1 1 0 1 1 -- UGE 27 00318 // 1 1 1 0 0 -- ULT 28 00319 // 1 1 1 0 1 -- ULE 29 00320 // 1 1 1 1 0 -- NE 30 00321 enum LatticeBits { 00322 EQ_BIT = 1, UGT_BIT = 2, ULT_BIT = 4, SGT_BIT = 8, SLT_BIT = 16 00323 }; 00324 enum LatticeVal { 00325 GT = SGT_BIT | UGT_BIT, 00326 GE = GT | EQ_BIT, 00327 LT = SLT_BIT | ULT_BIT, 00328 LE = LT | EQ_BIT, 00329 NE = SLT_BIT | SGT_BIT | ULT_BIT | UGT_BIT, 00330 SGTULT = SGT_BIT | ULT_BIT, 00331 SGEULE = SGTULT | EQ_BIT, 00332 SLTUGT = SLT_BIT | UGT_BIT, 00333 SLEUGE = SLTUGT | EQ_BIT, 00334 ULT = SLT_BIT | SGT_BIT | ULT_BIT, 00335 UGT = SLT_BIT | SGT_BIT | UGT_BIT, 00336 SLT = SLT_BIT | ULT_BIT | UGT_BIT, 00337 SGT = SGT_BIT | ULT_BIT | UGT_BIT, 00338 SLE = SLT | EQ_BIT, 00339 SGE = SGT | EQ_BIT, 00340 ULE = ULT | EQ_BIT, 00341 UGE = UGT | EQ_BIT 00342 }; 00343 00344 #ifndef NDEBUG 00345 /// validPredicate - determines whether a given value is actually a lattice 00346 /// value. Only used in assertions or debugging. 00347 static bool validPredicate(LatticeVal LV) { 00348 switch (LV) { 00349 case GT: case GE: case LT: case LE: case NE: 00350 case SGTULT: case SGT: case SGEULE: 00351 case SLTUGT: case SLT: case SLEUGE: 00352 case ULT: case UGT: 00353 case SLE: case SGE: case ULE: case UGE: 00354 return true; 00355 default: 00356 return false; 00357 } 00358 } 00359 #endif 00360 00361 /// reversePredicate - reverse the direction of the inequality 00362 static LatticeVal reversePredicate(LatticeVal LV) { 00363 unsigned reverse = LV ^ (SLT_BIT|SGT_BIT|ULT_BIT|UGT_BIT); //preserve EQ_BIT 00364 00365 if ((reverse & (SLT_BIT|SGT_BIT)) == 0) 00366 reverse |= (SLT_BIT|SGT_BIT); 00367 00368 if ((reverse & (ULT_BIT|UGT_BIT)) == 0) 00369 reverse |= (ULT_BIT|UGT_BIT); 00370 00371 LatticeVal Rev = static_cast<LatticeVal>(reverse); 00372 assert(validPredicate(Rev) && "Failed reversing predicate."); 00373 return Rev; 00374 } 00375 00376 /// ValueNumbering stores the scope-specific value numbers for a given Value. 00377 class VISIBILITY_HIDDEN ValueNumbering { 00378 00379 /// VNPair is a tuple of {Value, index number, DomTreeDFS::Node}. It 00380 /// includes the comparison operators necessary to allow you to store it 00381 /// in a sorted vector. 00382 class VISIBILITY_HIDDEN VNPair { 00383 public: 00384 Value *V; 00385 unsigned index; 00386 DomTreeDFS::Node *Subtree; 00387 00388 VNPair(Value *V, unsigned index, DomTreeDFS::Node *Subtree) 00389 : V(V), index(index), Subtree(Subtree) {} 00390 00391 bool operator==(const VNPair &RHS) const { 00392 return V == RHS.V && Subtree == RHS.Subtree; 00393 } 00394 00395 bool operator<(const VNPair &RHS) const { 00396 if (V != RHS.V) return V < RHS.V; 00397 return *Subtree < *RHS.Subtree; 00398 } 00399 00400 bool operator<(Value *RHS) const { 00401 return V < RHS; 00402 } 00403 00404 bool operator>(Value *RHS) const { 00405 return V > RHS; 00406 } 00407 00408 friend bool operator<(Value *RHS, const VNPair &pair) { 00409 return pair.operator>(RHS); 00410 } 00411 }; 00412 00413 typedef std::vector<VNPair> VNMapType; 00414 VNMapType VNMap; 00415 00416 /// The canonical choice for value number at index. 00417 std::vector<Value *> Values; 00418 00419 DomTreeDFS *DTDFS; 00420 00421 public: 00422 #ifndef NDEBUG 00423 virtual ~ValueNumbering() {} 00424 virtual void dump() { 00425 dump(*cerr.stream()); 00426 } 00427 00428 void dump(std::ostream &os) { 00429 for (unsigned i = 1; i <= Values.size(); ++i) { 00430 os << i << " = "; 00431 WriteAsOperand(os, Values[i-1]); 00432 os << " {"; 00433 for (unsigned j = 0; j < VNMap.size(); ++j) { 00434 if (VNMap[j].index == i) { 00435 WriteAsOperand(os, VNMap[j].V); 00436 os << " (" << VNMap[j].Subtree->getDFSNumIn() << ") "; 00437 } 00438 } 00439 os << "}\n"; 00440 } 00441 } 00442 #endif 00443 00444 /// compare - returns true if V1 is a better canonical value than V2. 00445 bool compare(Value *V1, Value *V2) const { 00446 if (isa<Constant>(V1)) 00447 return !isa<Constant>(V2); 00448 else if (isa<Constant>(V2)) 00449 return false; 00450 else if (isa<Argument>(V1)) 00451 return !isa<Argument>(V2); 00452 else if (isa<Argument>(V2)) 00453 return false; 00454 00455 Instruction *I1 = dyn_cast<Instruction>(V1); 00456 Instruction *I2 = dyn_cast<Instruction>(V2); 00457 00458 if (!I1 || !I2) 00459 return V1->getNumUses() < V2->getNumUses(); 00460 00461 return DTDFS->dominates(I1, I2); 00462 } 00463 00464 ValueNumbering(DomTreeDFS *DTDFS) : DTDFS(DTDFS) {} 00465 00466 /// valueNumber - finds the value number for V under the Subtree. If 00467 /// there is no value number, returns zero. 00468 unsigned valueNumber(Value *V, DomTreeDFS::Node *Subtree) { 00469 if (!(isa<Constant>(V) || isa<Argument>(V) || isa<Instruction>(V)) 00470 || V->getType() == Type::VoidTy) return 0; 00471 00472 VNMapType::iterator E = VNMap.end(); 00473 VNPair pair(V, 0, Subtree); 00474 VNMapType::iterator I = std::lower_bound(VNMap.begin(), E, pair); 00475 while (I != E && I->V == V) { 00476 if (I->Subtree->dominates(Subtree)) 00477 return I->index; 00478 ++I; 00479 } 00480 return 0; 00481 } 00482 00483 /// getOrInsertVN - always returns a value number, creating it if necessary. 00484 unsigned getOrInsertVN(Value *V, DomTreeDFS::Node *Subtree) { 00485 if (unsigned n = valueNumber(V, Subtree)) 00486 return n; 00487 else 00488 return newVN(V); 00489 } 00490 00491 /// newVN - creates a new value number. Value V must not already have a 00492 /// value number assigned. 00493 unsigned newVN(Value *V) { 00494 assert((isa<Constant>(V) || isa<Argument>(V) || isa<Instruction>(V)) && 00495 "Bad Value for value numbering."); 00496 assert(V->getType() != Type::VoidTy && "Won't value number a void value"); 00497 00498 Values.push_back(V); 00499 00500 VNPair pair = VNPair(V, Values.size(), DTDFS->getRootNode()); 00501 VNMapType::iterator I = std::lower_bound(VNMap.begin(), VNMap.end(), pair); 00502 assert((I == VNMap.end() || value(I->index) != V) && 00503 "Attempt to create a duplicate value number."); 00504 VNMap.insert(I, pair); 00505 00506 return Values.size(); 00507 } 00508 00509 /// value - returns the Value associated with a value number. 00510 Value *value(unsigned index) const { 00511 assert(index != 0 && "Zero index is reserved for not found."); 00512 assert(index <= Values.size() && "Index out of range."); 00513 return Values[index-1]; 00514 } 00515 00516 /// canonicalize - return a Value that is equal to V under Subtree. 00517 Value *canonicalize(Value *V, DomTreeDFS::Node *Subtree) { 00518 if (isa<Constant>(V)) return V; 00519 00520 if (unsigned n = valueNumber(V, Subtree)) 00521 return value(n); 00522 else 00523 return V; 00524 } 00525 00526 /// addEquality - adds that value V belongs to the set of equivalent 00527 /// values defined by value number n under Subtree. 00528 void addEquality(unsigned n, Value *V, DomTreeDFS::Node *Subtree) { 00529 assert(canonicalize(value(n), Subtree) == value(n) && 00530 "Node's 'canonical' choice isn't best within this subtree."); 00531 00532 // Suppose that we are given "%x -> node #1 (%y)". The problem is that 00533 // we may already have "%z -> node #2 (%x)" somewhere above us in the 00534 // graph. We need to find those edges and add "%z -> node #1 (%y)" 00535 // to keep the lookups canonical. 00536 00537 std::vector<Value *> ToRepoint(1, V); 00538 00539 if (unsigned Conflict = valueNumber(V, Subtree)) { 00540 for (VNMapType::iterator I = VNMap.begin(), E = VNMap.end(); 00541 I != E; ++I) { 00542 if (I->index == Conflict && I->Subtree->dominates(Subtree)) 00543 ToRepoint.push_back(I->V); 00544 } 00545 } 00546 00547 for (std::vector<Value *>::iterator VI = ToRepoint.begin(), 00548 VE = ToRepoint.end(); VI != VE; ++VI) { 00549 Value *V = *VI; 00550 00551 VNPair pair(V, n, Subtree); 00552 VNMapType::iterator B = VNMap.begin(), E = VNMap.end(); 00553 VNMapType::iterator I = std::lower_bound(B, E, pair); 00554 if (I != E && I->V == V && I->Subtree == Subtree) 00555 I->index = n; // Update best choice 00556 else 00557 VNMap.insert(I, pair); // New Value 00558 00559 // XXX: we currently don't have to worry about updating values with 00560 // more specific Subtrees, but we will need to for PHI node support. 00561 00562 #ifndef NDEBUG 00563 Value *V_n = value(n); 00564 if (isa<Constant>(V) && isa<Constant>(V_n)) { 00565 assert(V == V_n && "Constant equals different constant?"); 00566 } 00567 #endif 00568 } 00569 } 00570 00571 /// remove - removes all references to value V. 00572 void remove(Value *V) { 00573 VNMapType::iterator B = VNMap.begin(), E = VNMap.end(); 00574 VNPair pair(V, 0, DTDFS->getRootNode()); 00575 VNMapType::iterator J = std::upper_bound(B, E, pair); 00576 VNMapType::iterator I = J; 00577 00578 while (I != B && (I == E || I->V == V)) --I; 00579 00580 VNMap.erase(I, J); 00581 } 00582 }; 00583 00584 /// The InequalityGraph stores the relationships between values. 00585 /// Each Value in the graph is assigned to a Node. Nodes are pointer 00586 /// comparable for equality. The caller is expected to maintain the logical 00587 /// consistency of the system. 00588 /// 00589 /// The InequalityGraph class may invalidate Node*s after any mutator call. 00590 /// @brief The InequalityGraph stores the relationships between values. 00591 class VISIBILITY_HIDDEN InequalityGraph { 00592 ValueNumbering &VN; 00593 DomTreeDFS::Node *TreeRoot; 00594 00595 InequalityGraph(); // DO NOT IMPLEMENT 00596 InequalityGraph(InequalityGraph &); // DO NOT IMPLEMENT 00597 public: 00598 InequalityGraph(ValueNumbering &VN, DomTreeDFS::Node *TreeRoot) 00599 : VN(VN), TreeRoot(TreeRoot) {} 00600 00601 class Node; 00602 00603 /// An Edge is contained inside a Node making one end of the edge implicit 00604 /// and contains a pointer to the other end. The edge contains a lattice 00605 /// value specifying the relationship and an DomTreeDFS::Node specifying 00606 /// the root in the dominator tree to which this edge applies. 00607 class VISIBILITY_HIDDEN Edge { 00608 public: 00609 Edge(unsigned T, LatticeVal V, DomTreeDFS::Node *ST) 00610 : To(T), LV(V), Subtree(ST) {} 00611 00612 unsigned To; 00613 LatticeVal LV; 00614 DomTreeDFS::Node *Subtree; 00615 00616 bool operator<(const Edge &edge) const { 00617 if (To != edge.To) return To < edge.To; 00618 return *Subtree < *edge.Subtree; 00619 } 00620 00621 bool operator<(unsigned to) const { 00622 return To < to; 00623 } 00624 00625 bool operator>(unsigned to) const { 00626 return To > to; 00627 } 00628 00629 friend bool operator<(unsigned to, const Edge &edge) { 00630 return edge.operator>(to); 00631 } 00632 }; 00633 00634 /// A single node in the InequalityGraph. This stores the canonical Value 00635 /// for the node, as well as the relationships with the neighbours. 00636 /// 00637 /// @brief A single node in the InequalityGraph. 00638 class VISIBILITY_HIDDEN Node { 00639 friend class InequalityGraph; 00640 00641 typedef SmallVector<Edge, 4> RelationsType; 00642 RelationsType Relations; 00643 00644 // TODO: can this idea improve performance? 00645 //friend class std::vector<Node>; 00646 //Node(Node &N) { RelationsType.swap(N.RelationsType); } 00647 00648 public: 00649 typedef RelationsType::iterator iterator; 00650 typedef RelationsType::const_iterator const_iterator; 00651 00652 #ifndef NDEBUG 00653 virtual ~Node() {} 00654 virtual void dump() const { 00655 dump(*cerr.stream()); 00656 } 00657 private: 00658 void dump(std::ostream &os) const { 00659 static const std::string names[32] = 00660 { "000000", "000001", "000002", "000003", "000004", "000005", 00661 "000006", "000007", "000008", "000009", " >", " >=", 00662 " s>u<", "s>=u<=", " s>", " s>=", "000016", "000017", 00663 " s<u>", "s<=u>=", " <", " <=", " s<", " s<=", 00664 "000024", "000025", " u>", " u>=", " u<", " u<=", 00665 " !=", "000031" }; 00666 for (Node::const_iterator NI = begin(), NE = end(); NI != NE; ++NI) { 00667 os << names[NI->LV] << " " << NI->To 00668 << " (" << NI->Subtree->getDFSNumIn() << "), "; 00669 } 00670 } 00671 public: 00672 #endif 00673 00674 iterator begin() { return Relations.begin(); } 00675 iterator end() { return Relations.end(); } 00676 const_iterator begin() const { return Relations.begin(); } 00677 const_iterator end() const { return Relations.end(); } 00678 00679 iterator find(unsigned n, DomTreeDFS::Node *Subtree) { 00680 iterator E = end(); 00681 for (iterator I = std::lower_bound(begin(), E, n); 00682 I != E && I->To == n; ++I) { 00683 if (Subtree->DominatedBy(I->Subtree)) 00684 return I; 00685 } 00686 return E; 00687 } 00688 00689 const_iterator find(unsigned n, DomTreeDFS::Node *Subtree) const { 00690 const_iterator E = end(); 00691 for (const_iterator I = std::lower_bound(begin(), E, n); 00692 I != E && I->To == n; ++I) { 00693 if (Subtree->DominatedBy(I->Subtree)) 00694 return I; 00695 } 00696 return E; 00697 } 00698 00699 /// update - updates the lattice value for a given node, creating a new 00700 /// entry if one doesn't exist. The new lattice value must not be 00701 /// inconsistent with any previously existing value. 00702 void update(unsigned n, LatticeVal R, DomTreeDFS::Node *Subtree) { 00703 assert(validPredicate(R) && "Invalid predicate."); 00704 00705 Edge edge(n, R, Subtree); 00706 iterator B = begin(), E = end(); 00707 iterator I = std::lower_bound(B, E, edge); 00708 00709 iterator J = I; 00710 while (J != E && J->To == n) { 00711 if (Subtree->DominatedBy(J->Subtree)) 00712 break; 00713 ++J; 00714 } 00715 00716 if (J != E && J->To == n) { 00717 edge.LV = static_cast<LatticeVal>(J->LV & R); 00718 assert(validPredicate(edge.LV) && "Invalid union of lattice values."); 00719 00720 if (edge.LV == J->LV) 00721 return; // This update adds nothing new. 00722 } 00723 00724 if (I != B) { 00725 // We also have to tighten any edge beneath our update. 00726 for (iterator K = I - 1; K->To == n; --K) { 00727 if (K->Subtree->DominatedBy(Subtree)) { 00728 LatticeVal LV = static_cast<LatticeVal>(K->LV & edge.LV); 00729 assert(validPredicate(LV) && "Invalid union of lattice values"); 00730 K->LV = LV; 00731 } 00732 if (K == B) break; 00733 } 00734 } 00735 00736 // Insert new edge at Subtree if it isn't already there. 00737 if (I == E || I->To != n || Subtree != I->Subtree) 00738 Relations.insert(I, edge); 00739 } 00740 }; 00741 00742 private: 00743 00744 std::vector<Node> Nodes; 00745 00746 public: 00747 /// node - returns the node object at a given value number. The pointer 00748 /// returned may be invalidated on the next call to node(). 00749 Node *node(unsigned index) { 00750 assert(VN.value(index)); // This triggers the necessary checks. 00751 if (Nodes.size() < index) Nodes.resize(index); 00752 return &Nodes[index-1]; 00753 } 00754 00755 /// isRelatedBy - true iff n1 op n2 00756 bool isRelatedBy(unsigned n1, unsigned n2, DomTreeDFS::Node *Subtree, 00757 LatticeVal LV) { 00758 if (n1 == n2) return LV & EQ_BIT; 00759 00760 Node *N1 = node(n1); 00761 Node::iterator I = N1->find(n2, Subtree), E = N1->end(); 00762 if (I != E) return (I->LV & LV) == I->LV; 00763 00764 return false; 00765 } 00766 00767 // The add* methods assume that your input is logically valid and may 00768 // assertion-fail or infinitely loop if you attempt a contradiction. 00769 00770 /// addInequality - Sets n1 op n2. 00771 /// It is also an error to call this on an inequality that is already true. 00772 void addInequality(unsigned n1, unsigned n2, DomTreeDFS::Node *Subtree, 00773 LatticeVal LV1) { 00774 assert(n1 != n2 && "A node can't be inequal to itself."); 00775 00776 if (LV1 != NE) 00777 assert(!isRelatedBy(n1, n2, Subtree, reversePredicate(LV1)) && 00778 "Contradictory inequality."); 00779 00780 // Suppose we're adding %n1 < %n2. Find all the %a < %n1 and 00781 // add %a < %n2 too. This keeps the graph fully connected. 00782 if (LV1 != NE) { 00783 // Break up the relationship into signed and unsigned comparison parts. 00784 // If the signed parts of %a op1 %n1 match that of %n1 op2 %n2, and 00785 // op1 and op2 aren't NE, then add %a op3 %n2. The new relationship 00786 // should have the EQ_BIT iff it's set for both op1 and op2. 00787 00788 unsigned LV1_s = LV1 & (SLT_BIT|SGT_BIT); 00789 unsigned LV1_u = LV1 & (ULT_BIT|UGT_BIT); 00790 00791 for (Node::iterator I = node(n1)->begin(), E = node(n1)->end(); I != E; ++I) { 00792 if (I->LV != NE && I->To != n2) { 00793 00794 DomTreeDFS::Node *Local_Subtree = NULL; 00795 if (Subtree->DominatedBy(I->Subtree)) 00796 Local_Subtree = Subtree; 00797 else if (I->Subtree->DominatedBy(Subtree)) 00798 Local_Subtree = I->Subtree; 00799 00800 if (Local_Subtree) { 00801 unsigned new_relationship = 0; 00802 LatticeVal ILV = reversePredicate(I->LV); 00803 unsigned ILV_s = ILV & (SLT_BIT|SGT_BIT); 00804 unsigned ILV_u = ILV & (ULT_BIT|UGT_BIT); 00805 00806 if (LV1_s != (SLT_BIT|SGT_BIT) && ILV_s == LV1_s) 00807 new_relationship |= ILV_s; 00808 if (LV1_u != (ULT_BIT|UGT_BIT) && ILV_u == LV1_u) 00809 new_relationship |= ILV_u; 00810 00811 if (new_relationship) { 00812 if ((new_relationship & (SLT_BIT|SGT_BIT)) == 0) 00813 new_relationship |= (SLT_BIT|SGT_BIT); 00814 if ((new_relationship & (ULT_BIT|UGT_BIT)) == 0) 00815 new_relationship |= (ULT_BIT|UGT_BIT); 00816 if ((LV1 & EQ_BIT) && (ILV & EQ_BIT)) 00817 new_relationship |= EQ_BIT; 00818 00819 LatticeVal NewLV = static_cast<LatticeVal>(new_relationship); 00820 00821 node(I->To)->update(n2, NewLV, Local_Subtree); 00822 node(n2)->update(I->To, reversePredicate(NewLV), Local_Subtree); 00823 } 00824 } 00825 } 00826 } 00827 00828 for (Node::iterator I = node(n2)->begin(), E = node(n2)->end(); I != E; ++I) { 00829 if (I->LV != NE && I->To != n1) { 00830 DomTreeDFS::Node *Local_Subtree = NULL; 00831 if (Subtree->DominatedBy(I->Subtree)) 00832 Local_Subtree = Subtree; 00833 else if (I->Subtree->DominatedBy(Subtree)) 00834 Local_Subtree = I->Subtree; 00835 00836 if (Local_Subtree) { 00837 unsigned new_relationship = 0; 00838 unsigned ILV_s = I->LV & (SLT_BIT|SGT_BIT); 00839 unsigned ILV_u = I->LV & (ULT_BIT|UGT_BIT); 00840 00841 if (LV1_s != (SLT_BIT|SGT_BIT) && ILV_s == LV1_s) 00842 new_relationship |= ILV_s; 00843 00844 if (LV1_u != (ULT_BIT|UGT_BIT) && ILV_u == LV1_u) 00845 new_relationship |= ILV_u; 00846 00847 if (new_relationship) { 00848 if ((new_relationship & (SLT_BIT|SGT_BIT)) == 0) 00849 new_relationship |= (SLT_BIT|SGT_BIT); 00850 if ((new_relationship & (ULT_BIT|UGT_BIT)) == 0) 00851 new_relationship |= (ULT_BIT|UGT_BIT); 00852 if ((LV1 & EQ_BIT) && (I->LV & EQ_BIT)) 00853 new_relationship |= EQ_BIT; 00854 00855 LatticeVal NewLV = static_cast<LatticeVal>(new_relationship); 00856 00857 node(n1)->update(I->To, NewLV, Local_Subtree); 00858 node(I->To)->update(n1, reversePredicate(NewLV), Local_Subtree); 00859 } 00860 } 00861 } 00862 } 00863 } 00864 00865 node(n1)->update(n2, LV1, Subtree); 00866 node(n2)->update(n1, reversePredicate(LV1), Subtree); 00867 } 00868 00869 /// remove - removes a node from the graph by removing all references to 00870 /// and from it. 00871 void remove(unsigned n) { 00872 Node *N = node(n); 00873 for (Node::iterator NI = N->begin(), NE = N->end(); NI != NE; ++NI) { 00874 Node::iterator Iter = node(NI->To)->find(n, TreeRoot); 00875 do { 00876 node(NI->To)->Relations.erase(Iter); 00877 Iter = node(NI->To)->find(n, TreeRoot); 00878 } while (Iter != node(NI->To)->end()); 00879 } 00880 N->Relations.clear(); 00881 } 00882 00883 #ifndef NDEBUG 00884 virtual ~InequalityGraph() {} 00885 virtual void