Commit 94a7682d by Richard Sandiford Committed by Richard Sandiford

dse.c (find_shift_sequence): Reinstate "<= UNITS_PER_WORD" condition.

gcc/
	* dse.c (find_shift_sequence): Reinstate "<= UNITS_PER_WORD" condition.
	* var-tracking.c (micro_operation_def): Update comment on u.loc.
	(mode_for_reg_attrs, var_lowpart): New functions.
	(add_uses): Consider recording a lowpart of LOC for MO_USE.
	(add_stores): Likewise MO_SET and MO_COPY.  If the source of a set
	or copy is known, set LOC to the SET that performs the set, instead
	of the destination.
	(find_src_status, find_src_set_src): Remove LOC parameter.
	Replace INSN with the source value.
	(compute_bb_dataflow, emit_notes_in_bb): Check for a SET u.loc when
	handling MO_SET and MO_COPY.  Update the calls to find_src_status
	and find_src_set_src.

From-SVN: r129269
parent 27372c38
2007-10-12 Richard Sandiford <rsandifo@nildram.co.uk>
* dse.c (find_shift_sequence): Reinstate "<= UNITS_PER_WORD" condition.
* var-tracking.c (micro_operation_def): Update comment on u.loc.
(mode_for_reg_attrs, var_lowpart): New functions.
(add_uses): Consider recording a lowpart of LOC for MO_USE.
(add_stores): Likewise MO_SET and MO_COPY. If the source of a set
or copy is known, set LOC to the SET that performs the set, instead
of the destination.
(find_src_status, find_src_set_src): Remove LOC parameter.
Replace INSN with the source value.
(compute_bb_dataflow, emit_notes_in_bb): Check for a SET u.loc when
handling MO_SET and MO_COPY. Update the calls to find_src_status
and find_src_set_src.
2007-10-12 Nathan Froyd <froydnj@codesourcery.com> 2007-10-12 Nathan Froyd <froydnj@codesourcery.com>
PR 11001 PR 11001
...@@ -1415,7 +1415,7 @@ find_shift_sequence (rtx read_reg, ...@@ -1415,7 +1415,7 @@ find_shift_sequence (rtx read_reg,
justify the value we want to read but is available in one insn on justify the value we want to read but is available in one insn on
the machine. */ the machine. */
for (; access_size < UNITS_PER_WORD; access_size *= 2) for (; access_size <= UNITS_PER_WORD; access_size *= 2)
{ {
rtx target, new_reg, shift_seq, insn; rtx target, new_reg, shift_seq, insn;
enum machine_mode new_mode; enum machine_mode new_mode;
......
...@@ -134,7 +134,9 @@ typedef struct micro_operation_def ...@@ -134,7 +134,9 @@ typedef struct micro_operation_def
enum micro_operation_type type; enum micro_operation_type type;
union { union {
/* Location. */ /* Location. For MO_SET and MO_COPY, this is the SET that performs
the assignment, if known, otherwise it is the target of the
assignment. */
rtx loc; rtx loc;
/* Stack adjustment. */ /* Stack adjustment. */
...@@ -1672,6 +1674,54 @@ same_variable_part_p (rtx loc, tree expr, HOST_WIDE_INT offset) ...@@ -1672,6 +1674,54 @@ same_variable_part_p (rtx loc, tree expr, HOST_WIDE_INT offset)
return (expr == expr2 && offset == offset2); return (expr == expr2 && offset == offset2);
} }
/* REG is a register we want to track. If not all of REG contains useful
information, return the mode of the lowpart that does contain useful
information, otherwise return the mode of REG.
If REG was a paradoxical subreg, its REG_ATTRS will describe the
whole subreg, but only the old inner part is really relevant. */
static enum machine_mode
mode_for_reg_attrs (rtx reg)
{
enum machine_mode mode;
mode = GET_MODE (reg);
if (!HARD_REGISTER_NUM_P (ORIGINAL_REGNO (reg)))
{
enum machine_mode pseudo_mode;
pseudo_mode = PSEUDO_REGNO_MODE (ORIGINAL_REGNO (reg));
if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (pseudo_mode))
mode = pseudo_mode;
}
return mode;
}
/* Return the MODE lowpart of LOC, or null if LOC is not something we
want to track. When returning nonnull, make sure that the attributes
on the returned value are updated. */
static rtx
var_lowpart (enum machine_mode mode, rtx loc)
{
unsigned int offset, regno;
if (!REG_P (loc) && !MEM_P (loc))
return NULL;
if (GET_MODE (loc) == mode)
return loc;
offset = subreg_lowpart_offset (mode, GET_MODE (loc));
if (MEM_P (loc))
return adjust_address_nv (loc, mode, offset);
regno = REGNO (loc) + subreg_regno_offset (REGNO (loc), GET_MODE (loc),
offset, mode);
return gen_rtx_REG_offset (loc, mode, regno, offset);
}
/* Count uses (register and memory references) LOC which will be tracked. /* Count uses (register and memory references) LOC which will be tracked.
INSN is instruction which the LOC is part of. */ INSN is instruction which the LOC is part of. */
...@@ -1724,9 +1774,16 @@ add_uses (rtx *loc, void *insn) ...@@ -1724,9 +1774,16 @@ add_uses (rtx *loc, void *insn)
basic_block bb = BLOCK_FOR_INSN ((rtx) insn); basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++; micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
mo->type = ((REG_EXPR (*loc) && track_expr_p (REG_EXPR (*loc))) if (REG_EXPR (*loc) && track_expr_p (REG_EXPR (*loc)))
? MO_USE : MO_USE_NO_VAR); {
mo->type = MO_USE;
mo->u.loc = var_lowpart (mode_for_reg_attrs (*loc), *loc);
}
else
{
mo->type = MO_USE_NO_VAR;
mo->u.loc = *loc; mo->u.loc = *loc;
}
mo->insn = (rtx) insn; mo->insn = (rtx) insn;
} }
else if (MEM_P (*loc) else if (MEM_P (*loc)
...@@ -1767,16 +1824,35 @@ add_stores (rtx loc, const_rtx expr, void *insn) ...@@ -1767,16 +1824,35 @@ add_stores (rtx loc, const_rtx expr, void *insn)
if (GET_CODE (expr) == CLOBBER if (GET_CODE (expr) == CLOBBER
|| ! REG_EXPR (loc) || ! REG_EXPR (loc)
|| ! track_expr_p (REG_EXPR (loc))) || ! track_expr_p (REG_EXPR (loc)))
{
mo->type = MO_CLOBBER; mo->type = MO_CLOBBER;
else if (GET_CODE (expr) == SET mo->u.loc = loc;
&& SET_DEST (expr) == loc }
&& same_variable_part_p (SET_SRC (expr),
REG_EXPR (loc),
REG_OFFSET (loc)))
mo->type = MO_COPY;
else else
{
enum machine_mode mode = mode_for_reg_attrs (loc);
rtx src = NULL;
if (GET_CODE (expr) == SET && SET_DEST (expr) == loc)
src = var_lowpart (mode, SET_SRC (expr));
loc = var_lowpart (mode, loc);
if (src == NULL)
{
mo->type = MO_SET; mo->type = MO_SET;
mo->u.loc = loc; mo->u.loc = loc;
}
else
{
if (SET_SRC (expr) != src)
expr = gen_rtx_SET (VOIDmode, loc, src);
if (same_variable_part_p (src, REG_EXPR (loc), REG_OFFSET (loc)))
mo->type = MO_COPY;
else
mo->type = MO_SET;
mo->u.loc = CONST_CAST_RTX (expr);
}
}
mo->insn = (rtx) insn; mo->insn = (rtx) insn;
} }
else if (MEM_P (loc) else if (MEM_P (loc)
...@@ -1787,49 +1863,47 @@ add_stores (rtx loc, const_rtx expr, void *insn) ...@@ -1787,49 +1863,47 @@ add_stores (rtx loc, const_rtx expr, void *insn)
micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++; micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
if (GET_CODE (expr) == CLOBBER) if (GET_CODE (expr) == CLOBBER)
{
mo->type = MO_CLOBBER; mo->type = MO_CLOBBER;
else if (GET_CODE (expr) == SET mo->u.loc = loc;
&& SET_DEST (expr) == loc }
&& same_variable_part_p (SET_SRC (expr), else
{
rtx src = NULL;
if (GET_CODE (expr) == SET && SET_DEST (expr) == loc)
src = var_lowpart (GET_MODE (loc), SET_SRC (expr));
if (src == NULL)
{
mo->type = MO_SET;
mo->u.loc = loc;
}
else
{
if (same_variable_part_p (SET_SRC (expr),
MEM_EXPR (loc), MEM_EXPR (loc),
MEM_OFFSET (loc) MEM_OFFSET (loc)
? INTVAL (MEM_OFFSET (loc)) : 0)) ? INTVAL (MEM_OFFSET (loc)) : 0))
mo->type = MO_COPY; mo->type = MO_COPY;
else else
mo->type = MO_SET; mo->type = MO_SET;
mo->u.loc = loc; mo->u.loc = CONST_CAST_RTX (expr);
}
}
mo->insn = (rtx) insn; mo->insn = (rtx) insn;
} }
} }
static enum var_init_status static enum var_init_status
find_src_status (dataflow_set *in, rtx loc, rtx insn) find_src_status (dataflow_set *in, rtx src)
{ {
rtx src = NULL_RTX;
rtx pattern;
tree decl = NULL_TREE; tree decl = NULL_TREE;
enum var_init_status status = VAR_INIT_STATUS_UNINITIALIZED; enum var_init_status status = VAR_INIT_STATUS_UNINITIALIZED;
if (! flag_var_tracking_uninit) if (! flag_var_tracking_uninit)
status = VAR_INIT_STATUS_INITIALIZED; status = VAR_INIT_STATUS_INITIALIZED;
pattern = PATTERN (insn);
if (GET_CODE (pattern) == COND_EXEC)
pattern = COND_EXEC_CODE (pattern);
if (GET_CODE (pattern) == SET)
src = SET_SRC (pattern);
else if (GET_CODE (pattern) == PARALLEL
|| GET_CODE (pattern) == SEQUENCE)
{
int i;
for (i = XVECLEN (pattern, 0) - 1; i >= 0; i--)
if (GET_CODE (XVECEXP (pattern, 0, i)) == SET
&& SET_DEST (XVECEXP (pattern, 0, i)) == loc)
src = SET_SRC (XVECEXP (pattern, 0, i));
}
if (src && REG_P (src)) if (src && REG_P (src))
decl = var_debug_decl (REG_EXPR (src)); decl = var_debug_decl (REG_EXPR (src));
else if (src && MEM_P (src)) else if (src && MEM_P (src))
...@@ -1841,39 +1915,21 @@ find_src_status (dataflow_set *in, rtx loc, rtx insn) ...@@ -1841,39 +1915,21 @@ find_src_status (dataflow_set *in, rtx loc, rtx insn)
return status; return status;
} }
/* LOC is the destination the variable is being copied to. INSN /* SRC is the source of an assignment. Use SET to try to find what
contains the copy instruction. SET is the dataflow set containing was ultimately assigned to SRC. Return that value if known,
the variable in LOC. */ otherwise return SRC itself. */
static rtx static rtx
find_src_set_src (dataflow_set *set, rtx loc, rtx insn) find_src_set_src (dataflow_set *set, rtx src)
{ {
tree decl = NULL_TREE; /* The variable being copied around. */ tree decl = NULL_TREE; /* The variable being copied around. */
rtx src = NULL_RTX; /* The location "decl" is being copied from. */
rtx set_src = NULL_RTX; /* The value for "decl" stored in "src". */ rtx set_src = NULL_RTX; /* The value for "decl" stored in "src". */
rtx pattern;
void **slot; void **slot;
variable var; variable var;
location_chain nextp; location_chain nextp;
int i; int i;
bool found; bool found;
pattern = PATTERN (insn);
if (GET_CODE (pattern) == COND_EXEC)
pattern = COND_EXEC_CODE (pattern);
if (GET_CODE (pattern) == SET)
src = SET_SRC (pattern);
else if (GET_CODE (pattern) == PARALLEL
|| GET_CODE (pattern) == SEQUENCE)
{
for (i = XVECLEN (pattern, 0) - 1; i >= 0; i--)
if (GET_CODE (XVECEXP (pattern, 0, i)) == SET
&& SET_DEST (XVECEXP (pattern, 0, i)) == loc)
src = SET_SRC (XVECEXP (pattern, 0, i));
}
if (src && REG_P (src)) if (src && REG_P (src))
decl = var_debug_decl (REG_EXPR (src)); decl = var_debug_decl (REG_EXPR (src));
else if (src && MEM_P (src)) else if (src && MEM_P (src))
...@@ -1948,18 +2004,11 @@ compute_bb_dataflow (basic_block bb) ...@@ -1948,18 +2004,11 @@ compute_bb_dataflow (basic_block bb)
{ {
rtx loc = VTI (bb)->mos[i].u.loc; rtx loc = VTI (bb)->mos[i].u.loc;
rtx set_src = NULL; rtx set_src = NULL;
rtx insn = VTI (bb)->mos[i].insn;
if (GET_CODE (PATTERN (insn)) == SET) if (GET_CODE (loc) == SET)
set_src = SET_SRC (PATTERN (insn));
else if (GET_CODE (PATTERN (insn)) == PARALLEL
|| GET_CODE (PATTERN (insn)) == SEQUENCE)
{ {
int j; set_src = SET_SRC (loc);
for (j = XVECLEN (PATTERN (insn), 0) - 1; j >= 0; j--) loc = SET_DEST (loc);
if (GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == SET
&& SET_DEST (XVECEXP (PATTERN (insn), 0, j)) == loc)
set_src = SET_SRC (XVECEXP (PATTERN (insn), 0, j));
} }
if (REG_P (loc)) if (REG_P (loc))
...@@ -1975,17 +2024,23 @@ compute_bb_dataflow (basic_block bb) ...@@ -1975,17 +2024,23 @@ compute_bb_dataflow (basic_block bb)
{ {
rtx loc = VTI (bb)->mos[i].u.loc; rtx loc = VTI (bb)->mos[i].u.loc;
enum var_init_status src_status; enum var_init_status src_status;
rtx set_src; rtx set_src = NULL;
if (GET_CODE (loc) == SET)
{
set_src = SET_SRC (loc);
loc = SET_DEST (loc);
}
if (! flag_var_tracking_uninit) if (! flag_var_tracking_uninit)
src_status = VAR_INIT_STATUS_INITIALIZED; src_status = VAR_INIT_STATUS_INITIALIZED;
else else
src_status = find_src_status (in, loc, VTI (bb)->mos[i].insn); src_status = find_src_status (in, set_src);
if (src_status == VAR_INIT_STATUS_UNKNOWN) if (src_status == VAR_INIT_STATUS_UNKNOWN)
src_status = find_src_status (out, loc, VTI (bb)->mos[i].insn); src_status = find_src_status (out, set_src);
set_src = find_src_set_src (in, loc, VTI (bb)->mos[i].insn); set_src = find_src_set_src (in, set_src);
if (REG_P (loc)) if (REG_P (loc))
var_reg_delete_and_set (out, loc, false, src_status, set_src); var_reg_delete_and_set (out, loc, false, src_status, set_src);
...@@ -2885,16 +2940,10 @@ emit_notes_in_bb (basic_block bb) ...@@ -2885,16 +2940,10 @@ emit_notes_in_bb (basic_block bb)
rtx loc = VTI (bb)->mos[i].u.loc; rtx loc = VTI (bb)->mos[i].u.loc;
rtx set_src = NULL; rtx set_src = NULL;
if (GET_CODE (PATTERN (insn)) == SET) if (GET_CODE (loc) == SET)
set_src = SET_SRC (PATTERN (insn));
else if (GET_CODE (PATTERN (insn)) == PARALLEL
|| GET_CODE (PATTERN (insn)) == SEQUENCE)
{ {
int j; set_src = SET_SRC (loc);
for (j = XVECLEN (PATTERN (insn), 0) - 1; j >= 0; j--) loc = SET_DEST (loc);
if (GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == SET
&& SET_DEST (XVECEXP (PATTERN (insn), 0, j)) == loc)
set_src = SET_SRC (XVECEXP (PATTERN (insn), 0, j));
} }
if (REG_P (loc)) if (REG_P (loc))
...@@ -2912,10 +2961,16 @@ emit_notes_in_bb (basic_block bb) ...@@ -2912,10 +2961,16 @@ emit_notes_in_bb (basic_block bb)
{ {
rtx loc = VTI (bb)->mos[i].u.loc; rtx loc = VTI (bb)->mos[i].u.loc;
enum var_init_status src_status; enum var_init_status src_status;
rtx set_src; rtx set_src = NULL;
if (GET_CODE (loc) == SET)
{
set_src = SET_SRC (loc);
loc = SET_DEST (loc);
}
src_status = find_src_status (&set, loc, VTI (bb)->mos[i].insn); src_status = find_src_status (&set, set_src);
set_src = find_src_set_src (&set, loc, VTI (bb)->mos[i].insn); set_src = find_src_set_src (&set, set_src);
if (REG_P (loc)) if (REG_P (loc))
var_reg_delete_and_set (&set, loc, false, src_status, set_src); var_reg_delete_and_set (&set, loc, false, src_status, set_src);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment