diff mbox

[PR,tree-optimization/65002] Disable SRA for functions wrongly marked as read-only

Message ID 20150212141419.GA35812@msticlxl57.ims.intel.com
State New
Headers show

Commit Message

Ilya Enkovich Feb. 12, 2015, 2:14 p.m. UTC
Hi,

PR65002 is the second issue caused by SRA for functions wrongly marked as read-only.  Previous fix for PR64353 doesn't work for this case because SSA update happens too late.  Here is a patch to disable SRA for such functions to avoid inconsistent SSA issues.

Bootstrapped and tested on x86_64-unknown-linux-gnu.  OK for trunk?

Thanks,
Ilya
--
gcc/

2015-02-12  Ilya Enkovich  <ilya.enkovich@intel.com>

	PR tree-optimization/65002
	* tree-cfg.c (pass_data_fixup_cfg): Don't update
	SSA on start.
	* tree-sra.c (some_callers_have_no_vuse_p): New.
	(ipa_early_sra): Reject functions whose callers
	assume funciton is read only.

gcc/testsuite/

2015-02-12  Ilya Enkovich  <ilya.enkovich@intel.com>

	PR tree-optimization/65002
	* gcc.dg/pr65002.C: New.

Comments

Richard Biener Feb. 13, 2015, 8:47 a.m. UTC | #1
On Thu, Feb 12, 2015 at 3:14 PM, Ilya Enkovich <enkovich.gnu@gmail.com> wrote:
> Hi,
>
> PR65002 is the second issue caused by SRA for functions wrongly marked as read-only.  Previous fix for PR64353 doesn't work for this case because SSA update happens too late.  Here is a patch to disable SRA for such functions to avoid inconsistent SSA issues.
>
> Bootstrapped and tested on x86_64-unknown-linux-gnu.  OK for trunk?

Ok.  I'm not entirely happy with this but I guess any other solution has to wait
for GCC 6.

Thanks,
Richard.

> Thanks,
> Ilya
> --
> gcc/
>
> 2015-02-12  Ilya Enkovich  <ilya.enkovich@intel.com>
>
>         PR tree-optimization/65002
>         * tree-cfg.c (pass_data_fixup_cfg): Don't update
>         SSA on start.
>         * tree-sra.c (some_callers_have_no_vuse_p): New.
>         (ipa_early_sra): Reject functions whose callers
>         assume funciton is read only.
>
> gcc/testsuite/
>
> 2015-02-12  Ilya Enkovich  <ilya.enkovich@intel.com>
>
>         PR tree-optimization/65002
>         * gcc.dg/pr65002.C: New.
>
>
> diff --git a/gcc/testsuite/gcc.dg/pr65002.C b/gcc/testsuite/gcc.dg/pr65002.C
> new file mode 100644
> index 0000000..ac7c66b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr65002.C
> @@ -0,0 +1,26 @@
> +/* PR tree-optimization/65002 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2" } */
> +
> +namespace fastmath {
> +  template <typename T> float floor(const T &) __attribute__((const));
> +  template <typename T> float floor(const T &p1) { return p1; }
> +}
> +using fastmath::floor;
> +class A {
> +public:
> +  A(int, int);
> +  virtual int m_fn1(float) const;
> +};
> +class B : A {
> +public:
> +  B(int, int p2) : A(entity, p2) {}
> +  int m_fn1(float p1) const { long b(floor(p1)); }
> +  int entity;
> +};
> +
> +int a;
> +void Convert() {
> +  if (int *c = 0)
> +    B(*c, a);
> +}
> diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
> index 2e23553..006bc08 100644
> --- a/gcc/tree-cfg.c
> +++ b/gcc/tree-cfg.c
> @@ -8754,7 +8754,7 @@ const pass_data pass_data_fixup_cfg =
>    PROP_cfg, /* properties_required */
>    0, /* properties_provided */
>    0, /* properties_destroyed */
> -  TODO_update_ssa_only_virtuals, /* todo_flags_start */
> +  0, /* todo_flags_start */
>    0, /* todo_flags_finish */
>  };
>
> diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
> index ad9584e..7f78e68 100644
> --- a/gcc/tree-sra.c
> +++ b/gcc/tree-sra.c
> @@ -4890,6 +4890,20 @@ some_callers_have_mismatched_arguments_p (struct cgraph_node *node,
>    return false;
>  }
>
> +/* Return false if all callers have vuse attached to a call statement.  */
> +
> +static bool
> +some_callers_have_no_vuse_p (struct cgraph_node *node,
> +                            void *data ATTRIBUTE_UNUSED)
> +{
> +  struct cgraph_edge *cs;
> +  for (cs = node->callers; cs; cs = cs->next_caller)
> +    if (!cs->call_stmt || !gimple_vuse (cs->call_stmt))
> +      return true;
> +
> +  return false;
> +}
> +
>  /* Convert all callers of NODE.  */
>
>  static bool
> @@ -5116,6 +5130,15 @@ ipa_early_sra (void)
>        goto simple_out;
>      }
>
> +  if (node->call_for_symbol_thunks_and_aliases
> +       (some_callers_have_no_vuse_p, NULL, true))
> +    {
> +      if (dump_file)
> +       fprintf (dump_file, "There are callers with no VUSE attached "
> +                "to a call stmt.\n");
> +      goto simple_out;
> +    }
> +
>    bb_dereferences = XCNEWVEC (HOST_WIDE_INT,
>                                  func_param_count
>                                  * last_basic_block_for_fn (cfun));
Jakub Jelinek Feb. 13, 2015, 8:54 a.m. UTC | #2
On Fri, Feb 13, 2015 at 09:47:56AM +0100, Richard Biener wrote:
> > 2015-02-12  Ilya Enkovich  <ilya.enkovich@intel.com>
> >
> >         PR tree-optimization/65002
> >         * tree-cfg.c (pass_data_fixup_cfg): Don't update
> >         SSA on start.
> >         * tree-sra.c (some_callers_have_no_vuse_p): New.
> >         (ipa_early_sra): Reject functions whose callers
> >         assume funciton is read only.

