sh casesi patch
Richard Henderson
rth@cygnus.com
Tue Mar 9 14:42:00 GMT 1999
Here's a proposed solution to the nastiness that is currently
causing flow to abort on SH.
The braf code label is not emitted until it is needed, so there's
no chance it will get optimized away. This obviates the need for
the dummy_jump hack, which is what was causing flow indigestion.
It's somewhat less than clear to me exactly what fixup_addr_diff_vecs
is doing. It's quite possible the two fixup functions could be merged.
r~
* sh.c (fixup_braf_labels): New function.
(machine_dependent_reorg): Call it.
(label_ref_operand): Rename from braf_*. Kill all but label test.
* sh.h (PREDICATE_OPERANDS): Rename braf_label_ref_operand.
* sh.md (casesi_jump_2): Likewise.
(dummy_jump): Kill.
(casesi): Don't emit the braf label.
Index: sh.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/sh/sh.c,v
retrieving revision 1.25
diff -c -p -d -r1.25 sh.c
*** sh.c 1999/03/02 16:42:59 1.25
--- sh.c 1999/03/09 22:37:12
*************** gen_far_branch (bp)
*** 2632,2637 ****
--- 2632,2661 ----
gen_block_redirect (jump, bp->address += 2, 2);
}
+ /* Emit the label that's to follow the `braf' of a casesi_jump_2 pattern.
+
+ Up until this point the label has existed only in a LABEL_REF on the
+ casesi pattern. This was done to avoid confusing flow with otherwise
+ unreachable code labels etc. */
+
+ static void
+ fixup_braf_labels (first)
+ rtx first;
+ {
+ rtx insn;
+
+ for (insn = first; insn; insn = NEXT_INSN (insn))
+ {
+ rtx lab;
+
+ if (INSN_CODE (insn) != CODE_FOR_casesi_jump_2)
+ continue;
+
+ lab = XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 1), 0);
+ insn = emit_label_after (lab, insn);
+ }
+ }
+
/* Fix up ADDR_DIFF_VECs. */
void
fixup_addr_diff_vecs (first)
*************** machine_dependent_reorg (first)
*** 2993,2999 ****
}
if (TARGET_SH2)
! fixup_addr_diff_vecs (first);
if (optimize)
{
--- 3017,3026 ----
}
if (TARGET_SH2)
! {
! fixup_braf_labels (first);
! fixup_addr_diff_vecs (first);
! }
if (optimize)
{
*************** fp_one_operand (op)
*** 4290,4315 ****
}
int
! braf_label_ref_operand(op, mode)
rtx op;
enum machine_mode mode;
{
rtx prev;
if (GET_CODE (op) != LABEL_REF)
- return 0;
- prev = prev_real_insn (XEXP (op, 0));
- if (GET_CODE (prev) != JUMP_INSN)
- return 0;
- prev = PATTERN (prev);
- if (GET_CODE (prev) != PARALLEL || XVECLEN (prev, 0) != 2)
return 0;
! prev = XVECEXP (prev, 0, 0);
! if (GET_CODE (prev) != SET)
! return 0;
! prev = SET_SRC (prev);
! if (GET_CODE (prev) != PLUS || XEXP (prev, 1) != op)
! return 0;
}
int
--- 4317,4331 ----
}
int
! label_ref_operand(op, mode)
rtx op;
enum machine_mode mode;
{
rtx prev;
if (GET_CODE (op) != LABEL_REF)
return 0;
! return 1;
}
int
Index: sh.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/sh/sh.h,v
retrieving revision 1.30
diff -c -p -d -r1.30 sh.h
*** sh.h 1999/03/05 11:28:33 1.30
--- sh.h 1999/03/09 22:37:12
*************** extern struct rtx_def *get_fpscr_rtx ();
*** 2120,2126 ****
{"arith_reg_operand", {SUBREG, REG}}, \
{"arith_reg_or_0_operand", {SUBREG, REG, CONST_INT}}, \
{"binary_float_operator", {PLUS, MULT}}, \
! {"braf_label_ref_operand", {LABEL_REF}}, \
{"commutative_float_operator", {PLUS, MULT}}, \
{"fp_arith_reg_operand", {SUBREG, REG}}, \
{"fp_extended_operand", {SUBREG, REG, FLOAT_EXTEND}}, \
--- 2120,2126 ----
{"arith_reg_operand", {SUBREG, REG}}, \
{"arith_reg_or_0_operand", {SUBREG, REG, CONST_INT}}, \
{"binary_float_operator", {PLUS, MULT}}, \
! {"label_ref_operand", {LABEL_REF}}, \
{"commutative_float_operator", {PLUS, MULT}}, \
{"fp_arith_reg_operand", {SUBREG, REG}}, \
{"fp_extended_operand", {SUBREG, REG, FLOAT_EXTEND}}, \
Index: sh.md
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/sh/sh.md,v
retrieving revision 1.15
diff -c -p -d -r1.15 sh.md
*** sh.md 1999/02/11 07:48:50 1.15
--- sh.md 1999/03/09 22:37:12
***************
*** 3190,3208 ****
;; For all later processors.
(define_insn "casesi_jump_2"
[(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
! (match_operand 1 "braf_label_ref_operand" "")))
(use (label_ref (match_operand 2 "" "")))]
""
"braf %0%#"
[(set_attr "needs_delay_slot" "yes")
(set_attr "type" "jump_ind")])
- (define_insn "dummy_jump"
- [(set (pc) (const_int 0))]
- ""
- ""
- [(set_attr "length" "0")])
-
;; Call subroutine returning any type.
;; ??? This probably doesn't work.
--- 3190,3202 ----
;; For all later processors.
(define_insn "casesi_jump_2"
[(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
! (match_operand 1 "label_ref_operand" "")))
(use (label_ref (match_operand 2 "" "")))]
""
"braf %0%#"
[(set_attr "needs_delay_slot" "yes")
(set_attr "type" "jump_ind")])
;; Call subroutine returning any type.
;; ??? This probably doesn't work.
***************
*** 3294,3303 ****
emit_jump_insn (gen_casesi_jump_2 (reg2,
gen_rtx (LABEL_REF, VOIDmode, lab),
operands[3]));
- emit_label (lab);
- /* Put a fake jump after the label, lest some optimization might
- delete the barrier and LAB. */
- emit_jump_insn (gen_dummy_jump ());
}
else
{
--- 3288,3293 ----
More information about the Gcc-patches
mailing list