diff --git a/runtime/vm/compiler/backend/constant_propagator.cc b/runtime/vm/compiler/backend/constant_propagator.cc index eb223e846498..6899b7f821b4 100644 --- a/runtime/vm/compiler/backend/constant_propagator.cc +++ b/runtime/vm/compiler/backend/constant_propagator.cc @@ -1197,20 +1197,10 @@ void ConstantPropagator::VisitShiftInt64Op(ShiftInt64OpInstr* instr) { VisitBinaryIntegerOp(instr); } -void ConstantPropagator::VisitSpeculativeShiftInt64Op( - SpeculativeShiftInt64OpInstr* instr) { - VisitBinaryIntegerOp(instr); -} - void ConstantPropagator::VisitShiftUint32Op(ShiftUint32OpInstr* instr) { VisitBinaryIntegerOp(instr); } -void ConstantPropagator::VisitSpeculativeShiftUint32Op( - SpeculativeShiftUint32OpInstr* instr) { - VisitBinaryIntegerOp(instr); -} - void ConstantPropagator::VisitBoxInt64(BoxInt64Instr* instr) { VisitBox(instr); } diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc index 17bca748c0d4..a1f3391b7533 100644 --- a/runtime/vm/compiler/backend/il.cc +++ b/runtime/vm/compiler/backend/il.cc @@ -2285,13 +2285,8 @@ BinaryIntegerOpInstr* BinaryIntegerOpInstr::Make(Representation representation, case kUnboxedUint32: if ((op_kind == Token::kSHL) || (op_kind == Token::kSHR) || (op_kind == Token::kUSHR)) { - if (CompilerState::Current().is_aot()) { - op = new ShiftUint32OpInstr(op_kind, left, right, deopt_id, - right_range); - } else { - op = new SpeculativeShiftUint32OpInstr(op_kind, left, right, deopt_id, - right_range); - } + op = + new ShiftUint32OpInstr(op_kind, left, right, deopt_id, right_range); } else { op = new BinaryUint32OpInstr(op_kind, left, right, deopt_id); } @@ -2299,13 +2294,7 @@ BinaryIntegerOpInstr* BinaryIntegerOpInstr::Make(Representation representation, case kUnboxedInt64: if ((op_kind == Token::kSHL) || (op_kind == Token::kSHR) || (op_kind == Token::kUSHR)) { - if (CompilerState::Current().is_aot()) { - op = new ShiftInt64OpInstr(op_kind, left, right, deopt_id, - right_range); - } else { - op = new SpeculativeShiftInt64OpInstr(op_kind, left, right, deopt_id, - right_range); - } + op = new ShiftInt64OpInstr(op_kind, left, right, deopt_id, right_range); } else { op = new BinaryInt64OpInstr(op_kind, left, right, deopt_id); } @@ -2430,10 +2419,8 @@ Definition* BinaryIntegerOpInstr::Canonicalize(FlowGraph* flow_graph) { return right()->definition(); } else if ((rhs > 0) && Utils::IsPowerOfTwo(rhs)) { const int64_t shift_amount = Utils::ShiftForPowerOfTwo(rhs); - const Representation shift_amount_rep = - CompilerState::Current().is_aot() ? kUnboxedInt64 : kTagged; ConstantInstr* constant_shift_amount = flow_graph->GetConstant( - Smi::Handle(Smi::New(shift_amount)), shift_amount_rep); + Smi::Handle(Smi::New(shift_amount)), kUnboxedInt64); BinaryIntegerOpInstr* shift = BinaryIntegerOpInstr::Make( representation(), Token::kSHL, left()->CopyWithType(), new Value(constant_shift_amount), GetDeoptId(), can_overflow(), diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h index d6945d469d92..60e915adbc2c 100644 --- a/runtime/vm/compiler/backend/il.h +++ b/runtime/vm/compiler/backend/il.h @@ -503,7 +503,6 @@ struct InstrAttrs { M(CaseInsensitiveCompare, kNoGC) \ M(BinaryInt64Op, kNoGC) \ M(ShiftInt64Op, kNoGC) \ - M(SpeculativeShiftInt64Op, kNoGC) \ M(UnaryInt64Op, kNoGC) \ M(CheckArrayBound, kNoGC) \ M(GenericCheckBound, kNoGC) \ @@ -529,7 +528,6 @@ struct InstrAttrs { M(BoxLanes, _) \ M(BinaryUint32Op, kNoGC) \ M(ShiftUint32Op, kNoGC) \ - M(SpeculativeShiftUint32Op, kNoGC) \ M(UnaryUint32Op, kNoGC) \ M(BoxUint32, _) \ M(UnboxUint32, kNoGC) \ @@ -8739,8 +8737,7 @@ class UnboxInt64Instr : public UnboxIntegerInstr { bool Definition::IsInt64Definition() { return (Type()->ToCid() == kMintCid) || IsBinaryInt64Op() || - IsUnaryInt64Op() || IsShiftInt64Op() || IsSpeculativeShiftInt64Op() || - IsBoxInt64() || IsUnboxInt64(); + IsUnaryInt64Op() || IsShiftInt64Op() || IsBoxInt64() || IsUnboxInt64(); } // Calls into the runtime and performs a case-insensitive comparison of the @@ -9495,6 +9492,9 @@ class ShiftInt64OpInstr : public ShiftIntegerOpInstr { : ShiftIntegerOpInstr(op_kind, left, right, deopt_id, right_range) {} virtual bool ComputeCanDeoptimize() const { return false; } + virtual bool ComputeCanDeoptimizeAfterCall() const { + return !CompilerState::Current().is_aot(); + } virtual bool MayThrow() const { return !IsShiftCountInRange(); } virtual Representation representation() const { return kUnboxedInt64; } @@ -9512,37 +9512,6 @@ class ShiftInt64OpInstr : public ShiftIntegerOpInstr { DISALLOW_COPY_AND_ASSIGN(ShiftInt64OpInstr); }; -// Speculative int64 shift. Takes unboxed int64 and smi. -// Deoptimizes if right operand is negative or greater than kShiftCountLimit. -class SpeculativeShiftInt64OpInstr : public ShiftIntegerOpInstr { - public: - SpeculativeShiftInt64OpInstr(Token::Kind op_kind, - Value* left, - Value* right, - intptr_t deopt_id, - Range* right_range = nullptr) - : ShiftIntegerOpInstr(op_kind, left, right, deopt_id, right_range) {} - - virtual bool ComputeCanDeoptimize() const { - ASSERT(!can_overflow()); - return !IsShiftCountInRange(); - } - - virtual Representation representation() const { return kUnboxedInt64; } - - virtual Representation RequiredInputRepresentation(intptr_t idx) const { - ASSERT((idx == 0) || (idx == 1)); - return (idx == 0) ? kUnboxedInt64 : kTagged; - } - - DECLARE_INSTRUCTION(SpeculativeShiftInt64Op) - - DECLARE_EMPTY_SERIALIZATION(SpeculativeShiftInt64OpInstr, ShiftIntegerOpInstr) - - private: - DISALLOW_COPY_AND_ASSIGN(SpeculativeShiftInt64OpInstr); -}; - // Non-speculative uint32 shift. Takes unboxed uint32 and unboxed int64. // Throws if right operand is negative. class ShiftUint32OpInstr : public ShiftIntegerOpInstr { @@ -9555,6 +9524,9 @@ class ShiftUint32OpInstr : public ShiftIntegerOpInstr { : ShiftIntegerOpInstr(op_kind, left, right, deopt_id, right_range) {} virtual bool ComputeCanDeoptimize() const { return false; } + virtual bool ComputeCanDeoptimizeAfterCall() const { + return !CompilerState::Current().is_aot(); + } virtual bool MayThrow() const { return !IsShiftCountInRange(kUint32ShiftCountLimit); } @@ -9576,37 +9548,6 @@ class ShiftUint32OpInstr : public ShiftIntegerOpInstr { DISALLOW_COPY_AND_ASSIGN(ShiftUint32OpInstr); }; -// Speculative uint32 shift. Takes unboxed uint32 and smi. -// Deoptimizes if right operand is negative. -class SpeculativeShiftUint32OpInstr : public ShiftIntegerOpInstr { - public: - SpeculativeShiftUint32OpInstr(Token::Kind op_kind, - Value* left, - Value* right, - intptr_t deopt_id, - Range* right_range = nullptr) - : ShiftIntegerOpInstr(op_kind, left, right, deopt_id, right_range) {} - - virtual bool ComputeCanDeoptimize() const { return !IsShiftCountInRange(); } - - virtual Representation representation() const { return kUnboxedUint32; } - - virtual Representation RequiredInputRepresentation(intptr_t idx) const { - ASSERT((idx == 0) || (idx == 1)); - return (idx == 0) ? kUnboxedUint32 : kTagged; - } - - DECLARE_INSTRUCTION(SpeculativeShiftUint32Op) - - DECLARE_EMPTY_SERIALIZATION(SpeculativeShiftUint32OpInstr, - ShiftIntegerOpInstr) - - private: - static constexpr intptr_t kUint32ShiftCountLimit = 31; - - DISALLOW_COPY_AND_ASSIGN(SpeculativeShiftUint32OpInstr); -}; - class UnaryDoubleOpInstr : public TemplateDefinition<1, NoThrow, Pure> { public: UnaryDoubleOpInstr(Token::Kind op_kind, diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc index 5769664cd84f..16e7585a0a28 100644 --- a/runtime/vm/compiler/backend/il_arm.cc +++ b/runtime/vm/compiler/backend/il_arm.cc @@ -6667,53 +6667,6 @@ void ShiftInt64OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { } } -LocationSummary* SpeculativeShiftInt64OpInstr::MakeLocationSummary( - Zone* zone, - bool opt) const { - const intptr_t kNumInputs = 2; - const intptr_t kNumTemps = 0; - LocationSummary* summary = new (zone) - LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); - summary->set_in(0, Location::Pair(Location::RequiresRegister(), - Location::RequiresRegister())); - summary->set_in(1, LocationWritableRegisterOrSmiConstant(right())); - summary->set_out(0, Location::Pair(Location::RequiresRegister(), - Location::RequiresRegister())); - return summary; -} - -void SpeculativeShiftInt64OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { - PairLocation* left_pair = locs()->in(0).AsPairLocation(); - Register left_lo = left_pair->At(0).reg(); - Register left_hi = left_pair->At(1).reg(); - PairLocation* out_pair = locs()->out(0).AsPairLocation(); - Register out_lo = out_pair->At(0).reg(); - Register out_hi = out_pair->At(1).reg(); - ASSERT(!can_overflow()); - - if (locs()->in(1).IsConstant()) { - EmitShiftInt64ByConstant(compiler, op_kind(), out_lo, out_hi, left_lo, - left_hi, locs()->in(1).constant()); - } else { - // Code for a variable shift amount. - Register shift = locs()->in(1).reg(); - __ SmiUntag(shift); - - // Deopt if shift is larger than 63 or less than 0 (or not a smi). - if (!IsShiftCountInRange()) { - ASSERT(CanDeoptimize()); - compiler::Label* deopt = - compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryInt64Op); - - __ CompareImmediate(shift, kShiftCountLimit); - __ b(deopt, HI); - } - - EmitShiftInt64ByRegister(compiler, op_kind(), out_lo, out_hi, left_lo, - left_hi, shift); - } -} - class ShiftUint32OpSlowPath : public ThrowErrorSlowPathCode { public: explicit ShiftUint32OpSlowPath(ShiftUint32OpInstr* instruction) @@ -6799,57 +6752,6 @@ void ShiftUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { } } -LocationSummary* SpeculativeShiftUint32OpInstr::MakeLocationSummary( - Zone* zone, - bool opt) const { - const intptr_t kNumInputs = 2; - const intptr_t kNumTemps = 1; - LocationSummary* summary = new (zone) - LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); - summary->set_in(0, Location::RequiresRegister()); - summary->set_in(1, LocationRegisterOrSmiConstant(right())); - summary->set_temp(0, Location::RequiresRegister()); - summary->set_out(0, Location::RequiresRegister()); - return summary; -} - -void SpeculativeShiftUint32OpInstr::EmitNativeCode( - FlowGraphCompiler* compiler) { - Register left = locs()->in(0).reg(); - Register out = locs()->out(0).reg(); - Register temp = locs()->temp(0).reg(); - ASSERT(left != out); - - if (locs()->in(1).IsConstant()) { - EmitShiftUint32ByConstant(compiler, op_kind(), out, left, - locs()->in(1).constant()); - } else { - Register right = locs()->in(1).reg(); - const bool shift_count_in_range = - IsShiftCountInRange(kUint32ShiftCountLimit); - - __ SmiUntag(temp, right); - right = temp; - - // Deopt if shift count is negative. - if (!shift_count_in_range) { - ASSERT(CanDeoptimize()); - compiler::Label* deopt = - compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryInt64Op); - - __ CompareImmediate(right, 0); - __ b(deopt, LT); - } - - EmitShiftUint32ByRegister(compiler, op_kind(), out, left, right); - - if (!shift_count_in_range) { - __ CompareImmediate(right, kUint32ShiftCountLimit); - __ LoadImmediate(out, 0, HI); - } - } -} - LocationSummary* UnaryInt64OpInstr::MakeLocationSummary(Zone* zone, bool opt) const { const intptr_t kNumInputs = 1; diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc index 9a5034132a25..dc894c41d053 100644 --- a/runtime/vm/compiler/backend/il_arm64.cc +++ b/runtime/vm/compiler/backend/il_arm64.cc @@ -5728,49 +5728,6 @@ void ShiftInt64OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { } } -LocationSummary* SpeculativeShiftInt64OpInstr::MakeLocationSummary( - Zone* zone, - bool opt) const { - const intptr_t kNumInputs = 2; - const intptr_t kNumTemps = 0; - LocationSummary* summary = new (zone) - LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); - summary->set_in(0, Location::RequiresRegister()); - summary->set_in(1, LocationRegisterOrSmiConstant(right())); - summary->set_out(0, Location::RequiresRegister()); - return summary; -} - -void SpeculativeShiftInt64OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { - const Register left = locs()->in(0).reg(); - const Register out = locs()->out(0).reg(); - ASSERT(!can_overflow()); - - if (locs()->in(1).IsConstant()) { - EmitShiftInt64ByConstant(compiler, op_kind(), out, left, - locs()->in(1).constant()); - } else { - // Code for a variable shift amount. - Register shift = locs()->in(1).reg(); - - // Untag shift count. - __ SmiUntag(TMP, shift); - shift = TMP; - - // Deopt if shift is larger than 63 or less than 0 (or not a smi). - if (!IsShiftCountInRange()) { - ASSERT(CanDeoptimize()); - compiler::Label* deopt = - compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryInt64Op); - - __ CompareImmediate(shift, kShiftCountLimit); - __ b(deopt, HI); - } - - EmitShiftInt64ByRegister(compiler, op_kind(), out, left, shift); - } -} - class ShiftUint32OpSlowPath : public ThrowErrorSlowPathCode { public: explicit ShiftUint32OpSlowPath(ShiftUint32OpInstr* instruction) @@ -5838,55 +5795,6 @@ void ShiftUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { } } -LocationSummary* SpeculativeShiftUint32OpInstr::MakeLocationSummary( - Zone* zone, - bool opt) const { - const intptr_t kNumInputs = 2; - const intptr_t kNumTemps = 0; - LocationSummary* summary = new (zone) - LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); - summary->set_in(0, Location::RequiresRegister()); - summary->set_in(1, LocationRegisterOrSmiConstant(right())); - summary->set_out(0, Location::RequiresRegister()); - return summary; -} - -void SpeculativeShiftUint32OpInstr::EmitNativeCode( - FlowGraphCompiler* compiler) { - Register left = locs()->in(0).reg(); - Register out = locs()->out(0).reg(); - - if (locs()->in(1).IsConstant()) { - EmitShiftUint32ByConstant(compiler, op_kind(), out, left, - locs()->in(1).constant()); - } else { - Register right = locs()->in(1).reg(); - const bool shift_count_in_range = - IsShiftCountInRange(kUint32ShiftCountLimit); - - __ SmiUntag(TMP, right); - right = TMP; - - // Jump to a slow path if shift count is negative. - if (!shift_count_in_range) { - // Deoptimize if shift count is negative. - ASSERT(CanDeoptimize()); - compiler::Label* deopt = - compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryInt64Op); - - __ tbnz(deopt, right, compiler::target::kSmiBits + 1); - } - - EmitShiftUint32ByRegister(compiler, op_kind(), out, left, right); - - if (!shift_count_in_range) { - // If shift value is > 31, return zero. - __ CompareImmediate(right, 31, compiler::kObjectBytes); - __ csel(out, out, ZR, LE); - } - } -} - LocationSummary* UnaryInt64OpInstr::MakeLocationSummary(Zone* zone, bool opt) const { const intptr_t kNumInputs = 1; diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc index 4619b28b74f2..6e07cfdd47e7 100644 --- a/runtime/vm/compiler/backend/il_ia32.cc +++ b/runtime/vm/compiler/backend/il_ia32.cc @@ -5794,51 +5794,6 @@ void ShiftInt64OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { } } -LocationSummary* SpeculativeShiftInt64OpInstr::MakeLocationSummary( - Zone* zone, - bool opt) const { - const intptr_t kNumInputs = 2; - const intptr_t kNumTemps = 0; - LocationSummary* summary = new (zone) - LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); - summary->set_in(0, Location::Pair(Location::RequiresRegister(), - Location::RequiresRegister())); - summary->set_in(1, LocationFixedRegisterOrSmiConstant(right(), ECX)); - summary->set_out(0, Location::SameAsFirstInput()); - return summary; -} - -void SpeculativeShiftInt64OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { - PairLocation* left_pair = locs()->in(0).AsPairLocation(); - Register left_lo = left_pair->At(0).reg(); - Register left_hi = left_pair->At(1).reg(); - PairLocation* out_pair = locs()->out(0).AsPairLocation(); - Register out_lo = out_pair->At(0).reg(); - Register out_hi = out_pair->At(1).reg(); - ASSERT(out_lo == left_lo); - ASSERT(out_hi == left_hi); - ASSERT(!can_overflow()); - - if (locs()->in(1).IsConstant()) { - EmitShiftInt64ByConstant(compiler, op_kind(), left_lo, left_hi, - locs()->in(1).constant()); - } else { - ASSERT(locs()->in(1).reg() == ECX); - __ SmiUntag(ECX); - - // Deoptimize if shift count is > 63 or negative (or not a smi). - if (!IsShiftCountInRange()) { - ASSERT(CanDeoptimize()); - compiler::Label* deopt = - compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryInt64Op); - __ cmpl(ECX, compiler::Immediate(kShiftCountLimit)); - __ j(ABOVE, deopt); - } - - EmitShiftInt64ByECX(compiler, op_kind(), left_lo, left_hi); - } -} - class ShiftUint32OpSlowPath : public ThrowErrorSlowPathCode { public: explicit ShiftUint32OpSlowPath(ShiftUint32OpInstr* instruction) @@ -5930,56 +5885,6 @@ void ShiftUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { } } -LocationSummary* SpeculativeShiftUint32OpInstr::MakeLocationSummary( - Zone* zone, - bool opt) const { - const intptr_t kNumInputs = 2; - const intptr_t kNumTemps = 0; - LocationSummary* summary = new (zone) - LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); - summary->set_in(0, Location::RequiresRegister()); - summary->set_in(1, LocationFixedRegisterOrSmiConstant(right(), ECX)); - summary->set_out(0, Location::SameAsFirstInput()); - return summary; -} - -void SpeculativeShiftUint32OpInstr::EmitNativeCode( - FlowGraphCompiler* compiler) { - Register left = locs()->in(0).reg(); - Register out = locs()->out(0).reg(); - ASSERT(left == out); - - if (locs()->in(1).IsConstant()) { - EmitShiftUint32ByConstant(compiler, op_kind(), left, - locs()->in(1).constant()); - } else { - ASSERT(locs()->in(1).reg() == ECX); - __ SmiUntag(ECX); - - if (!IsShiftCountInRange(kUint32ShiftCountLimit)) { - if (!IsShiftCountInRange()) { - // Deoptimize if shift count is negative. - ASSERT(CanDeoptimize()); - compiler::Label* deopt = - compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryInt64Op); - - __ testl(ECX, ECX); - __ j(LESS, deopt); - } - - compiler::Label cont; - __ cmpl(ECX, compiler::Immediate(kUint32ShiftCountLimit)); - __ j(LESS_EQUAL, &cont); - - __ xorl(left, left); - - __ Bind(&cont); - } - - EmitShiftUint32ByECX(compiler, op_kind(), left); - } -} - LocationSummary* UnaryInt64OpInstr::MakeLocationSummary(Zone* zone, bool opt) const { const intptr_t kNumInputs = 1; diff --git a/runtime/vm/compiler/backend/il_riscv.cc b/runtime/vm/compiler/backend/il_riscv.cc index c1e15b285b33..272cab49dc31 100644 --- a/runtime/vm/compiler/backend/il_riscv.cc +++ b/runtime/vm/compiler/backend/il_riscv.cc @@ -6103,89 +6103,6 @@ void ShiftInt64OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { #endif } -LocationSummary* SpeculativeShiftInt64OpInstr::MakeLocationSummary( - Zone* zone, - bool opt) const { - const intptr_t kNumInputs = 2; - const intptr_t kNumTemps = 0; - LocationSummary* summary = new (zone) - LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); -#if XLEN == 32 - summary->set_in(0, Location::Pair(Location::RequiresRegister(), - Location::RequiresRegister())); - summary->set_in(1, LocationWritableRegisterOrSmiConstant(right())); - summary->set_out(0, Location::Pair(Location::RequiresRegister(), - Location::RequiresRegister())); -#else - summary->set_in(0, Location::RequiresRegister()); - summary->set_in(1, LocationRegisterOrSmiConstant(right())); - summary->set_out(0, Location::RequiresRegister()); -#endif - return summary; -} - -void SpeculativeShiftInt64OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { -#if XLEN == 32 - PairLocation* left_pair = locs()->in(0).AsPairLocation(); - Register left_lo = left_pair->At(0).reg(); - Register left_hi = left_pair->At(1).reg(); - PairLocation* out_pair = locs()->out(0).AsPairLocation(); - Register out_lo = out_pair->At(0).reg(); - Register out_hi = out_pair->At(1).reg(); - ASSERT(!can_overflow()); - - if (locs()->in(1).IsConstant()) { - EmitShiftInt64ByConstant(compiler, op_kind(), out_lo, out_hi, left_lo, - left_hi, locs()->in(1).constant()); - } else { - // Code for a variable shift amount. - Register shift = locs()->in(1).reg(); - __ SmiUntag(shift); - - // Deopt if shift is larger than 63 or less than 0 (or not a smi). - if (!IsShiftCountInRange()) { - ASSERT(CanDeoptimize()); - compiler::Label* deopt = - compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryInt64Op); - - __ CompareImmediate(shift, kShiftCountLimit); - __ BranchIf(HI, deopt); - } - - EmitShiftInt64ByRegister(compiler, op_kind(), out_lo, out_hi, left_lo, - left_hi, shift); - } -#else - const Register left = locs()->in(0).reg(); - const Register out = locs()->out(0).reg(); - ASSERT(!can_overflow()); - - if (locs()->in(1).IsConstant()) { - EmitShiftInt64ByConstant(compiler, op_kind(), out, left, - locs()->in(1).constant()); - } else { - // Code for a variable shift amount. - Register shift = locs()->in(1).reg(); - - // Untag shift count. - __ SmiUntag(TMP, shift); - shift = TMP; - - // Deopt if shift is larger than 63 or less than 0 (or not a smi). - if (!IsShiftCountInRange()) { - ASSERT(CanDeoptimize()); - compiler::Label* deopt = - compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryInt64Op); - - __ CompareImmediate(shift, kShiftCountLimit); - __ BranchIf(HI, deopt); - } - - EmitShiftInt64ByRegister(compiler, op_kind(), out, left, shift); - } -#endif -} - class ShiftUint32OpSlowPath : public ThrowErrorSlowPathCode { public: explicit ShiftUint32OpSlowPath(ShiftUint32OpInstr* instruction) @@ -6324,58 +6241,6 @@ void ShiftUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { #endif } -LocationSummary* SpeculativeShiftUint32OpInstr::MakeLocationSummary( - Zone* zone, - bool opt) const { - const intptr_t kNumInputs = 2; - const intptr_t kNumTemps = 0; - LocationSummary* summary = new (zone) - LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); - summary->set_in(0, Location::RequiresRegister()); - summary->set_in(1, LocationRegisterOrSmiConstant(right())); - summary->set_out(0, Location::RequiresRegister()); - return summary; -} - -void SpeculativeShiftUint32OpInstr::EmitNativeCode( - FlowGraphCompiler* compiler) { - Register left = locs()->in(0).reg(); - Register out = locs()->out(0).reg(); - - if (locs()->in(1).IsConstant()) { - EmitShiftUint32ByConstant(compiler, op_kind(), out, left, - locs()->in(1).constant()); - } else { - Register right = locs()->in(1).reg(); - const bool shift_count_in_range = - IsShiftCountInRange(kUint32ShiftCountLimit); - - __ SmiUntag(TMP, right); - right = TMP; - - // Jump to a slow path if shift count is negative. - if (!shift_count_in_range) { - // Deoptimize if shift count is negative. - ASSERT(CanDeoptimize()); - compiler::Label* deopt = - compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryInt64Op); - - __ bltz(right, deopt); - } - - EmitShiftUint32ByRegister(compiler, op_kind(), out, left, right); - - if (!shift_count_in_range) { - // If shift value is > 31, return zero. - compiler::Label done; - __ CompareImmediate(right, 31); - __ BranchIf(LE, &done, compiler::Assembler::kNearJump); - __ li(out, 0); - __ Bind(&done); - } - } -} - LocationSummary* UnaryInt64OpInstr::MakeLocationSummary(Zone* zone, bool opt) const { #if XLEN == 32 diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc index 2eb3e753e571..b143764af951 100644 --- a/runtime/vm/compiler/backend/il_x64.cc +++ b/runtime/vm/compiler/backend/il_x64.cc @@ -6075,46 +6075,6 @@ void ShiftInt64OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { } } -LocationSummary* SpeculativeShiftInt64OpInstr::MakeLocationSummary( - Zone* zone, - bool opt) const { - const intptr_t kNumInputs = 2; - const intptr_t kNumTemps = 0; - LocationSummary* summary = new (zone) - LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); - summary->set_in(0, Location::RequiresRegister()); - summary->set_in(1, LocationFixedRegisterOrSmiConstant(right(), RCX)); - summary->set_out(0, Location::SameAsFirstInput()); - return summary; -} - -void SpeculativeShiftInt64OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { - const Register left = locs()->in(0).reg(); - const Register out = locs()->out(0).reg(); - ASSERT(left == out); - ASSERT(!can_overflow()); - - if (locs()->in(1).IsConstant()) { - EmitShiftInt64ByConstant(compiler, op_kind(), left, - locs()->in(1).constant()); - } else { - ASSERT(locs()->in(1).reg() == RCX); - __ SmiUntag(RCX); - - // Deoptimize if shift count is > 63 or negative (or not a smi). - if (!IsShiftCountInRange()) { - ASSERT(CanDeoptimize()); - compiler::Label* deopt = - compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryInt64Op); - - __ cmpq(RCX, compiler::Immediate(kShiftCountLimit)); - __ j(ABOVE, deopt); - } - - EmitShiftInt64ByRCX(compiler, op_kind(), left); - } -} - class ShiftUint32OpSlowPath : public ThrowErrorSlowPathCode { public: explicit ShiftUint32OpSlowPath(ShiftUint32OpInstr* instruction) @@ -6191,56 +6151,6 @@ void ShiftUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { } } -LocationSummary* SpeculativeShiftUint32OpInstr::MakeLocationSummary( - Zone* zone, - bool opt) const { - const intptr_t kNumInputs = 2; - const intptr_t kNumTemps = 0; - LocationSummary* summary = new (zone) - LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); - summary->set_in(0, Location::RequiresRegister()); - summary->set_in(1, LocationFixedRegisterOrSmiConstant(right(), RCX)); - summary->set_out(0, Location::SameAsFirstInput()); - return summary; -} - -void SpeculativeShiftUint32OpInstr::EmitNativeCode( - FlowGraphCompiler* compiler) { - Register left = locs()->in(0).reg(); - Register out = locs()->out(0).reg(); - ASSERT(left == out); - - if (locs()->in(1).IsConstant()) { - EmitShiftUint32ByConstant(compiler, op_kind(), left, - locs()->in(1).constant()); - } else { - ASSERT(locs()->in(1).reg() == RCX); - __ SmiUntag(RCX); - - if (!IsShiftCountInRange(kUint32ShiftCountLimit)) { - if (!IsShiftCountInRange()) { - // Deoptimize if shift count is negative. - ASSERT(CanDeoptimize()); - compiler::Label* deopt = - compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryInt64Op); - - __ OBJ(test)(RCX, RCX); - __ j(LESS, deopt); - } - - compiler::Label cont; - __ OBJ(cmp)(RCX, compiler::Immediate(kUint32ShiftCountLimit)); - __ j(LESS_EQUAL, &cont); - - __ xorl(left, left); - - __ Bind(&cont); - } - - EmitShiftUint32ByRCX(compiler, op_kind(), left); - } -} - LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Zone* zone, bool opt) const { const intptr_t kNumInputs = 2; diff --git a/runtime/vm/compiler/backend/range_analysis.cc b/runtime/vm/compiler/backend/range_analysis.cc index 41514e50b97d..598628a190c2 100644 --- a/runtime/vm/compiler/backend/range_analysis.cc +++ b/runtime/vm/compiler/backend/range_analysis.cc @@ -150,8 +150,7 @@ void RangeAnalysis::CollectValues() { values_.Add(defn); if (defn->IsBinaryInt64Op()) { binary_int64_ops_.Add(defn->AsBinaryInt64Op()); - } else if (defn->IsShiftInt64Op() || - defn->IsSpeculativeShiftInt64Op()) { + } else if (defn->IsShiftInt64Op()) { shift_int64_ops_.Add(defn->AsShiftIntegerOp()); } } @@ -1541,7 +1540,6 @@ bool IntegerInstructionSelector::IsPotentialUint32Definition(Definition* def) { // & untagged of intermediate results. // TODO(johnmccutchan): Consider phis. return def->IsBoxInt64() || def->IsUnboxInt64() || def->IsShiftInt64Op() || - def->IsSpeculativeShiftInt64Op() || (def->IsBinaryInt64Op() && BinaryUint32OpInstr::IsSupported( def->AsBinaryInt64Op()->op_kind())) || (def->IsUnaryInt64Op() && @@ -1638,7 +1636,7 @@ bool IntegerInstructionSelector::CanBecomeUint32(Definition* def) { } // A right shift with an input outside of Uint32 range cannot be converted // because we need the high bits. - if (def->IsShiftInt64Op() || def->IsSpeculativeShiftInt64Op()) { + if (def->IsShiftInt64Op()) { ShiftIntegerOpInstr* op = def->AsShiftIntegerOp(); if ((op->op_kind() == Token::kSHR) || (op->op_kind() == Token::kUSHR)) { Definition* shift_input = op->left()->definition(); diff --git a/runtime/vm/compiler/call_specializer.cc b/runtime/vm/compiler/call_specializer.cc index 7970bc2dd2a1..425e86f6fe18 100644 --- a/runtime/vm/compiler/call_specializer.cc +++ b/runtime/vm/compiler/call_specializer.cc @@ -647,30 +647,24 @@ bool CallSpecializer::TryReplaceWithBinaryOp(InstanceCallInstr* call, call->deopt_id(), call->source()); ReplaceCall(call, double_bin_op); } else if (operands_type == kMintCid) { + left = + UnboxInstr::Create(kUnboxedInt64, new (Z) Value(left), call->deopt_id(), + UnboxInstr::ValueMode::kCheckType); + InsertBefore(call, left, call->env(), FlowGraph::kValue); + right = + UnboxInstr::Create(kUnboxedInt64, new (Z) Value(right), + call->deopt_id(), UnboxInstr::ValueMode::kCheckType); + InsertBefore(call, right, call->env(), FlowGraph::kValue); + BinaryIntegerOpInstr* bin_op = nullptr; if ((op_kind == Token::kSHL) || (op_kind == Token::kSHR) || (op_kind == Token::kUSHR)) { - // left is unboxed, right is tagged. - left = UnboxInstr::Create(kUnboxedInt64, new (Z) Value(left), - call->deopt_id(), - UnboxInstr::ValueMode::kCheckType); - InsertBefore(call, left, call->env(), FlowGraph::kValue); - SpeculativeShiftInt64OpInstr* shift_op = new (Z) - SpeculativeShiftInt64OpInstr(op_kind, new (Z) Value(left), - new (Z) Value(right), call->deopt_id()); - ReplaceCall(call, shift_op); + bin_op = new (Z) ShiftInt64OpInstr( + op_kind, new (Z) Value(left), new (Z) Value(right), call->deopt_id()); } else { - left = UnboxInstr::Create(kUnboxedInt64, new (Z) Value(left), - call->deopt_id(), - UnboxInstr::ValueMode::kCheckType); - InsertBefore(call, left, call->env(), FlowGraph::kValue); - right = UnboxInstr::Create(kUnboxedInt64, new (Z) Value(right), - call->deopt_id(), - UnboxInstr::ValueMode::kCheckType); - InsertBefore(call, right, call->env(), FlowGraph::kValue); - BinaryInt64OpInstr* bin_op = new (Z) BinaryInt64OpInstr( + bin_op = new (Z) BinaryInt64OpInstr( op_kind, new (Z) Value(left), new (Z) Value(right), call->deopt_id()); - ReplaceCall(call, bin_op); } + ReplaceCall(call, bin_op); } else if ((operands_type == kFloat32x4Cid) || (operands_type == kInt32x4Cid) || (operands_type == kFloat64x2Cid)) {