This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] renesas abi and optimize mode switching
- From: Eric Christopher <echristo at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 01 Oct 2003 21:33:39 -0700
- Subject: [PATCH] renesas abi and optimize mode switching
Here's a patch to enhance optimize mode switching for the Renesas ABI.
The ABI has different modes on entering and exiting a function. I kept
the current default of, well, no default and test both in the code.
For simplicity I left the original definition of NORMAL_MODE and added
some additional abilities.
OK? Changes? Other thoughts?
-eric
--
Eric Christopher <echristo@redhat.com>
2003-10-01 Eric Christopher <echristo@redhat.com>
* lcm.c (optimize_mode_switching): Change NORMAL_MODE
to MODE_ENTRY and MODE_EXIT. Add MODE_AFTER for insns
that set mode.
* config/sh/sh.h (MODE_ENTRY): New macro.
(MODE_EXIT): Ditto.
(MODE_AFTER): Ditto.
* config/sh/sh.md: Change for MODE_AFTER. Add
fp_set attribute.
* doc/tm.texi: Document MODE_AFTER, MODE_ENTRY,
and MODE_EXIT.
Index: doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.257
diff -u -p -w -r1.257 tm.texi
--- doc/tm.texi 1 Oct 2003 06:01:47 -0000 1.257
+++ doc/tm.texi 1 Oct 2003 18:20:35 -0000
@@ -8239,7 +8239,8 @@ return nonzero for any @var{entity} that
If you define this macro, you also have to define
@code{NUM_MODES_FOR_MODE_SWITCHING}, @code{MODE_NEEDED},
@code{MODE_PRIORITY_TO_MODE} and @code{EMIT_MODE_SET}.
-@code{NORMAL_MODE} is optional.
+@code{MODE_AFTER}, @code{MODE_ENTRY}, and @code{MODE_EXIT}
+are optional.
@end defmac
@defmac NUM_MODES_FOR_MODE_SWITCHING
@@ -8263,10 +8264,22 @@ return an integer value not larger than
be switched into prior to the execution of @var{insn}.
@end defmac
-@defmac NORMAL_MODE (@var{entity})
+@defmac MODE_AFTER (@var{mode}, @var{insn})
+If this macro is defined, it is evaluated for every @var{insn} during
+mode switching. It determines the mode that an insn results in (if
+different from the incoming mode).
+@end defmac
+
+@defmac MODE_ENTRY (@var{entity})
If this macro is defined, it is evaluated for every @var{entity} that
needs
mode switching. It should evaluate to an integer, which is a mode that
-@var{entity} is assumed to be switched to at function entry and exit.
+@var{entity} is assumed to be switched to at function entry.
+@end defmac
+
+@defmac MODE_EXIT (@var{entity})
+If this macro is defined, it is evaluated for every @var{entity} that
needs
+mode switching. It should evaluate to an integer, which is a mode that
+@var{entity} is assumed to be switched to at function exit.
@end defmac
@defmac MODE_PRIORITY_TO_MODE (@var{entity}, @var{n})
@@ -9173,4 +9186,3 @@ more than this number of multiplications
system library's @code{pow}, @code{powf} or @code{powl} routines.
The default value places no upper bound on the multiplication count.
@end defmac
-
Index: lcm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/lcm.c,v
retrieving revision 1.56
diff -u -p -w -r1.56 lcm.c
--- lcm.c 19 Jul 2003 14:47:07 -0000 1.56
+++ lcm.c 1 Oct 2003 18:20:36 -0000
@@ -990,7 +990,7 @@ optimize_mode_switching (FILE *file)
/* Create the list of segments within each basic block.
If NORMAL_MODE is defined, allow for two extra
blocks split from the entry and exit block. */
-#ifdef NORMAL_MODE
+#if defined (MODE_ENTRY) && defined (MODE_EXIT)
entry_exit_extra = 2;
#endif
bb_info[n_entities]
@@ -1003,7 +1003,7 @@ optimize_mode_switching (FILE *file)
if (! n_entities)
return 0;
-#ifdef NORMAL_MODE
+#if defined (MODE_ENTRY) && defined (MODE_EXIT)
{
/* Split the edge from the entry block and the fallthrough edge to
the
exit block, so that we can note that there NORMAL_MODE is
supplied /
@@ -1069,6 +1069,7 @@ optimize_mode_switching (FILE *file)
RESET_BIT (transp[bb->index], j);
}
+ last_mode = MODE_AFTER (last_mode, insn);
/* Update LIVE_NOW. */
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
if (REG_NOTE_KIND (link) == REG_DEAD)
@@ -1089,9 +1090,9 @@ optimize_mode_switching (FILE *file)
add_seginfo (info + bb->index, ptr);
}
}
-#ifdef NORMAL_MODE
+#if defined (MODE_ENTRY) && defined (MODE_EXIT)
{
- int mode = NORMAL_MODE (e);
+ int mode = MODE_ENTRY (e);
if (mode != no_mode)
{
@@ -1109,7 +1110,7 @@ optimize_mode_switching (FILE *file)
info[bb->index].computing = mode;
if (pre_exit)
- info[pre_exit->index].seginfo->mode = mode;
+ info[pre_exit->index].seginfo->mode = MODE_EXIT (e);
}
}
#endif /* NORMAL_MODE */
@@ -1285,7 +1286,7 @@ optimize_mode_switching (FILE *file)
if (need_commit)
commit_edge_insertions ();
-#ifdef NORMAL_MODE
+#if defined (MODE_ENTRY) && defined (MODE_EXIT)
cleanup_cfg (CLEANUP_NO_INSN_DEL);
#else
if (!need_commit && !emited)
Index: config/sh/sh.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.h,v
retrieving revision 1.222
diff -u -p -w -r1.222 sh.h
--- config/sh/sh.h 27 Sep 2003 04:48:28 -0000 1.222
+++ config/sh/sh.h 1 Oct 2003 18:20:37 -0000
@@ -3234,6 +3234,10 @@ extern int rtx_equal_function_value_matt
? (TARGET_FMOVD ? FP_MODE_DOUBLE : FP_MODE_NONE) \
: ACTUAL_NORMAL_MODE (ENTITY))
+#define MODE_ENTRY(ENTITY) NORMAL_MODE (ENTITY)
+
+#define MODE_EXIT(ENTITY) (sh_cfun_attr_renesas_p () ? FP_MODE_NONE :
NORMAL_MODE (ENTITY))
+
#define EPILOGUE_USES(REGNO) ((TARGET_SH2E || TARGET_SH4) \
&& (REGNO) == FPSCR_REG)
@@ -3241,6 +3245,12 @@ extern int rtx_equal_function_value_matt
(recog_memoized (INSN) >= 0 \
? get_attr_fp_mode (INSN) \
: FP_MODE_NONE)
+
+#define MODE_AFTER(MODE, INSN) \
+ (recog_memoized (INSN) >= 0 \
+ && get_attr_fp_set (INSN) != FP_SET_NONE \
+ ? get_attr_fp_set (INSN) \
+ : (MODE))
#define MODE_PRIORITY_TO_MODE(ENTITY, N) \
((TARGET_FPU_SINGLE != 0) ^ (N) ? FP_MODE_SINGLE : FP_MODE_DOUBLE)
Index: config/sh/sh.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.md,v
retrieving revision 1.159
diff -u -p -w -r1.159 sh.md
--- config/sh/sh.md 27 Sep 2003 04:48:28 -0000 1.159
+++ config/sh/sh.md 1 Oct 2003 18:20:39 -0000
@@ -280,6 +280,14 @@
(define_attr "fp_mode" "single,double,none" (const_string "none"))
+;; Indicate if the fpu mode is set by this instruction
+;; "unknown" must have the value as "none" in fp_mode, and means
+;; that the instruction/abi has left the processor in an unknown
+;; state.
+;; "none" means that nothing has changed and no mode is set.
+;; This attribute is only used for the Renesas ABI.
+(define_attr "fp_set" "single,double,unknown,none" (const_string
"none"))
+
; If a conditional branch destination is within -252..258 bytes away
; from the instruction it can be 2 bytes long. Something in the
; range -4090..4100 bytes can be 6 bytes long. All other conditional
@@ -5562,7 +5570,8 @@
(set (attr "fp_mode")
(if_then_else (eq_attr "fpu_single" "yes")
(const_string "single") (const_string "double")))
- (set_attr "needs_delay_slot" "yes")])
+ (set_attr "needs_delay_slot" "yes")
+ (set_attr "fp_set" "unknown")])
;; This is a pc-rel call, using bsrf, for use with PIC.
@@ -5579,7 +5588,8 @@
(set (attr "fp_mode")
(if_then_else (eq_attr "fpu_single" "yes")
(const_string "single") (const_string "double")))
- (set_attr "needs_delay_slot" "yes")])
+ (set_attr "needs_delay_slot" "yes")
+ (set_attr "fp_set" "unknown")])
(define_insn_and_split "call_pcrel"
[(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
@@ -5607,7 +5617,8 @@
(set (attr "fp_mode")
(if_then_else (eq_attr "fpu_single" "yes")
(const_string "single") (const_string "double")))
- (set_attr "needs_delay_slot" "yes")])
+ (set_attr "needs_delay_slot" "yes")
+ (set_attr "fp_set" "unknown")])
(define_insn "call_compact"
[(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
@@ -5662,7 +5673,8 @@
(set (attr "fp_mode")
(if_then_else (eq_attr "fpu_single" "yes")
(const_string "single") (const_string "double")))
- (set_attr "needs_delay_slot" "yes")])
+ (set_attr "needs_delay_slot" "yes")
+ (set_attr "fp_set" "unknown")])
(define_insn "call_valuei_pcrel"
[(set (match_operand 0 "" "=rf")
@@ -5678,7 +5690,8 @@
(set (attr "fp_mode")
(if_then_else (eq_attr "fpu_single" "yes")
(const_string "single") (const_string "double")))
- (set_attr "needs_delay_slot" "yes")])
+ (set_attr "needs_delay_slot" "yes")
+ (set_attr "fp_set" "unknown")])
(define_insn_and_split "call_value_pcrel"
[(set (match_operand 0 "" "=rf")
@@ -5708,7 +5721,8 @@
(set (attr "fp_mode")
(if_then_else (eq_attr "fpu_single" "yes")
(const_string "single") (const_string "double")))
- (set_attr "needs_delay_slot" "yes")])
+ (set_attr "needs_delay_slot" "yes")
+ (set_attr "fp_set" "unknown")])
(define_insn "call_value_compact"
[(set (match_operand 0 "" "=rf")
@@ -8169,7 +8183,8 @@ mov.l\\t1f,r0\\n\\
[(set (reg:PSI FPSCR_REG)
(xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
"TARGET_SH4"
- "fschg")
+ "fschg"
+ [(set_attr "fp_set" "unknown")])
(define_expand "addsf3"
[(set (match_operand:SF 0 "arith_reg_operand" "")