public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* RFC: PATCH to genericize C++ loops to LOOP_EXPR instead of gotos
@ 2014-11-16  7:15 Jason Merrill
  2014-11-17 10:34 ` Richard Biener
  0 siblings, 1 reply; 7+ messages in thread
From: Jason Merrill @ 2014-11-16  7:15 UTC (permalink / raw)
  To: gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 594 bytes --]

I've had a TODO in genericize_cp_loop for a long time suggesting that we 
should genericize to LOOP_EXPR rather than gotos, and now that I need to 
interpret the function body for constexpr evaluation, making this change 
will also simplify that handling.

This change also does away with canonicalizing the condition to the 
bottom of the loop, to avoid the extra goto.  It seems to me that this 
is unnecessary nowadays, since the optimizers are very capable of making 
any necessary transformations, but I'm interested in feedback from other 
people.

Tested x86_64-pc-linux-gnu.

Opinions?

[-- Attachment #2: loop_expr.patch --]
[-- Type: text/x-patch, Size: 4386 bytes --]

commit 1a45860e7757ee054f6bf98bee4ebe5c661dfb90
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Nov 13 23:54:48 2014 -0500

    	* cp-gimplify.c (genericize_cp_loop): Use LOOP_EXPR.
    	(genericize_for_stmt): Handle null statement-list.

diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index e5436bb..81b26d2 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -208,7 +208,7 @@ genericize_cp_loop (tree *stmt_p, location_t start_locus, tree cond, tree body,
 		    void *data)
 {
   tree blab, clab;
-  tree entry = NULL, exit = NULL, t;
+  tree exit = NULL;
   tree stmt_list = NULL;
 
   blab = begin_bc_block (bc_break, start_locus);
@@ -222,64 +222,46 @@ genericize_cp_loop (tree *stmt_p, location_t start_locus, tree cond, tree body,
   cp_walk_tree (&incr, cp_genericize_r, data, NULL);
   *walk_subtrees = 0;
 
-  /* If condition is zero don't generate a loop construct.  */
-  if (cond && integer_zerop (cond))
+  if (cond && TREE_CODE (cond) != INTEGER_CST)
     {
-      if (cond_is_first)
-	{
-	  t = build1_loc (start_locus, GOTO_EXPR, void_type_node,
-			  get_bc_label (bc_break));
-	  append_to_statement_list (t, &stmt_list);
-	}
-    }
-  else
-    {
-      /* Expand to gotos, just like c_finish_loop.  TODO: Use LOOP_EXPR.  */
-      tree top = build1 (LABEL_EXPR, void_type_node,
-			 create_artificial_label (start_locus));
-
-      /* If we have an exit condition, then we build an IF with gotos either
-	 out of the loop, or to the top of it.  If there's no exit condition,
-	 then we just build a jump back to the top.  */
-      exit = build1 (GOTO_EXPR, void_type_node, LABEL_EXPR_LABEL (top));
-
-      if (cond && !integer_nonzerop (cond))
-	{
-	  /* Canonicalize the loop condition to the end.  This means
-	     generating a branch to the loop condition.  Reuse the
-	     continue label, if possible.  */
-	  if (cond_is_first)
-	    {
-	      if (incr)
-		{
-		  entry = build1 (LABEL_EXPR, void_type_node,
-				  create_artificial_label (start_locus));
-		  t = build1_loc (start_locus, GOTO_EXPR, void_type_node,
-				  LABEL_EXPR_LABEL (entry));
-		}
-	      else
-		t = build1_loc (start_locus, GOTO_EXPR, void_type_node,
-				get_bc_label (bc_continue));
-	      append_to_statement_list (t, &stmt_list);
-	    }
-
-	  t = build1 (GOTO_EXPR, void_type_node, get_bc_label (bc_break));
-	  exit = fold_build3_loc (start_locus,
-				  COND_EXPR, void_type_node, cond, exit, t);
-	}
-
-      append_to_statement_list (top, &stmt_list);
+      /* If COND is constant, don't bother building an exit.  If it's false,
+	 we won't build a loop.  If it's true, any exits are in the body.  */
+      location_t cloc = EXPR_LOC_OR_LOC (cond, start_locus);
+      exit = build1_loc (cloc, GOTO_EXPR, void_type_node,
+			 get_bc_label (bc_break));
+      exit = fold_build3_loc (cloc, COND_EXPR, void_type_node, cond,
+			      build_empty_stmt (cloc), exit);
     }
 
+  if (exit && cond_is_first)
+    append_to_statement_list (exit, &stmt_list);
   append_to_statement_list (body, &stmt_list);
   finish_bc_block (&stmt_list, bc_continue, clab);
   append_to_statement_list (incr, &stmt_list);
-  append_to_statement_list (entry, &stmt_list);
-  append_to_statement_list (exit, &stmt_list);
+  if (exit && !cond_is_first)
+    append_to_statement_list (exit, &stmt_list);
+
+  if (!stmt_list)
+    stmt_list = build_empty_stmt (start_locus);
+
+  tree loop;
+  if (cond && integer_zerop (cond))
+    {
+      if (cond_is_first)
+	loop = fold_build3_loc (start_locus, COND_EXPR,
+				void_type_node, cond, stmt_list,
+				build_empty_stmt (start_locus));
+      else
+	loop = stmt_list;
+    }
+  else
+    loop = build1_loc (start_locus, LOOP_EXPR, void_type_node, stmt_list);
+
+  stmt_list = NULL;
+  append_to_statement_list (loop, &stmt_list);
   finish_bc_block (&stmt_list, bc_break, blab);
-
-  if (stmt_list == NULL_TREE)
-    stmt_list = build1 (NOP_EXPR, void_type_node, integer_zero_node);
+  if (!stmt_list)
+    stmt_list = build_empty_stmt (start_locus);
 
   *stmt_p = stmt_list;
 }
@@ -303,6 +285,8 @@ genericize_for_stmt (tree *stmt_p, int *walk_subtrees, void *data)
   genericize_cp_loop (&loop, EXPR_LOCATION (stmt), FOR_COND (stmt),
 		      FOR_BODY (stmt), FOR_EXPR (stmt), 1, walk_subtrees, data);
   append_to_statement_list (loop, &expr);
+  if (expr == NULL_TREE)
+    expr = loop;
   *stmt_p = expr;
 }
 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: RFC: PATCH to genericize C++ loops to LOOP_EXPR instead of gotos
  2014-11-16  7:15 RFC: PATCH to genericize C++ loops to LOOP_EXPR instead of gotos Jason Merrill
@ 2014-11-17 10:34 ` Richard Biener
  2014-11-17 15:56   ` Jason Merrill
  0 siblings, 1 reply; 7+ messages in thread
From: Richard Biener @ 2014-11-17 10:34 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches List

On Sun, Nov 16, 2014 at 6:04 AM, Jason Merrill <jason@redhat.com> wrote:
> I've had a TODO in genericize_cp_loop for a long time suggesting that we
> should genericize to LOOP_EXPR rather than gotos, and now that I need to
> interpret the function body for constexpr evaluation, making this change
> will also simplify that handling.
>
> This change also does away with canonicalizing the condition to the bottom
> of the loop, to avoid the extra goto.  It seems to me that this is
> unnecessary nowadays, since the optimizers are very capable of making any
> necessary transformations, but I'm interested in feedback from other people.
>
> Tested x86_64-pc-linux-gnu.
>
> Opinions?

Lowering less is always nice though I didn't even know GENERIC has
LOOP_EXPR...

Fortran seems to use it though.

Did you inspect generated code for a few testcases?

Thanks,
Richard.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: RFC: PATCH to genericize C++ loops to LOOP_EXPR instead of gotos
  2014-11-17 10:34 ` Richard Biener
