| 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 ba9360352aa6ada659c7343fdff0a1dc3a6949ef..fcf55ee2ddc130d8b68069537f81160bc2127510 100644
|
| --- a/runtime/vm/flow_graph_range_analysis.cc
|
| +++ b/runtime/vm/flow_graph_range_analysis.cc
|
| @@ -2256,6 +2256,12 @@ void Range::Clamp(RangeBoundary::RangeSize size) {
|
| }
|
|
|
|
|
| +void Range::ClampToConstant(RangeBoundary::RangeSize size) {
|
| + min_ = min_.LowerBound().Clamp(size);
|
| + max_ = max_.UpperBound().Clamp(size);
|
| +}
|
| +
|
| +
|
| void Range::Shl(const Range* left,
|
| const Range* right,
|
| RangeBoundary* result_min,
|
| @@ -2886,10 +2892,32 @@ void BinaryIntegerOpInstr::InferRangeHelper(const Range* left_range,
|
| }
|
|
|
|
|
| +static void CacheRange(Range** slot,
|
| + const Range* range,
|
| + RangeBoundary::RangeSize size) {
|
| + if (range != NULL) {
|
| + if (*slot == NULL) {
|
| + *slot = new Range();
|
| + }
|
| + **slot = *range;
|
| +
|
| + // Eliminate any symbolic dependencies from the range information.
|
| + (*slot)->ClampToConstant(size);
|
| + } else if (*slot != NULL) {
|
| + **slot = Range(); // Clear cached range information.
|
| + }
|
| +}
|
| +
|
| +
|
| void BinarySmiOpInstr::InferRange(RangeAnalysis* analysis, Range* range) {
|
| + const Range* right_smi_range = analysis->GetSmiRange(right());
|
| // TODO(vegorov) completely remove this once GetSmiRange is eliminated.
|
| - InferRangeHelper(analysis->GetSmiRange(left()),
|
| - analysis->GetSmiRange(right()), range);
|
| + if (op_kind() == Token::kSHR || op_kind() == Token::kSHL ||
|
| + op_kind() == Token::kMOD || op_kind() == Token::kTRUNCDIV) {
|
| + CacheRange(&right_range_, right_smi_range,
|
| + RangeBoundary::kRangeBoundarySmi);
|
| + }
|
| + InferRangeHelper(analysis->GetSmiRange(left()), right_smi_range, range);
|
| }
|
|
|
|
|
| @@ -2906,6 +2934,8 @@ void BinaryMintOpInstr::InferRange(RangeAnalysis* analysis, Range* range) {
|
|
|
|
|
| void ShiftMintOpInstr::InferRange(RangeAnalysis* analysis, Range* range) {
|
| + CacheRange(&shift_range_, right()->definition()->range(),
|
| + RangeBoundary::kRangeBoundaryInt64);
|
| InferRangeHelper(left()->definition()->range(),
|
| right()->definition()->range(), range);
|
| }
|
|
|