Chromium Code Reviews| Index: lib/compiler/implementation/ssa/value_range_analyzer.dart |
| =================================================================== |
| --- lib/compiler/implementation/ssa/value_range_analyzer.dart (revision 13343) |
| +++ lib/compiler/implementation/ssa/value_range_analyzer.dart (working copy) |
| @@ -52,12 +52,18 @@ |
| } |
| Value operator -(other) { |
| - if (other is !IntValue) return other - this; |
| + if (other is !IntValue) { |
| + 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
|
| + } |
| return new IntValue(value - other.value); |
| } |
| Value operator &(other) { |
| - if (other is !IntValue) return this; |
| + if (other is !IntValue) { |
| + if (isPositive()) return this; |
| + 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,
|
| + return const UnknownValue(); |
| + } |
| return new IntValue(value & other.value); |
| } |
| @@ -286,11 +292,34 @@ |
| } |
| Range operator -(Range other) { |
| - return new Range.normalize(lower - other.lower, upper - other.upper); |
| + return new Range.normalize(lower - other.upper, upper - other.lower); |
| } |
| Range operator &(Range other) { |
| - return new Range.normalize(lower & other.lower, upper & other.upper); |
| + if (isSingleValue() |
| + && other.isSingleValue() |
| + && lower is IntValue |
| + && other.lower is IntValue) { |
| + return new Range(lower & other.lower, upper & other.upper); |
| + } |
| + if (isPositive() && other.isPositive()) { |
| + Value up = upper.min(other.upper); |
| + if (up == const UnknownValue()) { |
| + // If we could not find a trivial bound, just try to use the |
| + // one that is an int. |
| + up = upper is IntValue ? upper : other.upper; |
| + // Make sure we get the same upper bound, whether it's a & b |
| + // or b & a. |
| + if (up is! IntValue && upper != other.upper) up = const MaxIntValue(); |
| + } |
| + return new Range(const IntValue(0), up); |
| + } else if (isPositive()) { |
| + return new Range(const IntValue(0), upper); |
| + } else if (other.isPositive()) { |
| + return new Range(const IntValue(0), other.upper); |
| + } else { |
| + return const Range.unbound(); |
| + } |
| } |
| bool operator ==(other) { |