aboutsummaryrefslogtreecommitdiff
path: root/gcc/ipa-modref.c
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2021-11-08 07:52:45 +0100
committerJan Hubicka <hubicka@ucw.cz>2021-11-08 07:52:45 +0100
commit1f3a33633dd06a8e4861180ab20c9136361c69e6 (patch)
treed25e2b725823cf4a6055b9844dd82d65809425e7 /gcc/ipa-modref.c
parent14e355df30534b1d07018e2934948a09fa5a8e52 (diff)
downloadgcc-1f3a33633dd06a8e4861180ab20c9136361c69e6.zip
gcc-1f3a33633dd06a8e4861180ab20c9136361c69e6.tar.gz
gcc-1f3a33633dd06a8e4861180ab20c9136361c69e6.tar.bz2
Add loads/stores relative to static chain in ipa-modref
Adds tracking of accesses relative to static chain into modref load/stores analysis. This helps some Fortran benchmarks however it is still quite limited. One problem is that we never discover functions with nested functions as const, pure or not accessing global memory because it contains __builtin_dward_cfa call which we believe to be non-pure. Bootstrapped/regtested x86_64-linux. Plan to commit it tomorrow if there are no complains and once periodic testers picks today modref changes. Honza gcc/ChangeLog: * ipa-modref-tree.h (enum modref_special_parms): New enum. (struct modref_access_node): update for special parms. (struct modref_ref_node): Likewise. (struct modref_parm_map): Likewise. (struct modref_tree): Likewise. * ipa-modref.c (dump_access): Likewise. (get_access): Detect static chain. (parm_map_for_arg): Take tree as arg instead of stmt and index. (merge_call_side_effects): Compute map for static chain. (process_fnspec): Update. (struct escape_point): Remove retslot_arg and static_chain_arg. (analyze_parms): Update. (compute_parm_map): Update. (propagate_unknown_call): Update. (modref_propagate_in_scc): Update. (modref_merge_call_site_flags): Update. (ipa_merge_modref_summary_after_inlining): Update. * tree-ssa-alias.c (modref_may_conflict): Handle static chain. * ipa-modref-tree.c (test_merge): Update. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/modref-12.c: New test.
Diffstat (limited to 'gcc/ipa-modref.c')
-rw-r--r--gcc/ipa-modref.c152
1 files changed, 89 insertions, 63 deletions
diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c
index 4e64ee5..4429bce 100644
--- a/gcc/ipa-modref.c
+++ b/gcc/ipa-modref.c
@@ -426,9 +426,14 @@ static void
dump_access (modref_access_node *a, FILE *out)
{
fprintf (out, " access:");
- if (a->parm_index != -1)
+ if (a->parm_index != MODREF_UNKNOWN_PARM)
{
- fprintf (out, " Parm %i", a->parm_index);
+ if (a->parm_index >= 0)
+ fprintf (out, " Parm %i", a->parm_index);
+ else if (a->parm_index == MODREF_STATIC_CHAIN_PARM)
+ fprintf (out, " Static chain");
+ else
+ gcc_unreachable ();
if (a->parm_offset_known)
{
fprintf (out, " param offset:");
@@ -697,40 +702,40 @@ get_access (ao_ref *ref)
base = ao_ref_base (ref);
modref_access_node a = {ref->offset, ref->size, ref->max_size,
- 0, -1, false, 0};
+ 0, MODREF_UNKNOWN_PARM, false, 0};
if (TREE_CODE (base) == MEM_REF || TREE_CODE (base) == TARGET_MEM_REF)
{
tree memref = base;
base = TREE_OPERAND (base, 0);
+
if (TREE_CODE (base) == SSA_NAME
&& SSA_NAME_IS_DEFAULT_DEF (base)
&& TREE_CODE (SSA_NAME_VAR (base)) == PARM_DECL)
{
a.parm_index = 0;
- for (tree t = DECL_ARGUMENTS (current_function_decl);
- t != SSA_NAME_VAR (base); t = DECL_CHAIN (t))
- {
- if (!t)
- {
- a.parm_index = -1;
- break;
- }
- a.parm_index++;
- }
- if (TREE_CODE (memref) == MEM_REF)
- {
- a.parm_offset_known
- = wi::to_poly_wide (TREE_OPERAND
- (memref, 1)).to_shwi (&a.parm_offset);
- }
+ if (cfun->static_chain_decl
+ && base == ssa_default_def (cfun, cfun->static_chain_decl))
+ a.parm_index = MODREF_STATIC_CHAIN_PARM;
else
- a.parm_offset_known = false;
+ for (tree t = DECL_ARGUMENTS (current_function_decl);
+ t != SSA_NAME_VAR (base); t = DECL_CHAIN (t))
+ a.parm_index++;
+ }
+ else
+ a.parm_index = MODREF_UNKNOWN_PARM;
+
+ if (a.parm_index != MODREF_UNKNOWN_PARM
+ && TREE_CODE (memref) == MEM_REF)
+ {
+ a.parm_offset_known
+ = wi::to_poly_wide (TREE_OPERAND
+ (memref, 1)).to_shwi (&a.parm_offset);
}
else
- a.parm_index = -1;
+ a.parm_offset_known = false;
}
else
- a.parm_index = -1;
+ a.parm_index = MODREF_UNKNOWN_PARM;
return a;
}
@@ -858,12 +863,11 @@ ignore_stores_p (tree caller, int flags)
return false;
}
-/* Determine parm_map for argument I of STMT. */
+/* Determine parm_map for argument OP. */
modref_parm_map
-parm_map_for_arg (gimple *stmt, int i)
+parm_map_for_arg (tree op)
{
- tree op = gimple_call_arg (stmt, i);
bool offset_known;
poly_int64 offset;
struct modref_parm_map parm_map;
@@ -882,7 +886,7 @@ parm_map_for_arg (gimple *stmt, int i)
{
if (!t)
{
- index = -1;
+ index = MODREF_UNKNOWN_PARM;
break;
}
index++;
@@ -892,9 +896,9 @@ parm_map_for_arg (gimple *stmt, int i)
parm_map.parm_offset = offset;
}
else if (points_to_local_or_readonly_memory_p (op))
- parm_map.parm_index = -2;
+ parm_map.parm_index = MODREF_LOCAL_MEMORY_PARM;
else
- parm_map.parm_index = -1;
+ parm_map.parm_index = MODREF_UNKNOWN_PARM;
return parm_map;
}
@@ -911,6 +915,7 @@ merge_call_side_effects (modref_summary *cur_summary,
bool record_adjustments)
{
auto_vec <modref_parm_map, 32> parm_map;
+ modref_parm_map chain_map;
bool changed = false;
/* We can not safely optimize based on summary of callee if it does
@@ -931,7 +936,7 @@ merge_call_side_effects (modref_summary *cur_summary,
parm_map.safe_grow_cleared (gimple_call_num_args (stmt), true);
for (unsigned i = 0; i < gimple_call_num_args (stmt); i++)
{
- parm_map[i] = parm_map_for_arg (stmt, i);
+ parm_map[i] = parm_map_for_arg (gimple_call_arg (stmt, i));
if (dump_file)
{
fprintf (dump_file, " %i", parm_map[i].parm_index);
@@ -943,16 +948,30 @@ merge_call_side_effects (modref_summary *cur_summary,
}
}
}
+ if (gimple_call_chain (stmt))
+ {
+ chain_map = parm_map_for_arg (gimple_call_chain (stmt));
+ if (dump_file)
+ {
+ fprintf (dump_file, "static chain %i", chain_map.parm_index);
+ if (chain_map.parm_offset_known)
+ {
+ fprintf (dump_file, " offset:");
+ print_dec ((poly_int64_pod)chain_map.parm_offset,
+ dump_file, SIGNED);
+ }
+ }
+ }
if (dump_file)
fprintf (dump_file, "\n");
/* Merge with callee's summary. */
changed |= cur_summary->loads->merge (callee_summary->loads, &parm_map,
- record_adjustments);
+ &chain_map, record_adjustments);
if (!ignore_stores)
{
changed |= cur_summary->stores->merge (callee_summary->stores,
- &parm_map,
+ &parm_map, &chain_map,
record_adjustments);
if (!cur_summary->writes_errno
&& callee_summary->writes_errno)
@@ -1078,11 +1097,12 @@ process_fnspec (modref_summary *cur_summary,
else if (!fnspec.arg_specified_p (i)
|| fnspec.arg_maybe_read_p (i))
{
- modref_parm_map map = parm_map_for_arg (call, i);
+ modref_parm_map map = parm_map_for_arg
+ (gimple_call_arg (call, i));
- if (map.parm_index == -2)
+ if (map.parm_index == MODREF_LOCAL_MEMORY_PARM)
continue;
- if (map.parm_index == -1)
+ if (map.parm_index == MODREF_UNKNOWN_PARM)
{
collapse_loads (cur_summary, cur_summary_lto);
break;
@@ -1113,11 +1133,12 @@ process_fnspec (modref_summary *cur_summary,
else if (!fnspec.arg_specified_p (i)
|| fnspec.arg_maybe_written_p (i))
{
- modref_parm_map map = parm_map_for_arg (call, i);
+ modref_parm_map map = parm_map_for_arg
+ (gimple_call_arg (call, i));
- if (map.parm_index == -2)
+ if (map.parm_index == MODREF_LOCAL_MEMORY_PARM)
continue;
- if (map.parm_index == -1)
+ if (map.parm_index == MODREF_UNKNOWN_PARM)
{
collapse_stores (cur_summary, cur_summary_lto);
break;
@@ -1429,12 +1450,6 @@ deref_flags (int flags, bool ignore_stores)
struct escape_point
{
- /* Extra hidden args we keep track of. */
- enum hidden_args
- {
- retslot_arg = -1,
- static_chain_arg = -2
- };
/* Value escapes to this call. */
gcall *call;
/* Argument it escapes to. */
@@ -2410,7 +2425,7 @@ analyze_parms (modref_summary *summary, modref_summary_lto *summary_lto,
if (summary_lto)
summary_lto->retslot_flags = flags;
eaf_analysis.record_escape_points (retslot,
- escape_point::retslot_arg, flags);
+ MODREF_RETSLOT_PARM, flags);
}
}
if (static_chain)
@@ -2425,7 +2440,7 @@ analyze_parms (modref_summary *summary, modref_summary_lto *summary_lto,
if (summary_lto)
summary_lto->static_chain_flags = flags;
eaf_analysis.record_escape_points (static_chain,
- escape_point::static_chain_arg,
+ MODREF_STATIC_CHAIN_PARM,
flags);
}
}
@@ -3586,7 +3601,7 @@ compute_parm_map (cgraph_edge *callee_edge, vec<modref_parm_map> *parm_map)
{
if (es && es->param[i].points_to_local_or_readonly_memory)
{
- (*parm_map)[i].parm_index = -2;
+ (*parm_map)[i].parm_index = MODREF_LOCAL_MEMORY_PARM;
continue;
}
@@ -3600,7 +3615,7 @@ compute_parm_map (cgraph_edge *callee_edge, vec<modref_parm_map> *parm_map)
(callee_pi, i));
if (cst && points_to_local_or_readonly_memory_p (cst))
{
- (*parm_map)[i].parm_index = -2;
+ (*parm_map)[i].parm_index = MODREF_LOCAL_MEMORY_PARM;
continue;
}
}
@@ -3798,9 +3813,9 @@ propagate_unknown_call (cgraph_node *node,
|| fnspec.arg_maybe_read_p (i))
{
modref_parm_map map = parm_map[i];
- if (map.parm_index == -2)
+ if (map.parm_index == MODREF_LOCAL_MEMORY_PARM)
continue;
- if (map.parm_index == -1)
+ if (map.parm_index == MODREF_UNKNOWN_PARM)
{
collapse_loads (cur_summary, cur_summary_lto);
break;
@@ -3828,9 +3843,9 @@ propagate_unknown_call (cgraph_node *node,
|| fnspec.arg_maybe_written_p (i))
{
modref_parm_map map = parm_map[i];
- if (map.parm_index == -2)
+ if (map.parm_index == MODREF_LOCAL_MEMORY_PARM)
continue;
- if (map.parm_index == -1)
+ if (map.parm_index == MODREF_UNKNOWN_PARM)
{
collapse_stores (cur_summary, cur_summary_lto);
break;
@@ -4030,6 +4045,10 @@ modref_propagate_in_scc (cgraph_node *component_node)
auto_vec <modref_parm_map, 32> parm_map;
+ modref_parm_map chain_map;
+ /* TODO: Once we get jump functions for static chains we could
+ compute this. */
+ chain_map.parm_index = MODREF_UNKNOWN_PARM;
compute_parm_map (callee_edge, &parm_map);
@@ -4037,12 +4056,13 @@ modref_propagate_in_scc (cgraph_node *component_node)
if (callee_summary)
{
changed |= cur_summary->loads->merge
- (callee_summary->loads, &parm_map, !first);
+ (callee_summary->loads, &parm_map,
+ &chain_map, !first);
if (!ignore_stores)
{
changed |= cur_summary->stores->merge
(callee_summary->stores, &parm_map,
- !first);
+ &chain_map, !first);
if (!cur_summary->writes_errno
&& callee_summary->writes_errno)
{
@@ -4055,12 +4075,12 @@ modref_propagate_in_scc (cgraph_node *component_node)
{
changed |= cur_summary_lto->loads->merge
(callee_summary_lto->loads, &parm_map,
- !first);
+ &chain_map, !first);
if (!ignore_stores)
{
changed |= cur_summary_lto->stores->merge
(callee_summary_lto->stores, &parm_map,
- !first);
+ &chain_map, !first);
if (!cur_summary_lto->writes_errno
&& callee_summary_lto->writes_errno)
{
@@ -4223,9 +4243,9 @@ modref_merge_call_site_flags (escape_summary *sum,
if (!(flags & EAF_UNUSED)
&& cur_summary && ee->parm_index < (int)cur_summary->arg_flags.length ())
{
- eaf_flags_t &f = ee->parm_index == escape_point::retslot_arg
+ eaf_flags_t &f = ee->parm_index == MODREF_RETSLOT_PARM
? cur_summary->retslot_flags
- : ee->parm_index == escape_point::static_chain_arg
+ : ee->parm_index == MODREF_STATIC_CHAIN_PARM
? cur_summary->static_chain_flags
: cur_summary->arg_flags[ee->parm_index];
if ((f & flags) != f)
@@ -4240,9 +4260,9 @@ modref_merge_call_site_flags (escape_summary *sum,
&& cur_summary_lto
&& ee->parm_index < (int)cur_summary_lto->arg_flags.length ())
{
- eaf_flags_t &f = ee->parm_index == escape_point::retslot_arg
+ eaf_flags_t &f = ee->parm_index == MODREF_RETSLOT_PARM
? cur_summary_lto->retslot_flags
- : ee->parm_index == escape_point::static_chain_arg
+ : ee->parm_index == MODREF_STATIC_CHAIN_PARM
? cur_summary_lto->static_chain_flags
: cur_summary_lto->arg_flags[ee->parm_index];
if ((f & flags_lto) != f)
@@ -4428,24 +4448,30 @@ ipa_merge_modref_summary_after_inlining (cgraph_edge *edge)
if (callee_info || callee_info_lto)
{
auto_vec <modref_parm_map, 32> parm_map;
+ modref_parm_map chain_map;
+ /* TODO: Once we get jump functions for static chains we could
+ compute this. */
+ chain_map.parm_index = MODREF_UNKNOWN_PARM;
compute_parm_map (edge, &parm_map);
if (!ignore_stores)
{
if (to_info && callee_info)
- to_info->stores->merge (callee_info->stores, &parm_map, false);
+ to_info->stores->merge (callee_info->stores, &parm_map,
+ &chain_map, false);
if (to_info_lto && callee_info_lto)
to_info_lto->stores->merge (callee_info_lto->stores, &parm_map,
- false);
+ &chain_map, false);
}
if (!(flags & (ECF_CONST | ECF_NOVOPS)))
{
if (to_info && callee_info)
- to_info->loads->merge (callee_info->loads, &parm_map, false);
+ to_info->loads->merge (callee_info->loads, &parm_map,
+ &chain_map, false);
if (to_info_lto && callee_info_lto)
to_info_lto->loads->merge (callee_info_lto->loads, &parm_map,
- false);
+ &chain_map, false);
}
}