aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/cgraphunit.c52
-rw-r--r--gcc/ipa-icf.c44
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-icf-32.c24
-rw-r--r--gcc/tree.h10
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" } } */
diff --git a/gcc/tree.h b/gcc/tree.h
index 3e74c7e..e9af9bf 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -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)