Skip to content

Commit

Permalink
ipa-sra: Move caller->callee propagation before callee->caller one
Browse files Browse the repository at this point in the history
Hi,

I'm re-posting patches which I have posted at the end of stage 1 but
which have not passed review yet.

8<--------------------------------------------------------------------

This patch does not do any functional changes, it merely moves
top-down propagation in the IPA-SRA WPA phase before bottom-up one.
This also meant moving some preliminary checks from the latter to the
former - where they need to be in their own loop over each SCC because
the subsequent one looks at callers.

Currently the propagations are independent (top-down is used for
return value rermoval, bottom-up for parameter removal and splitting)
but subsequent patches will introduce flags about parameters which
should be propagated from callers first and used in splitting.  I
separated this change to test ir independently and make those
subsequent patches cleaner.

While at it, I also replaced couple of FOR_EACH_VEC_ELT macros with
C++11 style iteration.

Bootstrapped and tested individually when I originally posted it and
now bootstrapped and LTO-bootstrapped and tested as part of the whole
series.  OK for master?

gcc/ChangeLog:

2022-11-11  Martin Jambor  <mjambor@suse.cz>

	* ipa-sra.c (ipa_sra_analysis): Move top-down analysis before
	bottom-up analysis.  Replace FOR_EACH_VEC_ELT with C++11 iteration.

gcc/testsuite/ChangeLog:

2021-12-14  Martin Jambor  <mjambor@suse.cz>

	* gcc.dg/ipa/ipa-sra-25.c: New test
  • Loading branch information
jamborm authored and ouuleilei-bot committed Dec 12, 2022
1 parent 8ee5084 commit 814baf3
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 62 deletions.
123 changes: 61 additions & 62 deletions gcc/ipa-sra.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3925,27 +3925,74 @@ ipa_sra_analysis (void)
auto_vec <cgraph_node *, 16> stack;
int node_scc_count = ipa_reduced_postorder (order, true, NULL);

