var-tracking.c (use_narrower_mode_test, [...]): New functions.
* var-tracking.c (use_narrower_mode_test, use_narrower_mode): New functions. (adjust_mems): Replace narrowing SUBREG of expression containing just PLUS, MINUS, MULT and ASHIFT of registers and constants with operations in the narrower mode. From-SVN: r157835
This commit is contained in:
parent
03a5f060b9
commit
e9e008859c
2 changed files with 88 additions and 5 deletions
|
@ -1,5 +1,11 @@
|
|||
2010-03-30 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* var-tracking.c (use_narrower_mode_test, use_narrower_mode): New
|
||||
functions.
|
||||
(adjust_mems): Replace narrowing SUBREG of expression containing
|
||||
just PLUS, MINUS, MULT and ASHIFT of registers and constants
|
||||
with operations in the narrower mode.
|
||||
|
||||
PR debug/43593
|
||||
* var-tracking.c (dataflow_set_clear_at_call): Invalidate
|
||||
just regs_invalidated_by_call instead all call_used_reg_set
|
||||
|
|
|
@ -729,6 +729,65 @@ struct adjust_mem_data
|
|||
rtx side_effects;
|
||||
};
|
||||
|
||||
/* Helper for adjust_mems. Return 1 if *loc is unsuitable for
|
||||
transformation of wider mode arithmetics to narrower mode,
|
||||
-1 if it is suitable and subexpressions shouldn't be
|
||||
traversed and 0 if it is suitable and subexpressions should
|
||||
be traversed. Called through for_each_rtx. */
|
||||
|
||||
static int
|
||||
use_narrower_mode_test (rtx *loc, void *data)
|
||||
{
|
||||
rtx subreg = (rtx) data;
|
||||
|
||||
if (CONSTANT_P (*loc))
|
||||
return -1;
|
||||
switch (GET_CODE (*loc))
|
||||
{
|
||||
case REG:
|
||||
if (cselib_lookup (*loc, GET_MODE (SUBREG_REG (subreg)), 0))
|
||||
return 1;
|
||||
return -1;
|
||||
case PLUS:
|
||||
case MINUS:
|
||||
case MULT:
|
||||
return 0;
|
||||
case ASHIFT:
|
||||
if (for_each_rtx (&XEXP (*loc, 0), use_narrower_mode_test, data))
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Transform X into narrower mode MODE from wider mode WMODE. */
|
||||
|
||||
static rtx
|
||||
use_narrower_mode (rtx x, enum machine_mode mode, enum machine_mode wmode)
|
||||
{
|
||||
rtx op0, op1;
|
||||
if (CONSTANT_P (x))
|
||||
return lowpart_subreg (mode, x, wmode);
|
||||
switch (GET_CODE (x))
|
||||
{
|
||||
case REG:
|
||||
return lowpart_subreg (mode, x, wmode);
|
||||
case PLUS:
|
||||
case MINUS:
|
||||
case MULT:
|
||||
op0 = use_narrower_mode (XEXP (x, 0), mode, wmode);
|
||||
op1 = use_narrower_mode (XEXP (x, 1), mode, wmode);
|
||||
return simplify_gen_binary (GET_CODE (x), mode, op0, op1);
|
||||
case ASHIFT:
|
||||
op0 = use_narrower_mode (XEXP (x, 0), mode, wmode);
|
||||
return simplify_gen_binary (ASHIFT, mode, op0, XEXP (x, 1));
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Helper function for adjusting used MEMs. */
|
||||
|
||||
static rtx
|
||||
|
@ -822,18 +881,36 @@ adjust_mems (rtx loc, const_rtx old_rtx, void *data)
|
|||
amd->store = store_save;
|
||||
mem = simplify_replace_fn_rtx (addr, old_rtx, adjust_mems, data);
|
||||
if (mem == SUBREG_REG (loc))
|
||||
return loc;
|
||||
{
|
||||
tem = loc;
|
||||
goto finish_subreg;
|
||||
}
|
||||
tem = simplify_gen_subreg (GET_MODE (loc), mem,
|
||||
GET_MODE (SUBREG_REG (loc)),
|
||||
SUBREG_BYTE (loc));
|
||||
if (tem)
|
||||
return tem;
|
||||
goto finish_subreg;
|
||||
tem = simplify_gen_subreg (GET_MODE (loc), addr,
|
||||
GET_MODE (SUBREG_REG (loc)),
|
||||
SUBREG_BYTE (loc));
|
||||
if (tem)
|
||||
return tem;
|
||||
return gen_rtx_raw_SUBREG (GET_MODE (loc), addr, SUBREG_BYTE (loc));
|
||||
if (tem == NULL_RTX)
|
||||
tem = gen_rtx_raw_SUBREG (GET_MODE (loc), addr, SUBREG_BYTE (loc));
|
||||
finish_subreg:
|
||||
if (MAY_HAVE_DEBUG_INSNS
|
||||
&& GET_CODE (tem) == SUBREG
|
||||
&& (GET_CODE (SUBREG_REG (tem)) == PLUS
|
||||
|| GET_CODE (SUBREG_REG (tem)) == MINUS
|
||||
|| GET_CODE (SUBREG_REG (tem)) == MULT
|
||||
|| GET_CODE (SUBREG_REG (tem)) == ASHIFT)
|
||||
&& GET_MODE_CLASS (GET_MODE (tem)) == MODE_INT
|
||||
&& GET_MODE_CLASS (GET_MODE (SUBREG_REG (tem))) == MODE_INT
|
||||
&& GET_MODE_SIZE (GET_MODE (tem))
|
||||
< GET_MODE_SIZE (GET_MODE (SUBREG_REG (tem)))
|
||||
&& subreg_lowpart_p (tem)
|
||||
&& !for_each_rtx (&SUBREG_REG (tem), use_narrower_mode_test, tem))
|
||||
return use_narrower_mode (SUBREG_REG (tem), GET_MODE (tem),
|
||||
GET_MODE (SUBREG_REG (tem)));
|
||||
return tem;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue