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

Side by Side Diff: lib/compiler/implementation/ssa/value_range_analyzer.dart

Issue 11042002: Fix buggy computations in value ranges, spotted by floitsch@. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 2 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 | « no previous file | tests/compiler/dart2js/value_range2_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /** 5 /**
6 * A [Value] represents both symbolic values like the value of a 6 * A [Value] represents both symbolic values like the value of a
7 * parameter, or the length of an array, and concrete values, like 7 * parameter, or the length of an array, and concrete values, like
8 * constants. 8 * constants.
9 */ 9 */
10 abstract class Value { 10 abstract class Value {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 class IntValue extends Value { 45 class IntValue extends Value {
46 final int value; 46 final int value;
47 const IntValue(this.value); 47 const IntValue(this.value);
48 48
49 Value operator +(other) { 49 Value operator +(other) {
50 if (other is !IntValue) return other + this; 50 if (other is !IntValue) return other + this;
51 return new IntValue(value + other.value); 51 return new IntValue(value + other.value);
52 } 52 }
53 53
54 Value operator -(other) { 54 Value operator -(other) {
55 if (other is !IntValue) return other - this; 55 if (other is !IntValue) {
56 return new OperationValue(this, other, const SubtractOperation());
floitsch 2012/10/10 15:19:59 you shouldn't use the operations directly but fetc
ngeoffray 2012/10/15 12:17:23 I removed this code, so it's not a problem anymore
57 }
56 return new IntValue(value - other.value); 58 return new IntValue(value - other.value);
57 } 59 }
58 60
59 Value operator &(other) { 61 Value operator &(other) {
60 if (other is !IntValue) return this; 62 if (other is !IntValue) {
63 if (isPositive()) return this;
64 if (other.isPositive()) return new IntValue(-value);
floitsch 2012/10/10 15:19:59 I don't think this is true. -1 & FF => FF and not
ngeoffray 2012/10/15 12:17:23 Well spotted. Actually I think this is dead code,
65 return const UnknownValue();
66 }
61 return new IntValue(value & other.value); 67 return new IntValue(value & other.value);
62 } 68 }
63 69
64 Value min(other) { 70 Value min(other) {
65 if (other is !IntValue) return other.min(this); 71 if (other is !IntValue) return other.min(this);
66 return this.value < other.value ? this : other; 72 return this.value < other.value ? this : other;
67 } 73 }
68 74
69 Value max(other) { 75 Value max(other) {
70 if (other is !IntValue) return other.max(this); 76 if (other is !IntValue) return other.max(this);
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 else up = upper; 285 else up = upper;
280 } 286 }
281 return new Range(low, up); 287 return new Range(low, up);
282 } 288 }
283 289
284 Range operator +(Range other) { 290 Range operator +(Range other) {
285 return new Range.normalize(lower + other.lower, upper + other.upper); 291 return new Range.normalize(lower + other.lower, upper + other.upper);
286 } 292 }
287 293
288 Range operator -(Range other) { 294 Range operator -(Range other) {
289 return new Range.normalize(lower - other.lower, upper - other.upper); 295 return new Range.normalize(lower - other.upper, upper - other.lower);
290 } 296 }
291 297
292 Range operator &(Range other) { 298 Range operator &(Range other) {
293 return new Range.normalize(lower & other.lower, upper & other.upper); 299 if (isSingleValue()
300 && other.isSingleValue()
301 && lower is IntValue
302 && other.lower is IntValue) {
303 return new Range(lower & other.lower, upper & other.upper);
304 }
305 if (isPositive() && other.isPositive()) {
306 Value up = upper.min(other.upper);
307 if (up == const UnknownValue()) {
308 // If we could not find a trivial bound, just try to use the
309 // one that is an int.
310 up = upper is IntValue ? upper : other.upper;
311 // Make sure we get the same upper bound, whether it's a & b
312 // or b & a.
313 if (up is! IntValue && upper != other.upper) up = const MaxIntValue();
314 }
315 return new Range(const IntValue(0), up);
316 } else if (isPositive()) {
317 return new Range(const IntValue(0), upper);
318 } else if (other.isPositive()) {
319 return new Range(const IntValue(0), other.upper);
320 } else {
321 return const Range.unbound();
322 }
294 } 323 }
295 324
296 bool operator ==(other) { 325 bool operator ==(other) {
297 if (other is! Range) return false; 326 if (other is! Range) return false;
298 return other.lower == lower && other.upper == upper; 327 return other.lower == lower && other.upper == upper;
299 } 328 }
300 329
301 bool operator <(Range other) { 330 bool operator <(Range other) {
302 return upper != other.lower && upper.min(other.lower) == upper; 331 return upper != other.lower && upper.min(other.lower) == upper;
303 } 332 }
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after
774 if (instruction is HPhi && !instruction.block.isLoopHeader()) { 803 if (instruction is HPhi && !instruction.block.isLoopHeader()) {
775 HInstruction result = unwrap(instruction.inputs[0]); 804 HInstruction result = unwrap(instruction.inputs[0]);
776 for (int i = 1; i < instruction.inputs.length; i++) { 805 for (int i = 1; i < instruction.inputs.length; i++) {
777 if (result != unwrap(instruction.inputs[i])) return instruction; 806 if (result != unwrap(instruction.inputs[i])) return instruction;
778 } 807 }
779 return result; 808 return result;
780 } 809 }
781 return instruction; 810 return instruction;
782 } 811 }
783 } 812 }
OLDNEW
« no previous file with comments | « no previous file | tests/compiler/dart2js/value_range2_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698