Refactor Instruction::speculative_mode()

The same instruction should be able to set different speculative
modes for its inputs when they are inserted by select representations,
e.g. static calls that have unboxed parameters might set unbox
instructions for those parameters as non speculative.

Change-Id: Ie450f0431e4dbbf0269869f520f59d5d5e946887
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/134334
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Victor Agnez Lima <victoragnez@google.com>
This commit is contained in:
Victor Lima 2020-02-06 09:21:31 +00:00 committed by commit-bot@chromium.org
parent 0fe2779149
commit 43b69d4ba9
4 changed files with 77 additions and 37 deletions

View file

@ -1680,8 +1680,9 @@ void FlowGraph::InsertConversion(Representation from,
const intptr_t deopt_id = (deopt_target != NULL)
? deopt_target->DeoptimizationTarget()
: DeoptId::kNone;
converted = UnboxInstr::Create(to, use->CopyWithType(), deopt_id,
use->instruction()->speculative_mode());
converted = UnboxInstr::Create(
to, use->CopyWithType(), deopt_id,
use->instruction()->SpeculativeModeOfInput(use->use_index()));
} else if ((to == kTagged) && Boxing::Supports(from)) {
converted = BoxInstr::Create(from, use->CopyWithType());
} else {

View file

@ -1971,7 +1971,7 @@ bool IntConverterInstr::ComputeCanDeoptimize() const {
}
bool UnboxInt32Instr::ComputeCanDeoptimize() const {
if (speculative_mode() == kNotSpeculative) {
if (SpeculativeModeOfInputs() == kNotSpeculative) {
return false;
}
const intptr_t value_cid = value()->Type()->ToCid();
@ -1995,7 +1995,7 @@ bool UnboxInt32Instr::ComputeCanDeoptimize() const {
bool UnboxUint32Instr::ComputeCanDeoptimize() const {
ASSERT(is_truncating());
if (speculative_mode() == kNotSpeculative) {
if (SpeculativeModeOfInputs() == kNotSpeculative) {
return false;
}
if ((value()->Type()->ToCid() == kSmiCid) ||
@ -2433,7 +2433,7 @@ Definition* BinaryIntegerOpInstr::Canonicalize(FlowGraph* flow_graph) {
BinaryIntegerOpInstr* shift = BinaryIntegerOpInstr::Make(
representation(), Token::kSHL, left()->CopyWithType(),
new Value(constant_1), GetDeoptId(), can_overflow(),
is_truncating(), range(), speculative_mode());
is_truncating(), range(), SpeculativeModeOfInputs());
if (shift != nullptr) {
// Assign a range to the shift factor, just in case range
// analysis no longer runs after this rewriting.
@ -3024,7 +3024,7 @@ Definition* BoxInt64Instr::Canonicalize(FlowGraph* flow_graph) {
// For all x, box(unbox(x)) = x.
if (auto unbox = value()->definition()->AsUnboxInt64()) {
if (unbox->speculative_mode() == kNotSpeculative) {
if (unbox->SpeculativeModeOfInputs() == kNotSpeculative) {
return unbox->value()->definition();
}
} else if (auto unbox = value()->definition()->AsUnboxedConstant()) {
@ -4900,7 +4900,7 @@ void UnboxInstr::EmitLoadFromBoxWithDeopt(FlowGraphCompiler* compiler) {
}
void UnboxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
if (speculative_mode() == kNotSpeculative) {
if (SpeculativeModeOfInputs() == kNotSpeculative) {
switch (representation()) {
case kUnboxedDouble:
case kUnboxedFloat:
@ -4929,7 +4929,7 @@ void UnboxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
break;
}
} else {
ASSERT(speculative_mode() == kGuardInputs);
ASSERT(SpeculativeModeOfInputs() == kGuardInputs);
const intptr_t value_cid = value()->Type()->ToCid();
const intptr_t box_cid = BoxCid();
@ -5055,7 +5055,8 @@ ComparisonInstr* EqualityCompareInstr::CopyWithNewOperands(Value* new_left,
ComparisonInstr* RelationalOpInstr::CopyWithNewOperands(Value* new_left,
Value* new_right) {
return new RelationalOpInstr(token_pos(), kind(), new_left, new_right,
operation_cid(), deopt_id(), speculative_mode());
operation_cid(), deopt_id(),
SpeculativeModeOfInputs());
}
ComparisonInstr* StrictCompareInstr::CopyWithNewOperands(Value* new_left,

View file

@ -979,8 +979,19 @@ class Instruction : public ZoneAllocated {
return kTagged;
}
// By default, instructions should check types of inputs when unboxing.
virtual SpeculativeMode speculative_mode() const { return kGuardInputs; }
SpeculativeMode SpeculativeModeOfInputs() const {
for (intptr_t i = 0; i < InputCount(); i++) {
if (SpeculativeModeOfInput(i) == kGuardInputs) {
return kGuardInputs;
}
}
return kNotSpeculative;
}
// By default, instructions should check types of inputs when unboxing
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
return kGuardInputs;
}
// Representation of the value produced by this computation.
virtual Representation representation() const { return kTagged; }
@ -2378,7 +2389,7 @@ class PhiInstr : public Definition {
virtual void set_representation(Representation r) { representation_ = r; }
// In AOT mode Phi instructions do not check types of inputs when unboxing.
virtual SpeculativeMode speculative_mode() const {
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
return FLAG_precompiled_mode ? kNotSpeculative : kGuardInputs;
}
@ -4203,12 +4214,13 @@ class EqualityCompareInstr : public TemplateComparison<2, NoThrow, Pure> {
return kTagged;
}
virtual SpeculativeMode speculative_mode() const { return speculative_mode_; }
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
return speculative_mode_;
}
virtual bool AttributesEqual(Instruction* other) const {
return ComparisonInstr::AttributesEqual(other) &&
(speculative_mode() ==
other->AsEqualityCompare()->speculative_mode());
(speculative_mode_ == other->AsEqualityCompare()->speculative_mode_);
}
PRINT_OPERANDS_TO_SUPPORT
@ -4250,11 +4262,13 @@ class RelationalOpInstr : public TemplateComparison<2, NoThrow, Pure> {
return kTagged;
}
virtual SpeculativeMode speculative_mode() const { return speculative_mode_; }
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
return speculative_mode_;
}
virtual bool AttributesEqual(Instruction* other) const {
return ComparisonInstr::AttributesEqual(other) &&
(speculative_mode() == other->AsRelationalOp()->speculative_mode());
(speculative_mode_ == other->AsRelationalOp()->speculative_mode_);
}
PRINT_OPERANDS_TO_SUPPORT
@ -4881,7 +4895,7 @@ class StoreInstanceFieldInstr : public TemplateInstruction<2, NoThrow> {
token_pos,
kind) {}
virtual SpeculativeMode speculative_mode() const {
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
// In AOT unbox is done based on TFA, therefore it was proven to be correct
// and it can never deoptmize.
return (IsUnboxedStore() && FLAG_precompiled_mode) ? kNotSpeculative
@ -5362,7 +5376,9 @@ class StoreIndexedInstr : public TemplateInstruction<3, NoThrow> {
(emit_store_barrier_ == kEmitStoreBarrier);
}
virtual SpeculativeMode speculative_mode() const { return speculative_mode_; }
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
return speculative_mode_;
}
virtual bool ComputeCanDeoptimize() const { return false; }
@ -6306,7 +6322,9 @@ class BoxIntegerInstr : public BoxInstr {
virtual void InferRange(RangeAnalysis* analysis, Range* range);
virtual SpeculativeMode speculative_mode() const { return kNotSpeculative; }
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
return kNotSpeculative;
}
virtual CompileType ComputeType() const;
virtual bool RecomputeType();
@ -6375,7 +6393,7 @@ class UnboxInstr : public TemplateDefinition<1, NoThrow, Pure> {
Value* value() const { return inputs_[0]; }
virtual bool ComputeCanDeoptimize() const {
if (speculative_mode() == kNotSpeculative) {
if (SpeculativeModeOfInputs() == kNotSpeculative) {
return false;
}
@ -6393,7 +6411,9 @@ class UnboxInstr : public TemplateDefinition<1, NoThrow, Pure> {
return true;
}
virtual SpeculativeMode speculative_mode() const { return speculative_mode_; }
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
return speculative_mode_;
}
virtual Representation representation() const { return representation_; }
@ -6403,7 +6423,7 @@ class UnboxInstr : public TemplateDefinition<1, NoThrow, Pure> {
virtual bool AttributesEqual(Instruction* other) const {
UnboxInstr* other_unbox = other->AsUnbox();
return (representation() == other_unbox->representation()) &&
(speculative_mode() == other_unbox->speculative_mode());
(speculative_mode_ == other_unbox->speculative_mode_);
}
Definition* Canonicalize(FlowGraph* flow_graph);
@ -6763,7 +6783,9 @@ class BinaryDoubleOpInstr : public TemplateDefinition<2, NoThrow, Pure> {
return kUnboxedDouble;
}
virtual SpeculativeMode speculative_mode() const { return speculative_mode_; }
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
return speculative_mode_;
}
virtual intptr_t DeoptimizationTarget() const {
// Direct access since this instruction cannot deoptimize, and the deopt-id
@ -6781,7 +6803,7 @@ class BinaryDoubleOpInstr : public TemplateDefinition<2, NoThrow, Pure> {
virtual bool AttributesEqual(Instruction* other) const {
const BinaryDoubleOpInstr* other_bin_op = other->AsBinaryDoubleOp();
return (op_kind() == other_bin_op->op_kind()) &&
(speculative_mode() == other_bin_op->speculative_mode());
(speculative_mode_ == other_bin_op->speculative_mode_);
}
private:
@ -6939,11 +6961,14 @@ class UnaryInt64OpInstr : public UnaryIntegerOpInstr {
}
virtual bool AttributesEqual(Instruction* other) const {
UnaryInt64OpInstr* unary_op_other = other->AsUnaryInt64Op();
return UnaryIntegerOpInstr::AttributesEqual(other) &&
(speculative_mode() == other->speculative_mode());
(speculative_mode_ == unary_op_other->speculative_mode_);
}
virtual SpeculativeMode speculative_mode() const { return speculative_mode_; }
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
return speculative_mode_;
}
DECLARE_INSTRUCTION(UnaryInt64Op)
@ -7259,11 +7284,13 @@ class BinaryInt64OpInstr : public BinaryIntegerOpInstr {
return kUnboxedInt64;
}
virtual SpeculativeMode speculative_mode() const { return speculative_mode_; }
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
return speculative_mode_;
}
virtual bool AttributesEqual(Instruction* other) const {
return BinaryIntegerOpInstr::AttributesEqual(other) &&
(speculative_mode() == other->AsBinaryInt64Op()->speculative_mode());
(speculative_mode_ == other->AsBinaryInt64Op()->speculative_mode_);
}
virtual void InferRange(RangeAnalysis* analysis, Range* range);
@ -7321,7 +7348,9 @@ class ShiftInt64OpInstr : public ShiftIntegerOpInstr {
intptr_t deopt_id)
: ShiftIntegerOpInstr(op_kind, left, right, deopt_id) {}
virtual SpeculativeMode speculative_mode() const { return kNotSpeculative; }
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
return kNotSpeculative;
}
virtual bool ComputeCanDeoptimize() const { return false; }
virtual bool MayThrow() const { return true; }
@ -7380,7 +7409,9 @@ class ShiftUint32OpInstr : public ShiftIntegerOpInstr {
intptr_t deopt_id)
: ShiftIntegerOpInstr(op_kind, left, right, deopt_id) {}
virtual SpeculativeMode speculative_mode() const { return kNotSpeculative; }
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
return kNotSpeculative;
}
virtual bool ComputeCanDeoptimize() const { return false; }
virtual bool MayThrow() const { return true; }
@ -7465,10 +7496,12 @@ class UnaryDoubleOpInstr : public TemplateDefinition<1, NoThrow, Pure> {
return kUnboxedDouble;
}
virtual SpeculativeMode speculative_mode() const { return speculative_mode_; }
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
return speculative_mode_;
}
virtual bool AttributesEqual(Instruction* other) const {
return speculative_mode() == other->AsUnaryDoubleOp()->speculative_mode();
return speculative_mode_ == other->AsUnaryDoubleOp()->speculative_mode_;
}
PRINT_OPERANDS_TO_SUPPORT
@ -7614,10 +7647,12 @@ class Int64ToDoubleInstr : public TemplateDefinition<1, NoThrow, Pure> {
virtual bool ComputeCanDeoptimize() const { return false; }
virtual SpeculativeMode speculative_mode() const { return speculative_mode_; }
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
return speculative_mode_;
}
virtual bool AttributesEqual(Instruction* other) const {
return speculative_mode() == other->AsInt64ToDouble()->speculative_mode();
return speculative_mode_ == other->AsInt64ToDouble()->speculative_mode_;
}
private:
@ -7746,7 +7781,9 @@ class DoubleToFloatInstr : public TemplateDefinition<1, NoThrow, Pure> {
return kUnboxedDouble;
}
virtual SpeculativeMode speculative_mode() const { return speculative_mode_; }
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
return speculative_mode_;
}
virtual intptr_t DeoptimizationTarget() const { return GetDeoptId(); }

View file

@ -1655,7 +1655,8 @@ Definition* IntegerInstructionSelector::ConstructReplacementFor(
UnboxInstr* unbox = def->AsUnboxInt64();
Value* value = unbox->value()->CopyWithType();
intptr_t deopt_id = unbox->DeoptimizationTarget();
return new (Z) UnboxUint32Instr(value, deopt_id, def->speculative_mode());
return new (Z)
UnboxUint32Instr(value, deopt_id, def->SpeculativeModeOfInputs());
} else if (def->IsUnaryInt64Op()) {
UnaryInt64OpInstr* op = def->AsUnaryInt64Op();
Token::Kind op_kind = op->op_kind();