aboutsummaryrefslogtreecommitdiff
path: root/gcc/ipa-reference.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ipa-reference.c')
-rw-r--r--gcc/ipa-reference.c52
1 files changed, 46 insertions, 6 deletions
diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c
index 64ccb4e..96482f1 100644
--- a/gcc/ipa-reference.c
+++ b/gcc/ipa-reference.c
@@ -200,6 +200,8 @@ ipa_reference_get_not_read_global (struct cgraph_node *fn)
info = get_reference_optimization_summary (fn);
if (info)
return info->statics_not_read;
+ else if (flags_from_decl_or_type (fn->decl) & ECF_LEAF)
+ return all_module_statics;
else
return NULL;
}
@@ -217,6 +219,8 @@ ipa_reference_get_not_written_global (struct cgraph_node *fn)
info = get_reference_optimization_summary (fn);
if (info)
return info->statics_not_written;
+ else if (flags_from_decl_or_type (fn->decl) & ECF_LEAF)
+ return all_module_statics;
else
return NULL;
}
@@ -299,9 +303,13 @@ propagate_bits (ipa_reference_global_vars_info_t x_global, struct cgraph_node *x
for (e = x->callees; e; e = e->next_callee)
{
struct cgraph_node *y = e->callee;
+ enum availability avail;
+ avail = cgraph_function_body_availability (e->callee);
/* Only look into nodes we can propagate something. */
- if (cgraph_function_body_availability (e->callee) > AVAIL_OVERWRITABLE)
+ if (avail > AVAIL_OVERWRITABLE
+ || (avail == AVAIL_OVERWRITABLE
+ && (flags_from_decl_or_type (e->callee->decl) & ECF_LEAF)))
{
int flags = flags_from_decl_or_type (e->callee->decl);
if (get_reference_vars_info (y))
@@ -573,17 +581,28 @@ read_write_all_from_decl (struct cgraph_node *node, bool * read_all,
{
tree decl = node->decl;
int flags = flags_from_decl_or_type (decl);
- if (flags & ECF_CONST)
+ if ((flags & ECF_LEAF)
+ && cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
+ ;
+ else if (flags & ECF_CONST)
;
else if ((flags & ECF_PURE)
|| cgraph_node_cannot_return (node))
- *read_all = true;
+ {
+ *read_all = true;
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, " %s/%i -> read all\n",
+ cgraph_node_name (node), node->uid);
+ }
else
{
/* TODO: To be able to produce sane results, we should also handle
common builtins, in particular throw. */
*read_all = true;
*write_all = true;
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, " %s/%i -> read all, write all\n",
+ cgraph_node_name (node), node->uid);
}
}
@@ -629,6 +648,11 @@ propagate (void)
node_info = get_reference_vars_info (node);
gcc_assert (node_info);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Starting cycle with %s/%i\n",
+ cgraph_node_name (node), node->uid);
+
node_l = &node_info->local;
node_g = &node_info->global;
@@ -647,9 +671,15 @@ propagate (void)
if (!(ie->indirect_info->ecf_flags & ECF_CONST))
{
read_all = true;
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, " indirect call -> read all\n");
if (!cgraph_edge_cannot_lead_to_return (ie)
&& !(ie->indirect_info->ecf_flags & ECF_PURE))
- write_all = true;
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, " indirect call -> write all\n");
+ write_all = true;
+ }
}
@@ -659,6 +689,9 @@ propagate (void)
w = w_info->next_cycle;
while (w && (!read_all || !write_all))
{
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, " Visiting %s/%i\n",
+ cgraph_node_name (w), w->uid);
/* When function is overwrittable, we can not assume anything. */
if (cgraph_function_body_availability (w) <= AVAIL_OVERWRITABLE)
read_write_all_from_decl (w, &read_all, &write_all);
@@ -671,9 +704,15 @@ propagate (void)
if (!(ie->indirect_info->ecf_flags & ECF_CONST))
{
read_all = true;
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, " indirect call -> read all\n");
if (!cgraph_edge_cannot_lead_to_return (ie)
&& !(ie->indirect_info->ecf_flags & ECF_PURE))
- write_all = true;
+ {
+ write_all = true;
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, " indirect call -> write all\n");
+ }
}
w_info = (struct ipa_dfs_info *) w->aux;
@@ -841,7 +880,8 @@ propagate (void)
continue;
node_info = get_reference_vars_info (node);
- if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE)
+ if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE
+ || (flags_from_decl_or_type (node->decl) & ECF_LEAF))
{
node_g = &node_info->global;