Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(87)

Unified Diff: runtime/vm/flow_graph_inliner.cc

Issue 2894953002: Support inlining of calls where type arguments are passed to generic functions. (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/vm/flow_graph_inliner.cc
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index f5b3030347d83d7cc51c6cac47e5f5d11e8a39ea..f86e96872125b497e22009e30cf28af9a86d5baa 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -432,24 +432,27 @@ class CallSites : public ValueObject {
struct InlinedCallData {
InlinedCallData(Definition* call,
+ intptr_t first_param_index, // 1 if type args are passed.
GrowableArray<Value*>* arguments,
const Function& caller,
intptr_t caller_inlining_id)
: call(call),
+ first_param_index(first_param_index),
arguments(arguments),
callee_graph(NULL),
parameter_stubs(NULL),
exit_collector(NULL),
caller(caller),
- caller_inlining_id_(caller_inlining_id) {}
+ caller_inlining_id(caller_inlining_id) {}
Definition* call;
+ const intptr_t first_param_index;
GrowableArray<Value*>* arguments;
FlowGraph* callee_graph;
ZoneGrowableArray<Definition*>* parameter_stubs;
InlineExitCollector* exit_collector;
const Function& caller;
- const intptr_t caller_inlining_id_;
+ const intptr_t caller_inlining_id;
};
@@ -573,7 +576,7 @@ class CallSiteInliner : public ValueObject {
}
void InlineCalls() {
- // If inlining depth is less then one abort.
+ // If inlining depth is less than one abort.
if (inlining_depth_threshold_ < 1) return;
if (caller_graph_->function().deoptimization_counter() >=
FLAG_deoptimization_counter_inlining_threshold) {
@@ -830,13 +833,22 @@ class CallSiteInliner : public ValueObject {
// concrete information about the values, for example constant values,
// without linking between the caller and callee graphs.
// TODO(zerny): Put more information in the stubs, eg, type information.
+ const intptr_t first_param_index = call_data->first_param_index;
+ const intptr_t num_params =
+ first_param_index + function.NumParameters();
ZoneGrowableArray<Definition*>* param_stubs =
- new (Z) ZoneGrowableArray<Definition*>(function.NumParameters());
+ new (Z) ZoneGrowableArray<Definition*>(num_params);
+ // Create a ConstantInstr as Definition for the type arguments, if any.
+ Definition* type_args_stub = NULL;
+ if (first_param_index > 0) {
+ type_args_stub =
+ CreateParameterStub(0, (*arguments)[0], callee_graph);
+ }
// Create a parameter stub for each fixed positional parameter.
for (intptr_t i = 0; i < function.num_fixed_parameters(); ++i) {
- param_stubs->Add(
- CreateParameterStub(i, (*arguments)[i], callee_graph));
+ param_stubs->Add(CreateParameterStub(
+ i, (*arguments)[first_param_index + i], callee_graph));
}
// If the callee has optional parameters, rebuild the argument and stub
@@ -844,9 +856,9 @@ class CallSiteInliner : public ValueObject {
// parameters.
if (function.HasOptionalParameters()) {
TRACE_INLINING(THR_Print(" adjusting for optional parameters\n"));
- if (!AdjustForOptionalParameters(*parsed_function, argument_names,
- arguments, param_stubs,
- callee_graph)) {
+ if (!AdjustForOptionalParameters(*parsed_function, first_param_index,
+ argument_names, arguments,
+ param_stubs, callee_graph)) {
function.set_is_inlinable(false);
TRACE_INLINING(THR_Print(" Bailout: optional arg mismatch\n"));
PRINT_INLINING_TREE("Optional arg mismatch", &call_data->caller,
@@ -887,7 +899,7 @@ class CallSiteInliner : public ValueObject {
CSTAT_TIMER_SCOPE(thread(), graphinliner_ssa_timer);
// Compute SSA on the callee graph, catching bailouts.
callee_graph->ComputeSSA(caller_graph_->max_virtual_register_number(),
- param_stubs);
+ param_stubs, type_args_stub);
DEBUG_ASSERT(callee_graph->VerifyUseLists());
}
@@ -1021,7 +1033,7 @@ class CallSiteInliner : public ValueObject {
callee_graph,
inliner_->NextInlineId(callee_graph->function(),
call_data->call->token_pos(),
- call_data->caller_inlining_id_));
+ call_data->caller_inlining_id));
TRACE_INLINING(THR_Print(" Success\n"));
TRACE_INLINING(THR_Print(" with size %" Pd "\n",
function.optimized_instruction_count()));
@@ -1134,10 +1146,11 @@ class CallSiteInliner : public ValueObject {
// Replace each stub with the actual argument or the caller's constant.
// Nulls denote optional parameters for which no actual was given.
+ const intptr_t first_param_index = call_data->first_param_index;
GrowableArray<Value*>* arguments = call_data->arguments;
- for (intptr_t i = 0; i < arguments->length(); ++i) {
+ for (intptr_t i = 0; i < arguments->length() - first_param_index; ++i) {
Definition* stub = (*call_data->parameter_stubs)[i];
- Value* actual = (*arguments)[i];
+ Value* actual = (*arguments)[first_param_index + i];
if (actual != NULL) stub->ReplaceUsesWith(actual->definition());
}
@@ -1229,7 +1242,8 @@ class CallSiteInliner : public ValueObject {
arguments.Add(call->PushArgumentAt(i)->value());
}
InlinedCallData call_data(
- call, &arguments, call_info[call_idx].caller(),
+ call, call->FirstParamIndex(), &arguments,
+ call_info[call_idx].caller(),
call_info[call_idx].caller_graph->inlining_id());
if (TryInlining(call->function(), call->argument_names(), &call_data)) {
InlineCall(&call_data);
@@ -1275,7 +1289,8 @@ class CallSiteInliner : public ValueObject {
arguments.Add(call->PushArgumentAt(i)->value());
}
InlinedCallData call_data(
- call, &arguments, call_info[call_idx].caller(),
+ call, call->FirstParamIndex(), &arguments,
+ call_info[call_idx].caller(),
call_info[call_idx].caller_graph->inlining_id());
if (TryInlining(target, call->argument_names(), &call_data)) {
InlineCall(&call_data);
@@ -1306,6 +1321,7 @@ class CallSiteInliner : public ValueObject {
}
bool AdjustForOptionalParameters(const ParsedFunction& parsed_function,
+ intptr_t first_param_index,
const Array& argument_names,
GrowableArray<Value*>* arguments,
ZoneGrowableArray<Definition*>* param_stubs,
@@ -1320,19 +1336,20 @@ class CallSiteInliner : public ValueObject {
intptr_t arg_count = arguments->length();
intptr_t param_count = function.NumParameters();
intptr_t fixed_param_count = function.num_fixed_parameters();
- ASSERT(fixed_param_count <= arg_count);
- ASSERT(arg_count <= param_count);
+ ASSERT(fixed_param_count <= arg_count - first_param_index);
+ ASSERT(arg_count - first_param_index <= param_count);
if (function.HasOptionalPositionalParameters()) {
// Create a stub for each optional positional parameters with an actual.
- for (intptr_t i = fixed_param_count; i < arg_count; ++i) {
+ for (intptr_t i = first_param_index + fixed_param_count; i < arg_count;
+ ++i) {
param_stubs->Add(CreateParameterStub(i, (*arguments)[i], callee_graph));
}
ASSERT(function.NumOptionalPositionalParameters() ==
(param_count - fixed_param_count));
// For each optional positional parameter without an actual, add its
// default value.
- for (intptr_t i = arg_count; i < param_count; ++i) {
+ for (intptr_t i = arg_count - first_param_index; i < param_count; ++i) {
const Instance& object =
parsed_function.DefaultParameterValueAt(i - fixed_param_count);
ConstantInstr* constant = new (Z) ConstantInstr(object);
@@ -1344,10 +1361,12 @@ class CallSiteInliner : public ValueObject {
ASSERT(function.HasOptionalNamedParameters());
- // Passed arguments must match fixed parameters plus named arguments.
+ // Passed arguments (not counting optional type args) must match fixed
+ // parameters plus named arguments.
intptr_t argument_names_count =
(argument_names.IsNull()) ? 0 : argument_names.Length();
- ASSERT(arg_count == (fixed_param_count + argument_names_count));
+ ASSERT((arg_count - first_param_index) ==
+ (fixed_param_count + argument_names_count));
// Fast path when no optional named parameters are given.
if (argument_names_count == 0) {
@@ -1363,12 +1382,12 @@ class CallSiteInliner : public ValueObject {
for (intptr_t i = 0; i < argument_names.Length(); ++i) {
String& arg_name = String::Handle(caller_graph_->zone());
arg_name ^= argument_names.At(i);
- named_args.Add(
- NamedArgument(&arg_name, (*arguments)[i + fixed_param_count]));
+ named_args.Add(NamedArgument(
+ &arg_name, (*arguments)[first_param_index + fixed_param_count + i]));
}
- // Truncate the arguments array to just fixed parameters.
- arguments->TruncateTo(fixed_param_count);
+ // Truncate the arguments array to just type args and fixed parameters.
+ arguments->TruncateTo(first_param_index + fixed_param_count);
// For each optional named parameter, add the actual argument or its
// default if no argument is passed.
@@ -1387,7 +1406,8 @@ class CallSiteInliner : public ValueObject {
arguments->Add(arg);
// Create a stub for the argument or use the parameter's default value.
if (arg != NULL) {
- param_stubs->Add(CreateParameterStub(i, arg, callee_graph));
+ param_stubs->Add(
+ CreateParameterStub(first_param_index + i, arg, callee_graph));
} else {
param_stubs->Add(
GetDefaultValue(i - fixed_param_count, parsed_function));
@@ -1530,8 +1550,8 @@ bool PolymorphicInliner::TryInliningPoly(const TargetInfo& target_info) {
for (int i = 0; i < call_->ArgumentCount(); ++i) {
arguments.Add(call_->PushArgumentAt(i)->value());
}
- InlinedCallData call_data(call_, &arguments, caller_function_,
- caller_inlining_id_);
+ InlinedCallData call_data(call_, call_->instance_call()->FirstParamIndex(),
+ &arguments, caller_function_, caller_inlining_id_);
Function& target = Function::ZoneHandle(zone(), target_info.target->raw());
if (!owner_->TryInlining(target, call_->instance_call()->argument_names(),
&call_data)) {

Powered by Google App Engine
This is Rietveld 408576698