Commit ff0d9879 by Hans-Peter Nilsson Committed by Hans-Peter Nilsson

re PR middle-end/24912 (m68k build failure: ICE: in reload_cse_simplify_operands)

	PR middle-end/24912
	PR middle-end/24750
	* reload.c (find_reloads_address_1): Mention dependency on
	gen_reload.
	* reload1.c (gen_reload): For IN with an unary operation, try
	moving inner expression to OUT if trivial SET is not valid.
	Confirm that the result is valid.  Move common code block into...
	(emit_insn_if_valid_for_reload): New function.

From-SVN: r107231
parent 152f76ec
2005-11-19 Hans-Peter Nilsson <hp@axis.com>
PR middle-end/24912
PR middle-end/24750
* reload.c (find_reloads_address_1): Mention dependency on
gen_reload.
* reload1.c (gen_reload): For IN with an unary operation, try
moving inner expression to OUT if trivial SET is not valid.
Confirm that the result is valid. Move common code block into...
(emit_insn_if_valid_for_reload): New function.
2005-11-19 Richard Guenther <rguenther@suse.de> 2005-11-19 Richard Guenther <rguenther@suse.de>
* fold-const.c (fold_indirect_ref_1): Make sure we fold * fold-const.c (fold_indirect_ref_1): Make sure we fold
......
...@@ -5311,7 +5311,9 @@ update_auto_inc_notes (rtx insn ATTRIBUTE_UNUSED, int regno ATTRIBUTE_UNUSED, ...@@ -5311,7 +5311,9 @@ update_auto_inc_notes (rtx insn ATTRIBUTE_UNUSED, int regno ATTRIBUTE_UNUSED,
occurs as part of an address. occurs as part of an address.
Also, this is not fully machine-customizable; it works for machines Also, this is not fully machine-customizable; it works for machines
such as VAXen and 68000's and 32000's, but other possible machines such as VAXen and 68000's and 32000's, but other possible machines
could have addressing modes that this does not handle right. */ could have addressing modes that this does not handle right.
If you add push_reload calls here, you need to make sure gen_reload
handles those cases gracefully. */
static int static int
find_reloads_address_1 (enum machine_mode mode, rtx x, int context, find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
......
...@@ -437,6 +437,7 @@ static void add_auto_inc_notes (rtx, rtx); ...@@ -437,6 +437,7 @@ static void add_auto_inc_notes (rtx, rtx);
static void copy_eh_notes (rtx, rtx); static void copy_eh_notes (rtx, rtx);
static int reloads_conflict (int, int); static int reloads_conflict (int, int);
static rtx gen_reload (rtx, rtx, int, enum reload_type); static rtx gen_reload (rtx, rtx, int, enum reload_type);
static rtx emit_insn_if_valid_for_reload (rtx);
/* Initialize the reload pass once per compilation. */ /* Initialize the reload pass once per compilation. */
...@@ -7449,6 +7450,32 @@ emit_reload_insns (struct insn_chain *chain) ...@@ -7449,6 +7450,32 @@ emit_reload_insns (struct insn_chain *chain)
IOR_HARD_REG_SET (reg_reloaded_dead, reg_reloaded_died); IOR_HARD_REG_SET (reg_reloaded_dead, reg_reloaded_died);
} }
/* Go through the motions to emit INSN and test if it is strictly valid.
Return the emitted insn if valid, else return NULL. */
static rtx
emit_insn_if_valid_for_reload (rtx insn)
{
rtx last = get_last_insn ();
int code;
insn = emit_insn (insn);
code = recog_memoized (insn);
if (code >= 0)
{
extract_insn (insn);
/* We want constrain operands to treat this insn strictly in its
validity determination, i.e., the way it would after reload has
completed. */
if (constrain_operands (1))
return insn;
}
delete_insns_since (last);
return NULL;
}
/* Emit code to perform a reload from IN (which may be a reload register) to /* Emit code to perform a reload from IN (which may be a reload register) to
OUT (which may also be a reload register). IN or OUT is from operand OUT (which may also be a reload register). IN or OUT is from operand
OPNUM with reload type TYPE. OPNUM with reload type TYPE.
...@@ -7485,6 +7512,12 @@ gen_reload (rtx out, rtx in, int opnum, enum reload_type type) ...@@ -7485,6 +7512,12 @@ gen_reload (rtx out, rtx in, int opnum, enum reload_type type)
trying to emit a single insn to perform the add. If it is not valid, trying to emit a single insn to perform the add. If it is not valid,
we use a two insn sequence. we use a two insn sequence.
Or we can be asked to reload an unary operand that was a fragment of
an addressing mode, into a register. If it isn't recognized as-is,
we try making the unop operand and the reload-register the same:
(set reg:X (unop:X expr:Y))
-> (set reg:Y expr:Y) (set reg:X (unop:X reg:Y)).
Finally, we could be called to handle an 'o' constraint by putting Finally, we could be called to handle an 'o' constraint by putting
an address into a register. In that case, we first try to do this an address into a register. In that case, we first try to do this
with a named pattern of "reload_load_address". If no such pattern with a named pattern of "reload_load_address". If no such pattern
...@@ -7542,20 +7575,9 @@ gen_reload (rtx out, rtx in, int opnum, enum reload_type type) ...@@ -7542,20 +7575,9 @@ gen_reload (rtx out, rtx in, int opnum, enum reload_type type)
if (op0 != XEXP (in, 0) || op1 != XEXP (in, 1)) if (op0 != XEXP (in, 0) || op1 != XEXP (in, 1))
in = gen_rtx_PLUS (GET_MODE (in), op0, op1); in = gen_rtx_PLUS (GET_MODE (in), op0, op1);
insn = emit_insn (gen_rtx_SET (VOIDmode, out, in)); insn = emit_insn_if_valid_for_reload (gen_rtx_SET (VOIDmode, out, in));
code = recog_memoized (insn); if (insn)
if (code >= 0)
{
extract_insn (insn);
/* We want constrain operands to treat this insn strictly in
its validity determination, i.e., the way it would after reload
has completed. */
if (constrain_operands (1))
return insn; return insn;
}
delete_insns_since (last);
/* If that failed, we must use a conservative two-insn sequence. /* If that failed, we must use a conservative two-insn sequence.
...@@ -7591,29 +7613,17 @@ gen_reload (rtx out, rtx in, int opnum, enum reload_type type) ...@@ -7591,29 +7613,17 @@ gen_reload (rtx out, rtx in, int opnum, enum reload_type type)
if (rtx_equal_p (op0, op1)) if (rtx_equal_p (op0, op1))
op1 = out; op1 = out;
insn = emit_insn (gen_add2_insn (out, op1)); insn = emit_insn_if_valid_for_reload (gen_add2_insn (out, op1));
if (insn)
/* If that failed, copy the address register to the reload register.
Then add the constant to the reload register. */
code = recog_memoized (insn);
if (code >= 0)
{
extract_insn (insn);
/* We want constrain operands to treat this insn strictly in
its validity determination, i.e., the way it would after reload
has completed. */
if (constrain_operands (1))
{ {
/* Add a REG_EQUIV note so that find_equiv_reg can find it. */ /* Add a REG_EQUIV note so that find_equiv_reg can find it. */
REG_NOTES (insn) REG_NOTES (insn)
= gen_rtx_EXPR_LIST (REG_EQUIV, in, REG_NOTES (insn)); = gen_rtx_EXPR_LIST (REG_EQUIV, in, REG_NOTES (insn));
return insn; return insn;
} }
}
delete_insns_since (last); /* If that failed, copy the address register to the reload register.
Then add the constant to the reload register. */
gen_reload (out, op1, opnum, type); gen_reload (out, op1, opnum, type);
insn = emit_insn (gen_add2_insn (out, op0)); insn = emit_insn (gen_add2_insn (out, op0));
...@@ -7643,7 +7653,44 @@ gen_reload (rtx out, rtx in, int opnum, enum reload_type type) ...@@ -7643,7 +7653,44 @@ gen_reload (rtx out, rtx in, int opnum, enum reload_type type)
gen_reload (out, loc, opnum, type); gen_reload (out, loc, opnum, type);
} }
#endif #endif
else if (REG_P (out) && UNARY_P (in))
{
rtx insn;
rtx op1;
rtx out_moded;
rtx set;
/* First, try a plain SET. */
set = emit_insn_if_valid_for_reload (gen_rtx_SET (VOIDmode, out, in));
if (set)
return set;
/* If that failed, move the inner operand to the reload
register, and try the same unop with the inner expression
replaced with the reload register. */
op1 = XEXP (in, 0);
if (GET_MODE (op1) != GET_MODE (out))
out_moded = gen_rtx_REG (GET_MODE (op1), REGNO (out));
else
out_moded = out;
gen_reload (out_moded, op1, opnum, type);
insn
= gen_rtx_SET (VOIDmode, out,
gen_rtx_fmt_e (GET_CODE (in), GET_MODE (in),
out_moded));
insn = emit_insn_if_valid_for_reload (insn);
if (insn)
{
REG_NOTES (insn)
= gen_rtx_EXPR_LIST (REG_EQUIV, in, REG_NOTES (insn));
return insn;
}
fatal_insn ("Failure trying to reload:", set);
}
/* If IN is a simple operand, use gen_move_insn. */ /* If IN is a simple operand, use gen_move_insn. */
else if (OBJECT_P (in) || GET_CODE (in) == SUBREG) else if (OBJECT_P (in) || GET_CODE (in) == SUBREG)
emit_insn (gen_move_insn (out, in)); emit_insn (gen_move_insn (out, in));
......
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