Skip to content

Commit c4a7f1c

Browse files
bkonyicommit-bot@chromium.org
authored andcommitted
Revert "[vm/compiler] Mark more stores as initializing."
This reverts commit eb87e79. Reason for revert: Multiple configurations are red IRTest_InitializingStores: https://ci.chromium.org/p/dart/builders/ci.sandbox/vm-dartkb-linux-debug-simarm64/1684 https://ci.chromium.org/p/dart/builders/ci.sandbox/vm-dartkb-linux-product-simarm64/1796 http_server_test: https://ci.chromium.org/p/dart/builders/ci.sandbox/vm-kernel-precomp-linux-release-simarm/6796 Original change's description: > [vm/compiler] Mark more stores as initializing. > > We inline allocation of contexts and closures manually so stores > which are effectively initializing were not marked as such. > > Additionally permit elimination of initializing stores into context > objects in AOT mode because all contexts are null-initialized there. > > Bug: #38454 > Change-Id: I27886d85160b8600e6e0d38d7bf389d20006fa44 > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/121849 > Commit-Queue: Vyacheslav Egorov <[email protected]> > Reviewed-by: Martin Kustermann <[email protected]> [email protected],[email protected] Change-Id: I4c2df7b675fa3cdab22a8708440dc45ff3ec3476 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: #38454 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/121885 Reviewed-by: Ben Konyi <[email protected]> Commit-Queue: Ben Konyi <[email protected]>
1 parent 01bd0ab commit c4a7f1c

9 files changed

+60
-201
lines changed

runtime/vm/compiler/backend/il.cc

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -903,16 +903,6 @@ Representation LoadFieldInstr::representation() const {
903903
return kTagged;
904904
}
905905

