/* Infrastructure for tracking user variable locations and values
throughout compilation.
- Copyright (C) 2010-2014 Free Software Foundation, Inc.
+ Copyright (C) 2010-2015 Free Software Foundation, Inc.
Contributed by Alexandre Oliva <aoliva@redhat.com>.
This file is part of GCC.
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
+#include "predict.h"
+#include "basic-block.h"
#include "valtrack.h"
+#include "hard-reg-set.h"
#include "function.h"
#include "regs.h"
#include "emit-rtl.h"
instructions. */
static rtx
-gen_lowpart_for_debug (enum machine_mode mode, rtx x)
+gen_lowpart_for_debug (machine_mode mode, rtx x)
{
rtx result = gen_lowpart_if_possible (mode, x);
if (result)
the same addresses without modifying the corresponding registers. */
static rtx
-cleanup_auto_inc_dec (rtx src, enum machine_mode mem_mode ATTRIBUTE_UNUSED)
+cleanup_auto_inc_dec (rtx src, machine_mode mem_mode ATTRIBUTE_UNUSED)
{
rtx x = src;
#ifdef AUTO_INC_DEC
{
rtx_insn *next, *end = NEXT_INSN (BB_END (this_basic_block));
rtx loc;
- rtx (*saved_rtl_hook_no_emit) (enum machine_mode, rtx);
+ rtx (*saved_rtl_hook_no_emit) (machine_mode, rtx);
struct rtx_subst_pair p;
p.to = src;
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
int
dead_debug_insert_temp (struct dead_debug_local *debug, unsigned int uregno,
- rtx insn, enum debug_temp_where where)
+ rtx_insn *insn, enum debug_temp_where where)
{
struct dead_debug_use **tailp = &debug->head;
struct dead_debug_use *cur;
the debug temp to. ??? We could bind the debug_expr to a
CONCAT or PARALLEL with the split multi-registers, and
replace them as we found the corresponding sets. */
- else if (REGNO (reg) < FIRST_PSEUDO_REGISTER
- && (hard_regno_nregs[REGNO (reg)][GET_MODE (reg)]
- != hard_regno_nregs[REGNO (reg)][GET_MODE (dest)]))
+ else if (REG_NREGS (reg) != REG_NREGS (dest))
breg = NULL;
/* 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)
{
setting REG in its mode would, we won't know what to bind
the debug temp to. */
else if (REGNO (reg) < FIRST_PSEUDO_REGISTER
- && (hard_regno_nregs[REGNO (reg)][GET_MODE (reg)]
+ && (REG_NREGS (reg)
!= hard_regno_nregs[REGNO (reg)][GET_MODE (dest)]))
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
*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;