diff options
author | Martin Liska <mliska@suse.cz> | 2015-01-09 11:33:00 +0100 |
---|---|---|
committer | Martin Liska <marxin@gcc.gnu.org> | 2015-01-09 10:33:00 +0000 |
commit | 3f9f4ae70554ee0f7b756fc1d811aefb6e70f076 (patch) | |
tree | 1c877e5ceb75376cc425d2d78971a217c753a79c /gcc | |
parent | 56f6033d2bc75b90a1006b5245a8da338224506d (diff) | |
download | gcc-3f9f4ae70554ee0f7b756fc1d811aefb6e70f076.zip gcc-3f9f4ae70554ee0f7b756fc1d811aefb6e70f076.tar.gz gcc-3f9f4ae70554ee0f7b756fc1d811aefb6e70f076.tar.bz2 |
IPA ICF: target and optimization flags comparison.
* cgraphunit.c (cgraph_node::create_wrapper): Fix level of indentation.
* ipa-icf.c (sem_function::equals_private): Add support for target and
(sem_item_optimizer::merge_classes): Remove redundant function
optimization flags comparison.
* tree.h (target_opts_for_fn): New function.
* gcc.dg/ipa/ipa-icf-32.c: New test.
From-SVN: r219377
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cgraphunit.c | 52 | ||||
-rw-r--r-- | gcc/ipa-icf.c | 44 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/ipa/ipa-icf-32.c | 24 | ||||
-rw-r--r-- | gcc/tree.h | 10 |
6 files changed, 115 insertions, 27 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d3d121d..eb69b39 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2015-01-09 Martin Liska <mliska@suse.cz> + + * cgraphunit.c (cgraph_node::create_wrapper): Fix level of indentation. + * ipa-icf.c (sem_function::equals_private): Add support for target and + (sem_item_optimizer::merge_classes): Remove redundant function + optimization flags comparison. + * tree.h (target_opts_for_fn): New function. + 2015-01-09 Tom de Vries <tom@codesourcery.com> * omp-low.c (expand_omp_for_static_chunk): Fix assert. diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index c8c8562..81246e2 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -2385,40 +2385,40 @@ cgraphunit_c_finalize (void) void cgraph_node::create_wrapper (cgraph_node *target) { - /* Preserve DECL_RESULT so we get right by reference flag. */ - tree decl_result = DECL_RESULT (decl); + /* Preserve DECL_RESULT so we get right by reference flag. */ + tree decl_result = DECL_RESULT (decl); - /* Remove the function's body but keep arguments to be reused - for thunk. */ - release_body (true); - reset (); + /* Remove the function's body but keep arguments to be reused + for thunk. */ + release_body (true); + reset (); - DECL_RESULT (decl) = decl_result; - DECL_INITIAL (decl) = NULL; - allocate_struct_function (decl, false); - set_cfun (NULL); + DECL_RESULT (decl) = decl_result; + DECL_INITIAL (decl) = NULL; + allocate_struct_function (decl, false); + set_cfun (NULL); - /* Turn alias into thunk and expand it into GIMPLE representation. */ - definition = true; - thunk.thunk_p = true; - thunk.this_adjusting = false; + /* Turn alias into thunk and expand it into GIMPLE representation. */ + definition = true; + thunk.thunk_p = true; + thunk.this_adjusting = false; - cgraph_edge *e = create_edge (target, NULL, 0, CGRAPH_FREQ_BASE); + cgraph_edge *e = create_edge (target, NULL, 0, CGRAPH_FREQ_BASE); - tree arguments = DECL_ARGUMENTS (decl); + tree arguments = DECL_ARGUMENTS (decl); - while (arguments) - { - TREE_ADDRESSABLE (arguments) = false; - arguments = TREE_CHAIN (arguments); - } + while (arguments) + { + TREE_ADDRESSABLE (arguments) = false; + arguments = TREE_CHAIN (arguments); + } - expand_thunk (false, true); - e->call_stmt_cannot_inline_p = true; + expand_thunk (false, true); + e->call_stmt_cannot_inline_p = true; - /* Inline summary set-up. */ - analyze (); - inline_analyze_function (this); + /* Inline summary set-up. */ + analyze (); + inline_analyze_function (this); } #include "gt-cgraphunit.h" diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c index c7ba75a..28158b3 100644 --- a/gcc/ipa-icf.c +++ b/gcc/ipa-icf.c @@ -427,6 +427,49 @@ sem_function::equals_private (sem_item *item, if (!equals_wpa (item, ignored_nodes)) return false; + /* Checking function TARGET and OPTIMIZATION flags. */ + cl_target_option *tar1 = target_opts_for_fn (decl); + cl_target_option *tar2 = target_opts_for_fn (m_compared_func->decl); + + if (tar1 != NULL || tar2 != NULL) + { + if (!cl_target_option_eq (tar1, tar2)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Source target flags\n"); + cl_target_option_print (dump_file, 2, tar1); + fprintf (dump_file, "Target target flags\n"); + cl_target_option_print (dump_file, 2, tar2); + } + + return return_false_with_msg ("Target flags are different"); + } + } + else if (tar1 != NULL || tar2 != NULL) + return return_false_with_msg ("Target flags are different"); + + cl_optimization *opt1 = opts_for_fn (decl); + cl_optimization *opt2 = opts_for_fn (m_compared_func->decl); + + if (opt1 != NULL && opt2 != NULL) + { + if (memcmp (opt1, opt2, sizeof(cl_optimization))) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Source optimization flags\n"); + cl_optimization_print (dump_file, 2, opt1); + fprintf (dump_file, "Target optimization flags\n"); + cl_optimization_print (dump_file, 2, opt2); + } + + return return_false_with_msg ("optimization flags are different"); + } + } + else if (opt1 != NULL || opt2 != NULL) + return return_false_with_msg ("optimization flags are different"); + /* Checking function arguments. */ tree decl1 = DECL_ATTRIBUTES (decl); tree decl2 = DECL_ATTRIBUTES (m_compared_func->decl); @@ -2302,7 +2345,6 @@ sem_item_optimizer::merge_classes (unsigned int prev_class_count) for (unsigned int j = 1; j < c->members.length (); j++) { sem_item *alias = c->members[j]; - source->equals (alias, m_symtab_node_map); if (dump_file) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bc1c52c..b1aff26 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2015-01-09 Martin Liska <mliska@suse.cz> + + * gcc.dg/ipa/ipa-icf-32.c: New test. + 2015-01-08 Bernd Edlinger <bernd.edlinger@hotmail.de> * c-c++-common/tsan/tsan_barrier.h: New. diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-32.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-32.c new file mode 100644 index 0000000..22544a7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-32.c @@ -0,0 +1,24 @@ +/* { dg-do run } */ +/* { dg-options "-O0 -fipa-icf -fdump-ipa-icf-details" } */ + +int +__attribute__((optimize("O0"), noinline, noclone)) +foo(int a) +{ + return a * a; +} + +__attribute__ ((noinline, noclone)) +int bar(int b) +{ + return b * b; +} + +int main() +{ + return foo (0) + bar (0); +} + +/* { dg-final { scan-ipa-dump "optimization flags are different" "icf" } } */ +/* { dg-final { scan-ipa-dump "Equal symbols: 0" "icf" } } */ +/* { dg-final { cleanup-ipa-dump "icf" } } */ @@ -4671,6 +4671,16 @@ opts_for_fn (const_tree fndecl) return TREE_OPTIMIZATION (fn_opts); } +/* Return pointer to target flags of FNDECL. */ +static inline cl_target_option * +target_opts_for_fn (const_tree fndecl) +{ + tree fn_opts = DECL_FUNCTION_SPECIFIC_TARGET (fndecl); + if (fn_opts == NULL_TREE) + fn_opts = target_option_default_node; + return TREE_TARGET_OPTION (fn_opts); +} + /* opt flag for function FNDECL, e.g. opts_for_fn (fndecl, optimize) is the optimization level of function fndecl. */ #define opt_for_fn(fndecl, opt) (opts_for_fn (fndecl)->x_##opt) |