[vm/compiler] Remove speculative inputs from IL instructions
All inputs of IL instructions are now non-speculative,
SelectRepresentations pass now always inserts non-speculative
unboxing instructions.
In call specializer, where JIT compiler speculates, speculative Unbox
instructions are now explicitly added for inputs which may have
incorrect type. Unbox instructions now have 'value_mode' (either
kHasValidType or kCheckType) instead of speculative mode.
Added canonicalization rule to change value mode if
compiler can prove that value has correct type.
Also, cleaned up speculations around UnboxedInt32 representation in
JIT mode, which aligns this representation with other unboxed
representations.
TEST=ci
Change-Id: I52f5c959c3f6515b1a7c9e8ab15b420beed0e3f5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/391492
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
diff --git a/runtime/vm/compiler/aot/aot_call_specializer.cc b/runtime/vm/compiler/aot/aot_call_specializer.cc
index 3758ee1..4177532 100644
--- a/runtime/vm/compiler/aot/aot_call_specializer.cc
+++ b/runtime/vm/compiler/aot/aot_call_specializer.cc
@@ -290,8 +290,7 @@
if (input->Type()->ToNullableCid() == kSmiCid) {
conversion = new (Z) SmiToDoubleInstr(input, call->source());
} else if (FlowGraphCompiler::CanConvertInt64ToDouble()) {
- conversion = new (Z) Int64ToDoubleInstr(input, DeoptId::kNone,
- Instruction::kNotSpeculative);
+ conversion = new (Z) Int64ToDoubleInstr(input, DeoptId::kNone);
} else {
UNREACHABLE();
}
@@ -443,9 +442,8 @@
if (magnitude == 1) return right_definition;
InsertBefore(instr, right_definition, /*env=*/nullptr, FlowGraph::kValue);
right_value = new (Z) Value(right_definition);
- return new (Z)
- BinaryInt64OpInstr(Token::kBIT_AND, left_value, right_value,
- DeoptId::kNone, Instruction::kNotSpeculative);
+ return new (Z) BinaryInt64OpInstr(Token::kBIT_AND, left_value, right_value,
+ DeoptId::kNone);
} else {
ASSERT_EQUAL(op_kind, Token::kTRUNCDIV);
#if !defined(TARGET_ARCH_IS_32_BIT)
@@ -484,16 +482,14 @@
auto* rounding_adjustment = unboxed_constant(magnitude - 1);
InsertBefore(instr, rounding_adjustment, /*env=*/nullptr,
FlowGraph::kValue);
- rounding_adjustment = new (Z)
- BinaryInt64OpInstr(Token::kBIT_AND, new (Z) Value(sign_bit_extended),
- new (Z) Value(rounding_adjustment), DeoptId::kNone,
- Instruction::kNotSpeculative);
+ rounding_adjustment = new (Z) BinaryInt64OpInstr(
+ Token::kBIT_AND, new (Z) Value(sign_bit_extended),
+ new (Z) Value(rounding_adjustment), DeoptId::kNone);
InsertBefore(instr, rounding_adjustment, /*env=*/nullptr,
FlowGraph::kValue);
- auto* const left_definition = new (Z)
- BinaryInt64OpInstr(Token::kADD, left_value->CopyWithType(Z),
- new (Z) Value(rounding_adjustment), DeoptId::kNone,
- Instruction::kNotSpeculative);
+ auto* const left_definition = new (Z) BinaryInt64OpInstr(
+ Token::kADD, left_value->CopyWithType(Z),
+ new (Z) Value(rounding_adjustment), DeoptId::kNone);
InsertBefore(instr, left_definition, /*env=*/nullptr, FlowGraph::kValue);
left_value = new (Z) Value(left_definition);
auto* const right_definition =
@@ -553,7 +549,7 @@
replacement = new (Z) EqualityCompareInstr(
instr->source(), op_kind, left_value->CopyWithType(Z),
right_value->CopyWithType(Z), kMintCid, DeoptId::kNone,
- /*null_aware=*/either_can_be_null, Instruction::kNotSpeculative);
+ /*null_aware=*/either_can_be_null);
break;
}
case Token::kLT:
@@ -562,9 +558,9 @@
case Token::kGTE:
left_value = PrepareStaticOpInput(left_value, kMintCid, instr);
right_value = PrepareStaticOpInput(right_value, kMintCid, instr);
- replacement = new (Z) RelationalOpInstr(
- instr->source(), op_kind, left_value, right_value, kMintCid,
- DeoptId::kNone, Instruction::kNotSpeculative);
+ replacement =
+ new (Z) RelationalOpInstr(instr->source(), op_kind, left_value,
+ right_value, kMintCid, DeoptId::kNone);
break;
case Token::kMOD:
case Token::kTRUNCDIV:
@@ -605,9 +601,8 @@
} else {
left_value = PrepareStaticOpInput(left_value, kMintCid, instr);
right_value = PrepareStaticOpInput(right_value, kMintCid, instr);
- replacement = new (Z)
- BinaryInt64OpInstr(op_kind, left_value, right_value,
- DeoptId::kNone, Instruction::kNotSpeculative);
+ replacement = new (Z) BinaryInt64OpInstr(op_kind, left_value,
+ right_value, DeoptId::kNone);
}
break;
}
@@ -626,8 +621,8 @@
if (op_kind == Token::kNEGATE || op_kind == Token::kBIT_NOT) {
left_value = PrepareStaticOpInput(left_value, kMintCid, instr);
- replacement = new (Z) UnaryInt64OpInstr(
- op_kind, left_value, DeoptId::kNone, Instruction::kNotSpeculative);
+ replacement =
+ new (Z) UnaryInt64OpInstr(op_kind, left_value, DeoptId::kNone);
}
}
@@ -679,8 +674,7 @@
right_value = PrepareStaticOpInput(right_value, kDoubleCid, instr);
replacement = new (Z) EqualityCompareInstr(
instr->source(), op_kind, left_value, right_value, kDoubleCid,
- DeoptId::kNone, /*null_aware=*/false,
- Instruction::kNotSpeculative);
+ DeoptId::kNone, /*null_aware=*/false);
break;
}
break;
@@ -694,9 +688,9 @@
case Token::kGTE: {
left_value = PrepareStaticOpInput(left_value, kDoubleCid, instr);
right_value = PrepareStaticOpInput(right_value, kDoubleCid, instr);
- replacement = new (Z) RelationalOpInstr(
- instr->source(), op_kind, left_value, right_value, kDoubleCid,
- DeoptId::kNone, Instruction::kNotSpeculative);
+ replacement =
+ new (Z) RelationalOpInstr(instr->source(), op_kind, left_value,
+ right_value, kDoubleCid, DeoptId::kNone);
break;
}
case Token::kADD:
@@ -709,8 +703,7 @@
left_value = PrepareStaticOpInput(left_value, kDoubleCid, instr);
right_value = PrepareStaticOpInput(right_value, kDoubleCid, instr);
replacement = new (Z) BinaryDoubleOpInstr(
- op_kind, left_value, right_value, DeoptId::kNone, instr->source(),
- Instruction::kNotSpeculative);
+ op_kind, left_value, right_value, DeoptId::kNone, instr->source());
break;
}
@@ -739,8 +732,7 @@
if (op_kind == Token::kNEGATE) {
left_value = PrepareStaticOpInput(left_value, kDoubleCid, instr);
replacement = new (Z)
- UnaryDoubleOpInstr(Token::kNEGATE, left_value, instr->deopt_id(),
- Instruction::kNotSpeculative);
+ UnaryDoubleOpInstr(Token::kNEGATE, left_value, instr->deopt_id());
}
}
@@ -1139,10 +1131,10 @@
if (lower_limit == upper_limit) {
ConstantInstr* cid_constant = flow_graph()->GetConstant(
Smi::Handle(Z, Smi::New(lower_limit)), kUnboxedUword);
- check_range = new (Z) EqualityCompareInstr(
- call->source(), Token::kEQ, new Value(load_cid),
- new Value(cid_constant), kIntegerCid, DeoptId::kNone, false,
- Instruction::kNotSpeculative);
+ check_range = new (Z)
+ EqualityCompareInstr(call->source(), Token::kEQ, new Value(load_cid),
+ new Value(cid_constant), kIntegerCid,
+ DeoptId::kNone, /*null_aware=*/false);
} else {
check_range =
new (Z) TestRangeInstr(call->source(), new (Z) Value(load_cid),
diff --git a/runtime/vm/compiler/backend/block_builder.h b/runtime/vm/compiler/backend/block_builder.h
index d04eb4b..5941a55 100644
--- a/runtime/vm/compiler/backend/block_builder.h
+++ b/runtime/vm/compiler/backend/block_builder.h
@@ -100,20 +100,22 @@
return flow_graph_->GetConstant(Object::ZoneHandle());
}
- Definition* AddUnboxInstr(Representation rep, Value* value, bool is_checked) {
+ Definition* AddUnboxInstr(Representation rep,
+ Value* value,
+ UnboxInstr::ValueMode value_mode) {
// Unbox floats by first unboxing a double then converting it to a float.
auto const unbox_rep = rep == kUnboxedFloat
? kUnboxedDouble
: Boxing::NativeRepresentation(rep);
- Definition* unboxed_value =
- AddDefinition(UnboxInstr::Create(unbox_rep, value, DeoptId::kNone));
+ Definition* unboxed_value = AddDefinition(
+ UnboxInstr::Create(unbox_rep, value, DeoptId::kNone, value_mode));
if (rep != unbox_rep && unboxed_value->IsUnboxInteger()) {
ASSERT(RepresentationUtils::ValueSize(rep) <
RepresentationUtils::ValueSize(unbox_rep));
// Mark unboxing of small unboxed integer representations as truncating.
unboxed_value->AsUnboxInteger()->mark_truncating();
}
- if (is_checked) {
+ if (value_mode == UnboxInstr::ValueMode::kHasValidType) {
// The type of |value| has already been checked and it is safe to
// adjust reaching type. This is done manually because there is no type
// propagation when building intrinsics.
@@ -129,8 +131,8 @@
Definition* AddUnboxInstr(Representation rep,
Definition* boxed,
- bool is_checked) {
- return AddUnboxInstr(rep, new Value(boxed), is_checked);
+ UnboxInstr::ValueMode value_mode) {
+ return AddUnboxInstr(rep, new Value(boxed), value_mode);
}
BranchInstr* AddBranch(ComparisonInstr* comp,
diff --git a/runtime/vm/compiler/backend/constant_propagator_test.cc b/runtime/vm/compiler/backend/constant_propagator_test.cc
index c0736b5..3f14070 100644
--- a/runtime/vm/compiler/backend/constant_propagator_test.cc
+++ b/runtime/vm/compiler/backend/constant_propagator_test.cc
@@ -54,9 +54,9 @@
BlockBuilder builder(H.flow_graph(), b2);
v1 = H.Phi(b2, {{b1, v0}, {b3, &v1}});
builder.AddPhi(v1);
- auto v2 = builder.AddDefinition(
- new EqualityCompareInstr(InstructionSource(), Token::kEQ, new Value(v1),
- new Value(v0), kSmiCid, S.GetNextDeoptId()));
+ auto v2 = builder.AddDefinition(new EqualityCompareInstr(
+ InstructionSource(), Token::kEQ, new Value(v1), new Value(v0), kSmiCid,
+ S.GetNextDeoptId(), /*null_aware=*/false));
builder.AddBranch(new StrictCompareInstr(
InstructionSource(), Token::kEQ_STRICT, new Value(v2),
new Value(H.flow_graph()->GetConstant(Bool::True())),
@@ -245,7 +245,7 @@
auto make_int64_add = [](Definition* lhs, Definition* rhs,
intptr_t deopt_id) {
return new BinaryInt64OpInstr(Token::kADD, new Value(lhs), new Value(rhs),
- deopt_id, Instruction::kNotSpeculative);
+ deopt_id);
};
auto make_int32_add = [](Definition* lhs, Definition* rhs,
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc
index ea4e2bc..080bb73 100644
--- a/runtime/vm/compiler/backend/flow_graph.cc
+++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -1971,34 +1971,19 @@
} else {
insert_before = use->instruction();
}
- const Instruction::SpeculativeMode speculative_mode =
- use->instruction()->SpeculativeModeOfInput(use->use_index());
- Instruction* deopt_target = nullptr;
- if (speculative_mode == Instruction::kGuardInputs || to == kUnboxedInt32) {
- deopt_target = insert_before;
- }
Definition* converted = nullptr;
if (IsUnboxedInteger(from) && IsUnboxedInteger(to)) {
- const intptr_t deopt_id = (to == kUnboxedInt32) && (deopt_target != nullptr)
- ? deopt_target->DeoptimizationTarget()
- : DeoptId::kNone;
- converted =
- new (Z) IntConverterInstr(from, to, use->CopyWithType(), deopt_id);
+ converted = new (Z)
+ IntConverterInstr(from, to, use->CopyWithType(), DeoptId::kNone);
} else if ((from == kUnboxedInt32) && (to == kUnboxedDouble)) {
converted = new Int32ToDoubleInstr(use->CopyWithType());
} else if ((from == kUnboxedInt64) && (to == kUnboxedDouble) &&
CanConvertInt64ToDouble()) {
- const intptr_t deopt_id = (deopt_target != nullptr)
- ? deopt_target->DeoptimizationTarget()
- : DeoptId::kNone;
- converted = new Int64ToDoubleInstr(use->CopyWithType(), deopt_id);
+ converted = new Int64ToDoubleInstr(use->CopyWithType(), DeoptId::kNone);
} else if ((from == kTagged) && Boxing::Supports(to)) {
- const intptr_t deopt_id = (deopt_target != nullptr)
- ? deopt_target->DeoptimizationTarget()
- : DeoptId::kNone;
- converted =
- UnboxInstr::Create(to, use->CopyWithType(), deopt_id, speculative_mode);
+ converted = UnboxInstr::Create(to, use->CopyWithType(), DeoptId::kNone,
+ UnboxInstr::ValueMode::kHasValidType);
} else if ((to == kTagged) && Boxing::Supports(from)) {
converted = BoxInstr::Create(from, use->CopyWithType());
} else if ((to == kPairOfTagged) && (from == kTagged)) {
@@ -2042,23 +2027,16 @@
// trigger a deoptimization if executed. See #12417 for a discussion.
// If the use is not speculative, then this code should be unreachable.
// Insert Stop for a graceful error and aid unreachable code elimination.
- if (speculative_mode == Instruction::kNotSpeculative) {
- StopInstr* stop = new (Z) StopInstr("Incompatible conversion.");
- InsertBefore(insert_before, stop, nullptr, FlowGraph::kEffect);
- }
- const intptr_t deopt_id = (deopt_target != nullptr)
- ? deopt_target->DeoptimizationTarget()
- : DeoptId::kNone;
+ StopInstr* stop = new (Z) StopInstr("Incompatible conversion.");
+ InsertBefore(insert_before, stop, nullptr, FlowGraph::kEffect);
Definition* boxed = BoxInstr::Create(from, use->CopyWithType());
use->BindTo(boxed);
InsertBefore(insert_before, boxed, nullptr, FlowGraph::kValue);
- converted = UnboxInstr::Create(to, new (Z) Value(boxed), deopt_id,
- speculative_mode);
+ converted = UnboxInstr::Create(to, new (Z) Value(boxed), DeoptId::kNone,
+ UnboxInstr::ValueMode::kHasValidType);
}
ASSERT(converted != nullptr);
- InsertBefore(insert_before, converted,
- (deopt_target != nullptr) ? deopt_target->env() : nullptr,
- FlowGraph::kValue);
+ InsertBefore(insert_before, converted, nullptr, FlowGraph::kValue);
if (is_environment_use) {
use->BindToEnvironment(converted);
} else {
@@ -2492,13 +2470,6 @@
if (auto join = block->AsJoinEntry()) {
for (PhiIterator it(join); !it.Done(); it.Advance()) {
PhiInstr* current = it.Current();
- if (current->HasUnmatchedInputRepresentations() &&
- (current->SpeculativeModeOfInputs() == Instruction::kGuardInputs)) {
- // Can't canonicalize this instruction until all conversions for its
- // speculative inputs are inserted.
- continue;
- }
-
Definition* replacement = current->Canonicalize(this);
ASSERT(replacement != nullptr);
RELEASE_ASSERT(unmatched_representations_allowed() ||
@@ -2512,13 +2483,6 @@
}
for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
Instruction* current = it.Current();
- if (current->HasUnmatchedInputRepresentations() &&
- (current->SpeculativeModeOfInputs() == Instruction::kGuardInputs)) {
- // Can't canonicalize this instruction until all conversions for its
- // speculative inputs are inserted.
- continue;
- }
-
Instruction* replacement = current->Canonicalize(this);
if (replacement != current) {
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index 2d64564..171f1b8 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -1794,8 +1794,6 @@
switch (instr->RequiredInputRepresentation(i)) {
case kUnboxedDouble:
ASSERT(fpu_reg != kNoFpuRegister);
- ASSERT(instr->SpeculativeModeOfInput(i) ==
- Instruction::kNotSpeculative);
assembler()->LoadUnboxedDouble(
fpu_reg, reg,
compiler::target::Double::value_offset() - kHeapObjectTag);
@@ -1803,8 +1801,6 @@
case kUnboxedFloat32x4:
case kUnboxedFloat64x2:
ASSERT(fpu_reg != kNoFpuRegister);
- ASSERT(instr->SpeculativeModeOfInput(i) ==
- Instruction::kNotSpeculative);
assembler()->LoadUnboxedSimd128(
fpu_reg, reg,
compiler::target::Float32x4::value_offset() - kHeapObjectTag);
diff --git a/runtime/vm/compiler/backend/flow_graph_test.cc b/runtime/vm/compiler/backend/flow_graph_test.cc
index 505928a..3015d7f 100644
--- a/runtime/vm/compiler/backend/flow_graph_test.cc
+++ b/runtime/vm/compiler/backend/flow_graph_test.cc
@@ -46,18 +46,18 @@
BlockBuilder builder(H.flow_graph(), loop_header);
loop_var = H.Phi(loop_header, {{normal_entry, v0}, {loop_body, &add1}});
builder.AddPhi(loop_var);
- builder.AddBranch(new RelationalOpInstr(
- InstructionSource(), Token::kLT, new Value(loop_var),
- new Value(H.IntConstant(50)), kMintCid,
- S.GetNextDeoptId(), Instruction::kNotSpeculative),
- loop_body, loop_exit);
+ builder.AddBranch(
+ new RelationalOpInstr(InstructionSource(), Token::kLT,
+ new Value(loop_var), new Value(H.IntConstant(50)),
+ kMintCid, S.GetNextDeoptId()),
+ loop_body, loop_exit);
}
{
BlockBuilder builder(H.flow_graph(), loop_body);
add1 = builder.AddDefinition(new BinaryInt64OpInstr(
Token::kADD, new Value(loop_var), new Value(H.IntConstant(1)),
- S.GetNextDeoptId(), Instruction::kNotSpeculative));
+ S.GetNextDeoptId()));
builder.AddInstruction(new GotoInstr(loop_header, S.GetNextDeoptId()));
}
@@ -109,18 +109,18 @@
late_var =
H.Phi(loop_header, {{normal_entry, sentinel}, {loop_body, &add1}});
builder.AddPhi(late_var);
- builder.AddBranch(new RelationalOpInstr(
- InstructionSource(), Token::kLT, new Value(loop_var),
- new Value(H.IntConstant(10)), kMintCid,
- S.GetNextDeoptId(), Instruction::kNotSpeculative),
- loop_body, loop_exit);
+ builder.AddBranch(
+ new RelationalOpInstr(InstructionSource(), Token::kLT,
+ new Value(loop_var), new Value(H.IntConstant(10)),
+ kMintCid, S.GetNextDeoptId()),
+ loop_body, loop_exit);
}
{
BlockBuilder builder(H.flow_graph(), loop_body);
add1 = builder.AddDefinition(new BinaryInt64OpInstr(
Token::kADD, new Value(loop_var), new Value(H.IntConstant(1)),
- S.GetNextDeoptId(), Instruction::kNotSpeculative));
+ S.GetNextDeoptId()));
builder.AddInstruction(new GotoInstr(loop_header, S.GetNextDeoptId()));
}
@@ -168,16 +168,14 @@
{
BlockBuilder builder(H.flow_graph(), then_body);
double_to_float_1 = builder.AddDefinition(new DoubleToFloatInstr(
- new Value(H.DoubleConstant(1)), S.GetNextDeoptId(),
- Instruction::kNotSpeculative));
+ new Value(H.DoubleConstant(1)), S.GetNextDeoptId()));
builder.AddInstruction(new GotoInstr(join_exit, S.GetNextDeoptId()));
}
{
BlockBuilder builder(H.flow_graph(), else_body);
double_to_float_2 = builder.AddDefinition(new DoubleToFloatInstr(
- new Value(H.DoubleConstant(2)), S.GetNextDeoptId(),
- Instruction::kNotSpeculative));
+ new Value(H.DoubleConstant(2)), S.GetNextDeoptId()));
builder.AddInstruction(new GotoInstr(join_exit, S.GetNextDeoptId()));
}
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 9ee4e90..19a3a25 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -2034,7 +2034,7 @@
}
bool UnboxIntegerInstr::ComputeCanDeoptimize() const {
- if (SpeculativeModeOfInputs() == kNotSpeculative) {
+ if (value_mode() == ValueMode::kHasValidType) {
return false;
}
if (!value()->Type()->IsInt()) {
@@ -2185,7 +2185,7 @@
// F2D(D2F(v)) == v.
return value()->definition()->AsFloatToDouble()->value()->definition();
}
- if (value()->BindsToConstant()) {
+ if (value()->BindsToConstant() && value()->BoundConstant().IsDouble()) {
double narrowed_val =
static_cast<float>(Double::Cast(value()->BoundConstant()).value());
return flow_graph->GetConstant(
@@ -2219,9 +2219,9 @@
if ((op_kind() == Token::kMUL) &&
(left()->definition() == right()->definition())) {
- UnaryDoubleOpInstr* square = new UnaryDoubleOpInstr(
- Token::kSQUARE, new Value(left()->definition()), DeoptimizationTarget(),
- speculative_mode_, representation());
+ UnaryDoubleOpInstr* square =
+ new UnaryDoubleOpInstr(Token::kSQUARE, new Value(left()->definition()),
+ DeoptimizationTarget(), representation());
flow_graph->InsertBefore(this, square, env(), FlowGraph::kValue);
return square;
}
@@ -2245,7 +2245,6 @@
Token::Kind op_kind,
Value* value,
intptr_t deopt_id,
- SpeculativeMode speculative_mode,
Range* range) {
UnaryIntegerOpInstr* op = nullptr;
switch (representation) {
@@ -2258,7 +2257,7 @@
op = new UnaryUint32OpInstr(op_kind, value, deopt_id);
break;
case kUnboxedInt64:
- op = new UnaryInt64OpInstr(op_kind, value, deopt_id, speculative_mode);
+ op = new UnaryInt64OpInstr(op_kind, value, deopt_id);
break;
default:
UNREACHABLE();
@@ -2277,13 +2276,11 @@
return op;
}
-BinaryIntegerOpInstr* BinaryIntegerOpInstr::Make(
- Representation representation,
- Token::Kind op_kind,
- Value* left,
- Value* right,
- intptr_t deopt_id,
- SpeculativeMode speculative_mode) {
+BinaryIntegerOpInstr* BinaryIntegerOpInstr::Make(Representation representation,
+ Token::Kind op_kind,
+ Value* left,
+ Value* right,
+ intptr_t deopt_id) {
BinaryIntegerOpInstr* op = nullptr;
Range* right_range = nullptr;
switch (op_kind) {
@@ -2315,7 +2312,7 @@
case kUnboxedUint32:
if ((op_kind == Token::kSHL) || (op_kind == Token::kSHR) ||
(op_kind == Token::kUSHR)) {
- if (speculative_mode == kNotSpeculative) {
+ if (CompilerState::Current().is_aot()) {
op = new ShiftUint32OpInstr(op_kind, left, right, deopt_id,
right_range);
} else {
@@ -2329,7 +2326,7 @@
case kUnboxedInt64:
if ((op_kind == Token::kSHL) || (op_kind == Token::kSHR) ||
(op_kind == Token::kUSHR)) {
- if (speculative_mode == kNotSpeculative) {
+ if (CompilerState::Current().is_aot()) {
op = new ShiftInt64OpInstr(op_kind, left, right, deopt_id,
right_range);
} else {
@@ -2337,8 +2334,7 @@
right_range);
}
} else {
- op = new BinaryInt64OpInstr(op_kind, left, right, deopt_id,
- speculative_mode);
+ op = new BinaryInt64OpInstr(op_kind, left, right, deopt_id);
}
break;
default:
@@ -2350,18 +2346,16 @@
return op;
}
-BinaryIntegerOpInstr* BinaryIntegerOpInstr::Make(
- Representation representation,
- Token::Kind op_kind,
- Value* left,
- Value* right,
- intptr_t deopt_id,
- bool can_overflow,
- bool is_truncating,
- Range* range,
- SpeculativeMode speculative_mode) {
- BinaryIntegerOpInstr* op = BinaryIntegerOpInstr::Make(
- representation, op_kind, left, right, deopt_id, speculative_mode);
+BinaryIntegerOpInstr* BinaryIntegerOpInstr::Make(Representation representation,
+ Token::Kind op_kind,
+ Value* left,
+ Value* right,
+ intptr_t deopt_id,
+ bool can_overflow,
+ bool is_truncating,
+ Range* range) {
+ BinaryIntegerOpInstr* op = BinaryIntegerOpInstr::Make(representation, op_kind,
+ left, right, deopt_id);
if (op == nullptr) {
return nullptr;
}
@@ -2464,14 +2458,13 @@
} else if ((rhs > 0) && Utils::IsPowerOfTwo(rhs)) {
const int64_t shift_amount = Utils::ShiftForPowerOfTwo(rhs);
const Representation shift_amount_rep =
- (SpeculativeModeOfInputs() == kNotSpeculative) ? kUnboxedInt64
- : kTagged;
+ CompilerState::Current().is_aot() ? kUnboxedInt64 : kTagged;
ConstantInstr* constant_shift_amount = flow_graph->GetConstant(
Smi::Handle(Smi::New(shift_amount)), shift_amount_rep);
BinaryIntegerOpInstr* shift = BinaryIntegerOpInstr::Make(
representation(), Token::kSHL, left()->CopyWithType(),
new Value(constant_shift_amount), GetDeoptId(), can_overflow(),
- is_truncating(), range(), SpeculativeModeOfInputs());
+ is_truncating(), range());
if (shift != nullptr) {
// Assign a range to the shift factor, just in case range
// analysis no longer runs after this rewriting.
@@ -2517,7 +2510,7 @@
} else if (rhs == RepresentationMask(representation())) {
UnaryIntegerOpInstr* bit_not = UnaryIntegerOpInstr::Make(
representation(), Token::kBIT_NOT, left()->CopyWithType(),
- GetDeoptId(), SpeculativeModeOfInputs(), range());
+ GetDeoptId(), range());
if (bit_not != nullptr) {
flow_graph->InsertBefore(this, bit_not, env(), FlowGraph::kValue);
return bit_not;
@@ -2537,7 +2530,7 @@
} else if (rhs == -1) {
UnaryIntegerOpInstr* negation = UnaryIntegerOpInstr::Make(
representation(), Token::kNEGATE, left()->CopyWithType(),
- GetDeoptId(), SpeculativeModeOfInputs(), range());
+ GetDeoptId(), range());
if (negation != nullptr) {
flow_graph->InsertBefore(this, negation, env(), FlowGraph::kValue);
return negation;
@@ -3260,7 +3253,7 @@
// For all x, box(unbox(x)) = x.
if (auto unbox = value()->definition()->AsUnboxInt64()) {
- if (unbox->SpeculativeModeOfInputs() == kNotSpeculative) {
+ if (unbox->value_mode() == UnboxInstr::ValueMode::kHasValidType) {
return unbox->value()->definition();
}
}
@@ -3394,10 +3387,10 @@
}
}
- if ((SpeculativeModeOfInput(0) == kGuardInputs) && !ComputeCanDeoptimize()) {
+ if ((value_mode() == ValueMode::kCheckType) && HasMatchingType()) {
// Remember if we ever learn out input doesn't require checking, as
// the input Value might be later changed that would make us forget.
- set_speculative_mode(kNotSpeculative);
+ set_value_mode(ValueMode::kHasValidType);
}
if (value()->BindsToConstant()) {
@@ -3488,7 +3481,8 @@
Definition* replacement =
new UnboxInt32Instr(is_truncating() ? UnboxInt32Instr::kTruncate
: UnboxInt32Instr::kNoTruncation,
- unbox_defn->value()->CopyWithType(), GetDeoptId());
+ unbox_defn->value()->CopyWithType(), GetDeoptId(),
+ unbox_defn->value_mode());
flow_graph->InsertBefore(this, replacement, env(), FlowGraph::kValue);
return replacement;
}
@@ -3687,9 +3681,7 @@
return this;
}
ComparisonInstr* comp = replacement->AsComparison();
- if ((comp == nullptr) || comp->CanDeoptimize() ||
- ((comp->SpeculativeModeOfInputs() == kGuardInputs) &&
- comp->HasUnmatchedInputRepresentations())) {
+ if ((comp == nullptr) || comp->CanDeoptimize()) {
return this;
}
@@ -4043,28 +4035,28 @@
UnboxInstr* UnboxInstr::Create(Representation to,
Value* value,
intptr_t deopt_id,
- SpeculativeMode speculative_mode) {
+ UnboxInstr::ValueMode value_mode) {
switch (to) {
case kUnboxedInt32:
// We must truncate if we can't deoptimize.
return new UnboxInt32Instr(
- speculative_mode == SpeculativeMode::kNotSpeculative
- ? UnboxInt32Instr::kTruncate
- : UnboxInt32Instr::kNoTruncation,
- value, deopt_id, speculative_mode);
+ (value_mode == UnboxInstr::ValueMode::kCheckType)
+ ? UnboxInt32Instr::kNoTruncation
+ : UnboxInt32Instr::kTruncate,
+ value, deopt_id, value_mode);
case kUnboxedUint32:
- return new UnboxUint32Instr(value, deopt_id, speculative_mode);
+ return new UnboxUint32Instr(value, deopt_id, value_mode);
case kUnboxedInt64:
- return new UnboxInt64Instr(value, deopt_id, speculative_mode);
+ return new UnboxInt64Instr(value, deopt_id, value_mode);
case kUnboxedDouble:
case kUnboxedFloat:
case kUnboxedFloat32x4:
case kUnboxedFloat64x2:
case kUnboxedInt32x4:
- return new UnboxInstr(to, value, deopt_id, speculative_mode);
+ return new UnboxInstr(to, value, deopt_id, value_mode);
default:
UNREACHABLE();
@@ -4072,6 +4064,29 @@
}
}
+bool UnboxInstr::HasMatchingType() {
+ CompileType* type = value()->Type();
+ switch (representation_) {
+ case kUnboxedInt32:
+ case kUnboxedUint32:
+ case kUnboxedInt64:
+ return type->IsInt();
+
+ case kUnboxedDouble:
+ case kUnboxedFloat:
+ return type->IsDouble() || (type->ToCid() == kSmiCid);
+
+ case kUnboxedFloat32x4:
+ case kUnboxedFloat64x2:
+ case kUnboxedInt32x4:
+ return type->ToCid() == BoxCid();
+
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
bool UnboxInstr::CanConvertSmi() const {
switch (representation()) {
case kUnboxedDouble:
@@ -6388,12 +6403,14 @@
}
void UnboxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- if (SpeculativeModeOfInputs() == kNotSpeculative) {
- if (BoxCid() == kSmiCid) {
- // Since the representation fits in a Smi, we can extract it directly.
- ASSERT_EQUAL(value()->Type()->ToCid(), kSmiCid);
- return EmitSmiConversion(compiler);
- }
+ const intptr_t value_cid = value()->Type()->ToCid();
+ const intptr_t box_cid = BoxCid();
+
+ if (box_cid == kSmiCid || (CanConvertSmi() && (value_cid == kSmiCid))) {
+ ASSERT_EQUAL(value_cid, kSmiCid);
+ EmitSmiConversion(compiler);
+
+ } else if (value_mode() == ValueMode::kHasValidType) {
switch (representation()) {
case kUnboxedDouble:
case kUnboxedFloat:
@@ -6408,13 +6425,7 @@
break;
case kUnboxedInt64: {
- if (value()->Type()->ToCid() == kSmiCid) {
- // Smi -> int64 conversion is more efficient than
- // handling arbitrary smi/mint.
- EmitSmiConversion(compiler);
- } else {
- EmitLoadInt64FromBoxOrSmi(compiler);
- }
+ EmitLoadInt64FromBoxOrSmi(compiler);
break;
}
default:
@@ -6422,22 +6433,7 @@
break;
}
} else {
- ASSERT(SpeculativeModeOfInputs() == kGuardInputs);
- const intptr_t value_cid = value()->Type()->ToCid();
- const intptr_t box_cid = BoxCid();
-
- if (box_cid == kSmiCid || (CanConvertSmi() && (value_cid == kSmiCid))) {
- ASSERT_EQUAL(value_cid, kSmiCid);
- EmitSmiConversion(compiler);
- } else if (representation() == kUnboxedInt32 && value()->Type()->IsInt()) {
- EmitLoadInt32FromBoxOrSmi(compiler);
- } else if (representation() == kUnboxedInt64 && value()->Type()->IsInt()) {
- EmitLoadInt64FromBoxOrSmi(compiler);
- } else if ((value_cid == box_cid) || !CanDeoptimize()) {
- EmitLoadFromBox(compiler);
- } else {
- EmitLoadFromBoxWithDeopt(compiler);
- }
+ EmitLoadFromBoxWithDeopt(compiler);
}
}
@@ -6551,15 +6547,13 @@
ComparisonInstr* EqualityCompareInstr::CopyWithNewOperands(Value* new_left,
Value* new_right) {
return new EqualityCompareInstr(source(), kind(), new_left, new_right,
- operation_cid(), deopt_id(), is_null_aware(),
- speculative_mode_);
+ operation_cid(), deopt_id(), is_null_aware());
}
ComparisonInstr* RelationalOpInstr::CopyWithNewOperands(Value* new_left,
Value* new_right) {
return new RelationalOpInstr(source(), kind(), new_left, new_right,
- operation_cid(), deopt_id(),
- SpeculativeModeOfInputs());
+ operation_cid(), deopt_id());
}
ComparisonInstr* StrictCompareInstr::CopyWithNewOperands(Value* new_left,
@@ -6877,16 +6871,14 @@
intptr_t class_id,
AlignmentType alignment,
intptr_t deopt_id,
- const InstructionSource& source,
- SpeculativeMode speculative_mode)
+ const InstructionSource& source)
: TemplateInstruction(source, deopt_id),
emit_store_barrier_(emit_store_barrier),
index_unboxed_(index_unboxed),
index_scale_(index_scale),
class_id_(class_id),
alignment_(StrengthenAlignment(class_id, alignment)),
- token_pos_(source.token_pos),
- speculative_mode_(speculative_mode) {
+ token_pos_(source.token_pos) {
// In particular, notice that kPointerCid is _not_ supported because it gives
// no information about whether the elements are signed for elements with
// unboxed integer representations. The constructor must take that information
@@ -6908,7 +6900,7 @@
array()->CopyWithType(Z), box->value()->CopyWithType(Z),
value()->CopyWithType(Z), emit_store_barrier_,
/*index_unboxed=*/true, index_scale(), class_id(), alignment_,
- GetDeoptId(), source(), speculative_mode_);
+ GetDeoptId(), source());
flow_graph->InsertBefore(this, store, env(), FlowGraph::kEffect);
return nullptr;
}
@@ -7275,9 +7267,9 @@
default:
return this;
}
- auto* instr = new UnaryDoubleOpInstr(
- op_kind, new Value(InputAt(0)->definition()), GetDeoptId(),
- Instruction::kNotSpeculative, kUnboxedDouble);
+ auto* instr =
+ new UnaryDoubleOpInstr(op_kind, new Value(InputAt(0)->definition()),
+ GetDeoptId(), kUnboxedDouble);
flow_graph->InsertBefore(this, instr, env(), FlowGraph::kValue);
return instr;
}
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 2dcc427..09b0a54 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -972,14 +972,6 @@
static const intptr_t kInstructionAttrs[kNumInstructions];
- enum SpeculativeMode {
- // Types of inputs should be checked when unboxing for this instruction.
- kGuardInputs,
- // Each input is guaranteed to have a valid type for the input
- // representation and its type should not be checked when unboxing.
- kNotSpeculative
- };
-
// If the source has the inlining ID of the root function, then don't set
// the inlining ID to that; instead, treat it as unset.
explicit Instruction(const InstructionSource& source,
@@ -1265,20 +1257,6 @@
return kTagged;
}
- 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; }
@@ -2868,14 +2846,6 @@
virtual void set_representation(Representation r) { representation_ = r; }
- // Only Int32 phis in JIT mode are unboxed optimistically.
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
- return (CompilerState::Current().is_aot() ||
- (representation_ != kUnboxedInt32))
- ? kNotSpeculative
- : kGuardInputs;
- }
-
virtual uword Hash() const {
UNREACHABLE();
return 0;
@@ -3481,10 +3451,6 @@
virtual bool MayThrow() const { return false; }
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
- return kNotSpeculative;
- }
-
DECLARE_ABSTRACT_INSTRUCTION(ReturnBase)
DECLARE_EMPTY_SERIALIZATION(ReturnBaseInstr, Instruction)
@@ -4054,10 +4020,6 @@
return comparison()->RequiredInputRepresentation(i);
}
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
- return comparison()->SpeculativeModeOfInput(index);
- }
-
virtual Instruction* Canonicalize(FlowGraph* flow_graph);
void set_constant_target(TargetEntryInstr* target) {
@@ -4774,18 +4736,6 @@
bool CanReceiverBeSmiBasedOnInterfaceTarget(Zone* zone) const;
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t idx) const {
- if (type_args_len() > 0) {
- if (idx == 0) {
- return kGuardInputs;
- }
- idx--;
- }
- if (interface_target_.IsNull()) return kGuardInputs;
- return interface_target_.is_unboxed_parameter_at(idx) ? kNotSpeculative
- : kGuardInputs;
- }
-
virtual intptr_t ArgumentsSize() const;
virtual Representation RequiredInputRepresentation(intptr_t idx) const;
@@ -5072,17 +5022,6 @@
virtual bool HasUnknownSideEffects() const { return true; }
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t idx) const {
- if (type_args_len() > 0) {
- if (idx == 0) {
- return kGuardInputs;
- }
- idx--;
- }
- return interface_target_.is_unboxed_parameter_at(idx) ? kNotSpeculative
- : kGuardInputs;
- }
-
virtual intptr_t ArgumentsSize() const;
virtual Representation RequiredInputRepresentation(intptr_t idx) const;
@@ -5182,10 +5121,6 @@
return representation_;
}
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
- return kNotSpeculative;
- }
-
static bool IsSupported(Representation representation) {
switch (representation) {
case kTagged:
@@ -5320,11 +5255,8 @@
Value* right,
intptr_t cid,
intptr_t deopt_id,
- bool null_aware = false,
- SpeculativeMode speculative_mode = kGuardInputs)
- : TemplateComparison(source, kind, deopt_id),
- null_aware_(null_aware),
- speculative_mode_(speculative_mode) {
+ bool null_aware)
+ : TemplateComparison(source, kind, deopt_id), null_aware_(null_aware) {
ASSERT(Token::IsEqualityOperator(kind));
SetInputAt(0, left);
SetInputAt(1, right);
@@ -5351,23 +5283,16 @@
return kTagged;
}
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
- return speculative_mode_;
- }
-
virtual bool AttributesEqual(const Instruction& other) const {
return ComparisonInstr::AttributesEqual(other) &&
- (null_aware_ == other.AsEqualityCompare()->null_aware_) &&
- (speculative_mode_ == other.AsEqualityCompare()->speculative_mode_);
+ (null_aware_ == other.AsEqualityCompare()->null_aware_);
}
virtual Definition* Canonicalize(FlowGraph* flow_graph);
PRINT_OPERANDS_TO_SUPPORT
-#define FIELD_LIST(F) \
- F(bool, null_aware_) \
- F(const SpeculativeMode, speculative_mode_)
+#define FIELD_LIST(F) F(bool, null_aware_)
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(EqualityCompareInstr,
TemplateComparison,
@@ -5385,10 +5310,8 @@
Value* left,
Value* right,
intptr_t cid,
- intptr_t deopt_id,
- SpeculativeMode speculative_mode = kGuardInputs)
- : TemplateComparison(source, kind, deopt_id),
- speculative_mode_(speculative_mode) {
+ intptr_t deopt_id)
+ : TemplateComparison(source, kind, deopt_id) {
ASSERT(Token::IsRelationalOperator(kind));
ASSERT((cid == kSmiCid) || (cid == kMintCid) || (cid == kDoubleCid));
SetInputAt(0, left);
@@ -5411,23 +5334,9 @@
return kTagged;
}
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
- return speculative_mode_;
- }
-
- virtual bool AttributesEqual(const Instruction& other) const {
- return ComparisonInstr::AttributesEqual(other) &&
- (speculative_mode_ == other.AsRelationalOp()->speculative_mode_);
- }
-
PRINT_OPERANDS_TO_SUPPORT
-#define FIELD_LIST(F) F(const SpeculativeMode, speculative_mode_)
-
- DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(RelationalOpInstr,
- TemplateComparison,
- FIELD_LIST)
-#undef FIELD_LIST
+ DECLARE_EMPTY_SERIALIZATION(RelationalOpInstr, TemplateComparison)
private:
DISALLOW_COPY_AND_ASSIGN(RelationalOpInstr);
@@ -5478,10 +5387,6 @@
return comparison()->RequiredInputRepresentation(i);
}
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
- return comparison()->SpeculativeModeOfInput(index);
- }
-
virtual CompileType ComputeType() const;
virtual void InferRange(RangeAnalysis* analysis, Range* range);
@@ -5675,17 +5580,6 @@
bool IsRecognizedFactory() const { return is_known_list_constructor(); }
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t idx) const {
- if (type_args_len() > 0 || function().IsFactory()) {
- if (idx == 0) {
- return kGuardInputs;
- }
- idx--;
- }
- return function_.is_unboxed_parameter_at(idx) ? kNotSpeculative
- : kGuardInputs;
- }
-
virtual intptr_t ArgumentsSize() const;
virtual Representation RequiredInputRepresentation(intptr_t idx) const;
@@ -5770,17 +5664,6 @@
virtual bool CanCallDart() const { return true; }
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t idx) const {
- if (type_args_len() > 0) {
- if (idx == 0) {
- return kGuardInputs;
- }
- idx--;
- }
- return function_.is_unboxed_parameter_at(idx) ? kNotSpeculative
- : kGuardInputs;
- }
-
virtual intptr_t ArgumentsSize() const;
virtual Representation RequiredInputRepresentation(intptr_t idx) const;
@@ -6221,10 +6104,6 @@
return kUntagged;
}
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
- return kNotSpeculative;
- }
-
virtual bool MayCreateUnsafeUntaggedPointer() const {
if (representation() != kUntagged) return false;
// Returns true iff any of the inputs to the target may be an unsafe
@@ -6416,13 +6295,6 @@
source,
kind) {}
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
- // Slots are unboxed based on statically inferrable type information.
- // Either sound non-nullable static types (JIT) or global type flow analysis
- // results (AOT).
- return slot().representation() != kTagged ? kNotSpeculative : kGuardInputs;
- }
-
DECLARE_INSTRUCTION(StoreField)
DECLARE_ATTRIBUTES_NAMED(("slot", "is_initialization"),
(&slot(), is_initialization()))
@@ -7048,10 +6920,6 @@
virtual intptr_t DeoptimizationTarget() const { return DeoptId::kNone; }
virtual void InferRange(RangeAnalysis* analysis, Range* range);
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
- return kNotSpeculative;
- }
-
virtual bool AttributesEqual(const Instruction& other) const {
return scan_flags_field_.Equals(other.AsUtf8Scan()->scan_flags_field_);
}
@@ -7082,8 +6950,7 @@
intptr_t class_id,
AlignmentType alignment,
intptr_t deopt_id,
- const InstructionSource& source,
- SpeculativeMode speculative_mode = kGuardInputs);
+ const InstructionSource& source);
DECLARE_INSTRUCTION(StoreIndexed)
enum { kArrayPos = 0, kIndexPos = 1, kValuePos = 2 };
@@ -7108,10 +6975,6 @@
emit_store_barrier_ = value;
}
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
- return speculative_mode_;
- }
-
virtual bool ComputeCanDeoptimize() const { return false; }
// The value representation expected by StoreIndexed for arrays with the
@@ -7145,8 +7008,7 @@
F(const intptr_t, index_scale_) \
F(const intptr_t, class_id_) \
F(const AlignmentType, alignment_) \
- F(const TokenPosition, token_pos_) \
- F(const SpeculativeMode, speculative_mode_)
+ F(const TokenPosition, token_pos_)
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(StoreIndexedInstr,
TemplateInstruction,
@@ -8015,10 +7877,6 @@
return kUnboxedIntPtr;
}
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
- return kNotSpeculative;
- }
-
Value* base() const { return inputs_[kBasePos]; }
Value* index() const { return inputs_[kIndexPos]; }
Value* offset() const { return inputs_[kOffsetPos]; }
@@ -8557,10 +8415,6 @@
virtual TokenPosition token_pos() const { return TokenPosition::kBox; }
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
- return kNotSpeculative;
- }
-
#define FIELD_LIST(F) F(const Representation, from_representation_)
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(BoxInstr,
@@ -8680,35 +8534,29 @@
class UnboxInstr : public TemplateDefinition<1, NoThrow, Pure> {
public:
+ enum class ValueMode {
+ // Input value has a type which matches representation.
+ kHasValidType,
+ // Type of the input value should be checked during unboxing.
+ // Deoptimize if type doesn't match representation.
+ kCheckType,
+ };
+
static UnboxInstr* Create(Representation to,
Value* value,
intptr_t deopt_id,
- SpeculativeMode speculative_mode = kGuardInputs);
+ ValueMode value_mode);
Value* value() const { return inputs_[0]; }
+ bool HasMatchingType();
+
virtual bool ComputeCanDeoptimize() const {
- if (SpeculativeModeOfInputs() == kNotSpeculative) {
- return false;
- }
-
- const intptr_t value_cid = value()->Type()->ToCid();
- const intptr_t box_cid = BoxCid();
-
- if (value_cid == box_cid) {
- return false;
- }
-
- if (CanConvertSmi() && (value_cid == kSmiCid)) {
- return false;
- }
-
- return true;
+ return value_mode() == ValueMode::kCheckType;
}
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
- return speculative_mode_;
- }
+ ValueMode value_mode() const { return value_mode_; }
+ void set_value_mode(ValueMode value_mode) { value_mode_ = value_mode; }
virtual Representation representation() const { return representation_; }
@@ -8717,7 +8565,7 @@
virtual bool AttributesEqual(const Instruction& other) const {
auto const other_unbox = other.AsUnbox();
return (representation() == other_unbox->representation()) &&
- (speculative_mode_ == other_unbox->speculative_mode_);
+ (value_mode_ == other_unbox->value_mode_);
}
Definition* Canonicalize(FlowGraph* flow_graph);
@@ -8728,7 +8576,7 @@
#define FIELD_LIST(F) \
F(const Representation, representation_) \
- F(SpeculativeMode, speculative_mode_)
+ F(ValueMode, value_mode_)
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(UnboxInstr,
TemplateDefinition,
@@ -8739,19 +8587,15 @@
UnboxInstr(Representation representation,
Value* value,
intptr_t deopt_id,
- SpeculativeMode speculative_mode)
+ ValueMode value_mode)
: TemplateDefinition(deopt_id),
representation_(representation),
- speculative_mode_(speculative_mode) {
+ value_mode_(value_mode) {
// Unboxing doesn't currently handle non-native representations.
ASSERT_EQUAL(Boxing::NativeRepresentation(representation), representation);
SetInputAt(0, value);
}
- void set_speculative_mode(SpeculativeMode value) {
- speculative_mode_ = value;
- }
-
private:
bool CanConvertSmi() const;
void EmitLoadFromBox(FlowGraphCompiler* compiler);
@@ -8775,8 +8619,8 @@
TruncationMode truncation_mode,
Value* value,
intptr_t deopt_id,
- SpeculativeMode speculative_mode)
- : UnboxInstr(representation, value, deopt_id, speculative_mode),
+ ValueMode value_mode)
+ : UnboxInstr(representation, value, deopt_id, value_mode),
is_truncating_(truncation_mode == kTruncate) {}
bool is_truncating() const { return is_truncating_; }
@@ -8816,12 +8660,12 @@
TruncationMode truncation_mode,
Value* value,
intptr_t deopt_id,
- SpeculativeMode speculative_mode)
+ ValueMode value_mode)
: UnboxIntegerInstr(representation,
truncation_mode,
value,
deopt_id,
- speculative_mode) {}
+ value_mode) {}
DECLARE_INSTRUCTION_BACKEND()
@@ -8833,14 +8677,12 @@
class UnboxUint32Instr : public UnboxInteger32Instr {
public:
- UnboxUint32Instr(Value* value,
- intptr_t deopt_id,
- SpeculativeMode speculative_mode = kGuardInputs)
+ UnboxUint32Instr(Value* value, intptr_t deopt_id, ValueMode value_mode)
: UnboxInteger32Instr(kUnboxedUint32,
kTruncate,
value,
deopt_id,
- speculative_mode) {
+ value_mode) {
ASSERT(is_truncating());
}
@@ -8857,12 +8699,12 @@
UnboxInt32Instr(TruncationMode truncation_mode,
Value* value,
intptr_t deopt_id,
- SpeculativeMode speculative_mode = kGuardInputs)
+ ValueMode value_mode)
: UnboxInteger32Instr(kUnboxedInt32,
truncation_mode,
value,
deopt_id,
- speculative_mode) {}
+ value_mode) {}
DECLARE_INSTRUCTION_NO_BACKEND(UnboxInt32)
@@ -8874,14 +8716,12 @@
class UnboxInt64Instr : public UnboxIntegerInstr {
public:
- UnboxInt64Instr(Value* value,
- intptr_t deopt_id,
- SpeculativeMode speculative_mode)
+ UnboxInt64Instr(Value* value, intptr_t deopt_id, ValueMode value_mode)
: UnboxIntegerInstr(kUnboxedInt64,
kNoTruncation,
value,
deopt_id,
- speculative_mode) {}
+ value_mode) {}
DECLARE_INSTRUCTION_NO_BACKEND(UnboxInt64)
@@ -9029,12 +8869,10 @@
Value* right,
intptr_t deopt_id,
const InstructionSource& source,
- SpeculativeMode speculative_mode = kGuardInputs,
Representation representation = kUnboxedDouble)
: TemplateDefinition(source, deopt_id),
op_kind_(op_kind),
token_pos_(source.token_pos),
- speculative_mode_(speculative_mode),
representation_(representation) {
ASSERT((representation == kUnboxedFloat) ||
(representation == kUnboxedDouble));
@@ -9058,10 +8896,6 @@
return representation_;
}
- 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
// was inherited from another instruction that could deoptimize.
@@ -9079,14 +8913,12 @@
virtual bool AttributesEqual(const Instruction& other) const {
auto const other_bin_op = other.AsBinaryDoubleOp();
return (op_kind() == other_bin_op->op_kind()) &&
- (speculative_mode_ == other_bin_op->speculative_mode_) &&
(representation_ == other_bin_op->representation_);
}
#define FIELD_LIST(F) \
F(const Token::Kind, op_kind_) \
F(const TokenPosition, token_pos_) \
- F(const SpeculativeMode, speculative_mode_) \
F(const Representation, representation_)
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(BinaryDoubleOpInstr,
@@ -9244,7 +9076,6 @@
Token::Kind op_kind,
Value* value,
intptr_t deopt_id,
- SpeculativeMode speculative_mode,
Range* range);
Value* value() const { return inputs_[0]; }
@@ -9329,12 +9160,8 @@
class UnaryInt64OpInstr : public UnaryIntegerOpInstr {
public:
- UnaryInt64OpInstr(Token::Kind op_kind,
- Value* value,
- intptr_t deopt_id,
- SpeculativeMode speculative_mode = kGuardInputs)
- : UnaryIntegerOpInstr(op_kind, value, deopt_id),
- speculative_mode_(speculative_mode) {
+ UnaryInt64OpInstr(Token::Kind op_kind, Value* value, intptr_t deopt_id)
+ : UnaryIntegerOpInstr(op_kind, value, deopt_id) {
ASSERT(op_kind == Token::kBIT_NOT || op_kind == Token::kNEGATE);
}
@@ -9347,24 +9174,9 @@
return kUnboxedInt64;
}
- virtual bool AttributesEqual(const Instruction& other) const {
- auto const unary_op_other = other.AsUnaryInt64Op();
- return UnaryIntegerOpInstr::AttributesEqual(other) &&
- (speculative_mode_ == unary_op_other->speculative_mode_);
- }
-
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
- return speculative_mode_;
- }
-
DECLARE_INSTRUCTION(UnaryInt64Op)
-#define FIELD_LIST(F) F(const SpeculativeMode, speculative_mode_)
-
- DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(UnaryInt64OpInstr,
- UnaryIntegerOpInstr,
- FIELD_LIST)
-#undef FIELD_LIST
+ DECLARE_EMPTY_SERIALIZATION(UnaryInt64OpInstr, UnaryIntegerOpInstr)
private:
DISALLOW_COPY_AND_ASSIGN(UnaryInt64OpInstr);
@@ -9384,24 +9196,20 @@
SetInputAt(1, right);
}
- static BinaryIntegerOpInstr* Make(
- Representation representation,
- Token::Kind op_kind,
- Value* left,
- Value* right,
- intptr_t deopt_id,
- SpeculativeMode speculative_mode = kGuardInputs);
+ static BinaryIntegerOpInstr* Make(Representation representation,
+ Token::Kind op_kind,
+ Value* left,
+ Value* right,
+ intptr_t deopt_id);
- static BinaryIntegerOpInstr* Make(
- Representation representation,
- Token::Kind op_kind,
- Value* left,
- Value* right,
- intptr_t deopt_id,
- bool can_overflow,
- bool is_truncating,
- Range* range,
- SpeculativeMode speculative_mode = kGuardInputs);
+ static BinaryIntegerOpInstr* Make(Representation representation,
+ Token::Kind op_kind,
+ Value* left,
+ Value* right,
+ intptr_t deopt_id,
+ bool can_overflow,
+ bool is_truncating,
+ Range* range);
Token::Kind op_kind() const { return op_kind_; }
Value* left() const { return inputs_[0]; }
@@ -9569,10 +9377,6 @@
return kUnboxedUint32;
}
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
- return kNotSpeculative;
- }
-
static bool IsSupported(Token::Kind op_kind) {
switch (op_kind) {
case Token::kADD:
@@ -9600,10 +9404,8 @@
BinaryInt64OpInstr(Token::Kind op_kind,
Value* left,
Value* right,
- intptr_t deopt_id,
- SpeculativeMode speculative_mode = kGuardInputs)
- : BinaryIntegerOpInstr(op_kind, left, right, deopt_id),
- speculative_mode_(speculative_mode) {
+ intptr_t deopt_id)
+ : BinaryIntegerOpInstr(op_kind, left, right, deopt_id) {
mark_truncating();
}
@@ -9624,23 +9426,9 @@
return kUnboxedInt64;
}
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
- return speculative_mode_;
- }
-
- virtual bool AttributesEqual(const Instruction& other) const {
- return BinaryIntegerOpInstr::AttributesEqual(other) &&
- (speculative_mode_ == other.AsBinaryInt64Op()->speculative_mode_);
- }
-
DECLARE_INSTRUCTION(BinaryInt64Op)
-#define FIELD_LIST(F) F(const SpeculativeMode, speculative_mode_)
-
- DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(BinaryInt64OpInstr,
- BinaryIntegerOpInstr,
- FIELD_LIST)
-#undef FIELD_LIST
+ DECLARE_EMPTY_SERIALIZATION(BinaryInt64OpInstr, BinaryIntegerOpInstr)
private:
DISALLOW_COPY_AND_ASSIGN(BinaryInt64OpInstr);
@@ -9700,9 +9488,6 @@
Range* right_range = nullptr)
: ShiftIntegerOpInstr(op_kind, left, right, deopt_id, right_range) {}
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
- return kNotSpeculative;
- }
virtual bool ComputeCanDeoptimize() const { return false; }
virtual bool MayThrow() const { return !IsShiftCountInRange(); }
@@ -9763,9 +9548,6 @@
Range* right_range = nullptr)
: ShiftIntegerOpInstr(op_kind, left, right, deopt_id, right_range) {}
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
- return kNotSpeculative;
- }
virtual bool ComputeCanDeoptimize() const { return false; }
virtual bool MayThrow() const {
return !IsShiftCountInRange(kUint32ShiftCountLimit);
@@ -9824,11 +9606,9 @@
UnaryDoubleOpInstr(Token::Kind op_kind,
Value* value,
intptr_t deopt_id,
- SpeculativeMode speculative_mode = kGuardInputs,
Representation representation = kUnboxedDouble)
: TemplateDefinition(deopt_id),
op_kind_(op_kind),
- speculative_mode_(speculative_mode),
representation_(representation) {
ASSERT((representation == kUnboxedFloat) ||
(representation == kUnboxedDouble));
@@ -9855,14 +9635,9 @@
return representation_;
}
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
- return speculative_mode_;
- }
-
virtual bool AttributesEqual(const Instruction& other) const {
auto other_op = other.Cast<UnaryDoubleOpInstr>();
return (op_kind_ == other_op->op_kind_) &&
- (speculative_mode_ == other_op->speculative_mode_) &&
(representation_ == other_op->representation_);
}
@@ -9872,7 +9647,6 @@
#define FIELD_LIST(F) \
F(const Token::Kind, op_kind_) \
- F(const SpeculativeMode, speculative_mode_) \
F(const Representation, representation_)
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(UnaryDoubleOpInstr,
@@ -10008,10 +9782,8 @@
class Int64ToDoubleInstr : public TemplateDefinition<1, NoThrow, Pure> {
public:
- Int64ToDoubleInstr(Value* value,
- intptr_t deopt_id,
- SpeculativeMode speculative_mode = kGuardInputs)
- : TemplateDefinition(deopt_id), speculative_mode_(speculative_mode) {
+ Int64ToDoubleInstr(Value* value, intptr_t deopt_id)
+ : TemplateDefinition(deopt_id) {
SetInputAt(0, value);
}
@@ -10034,20 +9806,9 @@
virtual bool ComputeCanDeoptimize() const { return false; }
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
- return speculative_mode_;
- }
+ virtual bool AttributesEqual(const Instruction& other) const { return true; }
- virtual bool AttributesEqual(const Instruction& other) const {
- return speculative_mode_ == other.AsInt64ToDouble()->speculative_mode_;
- }
-
-#define FIELD_LIST(F) F(const SpeculativeMode, speculative_mode_)
-
- DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(Int64ToDoubleInstr,
- TemplateDefinition,
- FIELD_LIST)
-#undef FIELD_LIST
+ DECLARE_EMPTY_SERIALIZATION(Int64ToDoubleInstr, TemplateDefinition)
private:
DISALLOW_COPY_AND_ASSIGN(Int64ToDoubleInstr);
@@ -10077,11 +9838,6 @@
return kUnboxedDouble;
}
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t idx) const {
- ASSERT(idx == 0);
- return kNotSpeculative;
- }
-
virtual bool ComputeCanDeoptimize() const {
return !CompilerState::Current().is_aot();
}
@@ -10142,10 +9898,8 @@
class DoubleToFloatInstr : public TemplateDefinition<1, NoThrow, Pure> {
public:
- DoubleToFloatInstr(Value* value,
- intptr_t deopt_id,
- SpeculativeMode speculative_mode = kGuardInputs)
- : TemplateDefinition(deopt_id), speculative_mode_(speculative_mode) {
+ DoubleToFloatInstr(Value* value, intptr_t deopt_id)
+ : TemplateDefinition(deopt_id) {
SetInputAt(0, value);
}
@@ -10162,22 +9916,13 @@
return kUnboxedDouble;
}
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
- return speculative_mode_;
- }
-
virtual intptr_t DeoptimizationTarget() const { return GetDeoptId(); }
virtual bool AttributesEqual(const Instruction& other) const { return true; }
virtual Definition* Canonicalize(FlowGraph* flow_graph);
-#define FIELD_LIST(F) F(const SpeculativeMode, speculative_mode_)
-
- DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(DoubleToFloatInstr,
- TemplateDefinition,
- FIELD_LIST)
-#undef FIELD_LIST
+ DECLARE_EMPTY_SERIALIZATION(DoubleToFloatInstr, TemplateDefinition)
private:
DISALLOW_COPY_AND_ASSIGN(DoubleToFloatInstr);
@@ -10283,11 +10028,6 @@
return kUnboxedDouble;
}
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t idx) const {
- ASSERT((0 <= idx) && (idx < InputCount()));
- return kNotSpeculative;
- }
-
virtual intptr_t DeoptimizationTarget() const { return GetDeoptId(); }
virtual bool AllowsCSE() const { return true; }
@@ -10530,10 +10270,6 @@
virtual TokenPosition token_pos() const { return TokenPosition::kBox; }
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
- return kNotSpeculative;
- }
-
PRINT_OPERANDS_TO_SUPPORT
#define FIELD_LIST(F) F(const Representation, from_representation_)
@@ -10905,10 +10641,6 @@
virtual intptr_t DeoptimizationTarget() const { return DeoptId::kNone; }
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
- return kNotSpeculative;
- }
-
virtual Representation representation() const {
return UseUnboxedRepresentation() ? kUnboxedInt64 : kTagged;
}
diff --git a/runtime/vm/compiler/backend/il_printer.cc b/runtime/vm/compiler/backend/il_printer.cc
index 306ae46..36c59dc 100644
--- a/runtime/vm/compiler/backend/il_printer.cc
+++ b/runtime/vm/compiler/backend/il_printer.cc
@@ -994,11 +994,6 @@
void RelationalOpInstr::PrintOperandsTo(BaseTextBuffer* f) const {
f->Printf("%s, ", Token::Str(kind()));
- if (SpeculativeModeOfInputs() == kGuardInputs) {
- f->AddString("[guard-inputs], ");
- } else {
- f->AddString("[non-speculative], ");
- }
left()->PrintTo(f);
f->AddString(", ");
right()->PrintTo(f);
@@ -1305,10 +1300,8 @@
if (is_truncating()) {
f->AddString("[tr], ");
}
- if (SpeculativeModeOfInputs() == kGuardInputs) {
- f->AddString("[guard-inputs], ");
- } else {
- f->AddString("[non-speculative], ");
+ if (value_mode() == ValueMode::kCheckType) {
+ f->AddString("[check-type], ");
}
Definition::PrintOperandsTo(f);
}
diff --git a/runtime/vm/compiler/backend/il_test.cc b/runtime/vm/compiler/backend/il_test.cc
index b6f805e..dae4430 100644
--- a/runtime/vm/compiler/backend/il_test.cc
+++ b/runtime/vm/compiler/backend/il_test.cc
@@ -357,8 +357,9 @@
new Value(H.flow_graph()->constant_null()),
/* dst_name */ String::Handle(String::New("not-null")),
S.GetNextDeoptId()));
- unbox = builder.AddDefinition(new UnboxInt64Instr(
- new Value(cast), S.GetNextDeoptId(), BoxInstr::kGuardInputs));
+ unbox = builder.AddDefinition(
+ new UnboxInt64Instr(new Value(cast), S.GetNextDeoptId(),
+ UnboxInstr::ValueMode::kCheckType));
builder.AddInstruction(new StoreIndexedInstr(
new Value(int64_array), new Value(index), new Value(unbox),
@@ -1214,11 +1215,11 @@
new Value(array), Slot::Array_length(), InstructionSource()));
unbox = builder.AddDefinition(new UnboxInt64Instr(
- new Value(load), DeoptId::kNone, Instruction::kNotSpeculative));
+ new Value(load), DeoptId::kNone, UnboxInstr::ValueMode::kHasValidType));
add = builder.AddDefinition(new BinaryInt64OpInstr(
Token::kADD, new Value(unbox), new Value(H.IntConstant(1)),
- S.GetNextDeoptId(), Instruction::kNotSpeculative));
+ S.GetNextDeoptId()));
Definition* box = builder.AddDefinition(new BoxInt64Instr(new Value(add)));
@@ -1811,12 +1812,12 @@
? H.IntConstant(immediate_mask.value(), rep)
: builder.AddParameter(1);
if (rep != lhs->representation()) {
- lhs =
- builder.AddUnboxInstr(kUnboxedInt64, lhs, /*is_checked=*/false);
+ lhs = builder.AddUnboxInstr(kUnboxedInt64, lhs,
+ UnboxInstr::ValueMode::kHasValidType);
}
if (rep != rhs->representation()) {
- rhs =
- builder.AddUnboxInstr(kUnboxedInt64, rhs, /*is_checked=*/false);
+ rhs = builder.AddUnboxInstr(kUnboxedInt64, rhs,
+ UnboxInstr::ValueMode::kHasValidType);
}
auto comparison = new TestIntInstr(
diff --git a/runtime/vm/compiler/backend/inliner.cc b/runtime/vm/compiler/backend/inliner.cc
index 9d53302..039d896 100644
--- a/runtime/vm/compiler/backend/inliner.cc
+++ b/runtime/vm/compiler/backend/inliner.cc
@@ -486,12 +486,6 @@
last_unhandled_call_index--;
}
- // Can't apply canonicalization rule to this definition.
- if (defn->HasUnmatchedInputRepresentations() &&
- defn->SpeculativeModeOfInputs() == Instruction::kGuardInputs) {
- continue;
- }
-
auto replacement = defn->Canonicalize(graph);
if (replacement != defn) {
changed = true;
@@ -2216,7 +2210,7 @@
call_->source(), Token::kEQ, new Value(load_cid),
new Value(cid_constant),
cid_representation == kTagged ? kSmiCid : kIntegerCid,
- DeoptId::kNone, false, Instruction::kNotSpeculative);
+ DeoptId::kNone, /*null_aware=*/false);
} else {
compare = new TestRangeInstr(call_->source(), new Value(load_cid),
variant.cid_start, variant.cid_end,
diff --git a/runtime/vm/compiler/backend/memory_copy_test.cc b/runtime/vm/compiler/backend/memory_copy_test.cc
index c256f1f..47b6aa7 100644
--- a/runtime/vm/compiler/backend/memory_copy_test.cc
+++ b/runtime/vm/compiler/backend/memory_copy_test.cc
@@ -335,19 +335,19 @@
if (unboxed_inputs) {
// Manually add the unbox instruction ourselves instead of leaving it
// up to the SelectDefinitions pass.
- length_def =
- UnboxInstr::Create(kUnboxedWord, new (zone) Value(param_length),
- DeoptId::kNone, Instruction::kNotSpeculative);
+ length_def = UnboxInstr::Create(
+ kUnboxedWord, new (zone) Value(param_length), DeoptId::kNone,
+ UnboxInstr::ValueMode::kHasValidType);
flow_graph->InsertBefore(return_instr, length_def, nullptr,
FlowGraph::kValue);
- dest_start_def =
- UnboxInstr::Create(kUnboxedWord, new (zone) Value(param_dest_start),
- DeoptId::kNone, Instruction::kNotSpeculative);
+ dest_start_def = UnboxInstr::Create(
+ kUnboxedWord, new (zone) Value(param_dest_start), DeoptId::kNone,
+ UnboxInstr::ValueMode::kHasValidType);
flow_graph->InsertBefore(length_def, dest_start_def, nullptr,
FlowGraph::kValue);
- src_start_def =
- UnboxInstr::Create(kUnboxedWord, new (zone) Value(param_src_start),
- DeoptId::kNone, Instruction::kNotSpeculative);
+ src_start_def = UnboxInstr::Create(
+ kUnboxedWord, new (zone) Value(param_src_start), DeoptId::kNone,
+ UnboxInstr::ValueMode::kHasValidType);
flow_graph->InsertBefore(dest_start_def, src_start_def, nullptr,
FlowGraph::kValue);
}
diff --git a/runtime/vm/compiler/backend/range_analysis.cc b/runtime/vm/compiler/backend/range_analysis.cc
index 1e2490a..040fefe 100644
--- a/runtime/vm/compiler/backend/range_analysis.cc
+++ b/runtime/vm/compiler/backend/range_analysis.cc
@@ -1654,10 +1654,8 @@
Value* left = op->left()->CopyWithType();
Value* right = op->right()->CopyWithType();
intptr_t deopt_id = op->DeoptimizationTarget();
- return BinaryIntegerOpInstr::Make(
- kUnboxedUint32, op_kind, left, right, deopt_id,
- def->IsSpeculativeShiftInt64Op() ? Instruction::kGuardInputs
- : Instruction::kNotSpeculative);
+ return BinaryIntegerOpInstr::Make(kUnboxedUint32, op_kind, left, right,
+ deopt_id);
} else if (def->IsBoxInt64()) {
Value* value = def->AsBoxInt64()->value()->CopyWithType();
return new (Z) BoxUint32Instr(value);
@@ -1665,8 +1663,7 @@
UnboxInstr* unbox = def->AsUnboxInt64();
Value* value = unbox->value()->CopyWithType();
intptr_t deopt_id = unbox->DeoptimizationTarget();
- return new (Z)
- UnboxUint32Instr(value, deopt_id, def->SpeculativeModeOfInputs());
+ return new (Z) UnboxUint32Instr(value, deopt_id, unbox->value_mode());
} else if (def->IsUnaryInt64Op()) {
UnaryInt64OpInstr* op = def->AsUnaryInt64Op();
Token::Kind op_kind = op->op_kind();
diff --git a/runtime/vm/compiler/backend/redundancy_elimination_test.cc b/runtime/vm/compiler/backend/redundancy_elimination_test.cc
index 06a3efc..8104c5a 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination_test.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination_test.cc
@@ -1281,47 +1281,44 @@
/* Flow graph to match:
4: CheckStackOverflow:8(stack=0, loop=0)
- 5: ParallelMove rax <- S+2
- 6: CheckClass:14(v2 Cids[1: _Double@0150898 etc. cid 62] nullcheck)
- 8: v312 <- Unbox:14(v2 T{_Double}) T{_Double}
- 10: ParallelMove xmm1 <- C
- 10: v221 <- BinaryDoubleOp:22(+, v341, v312) T{_Double}
- 11: ParallelMove DS-7 <- xmm1
- 12: ParallelMove xmm2 <- C
- 12: v227 <- BinaryDoubleOp:34(+, v342, v312) T{_Double}
- 13: ParallelMove DS-6 <- xmm2
- 14: v333 <- Box(v221) T{_Double}
- 15: ParallelMove S-4 <- rax
- 16: v334 <- Box(v227) T{_Double}
- 17: ParallelMove S-3 <- rcx
- 18: ParallelMove xmm0 <- xmm1
- 18: v15 <- BinaryDoubleOp:28(+, v221, v227) T{_Double}
- 19: ParallelMove rbx <- C, r10 <- C, DS-5 <- xmm0
- 20: v17 <- CreateArray:30(v0, v16) T{_List}
- 21: ParallelMove rcx <- rax
- 22: StoreIndexed(v17, v5, v18, NoStoreBarrier)
- 24: StoreIndexed(v17, v6, v6, NoStoreBarrier)
- 26: StoreIndexed(v17, v3, v20, NoStoreBarrier)
- 28: StoreIndexed(v17, v21, v7, NoStoreBarrier)
- 30: StoreIndexed(v17, v23, v24, NoStoreBarrier)
- 32: StoreIndexed(v17, v25, v8, NoStoreBarrier)
- 34: StoreIndexed(v17, v27, v20, NoStoreBarrier)
- 36: StoreIndexed(v17, v28, v9, NoStoreBarrier)
- 38: StoreIndexed(v17, v30, v31, NoStoreBarrier)
- 39: ParallelMove rax <- S-4
- 40: StoreIndexed(v17, v32, v333, NoStoreBarrier)
- 42: StoreIndexed(v17, v34, v20, NoStoreBarrier)
- 43: ParallelMove rax <- S-3
- 44: StoreIndexed(v17, v35, v334, NoStoreBarrier)
- 46: StoreIndexed(v17, v37, v38, NoStoreBarrier)
- 47: ParallelMove xmm0 <- DS-5
- 48: v335 <- Box(v15) T{_Double}
- 49: ParallelMove rdx <- rcx, rax <- rax
- 50: StoreIndexed(v17, v39, v335)
- 52: MoveArgument(v17)
- 54: v40 <- StaticCall:44( _interpolate@0150898<0> v17,
- recognized_kind = StringBaseInterpolate) T{String?}
- 56: Return:48(v40)
+ 5: ParallelMove rax <- fp[2]
+ 6: v291 <- Unbox:14(v2) double
+ 8: ParallelMove xmm2 <- C
+ 8: v208 <- BinaryDoubleOp:22(+, v297 T{_Double}, v291 T{_Double}) double
+ 9: ParallelMove fp[-5] f64 <- xmm2
+ 10: v214 <- BinaryDoubleOp:34(+, v291 T{_Double}, v298 T{_Double}) double
+ 11: ParallelMove fp[-4] f64 <- xmm1
+ 12: ParallelMove xmm0 <- xmm2
+ 12: v15 <- BinaryDoubleOp:28(+, v208 T{_Double}, v214 T{_Double}) double
+ 13: ParallelMove rbx <- C, r10 <- C, fp[-3] f64 <- xmm0
+ 14: v17 <- CreateArray:30(v0, v16) T{_List}
+ 15: ParallelMove rcx <- rax
+ 16: StoreIndexed([_List] v17, v5, v18, NoStoreBarrier)
+ 18: StoreIndexed([_List] v17, v6, v6, NoStoreBarrier)
+ 20: StoreIndexed([_List] v17, v3, v20, NoStoreBarrier)
+ 22: StoreIndexed([_List] v17, v21, v7, NoStoreBarrier)
+ 24: StoreIndexed([_List] v17, v23, v24, NoStoreBarrier)
+ 26: StoreIndexed([_List] v17, v25, v8 T{_Double}, NoStoreBarrier)
+ 28: StoreIndexed([_List] v17, v27, v20, NoStoreBarrier)
+ 30: StoreIndexed([_List] v17, v28, v9 T{_Double}, NoStoreBarrier)
+ 32: StoreIndexed([_List] v17, v30, v31, NoStoreBarrier)
+ 33: ParallelMove xmm0 <- fp[-5] f64
+ 34: v295 <- Box(v208 T{_Double}) T{_Double}
+ 35: ParallelMove rdx <- rcx, rax <- rax
+ 36: StoreIndexed([_List] v17, v32, v295 T{_Double})
+ 38: StoreIndexed([_List] v17, v34, v20, NoStoreBarrier)
+ 39: ParallelMove xmm0 <- fp[-4] f64
+ 40: v296 <- Box(v214 T{_Double}) T{_Double}
+ 41: ParallelMove rdx <- rcx, rax <- rax
+ 42: StoreIndexed([_List] v17, v35, v296 T{_Double})
+ 44: StoreIndexed([_List] v17, v37, v38, NoStoreBarrier)
+ 45: ParallelMove xmm0 <- fp[-3] f64
+ 46: v292 <- Box(v15) T{_Double}
+ 47: ParallelMove rdx <- rcx, rax <- rax
+ 48: StoreIndexed([_List] v17, v39, v292 T{_Double})
+ 50: MoveArgument(sp[0] <- v17)
+ 52: v40 <- StaticCall:44( _interpolate@0150898<0> v17, recognized_kind = StringBaseInterpolate) T{String}
+ 54: DartReturn:48(v40)
*/
CreateArrayInstr* create_array = nullptr;
@@ -1337,8 +1334,6 @@
kMatchAndMoveUnbox,
kMatchAndMoveBinaryDoubleOp,
kMatchAndMoveBinaryDoubleOp,
- kMatchAndMoveBox,
- kMatchAndMoveBox,
kMatchAndMoveBinaryDoubleOp,
{kMatchAndMoveCreateArray, &create_array},
kMatchAndMoveStoreIndexed,
@@ -1350,8 +1345,10 @@
kMatchAndMoveStoreIndexed,
kMatchAndMoveStoreIndexed,
kMatchAndMoveStoreIndexed,
+ kMatchAndMoveBox,
kMatchAndMoveStoreIndexed,
kMatchAndMoveStoreIndexed,
+ kMatchAndMoveBox,
kMatchAndMoveStoreIndexed,
kMatchAndMoveStoreIndexed,
kMatchAndMoveBox,
diff --git a/runtime/vm/compiler/backend/type_propagator_test.cc b/runtime/vm/compiler/backend/type_propagator_test.cc
index b79ef79..33d27fa 100644
--- a/runtime/vm/compiler/backend/type_propagator_test.cc
+++ b/runtime/vm/compiler/backend/type_propagator_test.cc
@@ -372,7 +372,7 @@
auto input = v3->InputAt(i);
auto unbox =
new UnboxInt64Instr(input->CopyWithType(), S.GetNextDeoptId(),
- Instruction::kNotSpeculative);
+ UnboxInstr::ValueMode::kHasValidType);
H.flow_graph()->InsertBefore(
v3->block()->PredecessorAt(i)->last_instruction(), unbox, nullptr,
FlowGraph::kValue);
diff --git a/runtime/vm/compiler/call_specializer.cc b/runtime/vm/compiler/call_specializer.cc
index dedf2c3..21fe4ac 100644
--- a/runtime/vm/compiler/call_specializer.cc
+++ b/runtime/vm/compiler/call_specializer.cc
@@ -336,9 +336,9 @@
}
// Comparing char-codes instead of strings.
- EqualityCompareInstr* comp =
- new (Z) EqualityCompareInstr(call->source(), op_kind, left_val,
- right_val, kSmiCid, call->deopt_id());
+ EqualityCompareInstr* comp = new (Z) EqualityCompareInstr(
+ call->source(), op_kind, left_val, right_val, kSmiCid, call->deopt_id(),
+ /*null_aware=*/false);
ReplaceCall(call, comp);
// Remove dead instructions.
@@ -367,8 +367,8 @@
ASSERT(call->type_args_len() == 0);
ASSERT(call->ArgumentCount() == 2);
- Definition* const left = call->ArgumentAt(0);
- Definition* const right = call->ArgumentAt(1);
+ Definition* left = call->ArgumentAt(0);
+ Definition* right = call->ArgumentAt(1);
intptr_t cid = kIllegalCid;
if (binary_feedback.OperandsAre(kOneByteStringCid)) {
@@ -385,6 +385,14 @@
cid = kSmiCid;
} else if (binary_feedback.OperandsAreSmiOrMint()) {
cid = 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);
} else if (binary_feedback.OperandsAreSmiOrDouble()) {
// Use double comparison.
if (SmiFitsInDouble()) {
@@ -403,6 +411,14 @@
cid = kDoubleCid;
}
}
+ left =
+ UnboxInstr::Create(kUnboxedDouble, new (Z) Value(left),
+ call->deopt_id(), UnboxInstr::ValueMode::kCheckType);
+ InsertBefore(call, left, call->env(), FlowGraph::kValue);
+ right =
+ UnboxInstr::Create(kUnboxedDouble, new (Z) Value(right),
+ call->deopt_id(), UnboxInstr::ValueMode::kCheckType);
+ InsertBefore(call, right, call->env(), FlowGraph::kValue);
} else {
// Check if ICDData contains checks with Smi/Null combinations. In that case
// we can still emit the optimized Smi equality operation but need to add
@@ -431,9 +447,9 @@
}
}
ASSERT(cid != kIllegalCid);
- EqualityCompareInstr* comp =
- new (Z) EqualityCompareInstr(call->source(), op_kind, new (Z) Value(left),
- new (Z) Value(right), cid, call->deopt_id());
+ EqualityCompareInstr* comp = new (Z) EqualityCompareInstr(
+ call->source(), op_kind, new (Z) Value(left), new (Z) Value(right), cid,
+ call->deopt_id(), /*null_aware=*/false);
ReplaceCall(call, comp);
return true;
}
@@ -459,6 +475,14 @@
call->env(), FlowGraph::kEffect);
cid = kSmiCid;
} else if (binary_feedback.OperandsAreSmiOrMint()) {
+ 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);
cid = kMintCid;
} else if (binary_feedback.OperandsAreSmiOrDouble()) {
// Use double comparison.
@@ -478,6 +502,14 @@
cid = kDoubleCid;
}
}
+ left =
+ UnboxInstr::Create(kUnboxedDouble, new (Z) Value(left),
+ call->deopt_id(), UnboxInstr::ValueMode::kCheckType);
+ InsertBefore(call, left, call->env(), FlowGraph::kValue);
+ right =
+ UnboxInstr::Create(kUnboxedDouble, new (Z) Value(right),
+ call->deopt_id(), UnboxInstr::ValueMode::kCheckType);
+ InsertBefore(call, right, call->env(), FlowGraph::kValue);
} else {
return false;
}
@@ -606,7 +638,14 @@
new (Z) Value(left), new (Z) Value(right), call->deopt_id()),
call->env(), FlowGraph::kEffect);
}
-
+ left =
+ UnboxInstr::Create(kUnboxedDouble, new (Z) Value(left),
+ call->deopt_id(), UnboxInstr::ValueMode::kCheckType);
+ InsertBefore(call, left, call->env(), FlowGraph::kValue);
+ right =
+ UnboxInstr::Create(kUnboxedDouble, new (Z) Value(right),
+ call->deopt_id(), UnboxInstr::ValueMode::kCheckType);
+ InsertBefore(call, right, call->env(), FlowGraph::kValue);
BinaryDoubleOpInstr* double_bin_op = new (Z)
BinaryDoubleOpInstr(op_kind, new (Z) Value(left), new (Z) Value(right),
call->deopt_id(), call->source());
@@ -614,11 +653,24 @@
} else if (operands_type == kMintCid) {
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);
} 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(
op_kind, new (Z) Value(left), new (Z) Value(right), call->deopt_id());
ReplaceCall(call, bin_op);
@@ -689,11 +741,19 @@
UnarySmiOpInstr(op_kind, new (Z) Value(input), call->deopt_id());
} else if ((op_kind == Token::kBIT_NOT) &&
call->Targets().ReceiverIsSmiOrMint()) {
+ input =
+ UnboxInstr::Create(kUnboxedInt64, new (Z) Value(input),
+ call->deopt_id(), UnboxInstr::ValueMode::kCheckType);
+ InsertBefore(call, input, call->env(), FlowGraph::kValue);
unary_op = new (Z)
UnaryInt64OpInstr(op_kind, new (Z) Value(input), call->deopt_id());
} else if (call->Targets().ReceiverIs(kDoubleCid) &&
(op_kind == Token::kNEGATE)) {
AddReceiverCheck(call);
+ input =
+ UnboxInstr::Create(kUnboxedDouble, new (Z) Value(input),
+ call->deopt_id(), UnboxInstr::ValueMode::kCheckType);
+ InsertBefore(call, input, call->env(), FlowGraph::kValue);
unary_op = new (Z) UnaryDoubleOpInstr(Token::kNEGATE, new (Z) Value(input),
call->deopt_id());
} else {
@@ -965,17 +1025,20 @@
MethodRecognizer::Kind recognized_kind = target.recognized_kind();
if (recognized_kind == MethodRecognizer::kIntegerToDouble) {
+ Definition* input = call->ArgumentAt(0);
if (receiver_cid == kSmiCid) {
AddReceiverCheck(call);
- ReplaceCall(call,
- new (Z) SmiToDoubleInstr(new (Z) Value(call->ArgumentAt(0)),
- call->source()));
+ ReplaceCall(
+ call, new (Z) SmiToDoubleInstr(new (Z) Value(input), call->source()));
return true;
} else if ((receiver_cid == kMintCid) && CanConvertInt64ToDouble()) {
AddReceiverCheck(call);
- ReplaceCall(call,
- new (Z) Int64ToDoubleInstr(new (Z) Value(call->ArgumentAt(0)),
- call->deopt_id()));
+ input = UnboxInstr::Create(kUnboxedInt64, new (Z) Value(input),
+ call->deopt_id(),
+ UnboxInstr::ValueMode::kCheckType);
+ InsertBefore(call, input, call->env(), FlowGraph::kValue);
+ ReplaceCall(call, new (Z) Int64ToDoubleInstr(new (Z) Value(input),
+ call->deopt_id()));
return true;
}
}
@@ -1204,10 +1267,10 @@
InsertBefore(call, load_cid, nullptr, FlowGraph::kValue);
ConstantInstr* constant_cid = flow_graph()->GetConstant(
Smi::Handle(Z, Smi::New(type_cid)), kUnboxedUword);
- EqualityCompareInstr* check_cid = new (Z) EqualityCompareInstr(
- call->source(), Token::kEQ, new Value(load_cid),
- new Value(constant_cid), kIntegerCid, DeoptId::kNone, false,
- Instruction::kNotSpeculative);
+ EqualityCompareInstr* check_cid = new (Z)
+ EqualityCompareInstr(call->source(), Token::kEQ, new Value(load_cid),
+ new Value(constant_cid), kIntegerCid,
+ DeoptId::kNone, /*null_aware=*/false);
ReplaceCall(call, check_cid);
return;
}
@@ -1668,19 +1731,17 @@
// Insert explicit unboxing instructions with truncation to avoid relying
// on [SelectRepresentations] which doesn't mark them as truncating.
value = UnboxInstr::Create(rep, new (Z) Value(value), deopt_id,
- Instruction::kNotSpeculative);
+ UnboxInstr::ValueMode::kHasValidType);
flow_graph_->InsertBefore(call, value, call->env(), FlowGraph::kValue);
} else if (rep == kUnboxedFloat) {
- value = new (Z) DoubleToFloatInstr(new (Z) Value(value), deopt_id,
- Instruction::kNotSpeculative);
+ value = new (Z) DoubleToFloatInstr(new (Z) Value(value), deopt_id);
flow_graph_->InsertBefore(call, value, call->env(), FlowGraph::kValue);
}
auto store = new (Z) StoreIndexedInstr(
new (Z) Value(array), new (Z) Value(index), new (Z) Value(value),
kNoStoreBarrier, /*index_unboxed=*/false, index_scale, cid,
- kAlignedAccess, DeoptId::kNone, call->source(),
- Instruction::kNotSpeculative);
+ kAlignedAccess, DeoptId::kNone, call->source());
flow_graph_->InsertBefore(call, store, call->env(), FlowGraph::kEffect);
}
@@ -1938,7 +1999,7 @@
// on [SelectRepresentations] which doesn't mark them as truncating.
stored_value =
UnboxInstr::Create(rep, new (Z) Value(stored_value), call->deopt_id(),
- Instruction::kNotSpeculative);
+ UnboxInstr::ValueMode::kHasValidType);
*last = flow_graph->AppendTo(*last, stored_value, call->env(),
FlowGraph::kValue);
}
@@ -1971,7 +2032,14 @@
new (Z) FunctionEntryInstr(graph_entry, flow_graph->allocate_block_id(),
call->GetBlock()->try_index(), DeoptId::kNone);
(*entry)->InheritDeoptTarget(Z, call);
- // Arguments are checked. No need for class check.
+ left =
+ UnboxInstr::Create(kUnboxedDouble, new (Z) Value(left), call->deopt_id(),
+ UnboxInstr::ValueMode::kCheckType);
+ flow_graph->InsertBefore(call, left, call->env(), FlowGraph::kValue);
+ right =
+ UnboxInstr::Create(kUnboxedDouble, new (Z) Value(right), call->deopt_id(),
+ UnboxInstr::ValueMode::kCheckType);
+ flow_graph->InsertBefore(call, right, call->env(), FlowGraph::kValue);
BinaryDoubleOpInstr* double_bin_op = new (Z)
BinaryDoubleOpInstr(op_kind, new (Z) Value(left), new (Z) Value(right),
call->deopt_id(), call->source());
@@ -2747,7 +2815,7 @@
}
Definition* unbox = AddDefinition(
UnboxInstr::Create(rep, new (zone()) Value(arg), DeoptId::kNone,
- Instruction::kNotSpeculative));
+ UnboxInstr::ValueMode::kHasValidType));
for (intptr_t lane = 0; lane < n; lane++) {
in_[i][lane] = unbox;
}
@@ -2772,8 +2840,7 @@
void UnaryDoubleOp(Token::Kind op, Representation rep, intptr_t n) {
for (intptr_t lane = 0; lane < n; lane++) {
op_[lane] = AddDefinition(new (zone()) UnaryDoubleOpInstr(
- op, new (zone()) Value(in_[0][lane]), call_->deopt_id(),
- Instruction::kNotSpeculative, rep));
+ op, new (zone()) Value(in_[0][lane]), call_->deopt_id(), rep));
}
}
@@ -2782,7 +2849,7 @@
op_[lane] = AddDefinition(new (zone()) BinaryDoubleOpInstr(
op, new (zone()) Value(in_[0][lane]),
new (zone()) Value(in_[1][lane]), call_->deopt_id(), call_->source(),
- Instruction::kNotSpeculative, rep));
+ rep));
}
}
@@ -3034,9 +3101,8 @@
Instruction* cursor,
Definition* x,
Definition* y) {
- BinaryInt64OpInstr* mul = new (Z)
- BinaryInt64OpInstr(Token::kMUL, new (Z) Value(x), new (Z) Value(y),
- DeoptId::kNone, Instruction::kNotSpeculative);
+ BinaryInt64OpInstr* mul = new (Z) BinaryInt64OpInstr(
+ Token::kMUL, new (Z) Value(x), new (Z) Value(y), DeoptId::kNone);
return flow_graph->AppendTo(cursor, mul, nullptr, FlowGraph::kValue);
}
@@ -3438,7 +3504,7 @@
// on [SelectRepresentations] which doesn't mark them as truncating.
value = UnboxInstr::Create(StoreIndexedInstr::ValueRepresentation(cid),
new (Z) Value(value), call->deopt_id(),
- Instruction::kNotSpeculative);
+ UnboxInstr::ValueMode::kHasValidType);
flow_graph->AppendTo(*entry, value, call->env(), FlowGraph::kValue);
*last = new (Z) StoreIndexedInstr(
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
index 3909716..4b987b4 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
@@ -502,8 +502,7 @@
Fragment BaseFlowGraphBuilder::DoubleToFloat() {
Value* value = Pop();
- DoubleToFloatInstr* instr = new DoubleToFloatInstr(
- value, DeoptId::kNone, Instruction::SpeculativeMode::kNotSpeculative);
+ DoubleToFloatInstr* instr = new DoubleToFloatInstr(value, DeoptId::kNone);
Push(instr);
return Fragment(instr);
}
@@ -703,8 +702,7 @@
Value* c_pointer = Pop();
StoreIndexedInstr* instr = new (Z) StoreIndexedInstr(
c_pointer, index, value, kNoStoreBarrier, index_unboxed, index_scale,
- class_id, alignment, DeoptId::kNone, InstructionSource(),
- Instruction::SpeculativeMode::kNotSpeculative);
+ class_id, alignment, DeoptId::kNone, InstructionSource());
return Fragment(instr);
}
@@ -1298,8 +1296,7 @@
Fragment BaseFlowGraphBuilder::UnaryDoubleOp(Token::Kind op) {
Value* value = Pop();
- auto* instr = new (Z) UnaryDoubleOpInstr(op, value, GetNextDeoptId(),
- Instruction::kNotSpeculative);
+ auto* instr = new (Z) UnaryDoubleOpInstr(op, value, GetNextDeoptId());
Push(instr);
return Fragment(instr);
}
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index a761bd7..41515bc 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -2547,8 +2547,8 @@
ASSERT(target.is_unboxed_double_parameter_at(i));
to = kUnboxedDouble;
}
- const auto unbox = UnboxInstr::Create(to, Pop(), DeoptId::kNone,
- Instruction::kNotSpeculative);
+ const auto unbox = UnboxInstr::Create(
+ to, Pop(), DeoptId::kNone, UnboxInstr::ValueMode::kHasValidType);
Push(unbox);
push_param += Fragment(unbox);
}
@@ -4590,7 +4590,7 @@
auto const unbox_to = to == kUnboxedFloat ? kUnboxedDouble : to;
Fragment instructions;
auto* unbox = UnboxInstr::Create(unbox_to, Pop(), DeoptId::kNone,
- Instruction::kNotSpeculative);
+ UnboxInstr::ValueMode::kHasValidType);
instructions <<= unbox;
Push(unbox);
if (to == kUnboxedFloat) {
@@ -4680,9 +4680,9 @@
if (CompilerState::Current().is_aot()) {
Value* right = Pop();
Value* left = Pop();
- RelationalOpInstr* instr = new (Z) RelationalOpInstr(
- InstructionSource(position), kind, left, right, kMintCid,
- GetNextDeoptId(), Instruction::SpeculativeMode::kNotSpeculative);
+ RelationalOpInstr* instr =
+ new (Z) RelationalOpInstr(InstructionSource(position), kind, left,
+ right, kMintCid, GetNextDeoptId());
Push(instr);
return Fragment(instr);
}
diff --git a/runtime/vm/compiler/graph_intrinsifier.cc b/runtime/vm/compiler/graph_intrinsifier.cc
index 9063676..ad70ee0 100644
--- a/runtime/vm/compiler/graph_intrinsifier.cc
+++ b/runtime/vm/compiler/graph_intrinsifier.cc
@@ -209,7 +209,8 @@
ASSERT(!function.has_unboxed_record_return());
if (function.has_unboxed_return() && value->representation() == kTagged) {
return builder->AddUnboxInstr(FlowGraph::ReturnRepresentationOf(function),
- new Value(value), /* is_checked = */ true);
+ new Value(value),
+ UnboxInstr::ValueMode::kHasValidType);
} else {
return value;
}
@@ -248,14 +249,14 @@
// Use same truncating unbox-instruction for int32 and uint32.
auto const unbox_rep = rep == kUnboxedInt32 ? kUnboxedUint32 : rep;
value = builder.AddUnboxInstr(unbox_rep, new Value(value),
- /* is_checked = */ false);
+ UnboxInstr::ValueMode::kCheckType);
} else if (RepresentationUtils::IsUnboxed(rep)) {
Zone* zone = flow_graph->zone();
Cids* value_check = Cids::CreateMonomorphic(zone, Boxing::BoxCid(rep));
builder.AddInstruction(new CheckClassInstr(new Value(value), DeoptId::kNone,
*value_check, builder.Source()));
value = builder.AddUnboxInstr(rep, new Value(value),
- /* is_checked = */ true);
+ UnboxInstr::ValueMode::kHasValidType);
}
if (IsExternalTypedDataClassId(array_cid)) {
@@ -349,11 +350,11 @@
// Check argument. Receiver (left) is known to be a Float32x4.
builder.AddInstruction(new CheckClassInstr(new Value(right), DeoptId::kNone,
*value_check, builder.Source()));
- Definition* left_simd = builder.AddUnboxInstr(rep, new Value(left),
- /* is_checked = */ true);
+ Definition* left_simd = builder.AddUnboxInstr(
+ rep, new Value(left), UnboxInstr::ValueMode::kHasValidType);
- Definition* right_simd = builder.AddUnboxInstr(rep, new Value(right),
- /* is_checked = */ true);
+ Definition* right_simd = builder.AddUnboxInstr(
+ rep, new Value(right), UnboxInstr::ValueMode::kHasValidType);
Definition* unboxed_result = builder.AddDefinition(SimdOpInstr::Create(
SimdOpInstr::KindForOperator(cid, kind), new Value(left_simd),
@@ -411,7 +412,7 @@
Definition* unboxed_receiver =
!function.is_unboxed_parameter_at(0)
? builder.AddUnboxInstr(kUnboxedFloat32x4, new Value(receiver),
- /* is_checked = */ true)
+ UnboxInstr::ValueMode::kHasValidType)
: receiver;
Definition* unboxed_result = builder.AddDefinition(
@@ -680,10 +681,11 @@
return BuildBinarySmiOp(flow_graph, Token::kUSHR);
}
-static Definition* ConvertOrUnboxDoubleParameter(BlockBuilder* builder,
- Definition* value,
- intptr_t index,
- bool is_checked) {
+static Definition* ConvertOrUnboxDoubleParameter(
+ BlockBuilder* builder,
+ Definition* value,
+ intptr_t index,
+ UnboxInstr::ValueMode value_mode) {
const auto& function = builder->function();
if (function.is_unboxed_double_parameter_at(index)) {
return value;
@@ -696,7 +698,7 @@
return builder->AddDefinition(to_double);
} else {
ASSERT(!function.is_unboxed_parameter_at(index));
- return builder->AddUnboxInstr(kUnboxedDouble, value, is_checked);
+ return builder->AddUnboxInstr(kUnboxedDouble, value, value_mode);
}
}
@@ -707,7 +709,7 @@
Definition* receiver = builder.AddParameter(0);
Definition* unboxed_value = ConvertOrUnboxDoubleParameter(
- &builder, receiver, 0, /* is_checked = */ true);
+ &builder, receiver, 0, UnboxInstr::ValueMode::kHasValidType);
if (unboxed_value == nullptr) {
return false;
}