Re: SRA: don't drop clobbers

2014-11-21 Thread Richard Biener
On Thu, Nov 20, 2014 at 7:11 PM, Martin Jambor mjam...@suse.cz wrote:
 Hi,

 On Mon, Nov 03, 2014 at 10:46:49PM +0100, Marc Glisse wrote:
 On Mon, 3 Nov 2014, Marc Glisse wrote:

 On Mon, 3 Nov 2014, Martin Jambor wrote:
 
 I just applied your patch on top of trunk revision 217032 on my
 
 Ah, that explains it, thanks. This patch is a follow-up to
 r217034. Still, I didn't expect the ICE you are seeing by applying
 this patch to older trunk, I'll try to reproduce that.

 It is TODO_update_address_taken that used to remove clobbers, and as
 you said ESRA goes straight to TODO_update_ssa, which explains why
 the clobbers caused trouble. In any case, after r217034, update_ssa
 should handle clobbers much better. Could you take an other look
 based on a more recent trunk, please?


 Sorry for the delay.  Anyway, on the current trunk (i.e. Tuesday
 checkout) the patch works as expected, there are assignments from
 default definitions now and even though we do not warn as we should,
 the patch improves the generated code.  The function foo from the
 testcase is optimized to return SR.1_2(D); as soon as release_ssa
 now, whereas unpatched trunk leaves an undefined load even in the
 optimized dump.

 Thus, I like the patch and given that you posted it well before stage1
 end, I'd like to see it committed.  Richi, can you have a look and
 perhaps approve it?

Yes, the patch is ok.

Thanks,
Richard.

 Thanks,

 Martin



Re: SRA: don't drop clobbers

2014-11-20 Thread Martin Jambor
Hi,

On Mon, Nov 03, 2014 at 10:46:49PM +0100, Marc Glisse wrote:
 On Mon, 3 Nov 2014, Marc Glisse wrote:
 
 On Mon, 3 Nov 2014, Martin Jambor wrote:
 
 I just applied your patch on top of trunk revision 217032 on my
 
 Ah, that explains it, thanks. This patch is a follow-up to
 r217034. Still, I didn't expect the ICE you are seeing by applying
 this patch to older trunk, I'll try to reproduce that.
 
 It is TODO_update_address_taken that used to remove clobbers, and as
 you said ESRA goes straight to TODO_update_ssa, which explains why
 the clobbers caused trouble. In any case, after r217034, update_ssa
 should handle clobbers much better. Could you take an other look
 based on a more recent trunk, please?
 

Sorry for the delay.  Anyway, on the current trunk (i.e. Tuesday
checkout) the patch works as expected, there are assignments from
default definitions now and even though we do not warn as we should,
the patch improves the generated code.  The function foo from the
testcase is optimized to return SR.1_2(D); as soon as release_ssa
now, whereas unpatched trunk leaves an undefined load even in the
optimized dump.

Thus, I like the patch and given that you posted it well before stage1
end, I'd like to see it committed.  Richi, can you have a look and
perhaps approve it?

Thanks,

Martin



SRA: don't drop clobbers

2014-11-03 Thread Marc Glisse

Hello,

now that the update_address_taken patch is in, let me re-post the SRA 
follow-up. With this patch, testcase pr60517.C (attached) has a use of an 
undefined variable at the time of the uninit pass. Sadly, while this 
warned with earlier versions of the other patch (when I was inserting 
default definitions of new variables), it does not anymore because we have 
TREE_NO_WARNING all over the place. Still, I believe this is a step in the 
right direction, and it passed bootstrap+testsuite (minus the new 
testcase). Would it be ok to commit the tree-sra.c change? Then I could 
close PR60770 (the warning itself is PR60517).


2014-11-03  Marc Glisse  marc.gli...@inria.fr

PR tree-optimization/60770
* tree-sra.c (clobber_subtree): New function.
(sra_modify_constructor_assign): Call it.

--
Marc GlisseIndex: gcc/testsuite/g++.dg/tree-ssa/pr60517.C
===
--- gcc/testsuite/g++.dg/tree-ssa/pr60517.C (revision 0)
+++ gcc/testsuite/g++.dg/tree-ssa/pr60517.C (working copy)
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options -O -Wall } */
+
+struct B {
+double x[2];
+};
+struct A {
+B b;
+B getB() { return b; }
+};
+
+double foo(A a) {
+double * x = (a.getB().x[0]);
+return x[0]; /* { dg-warning  } */
+}
Index: gcc/tree-sra.c
===
--- gcc/tree-sra.c  (revision 217035)
+++ gcc/tree-sra.c  (working copy)
@@ -2716,20 +2716,51 @@ init_subtree_with_zero (struct access *a
   if (insert_after)
gsi_insert_after (gsi, ds, GSI_NEW_STMT);
   else
gsi_insert_before (gsi, ds, GSI_SAME_STMT);
 }
 
   for (child = access-first_child; child; child = child-next_sibling)
 init_subtree_with_zero (child, gsi, insert_after, loc);
 }
 
