rtlanal.c (must_be_base_p, [...]): Delete.

gcc/
	* rtlanal.c (must_be_base_p, must_be_index_p): Delete.
	(binary_scale_code_p, get_base_term, get_index_term): New functions.
	(set_address_segment, set_address_base, set_address_index)
	(set_address_disp): Accept the argument unconditionally.
	(baseness): Remove must_be_base_p and must_be_index_p checks.
	(decompose_normal_address): Classify as much as possible in the
	main loop.

From-SVN: r202970
This commit is contained in:
Richard Sandiford 2013-09-27 11:21:19 +00:00 committed by Richard Sandiford
parent f91aec98e2
commit ec5a350405
2 changed files with 68 additions and 43 deletions

View File

@ -1,3 +1,13 @@
2013-09-27 Richard Sandiford <rdsandiford@googlemail.com>
* rtlanal.c (must_be_base_p, must_be_index_p): Delete.
(binary_scale_code_p, get_base_term, get_index_term): New functions.
(set_address_segment, set_address_base, set_address_index)
(set_address_disp): Accept the argument unconditionally.
(baseness): Remove must_be_base_p and must_be_index_p checks.
(decompose_normal_address): Classify as much as possible in the
main loop.
2013-09-27 Richard Sandiford <rdsandiford@googlemail.com>
* cse.c (count_reg_usage): Handle INT_LIST.

View File

@ -5521,26 +5521,50 @@ strip_address_mutations (rtx *loc, enum rtx_code *outer_code)
}
}
/* Return true if X must be a base rather than an index. */
/* Return true if CODE applies some kind of scale. The scaled value is
is the first operand and the scale is the second. */
static bool
must_be_base_p (rtx x)
binary_scale_code_p (enum rtx_code code)
{
return GET_CODE (x) == LO_SUM;
return (code == MULT
|| code == ASHIFT
/* Needed by ARM targets. */
|| code == ASHIFTRT
|| code == LSHIFTRT
|| code == ROTATE
|| code == ROTATERT);
}
/* Return true if X must be an index rather than a base. */
/* If *INNER can be interpreted as a base, return a pointer to the inner term
(see address_info). Return null otherwise. */
static bool
must_be_index_p (rtx x)
static rtx *
get_base_term (rtx *inner)
{
return (GET_CODE (x) == MULT
|| GET_CODE (x) == ASHIFT
/* Needed by ARM targets. */
|| GET_CODE (x) == ASHIFTRT
|| GET_CODE (x) == LSHIFTRT
|| GET_CODE (x) == ROTATE
|| GET_CODE (x) == ROTATERT);
if (GET_CODE (*inner) == LO_SUM)
inner = strip_address_mutations (&XEXP (*inner, 0));
if (REG_P (*inner)
|| MEM_P (*inner)
|| GET_CODE (*inner) == SUBREG)
return inner;
return 0;
}
/* If *INNER can be interpreted as an index, return a pointer to the inner term
(see address_info). Return null otherwise. */
static rtx *
get_index_term (rtx *inner)
{
/* At present, only constant scales are allowed. */
if (binary_scale_code_p (GET_CODE (*inner)) && CONSTANT_P (XEXP (*inner, 1)))
inner = strip_address_mutations (&XEXP (*inner, 0));
if (REG_P (*inner)
|| MEM_P (*inner)
|| GET_CODE (*inner) == SUBREG)
return inner;
return 0;
}
/* Set the segment part of address INFO to LOC, given that INNER is the
@ -5549,8 +5573,6 @@ must_be_index_p (rtx x)
static void
set_address_segment (struct address_info *info, rtx *loc, rtx *inner)
{
gcc_checking_assert (GET_CODE (*inner) == UNSPEC);
gcc_assert (!info->segment);
info->segment = loc;
info->segment_term = inner;
@ -5562,12 +5584,6 @@ set_address_segment (struct address_info *info, rtx *loc, rtx *inner)
static void
set_address_base (struct address_info *info, rtx *loc, rtx *inner)
{
if (must_be_base_p (*inner))
inner = strip_address_mutations (&XEXP (*inner, 0));
gcc_checking_assert (REG_P (*inner)
|| MEM_P (*inner)
|| GET_CODE (*inner) == SUBREG);
gcc_assert (!info->base);
info->base = loc;
info->base_term = inner;
@ -5579,12 +5595,6 @@ set_address_base (struct address_info *info, rtx *loc, rtx *inner)
static void
set_address_index (struct address_info *info, rtx *loc, rtx *inner)
{
if (must_be_index_p (*inner) && CONSTANT_P (XEXP (*inner, 1)))
inner = strip_address_mutations (&XEXP (*inner, 0));
gcc_checking_assert (REG_P (*inner)
|| MEM_P (*inner)
|| GET_CODE (*inner) == SUBREG);
gcc_assert (!info->index);
info->index = loc;
info->index_term = inner;
@ -5596,8 +5606,6 @@ set_address_index (struct address_info *info, rtx *loc, rtx *inner)
static void
set_address_disp (struct address_info *info, rtx *loc, rtx *inner)
{
gcc_checking_assert (CONSTANT_P (*inner));
gcc_assert (!info->disp);
info->disp = loc;
info->disp_term = inner;
@ -5677,12 +5685,6 @@ static int
baseness (rtx x, enum machine_mode mode, addr_space_t as,
enum rtx_code outer_code, enum rtx_code index_code)
{
/* See whether we can be certain. */
if (must_be_base_p (x))
return 3;
if (must_be_index_p (x))
return -3;
/* Believe *_POINTER unless the address shape requires otherwise. */
if (REG_P (x) && REG_POINTER (x))
return 2;
@ -5717,8 +5719,8 @@ decompose_normal_address (struct address_info *info)
if (n_ops > 1)
info->base_outer_code = PLUS;
/* Separate the parts that contain a REG or MEM from those that don't.
Record the latter in INFO and leave the former in OPS. */
/* Try to classify each sum operand now. Leave those that could be
either a base or an index in OPS. */
rtx *inner_ops[4];
size_t out = 0;
for (size_t in = 0; in < n_ops; ++in)
@ -5731,18 +5733,31 @@ decompose_normal_address (struct address_info *info)
set_address_segment (info, loc, inner);
else
{
ops[out] = loc;
inner_ops[out] = inner;
++out;
/* The only other possibilities are a base or an index. */
rtx *base_term = get_base_term (inner);
rtx *index_term = get_index_term (inner);
gcc_assert (base_term || index_term);
if (!base_term)
set_address_index (info, loc, index_term);
else if (!index_term)
set_address_base (info, loc, base_term);
else
{
gcc_assert (base_term == index_term);
ops[out] = loc;
inner_ops[out] = base_term;
++out;
}
}
}
/* Classify the remaining OPS members as bases and indexes. */
if (out == 1)
{
/* Assume that the remaining value is a base unless the shape
requires otherwise. */
if (!must_be_index_p (*inner_ops[0]))
/* If we haven't seen a base or an index yet, assume that this is
the base. If we were confident that another term was the base
or index, treat the remaining operand as the other kind. */
if (!info->base)
set_address_base (info, ops[0], inner_ops[0]);
else
set_address_index (info, ops[0], inner_ops[0]);