Typo, function.

> > +static bool
> > +some_callers_have_no_vuse_p (struct cgraph_node *node,
> > +                            void *data ATTRIBUTE_UNUSED)
> > +{
> > +  struct cgraph_edge *cs;
> > +  for (cs = node->callers; cs; cs = cs->next_caller)
> > +    if (!cs->call_stmt || !gimple_vuse (cs->call_stmt))
> > +      return true;
> > +
> > +  return false;
> > +}
> > +
> >  /* Convert all callers of NODE.  */
> >
> >  static bool
> > @@ -5116,6 +5130,15 @@ ipa_early_sra (void)
> >        goto simple_out;
> >      }
> >
> > +  if (node->call_for_symbol_thunks_and_aliases
> > +       (some_callers_have_no_vuse_p, NULL, true))
> > +    {
> > +      if (dump_file)
> > +       fprintf (dump_file, "There are callers with no VUSE attached "
> > +                "to a call stmt.\n");
> > +      goto simple_out;
> > +    }
> > +

I wonder if this won't pessimize const functions that just get called with
aggregate arguments passed by value, do those count as memory read or
just as parameters?

	Jakub
Ilya Enkovich Feb. 13, 2015, 9:18 a.m. UTC | #3
2015-02-13 11:54 GMT+03:00 Jakub Jelinek <jakub@redhat.com>:
> On Fri, Feb 13, 2015 at 09:47:56AM +0100, Richard Biener wrote:
>> > 2015-02-12  Ilya Enkovich  <ilya.enkovich@intel.com>
>> >
>> >         PR tree-optimization/65002
>> >         * tree-cfg.c (pass_data_fixup_cfg): Don't update
>> >         SSA on start.
>> >         * tree-sra.c (some_callers_have_no_vuse_p): New.
>> >         (ipa_early_sra): Reject functions whose callers
>> >         assume funciton is read only.
>
> Typo, function.
>
>> > +static bool
>> > +some_callers_have_no_vuse_p (struct cgraph_node *node,
>> > +                            void *data ATTRIBUTE_UNUSED)
>> > +{
>> > +  struct cgraph_edge *cs;
>> > +  for (cs = node->callers; cs; cs = cs->next_caller)
>> > +    if (!cs->call_stmt || !gimple_vuse (cs->call_stmt))
>> > +      return true;
>> > +
>> > +  return false;
>> > +}
>> > +
>> >  /* Convert all callers of NODE.  */
>> >
>> >  static bool
>> > @@ -5116,6 +5130,15 @@ ipa_early_sra (void)
>> >        goto simple_out;
>> >      }
>> >
>> > +  if (node->call_for_symbol_thunks_and_aliases
>> > +       (some_callers_have_no_vuse_p, NULL, true))
>> > +    {
>> > +      if (dump_file)
>> > +       fprintf (dump_file, "There are callers with no VUSE attached "
>> > +                "to a call stmt.\n");
>> > +      goto simple_out;
>> > +    }
>> > +
>
> I wonder if this won't pessimize const functions that just get called with
> aggregate arguments passed by value, do those count as memory read or
> just as parameters?

Tried it on a simple test.

struct S
{
  int a;
  int b;
};
int f1 (struct S s) __attribute__((const));
int f2 (struct S *ps)
{
  return f1 (*ps);
}

There is a memory use for a call:

  <bb 2>:
  # VUSE <.MEM_1(D)>
  _3 = f1 (*ps_2(D));


But if wrongly marked const function has all calls with vuses for some
reason then we just should be able to optimize it with a proper SSA
update.

Ilya

>
>         Jakub
Richard Biener Feb. 13, 2015, 9:21 a.m. UTC | #4
On Fri, Feb 13, 2015 at 9:54 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> On Fri, Feb 13, 2015 at 09:47:56AM +0100, Richard Biener wrote:
>> > 2015-02-12  Ilya Enkovich  <ilya.enkovich@intel.com>
>> >
>> >         PR tree-optimization/65002
>> >         * tree-cfg.c (pass_data_fixup_cfg): Don't update
>> >         SSA on start.
>> >         * tree-sra.c (some_callers_have_no_vuse_p): New.
>> >         (ipa_early_sra): Reject functions whose callers
>> >         assume funciton is read only.
>
> Typo, function.
>
>> > +static bool
>> > +some_callers_have_no_vuse_p (struct cgraph_node *node,
>> > +                            void *data ATTRIBUTE_UNUSED)
>> > +{
>> > +  struct cgraph_edge *cs;
>> > +  for (cs = node->callers; cs; cs = cs->next_caller)
>> > +    if (!cs->call_stmt || !gimple_vuse (cs->call_stmt))
>> > +      return true;
>> > +
>> > +  return false;
>> > +}
>> > +
>> >  /* Convert all callers of NODE.  */
>> >
>> >  static bool
>> > @@ -5116,6 +5130,15 @@ ipa_early_sra (void)
>> >        goto simple_out;
>> >      }
>> >
>> > +  if (node->call_for_symbol_thunks_and_aliases
>> > +       (some_callers_have_no_vuse_p, NULL, true))
>> > +    {
>> > +      if (dump_file)
>> > +       fprintf (dump_file, "There are callers with no VUSE attached "
>> > +                "to a call stmt.\n");
>> > +      goto simple_out;
>> > +    }
>> > +
>
> I wonder if this won't pessimize const functions that just get called with
> aggregate arguments passed by value, do those count as memory read or
> just as parameters?

They count as memory reads and thus cause a VUSE (similar to aggregate
returns causing a VDEF).

Richard.

>         Jakub
Jakub Jelinek Feb. 13, 2015, 9:27 a.m. UTC | #5
On Fri, Feb 13, 2015 at 10:21:42AM +0100, Richard Biener wrote:
> > I wonder if this won't pessimize const functions that just get called with
> > aggregate arguments passed by value, do those count as memory read or
> > just as parameters?
> 
> They count as memory reads and thus cause a VUSE (similar to aggregate
> returns causing a VDEF).

Ok.

	Jakub
Marek Polacek Feb. 13, 2015, 7:19 p.m. UTC | #6
On Thu, Feb 12, 2015 at 05:14:19PM +0300, Ilya Enkovich wrote:
> Hi,
> 
> PR65002 is the second issue caused by SRA for functions wrongly marked as read-only.  Previous fix for PR64353 doesn't work for this case because SSA update happens too late.  Here is a patch to disable SRA for such functions to avoid inconsistent SSA issues.
> 
> Bootstrapped and tested on x86_64-unknown-linux-gnu.  OK for trunk?
> 
> Thanks,
> Ilya
> --
> gcc/
> 
> 2015-02-12  Ilya Enkovich  <ilya.enkovich@intel.com>
> 
> 	PR tree-optimization/65002
> 	* tree-cfg.c (pass_data_fixup_cfg): Don't update
> 	SSA on start.
> 	* tree-sra.c (some_callers_have_no_vuse_p): New.
> 	(ipa_early_sra): Reject functions whose callers
> 	assume funciton is read only.
> 
> gcc/testsuite/
> 
> 2015-02-12  Ilya Enkovich  <ilya.enkovich@intel.com>
> 
> 	PR tree-optimization/65002
> 	* gcc.dg/pr65002.C: New.

This test should have gone into g++.dg.

	Marek
Jakub Jelinek Feb. 13, 2015, 7:25 p.m. UTC | #7
On Fri, Feb 13, 2015 at 08:19:52PM +0100, Marek Polacek wrote:
> On Thu, Feb 12, 2015 at 05:14:19PM +0300, Ilya Enkovich wrote:
> > Hi,
> > 
> > PR65002 is the second issue caused by SRA for functions wrongly marked as read-only.  Previous fix for PR64353 doesn't work for this case because SSA update happens too late.  Here is a patch to disable SRA for such functions to avoid inconsistent SSA issues.
> > 
> > Bootstrapped and tested on x86_64-unknown-linux-gnu.  OK for trunk?
> > 
> > Thanks,
> > Ilya
> > --
> > gcc/
> > 
> > 2015-02-12  Ilya Enkovich  <ilya.enkovich@intel.com>
> > 
> > 	PR tree-optimization/65002
> > 	* tree-cfg.c (pass_data_fixup_cfg): Don't update
> > 	SSA on start.
> > 	* tree-sra.c (some_callers_have_no_vuse_p): New.
> > 	(ipa_early_sra): Reject functions whose callers
> > 	assume funciton is read only.
> > 
> > gcc/testsuite/
> > 
> > 2015-02-12  Ilya Enkovich  <ilya.enkovich@intel.com>
> > 
> > 	PR tree-optimization/65002
> > 	* gcc.dg/pr65002.C: New.
> 
> This test should have gone into g++.dg.

Into g++.dg/opt or g++.dg/ipa in particular.

	Jakub
Mike Stump Feb. 15, 2015, 5:25 p.m. UTC | #8
On Feb 13, 2015, at 11:25 AM, Jakub Jelinek <jakub@redhat.com> wrote:
>>> 2015-02-12  Ilya Enkovich  <ilya.enkovich@intel.com>
>>> 
>>> 	PR tree-optimization/65002
>>> 	* gcc.dg/pr65002.C: New.
>> 
>> This test should have gone into g++.dg.
> 
> Into g++.dg/opt or g++.dg/ipa in particular.

Pre-approved if someone wants to svn mv it.
Ilya Enkovich Feb. 16, 2015, 10:08 a.m. UTC | #9
2015-02-15 20:25 GMT+03:00 Mike Stump <mikestump@comcast.net>:
> On Feb 13, 2015, at 11:25 AM, Jakub Jelinek <jakub@redhat.com> wrote:
>>>> 2015-02-12  Ilya Enkovich  <ilya.enkovich@intel.com>
>>>>
>>>>     PR tree-optimization/65002
>>>>     * gcc.dg/pr65002.C: New.
>>>
>>> This test should have gone into g++.dg.
>>
>> Into g++.dg/opt or g++.dg/ipa in particular.
>
> Pre-approved if someone wants to svn mv it.

Moved it.

2015-02-16  Ilya Enkovich  <ilya.enkovich@intel.com>

        * gcc.dg/pr65002.C: Move ...
        * g++.dg/ipa/pr65002.C: ... here.



Thanks,
Ilya
diff mbox

Patch

diff --git a/gcc/testsuite/gcc.dg/pr65002.C b/gcc/testsuite/gcc.dg/pr65002.C
new file mode 100644
index 0000000..ac7c66b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr65002.C
@@ -0,0 +1,26 @@ 
+/* PR tree-optimization/65002 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+namespace fastmath {
+  template <typename T> float floor(const T &) __attribute__((const));
+  template <typename T> float floor(const T &p1) { return p1; }
+}
+using fastmath::floor;
+class A {
+public:
+  A(int, int);
+  virtual int m_fn1(float) const;
+};
+class B : A {
+public:
+  B(int, int p2) : A(entity, p2) {}
+  int m_fn1(float p1) const { long b(floor(p1)); }
+  int entity;
+};
+
+int a;
+void Convert() {
+  if (int *c = 0)
+    B(*c, a);
+}
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 2e23553..006bc08 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -8754,7 +8754,7 @@  const pass_data pass_data_fixup_cfg =
   PROP_cfg, /* properties_required */
   0, /* properties_provided */
   0, /* properties_destroyed */
-  TODO_update_ssa_only_virtuals, /* todo_flags_start */
+  0, /* todo_flags_start */
   0, /* todo_flags_finish */
 };
 
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index ad9584e..7f78e68 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -4890,6 +4890,20 @@  some_callers_have_mismatched_arguments_p (struct cgraph_node *node,
   return false;
 }
 
+/* Return false if all callers have vuse attached to a call statement.  */
+
+static bool
+some_callers_have_no_vuse_p (struct cgraph_node *node,
+			     void *data ATTRIBUTE_UNUSED)
+{
+  struct cgraph_edge *cs;
+  for (cs = node->callers; cs; cs = cs->next_caller)
+    if (!cs->call_stmt || !gimple_vuse (cs->call_stmt))
+      return true;
+
+  return false;
+}
+
 /* Convert all callers of NODE.  */
 
 static bool
@@ -5116,6 +5130,15 @@  ipa_early_sra (void)
       goto simple_out;
     }
 
+  if (node->call_for_symbol_thunks_and_aliases
+       (some_callers_have_no_vuse_p, NULL, true))
+    {
+      if (dump_file)
+	fprintf (dump_file, "There are callers with no VUSE attached "
+		 "to a call stmt.\n");
+      goto simple_out;
+    }
+
   bb_dereferences = XCNEWVEC (HOST_WIDE_INT,
 				 func_param_count
 				 * last_basic_block_for_fn (cfun));