Commit ec5a3504 by Richard Sandiford Committed by Richard Sandiford

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
parent f91aec98
2013-09-27 Richard Sandiford <rdsandiford@googlemail.com> 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. * cse.c (count_reg_usage): Handle INT_LIST.
* lra-eliminations.c (lra_eliminate_regs_1): Likewise. * lra-eliminations.c (lra_eliminate_regs_1): Likewise.
* reginfo.c (reg_scan_mark_refs): Likewise. * reginfo.c (reg_scan_mark_refs): Likewise.
......
...@@ -5521,26 +5521,50 @@ strip_address_mutations (rtx *loc, enum rtx_code *outer_code) ...@@ -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 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 static rtx *
must_be_index_p (rtx x) get_base_term (rtx *inner)
{ {
return (GET_CODE (x) == MULT if (GET_CODE (*inner) == LO_SUM)
|| GET_CODE (x) == ASHIFT inner = strip_address_mutations (&XEXP (*inner, 0));
/* Needed by ARM targets. */ if (REG_P (*inner)
|| GET_CODE (x) == ASHIFTRT || MEM_P (*inner)
|| GET_CODE (x) == LSHIFTRT || GET_CODE (*inner) == SUBREG)
|| GET_CODE (x) == ROTATE return inner;
|| GET_CODE (x) == ROTATERT); 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 /* Set the segment part of address INFO to LOC, given that INNER is the
...@@ -5549,8 +5573,6 @@ must_be_index_p (rtx x) ...@@ -5549,8 +5573,6 @@ must_be_index_p (rtx x)
static void static void
set_address_segment (struct address_info *info, rtx *loc, rtx *inner) set_address_segment (struct address_info *info, rtx *loc, rtx *inner)
{ {
gcc_checking_assert (GET_CODE (*inner) == UNSPEC);
gcc_assert (!info->segment); gcc_assert (!info->segment);
info->segment = loc; info->segment = loc;
info->segment_term = inner; info->segment_term = inner;
...@@ -5562,12 +5584,6 @@ set_address_segment (struct address_info *info, rtx *loc, rtx *inner) ...@@ -5562,12 +5584,6 @@ set_address_segment (struct address_info *info, rtx *loc, rtx *inner)
static void static void
set_address_base (struct address_info *info, rtx *loc, rtx *inner) 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); gcc_assert (!info->base);
info->base = loc; info->base = loc;
info->base_term = inner; info->base_term = inner;
...@@ -5579,12 +5595,6 @@ set_address_base (struct address_info *info, rtx *loc, rtx *inner) ...@@ -5579,12 +5595,6 @@ set_address_base (struct address_info *info, rtx *loc, rtx *inner)
static void static void
set_address_index (struct address_info *info, rtx *loc, rtx *inner) 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); gcc_assert (!info->index);
info->index = loc; info->index = loc;
info->index_term = inner; info->index_term = inner;
...@@ -5596,8 +5606,6 @@ set_address_index (struct address_info *info, rtx *loc, rtx *inner) ...@@ -5596,8 +5606,6 @@ set_address_index (struct address_info *info, rtx *loc, rtx *inner)
static void static void
set_address_disp (struct address_info *info, rtx *loc, rtx *inner) set_address_disp (struct address_info *info, rtx *loc, rtx *inner)
{ {
gcc_checking_assert (CONSTANT_P (*inner));
gcc_assert (!info->disp); gcc_assert (!info->disp);
info->disp = loc; info->disp = loc;
info->disp_term = inner; info->disp_term = inner;
...@@ -5677,12 +5685,6 @@ static int ...@@ -5677,12 +5685,6 @@ static int
baseness (rtx x, enum machine_mode mode, addr_space_t as, baseness (rtx x, enum machine_mode mode, addr_space_t as,
enum rtx_code outer_code, enum rtx_code index_code) 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. */ /* Believe *_POINTER unless the address shape requires otherwise. */
if (REG_P (x) && REG_POINTER (x)) if (REG_P (x) && REG_POINTER (x))
return 2; return 2;
...@@ -5717,8 +5719,8 @@ decompose_normal_address (struct address_info *info) ...@@ -5717,8 +5719,8 @@ decompose_normal_address (struct address_info *info)
if (n_ops > 1) if (n_ops > 1)
info->base_outer_code = PLUS; info->base_outer_code = PLUS;
/* Separate the parts that contain a REG or MEM from those that don't. /* Try to classify each sum operand now. Leave those that could be
Record the latter in INFO and leave the former in OPS. */ either a base or an index in OPS. */
rtx *inner_ops[4]; rtx *inner_ops[4];
size_t out = 0; size_t out = 0;
for (size_t in = 0; in < n_ops; ++in) for (size_t in = 0; in < n_ops; ++in)
...@@ -5731,18 +5733,31 @@ decompose_normal_address (struct address_info *info) ...@@ -5731,18 +5733,31 @@ decompose_normal_address (struct address_info *info)
set_address_segment (info, loc, inner); set_address_segment (info, loc, inner);
else else
{ {
ops[out] = loc; /* The only other possibilities are a base or an index. */
inner_ops[out] = inner; rtx *base_term = get_base_term (inner);
++out; 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. */ /* Classify the remaining OPS members as bases and indexes. */
if (out == 1) if (out == 1)
{ {
/* Assume that the remaining value is a base unless the shape /* If we haven't seen a base or an index yet, assume that this is
requires otherwise. */ the base. If we were confident that another term was the base
if (!must_be_index_p (*inner_ops[0])) or index, treat the remaining operand as the other kind. */
if (!info->base)
set_address_base (info, ops[0], inner_ops[0]); set_address_base (info, ops[0], inner_ops[0]);
else else
set_address_index (info, ops[0], inner_ops[0]); set_address_index (info, ops[0], inner_ops[0]);
......
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