This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Be prepared for lround expander to fail
- From: Jan Hubicka <jh at suse dot cz>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 6 Aug 2008 09:48:27 +0200
- Subject: Be prepared for lround expander to fail
Hi,
I've added optimize_insn_for_size code to avoid lround and other
expansion that enlarge code size, however the optabs code is not ready
for expander failing. Emit_unop_insn has no way to signalize it failed,
so I added maybe variant (emit_unop_insn is used in many places and I
don't feel completely safe to update them without testing)
Bootstrapped/regtested i686-linux, OK?
* optabs.c (emit_unop_insn): Break out to ...
(maybe_emit_unop_insn): ... this one.
(expand_sfix_optab): Use maybe variant.
* optabs.h (maybe_emit_unop_insn): Declare.
Index: optabs.c
===================================================================
*** optabs.c (revision 138565)
--- optabs.c (working copy)
*************** expand_copysign (rtx op0, rtx op1, rtx t
*** 3759,3768 ****
with two operands: an output TARGET and an input OP0.
TARGET *must* be nonzero, and the output is always stored there.
CODE is an rtx code such that (CODE OP0) is an rtx that describes
! the value that is stored into TARGET. */
! void
! emit_unop_insn (int icode, rtx target, rtx op0, enum rtx_code code)
{
rtx temp;
enum machine_mode mode0 = insn_data[icode].operand[1].mode;
--- 3760,3771 ----
with two operands: an output TARGET and an input OP0.
TARGET *must* be nonzero, and the output is always stored there.
CODE is an rtx code such that (CODE OP0) is an rtx that describes
! the value that is stored into TARGET.
! Return false if expansion failed. */
!
! bool
! maybe_emit_unop_insn (int icode, rtx target, rtx op0, enum rtx_code code)
{
rtx temp;
enum machine_mode mode0 = insn_data[icode].operand[1].mode;
*************** emit_unop_insn (int icode, rtx target, r
*** 3779,3784 ****
--- 3782,3789 ----
temp = gen_reg_rtx (GET_MODE (temp));
pat = GEN_FCN (icode) (temp, op0);
+ if (!pat)
+ return false;
if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX && code != UNKNOWN)
add_equal_note (pat, temp, code, op0, NULL_RTX);
*************** emit_unop_insn (int icode, rtx target, r
*** 3787,3792 ****
--- 3792,3810 ----
if (temp != target)
emit_move_insn (target, temp);
+ return true;
+ }
+ /* Generate an instruction whose insn-code is INSN_CODE,
+ with two operands: an output TARGET and an input OP0.
+ TARGET *must* be nonzero, and the output is always stored there.
+ CODE is an rtx code such that (CODE OP0) is an rtx that describes
+ the value that is stored into TARGET. */
+
+ void
+ emit_unop_insn (int icode, rtx target, rtx op0, enum rtx_code code)
+ {
+ bool ok = maybe_emit_unop_insn (icode, target, op0, code);
+ gcc_assert (ok);
}
struct no_conflict_data
*************** expand_sfix_optab (rtx to, rtx from, con
*** 5371,5377 ****
if (imode != GET_MODE (to))
target = gen_reg_rtx (imode);
! emit_unop_insn (icode, target, from, UNKNOWN);
if (target != to)
convert_move (to, target, 0);
return true;
--- 5389,5396 ----
if (imode != GET_MODE (to))
target = gen_reg_rtx (imode);
! if (!maybe_emit_unop_insn (icode, target, from, UNKNOWN))
! return false;
if (target != to)
convert_move (to, target, 0);
return true;
Index: optabs.h
===================================================================
*** optabs.h (revision 138564)
--- optabs.h (working copy)
*************** extern rtx expand_copysign (rtx, rtx, rt
*** 722,727 ****
--- 722,728 ----
/* Generate an instruction with a given INSN_CODE with an output and
an input. */
extern void emit_unop_insn (int, rtx, rtx, enum rtx_code);
+ extern bool maybe_emit_unop_insn (int, rtx, rtx, enum rtx_code);
/* Emit one rtl insn to compare two rtx's. */
extern void emit_cmp_insn (rtx, rtx, enum rtx_code, rtx, enum machine_mode,