Skip to content

Commit 4c3ab23

Browse files
alexmarkovCommit Queue
authored andcommitted
[vm,compiler] Avoid passing anything except flow graph to code generation
This is a preparation to detach code generation from flow graph building and optimization passes. Extra inlining info (inline_id_to_function, inline_id_to_token_pos and caller_inline_id) is now added to FlowGraph and can be serialized and deserialized. ic_data_array is not needed for optimized compilation and is no longer passed. A separate CompilerPassState is created for code generation. TEST=ci (refactoring) Change-Id: Ib61af47c2ddde1353b9a0fe24995d29d6e85acad Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/399883 Commit-Queue: Alexander Markov <[email protected]> Reviewed-by: Slava Egorov <[email protected]>
1 parent d3b7edb commit 4c3ab23

File tree

13 files changed

+100
-98
lines changed

13 files changed

+100
-98
lines changed

runtime/vm/compiler/aot/precompiler.cc

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -344,9 +344,7 @@ class PrecompileParsedFunctionHelper : public ValueObject {
344344
ParsedFunction* parsed_function() const { return parsed_function_; }
345345
Thread* thread() const { return thread_; }
346346

347-
bool GenerateCode(FlowGraph* flow_graph,
348-
CompilerPassState* pass_state,
349-
ZoneGrowableArray<const ICData*>* ic_data_array);
347+
bool GenerateCode(FlowGraph* flow_graph);
350348

351349
void FinalizeCompilation(compiler::Assembler* assembler,
352350
FlowGraphCompiler* graph_compiler,
@@ -3465,10 +3463,7 @@ static void GenerateNecessaryAllocationStubs(FlowGraph* flow_graph) {
34653463
}
34663464
}
34673465

3468-
bool PrecompileParsedFunctionHelper::GenerateCode(
3469-
FlowGraph* flow_graph,
3470-
CompilerPassState* pass_state,
3471-
ZoneGrowableArray<const ICData*>* ic_data_array) {
3466+
bool PrecompileParsedFunctionHelper::GenerateCode(FlowGraph* flow_graph) {
34723467
// We may reattempt compilation if the function needs to be assembled using
34733468
// far branches on ARM. In the else branch of the setjmp call, done is set to
34743469
// false, and use_far_branches is set to true if there is a longjmp from the
@@ -3508,10 +3503,11 @@ bool PrecompileParsedFunctionHelper::GenerateCode(
35083503

35093504
FlowGraphCompiler graph_compiler(
35103505
&assembler, flow_graph, *parsed_function(), /*is_optimizing=*/true,
3511-
pass_state->inline_id_to_function, pass_state->inline_id_to_token_pos,
3512-
pass_state->caller_inline_id, ic_data_array, function_stats);
3513-
pass_state->graph_compiler = &graph_compiler;
3514-
CompilerPass::GenerateCode(pass_state);
3506+
/*deopt_id_to_ic_data=*/nullptr, function_stats);
3507+
3508+
CompilerPassState pass_state(thread(), flow_graph, precompiler_);
3509+
pass_state.graph_compiler = &graph_compiler;
3510+
CompilerPass::GenerateCode(&pass_state);
35153511
{
35163512
COMPILER_TIMINGS_TIMER_SCOPE(thread(), FinalizeCode);
35173513
TIMELINE_DURATION(thread(), CompilerVerbose, "FinalizeCompilation");
@@ -3595,7 +3591,6 @@ bool PrecompileParsedFunctionHelper::Compile() {
35953591
HANDLESCOPE(thread());
35963592

35973593
FlowGraph* flow_graph = nullptr;
3598-
ZoneGrowableArray<const ICData*>* ic_data_array = nullptr;
35993594
const Function& function = parsed_function()->function();
36003595
ASSERT(!function.IsIrregexpFunction());
36013596
ASSERT(function.IsOptimizable());
@@ -3606,7 +3601,8 @@ bool PrecompileParsedFunctionHelper::Compile() {
36063601
compiler_state.set_function(function);
36073602

36083603
{
3609-
ic_data_array = new (zone) ZoneGrowableArray<const ICData*>();
3604+
ZoneGrowableArray<const ICData*>* ic_data_array =
3605+
new (zone) ZoneGrowableArray<const ICData*>();
36103606

36113607
TIMELINE_DURATION(thread(), CompilerVerbose, "BuildFlowGraph");
36123608
COMPILER_TIMINGS_TIMER_SCOPE(thread(), BuildGraph);
@@ -3621,20 +3617,16 @@ bool PrecompileParsedFunctionHelper::Compile() {
36213617

36223618
flow_graph->PopulateWithICData(function);
36233619

3624-
CompilerPassState pass_state(thread(), flow_graph, precompiler_);
3625-
36263620
{
36273621
TIMELINE_DURATION(thread(), CompilerVerbose, "OptimizationPasses");
36283622

36293623
AotCallSpecializer call_specializer(precompiler_, flow_graph);
3624+
CompilerPassState pass_state(thread(), flow_graph, precompiler_);
36303625
pass_state.call_specializer = &call_specializer;
36313626

36323627
flow_graph = CompilerPass::RunPipeline(CompilerPass::kAOT, &pass_state);
36333628
}
36343629

3635-
ASSERT(pass_state.inline_id_to_function.length() ==
3636-
pass_state.caller_inline_id.length());
3637-
36383630
ASSERT(precompiler_ != nullptr);
36393631

36403632
// When generating code in bare instruction mode all code objects
@@ -3647,7 +3639,7 @@ bool PrecompileParsedFunctionHelper::Compile() {
36473639
// failure to commit object pool into the global object pool.
36483640
GenerateNecessaryAllocationStubs(flow_graph);
36493641

3650-
return GenerateCode(flow_graph, &pass_state, ic_data_array);
3642+
return GenerateCode(flow_graph);
36513643
}
36523644

36533645
void Precompiler::CompileFunction(Precompiler* precompiler,

runtime/vm/compiler/backend/flow_graph.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ FlowGraph::FlowGraph(const ParsedFunction& parsed_function,
7070
loop_invariant_loads_(nullptr),
7171
captured_parameters_(new(zone()) BitVector(zone(), variable_count())),
7272
inlining_id_(-1),
73+
inlining_info_(&parsed_function.function()),
7374
should_print_(false),
7475
should_omit_check_bounds_(
7576
dart::ShouldOmitCheckBoundsIn(parsed_function.function())) {

runtime/vm/compiler/backend/flow_graph.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,28 @@ struct PrologueInfo {
118118
}
119119
};
120120

121+
struct InliningInfo {
122+
// Maps inline_id_to_function[inline_id] -> function. Top scope
123+
// function has inline_id 0. The map is populated by the inliner.
124+
GrowableArray<const Function*> inline_id_to_function;
125+
// Token position where inlining occurred.
126+
GrowableArray<TokenPosition> inline_id_to_token_pos;
127+
// For a given inlining-id(index) specifies the caller's inlining-id.
128+
GrowableArray<intptr_t> caller_inline_id;
129+
130+
explicit InliningInfo(const Function* function) {
131+
// Top scope function is at inlining id 0.
132+
inline_id_to_function.Add(function);
133+
// Top scope function has no caller (-1).
134+
caller_inline_id.Add(-1);
135+
// We do not add a token position for the top scope function to
136+
// |inline_id_to_token_pos| because it is not (currently) inlined into
137+
// another graph at a given token position. A side effect of this is that
138+
// the length of |inline_id_to_function| and |caller_inline_id| is always
139+
// larger than the length of |inline_id_to_token_pos| by one.
140+
}
141+
};
142+
121143
// Class to encapsulate the construction and manipulation of the flow graph.
122144
class FlowGraph : public ZoneAllocated {
123145
public:
@@ -476,6 +498,9 @@ class FlowGraph : public ZoneAllocated {
476498
intptr_t inlining_id() const { return inlining_id_; }
477499
void set_inlining_id(intptr_t value) { inlining_id_ = value; }
478500

501+
InliningInfo& inlining_info() { return inlining_info_; }
502+
const InliningInfo& inlining_info() const { return inlining_info_; }
503+
479504
// Returns true if any instructions were canonicalized away.
480505
bool Canonicalize();
481506

@@ -745,7 +770,10 @@ class FlowGraph : public ZoneAllocated {
745770
DirectChainedHashMap<ConstantPoolTrait> constant_instr_pool_;
746771
BitVector* captured_parameters_;
747772

773+
// Inlining related fields.
748774
intptr_t inlining_id_;
775+
InliningInfo inlining_info_;
776+
749777
bool should_print_;
750778
const bool should_omit_check_bounds_;
751779
uint8_t* compiler_pass_filters_ = nullptr;

runtime/vm/compiler/backend/flow_graph_checker.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ class FlowGraphChecker : public FlowGraphVisitor {
3434
// Constructs graph checker. The checker uses some custom-made
3535
// visitation to perform additional checks, and uses the
3636
// FlowGraphVisitor structure for anything else.
37-
FlowGraphChecker(FlowGraph* flow_graph,
38-
const GrowableArray<const Function*>& inline_id_to_function)
37+
explicit FlowGraphChecker(FlowGraph* flow_graph)
3938
: FlowGraphVisitor(flow_graph->preorder()),
4039
flow_graph_(flow_graph),
41-
inline_id_to_function_(inline_id_to_function),
40+
inline_id_to_function_(
41+
flow_graph->inlining_info().inline_id_to_function),
4242
script_(Script::Handle(flow_graph_->zone())),
4343
current_block_(nullptr) {}
4444

runtime/vm/compiler/backend/flow_graph_compiler.cc

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,6 @@ FlowGraphCompiler::FlowGraphCompiler(
137137
FlowGraph* flow_graph,
138138
const ParsedFunction& parsed_function,
139139
bool is_optimizing,
140-
const GrowableArray<const Function*>& inline_id_to_function,
141-
const GrowableArray<TokenPosition>& inline_id_to_token_pos,
142-
const GrowableArray<intptr_t>& caller_inline_id,
143140
ZoneGrowableArray<const ICData*>* deopt_id_to_ic_data,
144141
CodeStatistics* stats /* = nullptr */)
145142
: thread_(Thread::Current()),
@@ -194,13 +191,18 @@ FlowGraphCompiler::FlowGraphCompiler(
194191
#else
195192
const bool stack_traces_only = false;
196193
#endif
194+
195+
const auto& inlining_info = flow_graph->inlining_info();
197196
// Make sure that the function is at the position for inline_id 0.
198-
ASSERT(inline_id_to_function.length() >= 1);
199-
ASSERT(inline_id_to_function[0]->ptr() ==
197+
ASSERT(inlining_info.inline_id_to_function.length() >= 1);
198+
ASSERT(inlining_info.inline_id_to_function[0]->ptr() ==
200199
flow_graph->parsed_function().function().ptr());
201-
code_source_map_builder_ = new (zone_)
202-
CodeSourceMapBuilder(zone_, stack_traces_only, caller_inline_id,
203-
inline_id_to_token_pos, inline_id_to_function);
200+
ASSERT(inlining_info.inline_id_to_function.length() ==
201+
inlining_info.caller_inline_id.length());
202+
code_source_map_builder_ = new (zone_) CodeSourceMapBuilder(
203+
zone_, stack_traces_only, inlining_info.caller_inline_id,
204+
inlining_info.inline_id_to_token_pos,
205+
inlining_info.inline_id_to_function);
204206

205207
ArchSpecificInitialization();
206208
}

runtime/vm/compiler/backend/flow_graph_compiler.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -380,9 +380,6 @@ class FlowGraphCompiler : public ValueObject {
380380
FlowGraph* flow_graph,
381381
const ParsedFunction& parsed_function,
382382
bool is_optimizing,
383-
const GrowableArray<const Function*>& inline_id_to_function,
384-
const GrowableArray<TokenPosition>& inline_id_to_token_pos,
385-
const GrowableArray<intptr_t>& caller_inline_id,
386383
ZoneGrowableArray<const ICData*>* deopt_id_to_ic_data,
387384
CodeStatistics* stats = nullptr);
388385

runtime/vm/compiler/backend/il_serializer.cc

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,6 @@ void FlowGraphSerializer::WriteFlowGraph(
658658

659659
Write<intptr_t>(flow_graph.current_ssa_temp_index());
660660
Write<intptr_t>(flow_graph.max_block_id());
661-
Write<intptr_t>(flow_graph.inlining_id());
662661
Write<const Array&>(flow_graph.coverage_array());
663662

664663
PrologueInfo prologue_info = flow_graph.prologue_info();
@@ -709,12 +708,27 @@ void FlowGraphSerializer::WriteFlowGraph(
709708
}
710709
Write<GrowableArray<intptr_t>>(indices);
711710
}
711+
712+
Write<intptr_t>(flow_graph.inlining_id());
713+
714+
const InliningInfo& inlining_info = flow_graph.inlining_info();
715+
Write<intptr_t>(inlining_info.inline_id_to_function.length());
716+
ASSERT(inlining_info.inline_id_to_function.length() ==
717+
inlining_info.caller_inline_id.length());
718+
ASSERT(inlining_info.inline_id_to_function.length() ==
719+
inlining_info.inline_id_to_token_pos.length() + 1);
720+
721+
for (intptr_t i = 1, n = inlining_info.inline_id_to_function.length(); i < n;
722+
++i) {
723+
Write<const Function&>(*(inlining_info.inline_id_to_function[i]));
724+
Write<intptr_t>(inlining_info.caller_inline_id[i]);
725+
Write<TokenPosition>(inlining_info.inline_id_to_token_pos[i - 1]);
726+
}
712727
}
713728

714729
FlowGraph* FlowGraphDeserializer::ReadFlowGraph() {
715730
const intptr_t current_ssa_temp_index = Read<intptr_t>();
716731
const intptr_t max_block_id = Read<intptr_t>();
717-
const intptr_t inlining_id = Read<intptr_t>();
718732
const Array& coverage_array = Read<const Array&>();
719733
const PrologueInfo prologue_info(Read<intptr_t>(), Read<intptr_t>());
720734

@@ -750,7 +764,6 @@ FlowGraph* FlowGraphDeserializer::ReadFlowGraph() {
750764
flow_graph->set_current_ssa_temp_index(current_ssa_temp_index);
751765
flow_graph->CreateCommonConstants();
752766
flow_graph->disallow_licm();
753-
flow_graph->set_inlining_id(inlining_id);
754767
flow_graph->set_coverage_array(coverage_array);
755768

756769
{
@@ -771,6 +784,19 @@ FlowGraph* FlowGraphDeserializer::ReadFlowGraph() {
771784
}
772785
}
773786

787+
flow_graph->set_inlining_id(Read<intptr_t>());
788+
789+
auto& inlining_info = flow_graph->inlining_info();
790+
const intptr_t inlining_info_len = Read<intptr_t>();
791+
ASSERT(inlining_info.inline_id_to_function.length() == 1);
792+
ASSERT(inlining_info.caller_inline_id.length() == 1);
793+
ASSERT(inlining_info.inline_id_to_token_pos.length() == 0);
794+
for (intptr_t i = 1; i < inlining_info_len; ++i) {
795+
inlining_info.inline_id_to_function.Add(&Read<const Function&>());
796+
inlining_info.caller_inline_id.Add(Read<intptr_t>());
797+
inlining_info.inline_id_to_token_pos.Add(Read<TokenPosition>());
798+
}
799+
774800
return flow_graph;
775801
}
776802

runtime/vm/compiler/backend/il_test_helper.cc

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -218,14 +218,10 @@ void TestPipeline::CompileGraphAndAttachFunction() {
218218
const intptr_t far_branch_level = 1;
219219
#endif
220220

221-
ASSERT(pass_state_->inline_id_to_function.length() ==
222-
pass_state_->caller_inline_id.length());
223221
compiler::ObjectPoolBuilder object_pool_builder;
224222
compiler::Assembler assembler(&object_pool_builder, far_branch_level);
225-
FlowGraphCompiler graph_compiler(
226-
&assembler, flow_graph_, *parsed_function_, optimized,
227-
pass_state_->inline_id_to_function, pass_state_->inline_id_to_token_pos,
228-
pass_state_->caller_inline_id, ic_data_array_);
223+
FlowGraphCompiler graph_compiler(&assembler, flow_graph_, *parsed_function_,
224+
optimized, ic_data_array_);
229225

230226
graph_compiler.CompileGraph();
231227

runtime/vm/compiler/backend/inliner.cc

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,12 +1324,7 @@ class CallSiteInliner : public ValueObject {
13241324
callee_graph->set_current_ssa_temp_index(
13251325
caller_graph_->current_ssa_temp_index());
13261326
#if defined(DEBUG)
1327-
// The inlining IDs of instructions in the callee graph are unset
1328-
// until we call SetInliningID later.
1329-
GrowableArray<const Function*> callee_inline_id_to_function;
1330-
callee_inline_id_to_function.Add(&function);
1331-
FlowGraphChecker(callee_graph, callee_inline_id_to_function)
1332-
.Check("Builder (callee)");
1327+
FlowGraphChecker(callee_graph).Check("Builder (callee)");
13331328
#endif
13341329
CalleeGraphValidator::Validate(callee_graph);
13351330
}
@@ -1406,12 +1401,7 @@ class CallSiteInliner : public ValueObject {
14061401
COMPILER_TIMINGS_TIMER_SCOPE(thread(), ComputeSSA);
14071402
callee_graph->ComputeSSA(param_stubs);
14081403
#if defined(DEBUG)
1409-
// The inlining IDs of instructions in the callee graph are unset
1410-
// until we call SetInliningID later.
1411-
GrowableArray<const Function*> callee_inline_id_to_function;
1412-
callee_inline_id_to_function.Add(&function);
1413-
FlowGraphChecker(callee_graph, callee_inline_id_to_function)
1414-
.Check("SSA (callee)");
1404+
FlowGraphChecker(callee_graph).Check("SSA (callee)");
14151405
#endif
14161406
}
14171407

@@ -2387,16 +2377,14 @@ bool PolymorphicInliner::Inline() {
23872377
return true;
23882378
}
23892379

2390-
FlowGraphInliner::FlowGraphInliner(
2391-
FlowGraph* flow_graph,
2392-
GrowableArray<const Function*>* inline_id_to_function,
2393-
GrowableArray<TokenPosition>* inline_id_to_token_pos,
2394-
GrowableArray<intptr_t>* caller_inline_id,
2395-
Precompiler* precompiler)
2380+
FlowGraphInliner::FlowGraphInliner(FlowGraph* flow_graph,
2381+
Precompiler* precompiler)
23962382
: flow_graph_(flow_graph),
2397-
inline_id_to_function_(inline_id_to_function),
2398-
inline_id_to_token_pos_(inline_id_to_token_pos),
2399-
caller_inline_id_(caller_inline_id),
2383+
inline_id_to_function_(
2384+
&(flow_graph->inlining_info().inline_id_to_function)),
2385+
inline_id_to_token_pos_(
2386+
&(flow_graph->inlining_info().inline_id_to_token_pos)),
2387+
caller_inline_id_(&(flow_graph->inlining_info().caller_inline_id)),
24002388
trace_inlining_(FLAG_trace_inlining && flow_graph->should_print()),
24012389
precompiler_(precompiler) {}
24022390

runtime/vm/compiler/backend/inliner.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,7 @@ class TargetEntryInstr;
3232

3333
class FlowGraphInliner : ValueObject {
3434
public:
35-
FlowGraphInliner(FlowGraph* flow_graph,
36-
GrowableArray<const Function*>* inline_id_to_function,
37-
GrowableArray<TokenPosition>* inline_id_to_token_pos,
38-
GrowableArray<intptr_t>* caller_inline_id,
39-
Precompiler* precompiler);
35+
FlowGraphInliner(FlowGraph* flow_graph, Precompiler* precompiler);
4036

4137
// The flow graph is destructively updated upon inlining. Returns the max
4238
// depth that we inlined.

0 commit comments

Comments
 (0)