re PR target/23706 (ICE in rtl_verify_flow_info_1)
PR 23706 * mode-switching.c (optimize_mode_switching): Clear transp bit for block with incomming abnormal edges. * config/sh/sh.c (fpscr_values, emit_fpu_switch): New. (fpscr_set_from_mem): Use them. * config/sh/sh.md (fpu_switch0, fpu_switch1): Remove. (fpscr postinc splitters): Rewrite as peephole2+split. From-SVN: r105045
This commit is contained in:
parent
27f0fe7f6e
commit
24c2fde2af
@ -1,3 +1,14 @@
|
|||||||
|
2005-10-06 Richard Henderson <rth@redhat.com>
|
||||||
|
|
||||||
|
PR 23706
|
||||||
|
* mode-switching.c (optimize_mode_switching): Clear transp bit
|
||||||
|
for block with incomming abnormal edges.
|
||||||
|
|
||||||
|
* config/sh/sh.c (fpscr_values, emit_fpu_switch): New.
|
||||||
|
(fpscr_set_from_mem): Use them.
|
||||||
|
* config/sh/sh.md (fpu_switch0, fpu_switch1): Remove.
|
||||||
|
(fpscr postinc splitters): Rewrite as peephole2+split.
|
||||||
|
|
||||||
2005-10-06 David Edelsohn <edelsohn@gnu.org>
|
2005-10-06 David Edelsohn <edelsohn@gnu.org>
|
||||||
|
|
||||||
* config/rs6000/rs6000.md (eq<mode>): Add !TARGET_POWER.
|
* config/rs6000/rs6000.md (eq<mode>): Add !TARGET_POWER.
|
||||||
|
@ -7854,6 +7854,44 @@ get_fpscr_rtx (void)
|
|||||||
return fpscr_rtx;
|
return fpscr_rtx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GTY(()) tree fpscr_values;
|
||||||
|
|
||||||
|
static void
|
||||||
|
emit_fpu_switch (rtx scratch, int index)
|
||||||
|
{
|
||||||
|
rtx dst, src;
|
||||||
|
|
||||||
|
if (fpscr_values == NULL)
|
||||||
|
{
|
||||||
|
tree t;
|
||||||
|
|
||||||
|
t = build_index_type (integer_one_node);
|
||||||
|
t = build_array_type (integer_type_node, t);
|
||||||
|
t = build_decl (VAR_DECL, get_identifier ("__fpscr_values"), t);
|
||||||
|
DECL_ARTIFICIAL (t) = 1;
|
||||||
|
DECL_IGNORED_P (t) = 1;
|
||||||
|
DECL_EXTERNAL (t) = 1;
|
||||||
|
TREE_STATIC (t) = 1;
|
||||||
|
TREE_USED (t) = 1;
|
||||||
|
|
||||||
|
fpscr_values = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
src = DECL_RTL (fpscr_values);
|
||||||
|
if (no_new_pseudos)
|
||||||
|
{
|
||||||
|
emit_move_insn (scratch, XEXP (src, 0));
|
||||||
|
if (index != 0)
|
||||||
|
emit_insn (gen_addsi3 (scratch, scratch, GEN_INT (index * 4)));
|
||||||
|
src = adjust_automodify_address (src, PSImode, scratch, index * 4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
src = adjust_address (src, PSImode, index * 4);
|
||||||
|
|
||||||
|
dst = get_fpscr_rtx ();
|
||||||
|
emit_move_insn (dst, src);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
emit_sf_insn (rtx pat)
|
emit_sf_insn (rtx pat)
|
||||||
{
|
{
|
||||||
@ -8006,12 +8044,10 @@ void
|
|||||||
fpscr_set_from_mem (int mode, HARD_REG_SET regs_live)
|
fpscr_set_from_mem (int mode, HARD_REG_SET regs_live)
|
||||||
{
|
{
|
||||||
enum attr_fp_mode fp_mode = mode;
|
enum attr_fp_mode fp_mode = mode;
|
||||||
|
enum attr_fp_mode norm_mode = ACTUAL_NORMAL_MODE (FP_MODE);
|
||||||
rtx addr_reg = get_free_reg (regs_live);
|
rtx addr_reg = get_free_reg (regs_live);
|
||||||
|
|
||||||
if (fp_mode == (enum attr_fp_mode) ACTUAL_NORMAL_MODE (FP_MODE))
|
emit_fpu_switch (addr_reg, fp_mode == norm_mode);
|
||||||
emit_insn (gen_fpu_switch1 (addr_reg));
|
|
||||||
else
|
|
||||||
emit_insn (gen_fpu_switch0 (addr_reg));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Is the given character a logical line separator for the assembler? */
|
/* Is the given character a logical line separator for the assembler? */
|
||||||
|
@ -9760,34 +9760,6 @@ mov.l\\t1f,r0\\n\\
|
|||||||
|
|
||||||
;; ??? All patterns should have a type attribute.
|
;; ??? All patterns should have a type attribute.
|
||||||
|
|
||||||
(define_expand "fpu_switch0"
|
|
||||||
[(set (match_operand:SI 0 "" "") (match_dup 2))
|
|
||||||
(set (match_dup 1) (mem:PSI (match_dup 0)))]
|
|
||||||
"(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
|
|
||||||
"
|
|
||||||
{
|
|
||||||
operands[1] = get_fpscr_rtx ();
|
|
||||||
operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
|
|
||||||
if (flag_pic)
|
|
||||||
operands[2] = legitimize_pic_address (operands[2], SImode,
|
|
||||||
no_new_pseudos ? operands[0] : 0);
|
|
||||||
}")
|
|
||||||
|
|
||||||
(define_expand "fpu_switch1"
|
|
||||||
[(set (match_operand:SI 0 "" "") (match_dup 2))
|
|
||||||
(set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
|
|
||||||
(set (match_dup 1) (mem:PSI (match_dup 3)))]
|
|
||||||
"(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
|
|
||||||
"
|
|
||||||
{
|
|
||||||
operands[1] = get_fpscr_rtx ();
|
|
||||||
operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
|
|
||||||
if (flag_pic)
|
|
||||||
operands[2] = legitimize_pic_address (operands[2], SImode,
|
|
||||||
no_new_pseudos ? operands[0] : 0);
|
|
||||||
operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
|
|
||||||
}")
|
|
||||||
|
|
||||||
(define_expand "movpsi"
|
(define_expand "movpsi"
|
||||||
[(set (match_operand:PSI 0 "register_operand" "")
|
[(set (match_operand:PSI 0 "register_operand" "")
|
||||||
(match_operand:PSI 1 "general_movsrc_operand" ""))]
|
(match_operand:PSI 1 "general_movsrc_operand" ""))]
|
||||||
@ -9822,35 +9794,43 @@ mov.l\\t1f,r0\\n\\
|
|||||||
[(set_attr "length" "0,2,2,4,2,2,2,2,2")
|
[(set_attr "length" "0,2,2,4,2,2,2,2,2")
|
||||||
(set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
|
(set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
|
||||||
|
|
||||||
(define_split
|
(define_peephole2
|
||||||
[(set (reg:PSI FPSCR_REG)
|
[(set (reg:PSI FPSCR_REG)
|
||||||
(mem:PSI (match_operand:SI 0 "register_operand" "")))]
|
(mem:PSI (match_operand:SI 0 "register_operand" "")))]
|
||||||
"(TARGET_SH4 || TARGET_SH2A_DOUBLE) && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
|
"(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
|
||||||
[(set (match_dup 0) (match_dup 0))]
|
[(const_int 0)]
|
||||||
"
|
|
||||||
{
|
{
|
||||||
rtx mem, insn;
|
rtx fpscr, mem, new_insn;
|
||||||
|
|
||||||
|
fpscr = SET_DEST (PATTERN (curr_insn));
|
||||||
mem = SET_SRC (PATTERN (curr_insn));
|
mem = SET_SRC (PATTERN (curr_insn));
|
||||||
mem = change_address (mem, PSImode, gen_rtx_POST_INC (Pmode, operands[0]));
|
mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
|
||||||
insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (), mem));
|
|
||||||
REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
|
new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
|
||||||
}")
|
REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
|
||||||
|
DONE;
|
||||||
|
})
|
||||||
|
|
||||||
(define_split
|
(define_split
|
||||||
[(set (reg:PSI FPSCR_REG)
|
[(set (reg:PSI FPSCR_REG)
|
||||||
(mem:PSI (match_operand:SI 0 "register_operand" "")))]
|
(mem:PSI (match_operand:SI 0 "register_operand" "")))]
|
||||||
"(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
|
"(TARGET_SH4 || TARGET_SH2A_DOUBLE)
|
||||||
[(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
|
&& (flag_peephole2 ? flow2_completed : reload_completed)"
|
||||||
"
|
[(const_int 0)]
|
||||||
{
|
{
|
||||||
rtx mem, insn;
|
rtx fpscr, mem, new_insn;
|
||||||
|
|
||||||
|
fpscr = SET_DEST (PATTERN (curr_insn));
|
||||||
mem = SET_SRC (PATTERN (curr_insn));
|
mem = SET_SRC (PATTERN (curr_insn));
|
||||||
mem = change_address (mem, PSImode, gen_rtx_POST_INC (Pmode, operands[0]));
|
mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
|
||||||
insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (), mem));
|
|
||||||
REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
|
new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
|
||||||
}")
|
REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
|
||||||
|
|
||||||
|
if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
|
||||||
|
emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
|
||||||
|
DONE;
|
||||||
|
})
|
||||||
|
|
||||||
;; ??? This uses the fp unit, but has no type indicating that.
|
;; ??? This uses the fp unit, but has no type indicating that.
|
||||||
;; If we did that, this would either give a bogus latency or introduce
|
;; If we did that, this would either give a bogus latency or introduce
|
||||||
|
@ -456,6 +456,18 @@ optimize_mode_switching (FILE *file)
|
|||||||
|
|
||||||
REG_SET_TO_HARD_REG_SET (live_now,
|
REG_SET_TO_HARD_REG_SET (live_now,
|
||||||
bb->il.rtl->global_live_at_start);
|
bb->il.rtl->global_live_at_start);
|
||||||
|
|
||||||
|
/* Pretend the mode is clobbered across abnormal edges. */
|
||||||
|
{
|
||||||
|
edge_iterator ei;
|
||||||
|
edge e;
|
||||||
|
FOR_EACH_EDGE (e, ei, bb->preds)
|
||||||
|
if (e->flags & EDGE_COMPLEX)
|
||||||
|
break;
|
||||||
|
if (e)
|
||||||
|
RESET_BIT (transp[bb->index], j);
|
||||||
|
}
|
||||||
|
|
||||||
for (insn = BB_HEAD (bb);
|
for (insn = BB_HEAD (bb);
|
||||||
insn != NULL && insn != NEXT_INSN (BB_END (bb));
|
insn != NULL && insn != NEXT_INSN (BB_END (bb));
|
||||||
insn = NEXT_INSN (insn))
|
insn = NEXT_INSN (insn))
|
||||||
|
Loading…
Reference in New Issue
Block a user