/* One sweep from callees to callers for parameter removal and splitting. */
for (int i = 0; i < node_scc_count; i++)
/* One sweep from callers to callees for return value removal. */
for (int i = node_scc_count - 1; i >= 0 ; i--)
{
cgraph_node *scc_rep = order[i];
vec<cgraph_node *> cycle_nodes = ipa_get_nodes_in_cycle (scc_rep);
unsigned j;

/* Preliminary IPA function level checks and first step of parameter
removal. */
cgraph_node *v;
FOR_EACH_VEC_ELT (cycle_nodes, j, v)
/* Preliminary IPA function level checks. */
for (cgraph_node *v : cycle_nodes)
{
isra_func_summary *ifs = func_sums->get (v);
if (!ifs || !ifs->m_candidate)
continue;
if (!ipa_sra_ipa_function_checks (v)
|| check_all_callers_for_issues (v))
{
ifs->zap ();
continue;
}
ifs->zap ();
}

for (cgraph_node *v : cycle_nodes)
{
isra_func_summary *ifs = func_sums->get (v);
if (!ifs || !ifs->m_candidate)
continue;
bool return_needed
= (ifs->m_returns_value
&& (!dbg_cnt (ipa_sra_retvalues)
|| v->call_for_symbol_and_aliases (retval_used_p,
NULL, true)));
ifs->m_return_ignored = !return_needed;
if (return_needed)
isra_push_node_to_stack (v, ifs, &stack);
}

while (!stack.is_empty ())
{
cgraph_node *node = stack.pop ();
isra_func_summary *ifs = func_sums->get (node);
gcc_checking_assert (ifs && ifs->m_queued);
ifs->m_queued = false;

for (cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
if (ipa_edge_within_scc (cs)
&& call_sums->get (cs)->m_return_returned)
{
enum availability av;
cgraph_node *callee = cs->callee->function_symbol (&av);
isra_func_summary *to_ifs = func_sums->get (callee);
if (to_ifs && to_ifs->m_return_ignored)
{
to_ifs->m_return_ignored = false;
isra_push_node_to_stack (callee, to_ifs, &stack);
}
}
}
cycle_nodes.release ();
}

/* One sweep from callees to callers for parameter removal and splitting. */
for (int i = 0; i < node_scc_count; i++)
{
cgraph_node *scc_rep = order[i];
vec<cgraph_node *> cycle_nodes = ipa_get_nodes_in_cycle (scc_rep);

/* First step of parameter removal. */
for (cgraph_node *v : cycle_nodes)
{
isra_func_summary *ifs = func_sums->get (v);
if (!ifs || !ifs->m_candidate)
continue;
if (disable_unavailable_parameters (v, ifs))
continue;
for (cgraph_edge *cs = v->indirect_calls; cs; cs = cs->next_callee)
Expand All @@ -3958,7 +4005,7 @@ ipa_sra_analysis (void)
/* Look at edges within the current SCC and propagate used-ness across
them, pushing onto the stack all notes which might need to be
revisited. */
FOR_EACH_VEC_ELT (cycle_nodes, j, v)
for (cgraph_node *v : cycle_nodes)
v->call_for_symbol_thunks_and_aliases (propagate_used_to_scc_callers,
&stack, true);

Expand All @@ -3979,7 +4026,7 @@ ipa_sra_analysis (void)
do
{
repeat_scc_access_propagation = false;
FOR_EACH_VEC_ELT (cycle_nodes, j, v)
for (cgraph_node *v : cycle_nodes)
{
isra_func_summary *ifs = func_sums->get (v);
if (!ifs
Expand All @@ -3994,60 +4041,12 @@ ipa_sra_analysis (void)
while (repeat_scc_access_propagation);

if (flag_checking)
FOR_EACH_VEC_ELT (cycle_nodes, j, v)
for (cgraph_node *v : cycle_nodes)
verify_splitting_accesses (v, true);

cycle_nodes.release ();
}

/* One sweep from caller to callees for result removal. */
for (int i = node_scc_count - 1; i >= 0 ; i--)
{
cgraph_node *scc_rep = order[i];
vec<cgraph_node *> cycle_nodes = ipa_get_nodes_in_cycle (scc_rep);
unsigned j;

cgraph_node *v;
FOR_EACH_VEC_ELT (cycle_nodes, j, v)
{
isra_func_summary *ifs = func_sums->get (v);
if (!ifs || !ifs->m_candidate)
continue;

bool return_needed
= (ifs->m_returns_value
&& (!dbg_cnt (ipa_sra_retvalues)
|| v->call_for_symbol_and_aliases (retval_used_p,
NULL, true)));
ifs->m_return_ignored = !return_needed;
if (return_needed)
isra_push_node_to_stack (v, ifs, &stack);
}

while (!stack.is_empty ())
{
cgraph_node *node = stack.pop ();
isra_func_summary *ifs = func_sums->get (node);
gcc_checking_assert (ifs && ifs->m_queued);
ifs->m_queued = false;

for (cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
if (ipa_edge_within_scc (cs)
&& call_sums->get (cs)->m_return_returned)
{
enum availability av;
cgraph_node *callee = cs->callee->function_symbol (&av);
isra_func_summary *to_ifs = func_sums->get (callee);
if (to_ifs && to_ifs->m_return_ignored)
{
to_ifs->m_return_ignored = false;
isra_push_node_to_stack (callee, to_ifs, &stack);
}
}
}
cycle_nodes.release ();
}

ipa_free_postorder_info ();
free (order);

Expand Down
17 changes: 17 additions & 0 deletions gcc/testsuite/gcc.dg/ipa/ipa-sra-25.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* { dg-do compile } */
/* { dg-options "-O2 -Wmaybe-uninitialized -Werror" } */

int cbos();
static int aos() {
cbos();
return 0;
}
int cbos_ptr;
long cbos_psize;
int cbos() {
if (cbos_ptr)
return aos();
if (cbos_psize)
return 1;
return 0;
}

0 comments on commit 814baf3

Please sign in to comment.