Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(194)

Side by Side Diff: src/hydrogen-instructions.cc

Issue 9156001: Improved range analysis for bitwise operations. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen-instructions.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « src/hydrogen-instructions.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698