Hi,

On Tue, Dec 17 2019, Jakub Jelinek wrote:
> On Tue, Dec 17, 2019 at 01:50:32PM +0100, Martin Jambor wrote:
>> Hi,
>> 
>> as reported in PR 92971, IPA-CP's
>> cgraph_edge_brings_all_agg_vals_for_node defines one local variable with
>> the static keyword which is a clear mistake, probabley a cut'n'paste
>> error when I originally wrote the code.
>> 
>> I'll commit the following as obvious after a round of bootstrap and
>> testing.  Early next year, I'll also commit it to all opened release
>> branches.
>
> Is that what you want to do though?
> Because when it is an automatic variable (shouldn't it be auto_vec, btw),
> then the first use of it doesn't make much sense:
>       values = intersect_aggregates_with_edge (cs, i, values);
> because it will be always (cs, i, vNULL).  So maybe the var should live
> across the iterations or live in the caller that should pass a pointer (or
> reference) to it?
> With the patch, there will be leaks too, because the values vector is only
> released if the function returns false and is not released otherwise.

the leak is indeed a problem, thanks for spotting it.  But apart from
that, I really wanted to pass vNULL to intersect_aggregates_with_edge,
and the patch below does it explicitely to make it clear, because while
the function can do also intersecting its actual task here is to carry
over aggregate constants from all types of callers (clones and
non-clones) and all kinds of supported jump functions.

That might be an overkill because the main goal of
cgraph_edge_brings_all_agg_vals_for_node is to add the last edge within
SCCs of nodes propagating the same constant to each other and I could
not quickly come up with a testcase where the caller would be a
non-clone (and the function something other than pass-through, but I
suspect that could actually happen) but since the code is written we
might as well use it.  The function is written to bail out early before
actual value comparing and that is why the code is rarely executed, in
fact I found out that it is not covered by our testsuite (see
https://users.suse.com/~mliska/lcov/gcc/ipa-cp.c.gcov.html) and so the
patch also adds a testcase which does execute it.

The way vectors are passed around by value rather than by reference is
how I wrote this stuff shortly after conversion from our C VEC_ headers
with which were used in the same way.  I agree that a lot of code in
ipa-cp would benefit from transitioning to auto_vecs but that is
something for the next stage 1.

The patch has been bootstrapped and LTO-profile-bootstrapped on
x86-64-linux.  OK for trunk?

Thanks,

Martin


2019-12-17  Martin Jambor  <mjam...@suse.cz>

        PR ipa/92971
        * Ipa-cp.c (cgraph_edge_brings_all_agg_vals_for_node): Fix
          definition of values, release memory on exit.

        testsuite/
        * gcc.dg/ipa/ipcp-agg-12.c: New test.
---
 gcc/ipa-cp.c                           |  4 +-
 gcc/testsuite/gcc.dg/ipa/ipcp-agg-12.c | 53 ++++++++++++++++++++++++++
 2 files changed, 55 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/ipa/ipcp-agg-12.c

diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 1a80ccbde2d..243b064ee2c 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -5117,7 +5117,6 @@ cgraph_edge_brings_all_agg_vals_for_node (struct 
cgraph_edge *cs,
 
   for (i = 0; i < count; i++)
     {
-      static vec<ipa_agg_value> values = vNULL;
       class ipcp_param_lattices *plats;
       bool interesting = false;
       for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
@@ -5133,7 +5132,7 @@ cgraph_edge_brings_all_agg_vals_for_node (struct 
cgraph_edge *cs,
       if (plats->aggs_bottom)
        return false;
 
-      values = intersect_aggregates_with_edge (cs, i, values);
+      vec<ipa_agg_value> values = intersect_aggregates_with_edge (cs, i, 
vNULL);
       if (!values.exists ())
        return false;
 
@@ -5157,6 +5156,7 @@ cgraph_edge_brings_all_agg_vals_for_node (struct 
cgraph_edge *cs,
                return false;
              }
          }
+      values.release ();
     }
   return true;
 }
diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-agg-12.c 
b/gcc/testsuite/gcc.dg/ipa/ipcp-agg-12.c
new file mode 100644
index 00000000000..5c57913803e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipcp-agg-12.c
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fno-ipa-sra -fdump-ipa-cp-details 
--param=ipa-cp-eval-threshold=2"  } */
+
+struct S
+{
+  int a, b, c;
+};
+
+int __attribute__((noinline)) foo (int i, struct S s);
+int __attribute__((noinline)) bar (int i, struct S s);
+int __attribute__((noinline)) baz (int i, struct S s);
+
+
+int __attribute__((noinline))
+bar (int i, struct S s)
+{
+  return baz (i, s);
+}
+
+int __attribute__((noinline))
+baz (int i, struct S s)
+{
+  return foo (i, s);
+}
+
+int __attribute__((noinline))
+foo (int i, struct S s)
+{
+  if (i == 2)
+    return 0;
+  else
+    return s.b * s.b + bar (i - 1, s);
+}
+
+volatile int g;
+
+void entry (void)
+{
+  struct S s;
+  s.b = 4;
+  g = bar (g, s);
+}
+
+
+void entry2 (void)
+{
+  struct S s;
+  s.b = 6;
+  g = baz (g, s);
+}
+
+
+/* { dg-final { scan-ipa-dump-times "adding an extra caller" 2 "cp" } } */
-- 
2.24.0

Reply via email to