Skip to content

Commit 06f9a9e

Browse files
mkustermanncommit-bot@chromium.org
authored andcommitted
[VM] Introduce function and osr entrypoints to the VM's IR
Similar to how we treat catch entry instructions, this cl adds new function and osr entry instructions. The [FunctionEntry] and [OsrEntry] - just like [CatchBlockEntry] - have now their own initial definitions. The [GraphEntry] has only initial definitions for constants. Explicit phis are inserted for all parameter / special parameter instructions if necessary. Future work is: a) Minimize parallel moves due to the phis on parameters b) Cleanup frame setup: Move it entirely into FunctionEntry/CatchEntry (instead of the split version we have now) Fixes #34435 Fixes #34287 Change-Id: Iefa0280a709716f748d6fb0523b8d0f4d8de1fec Reviewed-on: https://dart-review.googlesource.com/c/74782 Commit-Queue: Martin Kustermann <[email protected]> Reviewed-by: Vyacheslav Egorov <[email protected]>
1 parent 22b1171 commit 06f9a9e

38 files changed

+1061
-539
lines changed

runtime/observatory/tests/service/rewind_test.dart

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
4-
// VMOptions=--no-sync-async
54

65
import 'dart:developer';
76
import 'package:observatory/service_io.dart';
@@ -12,10 +11,10 @@ import 'test_helper.dart';
1211
const alwaysInline = "AlwaysInline";
1312
const noInline = "NeverInline";
1413

15-
int LINE_A = 35;
16-
int LINE_B = 40;
17-
int LINE_C = 43;
18-
int LINE_D = 47;
14+
int LINE_A = 34;
15+
int LINE_B = 39;
16+
int LINE_C = 42;
17+
int LINE_D = 46;
1918

2019
int global = 0;
2120

@@ -60,20 +59,20 @@ var tests = <IsolateTest>[
6059
} on ServerRpcException catch (e) {
6160
caughtException = true;
6261
expect(e.code, equals(ServerRpcException.kCannotResume));
63-
expect(e.message, 'Frame must be in bounds [1..9]: saw 0');
62+
expect(e.message, 'Frame must be in bounds [1..12]: saw 0');
6463
}
6564
expect(caughtException, isTrue);
6665
},
6766
(Isolate isolate) async {
68-
// We are not able to rewind frame 10.
67+
// We are not able to rewind frame 13.
6968
bool caughtException;
7069
try {
71-
await isolate.rewind(10);
70+
await isolate.rewind(13);
7271
expect(false, isTrue, reason: 'Unreachable');
7372
} on ServerRpcException catch (e) {
7473
caughtException = true;
7574
expect(e.code, equals(ServerRpcException.kCannotResume));
76-
expect(e.message, 'Frame must be in bounds [1..9]: saw 10');
75+
expect(e.message, 'Frame must be in bounds [1..12]: saw 13');
7776
}
7877
expect(caughtException, isTrue);
7978
},

runtime/observatory/tests/service/service.status

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ step_through_getter_test: RuntimeError # Debugging StringConcatenation doesn't w
104104
*: SkipByDesign
105105

106106
[ $compiler == dartk || $compiler == dartkp ]
107-
rewind_test: Pass, RuntimeError, Slow # Issue 34287
107+
rewind_test: Pass, Slow
108108

109109
# Skip all service tests because random reloads interfere.
110110
[ $hot_reload || $hot_reload_rollback ]

runtime/tests/vm/vm.status

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ dart/simd128float32_test: Skip # compilers not aware of Simd128
5151
dart/truncating_ints_test: SkipByDesign # The test requires int64.
5252
dart/wrap_around_in_range_analysis_test: SkipByDesign # The test requires int64.
5353

