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.
===================================================================
@@ -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 *);
===================================================================
@@ -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. */
===================================================================
@@ -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);