aboutsummaryrefslogtreecommitdiff
path: root/gcc/valtrack.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/valtrack.c')
-rw-r--r--gcc/valtrack.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/gcc/valtrack.c b/gcc/valtrack.c
index 804b8e880ed..3dfb8a97aea 100644
--- a/gcc/valtrack.c
+++ b/gcc/valtrack.c
@@ -534,6 +534,22 @@ dead_debug_add (struct dead_debug_local *debug, df_ref use, unsigned int uregno)
bitmap_set_bit (debug->used, uregno);
}
+/* Like lowpart_subreg, but if a subreg is not valid for machine, force
+ it anyway - for use in debug insns. */
+
+static rtx
+debug_lowpart_subreg (machine_mode outer_mode, rtx expr,
+ machine_mode inner_mode)
+{
+ if (inner_mode == VOIDmode)
+ inner_mode = GET_MODE (expr);
+ int offset = subreg_lowpart_offset (outer_mode, inner_mode);
+ rtx ret = simplify_gen_subreg (outer_mode, expr, inner_mode, offset);
+ if (ret)
+ return ret;
+ return gen_rtx_raw_SUBREG (outer_mode, expr, offset);
+}
+
/* If UREGNO is referenced by any entry in DEBUG, emit a debug insn
before or after INSN (depending on WHERE), that binds a (possibly
global) debug temp to the widest-mode use of UREGNO, if WHERE is
@@ -662,9 +678,9 @@ dead_debug_insert_temp (struct dead_debug_local *debug, unsigned int uregno,
/* Ok, it's the same (hardware) REG, but with a different
mode, so SUBREG it. */
else
- breg = lowpart_subreg (GET_MODE (reg),
- cleanup_auto_inc_dec (src, VOIDmode),
- GET_MODE (dest));
+ breg = debug_lowpart_subreg (GET_MODE (reg),
+ cleanup_auto_inc_dec (src, VOIDmode),
+ GET_MODE (dest));
}
else if (GET_CODE (dest) == SUBREG)
{
@@ -684,9 +700,9 @@ dead_debug_insert_temp (struct dead_debug_local *debug, unsigned int uregno,
breg = NULL;
/* Yay, we can use SRC, just adjust its mode. */
else
- breg = lowpart_subreg (GET_MODE (reg),
- cleanup_auto_inc_dec (src, VOIDmode),
- GET_MODE (dest));
+ breg = debug_lowpart_subreg (GET_MODE (reg),
+ cleanup_auto_inc_dec (src, VOIDmode),
+ GET_MODE (dest));
}
/* Oh well, we're out of luck. */
else
@@ -740,7 +756,8 @@ dead_debug_insert_temp (struct dead_debug_local *debug, unsigned int uregno,
*DF_REF_REAL_LOC (cur->use) = dval;
else
*DF_REF_REAL_LOC (cur->use)
- = gen_lowpart_SUBREG (GET_MODE (*DF_REF_REAL_LOC (cur->use)), dval);
+ = debug_lowpart_subreg (GET_MODE (*DF_REF_REAL_LOC (cur->use)), dval,
+ GET_MODE (dval));
/* ??? Should we simplify subreg of subreg? */
bitmap_set_bit (debug->to_rescan, INSN_UID (DF_REF_INSN (cur->use)));
uses = cur->next;