diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2014-05-16 19:49:06 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2014-05-16 17:49:06 +0000 |
commit | 6de88c6a1c7fb017720cf79a6f93e52221afdfb8 (patch) | |
tree | 95128482337699b940df1c3ea7402e38fb4ecb88 /gcc/ipa.c | |
parent | 54674a35bd0a8d231ad314064d5f7bb8a60ef5df (diff) | |
download | gcc-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.c | 114 |
1 files changed, 91 insertions, 23 deletions
@@ -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) |