| Chris Lattner | 10f2d13 | 2009-11-11 00:22:30 +0000 | [diff] [blame] | 1 | //===- LazyValueInfo.cpp - Value constraint analysis ----------------------===// | 
|  | 2 | // | 
|  | 3 | //                     The LLVM Compiler Infrastructure | 
|  | 4 | // | 
|  | 5 | // This file is distributed under the University of Illinois Open Source | 
|  | 6 | // License. See LICENSE.TXT for details. | 
|  | 7 | // | 
|  | 8 | //===----------------------------------------------------------------------===// | 
|  | 9 | // | 
|  | 10 | // This file defines the interface for lazy computation of value constraint | 
|  | 11 | // information. | 
|  | 12 | // | 
|  | 13 | //===----------------------------------------------------------------------===// | 
|  | 14 |  | 
| Chris Lattner | b8c124c | 2009-11-12 01:22:16 +0000 | [diff] [blame] | 15 | #define DEBUG_TYPE "lazy-value-info" | 
| Chris Lattner | 10f2d13 | 2009-11-11 00:22:30 +0000 | [diff] [blame] | 16 | #include "llvm/Analysis/LazyValueInfo.h" | 
| Chris Lattner | cc4d3b2 | 2009-11-11 02:08:33 +0000 | [diff] [blame] | 17 | #include "llvm/Constants.h" | 
|  | 18 | #include "llvm/Instructions.h" | 
|  | 19 | #include "llvm/Analysis/ConstantFolding.h" | 
|  | 20 | #include "llvm/Target/TargetData.h" | 
| Chris Lattner | 1697652 | 2009-11-11 22:48:44 +0000 | [diff] [blame] | 21 | #include "llvm/Support/CFG.h" | 
| Chris Lattner | b8c124c | 2009-11-12 01:22:16 +0000 | [diff] [blame] | 22 | #include "llvm/Support/Debug.h" | 
| Chris Lattner | 1697652 | 2009-11-11 22:48:44 +0000 | [diff] [blame] | 23 | #include "llvm/Support/raw_ostream.h" | 
|  | 24 | #include "llvm/ADT/DenseMap.h" | 
| Owen Anderson | 9a65dc9 | 2010-07-27 23:58:11 +0000 | [diff] [blame^] | 25 | #include "llvm/ADT/DenseSet.h" | 
| Chris Lattner | cc4d3b2 | 2009-11-11 02:08:33 +0000 | [diff] [blame] | 26 | #include "llvm/ADT/PointerIntPair.h" | 
| Chris Lattner | e564281 | 2009-11-15 20:00:52 +0000 | [diff] [blame] | 27 | #include "llvm/ADT/STLExtras.h" | 
| Chris Lattner | 10f2d13 | 2009-11-11 00:22:30 +0000 | [diff] [blame] | 28 | using namespace llvm; | 
|  | 29 |  | 
|  | 30 | char LazyValueInfo::ID = 0; | 
| Owen Anderson | d13db2c | 2010-07-21 22:09:45 +0000 | [diff] [blame] | 31 | INITIALIZE_PASS(LazyValueInfo, "lazy-value-info", | 
|  | 32 | "Lazy Value Information Analysis", false, true); | 
| Chris Lattner | 10f2d13 | 2009-11-11 00:22:30 +0000 | [diff] [blame] | 33 |  | 
|  | 34 | namespace llvm { | 
|  | 35 | FunctionPass *createLazyValueInfoPass() { return new LazyValueInfo(); } | 
|  | 36 | } | 
|  | 37 |  | 
| Chris Lattner | cc4d3b2 | 2009-11-11 02:08:33 +0000 | [diff] [blame] | 38 |  | 
|  | 39 | //===----------------------------------------------------------------------===// | 
|  | 40 | //                               LVILatticeVal | 
|  | 41 | //===----------------------------------------------------------------------===// | 
|  | 42 |  | 
|  | 43 | /// LVILatticeVal - This is the information tracked by LazyValueInfo for each | 
|  | 44 | /// value. | 
|  | 45 | /// | 
|  | 46 | /// FIXME: This is basically just for bringup, this can be made a lot more rich | 
|  | 47 | /// in the future. | 
|  | 48 | /// | 
|  | 49 | namespace { | 
|  | 50 | class LVILatticeVal { | 
|  | 51 | enum LatticeValueTy { | 
|  | 52 | /// undefined - This LLVM Value has no known value yet. | 
|  | 53 | undefined, | 
|  | 54 | /// constant - This LLVM Value has a specific constant value. | 
|  | 55 | constant, | 
| Chris Lattner | b52675b | 2009-11-12 04:36:58 +0000 | [diff] [blame] | 56 |  | 
|  | 57 | /// notconstant - This LLVM value is known to not have the specified value. | 
|  | 58 | notconstant, | 
|  | 59 |  | 
| Chris Lattner | cc4d3b2 | 2009-11-11 02:08:33 +0000 | [diff] [blame] | 60 | /// overdefined - This instruction is not known to be constant, and we know | 
|  | 61 | /// it has a value. | 
|  | 62 | overdefined | 
|  | 63 | }; | 
|  | 64 |  | 
|  | 65 | /// Val: This stores the current lattice value along with the Constant* for | 
| Chris Lattner | b52675b | 2009-11-12 04:36:58 +0000 | [diff] [blame] | 66 | /// the constant if this is a 'constant' or 'notconstant' value. | 
| Chris Lattner | cc4d3b2 | 2009-11-11 02:08:33 +0000 | [diff] [blame] | 67 | PointerIntPair<Constant *, 2, LatticeValueTy> Val; | 
|  | 68 |  | 
|  | 69 | public: | 
|  | 70 | LVILatticeVal() : Val(0, undefined) {} | 
|  | 71 |  | 
| Chris Lattner | 1697652 | 2009-11-11 22:48:44 +0000 | [diff] [blame] | 72 | static LVILatticeVal get(Constant *C) { | 
|  | 73 | LVILatticeVal Res; | 
|  | 74 | Res.markConstant(C); | 
|  | 75 | return Res; | 
|  | 76 | } | 
| Chris Lattner | b52675b | 2009-11-12 04:36:58 +0000 | [diff] [blame] | 77 | static LVILatticeVal getNot(Constant *C) { | 
|  | 78 | LVILatticeVal Res; | 
|  | 79 | Res.markNotConstant(C); | 
|  | 80 | return Res; | 
|  | 81 | } | 
| Chris Lattner | 1697652 | 2009-11-11 22:48:44 +0000 | [diff] [blame] | 82 |  | 
| Chris Lattner | cc4d3b2 | 2009-11-11 02:08:33 +0000 | [diff] [blame] | 83 | bool isUndefined() const   { return Val.getInt() == undefined; } | 
|  | 84 | bool isConstant() const    { return Val.getInt() == constant; } | 
| Chris Lattner | b52675b | 2009-11-12 04:36:58 +0000 | [diff] [blame] | 85 | bool isNotConstant() const { return Val.getInt() == notconstant; } | 
| Chris Lattner | cc4d3b2 | 2009-11-11 02:08:33 +0000 | [diff] [blame] | 86 | bool isOverdefined() const { return Val.getInt() == overdefined; } | 
|  | 87 |  | 
|  | 88 | Constant *getConstant() const { | 
|  | 89 | assert(isConstant() && "Cannot get the constant of a non-constant!"); | 
|  | 90 | return Val.getPointer(); | 
|  | 91 | } | 
|  | 92 |  | 
| Chris Lattner | b52675b | 2009-11-12 04:36:58 +0000 | [diff] [blame] | 93 | Constant *getNotConstant() const { | 
|  | 94 | assert(isNotConstant() && "Cannot get the constant of a non-notconstant!"); | 
|  | 95 | return Val.getPointer(); | 
| Chris Lattner | cc4d3b2 | 2009-11-11 02:08:33 +0000 | [diff] [blame] | 96 | } | 
|  | 97 |  | 
|  | 98 | /// markOverdefined - Return true if this is a change in status. | 
|  | 99 | bool markOverdefined() { | 
|  | 100 | if (isOverdefined()) | 
|  | 101 | return false; | 
|  | 102 | Val.setInt(overdefined); | 
|  | 103 | return true; | 
|  | 104 | } | 
|  | 105 |  | 
|  | 106 | /// markConstant - Return true if this is a change in status. | 
|  | 107 | bool markConstant(Constant *V) { | 
|  | 108 | if (isConstant()) { | 
|  | 109 | assert(getConstant() == V && "Marking constant with different value"); | 
|  | 110 | return false; | 
|  | 111 | } | 
|  | 112 |  | 
|  | 113 | assert(isUndefined()); | 
|  | 114 | Val.setInt(constant); | 
|  | 115 | assert(V && "Marking constant with NULL"); | 
|  | 116 | Val.setPointer(V); | 
| Chris Lattner | 1697652 | 2009-11-11 22:48:44 +0000 | [diff] [blame] | 117 | return true; | 
|  | 118 | } | 
|  | 119 |  | 
| Chris Lattner | b52675b | 2009-11-12 04:36:58 +0000 | [diff] [blame] | 120 | /// markNotConstant - Return true if this is a change in status. | 
|  | 121 | bool markNotConstant(Constant *V) { | 
|  | 122 | if (isNotConstant()) { | 
|  | 123 | assert(getNotConstant() == V && "Marking !constant with different value"); | 
|  | 124 | return false; | 
|  | 125 | } | 
|  | 126 |  | 
|  | 127 | if (isConstant()) | 
|  | 128 | assert(getConstant() != V && "Marking not constant with different value"); | 
|  | 129 | else | 
|  | 130 | assert(isUndefined()); | 
|  | 131 |  | 
|  | 132 | Val.setInt(notconstant); | 
|  | 133 | assert(V && "Marking constant with NULL"); | 
|  | 134 | Val.setPointer(V); | 
|  | 135 | return true; | 
|  | 136 | } | 
|  | 137 |  | 
| Chris Lattner | 1697652 | 2009-11-11 22:48:44 +0000 | [diff] [blame] | 138 | /// mergeIn - Merge the specified lattice value into this one, updating this | 
|  | 139 | /// one and returning true if anything changed. | 
|  | 140 | bool mergeIn(const LVILatticeVal &RHS) { | 
|  | 141 | if (RHS.isUndefined() || isOverdefined()) return false; | 
|  | 142 | if (RHS.isOverdefined()) return markOverdefined(); | 
|  | 143 |  | 
| Chris Lattner | b52675b | 2009-11-12 04:36:58 +0000 | [diff] [blame] | 144 | if (RHS.isNotConstant()) { | 
|  | 145 | if (isNotConstant()) { | 
| Chris Lattner | f496e79 | 2009-11-12 04:57:13 +0000 | [diff] [blame] | 146 | if (getNotConstant() != RHS.getNotConstant() || | 
|  | 147 | isa<ConstantExpr>(getNotConstant()) || | 
|  | 148 | isa<ConstantExpr>(RHS.getNotConstant())) | 
| Chris Lattner | b52675b | 2009-11-12 04:36:58 +0000 | [diff] [blame] | 149 | return markOverdefined(); | 
|  | 150 | return false; | 
|  | 151 | } | 
| Chris Lattner | f496e79 | 2009-11-12 04:57:13 +0000 | [diff] [blame] | 152 | if (isConstant()) { | 
|  | 153 | if (getConstant() == RHS.getNotConstant() || | 
|  | 154 | isa<ConstantExpr>(RHS.getNotConstant()) || | 
|  | 155 | isa<ConstantExpr>(getConstant())) | 
|  | 156 | return markOverdefined(); | 
|  | 157 | return markNotConstant(RHS.getNotConstant()); | 
|  | 158 | } | 
|  | 159 |  | 
|  | 160 | assert(isUndefined() && "Unexpected lattice"); | 
| Chris Lattner | b52675b | 2009-11-12 04:36:58 +0000 | [diff] [blame] | 161 | return markNotConstant(RHS.getNotConstant()); | 
|  | 162 | } | 
|  | 163 |  | 
| Chris Lattner | f496e79 | 2009-11-12 04:57:13 +0000 | [diff] [blame] | 164 | // RHS must be a constant, we must be undef, constant, or notconstant. | 
|  | 165 | if (isUndefined()) | 
|  | 166 | return markConstant(RHS.getConstant()); | 
|  | 167 |  | 
|  | 168 | if (isConstant()) { | 
|  | 169 | if (getConstant() != RHS.getConstant()) | 
|  | 170 | return markOverdefined(); | 
|  | 171 | return false; | 
|  | 172 | } | 
|  | 173 |  | 
|  | 174 | // If we are known "!=4" and RHS is "==5", stay at "!=4". | 
|  | 175 | if (getNotConstant() == RHS.getConstant() || | 
|  | 176 | isa<ConstantExpr>(getNotConstant()) || | 
|  | 177 | isa<ConstantExpr>(RHS.getConstant())) | 
| Chris Lattner | 1697652 | 2009-11-11 22:48:44 +0000 | [diff] [blame] | 178 | return markOverdefined(); | 
| Chris Lattner | f496e79 | 2009-11-12 04:57:13 +0000 | [diff] [blame] | 179 | return false; | 
| Chris Lattner | cc4d3b2 | 2009-11-11 02:08:33 +0000 | [diff] [blame] | 180 | } | 
|  | 181 |  | 
|  | 182 | }; | 
|  | 183 |  | 
|  | 184 | } // end anonymous namespace. | 
|  | 185 |  | 
| Chris Lattner | 1697652 | 2009-11-11 22:48:44 +0000 | [diff] [blame] | 186 | namespace llvm { | 
|  | 187 | raw_ostream &operator<<(raw_ostream &OS, const LVILatticeVal &Val) { | 
|  | 188 | if (Val.isUndefined()) | 
|  | 189 | return OS << "undefined"; | 
|  | 190 | if (Val.isOverdefined()) | 
|  | 191 | return OS << "overdefined"; | 
| Chris Lattner | b52675b | 2009-11-12 04:36:58 +0000 | [diff] [blame] | 192 |  | 
|  | 193 | if (Val.isNotConstant()) | 
|  | 194 | return OS << "notconstant<" << *Val.getNotConstant() << '>'; | 
| Chris Lattner | 1697652 | 2009-11-11 22:48:44 +0000 | [diff] [blame] | 195 | return OS << "constant<" << *Val.getConstant() << '>'; | 
|  | 196 | } | 
|  | 197 | } | 
| Chris Lattner | cc4d3b2 | 2009-11-11 02:08:33 +0000 | [diff] [blame] | 198 |  | 
|  | 199 | //===----------------------------------------------------------------------===// | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 200 | //                          LazyValueInfoCache Decl | 
| Chris Lattner | cc4d3b2 | 2009-11-11 02:08:33 +0000 | [diff] [blame] | 201 | //===----------------------------------------------------------------------===// | 
|  | 202 |  | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 203 | namespace { | 
|  | 204 | /// LazyValueInfoCache - This is the cache kept by LazyValueInfo which | 
|  | 205 | /// maintains information about queries across the clients' queries. | 
|  | 206 | class LazyValueInfoCache { | 
|  | 207 | public: | 
|  | 208 | /// BlockCacheEntryTy - This is a computed lattice value at the end of the | 
|  | 209 | /// specified basic block for a Value* that depends on context. | 
|  | 210 | typedef std::pair<BasicBlock*, LVILatticeVal> BlockCacheEntryTy; | 
|  | 211 |  | 
|  | 212 | /// ValueCacheEntryTy - This is all of the cached block information for | 
|  | 213 | /// exactly one Value*.  The entries are sorted by the BasicBlock* of the | 
|  | 214 | /// entries, allowing us to do a lookup with a binary search. | 
| Owen Anderson | 9a65dc9 | 2010-07-27 23:58:11 +0000 | [diff] [blame^] | 215 | typedef DenseMap<BasicBlock*, LVILatticeVal> ValueCacheEntryTy; | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 216 |  | 
|  | 217 | private: | 
|  | 218 | /// ValueCache - This is all of the cached information for all values, | 
|  | 219 | /// mapped from Value* to key information. | 
|  | 220 | DenseMap<Value*, ValueCacheEntryTy> ValueCache; | 
| Owen Anderson | cfa7fb6 | 2010-07-26 18:48:03 +0000 | [diff] [blame] | 221 |  | 
|  | 222 | /// OverDefinedCache - This tracks, on a per-block basis, the set of | 
|  | 223 | /// values that are over-defined at the end of that block.  This is required | 
|  | 224 | /// for cache updating. | 
| Owen Anderson | 9a65dc9 | 2010-07-27 23:58:11 +0000 | [diff] [blame^] | 225 | DenseSet<std::pair<BasicBlock*, Value*> > OverDefinedCache; | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 226 | public: | 
|  | 227 |  | 
|  | 228 | /// getValueInBlock - This is the query interface to determine the lattice | 
|  | 229 | /// value for the specified Value* at the end of the specified block. | 
|  | 230 | LVILatticeVal getValueInBlock(Value *V, BasicBlock *BB); | 
|  | 231 |  | 
|  | 232 | /// getValueOnEdge - This is the query interface to determine the lattice | 
|  | 233 | /// value for the specified Value* that is true on the specified edge. | 
|  | 234 | LVILatticeVal getValueOnEdge(Value *V, BasicBlock *FromBB,BasicBlock *ToBB); | 
| Owen Anderson | cfa7fb6 | 2010-07-26 18:48:03 +0000 | [diff] [blame] | 235 |  | 
|  | 236 | /// threadEdge - This is the update interface to inform the cache that an | 
|  | 237 | /// edge from PredBB to OldSucc has been threaded to be from PredBB to | 
|  | 238 | /// NewSucc. | 
|  | 239 | void threadEdge(BasicBlock *PredBB,BasicBlock *OldSucc,BasicBlock *NewSucc); | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 240 | }; | 
|  | 241 | } // end anonymous namespace | 
|  | 242 |  | 
| Chris Lattner | e564281 | 2009-11-15 20:00:52 +0000 | [diff] [blame] | 243 | namespace { | 
|  | 244 | struct BlockCacheEntryComparator { | 
|  | 245 | static int Compare(const void *LHSv, const void *RHSv) { | 
|  | 246 | const LazyValueInfoCache::BlockCacheEntryTy *LHS = | 
|  | 247 | static_cast<const LazyValueInfoCache::BlockCacheEntryTy *>(LHSv); | 
|  | 248 | const LazyValueInfoCache::BlockCacheEntryTy *RHS = | 
|  | 249 | static_cast<const LazyValueInfoCache::BlockCacheEntryTy *>(RHSv); | 
|  | 250 | if (LHS->first < RHS->first) | 
|  | 251 | return -1; | 
|  | 252 | if (LHS->first > RHS->first) | 
|  | 253 | return 1; | 
|  | 254 | return 0; | 
|  | 255 | } | 
|  | 256 |  | 
|  | 257 | bool operator()(const LazyValueInfoCache::BlockCacheEntryTy &LHS, | 
|  | 258 | const LazyValueInfoCache::BlockCacheEntryTy &RHS) const { | 
|  | 259 | return LHS.first < RHS.first; | 
|  | 260 | } | 
|  | 261 | }; | 
|  | 262 | } | 
|  | 263 |  | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 264 | //===----------------------------------------------------------------------===// | 
|  | 265 | //                              LVIQuery Impl | 
|  | 266 | //===----------------------------------------------------------------------===// | 
|  | 267 |  | 
|  | 268 | namespace { | 
|  | 269 | /// LVIQuery - This is a transient object that exists while a query is | 
|  | 270 | /// being performed. | 
| Chris Lattner | e564281 | 2009-11-15 20:00:52 +0000 | [diff] [blame] | 271 | /// | 
|  | 272 | /// TODO: Reuse LVIQuery instead of recreating it for every query, this avoids | 
|  | 273 | /// reallocation of the densemap on every query. | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 274 | class LVIQuery { | 
|  | 275 | typedef LazyValueInfoCache::BlockCacheEntryTy BlockCacheEntryTy; | 
|  | 276 | typedef LazyValueInfoCache::ValueCacheEntryTy ValueCacheEntryTy; | 
|  | 277 |  | 
| Chris Lattner | e564281 | 2009-11-15 20:00:52 +0000 | [diff] [blame] | 278 | /// This is the current value being queried for. | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 279 | Value *Val; | 
|  | 280 |  | 
|  | 281 | /// This is all of the cached information about this value. | 
|  | 282 | ValueCacheEntryTy &Cache; | 
|  | 283 |  | 
| Owen Anderson | cfa7fb6 | 2010-07-26 18:48:03 +0000 | [diff] [blame] | 284 | /// This tracks, for each block, what values are overdefined. | 
| Owen Anderson | 9a65dc9 | 2010-07-27 23:58:11 +0000 | [diff] [blame^] | 285 | DenseSet<std::pair<BasicBlock*, Value*> > &OverDefinedCache; | 
| Owen Anderson | cfa7fb6 | 2010-07-26 18:48:03 +0000 | [diff] [blame] | 286 |  | 
| Chris Lattner | d6add15 | 2009-11-16 03:51:42 +0000 | [diff] [blame] | 287 | ///  NewBlocks - This is a mapping of the new BasicBlocks which have been | 
| Chris Lattner | e564281 | 2009-11-15 20:00:52 +0000 | [diff] [blame] | 288 | /// added to cache but that are not in sorted order. | 
| Owen Anderson | 9a65dc9 | 2010-07-27 23:58:11 +0000 | [diff] [blame^] | 289 | DenseSet<BasicBlock*> NewBlockInfo; | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 290 | public: | 
|  | 291 |  | 
| Owen Anderson | cfa7fb6 | 2010-07-26 18:48:03 +0000 | [diff] [blame] | 292 | LVIQuery(Value *V, ValueCacheEntryTy &VC, | 
| Owen Anderson | 9a65dc9 | 2010-07-27 23:58:11 +0000 | [diff] [blame^] | 293 | DenseSet<std::pair<BasicBlock*, Value*> > &ODC) | 
| Owen Anderson | cfa7fb6 | 2010-07-26 18:48:03 +0000 | [diff] [blame] | 294 | : Val(V), Cache(VC), OverDefinedCache(ODC) { | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 295 | } | 
|  | 296 |  | 
| Chris Lattner | e564281 | 2009-11-15 20:00:52 +0000 | [diff] [blame] | 297 | ~LVIQuery() { | 
|  | 298 | // When the query is done, insert the newly discovered facts into the | 
|  | 299 | // cache in sorted order. | 
|  | 300 | if (NewBlockInfo.empty()) return; | 
| Chris Lattner | e564281 | 2009-11-15 20:00:52 +0000 | [diff] [blame] | 301 |  | 
| Owen Anderson | 9a65dc9 | 2010-07-27 23:58:11 +0000 | [diff] [blame^] | 302 | for (DenseSet<BasicBlock*>::iterator I = NewBlockInfo.begin(), | 
|  | 303 | E = NewBlockInfo.end(); I != E; ++I) { | 
|  | 304 | if (Cache[*I].isOverdefined()) | 
|  | 305 | OverDefinedCache.insert(std::make_pair(*I, Val)); | 
| Owen Anderson | cfa7fb6 | 2010-07-26 18:48:03 +0000 | [diff] [blame] | 306 | } | 
| Chris Lattner | e564281 | 2009-11-15 20:00:52 +0000 | [diff] [blame] | 307 | } | 
|  | 308 |  | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 309 | LVILatticeVal getBlockValue(BasicBlock *BB); | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 310 | LVILatticeVal getEdgeValue(BasicBlock *FromBB, BasicBlock *ToBB); | 
| Chris Lattner | e564281 | 2009-11-15 20:00:52 +0000 | [diff] [blame] | 311 |  | 
|  | 312 | private: | 
|  | 313 | LVILatticeVal &getCachedEntryForBlock(BasicBlock *BB); | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 314 | }; | 
|  | 315 | } // end anonymous namespace | 
|  | 316 |  | 
| Chris Lattner | e564281 | 2009-11-15 20:00:52 +0000 | [diff] [blame] | 317 | /// getCachedEntryForBlock - See if we already have a value for this block.  If | 
| Owen Anderson | 9a65dc9 | 2010-07-27 23:58:11 +0000 | [diff] [blame^] | 318 | /// so, return it, otherwise create a new entry in the Cache map to use. | 
| Chris Lattner | e564281 | 2009-11-15 20:00:52 +0000 | [diff] [blame] | 319 | LVILatticeVal &LVIQuery::getCachedEntryForBlock(BasicBlock *BB) { | 
| Owen Anderson | 9a65dc9 | 2010-07-27 23:58:11 +0000 | [diff] [blame^] | 320 | NewBlockInfo.insert(BB); | 
|  | 321 | return Cache[BB]; | 
| Chris Lattner | e564281 | 2009-11-15 20:00:52 +0000 | [diff] [blame] | 322 | } | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 323 |  | 
|  | 324 | LVILatticeVal LVIQuery::getBlockValue(BasicBlock *BB) { | 
|  | 325 | // See if we already have a value for this block. | 
| Chris Lattner | e564281 | 2009-11-15 20:00:52 +0000 | [diff] [blame] | 326 | LVILatticeVal &BBLV = getCachedEntryForBlock(BB); | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 327 |  | 
|  | 328 | // If we've already computed this block's value, return it. | 
| Chris Lattner | e564281 | 2009-11-15 20:00:52 +0000 | [diff] [blame] | 329 | if (!BBLV.isUndefined()) { | 
| David Greene | 5d93a1f | 2009-12-23 20:43:58 +0000 | [diff] [blame] | 330 | DEBUG(dbgs() << "  reuse BB '" << BB->getName() << "' val=" << BBLV <<'\n'); | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 331 | return BBLV; | 
| Chris Lattner | e564281 | 2009-11-15 20:00:52 +0000 | [diff] [blame] | 332 | } | 
|  | 333 |  | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 334 | // Otherwise, this is the first time we're seeing this block.  Reset the | 
|  | 335 | // lattice value to overdefined, so that cycles will terminate and be | 
|  | 336 | // conservatively correct. | 
|  | 337 | BBLV.markOverdefined(); | 
|  | 338 |  | 
|  | 339 | // If V is live into BB, see if our predecessors know anything about it. | 
|  | 340 | Instruction *BBI = dyn_cast<Instruction>(Val); | 
|  | 341 | if (BBI == 0 || BBI->getParent() != BB) { | 
|  | 342 | LVILatticeVal Result;  // Start Undefined. | 
|  | 343 | unsigned NumPreds = 0; | 
|  | 344 |  | 
|  | 345 | // Loop over all of our predecessors, merging what we know from them into | 
|  | 346 | // result. | 
|  | 347 | for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) { | 
|  | 348 | Result.mergeIn(getEdgeValue(*PI, BB)); | 
|  | 349 |  | 
|  | 350 | // If we hit overdefined, exit early.  The BlockVals entry is already set | 
|  | 351 | // to overdefined. | 
| Chris Lattner | e564281 | 2009-11-15 20:00:52 +0000 | [diff] [blame] | 352 | if (Result.isOverdefined()) { | 
| David Greene | 5d93a1f | 2009-12-23 20:43:58 +0000 | [diff] [blame] | 353 | DEBUG(dbgs() << " compute BB '" << BB->getName() | 
| Chris Lattner | e564281 | 2009-11-15 20:00:52 +0000 | [diff] [blame] | 354 | << "' - overdefined because of pred.\n"); | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 355 | return Result; | 
| Chris Lattner | e564281 | 2009-11-15 20:00:52 +0000 | [diff] [blame] | 356 | } | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 357 | ++NumPreds; | 
|  | 358 | } | 
|  | 359 |  | 
|  | 360 | // If this is the entry block, we must be asking about an argument.  The | 
|  | 361 | // value is overdefined. | 
|  | 362 | if (NumPreds == 0 && BB == &BB->getParent()->front()) { | 
|  | 363 | assert(isa<Argument>(Val) && "Unknown live-in to the entry block"); | 
|  | 364 | Result.markOverdefined(); | 
|  | 365 | return Result; | 
|  | 366 | } | 
|  | 367 |  | 
|  | 368 | // Return the merged value, which is more precise than 'overdefined'. | 
|  | 369 | assert(!Result.isOverdefined()); | 
| Chris Lattner | e564281 | 2009-11-15 20:00:52 +0000 | [diff] [blame] | 370 | return getCachedEntryForBlock(BB) = Result; | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 371 | } | 
|  | 372 |  | 
|  | 373 | // If this value is defined by an instruction in this block, we have to | 
|  | 374 | // process it here somehow or return overdefined. | 
|  | 375 | if (PHINode *PN = dyn_cast<PHINode>(BBI)) { | 
|  | 376 | (void)PN; | 
|  | 377 | // TODO: PHI Translation in preds. | 
|  | 378 | } else { | 
|  | 379 |  | 
|  | 380 | } | 
|  | 381 |  | 
| David Greene | 5d93a1f | 2009-12-23 20:43:58 +0000 | [diff] [blame] | 382 | DEBUG(dbgs() << " compute BB '" << BB->getName() | 
| Chris Lattner | e564281 | 2009-11-15 20:00:52 +0000 | [diff] [blame] | 383 | << "' - overdefined because inst def found.\n"); | 
|  | 384 |  | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 385 | LVILatticeVal Result; | 
|  | 386 | Result.markOverdefined(); | 
| Chris Lattner | e564281 | 2009-11-15 20:00:52 +0000 | [diff] [blame] | 387 | return getCachedEntryForBlock(BB) = Result; | 
| Chris Lattner | 10f2d13 | 2009-11-11 00:22:30 +0000 | [diff] [blame] | 388 | } | 
|  | 389 |  | 
| Chris Lattner | cc4d3b2 | 2009-11-11 02:08:33 +0000 | [diff] [blame] | 390 |  | 
| Chris Lattner | 800c47e | 2009-11-15 20:02:12 +0000 | [diff] [blame] | 391 | /// getEdgeValue - This method attempts to infer more complex | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 392 | LVILatticeVal LVIQuery::getEdgeValue(BasicBlock *BBFrom, BasicBlock *BBTo) { | 
| Chris Lattner | 800c47e | 2009-11-15 20:02:12 +0000 | [diff] [blame] | 393 | // TODO: Handle more complex conditionals.  If (v == 0 || v2 < 1) is false, we | 
|  | 394 | // know that v != 0. | 
| Chris Lattner | 1697652 | 2009-11-11 22:48:44 +0000 | [diff] [blame] | 395 | if (BranchInst *BI = dyn_cast<BranchInst>(BBFrom->getTerminator())) { | 
|  | 396 | // If this is a conditional branch and only one successor goes to BBTo, then | 
|  | 397 | // we maybe able to infer something from the condition. | 
|  | 398 | if (BI->isConditional() && | 
|  | 399 | BI->getSuccessor(0) != BI->getSuccessor(1)) { | 
|  | 400 | bool isTrueDest = BI->getSuccessor(0) == BBTo; | 
|  | 401 | assert(BI->getSuccessor(!isTrueDest) == BBTo && | 
|  | 402 | "BBTo isn't a successor of BBFrom"); | 
|  | 403 |  | 
|  | 404 | // If V is the condition of the branch itself, then we know exactly what | 
|  | 405 | // it is. | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 406 | if (BI->getCondition() == Val) | 
| Chris Lattner | 1697652 | 2009-11-11 22:48:44 +0000 | [diff] [blame] | 407 | return LVILatticeVal::get(ConstantInt::get( | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 408 | Type::getInt1Ty(Val->getContext()), isTrueDest)); | 
| Chris Lattner | 1697652 | 2009-11-11 22:48:44 +0000 | [diff] [blame] | 409 |  | 
|  | 410 | // If the condition of the branch is an equality comparison, we may be | 
|  | 411 | // able to infer the value. | 
|  | 412 | if (ICmpInst *ICI = dyn_cast<ICmpInst>(BI->getCondition())) | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 413 | if (ICI->isEquality() && ICI->getOperand(0) == Val && | 
| Chris Lattner | 1697652 | 2009-11-11 22:48:44 +0000 | [diff] [blame] | 414 | isa<Constant>(ICI->getOperand(1))) { | 
|  | 415 | // We know that V has the RHS constant if this is a true SETEQ or | 
|  | 416 | // false SETNE. | 
|  | 417 | if (isTrueDest == (ICI->getPredicate() == ICmpInst::ICMP_EQ)) | 
|  | 418 | return LVILatticeVal::get(cast<Constant>(ICI->getOperand(1))); | 
| Chris Lattner | b52675b | 2009-11-12 04:36:58 +0000 | [diff] [blame] | 419 | return LVILatticeVal::getNot(cast<Constant>(ICI->getOperand(1))); | 
| Chris Lattner | 1697652 | 2009-11-11 22:48:44 +0000 | [diff] [blame] | 420 | } | 
|  | 421 | } | 
|  | 422 | } | 
| Chris Lattner | 800c47e | 2009-11-15 20:02:12 +0000 | [diff] [blame] | 423 |  | 
|  | 424 | // If the edge was formed by a switch on the value, then we may know exactly | 
|  | 425 | // what it is. | 
|  | 426 | if (SwitchInst *SI = dyn_cast<SwitchInst>(BBFrom->getTerminator())) { | 
|  | 427 | // If BBTo is the default destination of the switch, we don't know anything. | 
|  | 428 | // Given a more powerful range analysis we could know stuff. | 
|  | 429 | if (SI->getCondition() == Val && SI->getDefaultDest() != BBTo) { | 
|  | 430 | // We only know something if there is exactly one value that goes from | 
|  | 431 | // BBFrom to BBTo. | 
|  | 432 | unsigned NumEdges = 0; | 
|  | 433 | ConstantInt *EdgeVal = 0; | 
|  | 434 | for (unsigned i = 1, e = SI->getNumSuccessors(); i != e; ++i) { | 
|  | 435 | if (SI->getSuccessor(i) != BBTo) continue; | 
|  | 436 | if (NumEdges++) break; | 
|  | 437 | EdgeVal = SI->getCaseValue(i); | 
|  | 438 | } | 
|  | 439 | assert(EdgeVal && "Missing successor?"); | 
|  | 440 | if (NumEdges == 1) | 
|  | 441 | return LVILatticeVal::get(EdgeVal); | 
|  | 442 | } | 
|  | 443 | } | 
| Chris Lattner | 1697652 | 2009-11-11 22:48:44 +0000 | [diff] [blame] | 444 |  | 
|  | 445 | // Otherwise see if the value is known in the block. | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 446 | return getBlockValue(BBFrom); | 
| Chris Lattner | 1697652 | 2009-11-11 22:48:44 +0000 | [diff] [blame] | 447 | } | 
|  | 448 |  | 
|  | 449 |  | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 450 | //===----------------------------------------------------------------------===// | 
|  | 451 | //                         LazyValueInfoCache Impl | 
|  | 452 | //===----------------------------------------------------------------------===// | 
|  | 453 |  | 
|  | 454 | LVILatticeVal LazyValueInfoCache::getValueInBlock(Value *V, BasicBlock *BB) { | 
|  | 455 | // If already a constant, there is nothing to compute. | 
| Chris Lattner | 1697652 | 2009-11-11 22:48:44 +0000 | [diff] [blame] | 456 | if (Constant *VC = dyn_cast<Constant>(V)) | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 457 | return LVILatticeVal::get(VC); | 
| Chris Lattner | 1697652 | 2009-11-11 22:48:44 +0000 | [diff] [blame] | 458 |  | 
| David Greene | 5d93a1f | 2009-12-23 20:43:58 +0000 | [diff] [blame] | 459 | DEBUG(dbgs() << "LVI Getting block end value " << *V << " at '" | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 460 | << BB->getName() << "'\n"); | 
|  | 461 |  | 
| Owen Anderson | cfa7fb6 | 2010-07-26 18:48:03 +0000 | [diff] [blame] | 462 | LVILatticeVal Result = LVIQuery(V, ValueCache[V], | 
|  | 463 | OverDefinedCache).getBlockValue(BB); | 
| Chris Lattner | 1697652 | 2009-11-11 22:48:44 +0000 | [diff] [blame] | 464 |  | 
| David Greene | 5d93a1f | 2009-12-23 20:43:58 +0000 | [diff] [blame] | 465 | DEBUG(dbgs() << "  Result = " << Result << "\n"); | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 466 | return Result; | 
|  | 467 | } | 
| Chris Lattner | 1697652 | 2009-11-11 22:48:44 +0000 | [diff] [blame] | 468 |  | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 469 | LVILatticeVal LazyValueInfoCache:: | 
|  | 470 | getValueOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB) { | 
|  | 471 | // If already a constant, there is nothing to compute. | 
|  | 472 | if (Constant *VC = dyn_cast<Constant>(V)) | 
|  | 473 | return LVILatticeVal::get(VC); | 
|  | 474 |  | 
| David Greene | 5d93a1f | 2009-12-23 20:43:58 +0000 | [diff] [blame] | 475 | DEBUG(dbgs() << "LVI Getting edge value " << *V << " from '" | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 476 | << FromBB->getName() << "' to '" << ToBB->getName() << "'\n"); | 
| Owen Anderson | cfa7fb6 | 2010-07-26 18:48:03 +0000 | [diff] [blame] | 477 |  | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 478 | LVILatticeVal Result = | 
| Owen Anderson | cfa7fb6 | 2010-07-26 18:48:03 +0000 | [diff] [blame] | 479 | LVIQuery(V, ValueCache[V], | 
|  | 480 | OverDefinedCache).getEdgeValue(FromBB, ToBB); | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 481 |  | 
| David Greene | 5d93a1f | 2009-12-23 20:43:58 +0000 | [diff] [blame] | 482 | DEBUG(dbgs() << "  Result = " << Result << "\n"); | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 483 |  | 
|  | 484 | return Result; | 
|  | 485 | } | 
|  | 486 |  | 
| Owen Anderson | cfa7fb6 | 2010-07-26 18:48:03 +0000 | [diff] [blame] | 487 | void LazyValueInfoCache::threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, | 
|  | 488 | BasicBlock *NewSucc) { | 
|  | 489 | // When an edge in the graph has been threaded, values that we could not | 
|  | 490 | // determine a value for before (i.e. were marked overdefined) may be possible | 
|  | 491 | // to solve now.  We do NOT try to proactively update these values.  Instead, | 
|  | 492 | // we clear their entries from the cache, and allow lazy updating to recompute | 
|  | 493 | // them when needed. | 
|  | 494 |  | 
|  | 495 | // The updating process is fairly simple: we need to dropped cached info | 
|  | 496 | // for all values that were marked overdefined in OldSucc, and for those same | 
|  | 497 | // values in any successor of OldSucc (except NewSucc) in which they were | 
|  | 498 | // also marked overdefined. | 
|  | 499 | std::vector<BasicBlock*> worklist; | 
|  | 500 | worklist.push_back(OldSucc); | 
|  | 501 |  | 
| Owen Anderson | 9a65dc9 | 2010-07-27 23:58:11 +0000 | [diff] [blame^] | 502 | DenseSet<Value*> ClearSet; | 
|  | 503 | for (DenseSet<std::pair<BasicBlock*, Value*> >::iterator | 
|  | 504 | I = OverDefinedCache.begin(), E = OverDefinedCache.end(); I != E; ++I) { | 
|  | 505 | if (I->first == OldSucc) | 
|  | 506 | ClearSet.insert(I->second); | 
|  | 507 | } | 
| Owen Anderson | cfa7fb6 | 2010-07-26 18:48:03 +0000 | [diff] [blame] | 508 |  | 
|  | 509 | // Use a worklist to perform a depth-first search of OldSucc's successors. | 
|  | 510 | // NOTE: We do not need a visited list since any blocks we have already | 
|  | 511 | // visited will have had their overdefined markers cleared already, and we | 
|  | 512 | // thus won't loop to their successors. | 
|  | 513 | while (!worklist.empty()) { | 
|  | 514 | BasicBlock *ToUpdate = worklist.back(); | 
|  | 515 | worklist.pop_back(); | 
|  | 516 |  | 
|  | 517 | // Skip blocks only accessible through NewSucc. | 
|  | 518 | if (ToUpdate == NewSucc) continue; | 
|  | 519 |  | 
|  | 520 | bool changed = false; | 
| Owen Anderson | 9a65dc9 | 2010-07-27 23:58:11 +0000 | [diff] [blame^] | 521 | for (DenseSet<Value*>::iterator I = ClearSet.begin(),E = ClearSet.end(); | 
| Owen Anderson | cfa7fb6 | 2010-07-26 18:48:03 +0000 | [diff] [blame] | 522 | I != E; ++I) { | 
|  | 523 | // If a value was marked overdefined in OldSucc, and is here too... | 
| Owen Anderson | 9a65dc9 | 2010-07-27 23:58:11 +0000 | [diff] [blame^] | 524 | DenseSet<std::pair<BasicBlock*, Value*> >::iterator OI = | 
|  | 525 | OverDefinedCache.find(std::make_pair(ToUpdate, *I)); | 
|  | 526 | if (OI == OverDefinedCache.end()) continue; | 
| Owen Anderson | cfa7fb6 | 2010-07-26 18:48:03 +0000 | [diff] [blame] | 527 |  | 
| Owen Anderson | 9a65dc9 | 2010-07-27 23:58:11 +0000 | [diff] [blame^] | 528 | // Remove it from the caches. | 
|  | 529 | ValueCacheEntryTy &Entry = ValueCache[*I]; | 
|  | 530 | ValueCacheEntryTy::iterator CI = Entry.find(ToUpdate); | 
|  | 531 |  | 
|  | 532 | assert(CI != Entry.end() && "Couldn't find entry to update?"); | 
|  | 533 | Entry.erase(CI); | 
|  | 534 | OverDefinedCache.erase(OI); | 
| Owen Anderson | cfa7fb6 | 2010-07-26 18:48:03 +0000 | [diff] [blame] | 535 |  | 
| Owen Anderson | 9a65dc9 | 2010-07-27 23:58:11 +0000 | [diff] [blame^] | 536 | // If we removed anything, then we potentially need to update | 
|  | 537 | // blocks successors too. | 
|  | 538 | changed = true; | 
| Owen Anderson | cfa7fb6 | 2010-07-26 18:48:03 +0000 | [diff] [blame] | 539 | } | 
|  | 540 |  | 
|  | 541 | if (!changed) continue; | 
|  | 542 |  | 
|  | 543 | worklist.insert(worklist.end(), succ_begin(ToUpdate), succ_end(ToUpdate)); | 
|  | 544 | } | 
|  | 545 | } | 
|  | 546 |  | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 547 | //===----------------------------------------------------------------------===// | 
|  | 548 | //                            LazyValueInfo Impl | 
|  | 549 | //===----------------------------------------------------------------------===// | 
|  | 550 |  | 
|  | 551 | bool LazyValueInfo::runOnFunction(Function &F) { | 
|  | 552 | TD = getAnalysisIfAvailable<TargetData>(); | 
|  | 553 | // Fully lazy. | 
|  | 554 | return false; | 
|  | 555 | } | 
|  | 556 |  | 
|  | 557 | /// getCache - This lazily constructs the LazyValueInfoCache. | 
|  | 558 | static LazyValueInfoCache &getCache(void *&PImpl) { | 
|  | 559 | if (!PImpl) | 
|  | 560 | PImpl = new LazyValueInfoCache(); | 
|  | 561 | return *static_cast<LazyValueInfoCache*>(PImpl); | 
|  | 562 | } | 
|  | 563 |  | 
|  | 564 | void LazyValueInfo::releaseMemory() { | 
|  | 565 | // If the cache was allocated, free it. | 
|  | 566 | if (PImpl) { | 
|  | 567 | delete &getCache(PImpl); | 
|  | 568 | PImpl = 0; | 
|  | 569 | } | 
|  | 570 | } | 
|  | 571 |  | 
|  | 572 | Constant *LazyValueInfo::getConstant(Value *V, BasicBlock *BB) { | 
|  | 573 | LVILatticeVal Result = getCache(PImpl).getValueInBlock(V, BB); | 
|  | 574 |  | 
| Chris Lattner | 1697652 | 2009-11-11 22:48:44 +0000 | [diff] [blame] | 575 | if (Result.isConstant()) | 
|  | 576 | return Result.getConstant(); | 
|  | 577 | return 0; | 
|  | 578 | } | 
| Chris Lattner | cc4d3b2 | 2009-11-11 02:08:33 +0000 | [diff] [blame] | 579 |  | 
| Chris Lattner | 38392bb | 2009-11-12 01:29:10 +0000 | [diff] [blame] | 580 | /// getConstantOnEdge - Determine whether the specified value is known to be a | 
|  | 581 | /// constant on the specified edge.  Return null if not. | 
|  | 582 | Constant *LazyValueInfo::getConstantOnEdge(Value *V, BasicBlock *FromBB, | 
|  | 583 | BasicBlock *ToBB) { | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 584 | LVILatticeVal Result = getCache(PImpl).getValueOnEdge(V, FromBB, ToBB); | 
| Chris Lattner | 38392bb | 2009-11-12 01:29:10 +0000 | [diff] [blame] | 585 |  | 
|  | 586 | if (Result.isConstant()) | 
|  | 587 | return Result.getConstant(); | 
|  | 588 | return 0; | 
|  | 589 | } | 
|  | 590 |  | 
| Chris Lattner | b52675b | 2009-11-12 04:36:58 +0000 | [diff] [blame] | 591 | /// getPredicateOnEdge - Determine whether the specified value comparison | 
|  | 592 | /// with a constant is known to be true or false on the specified CFG edge. | 
|  | 593 | /// Pred is a CmpInst predicate. | 
| Chris Lattner | cc4d3b2 | 2009-11-11 02:08:33 +0000 | [diff] [blame] | 594 | LazyValueInfo::Tristate | 
| Chris Lattner | b52675b | 2009-11-12 04:36:58 +0000 | [diff] [blame] | 595 | LazyValueInfo::getPredicateOnEdge(unsigned Pred, Value *V, Constant *C, | 
|  | 596 | BasicBlock *FromBB, BasicBlock *ToBB) { | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 597 | LVILatticeVal Result = getCache(PImpl).getValueOnEdge(V, FromBB, ToBB); | 
| Chris Lattner | cc4d3b2 | 2009-11-11 02:08:33 +0000 | [diff] [blame] | 598 |  | 
| Chris Lattner | b52675b | 2009-11-12 04:36:58 +0000 | [diff] [blame] | 599 | // If we know the value is a constant, evaluate the conditional. | 
|  | 600 | Constant *Res = 0; | 
|  | 601 | if (Result.isConstant()) { | 
|  | 602 | Res = ConstantFoldCompareInstOperands(Pred, Result.getConstant(), C, TD); | 
|  | 603 | if (ConstantInt *ResCI = dyn_cast_or_null<ConstantInt>(Res)) | 
|  | 604 | return ResCI->isZero() ? False : True; | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 605 | return Unknown; | 
|  | 606 | } | 
|  | 607 |  | 
|  | 608 | if (Result.isNotConstant()) { | 
| Chris Lattner | b52675b | 2009-11-12 04:36:58 +0000 | [diff] [blame] | 609 | // If this is an equality comparison, we can try to fold it knowing that | 
|  | 610 | // "V != C1". | 
|  | 611 | if (Pred == ICmpInst::ICMP_EQ) { | 
|  | 612 | // !C1 == C -> false iff C1 == C. | 
|  | 613 | Res = ConstantFoldCompareInstOperands(ICmpInst::ICMP_NE, | 
|  | 614 | Result.getNotConstant(), C, TD); | 
|  | 615 | if (Res->isNullValue()) | 
|  | 616 | return False; | 
|  | 617 | } else if (Pred == ICmpInst::ICMP_NE) { | 
|  | 618 | // !C1 != C -> true iff C1 == C. | 
| Chris Lattner | 5553a3a | 2009-11-15 20:01:24 +0000 | [diff] [blame] | 619 | Res = ConstantFoldCompareInstOperands(ICmpInst::ICMP_NE, | 
| Chris Lattner | b52675b | 2009-11-12 04:36:58 +0000 | [diff] [blame] | 620 | Result.getNotConstant(), C, TD); | 
|  | 621 | if (Res->isNullValue()) | 
|  | 622 | return True; | 
|  | 623 | } | 
| Chris Lattner | 2c5adf8 | 2009-11-15 19:59:49 +0000 | [diff] [blame] | 624 | return Unknown; | 
| Chris Lattner | b52675b | 2009-11-12 04:36:58 +0000 | [diff] [blame] | 625 | } | 
|  | 626 |  | 
| Chris Lattner | cc4d3b2 | 2009-11-11 02:08:33 +0000 | [diff] [blame] | 627 | return Unknown; | 
|  | 628 | } | 
|  | 629 |  | 
| Owen Anderson | cfa7fb6 | 2010-07-26 18:48:03 +0000 | [diff] [blame] | 630 | void LazyValueInfo::threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, | 
|  | 631 | BasicBlock* NewSucc) { | 
|  | 632 | getCache(PImpl).threadEdge(PredBB, OldSucc, NewSucc); | 
|  | 633 | } |