summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>2014-06-27 13:29:09 +0000
committerjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>2014-06-27 13:29:09 +0000
commit2e1475dae18752ce68fcdf156912636a0a274078 (patch)
treec0bd394c08c89edcf557da88c5a1221a5d610703
parent3e799e27b3e55e4ed1d9fd01bf62e4c1547007c9 (diff)
downloadgcc-2e1475dae18752ce68fcdf156912636a0a274078.tar.gz
2014-06-27 Martin Jambor <mjambor@suse.cz>
PR ipa/61160 * cgraphclones.c (duplicate_thunk_for_node): Removed parameter args_to_skip, use those from node instead. Copy args_to_skip and combined_args_to_skip from node to the new thunk. (redirect_edge_duplicating_thunks): Removed parameter args_to_skip. (cgraph_create_virtual_clone): Moved computation of combined_args_to_skip... (cgraph_clone_node): ...here, simplify it to bitmap_ior.. testsuite/ * g++.dg/ipa/pr61160-2.C: New test. * g++.dg/ipa/pr61160-3.C: Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@212071 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/cgraphclones.c66
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr61160-2.C43
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr61160-3.C37
5 files changed, 123 insertions, 40 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a7096a5cb1d..befe89ce2f0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2014-06-27 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/61160
+ * cgraphclones.c (duplicate_thunk_for_node): Removed parameter
+ args_to_skip, use those from node instead. Copy args_to_skip and
+ combined_args_to_skip from node to the new thunk.
+ (redirect_edge_duplicating_thunks): Removed parameter args_to_skip.
+ (cgraph_create_virtual_clone): Moved computation of
+ combined_args_to_skip...
+ (cgraph_clone_node): ...here, simplify it to bitmap_ior..
+
2014-06-27 trevor Saunders <tsaunders@mozilla.com>
* config/i386/winnt.c (i386_pe_section_type_flags): Remove
diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
index d57cd9f3a41..2e7dc9060b7 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -301,14 +301,13 @@ set_new_clone_decl_and_node_flags (cgraph_node *new_node)
thunk is this_adjusting but we are removing this parameter. */
static cgraph_node *
-duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node,
- bitmap args_to_skip)
+duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node)
{
cgraph_node *new_thunk, *thunk_of;
thunk_of = cgraph_function_or_thunk_node (thunk->callees->callee);
if (thunk_of->thunk.thunk_p)
- node = duplicate_thunk_for_node (thunk_of, node, args_to_skip);
+ node = duplicate_thunk_for_node (thunk_of, node);
struct cgraph_edge *cs;
for (cs = node->callers; cs; cs = cs->next_caller)
@@ -320,17 +319,18 @@ duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node,
return cs->caller;
tree new_decl;
- if (!args_to_skip)
+ if (!node->clone.args_to_skip)
new_decl = copy_node (thunk->decl);
else
{
/* We do not need to duplicate this_adjusting thunks if we have removed
this. */
if (thunk->thunk.this_adjusting
- && bitmap_bit_p (args_to_skip, 0))
+ && bitmap_bit_p (node->clone.args_to_skip, 0))
return node;
- new_decl = build_function_decl_skip_args (thunk->decl, args_to_skip,
+ new_decl = build_function_decl_skip_args (thunk->decl,
+ node->clone.args_to_skip,
false);
}
gcc_checking_assert (!DECL_STRUCT_FUNCTION (new_decl));
@@ -347,6 +347,8 @@ duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node,
new_thunk->thunk = thunk->thunk;
new_thunk->unique_name = in_lto_p;
new_thunk->former_clone_of = thunk->decl;
+ new_thunk->clone.args_to_skip = node->clone.args_to_skip;
+ new_thunk->clone.combined_args_to_skip = node->clone.combined_args_to_skip;
struct cgraph_edge *e = cgraph_create_edge (new_thunk, node, NULL, 0,
CGRAPH_FREQ_BASE);
@@ -363,12 +365,11 @@ duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node,
chain. */
void
-redirect_edge_duplicating_thunks (struct cgraph_edge *e, struct cgraph_node *n,
- bitmap args_to_skip)
+redirect_edge_duplicating_thunks (struct cgraph_edge *e, struct cgraph_node *n)
{
cgraph_node *orig_to = cgraph_function_or_thunk_node (e->callee);
if (orig_to->thunk.thunk_p)
- n = duplicate_thunk_for_node (orig_to, n, args_to_skip);
+ n = duplicate_thunk_for_node (orig_to, n);
cgraph_redirect_edge_callee (e, n);
}
@@ -421,9 +422,21 @@ cgraph_clone_node (struct cgraph_node *n, tree decl, gcov_type count, int freq,
new_node->rtl = n->rtl;
new_node->count = count;
new_node->frequency = n->frequency;
- new_node->clone = n->clone;
- new_node->clone.tree_map = NULL;
new_node->tp_first_run = n->tp_first_run;
+
+ new_node->clone.tree_map = NULL;
+ new_node->clone.args_to_skip = args_to_skip;
+ if (!args_to_skip)
+ new_node->clone.combined_args_to_skip = n->clone.combined_args_to_skip;
+ else if (n->clone.combined_args_to_skip)
+ {
+ new_node->clone.combined_args_to_skip = BITMAP_GGC_ALLOC ();
+ bitmap_ior (new_node->clone.combined_args_to_skip,
+ n->clone.combined_args_to_skip, args_to_skip);
+ }
+ else
+ new_node->clone.combined_args_to_skip = args_to_skip;
+
if (n->count)
{
if (new_node->count > n->count)
@@ -448,10 +461,9 @@ cgraph_clone_node (struct cgraph_node *n, tree decl, gcov_type count, int freq,
if (!e->callee
|| DECL_BUILT_IN_CLASS (e->callee->decl) != BUILT_IN_NORMAL
|| DECL_FUNCTION_CODE (e->callee->decl) != BUILT_IN_UNREACHABLE)
- redirect_edge_duplicating_thunks (e, new_node, args_to_skip);
+ redirect_edge_duplicating_thunks (e, new_node);
}
-
for (e = n->callees;e; e=e->next_callee)
cgraph_clone_edge (e, new_node, e->call_stmt, e->lto_stmt_uid,
count_scale, freq, update_original);
@@ -558,7 +570,6 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node,
ABI support for this. */
set_new_clone_decl_and_node_flags (new_node);
new_node->clone.tree_map = tree_map;
- new_node->clone.args_to_skip = args_to_skip;
/* Clones of global symbols or symbols with unique names are unique. */
if ((TREE_PUBLIC (old_decl)
@@ -569,32 +580,7 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node,
new_node->unique_name = true;
FOR_EACH_VEC_SAFE_ELT (tree_map, i, map)
new_node->maybe_add_reference (map->new_tree, IPA_REF_ADDR, NULL);
- if (!args_to_skip)
- new_node->clone.combined_args_to_skip = old_node->clone.combined_args_to_skip;
- else if (old_node->clone.combined_args_to_skip)
- {
- int newi = 0, oldi = 0;
- tree arg;
- bitmap new_args_to_skip = BITMAP_GGC_ALLOC ();
- struct cgraph_node *orig_node;
- for (orig_node = old_node; orig_node->clone_of; orig_node = orig_node->clone_of)
- ;
- for (arg = DECL_ARGUMENTS (orig_node->decl);
- arg; arg = DECL_CHAIN (arg), oldi++)
- {
- if (bitmap_bit_p (old_node->clone.combined_args_to_skip, oldi))
- {
- bitmap_set_bit (new_args_to_skip, oldi);
- continue;
- }
- if (bitmap_bit_p (args_to_skip, newi))
- bitmap_set_bit (new_args_to_skip, oldi);
- newi++;
- }
- new_node->clone.combined_args_to_skip = new_args_to_skip;
- }
- else
- new_node->clone.combined_args_to_skip = args_to_skip;
+
if (old_node->ipa_transforms_to_apply.exists ())
new_node->ipa_transforms_to_apply
= old_node->ipa_transforms_to_apply.copy ();
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index fdaf19ca5f6..04d08b5a034 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2014-06-27 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/61160
+ * g++.dg/ipa/pr61160-2.C: New test.
+ * g++.dg/ipa/pr61160-3.C: Likewise.
+
2014-06-27 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/57233
diff --git a/gcc/testsuite/g++.dg/ipa/pr61160-2.C b/gcc/testsuite/g++.dg/ipa/pr61160-2.C
new file mode 100644
index 00000000000..1011bd1efab
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/pr61160-2.C
@@ -0,0 +1,43 @@
+/* { dg-do run } */
+/* { dg-options "-O3 --param ipa-cp-eval-threshold=1" } */
+
+extern "C" void abort (void);
+
+struct CBase {
+ virtual void BaseFunc () {}
+};
+
+struct MMixin {
+ virtual void * MixinFunc (int, void *) = 0;
+};
+
+struct CExample: CBase, public MMixin
+{
+ int stuff, magic, more_stuff;
+
+ CExample ()
+ {
+ stuff = 0;
+ magic = 0xbeef;
+ more_stuff = 0;
+ }
+ void *MixinFunc (int arg, void *arg2)
+ {
+ if (arg != 1 || arg2)
+ return 0;
+ if (magic != 0xbeef)
+ abort();
+ return this;
+ }
+};
+
+void *test (MMixin & anExample)
+{
+ return anExample.MixinFunc (1, 0);
+}
+
+int main ()
+{
+ CExample c;
+ return (test (c) != &c);
+}
diff --git a/gcc/testsuite/g++.dg/ipa/pr61160-3.C b/gcc/testsuite/g++.dg/ipa/pr61160-3.C
new file mode 100644
index 00000000000..8184ec2cd3d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/pr61160-3.C
@@ -0,0 +1,37 @@
+/* { dg-do run } */
+/* { dg-options "-O3" } */
+
+struct A {
+ void *p;
+ A (void *q) : p (q) {}
+ A (const A &) : p () {}
+};
+
+struct CBase {
+ virtual void BaseFunc () {}
+};
+
+struct MMixin {
+ virtual A MixinFunc (int, A) = 0;
+};
+
+struct CExample: CBase, public MMixin
+{
+ A MixinFunc (int arg, A arg2)
+ {
+ if (arg != 1 || arg2.p)
+ return 0;
+ return this;
+ }
+};
+
+void *test (MMixin & anExample)
+{
+ return anExample.MixinFunc (1, (0)).p;
+}
+
+int main ()
+{
+ CExample c;
+ return (test (c) != &c);
+}