+/* Clobber all scalar replacements in an access subtree.  ACCESS is the the
+   root of the subtree to be processed.  GSI is the statement iterator used
+   for inserting statements which are added after the current statement if
+   INSERT_AFTER is true or before it otherwise.  */
+
+static void
+clobber_subtree (struct access *access, gimple_stmt_iterator *gsi,
+   bool insert_after, location_t loc)
+
+{
+  struct access *child;
+
+  if (access-grp_to_be_replaced)
+{
+  tree rep = get_access_replacement (access);
+  tree clobber = build_constructor (access-type, NULL);
+  TREE_THIS_VOLATILE (clobber) = 1;
+  gimple stmt = gimple_build_assign (rep, clobber);
+
+  if (insert_after)
+   gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
+  else
+   gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
+  update_stmt (stmt);
+  gimple_set_location (stmt, loc);
+}
+
+  for (child = access-first_child; child; child = child-next_sibling)
+clobber_subtree (child, gsi, insert_after, loc);
+}
+
 /* Search for an access representative for the given expression EXPR and
return it or NULL if it cannot be found.  */
 
 static struct access *
 get_access_for_expr (tree expr)
 {
   HOST_WIDE_INT offset, size, max_size;
   tree base;
 
   /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
@@ -3028,43 +3059,41 @@ enum assignment_mod_result { SRA_AM_NONE
 SRA_AM_REMOVED };  /* stmt eliminated */
 
 /* Modify assignments with a CONSTRUCTOR on their RHS.  STMT contains a pointer
to the assignment and GSI is the statement iterator pointing at it.  Returns
the same values as sra_modify_assign.  */
 
 static enum assignment_mod_result
 sra_modify_constructor_assign (gimple stmt, gimple_stmt_iterator *gsi)
 {
   tree lhs = gimple_assign_lhs (stmt);
-  struct access *acc;
-  location_t loc;
-
-  acc = get_access_for_expr (lhs);
+  struct access *acc = get_access_for_expr (lhs);
   if (!acc)
 return SRA_AM_NONE;
+  location_t loc = gimple_location (stmt);
 
   if (gimple_clobber_p (stmt))
 {
-  /* Remove clobbers of fully scalarized variables, otherwise
-do nothing.  */
+  /* Clobber the replacement variable.  */
+  clobber_subtree (acc, gsi, !acc-grp_covered, loc);
+  /* Remove clobbers of fully scalarized variables, they are dead.  */
   if (acc-grp_covered)
{
  unlink_stmt_vdef (stmt);
  gsi_remove (gsi, true);
  release_defs (stmt);
  return SRA_AM_REMOVED;
}
   else
-   return SRA_AM_NONE;
+   return SRA_AM_MODIFIED;
 }
 
-  loc = gimple_location (stmt);
   if (vec_safe_length (CONSTRUCTOR_ELTS (gimple_assign_rhs1 (stmt)))  0)
 {
   /* I have never seen this code path trigger but if it can happen the
 following should handle it gracefully.  */
   if (access_has_children_p (acc))
generate_subtree_copies (acc-first_child, lhs, acc-offset, 0, 0, gsi,
 true, true, loc);
   return SRA_AM_MODIFIED;
 }
 


Re: SRA: don't drop clobbers

2014-11-03 Thread Martin Jambor
Hi,

On Mon, Nov 03, 2014 at 01:59:24PM +0100, Marc Glisse wrote:
 Hello,
 
 now that the update_address_taken patch is in, let me re-post the
 SRA follow-up. With this patch, testcase pr60517.C (attached) has a
 use of an undefined variable at the time of the uninit pass. Sadly,
 while this warned with earlier versions of the other patch (when I
 was inserting default definitions of new variables), it does not
 anymore because we have TREE_NO_WARNING all over the place. Still, I
 believe this is a step in the right direction, and it passed
 bootstrap+testsuite (minus the new testcase).

I am not sure what you mean by minus the new testcase but, with the
gimple checking compiler at least, the testcase produces an ICE:

  pr60517.C: In function ‘double foo(A)’:
  pr60517.C:15:1: error: non-decl/MEM_REF LHS in clobber statement
   }
   ^
  SR.1_8
  SR.1_8 ={v} {CLOBBER};
  pr60517.C:15:1: internal compiler error: verify_gimple failed
  0xc7810d verify_gimple_in_cfg(function*, bool)
  /home/mjambor/gcc/mine/src/gcc/tree-cfg.c:5039
  0xb8256f execute_function_todo
  /home/mjambor/gcc/mine/src/gcc/passes.c:1758
  0xb83183 execute_todo
  /home/mjambor/gcc/mine/src/gcc/passes.c:1815

The problem is exactly what the verifier complains about, a clobber of
an SSA_NAME which I agree with the verifier is a really bad idea.

If you want SRA to produce information that at a given point a scalar
replacement (which will become an SSA_NAME) does not have any valid
data, the way to represent that is to load it with a value from a
default-definition SSA name.  Something along the lines of
get_repl_default_def_ssa_name which unfortunately you cannot directly
use without confusing the SSA renamer.

The easiest way, at least to test a proof of concept, is probably to
create another declaration of the same type (reusing bits from
create_access_replacement, especially setting the same
DECL_DEBUG_EXPR), get its default-definition using
get_or_create_ssa_default_def and then assign that to the replacement
instead of trying to clobber it.

(A more correct approach would be to design a way of telling the
renamer that at this point the scalar becomes undefined and that it
should start using default-defs until the next definition appears but
that is likely to be difficult, although that is just my guess, it
might be easy.)

 Would it be ok to commit the tree-sra.c change?

I don't think so, sorry about the bad news.

Martin


Re: SRA: don't drop clobbers

2014-11-03 Thread Marc Glisse

On Mon, 3 Nov 2014, Martin Jambor wrote:


On Mon, Nov 03, 2014 at 01:59:24PM +0100, Marc Glisse wrote:

Hello,

now that the update_address_taken patch is in, let me re-post the
SRA follow-up. With this patch, testcase pr60517.C (attached) has a
use of an undefined variable at the time of the uninit pass. Sadly,
while this warned with earlier versions of the other patch (when I
was inserting default definitions of new variables), it does not
anymore because we have TREE_NO_WARNING all over the place. Still, I
believe this is a step in the right direction, and it passed
bootstrap+testsuite (minus the new testcase).


I am not sure what you mean by minus the new testcase but, with the
gimple checking compiler at least, the testcase produces an ICE:

 pr60517.C: In function ‘double foo(A)’:
 pr60517.C:15:1: error: non-decl/MEM_REF LHS in clobber statement
  }
  ^
 SR.1_8
 SR.1_8 ={v} {CLOBBER};
 pr60517.C:15:1: internal compiler error: verify_gimple failed
 0xc7810d verify_gimple_in_cfg(function*, bool)
 /home/mjambor/gcc/mine/src/gcc/tree-cfg.c:5039
 0xb8256f execute_function_todo
 /home/mjambor/gcc/mine/src/gcc/passes.c:1758
 0xb83183 execute_todo
 /home/mjambor/gcc/mine/src/gcc/passes.c:1815

The problem is exactly what the verifier complains about, a clobber of
an SSA_NAME which I agree with the verifier is a really bad idea.

If you want SRA to produce information that at a given point a scalar
replacement (which will become an SSA_NAME) does not have any valid
data, the way to represent that is to load it with a value from a
default-definition SSA name.  Something along the lines of
get_repl_default_def_ssa_name which unfortunately you cannot directly
use without confusing the SSA renamer.

The easiest way, at least to test a proof of concept, is probably to
create another declaration of the same type (reusing bits from
create_access_replacement, especially setting the same
DECL_DEBUG_EXPR), get its default-definition using
get_or_create_ssa_default_def and then assign that to the replacement
instead of trying to clobber it.

(A more correct approach would be to design a way of telling the
renamer that at this point the scalar becomes undefined and that it
should start using default-defs until the next definition appears but
that is likely to be difficult, although that is just my guess, it
might be easy.)


Would it be ok to commit the tree-sra.c change?


I don't think so, sorry about the bad news.


Thanks for your help. I am quite confused. I am not seeing the failure you 
mention, but since I am building from trunk with no specific option I 
should be getting gimple checking.


The way I expect things to work:
1) we have a clobber for a variable V
2) SRA creates a variable SR and replaces uses of V
3) (new) next to V's clobber, we insert a clobber for SR
4) update_address_taken notices that SR does not have its address taken, 
and thus replaces it by SSA_NAMEs, and after the clobber by an undefined 
variable (yesterday it would just have removed the clobber).


What you describe in a parenthesis about the renamer is pretty much what I 
think rewrite_update_stmt does, with the clobber as the hint.


Do you have further comments, based on these explanations, that could help 
me pinpoint what is going wrong?


--
Marc Glisse


Re: SRA: don't drop clobbers

2014-11-03 Thread Martin Jambor
Hi,

On Mon, Nov 03, 2014 at 05:17:22PM +0100, Marc Glisse wrote:
 On Mon, 3 Nov 2014, Martin Jambor wrote:
 On Mon, Nov 03, 2014 at 01:59:24PM +0100, Marc Glisse wrote:
 
 now that the update_address_taken patch is in, let me re-post the
 SRA follow-up. With this patch, testcase pr60517.C (attached) has a
 use of an undefined variable at the time of the uninit pass. Sadly,
 while this warned with earlier versions of the other patch (when I
 was inserting default definitions of new variables), it does not
 anymore because we have TREE_NO_WARNING all over the place. Still, I
 believe this is a step in the right direction, and it passed
 bootstrap+testsuite (minus the new testcase).
 
 I am not sure what you mean by minus the new testcase but, with the
 gimple checking compiler at least, the testcase produces an ICE:
 
  pr60517.C: In function ‘double foo(A)’:
  pr60517.C:15:1: error: non-decl/MEM_REF LHS in clobber statement
   }
   ^
  SR.1_8
  SR.1_8 ={v} {CLOBBER};
  pr60517.C:15:1: internal compiler error: verify_gimple failed
  0xc7810d verify_gimple_in_cfg(function*, bool)
  /home/mjambor/gcc/mine/src/gcc/tree-cfg.c:5039
  0xb8256f execute_function_todo
  /home/mjambor/gcc/mine/src/gcc/passes.c:1758
  0xb83183 execute_todo
  /home/mjambor/gcc/mine/src/gcc/passes.c:1815
 
 The problem is exactly what the verifier complains about, a clobber of
 an SSA_NAME which I agree with the verifier is a really bad idea.
 
 If you want SRA to produce information that at a given point a scalar
 replacement (which will become an SSA_NAME) does not have any valid
 data, the way to represent that is to load it with a value from a
 default-definition SSA name.  Something along the lines of
 get_repl_default_def_ssa_name which unfortunately you cannot directly
 use without confusing the SSA renamer.
 
 The easiest way, at least to test a proof of concept, is probably to
 create another declaration of the same type (reusing bits from
 create_access_replacement, especially setting the same
 DECL_DEBUG_EXPR), get its default-definition using
 get_or_create_ssa_default_def and then assign that to the replacement
 instead of trying to clobber it.
 
 (A more correct approach would be to design a way of telling the
 renamer that at this point the scalar becomes undefined and that it
 should start using default-defs until the next definition appears but
 that is likely to be difficult, although that is just my guess, it
 might be easy.)
 
 Would it be ok to commit the tree-sra.c change?
 
 I don't think so, sorry about the bad news.
 
 Thanks for your help. I am quite confused. I am not seeing the
 failure you mention, but since I am building from trunk with no
 specific option I should be getting gimple checking.
 
 The way I expect things to work:
 1) we have a clobber for a variable V
 2) SRA creates a variable SR and replaces uses of V
 3) (new) next to V's clobber, we insert a clobber for SR
 4) update_address_taken notices that SR does not have its address
 taken, and thus replaces it by SSA_NAMEs, and after the clobber by
 an undefined variable (yesterday it would just have removed the
 clobber).

