Skip to content

Commit 43b69d4

Browse files
victoragnezcommit-bot@chromium.org
authored andcommitted
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 <[email protected]> Reviewed-by: Martin Kustermann <[email protected]> Commit-Queue: Victor Agnez Lima <[email protected]>
1 parent 0fe2779 commit 43b69d4

File tree

4 files changed

+77
-37
lines changed

4 files changed

+77
-37
lines changed

runtime/vm/compiler/backend/flow_graph.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1680,8 +1680,9 @@ void FlowGraph::InsertConversion(Representation from,
16801680
const intptr_t deopt_id = (deopt_target != NULL)
16811681
? deopt_target->DeoptimizationTarget()
16821682
: DeoptId::kNone;
1683-
converted = UnboxInstr::Create(to, use->CopyWithType(), deopt_id,
1684-
use->instruction()->speculative_mode());
1683+
converted = UnboxInstr::Create(
1684+
to, use->CopyWithType(), deopt_id,
1685+
use->instruction()->SpeculativeModeOfInput(use->use_index()));
16851686
} else if ((to == kTagged) && Boxing::Supports(from)) {
16861687
converted = BoxInstr::Create(from, use->CopyWithType());
16871688
} else {

runtime/vm/compiler/backend/il.cc

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1971,7 +1971,7 @@ bool IntConverterInstr::ComputeCanDeoptimize() const {
19711971
}
19721972

19731973
bool UnboxInt32Instr::ComputeCanDeoptimize() const {
1974-
if (speculative_mode() == kNotSpeculative) {
1974+
if (SpeculativeModeOfInputs() == kNotSpeculative) {
19751975
return false;
19761976
}
19771977
const intptr_t value_cid = value()->Type()->ToCid();
@@ -1995,7 +1995,7 @@ bool UnboxInt32Instr::ComputeCanDeoptimize() const {
19951995

19961996
bool UnboxUint32Instr::ComputeCanDeoptimize() const {
19971997
ASSERT(is_truncating());
1998-
if (speculative_mode() == kNotSpeculative) {
1998+
if (SpeculativeModeOfInputs() == kNotSpeculative) {
19991999
return false;
20002000
}
20012001
if ((value()->Type()->ToCid() == kSmiCid) ||
@@ -2433,7 +2433,7 @@ Definition* BinaryIntegerOpInstr::Canonicalize(FlowGraph* flow_graph) {
24332433
BinaryIntegerOpInstr* shift = BinaryIntegerOpInstr::Make(
24342434
representation(), Token::kSHL, left()->CopyWithType(),
24352435
new Value(constant_1), GetDeoptId(), can_overflow(),
2436-
is_truncating(), range(), speculative_mode());
2436+
is_truncating(), range(), SpeculativeModeOfInputs());
24372437
if (shift != nullptr) {
24382438
// Assign a range to the shift factor, just in case range
24392439
// analysis no longer runs after this rewriting.
@@ -3024,7 +3024,7 @@ Definition* BoxInt64Instr::Canonicalize(FlowGraph* flow_graph) {
30243024

30253025
// For all x, box(unbox(x)) = x.
30263026
if (auto unbox = value()->definition()->AsUnboxInt64()) {
3027-
if (unbox->speculative_mode() == kNotSpeculative) {
3027+
if (unbox->SpeculativeModeOfInputs() == kNotSpeculative) {
30283028
return unbox->value()->definition();
30293029
}
30303030
} else if (auto unbox = value()->definition()->AsUnboxedConstant()) {
@@ -4900,7 +4900,7 @@ void UnboxInstr::EmitLoadFromBoxWithDeopt(FlowGraphCompiler* compiler) {
49004900
}
49014901

49024902
void UnboxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4903-
if (speculative_mode() == kNotSpeculative) {
4903+
if (SpeculativeModeOfInputs() == kNotSpeculative) {
49044904
switch (representation()) {
49054905
case kUnboxedDouble:
49064906
case kUnboxedFloat:
@@ -4929,7 +4929,7 @@ void UnboxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
49294929
break;
49304930
}
49314931
} else {
4932-
ASSERT(speculative_mode() == kGuardInputs);
4932+
ASSERT(SpeculativeModeOfInputs() == kGuardInputs);
49334933
const intptr_t value_cid = value()->Type()->ToCid();
49344934
const intptr_t box_cid = BoxCid();
49354935

@@ -5055,7 +5055,8 @@ ComparisonInstr* EqualityCompareInstr::CopyWithNewOperands(Value* new_left,
50555055
ComparisonInstr* RelationalOpInstr::CopyWithNewOperands(Value* new_left,
50565056
Value* new_right) {
50575057
return new RelationalOpInstr(token_pos(), kind(), new_left, new_right,
5058-
operation_cid(), deopt_id(), speculative_mode());
5058+
operation_cid(), deopt_id(),
5059+
SpeculativeModeOfInputs());
50595060
}
50605061

50615062
ComparisonInstr* StrictCompareInstr::CopyWithNewOperands(Value* new_left,

runtime/vm/compiler/backend/il.h

Lines changed: 64 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -979,8 +979,19 @@ class Instruction : public ZoneAllocated {
979979
return kTagged;
980980
}
981981

982-
// By default, instructions should check types of inputs when unboxing.
983-
virtual SpeculativeMode speculative_mode() const { return kGuardInputs; }
982+
SpeculativeMode SpeculativeModeOfInputs() const {
983+
for (intptr_t i = 0; i < InputCount(); i++) {
984+
if (SpeculativeModeOfInput(i) == kGuardInputs) {
985+
return kGuardInputs;
986+
}
987+
}
988+
return kNotSpeculative;
989+
}
990+
991+
// By default, instructions should check types of inputs when unboxing
992+
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
993+
return kGuardInputs;
994+
}
984995

985996
// Representation of the value produced by this computation.
986997
virtual Representation representation() const { return kTagged; }
@@ -2378,7 +2389,7 @@ class PhiInstr : public Definition {
23782389
virtual void set_representation(Representation r) { representation_ = r; }
23792390

23802391
// In AOT mode Phi instructions do not check types of inputs when unboxing.
2381-
virtual SpeculativeMode speculative_mode() const {
2392+
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
23822393
return FLAG_precompiled_mode ? kNotSpeculative : kGuardInputs;
23832394
}
23842395

@@ -4203,12 +4214,13 @@ class EqualityCompareInstr : public TemplateComparison<2, NoThrow, Pure> {
42034214
return kTagged;
42044215
}
42054216

4206-
virtual SpeculativeMode speculative_mode() const { return speculative_mode_; }
4217+
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
4218+
return speculative_mode_;
4219+
}
42074220

42084221
virtual bool AttributesEqual(Instruction* other) const {
42094222
return ComparisonInstr::AttributesEqual(other) &&
4210-
(speculative_mode() ==
4211-
other->AsEqualityCompare()->speculative_mode());
4223+
(speculative_mode_ == other->AsEqualityCompare()->speculative_mode_);
42124224
}
42134225

42144226
PRINT_OPERANDS_TO_SUPPORT
@@ -4250,11 +4262,13 @@ class RelationalOpInstr : public TemplateComparison<2, NoThrow, Pure> {
42504262
return kTagged;
42514263
}
42524264

4253-
virtual SpeculativeMode speculative_mode() const { return speculative_mode_; }
4265+
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
4266+
return speculative_mode_;
4267+
}
42544268

42554269
virtual bool AttributesEqual(Instruction* other) const {
42564270
return ComparisonInstr::AttributesEqual(other) &&
4257-
(speculative_mode() == other->AsRelationalOp()->speculative_mode());
4271+
(speculative_mode_ == other->AsRelationalOp()->speculative_mode_);
42584272
}
42594273

42604274
PRINT_OPERANDS_TO_SUPPORT
@@ -4881,7 +4895,7 @@ class StoreInstanceFieldInstr : public TemplateInstruction<2, NoThrow> {
48814895
token_pos,
48824896
kind) {}
48834897

4884-
virtual SpeculativeMode speculative_mode() const {
4898+
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
48854899
// In AOT unbox is done based on TFA, therefore it was proven to be correct
48864900
// and it can never deoptmize.
48874901
return (IsUnboxedStore() && FLAG_precompiled_mode) ? kNotSpeculative
@@ -5362,7 +5376,9 @@ class StoreIndexedInstr : public TemplateInstruction<3, NoThrow> {
53625376
(emit_store_barrier_ == kEmitStoreBarrier);
53635377
}
53645378

5365-
virtual SpeculativeMode speculative_mode() const { return speculative_mode_; }
5379+
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
5380+
return speculative_mode_;
5381+
}
53665382

53675383
virtual bool ComputeCanDeoptimize() const { return false; }
53685384

@@ -6306,7 +6322,9 @@ class BoxIntegerInstr : public BoxInstr {
63066322

63076323
virtual void InferRange(RangeAnalysis* analysis, Range* range);
63086324

6309-
virtual SpeculativeMode speculative_mode() const { return kNotSpeculative; }
6325+
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
6326+
return kNotSpeculative;
6327+
}
63106328

63116329
virtual CompileType ComputeType() const;
63126330
virtual bool RecomputeType();
@@ -6375,7 +6393,7 @@ class UnboxInstr : public TemplateDefinition<1, NoThrow, Pure> {
63756393
Value* value() const { return inputs_[0]; }
63766394

63776395
virtual bool ComputeCanDeoptimize() const {
6378-
if (speculative_mode() == kNotSpeculative) {
6396+
if (SpeculativeModeOfInputs() == kNotSpeculative) {
63796397
return false;
63806398
}
63816399

@@ -6393,7 +6411,9 @@ class UnboxInstr : public TemplateDefinition<1, NoThrow, Pure> {
63936411
return true;
63946412
}
63956413

6396-
virtual SpeculativeMode speculative_mode() const { return speculative_mode_; }
6414+
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
6415+
return speculative_mode_;
6416+
}
63976417

63986418
virtual Representation representation() const { return representation_; }
63996419

@@ -6403,7 +6423,7 @@ class UnboxInstr : public TemplateDefinition<1, NoThrow, Pure> {
64036423
virtual bool AttributesEqual(Instruction* other) const {
64046424
UnboxInstr* other_unbox = other->AsUnbox();
64056425
return (representation() == other_unbox->representation()) &&
6406-
(speculative_mode() == other_unbox->speculative_mode());
6426+
(speculative_mode_ == other_unbox->speculative_mode_);
64076427
}
64086428

64096429
Definition* Canonicalize(FlowGraph* flow_graph);
@@ -6763,7 +6783,9 @@ class BinaryDoubleOpInstr : public TemplateDefinition<2, NoThrow, Pure> {
67636783
return kUnboxedDouble;
67646784
}
67656785

6766-
virtual SpeculativeMode speculative_mode() const { return speculative_mode_; }
6786+
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
6787+
return speculative_mode_;
6788+
}
67676789

67686790
virtual intptr_t DeoptimizationTarget() const {
67696791
// Direct access since this instruction cannot deoptimize, and the deopt-id
@@ -6781,7 +6803,7 @@ class BinaryDoubleOpInstr : public TemplateDefinition<2, NoThrow, Pure> {
67816803
virtual bool AttributesEqual(Instruction* other) const {
67826804
const BinaryDoubleOpInstr* other_bin_op = other->AsBinaryDoubleOp();
67836805
return (op_kind() == other_bin_op->op_kind()) &&
6784-
(speculative_mode() == other_bin_op->speculative_mode());
6806+
(speculative_mode_ == other_bin_op->speculative_mode_);
67856807
}
67866808

67876809
private:
@@ -6939,11 +6961,14 @@ class UnaryInt64OpInstr : public UnaryIntegerOpInstr {
69396961
}
69406962

69416963
virtual bool AttributesEqual(Instruction* other) const {
6964+
UnaryInt64OpInstr* unary_op_other = other->AsUnaryInt64Op();
69426965
return UnaryIntegerOpInstr::AttributesEqual(other) &&
6943-
(speculative_mode() == other->speculative_mode());
6966+
(speculative_mode_ == unary_op_other->speculative_mode_);
69446967
}
69456968

6946-
virtual SpeculativeMode speculative_mode() const { return speculative_mode_; }
6969+
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
6970+
return speculative_mode_;
6971+
}
69476972

69486973
DECLARE_INSTRUCTION(UnaryInt64Op)
69496974

@@ -7259,11 +7284,13 @@ class BinaryInt64OpInstr : public BinaryIntegerOpInstr {
72597284
return kUnboxedInt64;
72607285
}
72617286

7262-
virtual SpeculativeMode speculative_mode() const { return speculative_mode_; }
7287+
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
7288+
return speculative_mode_;
7289+
}
72637290

72647291
virtual bool AttributesEqual(Instruction* other) const {
72657292
return BinaryIntegerOpInstr::AttributesEqual(other) &&
7266-
(speculative_mode() == other->AsBinaryInt64Op()->speculative_mode());
7293+
(speculative_mode_ == other->AsBinaryInt64Op()->speculative_mode_);
72677294
}
72687295

72697296
virtual void InferRange(RangeAnalysis* analysis, Range* range);
@@ -7321,7 +7348,9 @@ class ShiftInt64OpInstr : public ShiftIntegerOpInstr {
73217348
intptr_t deopt_id)
73227349
: ShiftIntegerOpInstr(op_kind, left, right, deopt_id) {}
73237350

7324-
virtual SpeculativeMode speculative_mode() const { return kNotSpeculative; }
7351+
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
7352+
return kNotSpeculative;
7353+
}
73257354
virtual bool ComputeCanDeoptimize() const { return false; }
73267355
virtual bool MayThrow() const { return true; }
73277356

@@ -7380,7 +7409,9 @@ class ShiftUint32OpInstr : public ShiftIntegerOpInstr {
73807409
intptr_t deopt_id)
73817410
: ShiftIntegerOpInstr(op_kind, left, right, deopt_id) {}
73827411

7383-
virtual SpeculativeMode speculative_mode() const { return kNotSpeculative; }
7412+
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
7413+
return kNotSpeculative;
7414+
}
73847415
virtual bool ComputeCanDeoptimize() const { return false; }
73857416
virtual bool MayThrow() const { return true; }
73867417

@@ -7465,10 +7496,12 @@ class UnaryDoubleOpInstr : public TemplateDefinition<1, NoThrow, Pure> {
74657496
return kUnboxedDouble;
74667497
}
74677498

7468-
virtual SpeculativeMode speculative_mode() const { return speculative_mode_; }
7499+
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
7500+
return speculative_mode_;
7501+
}
74697502

74707503
virtual bool AttributesEqual(Instruction* other) const {
7471-
return speculative_mode() == other->AsUnaryDoubleOp()->speculative_mode();
7504+
return speculative_mode_ == other->AsUnaryDoubleOp()->speculative_mode_;
74727505
}
74737506

74747507
PRINT_OPERANDS_TO_SUPPORT
@@ -7614,10 +7647,12 @@ class Int64ToDoubleInstr : public TemplateDefinition<1, NoThrow, Pure> {
76147647

76157648
virtual bool ComputeCanDeoptimize() const { return false; }
76167649

7617-
virtual SpeculativeMode speculative_mode() const { return speculative_mode_; }
7650+
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
7651+
return speculative_mode_;
7652+
}
76187653

76197654
virtual bool AttributesEqual(Instruction* other) const {
7620-
return speculative_mode() == other->AsInt64ToDouble()->speculative_mode();
7655+
return speculative_mode_ == other->AsInt64ToDouble()->speculative_mode_;
76217656
}
76227657

76237658
private:
@@ -7746,7 +7781,9 @@ class DoubleToFloatInstr : public TemplateDefinition<1, NoThrow, Pure> {
77467781
return kUnboxedDouble;
77477782
}
77487783

7749-
virtual SpeculativeMode speculative_mode() const { return speculative_mode_; }
7784+
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
7785+
return speculative_mode_;
7786+
}
77507787

77517788
virtual intptr_t DeoptimizationTarget() const { return GetDeoptId(); }
77527789

runtime/vm/compiler/backend/range_analysis.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1655,7 +1655,8 @@ Definition* IntegerInstructionSelector::ConstructReplacementFor(
16551655
UnboxInstr* unbox = def->AsUnboxInt64();
16561656
Value* value = unbox->value()->CopyWithType();
16571657
intptr_t deopt_id = unbox->DeoptimizationTarget();
1658-
return new (Z) UnboxUint32Instr(value, deopt_id, def->speculative_mode());
1658+
return new (Z)
1659+
UnboxUint32Instr(value, deopt_id, def->SpeculativeModeOfInputs());
16591660
} else if (def->IsUnaryInt64Op()) {
16601661
UnaryInt64OpInstr* op = def->AsUnaryInt64Op();
16611662
Token::Kind op_kind = op->op_kind();

0 commit comments

Comments
 (0)