aboutsummaryrefslogtreecommitdiff
path: root/gcc/cgraphclones.c
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2021-07-27 10:02:38 +0200
committerMartin Jambor <mjambor@suse.cz>2021-07-27 10:03:17 +0200
commit13586172d0b70c9d7ca464fc5a2a46a8532b06d7 (patch)
treed9b3cd1eab248ec0adbf6334a9fa4b8663107b06 /gcc/cgraphclones.c
parenta21bd3cebd6f54af70a37c18b8fbeae933fb6515 (diff)
downloadgcc-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.c10
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