Skip to content

Commit

Permalink
Add option to configure a multiplier for different kinds of unused args
Browse files Browse the repository at this point in the history
Summary: The default is always a multiplier of 1, so this is a behavior-preserving change.

Reviewed By: beicy

Differential Revision: D57005516

fbshipit-source-id: f67421702b647d7aa5c28009c4fc126a2226ce8c
  • Loading branch information
Nikolai Tillmann authored and facebook-github-bot committed May 7, 2024
1 parent fc6faa1 commit fd22985
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 3 deletions.
33 changes: 33 additions & 0 deletions opt/methodinline/MethodInlinePass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,39 @@ void MethodInlinePass::bind_config() {
bind("cross_dex_penalty_const",
DEFAULT_COST_CONFIG.cross_dex_penalty_const,
m_inliner_cost_config.cross_dex_penalty_const);
bind("unused_arg_zero_multiplier",
DEFAULT_COST_CONFIG.unused_arg_zero_multiplier,
m_inliner_cost_config.unused_arg_zero_multiplier);
bind("unused_arg_non_zero_constant_multiplier",
DEFAULT_COST_CONFIG.unused_arg_non_zero_constant_multiplier,
m_inliner_cost_config.unused_arg_non_zero_constant_multiplier);
bind("unused_arg_nez_multiplier",
DEFAULT_COST_CONFIG.unused_arg_nez_multiplier,
m_inliner_cost_config.unused_arg_nez_multiplier);
bind("unused_arg_interval_multiplier",
DEFAULT_COST_CONFIG.unused_arg_interval_multiplier,
m_inliner_cost_config.unused_arg_interval_multiplier);
bind("unused_arg_singleton_object_multiplier",
DEFAULT_COST_CONFIG.unused_arg_singleton_object_multiplier,
m_inliner_cost_config.unused_arg_singleton_object_multiplier);
bind("unused_arg_object_with_immutable_attr_multiplier",
DEFAULT_COST_CONFIG.unused_arg_object_with_immutable_attr_multiplier,
m_inliner_cost_config.unused_arg_object_with_immutable_attr_multiplier);
bind("unused_arg_string_multiplier",
DEFAULT_COST_CONFIG.unused_arg_string_multiplier,
m_inliner_cost_config.unused_arg_string_multiplier);
bind("unused_arg_class_object_multiplier",
DEFAULT_COST_CONFIG.unused_arg_class_object_multiplier,
m_inliner_cost_config.unused_arg_class_object_multiplier);
bind("unused_arg_new_object_multiplier",
DEFAULT_COST_CONFIG.unused_arg_new_object_multiplier,
m_inliner_cost_config.unused_arg_new_object_multiplier);
bind("unused_arg_other_object_multiplier",
DEFAULT_COST_CONFIG.unused_arg_other_object_multiplier,
m_inliner_cost_config.unused_arg_other_object_multiplier);
bind("unused_arg_not_top_multiplier",
DEFAULT_COST_CONFIG.unused_arg_not_top_multiplier,
m_inliner_cost_config.unused_arg_not_top_multiplier);
}

