| Index: dart/runtime/vm/intermediate_language.cc
|
| ===================================================================
|
| --- dart/runtime/vm/intermediate_language.cc (revision 31530)
|
| +++ dart/runtime/vm/intermediate_language.cc (working copy)
|
| @@ -1455,6 +1455,31 @@
|
| }
|
|
|
|
|
| +LocationSummary* DebugStepCheckInstr::MakeLocationSummary(bool opt) const {
|
| + const intptr_t kNumInputs = 0;
|
| + const intptr_t kNumTemps = 0;
|
| + LocationSummary* locs =
|
| + new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
|
| + return locs;
|
| +}
|
| +
|
| +
|
| +void DebugStepCheckInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| + ASSERT(!compiler->is_optimizing());
|
| + const ExternalLabel label("debug_step_check",
|
| + StubCode::DebugStepCheckEntryPoint());
|
| + compiler->GenerateCall(token_pos(),
|
| + &label,
|
| + PcDescriptors::kReturn,
|
| + locs());
|
| +}
|
| +
|
| +
|
| +Instruction* DebugStepCheckInstr::Canonicalize(FlowGraph* flow_graph) {
|
| + return NULL;
|
| +}
|
| +
|
| +
|
| Definition* BoxDoubleInstr::Canonicalize(FlowGraph* flow_graph) {
|
| if (input_use_list() == NULL) {
|
| // Environments can accomodate any representation. No need to box.
|
| @@ -2618,6 +2643,30 @@
|
| }
|
|
|
|
|
| +static int64_t ConstantAbsMax(const Range* range) {
|
| + if (range == NULL) return Smi::kMaxValue;
|
| + const int64_t abs_min = Utils::Abs(Range::ConstantMin(range).value());
|
| + const int64_t abs_max = Utils::Abs(Range::ConstantMax(range).value());
|
| + return abs_min > abs_max ? abs_min : abs_max;
|
| +}
|
| +
|
| +
|
| +static bool OnlyPositiveOrZero(const Range* a, const Range* b) {
|
| + if ((a == NULL) || (b == NULL)) return false;
|
| + if (Range::ConstantMin(a).value() < 0) return false;
|
| + if (Range::ConstantMin(b).value() < 0) return false;
|
| + return true;
|
| +}
|
| +
|
| +
|
| +static bool OnlyNegativeOrZero(const Range* a, const Range* b) {
|
| + if ((a == NULL) || (b == NULL)) return false;
|
| + if (Range::ConstantMax(a).value() > 0) return false;
|
| + if (Range::ConstantMax(b).value() > 0) return false;
|
| + return true;
|
| +}
|
| +
|
| +
|
| void BinarySmiOpInstr::InferRange() {
|
| // TODO(vegorov): canonicalize BinarySmiOp to always have constant on the
|
| // right and a non-constant on the left.
|
| @@ -2674,6 +2723,27 @@
|
| }
|
| break;
|
|
|
| + case Token::kMUL: {
|
| + const int64_t left_max = ConstantAbsMax(left_range);
|
| + const int64_t right_max = ConstantAbsMax(right_range);
|
| + if ((left_max < 0x7FFFFFFF) && (right_max < 0x7FFFFFFF)) {
|
| + // Product of left and right max values stays in 64 bit range.
|
| + const int64_t result_max = left_max * right_max;
|
| + if (Smi::IsValid64(result_max) && Smi::IsValid64(-result_max)) {
|
| + const intptr_t r_min =
|
| + OnlyPositiveOrZero(left_range, right_range) ? 0 : -result_max;
|
| + min = RangeBoundary::FromConstant(r_min);
|
| + const intptr_t r_max =
|
| + OnlyNegativeOrZero(left_range, right_range) ? 0 : result_max;
|
| + max = RangeBoundary::FromConstant(r_max);
|
| + break;
|
| + }
|
| + }
|
| + if (range_ == NULL) {
|
| + range_ = Range::Unknown();
|
| + }
|
| + return;
|
| + }
|
| case Token::kBIT_AND:
|
| if (Range::ConstantMin(right_range).value() >= 0) {
|
| min = RangeBoundary::FromConstant(0);
|
|
|