@ 2014-11-17 15:56   ` Jason Merrill
  2014-11-17 16:07     ` Richard Biener
  0 siblings, 1 reply; 7+ messages in thread
From: Jason Merrill @ 2014-11-17 15:56 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches List

On 11/17/2014 05:26 AM, Richard Biener wrote:
> Did you inspect generated code for a few testcases?

The generated code for g++.dg/torture/pr37922.C is pretty different at 
-O2, but it's hard for me to tell whether the changes are good, bad, or 
neutral.

Jason

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: RFC: PATCH to genericize C++ loops to LOOP_EXPR instead of gotos
  2014-11-17 15:56   ` Jason Merrill
@ 2014-11-17 16:07     ` Richard Biener
  2014-11-17 18:38       ` Jason Merrill
  0 siblings, 1 reply; 7+ messages in thread
From: Richard Biener @ 2014-11-17 16:07 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches List

On Mon, Nov 17, 2014 at 4:25 PM, Jason Merrill <jason@redhat.com> wrote:
> On 11/17/2014 05:26 AM, Richard Biener wrote:
>>
>> Did you inspect generated code for a few testcases?
>
>
> The generated code for g++.dg/torture/pr37922.C is pretty different at -O2,
> but it's hard for me to tell whether the changes are good, bad, or neutral.

There is always the possibility of running the C++ portion of SPEC CPU 2006...

Richard.

> Jason
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: RFC: PATCH to genericize C++ loops to LOOP_EXPR instead of gotos
  2014-11-17 16:07     ` Richard Biener