void MethodInlinePass::run_pass(DexStoresVector& stores,
Expand Down
54 changes: 51 additions & 3 deletions service/method-inliner/Inliner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1369,11 +1369,21 @@ InlinedCost MultiMethodInliner::get_inlined_cost(
/* ignore_unreachable */ !reduced_code,
[&](auto* insn) { return opcode::is_a_load_param(insn->opcode()); });
auto def_use_chains = chains.get_def_use_chains();
size_t arg_idx = 0;
for (auto& mie : cfg->get_param_instructions()) {
auto uses = def_use_chains[mie.insn];
if (uses.empty()) {
unused_args++;
auto it = def_use_chains.find(mie.insn);
if (it == def_use_chains.end() || it->second.empty()) {
float multiplier =
1.0f; // all other multipliers are relative to this normative value
if (call_site_summary) {
const auto& cv = call_site_summary->arguments.get(arg_idx);
if (!cv.is_top()) {
multiplier = get_unused_arg_multiplier(cv);
}
}
unused_args += multiplier;
}
arg_idx++;
}
insn_size = cfg->estimate_code_units();
if (returns > 1) {
Expand All @@ -1396,6 +1406,44 @@ InlinedCost MultiMethodInliner::get_inlined_cost(
insn_size};
}

float MultiMethodInliner::get_unused_arg_multiplier(
const ConstantValue& cv) const {
always_assert(!cv.is_top());
always_assert(!cv.is_bottom());
if (cv.is_zero()) {
return m_inliner_cost_config.unused_arg_zero_multiplier;
}
if (auto scd = cv.maybe_get<SignedConstantDomain>()) {
if (scd->get_constant()) {
return m_inliner_cost_config.unused_arg_non_zero_constant_multiplier;
}
if (scd->is_nez()) {
return m_inliner_cost_config.unused_arg_nez_multiplier;
}
return m_inliner_cost_config.unused_arg_interval_multiplier;
}
if (cv.is_object()) {
if (cv.is_singleton_object()) {
return m_inliner_cost_config.unused_arg_singleton_object_multiplier;
}
if (cv.is_object_with_immutable_attr()) {
return m_inliner_cost_config
.unused_arg_object_with_immutable_attr_multiplier;
}
if (cv.maybe_get<StringDomain>()) {
return m_inliner_cost_config.unused_arg_string_multiplier;
}
if (cv.maybe_get<ConstantClassObjectDomain>()) {
return m_inliner_cost_config.unused_arg_class_object_multiplier;
}
if (cv.maybe_get<NewObjectDomain>()) {
return m_inliner_cost_config.unused_arg_new_object_multiplier;
}
return m_inliner_cost_config.unused_arg_other_object_multiplier;
}
return m_inliner_cost_config.unused_arg_not_top_multiplier;
}

const InlinedCost* MultiMethodInliner::get_fully_inlined_cost(
const DexMethod* callee) {
return m_fully_inlined_costs
Expand Down
25 changes: 25 additions & 0 deletions service/method-inliner/Inliner.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,18 @@ struct InlinerCostConfig {
size_t cross_dex_penalty_coe1;
size_t cross_dex_penalty_coe2;
size_t cross_dex_penalty_const;

float unused_arg_zero_multiplier;
float unused_arg_non_zero_constant_multiplier;
float unused_arg_nez_multiplier;
float unused_arg_interval_multiplier;
float unused_arg_singleton_object_multiplier;
float unused_arg_object_with_immutable_attr_multiplier;
float unused_arg_string_multiplier;
float unused_arg_class_object_multiplier;
float unused_arg_new_object_multiplier;
float unused_arg_other_object_multiplier;
float unused_arg_not_top_multiplier;
};

const struct InlinerCostConfig DEFAULT_COST_CONFIG = {
Expand All @@ -108,6 +120,17 @@ const struct InlinerCostConfig DEFAULT_COST_CONFIG = {
1, // cross_dex_penalty_coe1;
0, // cross_dex_penalty_coe2;
1, // cross_dex_penalty_const;
1.0f, // unused_arg_zero_multiplier
1.0f, // unused_arg_non_zero_constant_multiplier
1.0f, // unused_arg_nez_multiplier
1.0f, // unused_arg_interval_multiplier
1.0f, // unused_arg_singleton_object_multiplier
1.0f, // unused_arg_object_with_immutable_attr_multiplier
1.0f, // unused_arg_string_multiplier
1.0f, // unused_arg_class_object_multiplier
1.0f, // unused_arg_new_object_multiplier
1.0f, // unused_arg_other_object_multiplier
1.0f, // unused_arg_not_top_multiplier
};

// All call-sites of a callee.
Expand Down Expand Up @@ -474,6 +497,8 @@ class MultiMethodInliner {
const IRCode* code,
const CallSiteSummary* call_site_summary = nullptr);

float get_unused_arg_multiplier(const ConstantValue&) const;

/**
* Estimate inlined cost for fully inlining a callee without using any
* summaries for pruning.
Expand Down

0 comments on commit fd22985

Please sign in to comment.