OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
101 return ConvertAndSetOverflow(result, overflow); | 101 return ConvertAndSetOverflow(result, overflow); |
102 } | 102 } |
103 | 103 |
104 | 104 |
105 static int32_t MulWithoutOverflow(int32_t a, int32_t b, bool* overflow) { | 105 static int32_t MulWithoutOverflow(int32_t a, int32_t b, bool* overflow) { |
106 int64_t result = static_cast<int64_t>(a) * static_cast<int64_t>(b); | 106 int64_t result = static_cast<int64_t>(a) * static_cast<int64_t>(b); |
107 return ConvertAndSetOverflow(result, overflow); | 107 return ConvertAndSetOverflow(result, overflow); |
108 } | 108 } |
109 | 109 |
110 | 110 |
111 int32_t Range::Mask() const { | 111 class BitRange { |
112 if (lower_ == upper_) return lower_; | 112 public: |
113 if (lower_ >= 0) { | 113 BitRange() : known_(0), bits_(0) { } |
114 int32_t res = 1; | 114 BitRange(int32_t known, int32_t bits) |
115 while (res < upper_) { | 115 : known_(known), bits_(bits & known) { } |
116 res = (res << 1) | 1; | 116 |
117 } | 117 static void SetFromRange(BitRange* bits, int32_t lower, int32_t upper) { |
118 return res; | 118 // Find a mask for the most significant bits that are the same for all |
119 // values in the range. | |
120 int32_t same = ~(lower ^ upper); | |
121 // Flood zeros to any bits lower than the most significant zero. | |
122 same &= (same >> 1); | |
123 same &= (same >> 2); | |
124 same &= (same >> 4); | |
125 same &= (same >> 8); | |
126 same &= (same >> 16); | |
127 | |
128 bits->known_ = same; | |
129 bits->bits_ = lower & same; | |
119 } | 130 } |
120 return 0xffffffff; | 131 |
132 void ExtendRange(int32_t* lower, int32_t* upper) { | |
133 int32_t limit1 = (~known_ & 0x80000000) | bits_; | |
134 int32_t limit2 = (~known_ & 0x7fffffff) | bits_; | |
135 *lower = Min(*lower, Min(limit1, limit2)); | |
136 *upper = Max(*upper, Max(limit1, limit2)); | |
137 } | |
138 | |
139 static BitRange And(BitRange a, BitRange b) { | |
140 int32_t known = a.known_ & b.known_; | |
141 // Zeros in either operand become known. | |
142 known |= (a.known_ & ~a.bits_); | |
143 known |= (b.known_ & ~b.bits_); | |
144 return BitRange(known, a.bits_ & b.bits_); | |
145 } | |
146 | |
147 static BitRange Or(BitRange a, BitRange b) { | |
148 int32_t known = a.known_ & b.known_; | |
149 // Ones in either operand become known. | |
150 known |= (a.known_ & a.bits_); | |
151 known |= (b.known_ & b.bits_); | |
152 return BitRange(known, a.bits_ | b.bits_); | |
153 } | |
154 | |
155 static BitRange Xor(BitRange a, BitRange b) { | |
156 return BitRange(a.known_ & b.known_, a.bits_ ^ b.bits_); | |
157 } | |
158 | |
159 private: | |
160 int32_t known_; // A mask of known bits. | |
161 int32_t bits_; // Values of known bits, zero elsewhere. | |
162 }; | |
163 | |
164 | |
165 void Range::ToBitRange(BitRange* bits) const { | |
166 BitRange::SetFromRange(bits, lower_, upper_); | |
121 } | 167 } |
122 | 168 |
123 | 169 |
124 void Range::AddConstant(int32_t value) { | 170 void Range::AddConstant(int32_t value) { |
125 if (value == 0) return; | 171 if (value == 0) return; |
126 bool may_overflow = false; // Overflow is ignored here. | 172 bool may_overflow = false; // Overflow is ignored here. |
127 lower_ = AddWithoutOverflow(lower_, value, &may_overflow); | 173 lower_ = AddWithoutOverflow(lower_, value, &may_overflow); |
128 upper_ = AddWithoutOverflow(upper_, value, &may_overflow); | 174 upper_ = AddWithoutOverflow(upper_, value, &may_overflow); |
129 #ifdef DEBUG | 175 #ifdef DEBUG |
130 Verify(); | 176 Verify(); |
(...skipping 1105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1236 void HBinaryOperation::PrintDataTo(StringStream* stream) { | 1282 void HBinaryOperation::PrintDataTo(StringStream* stream) { |
1237 left()->PrintNameTo(stream); | 1283 left()->PrintNameTo(stream); |
1238 stream->Add(" "); | 1284 stream->Add(" "); |
1239 right()->PrintNameTo(stream); | 1285 right()->PrintNameTo(stream); |
1240 if (CheckFlag(kCanOverflow)) stream->Add(" !"); | 1286 if (CheckFlag(kCanOverflow)) stream->Add(" !"); |
1241 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); | 1287 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); |
1242 } | 1288 } |
1243 | 1289 |
1244 | 1290 |
1245 Range* HBitwise::InferRange() { | 1291 Range* HBitwise::InferRange() { |
1246 if (op() == Token::BIT_XOR) return HValue::InferRange(); | 1292 if (representation().IsInteger32()) { |
1247 int32_t left_mask = (left()->range() != NULL) | 1293 BitRange left_bits, right_bits; |
1248 ? left()->range()->Mask() | 1294 |
1249 : 0xffffffff; | 1295 if (left()->range() != NULL) |
1250 int32_t right_mask = (right()->range() != NULL) | 1296 left()->range()->ToBitRange(&left_bits); |
1251 ? right()->range()->Mask() | 1297 |
1252 : 0xffffffff; | 1298 if (right()->range() != NULL) |
1253 int32_t result_mask = (op() == Token::BIT_AND) | 1299 right()->range()->ToBitRange(&right_bits); |
1254 ? left_mask & right_mask | 1300 |
1255 : left_mask | right_mask; | 1301 BitRange result; |
1256 return (result_mask >= 0) | 1302 switch (op()) { |
1257 ? new Range(0, result_mask) | 1303 case Token::BIT_AND: |
1258 : HValue::InferRange(); | 1304 result = BitRange::And(left_bits, right_bits); |
1305 break; | |
1306 case Token::BIT_OR: | |
1307 result = BitRange::Or(left_bits, right_bits); | |
1308 break; | |
1309 case Token::BIT_XOR: | |
1310 result = BitRange::Xor(left_bits, right_bits); | |
1311 break; | |
1312 default: | |
1313 UNREACHABLE(); | |
1314 } | |
1315 | |
1316 int32_t lower = kMaxInt, upper = kMinInt; // 'empty' range. | |
1317 result.ExtendRange(&lower, &upper); | |
fschneider
2012/02/28 13:26:52
I'd simplify this by propagating the inputs kMaxIn
sra1
2013/06/11 05:19:15
This looks a little strange but let me explain.
T
fschneider
2013/06/11 10:22:37
Thanks for the explanation. The code just looked s
| |
1318 return new Range(lower, upper); | |
1319 } else { | |
1320 return HValue::InferRange(); | |
1321 } | |
1259 } | 1322 } |
1260 | 1323 |
1261 | 1324 |
1262 Range* HSar::InferRange() { | 1325 Range* HSar::InferRange() { |
1263 if (right()->IsConstant()) { | 1326 if (right()->IsConstant()) { |
1264 HConstant* c = HConstant::cast(right()); | 1327 HConstant* c = HConstant::cast(right()); |
1265 if (c->HasInteger32Value()) { | 1328 if (c->HasInteger32Value()) { |
1266 Range* result = (left()->range() != NULL) | 1329 Range* result = (left()->range() != NULL) |
1267 ? left()->range()->Copy() | 1330 ? left()->range()->Copy() |
1268 : new Range(); | 1331 : new Range(); |
(...skipping 837 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2106 | 2169 |
2107 | 2170 |
2108 void HCheckPrototypeMaps::Verify() { | 2171 void HCheckPrototypeMaps::Verify() { |
2109 HInstruction::Verify(); | 2172 HInstruction::Verify(); |
2110 ASSERT(HasNoUses()); | 2173 ASSERT(HasNoUses()); |
2111 } | 2174 } |
2112 | 2175 |
2113 #endif | 2176 #endif |
2114 | 2177 |
2115 } } // namespace v8::internal | 2178 } } // namespace v8::internal |
OLD | NEW |