diff options
author | Martin Jambor <mjambor@suse.cz> | 2021-07-27 10:02:38 +0200 |
---|---|---|
committer | Martin Jambor <mjambor@suse.cz> | 2021-07-27 10:03:17 +0200 |
commit | 13586172d0b70c9d7ca464fc5a2a46a8532b06d7 (patch) | |
tree | d9b3cd1eab248ec0adbf6334a9fa4b8663107b06 /gcc/cgraphclones.c | |
parent | a21bd3cebd6f54af70a37c18b8fbeae933fb6515 (diff) | |
download | gcc-13586172d0b70c9d7ca464fc5a2a46a8532b06d7.zip gcc-13586172d0b70c9d7ca464fc5a2a46a8532b06d7.tar.gz gcc-13586172d0b70c9d7ca464fc5a2a46a8532b06d7.tar.bz2 |
ipa: Adjust references to identify read-only globals
this patch has been motivated by SPEC 2017's 544.nab_r in which there is
a static variable which is never written to and so zero throughout the
run-time of the benchmark. However, it is passed by reference to a
function in which it is read and (after some multiplications) passed
into __builtin_exp which in turn unnecessarily consumes almost 10% of
the total benchmark run-time. The situation is illustrated by the added
testcase remref-3.c.
The patch adds a flag to ipa-prop descriptor of each parameter to mark
such parameters. IPA-CP and inling then take the effort to remove
IPA_REF_ADDR references in the caller and only add IPA_REF_LOAD
reference to the clone/overall inlined function. This is sufficient
for subsequent symbol table analysis code to identify the read-only
variable as such and optimize the code.
There are two changes from the RFC version posted to the list earlier.
First, three missing calls to get_base_address were added (there was
another one in an assert). Second, references are not stripped off
the callers if the cloned function cannot change the signature. The
second change reveals a real shortcoming stemming from the fact we
cannot adjust function prototypes with fnspecs. But that is a more
general problem.
gcc/ChangeLog:
2021-07-20 Martin Jambor <mjambor@suse.cz>
* cgraph.h (ipa_replace_map): New field force_load_ref.
* ipa-prop.h (ipa_param_descriptor): Reduce precision of move_cost,
aded new flag load_dereferenced, adjusted comments.
(ipa_get_param_dereferenced): New function.
(ipa_set_param_dereferenced): Likewise.
* cgraphclones.c (cgraph_node::create_virtual_clone): Follow it.
* ipa-cp.c: Include gimple.h.
(ipcp_discover_new_direct_edges): Take into account dereferenced flag.
(get_replacement_map): New parameter force_load_ref, set the
appropriate flag in ipa_replace_map if set.
(struct symbol_and_index_together): New type.
(adjust_refs_in_act_callers): New function.
(adjust_references_in_caller): Likewise.
(create_specialized_node): When appropriate, call
adjust_references_in_caller and force only load references.
* ipa-prop.c (load_from_dereferenced_name): New function.
(ipa_analyze_controlled_uses): Also detect loads from a
dereference, harden testing of call statements.
(ipa_write_node_info): Stream the dereferenced flag.
(ipa_read_node_info): Likewise.
(ipa_set_jf_constant): Also create refdesc when jump function
references a variable.
(cgraph_node_for_jfunc): Rename to symtab_node_for_jfunc, work
also on references of variables and return a symtab_node. Adjust
all callers.
(propagate_controlled_uses): Also remove references to VAR_DECLs.
gcc/testsuite/ChangeLog:
2021-06-29 Martin Jambor <mjambor@suse.cz>
* gcc.dg/ipa/remref-3.c: New test.
* gcc.dg/ipa/remref-4.c: Likewise.
* gcc.dg/ipa/remref-5.c: Likewise.
* gcc.dg/ipa/remref-6.c: Likewise.
Diffstat (limited to 'gcc/cgraphclones.c')
-rw-r--r-- | gcc/cgraphclones.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c index fef4a23..b16e681 100644 --- a/gcc/cgraphclones.c +++ b/gcc/cgraphclones.c @@ -633,7 +633,15 @@ cgraph_node::create_virtual_clone (const vec<cgraph_edge *> &redirect_callers, || in_lto_p) new_node->unique_name = true; FOR_EACH_VEC_SAFE_ELT (tree_map, i, map) - new_node->maybe_create_reference (map->new_tree, NULL); + { + tree repl = map->new_tree; + if (map->force_load_ref) + { + gcc_assert (TREE_CODE (repl) == ADDR_EXPR); + repl = get_base_address (TREE_OPERAND (repl, 0)); + } + new_node->maybe_create_reference (repl, NULL); + } if (ipa_transforms_to_apply.exists ()) new_node->ipa_transforms_to_apply |