Patchwork Fix VTA sp (and fp) based MEM handling (PR debug/43051, PR debug/43092)

login
register
mail settings
Submitter Alexandre Oliva
Date Sept. 10, 2010, 11:34 p.m.
Message ID <ortylxgokl.fsf@livre.localdomain>
Download mbox | patch
Permalink /patch/64478/
State New
Headers show

Comments

Alexandre Oliva - Sept. 10, 2010, 11:34 p.m.
On Mar 23, 2010, Alexandre Oliva <aoliva@redhat.com> wrote:

> On Mar 15, 2010, Jakub Jelinek <jakub@redhat.com> wrote:

>> One is that cselib doesn't handle autoinc rtls well
>> (Alex has a follow-up patch in which it teaches cselib about these; this
>> final version of the patch doesn't need it for var-tracking though).

> Here it is.  Regstraped on x86_64-linux-gnu, i686-linux-gnu and
> ia64-linux-gnu.  Ok to install?

In bug 43494, Bernd suggested us to track autoinc always, rather than
only within VTA.  I implemented that, splitting out the code needed to
introduce the explicit selection into a separate patch.

I also dropped the _addr renamed functions, and adjusted the few callers
that didn't pass a mode for the enclosing MEM.

I found out VTA, for reasons I didn't investigate, could somehow do
without cselib_invalidate_rtx() for autoinc-modified parameters, but
other passes failed without that.  I ended up introducing a loop to
explicitly invalidate dests of implicit autoinc sets.

The first patch implements unconditional autoinc support in cselib.  I
have regstrapped it on x86_64-linux-gnu and i686-linux-gnu.  Ok to
install?

The second patch makes autoinc support in cselib optional, making some
code conditional and conditionally restoring special-case handling that
could be removed if autoinc was unconditional.  I have *not* completed
its regstrap yet.  Should I?
Steven Bosscher - Sept. 11, 2010, 10:31 a.m.
On Sat, Sep 11, 2010 at 1:34 AM, Alexandre Oliva <aoliva@redhat.com> wrote:
> The first patch implements unconditional autoinc support in cselib.  I
> have regstrapped it on x86_64-linux-gnu and i686-linux-gnu.  Ok to
> install?

You should document what the arguments are here:

>  +typedef int (*for_each_inc_dec_fn) (rtx, rtx, rtx, rtx, rtx, void *);

and here too:

> +int
> +for_each_inc_dec (rtx *insn,
> +		  for_each_inc_dec_fn fn,
> +		  void *arg)

Looks like INSN doesn't have to be an insn, so maybe not call the
argument INSN but X just like in for_each_rtx.


> -	    cselib_lookup_from_insn (XEXP (t, 0), address_mode, 1, insn);
> -	    XEXP (t, 0) = cselib_subst_to_values (XEXP (t, 0));
> +	    cselib_lookup_from_insn (XEXP (t, 0), address_mode, 1,
> +				     GET_MODE (x), insn);
> +	    XEXP (t, 0) = cselib_subst_to_values (XEXP (t, 0), GET_MODE (x));

GET_MODE (t)?  I know t is a copy of x at this point so it makes no
real difference, but the existing code looks at the properties of t
here and IMHO it would be better to be consistent about that.
Likewise in the hunk for sel-sched-dump.c

Thanks for working on this,

Ciao!
Steven

Patch

for  gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR debug/43092
	PR debug/43494
	* cselib.h (CSELIB_RECORD_AUTOINC): New enumerator.
	* cselib.c (cselib_record_autoinc): New var.
	(rtx_equal_for_cselib_1): Test it.
	(cselib_hash_rtx): Likewise.
	(cselib_subst_to_values): Likewise.
	(cselib_record_sets): Likewise.  Move autoinc data into conditional.
	(cselib_init): Initialize cselib_record_autoinc.
	* var-tracking.c (vt_initialize): Pass CSELIB_RECORD_AUTOINC to
	cselib_init.

Index: gcc/cselib.h
===================================================================
--- gcc/cselib.h.orig	2010-09-10 20:24:28.000000000 -0300
+++ gcc/cselib.h	2010-09-10 20:26:34.000000000 -0300
@@ -69,7 +69,8 @@  struct cselib_set
 enum cselib_record_what
 {
   CSELIB_RECORD_MEMORY = 1,
-  CSELIB_PRESERVE_CONSTANTS = 2
+  CSELIB_PRESERVE_CONSTANTS = 2,
+  CSELIB_RECORD_AUTOINC = 4
 };
 
 extern void (*cselib_discard_hook) (cselib_val *);
Index: gcc/cselib.c
===================================================================
--- gcc/cselib.c.orig	2010-09-10 20:24:28.000000000 -0300
+++ gcc/cselib.c	2010-09-10 20:28:29.000000000 -0300
@@ -47,6 +47,7 @@  along with GCC; see the file COPYING3.  
 
 static bool cselib_record_memory;
 static bool cselib_preserve_constants;
+static bool cselib_record_autoinc;
 static int entry_and_rtx_equal_p (const void *, const void *);
 static hashval_t get_value_hash (const void *);
 static struct elt_list *new_elt_list (struct elt_list *, cselib_val *);
@@ -764,6 +765,9 @@  rtx_equal_for_cselib_1 (rtx x, rtx y, en
       rtx xorig = x, yorig = y;
       rtx xoff = NULL, yoff = NULL;
 
+      if (!cselib_record_autoinc)
+	return 0;
+
       x = autoinc_split (x, &xoff, memmode);
       y = autoinc_split (y, &yoff, memmode);
 
@@ -988,6 +992,8 @@  cselib_hash_rtx (rtx x, int create, enum
     case PRE_DEC:
     case PRE_INC:
       /* We can't compute these without knowing the MEM mode.  */
+      if (!cselib_record_autoinc)
+	return 0;
       gcc_assert (memmode != VOIDmode);
       i = GET_MODE_SIZE (memmode);
       if (code == PRE_DEC)
@@ -998,12 +1004,16 @@  cselib_hash_rtx (rtx x, int create, enum
       return hash ? hash : 1 + (unsigned) PLUS;
 
     case PRE_MODIFY:
+      if (!cselib_record_autoinc)
+	return 0;
       gcc_assert (memmode != VOIDmode);
       return cselib_hash_rtx (XEXP (x, 1), create, memmode);
 
     case POST_DEC:
     case POST_INC:
     case POST_MODIFY:
+      if (!cselib_record_autoinc)
+	return 0;
       gcc_assert (memmode != VOIDmode);
       return cselib_hash_rtx (XEXP (x, 0), create, memmode);
 
@@ -1622,7 +1632,8 @@  cselib_expand_value_rtx_1 (rtx orig, str
    to registers and memory.
    X isn't actually modified; if modifications are needed, new rtl is
    allocated.  However, the return value can share rtl with X.
-   If X is within a MEM, MEMMODE must be the mode of the MEM.  */
+   If X is within a MEM, MEMMODE must be the mode of the MEM if
+   cselib_record_autoinc holds.  */
 
 rtx
 cselib_subst_to_values (rtx x, enum machine_mode memmode)
@@ -1664,6 +1675,12 @@  cselib_subst_to_values (rtx x, enum mach
 
     case PRE_DEC:
     case PRE_INC:
+      if (!cselib_record_autoinc)
+	{
+	no_autoinc:
+	  e = new_cselib_val (next_uid, GET_MODE (x), x);
+	  return e->val_rtx;
+	}
       gcc_assert (memmode != VOIDmode);
       i = GET_MODE_SIZE (memmode);
       if (code == PRE_DEC)
@@ -1672,12 +1689,16 @@  cselib_subst_to_values (rtx x, enum mach
 				     memmode);
 
     case PRE_MODIFY:
+      if (!cselib_record_autoinc)
+	goto no_autoinc;
       gcc_assert (memmode != VOIDmode);
       return cselib_subst_to_values (XEXP (x, 1), memmode);
 
     case POST_DEC:
     case POST_INC:
     case POST_MODIFY:
+      if (!cselib_record_autoinc)
+	goto no_autoinc;
       gcc_assert (memmode != VOIDmode);
       return cselib_subst_to_values (XEXP (x, 0), memmode);
 
@@ -2074,6 +2095,13 @@  cselib_invalidate_rtx (rtx dest)
     cselib_invalidate_regno (REGNO (dest), GET_MODE (dest));
   else if (MEM_P (dest))
     cselib_invalidate_mem (dest);
+
+  /* Some machines don't define AUTO_INC_DEC, but they still use push
+     instructions.  We need to catch that case here in order to
+     invalidate the stack pointer correctly.  Note that invalidating
+     the stack pointer is different from invalidating DEST.  */
+  if (!cselib_record_autoinc && push_operand (dest, GET_MODE (dest)))
+    cselib_invalidate_rtx (stack_pointer_rtx);
 }
 
 /* A wrapper for cselib_invalidate_rtx to be called via note_stores.  */
@@ -2176,7 +2204,6 @@  cselib_record_sets (rtx insn)
   rtx body = PATTERN (insn);
   rtx cond = 0;
   int n_sets_before_autoinc;
-  struct cselib_record_autoinc_data data;
 
   body = PATTERN (insn);
   if (GET_CODE (body) == COND_EXEC)
@@ -2220,10 +2247,16 @@  cselib_record_sets (rtx insn)
 	sets[0].src = XEXP (note, 0);
     }
 
-  data.sets = sets;
-  data.n_sets = n_sets_before_autoinc = n_sets;
-  for_each_inc_dec (&insn, cselib_record_autoinc_cb, &data);
-  n_sets = data.n_sets;
+  if (cselib_record_autoinc)
+    {
+      struct cselib_record_autoinc_data data;
+      data.sets = sets;
+      data.n_sets = n_sets_before_autoinc = n_sets;
+      for_each_inc_dec (&insn, cselib_record_autoinc_cb, &data);
+      n_sets = data.n_sets;
+    }
+  else
+    n_sets_before_autoinc = n_sets;
 
   /* Look up the values that are read.  Do this before invalidating the
      locations that are written.  */
@@ -2397,6 +2430,7 @@  cselib_init (int record_what)
   value_pool = create_alloc_pool ("value", RTX_CODE_SIZE (VALUE), 100);
   cselib_record_memory = record_what & CSELIB_RECORD_MEMORY;
   cselib_preserve_constants = record_what & CSELIB_PRESERVE_CONSTANTS;
+  cselib_record_autoinc = record_what & CSELIB_RECORD_AUTOINC;
 
   /* (mem:BLK (scratch)) is a special mechanism to conflict with everything,
      see canon_true_dependence.  This is only created once.  */
Index: gcc/var-tracking.c
===================================================================
--- gcc/var-tracking.c.orig	2010-09-10 20:24:28.000000000 -0300
+++ gcc/var-tracking.c	2010-09-10 20:26:34.000000000 -0300
@@ -8297,7 +8297,8 @@  vt_initialize (void)
 
   if (MAY_HAVE_DEBUG_INSNS)
     {
-      cselib_init (CSELIB_RECORD_MEMORY | CSELIB_PRESERVE_CONSTANTS);
+      cselib_init (CSELIB_RECORD_MEMORY | CSELIB_PRESERVE_CONSTANTS
+		   | CSELIB_RECORD_AUTOINC);
       scratch_regs = BITMAP_ALLOC (NULL);
       valvar_pool = create_alloc_pool ("small variable_def pool",
 				       sizeof (struct variable_def), 256);