Commit b0fd4d7e by Martin Jambor Committed by Martin Jambor

[PR 77333] Fixup fntypes of gimple calls of clones

2017-03-30  Martin Jambor  <mjambor@suse.cz>

	PR ipa/77333
	* cgraph.h (cgraph_build_function_type_skip_args): Declare.
	* cgraph.c (redirect_call_stmt_to_callee): Set gimple fntype so that
	it reflects the signature changes performed at the callee side.
	* cgraphclones.c (build_function_type_skip_args): Make public, renamed
	to cgraph_build_function_type_skip_args.
	(build_function_decl_skip_args): Adjust call to the above function.

testsuite/
	* g++.dg/ipa/pr77333.C: New test.

From-SVN: r246589
parent de008ec4
2017-03-30 Martin Jambor <mjambor@suse.cz>
PR ipa/77333
* cgraph.h (cgraph_build_function_type_skip_args): Declare.
* cgraph.c (redirect_call_stmt_to_callee): Set gimple fntype so that
it reflects the signature changes performed at the callee side.
* cgraphclones.c (build_function_type_skip_args): Make public, renamed
to cgraph_build_function_type_skip_args.
(build_function_decl_skip_args): Adjust call to the above function.
2017-03-30 Jakub Jelinek <jakub@redhat.com> 2017-03-30 Jakub Jelinek <jakub@redhat.com>
PR target/80206 PR target/80206
......
...@@ -1424,8 +1424,23 @@ cgraph_edge::redirect_call_stmt_to_callee (void) ...@@ -1424,8 +1424,23 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
if (skip_bounds) if (skip_bounds)
new_stmt = chkp_copy_call_skip_bounds (new_stmt); new_stmt = chkp_copy_call_skip_bounds (new_stmt);
tree old_fntype = gimple_call_fntype (e->call_stmt);
gimple_call_set_fndecl (new_stmt, e->callee->decl); gimple_call_set_fndecl (new_stmt, e->callee->decl);
gimple_call_set_fntype (new_stmt, gimple_call_fntype (e->call_stmt)); cgraph_node *origin = e->callee;
while (origin->clone_of)
origin = origin->clone_of;
if ((origin->former_clone_of
&& old_fntype == TREE_TYPE (origin->former_clone_of))
|| old_fntype == TREE_TYPE (origin->decl))
gimple_call_set_fntype (new_stmt, TREE_TYPE (e->callee->decl));
else
{
bitmap skip = e->callee->clone.combined_args_to_skip;
tree t = cgraph_build_function_type_skip_args (old_fntype, skip,
false);
gimple_call_set_fntype (new_stmt, t);
}
if (gimple_vdef (new_stmt) if (gimple_vdef (new_stmt)
&& TREE_CODE (gimple_vdef (new_stmt)) == SSA_NAME) && TREE_CODE (gimple_vdef (new_stmt)) == SSA_NAME)
......
...@@ -2326,6 +2326,8 @@ void tree_function_versioning (tree, tree, vec<ipa_replace_map *, va_gc> *, ...@@ -2326,6 +2326,8 @@ void tree_function_versioning (tree, tree, vec<ipa_replace_map *, va_gc> *,
void dump_callgraph_transformation (const cgraph_node *original, void dump_callgraph_transformation (const cgraph_node *original,
const cgraph_node *clone, const cgraph_node *clone,
const char *suffix); const char *suffix);
tree cgraph_build_function_type_skip_args (tree orig_type, bitmap args_to_skip,
bool skip_return);
/* In cgraphbuild.c */ /* In cgraphbuild.c */
int compute_call_stmt_bb_frequency (tree, basic_block bb); int compute_call_stmt_bb_frequency (tree, basic_block bb);
......
...@@ -152,9 +152,9 @@ cgraph_edge::clone (cgraph_node *n, gcall *call_stmt, unsigned stmt_uid, ...@@ -152,9 +152,9 @@ cgraph_edge::clone (cgraph_node *n, gcall *call_stmt, unsigned stmt_uid,
/* Build variant of function type ORIG_TYPE skipping ARGS_TO_SKIP and the /* Build variant of function type ORIG_TYPE skipping ARGS_TO_SKIP and the
return value if SKIP_RETURN is true. */ return value if SKIP_RETURN is true. */
static tree tree
build_function_type_skip_args (tree orig_type, bitmap args_to_skip, cgraph_build_function_type_skip_args (tree orig_type, bitmap args_to_skip,
bool skip_return) bool skip_return)
{ {
tree new_type = NULL; tree new_type = NULL;
tree args, new_args = NULL; tree args, new_args = NULL;
...@@ -219,7 +219,8 @@ build_function_decl_skip_args (tree orig_decl, bitmap args_to_skip, ...@@ -219,7 +219,8 @@ build_function_decl_skip_args (tree orig_decl, bitmap args_to_skip,
if (prototype_p (new_type) if (prototype_p (new_type)
|| (skip_return && !VOID_TYPE_P (TREE_TYPE (new_type)))) || (skip_return && !VOID_TYPE_P (TREE_TYPE (new_type))))
new_type new_type
= build_function_type_skip_args (new_type, args_to_skip, skip_return); = cgraph_build_function_type_skip_args (new_type, args_to_skip,
skip_return);
TREE_TYPE (new_decl) = new_type; TREE_TYPE (new_decl) = new_type;
/* For declarations setting DECL_VINDEX (i.e. methods) /* For declarations setting DECL_VINDEX (i.e. methods)
......
2017-03-30 Martin Jambor <mjambor@suse.cz>
PR ipa/77333
* g++.dg/ipa/pr77333.C: New test.
2017-03-30 Jakub Jelinek <jakub@redhat.com> 2017-03-30 Jakub Jelinek <jakub@redhat.com>
PR target/80206 PR target/80206
......
// { dg-do run }
// { dg-options "-O2 -fno-ipa-sra" }
volatile int global;
int __attribute__((noinline, noclone))
get_data (int i)
{
global = i;
return i;
}
typedef int array[32];
namespace {
char buf[512];
class A
{
public:
int field;
char *s;
A() : field(223344)
{
s = buf;
}
int __attribute__((noinline))
foo (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j,
int k, int l, int m, int n, int o, int p, int q, int r, int s, int t)
{
global = a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+r+s+t;
return global;
}
int __attribute__((noinline))
bar()
{
int r = foo (get_data (1), get_data (1), get_data (1), get_data (1),
get_data (1), get_data (1), get_data (1), get_data (1),
get_data (1), get_data (1), get_data (1), get_data (1),
get_data (1), get_data (1), get_data (1), get_data (1),
get_data (1), get_data (1), get_data (1), get_data (1));
if (field != 223344)
__builtin_abort ();
return 0;
}
};
}
int main (int argc, char **argv)
{
A a;
int r = a.bar();
r = a.bar ();
if (a.field != 223344)
__builtin_abort ();
if (global != 20)
__builtin_abort ();
return r;
}
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