54+
[ $compiler != dartk || ($arch != x64 && $arch != simarm && $arch != arm) || $hot_reload || $hot_reload_rollback ]
55+
dart/entrypoints/*: Skip # Only supported in Dart 2 JIT (hot-reload -> issue 34199).
56+
5457
[ ($compiler == dartk || $compiler == dartkb) ]
5558
cc/DartAPI_New: Fail # Issue #33041
5659
dart/redirection_type_shuffling_test/00: RuntimeError, Pass

runtime/vm/compiler/backend/block_scheduler.cc

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,15 @@ void BlockScheduler::AssignEdgeWeights() const {
7171
Array& edge_counters = Array::Handle();
7272
edge_counters ^= ic_data_array.At(0);
7373

74-
intptr_t entry_count = GetEdgeCount(
75-
edge_counters,
76-
flow_graph()->graph_entry()->normal_entry()->preorder_number());
77-
flow_graph()->graph_entry()->set_entry_count(entry_count);
74+
auto graph_entry = flow_graph()->graph_entry();
75+
BlockEntryInstr* entry = graph_entry->normal_entry();
76+
if (entry == nullptr) {
77+
entry = graph_entry->osr_entry();
78+
ASSERT(entry != nullptr);
79+
}
80+
const intptr_t entry_count =
81+
GetEdgeCount(edge_counters, entry->preorder_number());
82+
graph_entry->set_entry_count(entry_count);
7883

7984
for (BlockIterator it = flow_graph()->reverse_postorder_iterator();
8085
!it.Done(); it.Advance()) {

runtime/vm/compiler/backend/branch_optimizer.cc

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ bool BranchSimplifier::Match(JoinEntryInstr* block) {
6161
}
6262

6363
JoinEntryInstr* BranchSimplifier::ToJoinEntry(Zone* zone,
64-
TargetEntryInstr* target) {
64+
BlockEntryInstr* target) {
6565
// Convert a target block into a join block. Branches will be duplicated
6666
// so the former true and false targets become joins of the control flows
6767
// from all the duplicated branches.
@@ -74,6 +74,17 @@ JoinEntryInstr* BranchSimplifier::ToJoinEntry(Zone* zone,
7474
return join;
7575
}
7676

77+
TargetEntryInstr* BranchSimplifier::ToTargetEntry(Zone* zone,
78+
BlockEntryInstr* target) {
79+
auto replacement = new (zone)
80+
TargetEntryInstr(target->block_id(), target->try_index(), DeoptId::kNone);
81+
replacement->InheritDeoptTarget(zone, target);
82+
replacement->LinkTo(target->next());
83+
replacement->set_last_instruction(target->last_instruction());
84+
target->UnuseAllInputs();
85+
return replacement;
86+
}
87+
7788
BranchInstr* BranchSimplifier::CloneBranch(Zone* zone,
7889
BranchInstr* branch,
7990
Value* new_left,

runtime/vm/compiler/backend/branch_optimizer.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99

1010
namespace dart {
1111

12+
class BlockEntryInstr;
1213
class FlowGraph;
14+
class FunctionEntryInstr;
1315
class JoinEntryInstr;
1416
class Zone;
1517
class TargetEntryInstr;
@@ -23,10 +25,15 @@ class BranchSimplifier : public AllStatic {
2325
public:
2426
static void Simplify(FlowGraph* flow_graph);
2527

26-
// Replace a target entry instruction with a join entry instruction. Does
28+
// Replace a block entry instruction with a join entry instruction. Does
2729
// not update the original target's predecessors to point to the new block
2830
// and does not replace the target in already computed block order lists.
29-
static JoinEntryInstr* ToJoinEntry(Zone* zone, TargetEntryInstr* target);
31+
static JoinEntryInstr* ToJoinEntry(Zone* zone, BlockEntryInstr* target);
32+
33+
// Replace a block entry instruction with a target entry instruction. Does
34+
// not update the original target's predecessors to point to the new block and
35+
// does not replace the target in already computed block order lists.
36+
static TargetEntryInstr* ToTargetEntry(Zone* zone, BlockEntryInstr* target);
3037

3138
private:
3239
// Match an instance of the pattern to rewrite. See the implementation

runtime/vm/compiler/backend/constant_propagator.cc

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,8 @@ void ConstantPropagator::Join(Object* left, const Object& right) {
121121
// Analysis of blocks. Called at most once per block. The block is already
122122
// marked as reachable. All instructions in the block are analyzed.
123123
void ConstantPropagator::VisitGraphEntry(GraphEntryInstr* block) {
124-
const GrowableArray<Definition*>& defs = *block->initial_definitions();
125-
for (intptr_t i = 0; i < defs.length(); ++i) {
126-
defs[i]->Accept(this);
124+
for (auto def : *block->initial_definitions()) {
125+
def->Accept(this);
127126
}
128127
ASSERT(ForwardInstructionIterator(block).Done());
129128

@@ -134,30 +133,47 @@ void ConstantPropagator::VisitGraphEntry(GraphEntryInstr* block) {
134133
}
135134
}
136135

137-
void ConstantPropagator::VisitJoinEntry(JoinEntryInstr* block) {
138-
// Phis are visited when visiting Goto at a predecessor. See VisitGoto.
136+
void ConstantPropagator::VisitFunctionEntry(FunctionEntryInstr* block) {
137+
for (auto def : *block->initial_definitions()) {
138+
def->Accept(this);
139+
}
139140
for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
140141
it.Current()->Accept(this);
141142
}
142143
}
143144

144-
void ConstantPropagator::VisitTargetEntry(TargetEntryInstr* block) {
145+
void ConstantPropagator::VisitOsrEntry(OsrEntryInstr* block) {
146+
for (auto def : *block->initial_definitions()) {
147+
def->Accept(this);
148+
}
145149
for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
146150
it.Current()->Accept(this);
147151
}
148152
}
149153

150-
void ConstantPropagator::VisitIndirectEntry(IndirectEntryInstr* block) {
154+
void ConstantPropagator::VisitCatchBlockEntry(CatchBlockEntryInstr* block) {
155+
for (auto def : *block->initial_definitions()) {
156+
def->Accept(this);
157+
}
151158
for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
152159
it.Current()->Accept(this);
153160
}
154161
}
155162

156-
void ConstantPropagator::VisitCatchBlockEntry(CatchBlockEntryInstr* block) {
157-
const GrowableArray<Definition*>& defs = *block->initial_definitions();
158-
for (intptr_t i = 0; i < defs.length(); ++i) {
159-
defs[i]->Accept(this);
163+
void ConstantPropagator::VisitJoinEntry(JoinEntryInstr* block) {
164+
// Phis are visited when visiting Goto at a predecessor. See VisitGoto.
165+
for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
166+
it.Current()->Accept(this);
160167
}
168+
}
169+
170+
void ConstantPropagator::VisitTargetEntry(TargetEntryInstr* block) {
171+
for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
172+
it.Current()->Accept(this);
173+
}
174+
}
175+
176+
void ConstantPropagator::VisitIndirectEntry(IndirectEntryInstr* block) {
161177
for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
162178
it.Current()->Accept(this);
163179
}

0 commit comments

Comments
 (0)