summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/var-tracking.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/var-tracking.c')
-rw-r--r--contrib/gcc/var-tracking.c50
1 files changed, 36 insertions, 14 deletions
diff --git a/contrib/gcc/var-tracking.c b/contrib/gcc/var-tracking.c
index d9f21b5..c392b2e 100644
--- a/contrib/gcc/var-tracking.c
+++ b/contrib/gcc/var-tracking.c
@@ -259,6 +259,9 @@ typedef struct variable_def
/* Pointer to the BB's information specific to variable tracking pass. */
#define VTI(BB) ((variable_tracking_info) (BB)->aux)
+/* Macro to access MEM_OFFSET as an HOST_WIDE_INT. Evaluates MEM twice. */
+#define INT_MEM_OFFSET(mem) (MEM_OFFSET (mem) ? INTVAL (MEM_OFFSET (mem)) : 0)
+
/* Alloc pool for struct attrs_def. */
static alloc_pool attrs_pool;
@@ -927,7 +930,7 @@ static void
var_mem_set (dataflow_set *set, rtx loc)
{
tree decl = MEM_EXPR (loc);
- HOST_WIDE_INT offset = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0;
+ HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
decl = var_debug_decl (decl);
@@ -945,7 +948,7 @@ static void
var_mem_delete_and_set (dataflow_set *set, rtx loc, bool modify)
{
tree decl = MEM_EXPR (loc);
- HOST_WIDE_INT offset = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0;
+ HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
decl = var_debug_decl (decl);
@@ -962,7 +965,7 @@ static void
var_mem_delete (dataflow_set *set, rtx loc, bool clobber)
{
tree decl = MEM_EXPR (loc);
- HOST_WIDE_INT offset = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0;
+ HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
decl = var_debug_decl (decl);
if (clobber)
@@ -1540,6 +1543,18 @@ track_expr_p (tree expr)
return 1;
}
+/* Return true if OFFSET is a valid offset for a register or memory
+ access we want to track. This is used to reject out-of-bounds
+ accesses that can cause assertions to fail later. Note that we
+ don't reject negative offsets because they can be generated for
+ paradoxical subregs on big-endian architectures. */
+
+static inline bool
+offset_valid_for_tracked_p (HOST_WIDE_INT offset)
+{
+ return (-MAX_VAR_PARTS < offset) && (offset < MAX_VAR_PARTS);
+}
+
/* Determine whether a given LOC refers to the same variable part as
EXPR+OFFSET. */
@@ -1560,7 +1575,7 @@ same_variable_part_p (rtx loc, tree expr, HOST_WIDE_INT offset)
else if (MEM_P (loc))
{
expr2 = MEM_EXPR (loc);
- offset2 = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0;
+ offset2 = INT_MEM_OFFSET (loc);
}
else
return false;
@@ -1590,7 +1605,8 @@ count_uses (rtx *loc, void *insn)
}
else if (MEM_P (*loc)
&& MEM_EXPR (*loc)
- && track_expr_p (MEM_EXPR (*loc)))
+ && track_expr_p (MEM_EXPR (*loc))
+ && offset_valid_for_tracked_p (INT_MEM_OFFSET (*loc)))
{
VTI (bb)->n_mos++;
}
@@ -1626,14 +1642,19 @@ add_uses (rtx *loc, void *insn)
basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
- mo->type = ((REG_EXPR (*loc) && track_expr_p (REG_EXPR (*loc)))
- ? MO_USE : MO_USE_NO_VAR);
+ if (REG_EXPR (*loc)
+ && track_expr_p (REG_EXPR (*loc))
+ && offset_valid_for_tracked_p (REG_OFFSET (*loc)))
+ mo->type = MO_USE;
+ else
+ mo->type = MO_USE_NO_VAR;
mo->u.loc = *loc;
mo->insn = (rtx) insn;
}
else if (MEM_P (*loc)
&& MEM_EXPR (*loc)
- && track_expr_p (MEM_EXPR (*loc)))
+ && track_expr_p (MEM_EXPR (*loc))
+ && offset_valid_for_tracked_p (INT_MEM_OFFSET (*loc)))
{
basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
@@ -1667,8 +1688,9 @@ add_stores (rtx loc, rtx expr, void *insn)
micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
if (GET_CODE (expr) == CLOBBER
- || ! REG_EXPR (loc)
- || ! track_expr_p (REG_EXPR (loc)))
+ || !(REG_EXPR (loc)
+ && track_expr_p (REG_EXPR (loc))
+ && offset_valid_for_tracked_p (REG_OFFSET (loc))))
mo->type = MO_CLOBBER;
else if (GET_CODE (expr) == SET
&& SET_DEST (expr) == loc
@@ -1683,7 +1705,8 @@ add_stores (rtx loc, rtx expr, void *insn)
}
else if (MEM_P (loc)
&& MEM_EXPR (loc)
- && track_expr_p (MEM_EXPR (loc)))
+ && track_expr_p (MEM_EXPR (loc))
+ && offset_valid_for_tracked_p (INT_MEM_OFFSET (loc)))
{
basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
@@ -1694,8 +1717,7 @@ add_stores (rtx loc, rtx expr, void *insn)
&& SET_DEST (expr) == loc
&& same_variable_part_p (SET_SRC (expr),
MEM_EXPR (loc),
- MEM_OFFSET (loc)
- ? INTVAL (MEM_OFFSET (loc)) : 0))
+ INT_MEM_OFFSET (loc)))
mo->type = MO_COPY;
else
mo->type = MO_SET;
@@ -2726,7 +2748,7 @@ vt_get_decl_and_offset (rtx rtl, tree *declp, HOST_WIDE_INT *offsetp)
if (MEM_ATTRS (rtl))
{
*declp = MEM_EXPR (rtl);
- *offsetp = MEM_OFFSET (rtl) ? INTVAL (MEM_OFFSET (rtl)) : 0;
+ *offsetp = INT_MEM_OFFSET (rtl);
return true;
}
}
OpenPOWER on IntegriCloud