aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2015-12-14 10:33:12 +0100
committerMartin Jambor <jamborm@gcc.gnu.org>2015-12-14 10:33:12 +0100
commit173b7355f6858dac3b1ff0919b5ae8a87f379dea (patch)
treea80ba4c0b00626fa7d08d354c9bfd67cc9bb2036
parent63da5ff6bfbc86294a911c36be99e70b9fc0a83a (diff)
downloadgcc-173b7355f6858dac3b1ff0919b5ae8a87f379dea.zip
gcc-173b7355f6858dac3b1ff0919b5ae8a87f379dea.tar.gz
gcc-173b7355f6858dac3b1ff0919b5ae8a87f379dea.tar.bz2
[PR 66616] Check for thunks when adding extra constants to clones
2015-12-14 Martin Jambor <mjambor@suse.cz> PR ipa/66616 * ipa-cp.c (propagate_constants_accross_call): Move thuk check... (call_passes_through_thunk_p): ...here. (find_more_scalar_values_for_callers_subset): Perform thunk checks like propagate_constants_accross_call does. testsuite/ * g++.dg/ipa/pr66616.C: New test. From-SVN: r231607
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/ipa-cp.c25
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr66616.C54
4 files changed, 86 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e6a2763..39bbf19 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2015-12-14 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/66616
+ * ipa-cp.c (propagate_constants_accross_call): Move thuk check...
+ (call_passes_through_thunk_p): ...here.
+ (find_more_scalar_values_for_callers_subset): Perform thunk checks
+ like propagate_constants_accross_call does.
+
2015-12-14 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/68730
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index ee28550..8087f66 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -1877,6 +1877,18 @@ propagate_aggs_accross_jump_function (struct cgraph_edge *cs,
return ret;
}
+/* Return true if on the way cfrom CS->caller to the final (non-alias and
+ non-thunk) destination, the call passes through a thunk. */
+
+static bool
+call_passes_through_thunk_p (cgraph_edge *cs)
+{
+ cgraph_node *alias_or_thunk = cs->callee;
+ while (alias_or_thunk->alias)
+ alias_or_thunk = alias_or_thunk->get_alias_target ();
+ return alias_or_thunk->thunk.thunk_p;
+}
+
/* Propagate constants from the caller to the callee of CS. INFO describes the
caller. */
@@ -1885,7 +1897,7 @@ propagate_constants_accross_call (struct cgraph_edge *cs)
{
struct ipa_node_params *callee_info;
enum availability availability;
- struct cgraph_node *callee, *alias_or_thunk;
+ cgraph_node *callee;
struct ipa_edge_args *args;
bool ret = false;
int i, args_count, parms_count;
@@ -1923,10 +1935,7 @@ propagate_constants_accross_call (struct cgraph_edge *cs)
/* If this call goes through a thunk we must not propagate to the first (0th)
parameter. However, we might need to uncover a thunk from below a series
of aliases first. */
- alias_or_thunk = cs->callee;
- while (alias_or_thunk->alias)
- alias_or_thunk = alias_or_thunk->get_alias_target ();
- if (alias_or_thunk->thunk.thunk_p)
+ if (call_passes_through_thunk_p (cs))
{
ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info,
0));
@@ -3499,7 +3508,11 @@ find_more_scalar_values_for_callers_subset (struct cgraph_node *node,
struct ipa_jump_func *jump_func;
tree t;
- if (i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs)))
+ if (i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs))
+ || (i == 0
+ && call_passes_through_thunk_p (cs))
+ || (!cs->callee->instrumentation_clone
+ && cs->callee->function_symbol ()->instrumentation_clone))
{
newval = NULL_TREE;
break;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2b900bf..cc8b9e2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2015-12-14 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/66616
+ * g++.dg/ipa/pr66616.C: New test.
+
2015-12-14 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/68730
diff --git a/gcc/testsuite/g++.dg/ipa/pr66616.C b/gcc/testsuite/g++.dg/ipa/pr66616.C
new file mode 100644
index 0000000..440ea6c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/pr66616.C
@@ -0,0 +1,54 @@
+// { dg-do run }
+// { dg-options "-O2 -fipa-cp-clone" }
+
+struct Distraction
+{
+ char fc[8];
+ virtual Distraction * return_self ()
+ { return this; }
+};
+
+static int go;
+
+struct A;
+
+struct A
+{
+ int fi;
+
+ A () : fi(0) {}
+ A (int pi) : fi (pi) {}
+ virtual void foo (int p) = 0;
+};
+
+struct B;
+
+struct B : public Distraction, A
+{
+ B () : Distraction(), A() { }
+ B (int pi) : Distraction (), A (pi) {}
+ virtual void foo (int p)
+ {
+ int o = fi;
+ for (int i = 0; i < p; i++)
+ o += i + i * i;
+ go = o;
+ }
+};
+
+struct B gb2 (2);
+
+extern "C" void abort (void);
+
+int
+main (void)
+{
+ for (int i = 0; i < 2; i++)
+ {
+ struct A *p = &gb2;
+ p->foo (0);
+ if (go != 2)
+ abort ();
+ }
+ return 0;
+}