Commit a36a1928 by Richard Sandiford Committed by Richard Sandiford

lower-subreg.c (find_decomposable_subregs): Turn from being a for_each_rtx…

lower-subreg.c (find_decomposable_subregs): Turn from being a for_each_rtx callback to being a function that examines each...

gcc/
	* lower-subreg.c (find_decomposable_subregs): Turn from being
	a for_each_rtx callback to being a function that examines each
	subrtx itself.  Remove handling of null rtxes.
	(decompose_multiword_subregs): Update accordingly.

From-SVN: r214649
parent f2d3f347
2014-08-28 Richard Sandiford <rdsandiford@googlemail.com> 2014-08-28 Richard Sandiford <rdsandiford@googlemail.com>
* lower-subreg.c (find_decomposable_subregs): Turn from being
a for_each_rtx callback to being a function that examines each
subrtx itself. Remove handling of null rtxes.
(decompose_multiword_subregs): Update accordingly.
2014-08-28 Richard Sandiford <rdsandiford@googlemail.com>
* lower-subreg.c (adjust_decomposed_uses): Delete. * lower-subreg.c (adjust_decomposed_uses): Delete.
(resolve_debug): Use FOR_EACH_SUBRTX_PTR rather than for_each_rtx. (resolve_debug): Use FOR_EACH_SUBRTX_PTR rather than for_each_rtx.
Remove handling of null rtxes. Remove handling of null rtxes.
......
...@@ -443,7 +443,7 @@ propagate_pseudo_copies (void) ...@@ -443,7 +443,7 @@ propagate_pseudo_copies (void)
} }
/* A pointer to one of these values is passed to /* A pointer to one of these values is passed to
find_decomposable_subregs via for_each_rtx. */ find_decomposable_subregs. */
enum classify_move_insn enum classify_move_insn
{ {
...@@ -455,120 +455,121 @@ enum classify_move_insn ...@@ -455,120 +455,121 @@ enum classify_move_insn
SIMPLE_MOVE SIMPLE_MOVE
}; };
/* This is called via for_each_rtx. If we find a SUBREG which we /* If we find a SUBREG in *LOC which we could use to decompose a
could use to decompose a pseudo-register, set a bit in pseudo-register, set a bit in DECOMPOSABLE_CONTEXT. If we find an
DECOMPOSABLE_CONTEXT. If we find an unadorned register which is unadorned register which is not a simple pseudo-register copy,
not a simple pseudo-register copy, DATA will point at the type of DATA will point at the type of move, and we set a bit in
move, and we set a bit in DECOMPOSABLE_CONTEXT or DECOMPOSABLE_CONTEXT or NON_DECOMPOSABLE_CONTEXT as appropriate. */
NON_DECOMPOSABLE_CONTEXT as appropriate. */
static int static void
find_decomposable_subregs (rtx *px, void *data) find_decomposable_subregs (rtx *loc, enum classify_move_insn *pcmi)
{ {
enum classify_move_insn *pcmi = (enum classify_move_insn *) data; subrtx_var_iterator::array_type array;
rtx x = *px; FOR_EACH_SUBRTX_VAR (iter, array, *loc, NONCONST)
if (x == NULL_RTX)
return 0;
if (GET_CODE (x) == SUBREG)
{ {
rtx inner = SUBREG_REG (x); rtx x = *iter;
unsigned int regno, outer_size, inner_size, outer_words, inner_words; if (GET_CODE (x) == SUBREG)
{
rtx inner = SUBREG_REG (x);
unsigned int regno, outer_size, inner_size, outer_words, inner_words;
if (!REG_P (inner)) if (!REG_P (inner))
return 0; continue;
regno = REGNO (inner); regno = REGNO (inner);
if (HARD_REGISTER_NUM_P (regno)) if (HARD_REGISTER_NUM_P (regno))
return -1; {
iter.skip_subrtxes ();
continue;
}
outer_size = GET_MODE_SIZE (GET_MODE (x)); outer_size = GET_MODE_SIZE (GET_MODE (x));
inner_size = GET_MODE_SIZE (GET_MODE (inner)); inner_size = GET_MODE_SIZE (GET_MODE (inner));
outer_words = (outer_size + UNITS_PER_WORD - 1) / UNITS_PER_WORD; outer_words = (outer_size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
inner_words = (inner_size + UNITS_PER_WORD - 1) / UNITS_PER_WORD; inner_words = (inner_size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
/* We only try to decompose single word subregs of multi-word /* We only try to decompose single word subregs of multi-word
registers. When we find one, we return -1 to avoid iterating registers. When we find one, we return -1 to avoid iterating
over the inner register. over the inner register.
??? This doesn't allow, e.g., DImode subregs of TImode values ??? This doesn't allow, e.g., DImode subregs of TImode values
on 32-bit targets. We would need to record the way the on 32-bit targets. We would need to record the way the
pseudo-register was used, and only decompose if all the uses pseudo-register was used, and only decompose if all the uses
were the same number and size of pieces. Hopefully this were the same number and size of pieces. Hopefully this
doesn't happen much. */ doesn't happen much. */
if (outer_words == 1 && inner_words > 1) if (outer_words == 1 && inner_words > 1)
{ {
bitmap_set_bit (decomposable_context, regno); bitmap_set_bit (decomposable_context, regno);
return -1; iter.skip_subrtxes ();
} continue;
}
/* If this is a cast from one mode to another, where the modes /* If this is a cast from one mode to another, where the modes
have the same size, and they are not tieable, then mark this have the same size, and they are not tieable, then mark this
register as non-decomposable. If we decompose it we are register as non-decomposable. If we decompose it we are
likely to mess up whatever the backend is trying to do. */ likely to mess up whatever the backend is trying to do. */
if (outer_words > 1 if (outer_words > 1
&& outer_size == inner_size && outer_size == inner_size
&& !MODES_TIEABLE_P (GET_MODE (x), GET_MODE (inner))) && !MODES_TIEABLE_P (GET_MODE (x), GET_MODE (inner)))
{ {
bitmap_set_bit (non_decomposable_context, regno); bitmap_set_bit (non_decomposable_context, regno);
bitmap_set_bit (subreg_context, regno); bitmap_set_bit (subreg_context, regno);
return -1; iter.skip_subrtxes ();
continue;
}
} }
} else if (REG_P (x))
else if (REG_P (x))
{
unsigned int regno;
/* We will see an outer SUBREG before we see the inner REG, so
when we see a plain REG here it means a direct reference to
the register.
If this is not a simple copy from one location to another,
then we can not decompose this register. If this is a simple
copy we want to decompose, and the mode is right,
then we mark the register as decomposable.
Otherwise we don't say anything about this register --
it could be decomposed, but whether that would be
profitable depends upon how it is used elsewhere.
We only set bits in the bitmap for multi-word
pseudo-registers, since those are the only ones we care about
and it keeps the size of the bitmaps down. */
regno = REGNO (x);
if (!HARD_REGISTER_NUM_P (regno)
&& GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD)
{ {
switch (*pcmi) unsigned int regno;
/* We will see an outer SUBREG before we see the inner REG, so
when we see a plain REG here it means a direct reference to
the register.
If this is not a simple copy from one location to another,
then we can not decompose this register. If this is a simple
copy we want to decompose, and the mode is right,
then we mark the register as decomposable.
Otherwise we don't say anything about this register --
it could be decomposed, but whether that would be
profitable depends upon how it is used elsewhere.
We only set bits in the bitmap for multi-word
pseudo-registers, since those are the only ones we care about
and it keeps the size of the bitmaps down. */
regno = REGNO (x);
if (!HARD_REGISTER_NUM_P (regno)
&& GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD)
{ {
case NOT_SIMPLE_MOVE: switch (*pcmi)
bitmap_set_bit (non_decomposable_context, regno); {
break; case NOT_SIMPLE_MOVE:
case DECOMPOSABLE_SIMPLE_MOVE: bitmap_set_bit (non_decomposable_context, regno);
if (MODES_TIEABLE_P (GET_MODE (x), word_mode)) break;
bitmap_set_bit (decomposable_context, regno); case DECOMPOSABLE_SIMPLE_MOVE:
break; if (MODES_TIEABLE_P (GET_MODE (x), word_mode))
case SIMPLE_MOVE: bitmap_set_bit (decomposable_context, regno);
break; break;
default: case SIMPLE_MOVE:
gcc_unreachable (); break;
default:
gcc_unreachable ();
}
} }
} }
} else if (MEM_P (x))
else if (MEM_P (x)) {
{ enum classify_move_insn cmi_mem = NOT_SIMPLE_MOVE;
enum classify_move_insn cmi_mem = NOT_SIMPLE_MOVE;
/* Any registers used in a MEM do not participate in a /* Any registers used in a MEM do not participate in a
SIMPLE_MOVE or DECOMPOSABLE_SIMPLE_MOVE. Do our own recursion SIMPLE_MOVE or DECOMPOSABLE_SIMPLE_MOVE. Do our own recursion
here, and return -1 to block the parent's recursion. */ here, and return -1 to block the parent's recursion. */
for_each_rtx (&XEXP (x, 0), find_decomposable_subregs, &cmi_mem); find_decomposable_subregs (&XEXP (x, 0), &cmi_mem);
return -1; iter.skip_subrtxes ();
}
} }
return 0;
} }
/* Decompose REGNO into word-sized components. We smash the REG node /* Decompose REGNO into word-sized components. We smash the REG node
...@@ -1496,9 +1497,7 @@ decompose_multiword_subregs (bool decompose_copies) ...@@ -1496,9 +1497,7 @@ decompose_multiword_subregs (bool decompose_copies)
n = recog_data.n_operands; n = recog_data.n_operands;
for (i = 0; i < n; ++i) for (i = 0; i < n; ++i)
{ {
for_each_rtx (&recog_data.operand[i], find_decomposable_subregs (&recog_data.operand[i], &cmi);
find_decomposable_subregs,
&cmi);
/* We handle ASM_OPERANDS as a special case to support /* We handle ASM_OPERANDS as a special case to support
things like x86 rdtsc which returns a DImode value. things like x86 rdtsc which returns a DImode value.
......
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