diff options
author | Martin Jambor <mjambor@suse.cz> | 2017-03-30 15:51:02 +0200 |
---|---|---|
committer | Martin Jambor <jamborm@gcc.gnu.org> | 2017-03-30 15:51:02 +0200 |
commit | b0fd4d7e328f0b967d61fdfe44b5e01b26cf3c30 (patch) | |
tree | 0d0aa00b6327fc3693098541fb8b4b3c966bfa64 | |
parent | de008ec4d69a5f7e9b75b25dc9e1fa937d65ff80 (diff) | |
download | gcc-b0fd4d7e328f0b967d61fdfe44b5e01b26cf3c30.zip gcc-b0fd4d7e328f0b967d61fdfe44b5e01b26cf3c30.tar.gz gcc-b0fd4d7e328f0b967d61fdfe44b5e01b26cf3c30.tar.bz2 |
[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
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cgraph.c | 17 | ||||
-rw-r--r-- | gcc/cgraph.h | 2 | ||||
-rw-r--r-- | gcc/cgraphclones.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ipa/pr77333.C | 65 |
6 files changed, 103 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 99256af..44e48ec 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +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> PR target/80206 diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 8393884..92ae091 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -1424,8 +1424,23 @@ cgraph_edge::redirect_call_stmt_to_callee (void) if (skip_bounds) 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_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) && TREE_CODE (gimple_vdef (new_stmt)) == SSA_NAME) diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 3889a3e..62cebd9 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -2326,6 +2326,8 @@ void tree_function_versioning (tree, tree, vec<ipa_replace_map *, va_gc> *, void dump_callgraph_transformation (const cgraph_node *original, const cgraph_node *clone, const char *suffix); +tree cgraph_build_function_type_skip_args (tree orig_type, bitmap args_to_skip, + bool skip_return); /* In cgraphbuild.c */ int compute_call_stmt_bb_frequency (tree, basic_block bb); diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c index c2337e8..69572b9 100644 --- a/gcc/cgraphclones.c +++ b/gcc/cgraphclones.c @@ -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 return value if SKIP_RETURN is true. */ -static tree -build_function_type_skip_args (tree orig_type, bitmap args_to_skip, - bool skip_return) +tree +cgraph_build_function_type_skip_args (tree orig_type, bitmap args_to_skip, + bool skip_return) { tree new_type = NULL; tree args, new_args = NULL; @@ -219,7 +219,8 @@ build_function_decl_skip_args (tree orig_decl, bitmap args_to_skip, if (prototype_p (new_type) || (skip_return && !VOID_TYPE_P (TREE_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; /* For declarations setting DECL_VINDEX (i.e. methods) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c1b6566..89ade94 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +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> PR target/80206 diff --git a/gcc/testsuite/g++.dg/ipa/pr77333.C b/gcc/testsuite/g++.dg/ipa/pr77333.C new file mode 100644 index 0000000..1ef997f --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr77333.C @@ -0,0 +1,65 @@ +// { 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; +} |