update_address_taken?  The conversion to SSA form is done by means of
returning TODO_update_ssa from the (early) SRA pass (which is what I
mean by the renamer).

 
 What you describe in a parenthesis about the renamer is pretty much
 what I think rewrite_update_stmt does, with the clobber as the hint.
 
 Do you have further comments, based on these explanations, that
 could help me pinpoint what is going wrong?

I just applied your patch on top of trunk revision 217032 on my
x86_64-linux (openSUSE 13.1) desktop, configured with

/home/mjambor/gcc/mine/src/configure --prefix=/home/mjambor/gcc/mine/inst 
--enable-languages=c,c++ --enable-checking=yes --disable-bootstrap 
--with-plugin-ld=/home/mjambor/binutils/obj/gold/ld-new --disable-libsanitizer 
--disable-multilib

built with simple make -j8, 

and ran the testcase with make -k check RUNTESTFLAGS=dg.exp=pr60517.C

And the error popped out in gcc/testsuite/g++/g++.log.  I really can't
think of reason why you don't see it.

But I do and little wonder, really, given the second condition in
verify_gimple_assign_single, which is there for more than a year.
Looking at the dumped statement it seems that the LHS is already an
SSA_NAME.  Moreover, when I dumped the erroneous body in gdb, I have
not seen any default definitions anywhere.  So if your intention was
to teach the renamer to turn this into default definitions, it does
not work and update_ssa did not get the hint.

Martin


Re: SRA: don't drop clobbers

2014-11-03 Thread Marc Glisse

On Mon, 3 Nov 2014, Martin Jambor wrote:


I just applied your patch on top of trunk revision 217032 on my


Ah, that explains it, thanks. This patch is a follow-up to r217034. Still, 
I didn't expect the ICE you are seeing by applying this patch to older 
trunk, I'll try to reproduce that.


--
Marc Glisse


Re: SRA: don't drop clobbers

2014-11-03 Thread Marc Glisse

On Mon, 3 Nov 2014, Marc Glisse wrote:


On Mon, 3 Nov 2014, Martin Jambor wrote:


I just applied your patch on top of trunk revision 217032 on my


Ah, that explains it, thanks. This patch is a follow-up to r217034. Still, I 
didn't expect the ICE you are seeing by applying this patch to older trunk, 
I'll try to reproduce that.


It is TODO_update_address_taken that used to remove clobbers, and as you 
said ESRA goes straight to TODO_update_ssa, which explains why the 
clobbers caused trouble. In any case, after r217034, update_ssa should 
handle clobbers much better. Could you take an other look based on a more 
recent trunk, please?


--
Marc Glisse


Re: SRA: don't drop clobbers

2014-07-10 Thread Richard Biener
On Mon, Jun 30, 2014 at 1:38 AM, Marc Glisse marc.gli...@inria.fr wrote:
 Hello,

 with this patch on top of
 https://gcc.gnu.org/ml/gcc-patches/2014-06/msg02315.html
 we finally warn for the testcase of PR 60517.

 The new function is copied from init_subtree_with_zero right above. I guess
 it might be possible to merge them into a single function, if desired. I
 don't understand the debug stuff, but hopefully by keeping the functions
 similar enough it shouldn't be too broken.

 When we see a clobber during scalarization, instead of dropping it, we add a
 clobber to the new variable, which the previous patch turns into an SSA_NAME
 with a default def. Then either we reach uninit and warn, or the variable
 appears in a PHI and CCP optimizes.

 Bootstrap+testsuite (all,obj-c++,ada,go) on x86_64-linux-gnu.


 2014-07-01  Marc Glisse  marc.gli...@inria.fr

 PR c++/60517
 PR tree-optimization/60770
 gcc/
 * tree-sra.c (clobber_subtree): New function.
 (sra_modify_constructor_assign): Call it.
 gcc/testsuite/
 * g++.dg/tree-ssa/pr60517.C: New file.

 --
 Marc Glisse
 Index: gcc/tree-sra.c
 ===
 --- gcc/tree-sra.c  (revision 212126)
 +++ gcc/tree-sra.c  (working copy)
 @@ -2727,20 +2727,58 @@ init_subtree_with_zero (struct access *a
if (insert_after)
 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
else
 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
  }

for (child = access-first_child; child; child = child-next_sibling)
  init_subtree_with_zero (child, gsi, insert_after, loc);
  }


