Commit 3f9f4ae7 by Martin Liska Committed by Martin Liska

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
parent 56f6033d
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> 2015-01-09 Tom de Vries <tom@codesourcery.com>
* omp-low.c (expand_omp_for_static_chunk): Fix assert. * omp-low.c (expand_omp_for_static_chunk): Fix assert.
......
...@@ -2385,40 +2385,40 @@ cgraphunit_c_finalize (void) ...@@ -2385,40 +2385,40 @@ cgraphunit_c_finalize (void)
void void
cgraph_node::create_wrapper (cgraph_node *target) cgraph_node::create_wrapper (cgraph_node *target)
{ {
/* Preserve DECL_RESULT so we get right by reference flag. */ /* Preserve DECL_RESULT so we get right by reference flag. */
tree decl_result = DECL_RESULT (decl); tree decl_result = DECL_RESULT (decl);
/* Remove the function's body but keep arguments to be reused /* Remove the function's body but keep arguments to be reused
for thunk. */ for thunk. */
release_body (true); release_body (true);
reset (); reset ();
DECL_RESULT (decl) = decl_result; DECL_RESULT (decl) = decl_result;
DECL_INITIAL (decl) = NULL; DECL_INITIAL (decl) = NULL;
allocate_struct_function (decl, false); allocate_struct_function (decl, false);
set_cfun (NULL); set_cfun (NULL);
/* Turn alias into thunk and expand it into GIMPLE representation. */ /* Turn alias into thunk and expand it into GIMPLE representation. */
definition = true; definition = true;
thunk.thunk_p = true; thunk.thunk_p = true;
thunk.this_adjusting = false; 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) while (arguments)
{ {
TREE_ADDRESSABLE (arguments) = false; TREE_ADDRESSABLE (arguments) = false;
arguments = TREE_CHAIN (arguments); arguments = TREE_CHAIN (arguments);
} }
expand_thunk (false, true); expand_thunk (false, true);
e->call_stmt_cannot_inline_p = true; e->call_stmt_cannot_inline_p = true;
/* Inline summary set-up. */ /* Inline summary set-up. */
analyze (); analyze ();
inline_analyze_function (this); inline_analyze_function (this);
} }
#include "gt-cgraphunit.h" #include "gt-cgraphunit.h"
...@@ -427,6 +427,49 @@ sem_function::equals_private (sem_item *item, ...@@ -427,6 +427,49 @@ sem_function::equals_private (sem_item *item,
if (!equals_wpa (item, ignored_nodes)) if (!equals_wpa (item, ignored_nodes))
return false; 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. */ /* Checking function arguments. */
tree decl1 = DECL_ATTRIBUTES (decl); tree decl1 = DECL_ATTRIBUTES (decl);
tree decl2 = DECL_ATTRIBUTES (m_compared_func->decl); tree decl2 = DECL_ATTRIBUTES (m_compared_func->decl);
...@@ -2302,7 +2345,6 @@ sem_item_optimizer::merge_classes (unsigned int prev_class_count) ...@@ -2302,7 +2345,6 @@ sem_item_optimizer::merge_classes (unsigned int prev_class_count)
for (unsigned int j = 1; j < c->members.length (); j++) for (unsigned int j = 1; j < c->members.length (); j++)
{ {
sem_item *alias = c->members[j]; sem_item *alias = c->members[j];
source->equals (alias, m_symtab_node_map);
if (dump_file) if (dump_file)
{ {
......
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> 2015-01-08 Bernd Edlinger <bernd.edlinger@hotmail.de>
* c-c++-common/tsan/tsan_barrier.h: New. * c-c++-common/tsan/tsan_barrier.h: New.
......
/* { 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) ...@@ -4671,6 +4671,16 @@ opts_for_fn (const_tree fndecl)
return TREE_OPTIMIZATION (fn_opts); 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 /* opt flag for function FNDECL, e.g. opts_for_fn (fndecl, optimize) is
the optimization level of function fndecl. */ the optimization level of function fndecl. */
#define opt_for_fn(fndecl, opt) (opts_for_fn (fndecl)->x_##opt) #define opt_for_fn(fndecl, opt) (opts_for_fn (fndecl)->x_##opt)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment