Chromium Code Reviews| Index: runtime/vm/flow_graph_range_analysis.cc |
| diff --git a/runtime/vm/flow_graph_range_analysis.cc b/runtime/vm/flow_graph_range_analysis.cc |
| index f731c5539ca2586eb3dd9237f49d54e8a11f60e7..1ba289125a91102f630466ac8f026c0a7a6f2c16 100644 |
| --- a/runtime/vm/flow_graph_range_analysis.cc |
| +++ b/runtime/vm/flow_graph_range_analysis.cc |
| @@ -2427,6 +2427,33 @@ bool Range::And(const Range* left_range, |
| } |
| +static int BitSize(const Range* range) { |
| + const int64_t min = Range::ConstantMin(range).ConstantValue(); |
| + const int64_t max = Range::ConstantMax(range).ConstantValue(); |
| + return Utils::Maximum(Utils::HighestBit(max >= 0 ? max : 0), |
|
Florian Schneider
2014/11/11 11:48:35
HighestBit already takes the sign into account, so
Vyacheslav Egorov (Google)
2014/11/11 14:29:40
Done.
|
| + Utils::HighestBit(min < -1 ? ~min : 0)) + 1; |
| +} |
| + |
| + |
| +void Range::Xor(const Range* left_range, |
|
Florian Schneider
2014/11/11 11:48:34
Please add test coverage for Xor to flow_graph_ran
Vyacheslav Egorov (Google)
2014/11/11 14:29:40
Done.
|
| + const Range* right_range, |
| + RangeBoundary* result_min, |
| + RangeBoundary* result_max) { |
| + const int bitsize = |
| + Utils::Maximum(BitSize(left_range), BitSize(right_range)); |
| + |
| + if (left_range->IsPositive() && right_range->IsPositive()) { |
| + *result_min = RangeBoundary::FromConstant(0); |
| + } else { |
| + *result_min = RangeBoundary::FromConstant( |
| + static_cast<int64_t>(-1) << bitsize); |
| + } |
| + |
| + *result_max = RangeBoundary::FromConstant( |
| + (static_cast<uint64_t>(1) << bitsize) - 1); |
| +} |
| + |
| + |
| static bool IsArrayLength(Definition* defn) { |
| if (defn == NULL) { |
| return false; |
| @@ -2595,12 +2622,18 @@ void Range::BinaryOp(const Token::Kind op, |
| Range::Shr(left_range, right_range, &min, &max); |
| break; |
| } |
| + |
| case Token::kBIT_AND: |
| if (!Range::And(left_range, right_range, &min, &max)) { |
| *result = Range::Full(RangeBoundary::kRangeBoundaryInt64); |
| return; |
| } |
| break; |
| + |
| + case Token::kBIT_XOR: |
| + Range::Xor(left_range, right_range, &min, &max); |
| + break; |
| + |
| default: |
| *result = Range::Full(RangeBoundary::kRangeBoundaryInt64); |
| return; |