Missing comment.

 +static void
 +clobber_subtree (struct access *access, gimple_stmt_iterator *gsi,
 +   bool insert_after, location_t loc)
 +
 +{
 +  struct access *child;
 +
 +  if (access-grp_to_be_replaced)
 +{
 +  tree rep = get_access_replacement (access);
 +  tree clobber = build_constructor (access-type, NULL);
 +  TREE_THIS_VOLATILE (clobber) = 1;
 +  gimple stmt = gimple_build_assign (rep, clobber);
 +
 +  if (insert_after)
 +   gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
 +  else
 +   gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
 +  update_stmt (stmt);
 +  gimple_set_location (stmt, loc);
 +}
 +  else if (access-grp_to_be_debug_replaced)
 +{

Why would we care to create clobbers for debug stmts?!  Are those
even valid?

Otherwise this looks good I think.

Richard.

 +  tree rep = get_access_replacement (access);
 +  tree clobber = build_constructor (access-type, NULL);
 +  TREE_THIS_VOLATILE (clobber) = 1;
 +  gimple ds = gimple_build_debug_bind (rep, clobber, gsi_stmt (*gsi));
 +
 +  if (insert_after)
 +   gsi_insert_after (gsi, ds, GSI_NEW_STMT);
 +  else
 +   gsi_insert_before (gsi, ds, GSI_SAME_STMT);
 +}
 +
 +  for (child = access-first_child; child; child = child-next_sibling)
 +clobber_subtree (child, gsi, insert_after, loc);
 +}
 +
  /* Search for an access representative for the given expression EXPR and
 return it or NULL if it cannot be found.  */

  static struct access *
  get_access_for_expr (tree expr)
  {
HOST_WIDE_INT offset, size, max_size;
tree base;

/* FIXME: This should not be necessary but Ada produces V_C_Es with a
 type of
 @@ -3039,43 +3077,41 @@ enum assignment_mod_result { SRA_AM_NONE
  SRA_AM_REMOVED };  /* stmt eliminated */

  /* Modify assignments with a CONSTRUCTOR on their RHS.  STMT contains a
 pointer
 to the assignment and GSI is the statement iterator pointing at it.
 Returns
 the same values as sra_modify_assign.  */

  static enum assignment_mod_result
  sra_modify_constructor_assign (gimple *stmt, gimple_stmt_iterator *gsi)
  {
tree lhs = gimple_assign_lhs (*stmt);
 -  struct access *acc;
 -  location_t loc;
 -
 -  acc = get_access_for_expr (lhs);
 +  struct access *acc = get_access_for_expr (lhs);
if (!acc)
  return SRA_AM_NONE;
 +  location_t loc = gimple_location (*stmt);

if (gimple_clobber_p (*stmt))
  {
 -  /* Remove clobbers of fully scalarized variables, otherwise
 -do nothing.  */
 +  /* Clobber the replacement variable.  */
 +  clobber_subtree (acc, gsi, !acc-grp_covered, loc);
 +  /* Remove clobbers of fully scalarized variables, they are dead.  */
if (acc-grp_covered)
 {
   unlink_stmt_vdef (*stmt);
   gsi_remove (gsi, true);
   release_defs (*stmt);
   return SRA_AM_REMOVED;
 }
else
 -   return SRA_AM_NONE;
 +   return SRA_AM_MODIFIED;
  }

 -  loc = gimple_location (*stmt);
if (vec_safe_length (CONSTRUCTOR_ELTS (gimple_assign_rhs1 (*stmt)))  0)
  {
/* I have never seen this code path trigger but if it can happen the
  following should handle it gracefully.  */
if (access_has_children_p (acc))
 

Re: SRA: don't drop clobbers

2014-07-10 Thread Jakub Jelinek
On Thu, Jul 10, 2014 at 04:54:53PM +0200, Richard Biener wrote:
  +  else if (access-grp_to_be_debug_replaced)
  +{
 
 Why would we care to create clobbers for debug stmts?!  Are those
 even valid?

It is not valid.  Though, the fields supposedly live nowhere after the
clobber, so perhaps one could use
GIMPLE_DEBUG_BIND_NOVALUE instead of the clobber in the
gimple_build_debug_bind call, and drop the previous two lines.
Not sure if it is desirable though, it might cause the debug info to say
something is unavailable even if it still lives in some register or memory
for a few extra instructions.

Alex, what do you think?

  +  tree rep = get_access_replacement (access);
  +  tree clobber = build_constructor (access-type, NULL);
  +  TREE_THIS_VOLATILE (clobber) = 1;
  +  gimple ds = gimple_build_debug_bind (rep, clobber, gsi_stmt (*gsi));
  +
  +  if (insert_after)
  +   gsi_insert_after (gsi, ds, GSI_NEW_STMT);
  +  else
  +   gsi_insert_before (gsi, ds, GSI_SAME_STMT);
  +}
  +
  +  for (child = access-first_child; child; child = child-next_sibling)
  +clobber_subtree (child, gsi, insert_after, loc);
  +}
  +

Jakub


Re: SRA: don't drop clobbers

2014-07-07 Thread Richard Biener
On Mon, Jun 30, 2014 at 1:38 AM, Marc Glisse marc.gli...@inria.fr wrote:
 Hello,

 with this patch on top of
 https://gcc.gnu.org/ml/gcc-patches/2014-06/msg02315.html
 we finally warn for the testcase of PR 60517.

 The new function is copied from init_subtree_with_zero right above. I guess
 it might be possible to merge them into a single function, if desired. I
 don't understand the debug stuff, but hopefully by keeping the functions
 similar enough it shouldn't be too broken.

 When we see a clobber during scalarization, instead of dropping it, we add a
 clobber to the new variable, which the previous patch turns into an SSA_NAME
 with a default def. Then either we reach uninit and warn, or the variable
 appears in a PHI and CCP optimizes.

What's the point of a clobber of sth that was scalarized away?  So ...
can you please explain in more detail?

 Bootstrap+testsuite (all,obj-c++,ada,go) on x86_64-linux-gnu.

The new function needs a comment.

Richard.


 2014-07-01  Marc Glisse  marc.gli...@inria.fr

 PR c++/60517
 PR tree-optimization/60770
 gcc/
 * tree-sra.c (clobber_subtree): New function.
 (sra_modify_constructor_assign): Call it.
 gcc/testsuite/
 * g++.dg/tree-ssa/pr60517.C: New file.

 --
 Marc Glisse
 Index: gcc/tree-sra.c
 ===
 --- gcc/tree-sra.c  (revision 212126)
 +++ gcc/tree-sra.c  (working copy)
 @@ -2727,20 +2727,58 @@ init_subtree_with_zero (struct access *a
if (insert_after)
 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
else
 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
  }

for (child = access-first_child; child; child = child-next_sibling)
  init_subtree_with_zero (child, gsi, insert_after, loc);
  }

 +static void
 +clobber_subtree (struct access *access, gimple_stmt_iterator *gsi,
 +   bool insert_after, location_t loc)
 +
 +{
 +  struct access *child;
 +
 +  if (access-grp_to_be_replaced)
 +{
 +  tree rep = get_access_replacement (access);
 +  tree clobber = build_constructor (access-type, NULL);
 +  TREE_THIS_VOLATILE (clobber) = 1;
 +  gimple stmt = gimple_build_assign (rep, clobber);
 +
 +  if (insert_after)
 +   gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
 +  else
 +   gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
 +  update_stmt (stmt);
 +  gimple_set_location (stmt, loc);
 +}
 +  else if (access-grp_to_be_debug_replaced)
 +{
 +  tree rep = get_access_replacement (access);
 +  tree clobber = build_constructor (access-type, NULL);
 +  TREE_THIS_VOLATILE (clobber) = 1;
 +  gimple ds = gimple_build_debug_bind (rep, clobber, gsi_stmt (*gsi));
 +
 +  if (insert_after)
 +   gsi_insert_after (gsi, ds, GSI_NEW_STMT);
 +  else
 +   gsi_insert_before (gsi, ds, GSI_SAME_STMT);
 +}
 +
 +  for (child = access-first_child; child; child = child-next_sibling)
 +clobber_subtree (child, gsi, insert_after, loc);
 +}
 +
  /* Search for an access representative for the given expression EXPR and
 return it or NULL if it cannot be found.  */

  static struct access *
  get_access_for_expr (tree expr)
  {
HOST_WIDE_INT offset, size, max_size;
tree base;

/* FIXME: This should not be necessary but Ada produces V_C_Es with a
 type of
 @@ -3039,43 +3077,41 @@ enum assignment_mod_result { SRA_AM_NONE
  SRA_AM_REMOVED };  /* stmt eliminated */

  /* Modify assignments with a CONSTRUCTOR on their RHS.  STMT contains a
 pointer
 to the assignment and GSI is the statement iterator pointing at it.
 Returns
 the same values as sra_modify_assign.  */

  static enum assignment_mod_result
  sra_modify_constructor_assign (gimple *stmt, gimple_stmt_iterator *gsi)
  {
tree lhs = gimple_assign_lhs (*stmt);
 -  struct access *acc;
 -  location_t loc;
 -
 -  acc = get_access_for_expr (lhs);
 +  struct access *acc = get_access_for_expr (lhs);
if (!acc)
  return SRA_AM_NONE;
 +  location_t loc = gimple_location (*stmt);

if (gimple_clobber_p (*stmt))
  {
 -  /* Remove clobbers of fully scalarized variables, otherwise
 -do nothing.  */
 +  /* Clobber the replacement variable.  */
 +  clobber_subtree (acc, gsi, !acc-grp_covered, loc);
 +  /* Remove clobbers of fully scalarized variables, they are dead.  */
if (acc-grp_covered)
 {
   unlink_stmt_vdef (*stmt);
   gsi_remove (gsi, true);
   release_defs (*stmt);
   return SRA_AM_REMOVED;
 }
else
 -   return SRA_AM_NONE;
 +   return SRA_AM_MODIFIED;
  }

 -  loc = gimple_location (*stmt);
if (vec_safe_length (CONSTRUCTOR_ELTS (gimple_assign_rhs1 (*stmt)))  0)
  {
/* I have never seen this code path trigger but if it can happen the
  following should handle it gracefully.  */
if (access_has_children_p (acc))
 

Re: SRA: don't drop clobbers

2014-07-07 Thread Marc Glisse

On Mon, 7 Jul 2014, Richard Biener wrote:


On Mon, Jun 30, 2014 at 1:38 AM, Marc Glisse marc.gli...@inria.fr wrote:

Hello,

with this patch on top of
https://gcc.gnu.org/ml/gcc-patches/2014-06/msg02315.html
we finally warn for the testcase of PR 60517.

The new function is copied from init_subtree_with_zero right above. I guess
it might be possible to merge them into a single function, if desired. I
don't understand the debug stuff, but hopefully by keeping the functions
similar enough it shouldn't be too broken.

When we see a clobber during scalarization, instead of dropping it, we add a
clobber to the new variable, which the previous patch turns into an SSA_NAME
with a default def. Then either we reach uninit and warn, or the variable
appears in a PHI and CCP optimizes.


What's the point of a clobber of sth that was scalarized away?  So ...
can you please explain in more detail?


The main idea of these patches is that when we read from a place that was 
clobbered, instead of dropping the clobber and reading what was there 
before, we can use a variable with a default definition to mark that the 
content is undefined. This enables both warnings and optimizations.


The previous patch makes update_ssa handle replacing clobbers with default 
definitions when a variable doesn't have its address taken anymore. When 
SRA scalarizes, it creates a new variable and relies on update_ssa to 
finish the job. So I am inserting a clobber on the new variable so that 
update_ssa knows to use a default definition.



The new function needs a comment.


Indeed, I'll add one once the conversation on the first patch converges.

Thanks,

--
Marc Glisse


Re: SRA: don't drop clobbers

2014-07-07 Thread Jeff Law

On 07/07/14 02:56, Richard Biener wrote:

On Mon, Jun 30, 2014 at 1:38 AM, Marc Glisse marc.gli...@inria.fr wrote:

Hello,

with this patch on top of
https://gcc.gnu.org/ml/gcc-patches/2014-06/msg02315.html
we finally warn for the testcase of PR 60517.

The new function is copied from init_subtree_with_zero right above. I guess
it might be possible to merge them into a single function, if desired. I
don't understand the debug stuff, but hopefully by keeping the functions
similar enough it shouldn't be too broken.

When we see a clobber during scalarization, instead of dropping it, we add a
clobber to the new variable, which the previous patch turns into an SSA_NAME
with a default def. Then either we reach uninit and warn, or the variable
appears in a PHI and CCP optimizes.


What's the point of a clobber of sth that was scalarized away?  So ...
can you please explain in more detail?
Marc is trying to exploit the undefinedness of the object that exists 
after the CLOBBER.  When we scalaraize, we are losing the undefinedness 
quality of the object.


It's very similar to what's already happening in tree-into-ssa, he's 
just handling it in another place.


Jeff



Re: SRA: don't drop clobbers

2014-07-07 Thread Richard Biener
On July 7, 2014 11:32:10 AM CEST, Marc Glisse marc.gli...@inria.fr wrote:
On Mon, 7 Jul 2014, Richard Biener wrote:

 On Mon, Jun 30, 2014 at 1:38 AM, Marc Glisse marc.gli...@inria.fr
wrote:
 Hello,

 with this patch on top of
 https://gcc.gnu.org/ml/gcc-patches/2014-06/msg02315.html
 we finally warn for the testcase of PR 60517.

 The new function is copied from init_subtree_with_zero right above.
I guess
 it might be possible to merge them into a single function, if
desired. I
 don't understand the debug stuff, but hopefully by keeping the
functions
 similar enough it shouldn't be too broken.

 When we see a clobber during scalarization, instead of dropping it,
we add a
 clobber to the new variable, which the previous patch turns into an
SSA_NAME
 with a default def. Then either we reach uninit and warn, or the
variable
 appears in a PHI and CCP optimizes.

 What's the point of a clobber of sth that was scalarized away?  So
...
 can you please explain in more detail?

The main idea of these patches is that when we read from a place that
was 
clobbered, instead of dropping the clobber and reading what was there 
before, we can use a variable with a default definition to mark that
the 
content is undefined. This enables both warnings and optimizations.

The previous patch makes update_ssa handle replacing clobbers with
default 
definitions when a variable doesn't have its address taken anymore.
When 
SRA scalarizes, it creates a new variable and relies on update_ssa to 
finish the job. So I am inserting a clobber on the new variable so that

update_ssa knows to use a default definition.

OK.  But can't SRA simply replace the reads with undef SSA names when the use 
is dominated by a clobber?

(I've long wanted to teach it some flow sensitivity by doing the replacements 
within a domwalk)

Richard.

 The new function needs a comment.

Indeed, I'll add one once the conversation on the first patch
converges.

Thanks,




Re: SRA: don't drop clobbers

2014-07-07 Thread Marc Glisse

On Mon, 7 Jul 2014, Richard Biener wrote:

The main idea of these patches is that when we read from a place that 
was clobbered, instead of dropping the clobber and reading what was 
there before, we can use a variable with a default definition to mark 
that the content is undefined. This enables both warnings and 
optimizations.


The previous patch makes update_ssa handle replacing clobbers with 
default definitions when a variable doesn't have its address taken 
anymore. When SRA scalarizes, it creates a new variable and relies on 
update_ssa to finish the job. So I am inserting a clobber on the new 
variable so that update_ssa knows to use a default definition.


OK.  But can't SRA simply replace the reads with undef SSA names when 
the use is dominated by a clobber?


I guess it could, but it seems safer and much simpler to avoid duplicating 
the logic.


SRA creates a new variable and replaces uses of the old one by uses of the 
new one. update_address_taken then handles replacing the new variable by a 
bunch of SSA_NAMEs, tracking which use corresponds to which def, so it 
seems natural to let it handle the clobber as well. Also, conceptually, 
saying that when the full variable is clobbered the subvariable is 
clobbered as well is a rather obvious operation.


Otherwise, I could create an extra variable tmp, with the same type as the 
new variable, and replace the clobber by an assignment of the default 
definition of tmp to the new variable. update_address_taken will then see 
a regular assignment and handle it as usual (create a new SSA_NAME for 
it). So instead of creating a clobber that is immediatly replaced with a 
NOP, this creates an extra SSA_NAME that only disappears in the next 
propagation pass.


Handling the reads myself directly in SRA and replacing them with undef 
SSA_NAMEs doesn't seem to fit well with how SRA works. It would certainly 
be possible, but would require quite a bit of new code. Also, the 
domination relation between the clobber and the reads is not always 
obvious and may require some PHIs in between.


--
Marc Glisse


SRA: don't drop clobbers

2014-06-29 Thread Marc Glisse

Hello,

with this patch on top of
https://gcc.gnu.org/ml/gcc-patches/2014-06/msg02315.html
we finally warn for the testcase of PR 60517.

The new function is copied from init_subtree_with_zero right above. I 
guess it might be possible to merge them into a single function, if 
desired. I don't understand the debug stuff, but hopefully by keeping the 
functions similar enough it shouldn't be too broken.


When we see a clobber during scalarization, instead of dropping it, we add 
a clobber to the new variable, which the previous patch turns into an 
SSA_NAME with a default def. Then either we reach uninit and warn, or the 
variable appears in a PHI and CCP optimizes.


Bootstrap+testsuite (all,obj-c++,ada,go) on x86_64-linux-gnu.


2014-07-01  Marc Glisse  marc.gli...@inria.fr

PR c++/60517
PR tree-optimization/60770
gcc/
* tree-sra.c (clobber_subtree): New function.
(sra_modify_constructor_assign): Call it.
gcc/testsuite/
* g++.dg/tree-ssa/pr60517.C: New file.

--
Marc GlisseIndex: gcc/tree-sra.c
===
--- gcc/tree-sra.c  (revision 212126)
+++ gcc/tree-sra.c  (working copy)
@@ -2727,20 +2727,58 @@ init_subtree_with_zero (struct access *a
   if (insert_after)
gsi_insert_after (gsi, ds, GSI_NEW_STMT);
   else
gsi_insert_before (gsi, ds, GSI_SAME_STMT);
 }
 
   for (child = access-first_child; child; child = child-next_sibling)
 init_subtree_with_zero (child, gsi, insert_after, loc);
 }
 
+static void
+clobber_subtree (struct access *access, gimple_stmt_iterator *gsi,
+   bool insert_after, location_t loc)
+
+{
+  struct access *child;
+
+  if (access-grp_to_be_replaced)
+{
+  tree rep = get_access_replacement (access);
+  tree clobber = build_constructor (access-type, NULL);
+  TREE_THIS_VOLATILE (clobber) = 1;
+  gimple stmt = gimple_build_assign (rep, clobber);
+
+  if (insert_after)
+   gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
+  else
+   gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
+  update_stmt (stmt);
+  gimple_set_location (stmt, loc);
+}
+  else if (access-grp_to_be_debug_replaced)
+{
+  tree rep = get_access_replacement (access);
+  tree clobber = build_constructor (access-type, NULL);
+  TREE_THIS_VOLATILE (clobber) = 1;
+  gimple ds = gimple_build_debug_bind (rep, clobber, gsi_stmt (*gsi));
+
+  if (insert_after)
+   gsi_insert_after (gsi, ds, GSI_NEW_STMT);
+  else
+   gsi_insert_before (gsi, ds, GSI_SAME_STMT);
+}
+
+  for (child = access-first_child; child; child = child-next_sibling)
+clobber_subtree (child, gsi, insert_after, loc);
+}
+
 /* Search for an access representative for the given expression EXPR and
return it or NULL if it cannot be found.  */
 
 static struct access *
 get_access_for_expr (tree expr)
 {
   HOST_WIDE_INT offset, size, max_size;
   tree base;
 
   /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
@@ -3039,43 +3077,41 @@ enum assignment_mod_result { SRA_AM_NONE
 SRA_AM_REMOVED };  /* stmt eliminated */
 
 /* Modify assignments with a CONSTRUCTOR on their RHS.  STMT contains a pointer
to the assignment and GSI is the statement iterator pointing at it.  Returns
the same values as sra_modify_assign.  */
 
 static enum assignment_mod_result
 sra_modify_constructor_assign (gimple *stmt, gimple_stmt_iterator *gsi)
 {
   tree lhs = gimple_assign_lhs (*stmt);
-  struct access *acc;
-  location_t loc;
-
-  acc = get_access_for_expr (lhs);
+  struct access *acc = get_access_for_expr (lhs);
   if (!acc)
 return SRA_AM_NONE;
+  location_t loc = gimple_location (*stmt);
 
   if (gimple_clobber_p (*stmt))
 {
-  /* Remove clobbers of fully scalarized variables, otherwise
-do nothing.  */
+  /* Clobber the replacement variable.  */
+  clobber_subtree (acc, gsi, !acc-grp_covered, loc);
+  /* Remove clobbers of fully scalarized variables, they are dead.  */
   if (acc-grp_covered)
{
  unlink_stmt_vdef (*stmt);
  gsi_remove (gsi, true);
  release_defs (*stmt);
  return SRA_AM_REMOVED;
}
   else
-   return SRA_AM_NONE;
+   return SRA_AM_MODIFIED;
 }
 
-  loc = gimple_location (*stmt);
   if (vec_safe_length (CONSTRUCTOR_ELTS (gimple_assign_rhs1 (*stmt)))  0)
 {
   /* I have never seen this code path trigger but if it can happen the
 following should handle it gracefully.  */
   if (access_has_children_p (acc))
generate_subtree_copies (acc-first_child, lhs, acc-offset, 0, 0, gsi,
 true, true, loc);
   return SRA_AM_MODIFIED;
 }
 
Index: gcc/testsuite/g++.dg/tree-ssa/pr60517.C
===
--- gcc/testsuite/g++.dg/tree-ssa/pr60517.C (revision 0)
+++