906-
AllocateUninitializedContextInstr::AllocateUninitializedContextInstr(
907-
TokenPosition token_pos,
908-
intptr_t num_context_variables)
909-
: token_pos_(token_pos),
910-
num_context_variables_(num_context_variables),
911-
identity_(AliasIdentity::Unknown()) {
912-
// This instruction is not used in AOT for code size reasons.
913-
ASSERT(!FLAG_precompiled_mode);
914-
}
915-
916906
bool StoreInstanceFieldInstr::IsUnboxedStore() const {
917907
return FLAG_unbox_numeric_fields && slot().IsDartField() &&
918908
FlowGraphCompiler::IsUnboxedField(slot().field());
@@ -945,12 +935,11 @@ Representation StoreInstanceFieldInstr::RequiredInputRepresentation(
945935
Instruction* StoreInstanceFieldInstr::Canonicalize(FlowGraph* flow_graph) {
946936
// Dart objects are allocated null-initialized, which means we can eliminate
947937
// all initializing stores which store null value.
948-
// Context objects can be allocated uninitialized as a performance
949-
// optimization in JIT mode - however in AOT mode we always allocate them
950-
// null initialized.
951-
if (is_initialization_ &&
952-
(!slot().IsContextSlot() ||
953-
!instance()->definition()->IsAllocateUninitializedContext()) &&
938+
// TODO(dartbug.com/38454) Context objects can be allocated uninitialized
939+
// as a performance optimization (all initializing stores are inlined into
940+
// the caller, which allocates the context). Investigate if this can be
941+
// changed to align with normal Dart objects for code size reasons.
942+
if (is_initialization_ && slot().IsDartField() &&
954943
value()->BindsToConstantNull()) {
955944
return nullptr;
956945
}

runtime/vm/compiler/backend/il.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5332,7 +5332,10 @@ class AllocateUninitializedContextInstr
53325332
: public TemplateAllocation<0, NoThrow> {
53335333
public:
53345334
AllocateUninitializedContextInstr(TokenPosition token_pos,
5335-
intptr_t num_context_variables);
5335+
intptr_t num_context_variables)
5336+
: token_pos_(token_pos),
5337+
num_context_variables_(num_context_variables),
5338+
identity_(AliasIdentity::Unknown()) {}
53365339

53375340
DECLARE_INSTRUCTION(AllocateUninitializedContext)
53385341
virtual CompileType ComputeType() const;

runtime/vm/compiler/backend/il_test.cc

Lines changed: 0 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
#include "vm/compiler/backend/il.h"
6-
7-
#include <vector>
8-
96
#include "vm/compiler/backend/il_test_helper.h"
107
#include "vm/unit_test.h"
118

@@ -88,94 +85,4 @@ ISOLATE_UNIT_TEST_CASE(IRTest_EliminateWriteBarrier) {
8885
EXPECT(!store_indexed->value()->NeedsWriteBarrier());
8986
}
9087

91-
static void ExpectStores(FlowGraph* flow_graph,
92-
const std::vector<const char*>& expected_stores) {
93-
size_t next_expected_store = 0;
94-
for (BlockIterator block_it = flow_graph->reverse_postorder_iterator();
95-
!block_it.Done(); block_it.Advance()) {
96-
for (ForwardInstructionIterator it(block_it.Current()); !it.Done();
97-
it.Advance()) {
98-
if (auto store = it.Current()->AsStoreInstanceField()) {
99-
EXPECT_LT(next_expected_store, expected_stores.size());
100-
EXPECT_STREQ(expected_stores[next_expected_store],
101-
store->slot().Name());
102-
next_expected_store++;
103-
}
104-
}
105-
}
106-
}
107-
108-
static void RunInitializingStoresTest(
109-
const Library& root_library,
110-
const char* function_name,
111-
CompilerPass::PipelineMode mode,
112-
const std::vector<const char*>& expected_stores) {
113-
const auto& function =
114-
Function::Handle(GetFunction(root_library, function_name));
115-
TestPipeline pipeline(function, mode);
116-
FlowGraph* flow_graph = pipeline.RunPasses({
117-
CompilerPass::kComputeSSA,
118-
CompilerPass::kTypePropagation,
119-
CompilerPass::kApplyICData,
120-
CompilerPass::kInlining,
121-
CompilerPass::kTypePropagation,
122-
CompilerPass::kSelectRepresentations,
123-
CompilerPass::kCanonicalize,
124-
CompilerPass::kConstantPropagation,
125-
});
126-
ASSERT(flow_graph != nullptr);
127-
ExpectStores(flow_graph, expected_stores);
128-
}
129-
130-
ISOLATE_UNIT_TEST_CASE(IRTest_InitializingStores) {
131-
const char* kScript = R"(
132-
class Bar {
133-
var f;
134-
var g;
135-
136-
Bar({this.f, this.g});
137-
}
138-
Bar f1() => Bar(f: 10);
139-
Bar f2() => Bar(g: 10);
140-
f3() {
141-
return () { };
142-
}
143-
f4<T>({T value}) {
144-
return () { return value; };
145-
}
146-
main() {
147-
f1();
148-
f2();
149-
f3();
150-
f4();
151-
}
152-
)";
153-
const auto& root_library = Library::Handle(LoadTestScript(kScript));
154-
Invoke(root_library, "main");
155-
156-
RunInitializingStoresTest(root_library, "f1", CompilerPass::kJIT,
157-
/*expected_stores=*/{"f"});
158-
RunInitializingStoresTest(root_library, "f2", CompilerPass::kJIT,
159-
/*expected_stores=*/{"g"});
160-
RunInitializingStoresTest(
161-
root_library, "f3", CompilerPass::kJIT,
162-
/*expected_stores=*/
163-
{"Closure.delayed_type_arguments", "Closure.function"});
164-
165-
// Note that in JIT mode we lower context allocation in a way that hinders
166-
// removal of initializing moves so there would be some redundant stores of
167-
// null left in the graph. In AOT mode we don't apply this optimization
168-
// which enables us to remove more stores.
169-
RunInitializingStoresTest(
170-
root_library, "f4", CompilerPass::kJIT, /*expected_stores=*/
171-
{"value", "Context.parent", "Context.parent", "value",
172-
"Closure.function_type_arguments", "Closure.delayed_type_arguments",
173-
"Closure.function", "Closure.context"});
174-
RunInitializingStoresTest(root_library, "f4",
175-
CompilerPass::kAOT, /*expected_stores=*/
176-
{"value", "Closure.function_type_arguments",
177-
"Closure.delayed_type_arguments",
178-
"Closure.function", "Closure.context"});
179-
}
180-
18188
} // namespace dart

runtime/vm/compiler/backend/slot.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,6 @@ class Slot : public ZoneAllocated {
181181

182182
bool IsIdentical(const Slot& other) const { return this == &other; }
183183

184-
bool IsContextSlot() const {
185-
return kind() == Kind::kCapturedVariable || kind() == Kind::kContext_parent;
186-
}
187-
188184
private:
189185
friend class FlowGraphDeserializer; // For GetNativeSlot.
190186

runtime/vm/compiler/frontend/base_flow_graph_builder.cc

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -478,22 +478,19 @@ const Field& BaseFlowGraphBuilder::MayCloneField(const Field& field) {
478478
Fragment BaseFlowGraphBuilder::StoreInstanceField(
479479
TokenPosition position,
480480
const Slot& field,
481-
StoreInstanceFieldInstr::Kind
482-
kind /* = StoreInstanceFieldInstr::Kind::kOther */,
483-
StoreBarrierType emit_store_barrier /* = kEmitStoreBarrier */) {
481+
StoreBarrierType emit_store_barrier) {
484482
Value* value = Pop();
485483
if (value->BindsToConstant()) {
486484
emit_store_barrier = kNoStoreBarrier;
487485
}
488486
StoreInstanceFieldInstr* store = new (Z) StoreInstanceFieldInstr(
489-
field, Pop(), value, emit_store_barrier, position, kind);
487+
field, Pop(), value, emit_store_barrier, position);
490488
return Fragment(store);
491489
}
492490

493491
Fragment BaseFlowGraphBuilder::StoreInstanceField(
494492
const Field& field,
495-
StoreInstanceFieldInstr::Kind
496-
kind /* = StoreInstanceFieldInstr::Kind::kOther */,
493+
bool is_initialization_store,
497494
StoreBarrierType emit_store_barrier) {
498495
Value* value = Pop();
499496
if (value->BindsToConstant()) {
@@ -502,15 +499,16 @@ Fragment BaseFlowGraphBuilder::StoreInstanceField(
502499

503500
StoreInstanceFieldInstr* store = new (Z) StoreInstanceFieldInstr(
504501
MayCloneField(field), Pop(), value, emit_store_barrier,
505-
TokenPosition::kNoSource, parsed_function_, kind);
502+
TokenPosition::kNoSource, parsed_function_,
503+
is_initialization_store ? StoreInstanceFieldInstr::Kind::kInitializing
504+
: StoreInstanceFieldInstr::Kind::kOther);
506505

507506
return Fragment(store);
508507
}
509508

510509
Fragment BaseFlowGraphBuilder::StoreInstanceFieldGuarded(
511510
const Field& field,
512-
StoreInstanceFieldInstr::Kind
513-
kind /* = StoreInstanceFieldInstr::Kind::kOther */) {
511+
bool is_initialization_store) {
514512
Fragment instructions;
515513
const Field& field_clone = MayCloneField(field);
516514
if (I->use_field_guards()) {
@@ -539,7 +537,7 @@ Fragment BaseFlowGraphBuilder::StoreInstanceFieldGuarded(
539537
new (Z) GuardFieldTypeInstr(Pop(), field_clone, GetNextDeoptId());
540538
}
541539
}
542-
instructions += StoreInstanceField(field_clone, kind);
540+
instructions += StoreInstanceField(field_clone, is_initialization_store);
543541
return instructions;
544542
}
545543

@@ -935,13 +933,12 @@ Fragment BaseFlowGraphBuilder::BuildFfiAsFunctionInternalCall(
935933

936934
code += LoadLocal(closure);
937935
code += LoadLocal(context);
938-
code += StoreInstanceField(TokenPosition::kNoSource, Slot::Closure_context(),
939-
StoreInstanceFieldInstr::Kind::kInitializing);
936+
code += StoreInstanceField(TokenPosition::kNoSource, Slot::Closure_context());
940937

941938
code += LoadLocal(closure);
942939
code += Constant(target);
943-
code += StoreInstanceField(TokenPosition::kNoSource, Slot::Closure_function(),
944-
StoreInstanceFieldInstr::Kind::kInitializing);
940+
code +=
941+
StoreInstanceField(TokenPosition::kNoSource, Slot::Closure_function());
945942

946943
// Drop address and context.
947944
code += DropTempsPreserveTop(2);

runtime/vm/compiler/frontend/base_flow_graph_builder.h

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -186,17 +186,13 @@ class BaseFlowGraphBuilder {
186186
Fragment StoreInstanceField(
187187
TokenPosition position,
188188
const Slot& field,
189-
StoreInstanceFieldInstr::Kind kind =
190-
StoreInstanceFieldInstr::Kind::kOther,
191189
StoreBarrierType emit_store_barrier = kEmitStoreBarrier);
192190
Fragment StoreInstanceField(
193191
const Field& field,
194-
StoreInstanceFieldInstr::Kind kind =
195-
StoreInstanceFieldInstr::Kind::kOther,
192+
bool is_initialization_store,
196193
StoreBarrierType emit_store_barrier = kEmitStoreBarrier);
197194
Fragment StoreInstanceFieldGuarded(const Field& field,
198-
StoreInstanceFieldInstr::Kind kind =
199-
StoreInstanceFieldInstr::Kind::kOther);
195+
bool is_initialization_store);
200196
Fragment LoadStaticField();
201197
Fragment RedefinitionWithType(const AbstractType& type);
202198
Fragment StoreStaticField(TokenPosition position, const Field& field);

runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,15 +1218,13 @@ void BytecodeFlowGraphBuilder::BuildStoreFieldTOS() {
12181218

12191219
if (field.Owner() == isolate()->object_store()->closure_class()) {
12201220
// Stores to _Closure fields are lower-level.
1221-
code_ +=
1222-
B->StoreInstanceField(position_, ClosureSlotByField(field),
1223-
StoreInstanceFieldInstr::Kind::kInitializing);
1221+
code_ += B->StoreInstanceField(position_, ClosureSlotByField(field));
12241222
} else {
12251223
// The rest of the StoreFieldTOS are for field initializers.
12261224
// TODO(alexmarkov): Consider adding a flag to StoreFieldTOS or even
12271225
// adding a separate bytecode instruction.
1228-
code_ += B->StoreInstanceFieldGuarded(
1229-
field, StoreInstanceFieldInstr::Kind::kInitializing);
1226+
code_ += B->StoreInstanceFieldGuarded(field,
1227+
/* is_initialization_store = */ true);
12301228
}
12311229
}
12321230

@@ -1253,8 +1251,7 @@ void BytecodeFlowGraphBuilder::BuildLoadFieldTOS() {
12531251
void BytecodeFlowGraphBuilder::BuildStoreContextParent() {
12541252
LoadStackSlots(2);
12551253

1256-
code_ += B->StoreInstanceField(position_, Slot::Context_parent(),
1257-
StoreInstanceFieldInstr::Kind::kInitializing);
1254+
code_ += B->StoreInstanceField(position_, Slot::Context_parent());
12581255
}
12591256

12601257
void BytecodeFlowGraphBuilder::BuildLoadContextParent() {

runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,7 @@ Fragment StreamingFlowGraphBuilder::BuildFieldInitializer(
187187
if (only_for_side_effects) {
188188
instructions += Drop();
189189
} else {
190-
instructions += flow_graph_builder_->StoreInstanceFieldGuarded(
191-
field, StoreInstanceFieldInstr::Kind::kInitializing);
190+
instructions += flow_graph_builder_->StoreInstanceFieldGuarded(field, true);
192191
}
193192
return instructions;
194193
}
@@ -675,8 +674,7 @@ Fragment StreamingFlowGraphBuilder::SetupCapturedParameters(
675674
body += LoadLocal(&raw_parameter);
676675
body += flow_graph_builder_->StoreInstanceField(
677676
TokenPosition::kNoSource,
678-
Slot::GetContextVariableSlotFor(thread(), *variable),
679-
StoreInstanceFieldInstr::Kind::kInitializing);
677+
Slot::GetContextVariableSlotFor(thread(), *variable));
680678
body += NullConstant();
681679
body += StoreLocal(TokenPosition::kNoSource, &raw_parameter);
682680
body += Drop();
@@ -3937,8 +3935,7 @@ Fragment StreamingFlowGraphBuilder::BuildPartialTearoffInstantiation(
39373935
instructions += LoadLocal(new_closure);
39383936
instructions += LoadLocal(type_args_vec);
39393937
instructions += flow_graph_builder_->StoreInstanceField(
3940-
TokenPosition::kNoSource, Slot::Closure_delayed_type_arguments(),
3941-
StoreInstanceFieldInstr::Kind::kInitializing);
3938+
TokenPosition::kNoSource, Slot::Closure_delayed_type_arguments());
39423939
instructions += Drop(); // Drop type args.
39433940

39443941
// Copy over the target function.
@@ -3947,34 +3944,30 @@ Fragment StreamingFlowGraphBuilder::BuildPartialTearoffInstantiation(
39473944
instructions +=
39483945
flow_graph_builder_->LoadNativeField(Slot::Closure_function());
39493946
instructions += flow_graph_builder_->StoreInstanceField(
3950-
TokenPosition::kNoSource, Slot::Closure_function(),
3951-
StoreInstanceFieldInstr::Kind::kInitializing);
3947+
TokenPosition::kNoSource, Slot::Closure_function());
39523948

39533949
// Copy over the instantiator type arguments.
39543950
instructions += LoadLocal(new_closure);
39553951
instructions += LoadLocal(original_closure);
39563952
instructions += flow_graph_builder_->LoadNativeField(
39573953
Slot::Closure_instantiator_type_arguments());
39583954
instructions += flow_graph_builder_->StoreInstanceField(
3959-
TokenPosition::kNoSource, Slot::Closure_instantiator_type_arguments(),
3960-
StoreInstanceFieldInstr::Kind::kInitializing);
3955+
TokenPosition::kNoSource, Slot::Closure_instantiator_type_arguments());
39613956

39623957
// Copy over the function type arguments.
39633958
instructions += LoadLocal(new_closure);
39643959
instructions += LoadLocal(original_closure);
39653960
instructions += flow_graph_builder_->LoadNativeField(
39663961
Slot::Closure_function_type_arguments());
39673962
instructions += flow_graph_builder_->StoreInstanceField(
3968-
TokenPosition::kNoSource, Slot::Closure_function_type_arguments(),
3969-
StoreInstanceFieldInstr::Kind::kInitializing);
3963+
TokenPosition::kNoSource, Slot::Closure_function_type_arguments());
39703964

39713965
// Copy over the context.
39723966
instructions += LoadLocal(new_closure);
39733967
instructions += LoadLocal(original_closure);
39743968
instructions += flow_graph_builder_->LoadNativeField(Slot::Closure_context());
39753969
instructions += flow_graph_builder_->StoreInstanceField(
3976-
TokenPosition::kNoSource, Slot::Closure_context(),
3977-
StoreInstanceFieldInstr::Kind::kInitializing);
3970+
TokenPosition::kNoSource, Slot::Closure_context());
39783971

39793972
instructions += DropTempsPreserveTop(1); // Drop old closure.
39803973

@@ -5096,36 +5089,31 @@ Fragment StreamingFlowGraphBuilder::BuildFunctionNode(
50965089
instructions += LoadLocal(closure);
50975090
instructions += LoadInstantiatorTypeArguments();
50985091
instructions += flow_graph_builder_->StoreInstanceField(
5099-
TokenPosition::kNoSource, Slot::Closure_instantiator_type_arguments(),
5100-
StoreInstanceFieldInstr::Kind::kInitializing);
5092+
TokenPosition::kNoSource, Slot::Closure_instantiator_type_arguments());
51015093
}
51025094

51035095
// TODO(30455): We only need to save these if the closure uses any captured
51045096
// type parameters.
51055097
instructions += LoadLocal(closure);
51065098
instructions += LoadFunctionTypeArguments();
51075099
instructions += flow_graph_builder_->StoreInstanceField(
5108-
TokenPosition::kNoSource, Slot::Closure_function_type_arguments(),
5109-
StoreInstanceFieldInstr::Kind::kInitializing);
5100+
TokenPosition::kNoSource, Slot::Closure_function_type_arguments());
51105101

51115102
instructions += LoadLocal(closure);
51125103
instructions += Constant(Object::empty_type_arguments());
51135104
instructions += flow_graph_builder_->StoreInstanceField(
5114-
TokenPosition::kNoSource, Slot::Closure_delayed_type_arguments(),
5115-
StoreInstanceFieldInstr::Kind::kInitializing);
5105+
TokenPosition::kNoSource, Slot::Closure_delayed_type_arguments());
51165106

51175107
// Store the function and the context in the closure.
51185108
instructions += LoadLocal(closure);
51195109
instructions += Constant(function);
51205110
instructions += flow_graph_builder_->StoreInstanceField(
5121-
TokenPosition::kNoSource, Slot::Closure_function(),
5122-
StoreInstanceFieldInstr::Kind::kInitializing);
5111+
TokenPosition::kNoSource, Slot::Closure_function());
51235112

51245113
instructions += LoadLocal(closure);
51255114
instructions += LoadLocal(parsed_function()->current_context_var());
51265115
instructions += flow_graph_builder_->StoreInstanceField(
5127-
TokenPosition::kNoSource, Slot::Closure_context(),
5128-
StoreInstanceFieldInstr::Kind::kInitializing);
5116+
TokenPosition::kNoSource, Slot::Closure_context());
51295117

51305118
return instructions;
51315119
}

0 commit comments

Comments
 (0)