Re: gOlogy: fix debug binds in auto-inc-dec

2018-11-04 Thread Jeff Law
On 10/21/18 2:07 AM, Alexandre Oliva wrote:
> As auto_inc_dec pass combines incs and mems from different insns, it
> often causes regs to temporarily hold a value different from the one
> it would before the transformation.  Debug insns within that range
> would therefore end up binding to the wrong expression after the
> transformation.
> 
> This patch adjusts debug binds in the affected range.
> 
> Regstrapped on x86_64-, i686-, ppc64-, ppc64el-, and aarch64-linux-gnu.
> Ok to install?
> 
> for  gcc/ChangeLog
> 
>   * auto-inc-dec.c: Include valtrack.h.  Improve comments.
>   (reg_next_debug_use): New.
>   (attempt_change): Propagate adjusted expression into affected
>   debug insns.
>   (merge_in_block): Track uses in debug insns.
>   (pass_inc_dec::execute): Allocate and release
>   reg_next_debug_use.
OK.

> ---
>  gcc/auto-inc-dec.c |  128 
> +++-
>  1 file changed, 125 insertions(+), 3 deletions(-)
> 
> diff --git a/gcc/auto-inc-dec.c b/gcc/auto-inc-dec.c
> index e6dc1c30d716..064b8afd4ff9 100644
> --- a/gcc/auto-inc-dec.c
> +++ b/gcc/auto-inc-dec.c
> @@ -509,27 +529,83 @@ attempt_change (rtx new_addr, rtx inc_reg)
>gcc_assert (mov_insn);
>emit_insn_before (mov_insn, inc_insn.insn);
>regno = REGNO (inc_insn.reg0);
> +  /* ??? Could REGNO possibly be used in MEM_INSN other than in
> +  the MEM address, and still die there, so that move_dead_notes
> +  would incorrectly move the note?  */
Perhaps some kind of weird parallel where there's a memory operation of
some sort and some unrelated ALU where REGNO is a source operand in the
ALU and dies?

I'm not immediately aware of any such insn on any target, but I'm far
from an expert in all the odd things ISAs do :-)



Jeff


gOlogy: fix debug binds in auto-inc-dec

2018-10-21 Thread Alexandre Oliva
As auto_inc_dec pass combines incs and mems from different insns, it
often causes regs to temporarily hold a value different from the one
it would before the transformation.  Debug insns within that range
would therefore end up binding to the wrong expression after the
transformation.

This patch adjusts debug binds in the affected range.

Regstrapped on x86_64-, i686-, ppc64-, ppc64el-, and aarch64-linux-gnu.
Ok to install?

for  gcc/ChangeLog

* auto-inc-dec.c: Include valtrack.h.  Improve comments.
(reg_next_debug_use): New.
(attempt_change): Propagate adjusted expression into affected
debug insns.
(merge_in_block): Track uses in debug insns.
(pass_inc_dec::execute): Allocate and release
reg_next_debug_use.
---
 gcc/auto-inc-dec.c |  128 +++-
 1 file changed, 125 insertions(+), 3 deletions(-)

diff --git a/gcc/auto-inc-dec.c b/gcc/auto-inc-dec.c
index e6dc1c30d716..064b8afd4ff9 100644
--- a/gcc/auto-inc-dec.c
+++ b/gcc/auto-inc-dec.c
@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-pass.h"
 #include "dbgcnt.h"
 #include "print-rtl.h"
+#include "valtrack.h"
 
 /* This pass was originally removed from flow.c. However there is
almost nothing that remains of that code.
@@ -53,6 +54,21 @@ along with GCC; see the file COPYING3.  If not see
...
*(a += c) pre
 
+or, alternately,
+
+   a <- b + c
+   ...
+   *b
+
+becomes
+
+   a <- b
+   ...
+   *(a += c) post
+
+This uses a post-add, but it's handled as FORM_PRE_ADD because
+the "increment" insn appears before the memory access.
+
 
   (2) FORM_PRE_INC
a += c
@@ -61,6 +77,7 @@ along with GCC; see the file COPYING3.  If not see
 
 becomes
 
+   ...
*(a += c) pre
 
 
@@ -75,8 +92,8 @@ along with GCC; see the file COPYING3.  If not see
 becomes
 
b <- a
-   ...
*(b += c) post
+   ...
 
 
   (4) FORM_POST_INC
@@ -87,6 +104,8 @@ along with GCC; see the file COPYING3.  If not see
 becomes
 
*(a += c) post
+   ...
+
 
   There are three types of values of c.
 
@@ -393,6 +412,7 @@ dump_mem_insn (FILE *file)
must be compared with the current block.
 */
 
+static rtx_insn **reg_next_debug_use = NULL;
 static rtx_insn **reg_next_use = NULL;
 static rtx_insn **reg_next_inc_use = NULL;
 static rtx_insn **reg_next_def = NULL;
@@ -509,27 +529,83 @@ attempt_change (rtx new_addr, rtx inc_reg)
   gcc_assert (mov_insn);
   emit_insn_before (mov_insn, inc_insn.insn);
   regno = REGNO (inc_insn.reg0);
+  /* ??? Could REGNO possibly be used in MEM_INSN other than in
+the MEM address, and still die there, so that move_dead_notes
+would incorrectly move the note?  */
   if (reg_next_use[regno] == mem_insn.insn)
move_dead_notes (mov_insn, mem_insn.insn, inc_insn.reg0);
   else
move_dead_notes (mov_insn, inc_insn.insn, inc_insn.reg0);
 
   regno = REGNO (inc_insn.reg_res);
+  if (reg_next_debug_use && reg_next_debug_use[regno]
+ && BLOCK_FOR_INSN (reg_next_debug_use[regno]) == bb)
+   {
+ rtx adjres = gen_rtx_PLUS (GET_MODE (inc_insn.reg_res),
+inc_insn.reg_res, inc_insn.reg1);
+ if (dump_file)
+   fprintf (dump_file, "adjusting debug insns\n");
+ propagate_for_debug (PREV_INSN (reg_next_debug_use[regno]),
+  mem_insn.insn,
+  inc_insn.reg_res, adjres, bb);
+ reg_next_debug_use[regno] = NULL;
+   }
   reg_next_def[regno] = mov_insn;
   reg_next_use[regno] = NULL;
+
   regno = REGNO (inc_insn.reg0);
+  if (reg_next_debug_use && reg_next_debug_use[regno]
+ && BLOCK_FOR_INSN (reg_next_debug_use[regno]) == bb
+ && find_reg_note (mov_insn, REG_DEAD, inc_insn.reg0))
+   {
+ if (dump_file)
+   fprintf (dump_file, "remapping debug insns\n");
+ propagate_for_debug (PREV_INSN (reg_next_debug_use[regno]),
+  mem_insn.insn,
+  inc_insn.reg0, inc_insn.reg_res, bb);
+ reg_next_debug_use[regno] = NULL;
+   }
   reg_next_use[regno] = mov_insn;
   df_recompute_luids (bb);
   break;
 
 case FORM_POST_INC:
   regno = REGNO (inc_insn.reg_res);
+  if (reg_next_debug_use && reg_next_debug_use[regno]
+ && BLOCK_FOR_INSN (reg_next_debug_use[regno]) == bb)
+   {
+ rtx adjres = gen_rtx_MINUS (GET_MODE (inc_insn.reg_res),
+ inc_insn.reg_res, inc_insn.reg1);
+ if (dump_file)
+   fprintf (dump_file, "adjusting debug insns\n");
+ propagate_for_debug (PREV_INSN (reg_next_debug_use[regno]),
+