@ 2014-11-17 18:38       ` Jason Merrill
  0 siblings, 0 replies; 7+ messages in thread
From: Jason Merrill @ 2014-11-17 18:38 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches List

On 11/17/2014 10:27 AM, Richard Biener wrote:
>> The generated code for g++.dg/torture/pr37922.C is pretty different at -O2,
>> but it's hard for me to tell whether the changes are good, bad, or neutral.
>
> There is always the possibility of running the C++ portion of SPEC CPU 2006...

I ran the tramp3d benchmark over 500 iterations before and after the 
change and couldn't see any measurable difference in runtime.  The 
binary with my change was 0.4% smaller.

I'm going to go ahead and check it in; if a performance hit shows up on 
the automated testing we can revisit the choice.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: RFC: PATCH to genericize C++ loops to LOOP_EXPR instead of gotos
  2014-12-09 23:10 Bernd Edlinger
@ 2014-12-11 11:53 ` Bernd Edlinger
  0 siblings, 0 replies; 7+ messages in thread
From: Bernd Edlinger @ 2014-12-11 11:53 UTC (permalink / raw)
  To: Jason Merrill; +Cc: Richard Biener, gcc-patches


Hi Jason,

I managed to reproduce this fault now.

and entered a bug tracker for it:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64265

any ideas how this patch could move the __tsan_func_entry into the loop?


Thanks
Bernd.

On Wed, 10 Dec 2014 00:10:07, Bernd Edlinger wrote:
>
> Hi Jason,
>
>> I ran the tramp3d benchmark over 500 iterations before and after the
> change and couldn't see any measurable difference in runtime. The
> binary with my
>> change was 0.4% smaller.
> I'm going to go ahead and check it in; if a performance hit shows up on
> the automated testing we can revisit the choice.
>
> Unfortunately, this checkin broke the thread sanitizer:
>
> r217669 | jason | 2014-11-17 20:08:02 +0100 (Mo, 17. Nov 2014) | 2 Zeilen
>
>         * cp-gimplify.c (genericize_cp_loop): Use LOOP_EXPR.
>         (genericize_for_stmt): Handle null statement-list.
>
>
> therefore I would kindly ask you to revert this again.
>
> After that patch some C++ functions moved the call to the __tsan_func_entry into the loop.
> And we get crashes or major memory leaks from this, if the software is compiled with -fsanitize=thread.
>
> This happens in a software package on which I currently work. It is called Softing OPC UA Toolbox.
>
> I found this in the generated assembler code by bisection:
>
> 000000000092747d <_ZNSt12_Destroy_auxILb0EE9__destroyIPN18SoftingOPCToolbox55ValueEEEvT_S5_>:
>   92747d:       55                      push   %rbp
>   92747e:       48 89 e5                mov    %rsp,%rbp
>   927481:       53                      push   %rbx
>   927482:       48 83 ec 18             sub    $0x18,%rsp
>   927486:       48 89 7d e8             mov    %rdi,-0x18(%rbp)
>   92748a:       48 89 75 e0             mov    %rsi,-0x20(%rbp)
>   92748e:       48 8b 45 08             mov    0x8(%rbp),%rax
>   927492:       48 89 c7                mov    %rax,%rdi
>   927495:       e8 26 33 fe ff          callq  90a7c0 <__tsan_func_entry@plt>
>   92749a:       48 8b 45 e8             mov    -0x18(%rbp),%rax
>   92749e:       48 3b 45 e0             cmp    -0x20(%rbp),%rax
>   9274a2:       74 3d                   je     9274e1 <_ZNSt12_Destroy_auxILb0EE9__destroyIPN18SoftingOPCToolbox55ValueEEEvT_S5_+0x64>
>   9274a4:       48 8b 5d e8             mov    -0x18(%rbp),%rbx
>   9274a8:       48 89 d8                mov    %rbx,%rax
>   9274ab:       48 85 db                test   %rbx,%rbx
>   9274ae:       74 0b                   je     9274bb <_ZNSt12_Destroy_auxILb0EE9__destroyIPN18SoftingOPCToolbox55ValueEEEvT_S5_+0x3e>
>   9274b0:       48 89 c2                mov    %rax,%rdx
>   9274b3:       83 e2 07                and    $0x7,%edx
>   9274b6:       48 85 d2                test   %rdx,%rdx
>   9274b9:       74 0f                   je     9274ca <_ZNSt12_Destroy_auxILb0EE9__destroyIPN18SoftingOPCToolbox55ValueEEEvT_S5_+0x4d>
>   9274bb:       48 89 c6                mov    %rax,%rsi
>   9274be:       48 8d 3d 1b a3 f8 00    lea    0xf8a31b(%rip),%rdi        # 18b17e0 <DW.ref.__gxx_personality_v0+0x11878>
>   9274c5:       e8 06 36 fe ff          callq  90aad0 <__ubsan_handle_type_mismatch@plt>
>   9274ca:       48 89 df                mov    %rbx,%rdi
>   9274cd:       e8 1b 09 00 00          callq  927ded <_ZSt11__addressofIN18SoftingOPCToolbox55ValueEEPT_RS2_>
>   9274d2:       48 89 c7                mov    %rax,%rdi
>   9274d5:       e8 21 09 00 00          callq  927dfb <_ZSt8_DestroyIN18SoftingOPCToolbox55ValueEEvPT_>
>   9274da:       48 83 45 e8 20          addq   $0x20,-0x18(%rbp)
>   9274df:       eb ad                   jmp    92748e <_ZNSt12_Destroy_auxILb0EE9__destroyIPN18SoftingOPCToolbox55ValueEEEvT_S5_+0x11>
>   9274e1:       e8 da 2c fe ff          callq  90a1c0 <__tsan_func_exit@plt>
>   9274e6:       48 83 c4 18             add    $0x18,%rsp
>   9274ea:       5b                      pop    %rbx
>   9274eb:       5d                      pop    %rbp
>   9274ec:       c3                      retq
>   9274ed:       90                      nop
>
>
> see the jmp at 9274df: it jumps to _before_ the tsan_func_entry.
> I am not sure how to locate the source code of the above assembler section.
> But I'd guess, it must be some kind of automatically generated default destructor.
>
> All I can say in the moment, that it is was working perfectly before Nov 17.
>
>
> Thanks
> Bernd.
>
 		 	   		  

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: RFC: PATCH to genericize C++ loops to LOOP_EXPR instead of gotos
@ 2014-12-09 23:10 Bernd Edlinger
  2014-12-11 11:53 ` Bernd Edlinger
  0 siblings, 1 reply; 7+ messages in thread
From: Bernd Edlinger @ 2014-12-09 23:10 UTC (permalink / raw)
  To: Jason Merrill; +Cc: Richard Biener, gcc-patches

Hi Jason,

> I ran the tramp3d benchmark over 500 iterations before and after the 
change and couldn't see any measurable difference in runtime.  The 
binary with my
> change was 0.4% smaller.
I'm going to go ahead and check it in; if a performance hit shows up on 
the automated testing we can revisit the choice.

Unfortunately, this checkin broke the thread sanitizer:

r217669 | jason | 2014-11-17 20:08:02 +0100 (Mo, 17. Nov 2014) | 2 Zeilen

        * cp-gimplify.c (genericize_cp_loop): Use LOOP_EXPR.
        (genericize_for_stmt): Handle null statement-list.


therefore I would kindly ask you to revert this again.

After that patch some C++ functions moved the call to the __tsan_func_entry into the loop.
And we get crashes or major memory leaks from this, if the software is compiled with -fsanitize=thread.

This happens in a software package on which I currently work. It is called Softing OPC UA Toolbox.

I found this in the generated assembler code by bisection:

000000000092747d <_ZNSt12_Destroy_auxILb0EE9__destroyIPN18SoftingOPCToolbox55ValueEEEvT_S5_>:
  92747d:       55                      push   %rbp
  92747e:       48 89 e5                mov    %rsp,%rbp
  927481:       53                      push   %rbx
  927482:       48 83 ec 18             sub    $0x18,%rsp
  927486:       48 89 7d e8             mov    %rdi,-0x18(%rbp)
  92748a:       48 89 75 e0             mov    %rsi,-0x20(%rbp)
  92748e:       48 8b 45 08             mov    0x8(%rbp),%rax
  927492:       48 89 c7                mov    %rax,%rdi
  927495:       e8 26 33 fe ff          callq  90a7c0 <__tsan_func_entry@plt>
  92749a:       48 8b 45 e8             mov    -0x18(%rbp),%rax
  92749e:       48 3b 45 e0             cmp    -0x20(%rbp),%rax
  9274a2:       74 3d                   je     9274e1 <_ZNSt12_Destroy_auxILb0EE9__destroyIPN18SoftingOPCToolbox55ValueEEEvT_S5_+0x64>
  9274a4:       48 8b 5d e8             mov    -0x18(%rbp),%rbx
  9274a8:       48 89 d8                mov    %rbx,%rax
  9274ab:       48 85 db                test   %rbx,%rbx
  9274ae:       74 0b                   je     9274bb <_ZNSt12_Destroy_auxILb0EE9__destroyIPN18SoftingOPCToolbox55ValueEEEvT_S5_+0x3e>
  9274b0:       48 89 c2                mov    %rax,%rdx
  9274b3:       83 e2 07                and    $0x7,%edx
  9274b6:       48 85 d2                test   %rdx,%rdx
  9274b9:       74 0f                   je     9274ca <_ZNSt12_Destroy_auxILb0EE9__destroyIPN18SoftingOPCToolbox55ValueEEEvT_S5_+0x4d>
  9274bb:       48 89 c6                mov    %rax,%rsi
  9274be:       48 8d 3d 1b a3 f8 00    lea    0xf8a31b(%rip),%rdi        # 18b17e0 <DW.ref.__gxx_personality_v0+0x11878>
  9274c5:       e8 06 36 fe ff          callq  90aad0 <__ubsan_handle_type_mismatch@plt>
  9274ca:       48 89 df                mov    %rbx,%rdi
  9274cd:       e8 1b 09 00 00          callq  927ded <_ZSt11__addressofIN18SoftingOPCToolbox55ValueEEPT_RS2_>
  9274d2:       48 89 c7                mov    %rax,%rdi
  9274d5:       e8 21 09 00 00          callq  927dfb <_ZSt8_DestroyIN18SoftingOPCToolbox55ValueEEvPT_>
  9274da:       48 83 45 e8 20          addq   $0x20,-0x18(%rbp)
  9274df:       eb ad                   jmp    92748e <_ZNSt12_Destroy_auxILb0EE9__destroyIPN18SoftingOPCToolbox55ValueEEEvT_S5_+0x11>
  9274e1:       e8 da 2c fe ff          callq  90a1c0 <__tsan_func_exit@plt>
  9274e6:       48 83 c4 18             add    $0x18,%rsp
  9274ea:       5b                      pop    %rbx
  9274eb:       5d                      pop    %rbp
  9274ec:       c3                      retq
  9274ed:       90                      nop


see the jmp at 9274df: it jumps to _before_ the tsan_func_entry.
I am not sure how to locate the source code of the above assembler section.
But I'd guess, it must be some kind of automatically generated default destructor. 

All I can say in the moment, that it is was working perfectly before Nov 17.


Thanks
Bernd.
 		 	   		  

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2014-12-11 11:53 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-16  7:15 RFC: PATCH to genericize C++ loops to LOOP_EXPR instead of gotos Jason Merrill
2014-11-17 10:34 ` Richard Biener
2014-11-17 15:56   ` Jason Merrill
2014-11-17 16:07     ` Richard Biener
2014-11-17 18:38       ` Jason Merrill
2014-12-09 23:10 Bernd Edlinger
2014-12-11 11:53 ` Bernd Edlinger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).