aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2020-04-02 17:52:38 +0200
committerMartin Jambor <mjambor@suse.cz>2020-04-02 17:52:38 +0200
commitb90061c6ec090c6b41a44987c646c828e5165298 (patch)
tree366ce819436620447d0b9af08181081b3c25a585
parent75efe9cb1f8938a713ce540dc3b27bc2afcd3fae (diff)
downloadgcc-b90061c6ec090c6b41a44987c646c828e5165298.zip
gcc-b90061c6ec090c6b41a44987c646c828e5165298.tar.gz
gcc-b90061c6ec090c6b41a44987c646c828e5165298.tar.bz2
Prevent IPA-SRA from creating calls to local comdats (PR 92676)
since r278669 (fix for PR ipa/91956), IPA-SRA makes sure that the clone it creates is put into the same same_comdat as the original cgraph_node, so that it can call private comdats (such as the ipa-split bits of a comdat that is private). However, that means that if there is non-comdat caller of a public comdat that is modified by IPA-SRA, it now finds itself calling a private comdat, which call graph verifier does not like (and for a reason, in theory it can disappear and since it is private it would not be available from other CUs). The patch fixes this by performing the fix for PR 91956 only when the node in question actually calls a local comdat and when it does, also making sure that no callers come from a different same_comdat (disabling IPA-SRA if both conditions are true), so that it plays by the rules in both modes, does not violate the private comdat calling rule and at the same time does not disable the transformation unnecessarily. The patch also fixes up the calls_comdat_local of callers of the modified node, despite that not triggering any known issues. 2020-04-02 Martin Jambor <mjambor@suse.cz> PR ipa/92676 * ipa-sra.c (struct caller_issues): New fields candidate and call_from_outside_comdat. (check_for_caller_issues): Check for calls from outsied of candidate's same_comdat_group. (check_all_callers_for_issues): Set up issues.candidate, check result of the new check. (mark_callers_calls_comdat_local): New function. (process_isra_node_results): Set calls_comdat_local of callers if appropriate.
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/ipa-sra.c38
2 files changed, 49 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4250204..e71466f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2020-04-02 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/92676
+ * ipa-sra.c (struct caller_issues): New fields candidate and
+ call_from_outside_comdat.
+ (check_for_caller_issues): Check for calls from outsied of
+ candidate's same_comdat_group.
+ (check_all_callers_for_issues): Set up issues.candidate, check result
+ of the new check.
+ (mark_callers_calls_comdat_local): New function.
+ (process_isra_node_results): Set calls_comdat_local of callers if
+ appropriate.
+
2020-04-02 Richard Biener <rguenther@suse.de>
PR c/94392
diff --git a/gcc/ipa-sra.c b/gcc/ipa-sra.c
index 31de527..f0ebaec 100644
--- a/gcc/ipa-sra.c
+++ b/gcc/ipa-sra.c
@@ -2897,10 +2897,14 @@ ipa_sra_ipa_function_checks (cgraph_node *node)
struct caller_issues
{
+ /* The candidate being considered. */
+ cgraph_node *candidate;
/* There is a thunk among callers. */
bool thunk;
/* Call site with no available information. */
bool unknown_callsite;
+ /* Call from outside the the candidate's comdat group. */
+ bool call_from_outside_comdat;
/* There is a bit-aligned load into one of non-gimple-typed arguments. */
bool bit_aligned_aggregate_argument;
};
@@ -2922,6 +2926,13 @@ check_for_caller_issues (struct cgraph_node *node, void *data)
thunks. */
return true;
}
+ if (issues->candidate->calls_comdat_local
+ && issues->candidate->same_comdat_group
+ && !issues->candidate->in_same_comdat_group_p (cs->caller))
+ {
+ issues->call_from_outside_comdat = true;
+ return true;
+ }
isra_call_summary *csum = call_sums->get (cs);
if (!csum)
@@ -2944,6 +2955,7 @@ check_all_callers_for_issues (cgraph_node *node)
{
struct caller_issues issues;
memset (&issues, 0, sizeof (issues));
+ issues.candidate = node;
node->call_for_symbol_and_aliases (check_for_caller_issues, &issues, true);
if (issues.unknown_callsite)
@@ -2962,6 +2974,13 @@ check_all_callers_for_issues (cgraph_node *node)
node->dump_name ());
return true;
}
+ if (issues.call_from_outside_comdat)
+ {
+ if (dump_file)
+ fprintf (dump_file, "Function would become private comdat called "
+ "outside of its comdat group.\n");
+ return true;
+ }
if (issues.bit_aligned_aggregate_argument)
{
@@ -3679,6 +3698,17 @@ push_param_adjustments_for_index (isra_func_summary *ifs, unsigned base_index,
}
}
+/* Worker for all call_for_symbol_thunks_and_aliases. Set calls_comdat_local
+ flag of all callers of NODE. */
+
+static bool
+mark_callers_calls_comdat_local (struct cgraph_node *node, void *)
+{
+ for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller)
+ cs->caller->calls_comdat_local = true;
+ return false;
+}
+
/* Do final processing of results of IPA propagation regarding NODE, clone it
if appropriate. */
@@ -3763,8 +3793,12 @@ process_isra_node_results (cgraph_node *node,
= node->create_virtual_clone (callers, NULL, new_adjustments, "isra",
suffix_counter);
suffix_counter++;
- if (node->same_comdat_group)
- new_node->add_to_same_comdat_group (node);
+ if (node->calls_comdat_local && node->same_comdat_group)
+ {
+ new_node->add_to_same_comdat_group (node);
+ new_node->call_for_symbol_and_aliases (mark_callers_calls_comdat_local,
+ NULL, true);
+ }
new_node->calls_comdat_local = node->calls_comdat_local;
if (dump_file)