aboutsummaryrefslogtreecommitdiff
path: root/gcc/ipa.c
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2014-05-16 19:49:06 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2014-05-16 17:49:06 +0000
commit6de88c6a1c7fb017720cf79a6f93e52221afdfb8 (patch)
tree95128482337699b940df1c3ea7402e38fb4ecb88 /gcc/ipa.c
parent54674a35bd0a8d231ad314064d5f7bb8a60ef5df (diff)
downloadgcc-6de88c6a1c7fb017720cf79a6f93e52221afdfb8.zip
gcc-6de88c6a1c7fb017720cf79a6f93e52221afdfb8.tar.gz
gcc-6de88c6a1c7fb017720cf79a6f93e52221afdfb8.tar.bz2
varpool.c (dump_varpool_node): Dump write-only flag.
* varpool.c (dump_varpool_node): Dump write-only flag. * lto-cgraph.c (lto_output_varpool_node, input_varpool_node): Stream write-only flag. * tree-cfg.c (execute_fixup_cfg): Remove statements setting write-only variables. * gcc.c-torture/execute/20101011-1.c: Update testcase. * gcc.dg/ira-shrinkwrap-prep-1.c: Update testcase. * gcc.dg/tree-ssa/writeonly.c: New testcase. * gcc.dg/tree-ssa/ssa-dse-6.c: Update testcase. * gcc.dg/tree-ssa/pr21559.c: Update testcase. * gcc.dg/debug/pr35154.c: Update testcase. * gcc.target/i386/vectorize1.c: Update testcase. * ipa.c (process_references): New function. (set_readonly_bit): New function. (set_writeonly_bit): New function. (clear_addressable_bit): New function. (ipa_discover_readonly_nonaddressable_var): Mark write only variables; fix handling of aliases. * cgraph.h (struct varpool_node): Add writeonly flag. From-SVN: r210522
Diffstat (limited to 'gcc/ipa.c')
-rw-r--r--gcc/ipa.c114
1 files changed, 91 insertions, 23 deletions
diff --git a/gcc/ipa.c b/gcc/ipa.c
index a14f024..da42491 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -624,6 +624,77 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
return changed;
}
+/* Process references to VNODE and set flags WRITTEN, ADDRESS_TAKEN, READ
+ as needed, also clear EXPLICIT_REFS if the references to given variable
+ do not need to be explicit. */
+
+void
+process_references (varpool_node *vnode,
+ bool *written, bool *address_taken,
+ bool *read, bool *explicit_refs)
+{
+ int i;
+ struct ipa_ref *ref;
+
+ if (!varpool_all_refs_explicit_p (vnode)
+ || TREE_THIS_VOLATILE (vnode->decl))
+ *explicit_refs = false;
+
+ for (i = 0; ipa_ref_list_referring_iterate (&vnode->ref_list,
+ i, ref)
+ && *explicit_refs && (!*written || !*address_taken || !*read); i++)
+ switch (ref->use)
+ {
+ case IPA_REF_ADDR:
+ *address_taken = true;
+ break;
+ case IPA_REF_LOAD:
+ *read = true;
+ break;
+ case IPA_REF_STORE:
+ *written = true;
+ break;
+ case IPA_REF_ALIAS:
+ process_references (varpool (ref->referring), written, address_taken,
+ read, explicit_refs);
+ break;
+ }
+}
+
+/* Set TREE_READONLY bit. */
+
+bool
+set_readonly_bit (varpool_node *vnode, void *data ATTRIBUTE_UNUSED)
+{
+ TREE_READONLY (vnode->decl) = true;
+ return false;
+}
+
+/* Set writeonly bit and clear the initalizer, since it will not be needed. */
+
+bool
+set_writeonly_bit (varpool_node *vnode, void *data ATTRIBUTE_UNUSED)
+{
+ vnode->writeonly = true;
+ if (optimize)
+ {
+ DECL_INITIAL (vnode->decl) = NULL;
+ if (!vnode->alias)
+ ipa_remove_all_references (&vnode->ref_list);
+ }
+ return false;
+}
+
+/* Clear addressale bit of VNODE. */
+
+bool
+clear_addressable_bit (varpool_node *vnode, void *data ATTRIBUTE_UNUSED)
+{
+ vnode->address_taken = false;
+ TREE_ADDRESSABLE (vnode->decl) = 0;
+ return false;
+}
+
/* Discover variables that have no longer address taken or that are read only
and update their flags.
@@ -640,43 +711,40 @@ ipa_discover_readonly_nonaddressable_vars (void)
if (dump_file)
fprintf (dump_file, "Clearing variable flags:");
FOR_EACH_VARIABLE (vnode)
- if (vnode->definition && varpool_all_refs_explicit_p (vnode)
+ if (!vnode->alias
&& (TREE_ADDRESSABLE (vnode->decl)
+ || !vnode->writeonly
|| !TREE_READONLY (vnode->decl)))
{
bool written = false;
bool address_taken = false;
- int i;
- struct ipa_ref *ref;
- for (i = 0; ipa_ref_list_referring_iterate (&vnode->ref_list,
- i, ref)
- && (!written || !address_taken); i++)
- switch (ref->use)
- {
- case IPA_REF_ADDR:
- address_taken = true;
- break;
- case IPA_REF_LOAD:
- break;
- case IPA_REF_STORE:
- written = true;
- break;
- }
- if (TREE_ADDRESSABLE (vnode->decl) && !address_taken)
+ bool read = false;
+ bool explicit_refs = true;
+
+ process_references (vnode, &written, &address_taken, &read, &explicit_refs);
+ if (!explicit_refs)
+ continue;
+ if (!address_taken)
{
- if (dump_file)
+ if (TREE_ADDRESSABLE (vnode->decl) && dump_file)
fprintf (dump_file, " %s (addressable)", vnode->name ());
- TREE_ADDRESSABLE (vnode->decl) = 0;
+ varpool_for_node_and_aliases (vnode, clear_addressable_bit, NULL, true);
}
- if (!TREE_READONLY (vnode->decl) && !address_taken && !written
+ if (!address_taken && !written
/* Making variable in explicit section readonly can cause section
type conflict.
See e.g. gcc.c-torture/compile/pr23237.c */
&& DECL_SECTION_NAME (vnode->decl) == NULL)
{
- if (dump_file)
+ if (!TREE_READONLY (vnode->decl) && dump_file)
fprintf (dump_file, " %s (read-only)", vnode->name ());
- TREE_READONLY (vnode->decl) = 1;
+ varpool_for_node_and_aliases (vnode, set_readonly_bit, NULL, true);
+ }
+ if (!vnode->writeonly && !read && !address_taken)
+ {
+ if (dump_file)
+ fprintf (dump_file, " %s (write-only)", vnode->name ());
+ varpool_for_node_and_aliases (vnode, set_writeonly_bit, NULL, true);
}
}
if (dump_file)