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 9d2da24fdb07fa58b9cfb3a3f69eb126a8a68621..84189367813d85dd5b501821cf30b7d5f645e680 100644 |
| --- a/runtime/vm/flow_graph_range_analysis.cc |
| +++ b/runtime/vm/flow_graph_range_analysis.cc |
| @@ -701,7 +701,7 @@ static void NarrowBinaryMintOp(BinaryMintOpInstr* mint_op) { |
| mint_op->right()->CopyWithType(), |
| mint_op->DeoptimizationTarget()); |
| int32_op->set_range(*mint_op->range()); |
| - int32_op->set_overflow(false); |
| + int32_op->set_can_overflow(false); |
| mint_op->ReplaceWith(int32_op, NULL); |
| } |
| } |
| @@ -722,7 +722,7 @@ static void NarrowShiftMintOp(ShiftMintOpInstr* mint_op) { |
| mint_op->right()->CopyWithType(), |
| mint_op->DeoptimizationTarget()); |
| int32_op->set_range(*mint_op->range()); |
| - int32_op->set_overflow(false); |
| + int32_op->set_can_overflow(false); |
| mint_op->ReplaceWith(int32_op, NULL); |
| } |
| } |
| @@ -1993,32 +1993,77 @@ void IfThenElseInstr::InferRange(RangeAnalysis* analysis, Range* range) { |
| } |
| -void BinarySmiOpInstr::InferRange(RangeAnalysis* analysis, Range* range) { |
| - // TODO(vegorov): canonicalize BinarySmiOp to always have constant on the |
| - // right and a non-constant on the left. |
| - Definition* left_defn = left()->definition(); |
| +static RangeBoundary::RangeSize RepresentationToRangeSize(Representation r) { |
| + switch (r) { |
| + case kTagged: |
| + return RangeBoundary::kRangeBoundarySmi; |
| + case kUnboxedInt32: |
| + return RangeBoundary::kRangeBoundaryInt32; |
| + case kUnboxedMint: |
| + return RangeBoundary::kRangeBoundaryInt64; |
| + default: |
| + UNREACHABLE(); |
| + return RangeBoundary::kRangeBoundarySmi; |
| + } |
| +} |
| - const Range* left_range = analysis->GetSmiRange(left()); |
| - const Range* right_range = analysis->GetSmiRange(right()); |
| - if (Range::IsUnknown(left_range) || Range::IsUnknown(right_range)) { |
| +void BinaryIntegerOpInstr::InferRangeHelper(const Range* left_range, |
| + const Range* right_range, |
| + Range* range) { |
| + // TODO(vegorov): canonicalize BinaryIntegerOp to always have constant on the |
| + // right and a non-constant on the left. |
| + if (Range::IsUnknown(left_range) || |
| + Range::IsUnknown(right_range)) { |
|
srdjan
2014/09/11 17:38:11
One line?
|
| return; |
| } |
| Range::BinaryOp(op_kind(), |
| left_range, |
| right_range, |
| - left_defn, |
| + left()->definition(), |
| range); |
| ASSERT(!Range::IsUnknown(range)); |
| - // Calculate overflowed status before clamping. |
| - const bool overflowed = range->min().LowerBound().OverflowedSmi() || |
| - range->max().UpperBound().OverflowedSmi(); |
| - set_overflow(overflowed); |
| + const RangeBoundary::RangeSize range_size = |
| + RepresentationToRangeSize(representation()); |
| - // Clamp value to be within smi range. |
| - range->Clamp(RangeBoundary::kRangeBoundarySmi); |
| + // Calculate overflowed status before clamping if operation is |
| + // not truncating. |
| + if (!is_truncating()) { |
| + set_can_overflow(!range->Fits(range_size)); |
| + } |
| + |
| + range->Clamp(range_size); |
| +} |
| + |
| + |
| +void BinarySmiOpInstr::InferRange(RangeAnalysis* analysis, Range* range) { |
| + // TODO(vegorov) completely remove this once GetSmiRange is eliminated. |
| + InferRangeHelper(analysis->GetSmiRange(left()), |
| + analysis->GetSmiRange(right()), |
| + range); |
| +} |
| + |
| + |
| +void BinaryInt32OpInstr::InferRange(RangeAnalysis* analysis, Range* range) { |
| + InferRangeHelper(analysis->GetSmiRange(left()), |
| + analysis->GetSmiRange(right()), |
| + range); |
| +} |
| + |
| + |
| +void BinaryMintOpInstr::InferRange(RangeAnalysis* analysis, Range* range) { |
| + InferRangeHelper(left()->definition()->range(), |
| + right()->definition()->range(), |
| + range); |
| +} |
| + |
| + |
| +void ShiftMintOpInstr::InferRange(RangeAnalysis* analysis, Range* range) { |
| + InferRangeHelper(left()->definition()->range(), |
| + right()->definition()->range(), |
| + range); |
| } |
| @@ -2077,86 +2122,6 @@ void UnboxedIntConverterInstr::InferRange(RangeAnalysis* analysis, |
| } |
| -void BinaryInt32OpInstr::InferRange(RangeAnalysis* analysis, Range* range) { |
| - // TODO(vegorov): canonicalize BinarySmiOp to always have constant on the |
| - // right and a non-constant on the left. |
| - Definition* left_defn = left()->definition(); |
| - |
| - const Range* left_range = analysis->GetSmiRange(left()); |
| - const Range* right_range = analysis->GetSmiRange(right()); |
| - |
| - if (Range::IsUnknown(left_range) || Range::IsUnknown(right_range)) { |
| - return; |
| - } |
| - |
| - Range::BinaryOp(op_kind(), |
| - left_range, |
| - right_range, |
| - left_defn, |
| - range); |
| - ASSERT(!Range::IsUnknown(range)); |
| - |
| - // Calculate overflowed status before clamping. |
| - set_overflow(!range->Fits(RangeBoundary::kRangeBoundaryInt32)); |
| - |
| - // Clamp value to be within smi range. |
| - range->Clamp(RangeBoundary::kRangeBoundaryInt32); |
| -} |
| - |
| -void BinaryMintOpInstr::InferRange(RangeAnalysis* analysis, Range* range) { |
| - // TODO(vegorov): canonicalize BinaryMintOpInstr to always have constant on |
| - // the right and a non-constant on the left. |
| - Definition* left_defn = left()->definition(); |
| - |
| - const Range* left_range = left_defn->range(); |
| - const Range* right_range = right()->definition()->range(); |
| - |
| - if (Range::IsUnknown(left_range) || Range::IsUnknown(right_range)) { |
| - return; |
| - } |
| - |
| - Range::BinaryOp(op_kind(), |
| - left_range, |
| - right_range, |
| - left_defn, |
| - range); |
| - ASSERT(!Range::IsUnknown(range)); |
| - |
| - // Calculate overflowed status before clamping. |
| - set_can_overflow(!range->Fits(RangeBoundary::kRangeBoundaryInt64)); |
| - |
| - // Clamp value to be within mint range. |
| - range->Clamp(RangeBoundary::kRangeBoundaryInt64); |
| -} |
| - |
| - |
| -void ShiftMintOpInstr::InferRange(RangeAnalysis* analysis, Range* range) { |
| - Definition* left_defn = left()->definition(); |
| - |
| - const Range* left_range = left_defn->range(); |
| - const Range* right_range = right()->definition()->range(); |
| - |
| - if (Range::IsUnknown(left_range) || Range::IsUnknown(right_range)) { |
| - return; |
| - } |
| - |
| - Range::BinaryOp(op_kind(), |
| - left_range, |
| - right_range, |
| - left_defn, |
| - range); |
| - ASSERT(!Range::IsUnknown(range)); |
| - |
| - // Calculate overflowed status before clamping. |
| - const bool overflowed = range->min().LowerBound().OverflowedMint() || |
| - range->max().UpperBound().OverflowedMint(); |
| - set_can_overflow(overflowed); |
| - |
| - // Clamp value to be within mint range. |
| - range->Clamp(RangeBoundary::kRangeBoundaryInt64); |
| -} |
| - |
| - |
| void BoxIntegerInstr::InferRange(RangeAnalysis* analysis, Range* range) { |
| const Range* input_range = value()->definition()->range(); |
| if (input_range != NULL) { |