Committed, MMIX: Add "return" pattern and options -msingle-exit/-mno-single-exit.
Hans-Peter Nilsson
hp@bitrange.com
Sun Jun 30 12:42:00 GMT 2002
This did a whopping 0.11%..0.15% on the mmix simulator and
0.002%..0.09% on Ghostscript. The main reason was to serve as
intermediate work though, but it's nice to know that at least
things didn't get worse. Tested as always on
mmix-knuth-mmixware and "make info && make dvi", no regressions
or nearby overfull hboxes.
* config/mmix/mmix.md ("return"): New pattern.
* config/mmix/mmix.h (TARGET_MASK_USE_RETURN_INSN)
(TARGET_USE_RETURN_INSN): New macros.
(TARGET_DEFAULT): Include TARGET_MASK_USE_RETURN_INSN.
(TARGET_SWITCHES): Add -msingle-exit and -mno-single-exit.
* config/mmix/mmix.c (MMIX_OUTPUT_REGNO): Fix spacing.
(MMIX_POP_ARGUMENT): New macro.
(mmix_target_asm_function_prologue): When no epilogue is executed,
just emit a blank line. Use MMIX_POP_ARGUMENT with final POP insn.
(mmix_print_operand) <case '.'>: New case.
(mmix_print_operand_punct_valid_p): Match '.'.
(mmix_use_simple_return): New function.
* config/mmix/mmix-protos.h (mmix_use_simple_return): Prototype.
* doc/invoke.texi (Option Summary) <MMIX Summary>: Add
-msingle-exit, -mno-single-exit.
(MMIX Options): Ditto.
Index: invoke.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/invoke.texi,v
retrieving revision 1.152
diff -p -c -r1.152 invoke.texi
*** invoke.texi 16 Jun 2002 19:09:27 -0000 1.152
--- invoke.texi 30 Jun 2002 18:21:59 -0000
*************** in the following sections.
*** 600,606 ****
-mlibfuncs -mno-libfuncs -mepsilon -mno-epsilon -mabi=gnu @gol
-mabi=mmixware -mzero-extend -mknuthdiv -mtoplevel-symbols @gol
-melf -mbranch-predict -mno-branch-predict -mbase-addresses @gol
! -mno-base-addresses}
@emph{IA-64 Options}
@gccoptlist{
--- 600,606 ----
-mlibfuncs -mno-libfuncs -mepsilon -mno-epsilon -mabi=gnu @gol
-mabi=mmixware -mzero-extend -mknuthdiv -mtoplevel-symbols @gol
-melf -mbranch-predict -mno-branch-predict -mbase-addresses @gol
! -mno-base-addresses -msingle-exit -mno-single-exit}
@emph{IA-64 Options}
@gccoptlist{
*************** to 255 from the value held in the regist
*** 9312,9317 ****
--- 9312,9324 ----
and fast code, but the number of different data items that can be
addressed is limited. This means that a program that uses lots of static
data may require @option{-mno-base-addresses}.
+
+ @item -msingle-exit
+ @itemx -mno-single-exit
+ @opindex msingle-exit
+ @opindex mno-single-exit
+ Force (do not force) generated code to have a single exit point in each
+ function.
@end table
@node PDP-11 Options
Index: mmix-protos.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/mmix/mmix-protos.h,v
retrieving revision 1.12
diff -p -c -r1.12 mmix-protos.h
*** mmix-protos.h 21 Jun 2002 03:55:47 -0000 1.12
--- mmix-protos.h 30 Jun 2002 17:52:53 -0000
*************** extern void mmix_asm_output_aligned_loca
*** 82,87 ****
--- 82,88 ----
extern void mmix_asm_declare_register_global
PARAMS ((FILE *, tree, int, const char *));
extern void mmix_asm_output_mi_thunk PARAMS ((FILE *, tree, int, tree));
+ extern int mmix_use_simple_return PARAMS ((void));
/* Need tree.h and rtl.h */
# ifdef RTX_CODE
Index: mmix.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/mmix/mmix.c,v
retrieving revision 1.33
diff -p -c -r1.33 mmix.c
*** mmix.c 21 Jun 2002 03:55:47 -0000 1.33
--- mmix.c 30 Jun 2002 17:52:54 -0000
*************** Boston, MA 02111-1307, USA. */
*** 71,81 ****
increasing rL and clearing unused (unset) registers with lower numbers. */
#define MMIX_OUTPUT_REGNO(N) \
(TARGET_ABI_GNU \
! || (int) (N) < MMIX_RETURN_VALUE_REGNUM \
! || (int) (N) > MMIX_LAST_STACK_REGISTER_REGNUM \
? (N) : ((N) - MMIX_RETURN_VALUE_REGNUM \
+ cfun->machine->highest_saved_stack_register + 1))
/* The canonical saved comparison operands for non-cc0 machines, set in
the compare expander. */
rtx mmix_compare_op0;
--- 71,90 ----
increasing rL and clearing unused (unset) registers with lower numbers. */
#define MMIX_OUTPUT_REGNO(N) \
(TARGET_ABI_GNU \
! || (int) (N) < MMIX_RETURN_VALUE_REGNUM \
! || (int) (N) > MMIX_LAST_STACK_REGISTER_REGNUM \
? (N) : ((N) - MMIX_RETURN_VALUE_REGNUM \
+ cfun->machine->highest_saved_stack_register + 1))
+ /* The %d in "POP %d,0". */
+ #define MMIX_POP_ARGUMENT() \
+ ((! TARGET_ABI_GNU \
+ && current_function_return_rtx != NULL \
+ && ! current_function_returns_struct) \
+ ? (GET_CODE (current_function_return_rtx) == PARALLEL \
+ ? GET_NUM_ELEM (XVEC (current_function_return_rtx, 0)) : 1) \
+ : 0)
+
/* The canonical saved comparison operands for non-cc0 machines, set in
the compare expander. */
rtx mmix_compare_op0;
*************** mmix_target_asm_function_epilogue (strea
*** 1058,1063 ****
--- 1067,1092 ----
/* The first address to access is beyond the outgoing_args area. */
int offset = current_function_outgoing_args_size;
+ rtx insn = get_last_insn ();
+
+ /* If the last insn was a BARRIER, we don't have to write any code,
+ then all returns were covered by "return" insns. */
+ if (GET_CODE (insn) == NOTE)
+ insn = prev_nonnote_insn (insn);
+ if (insn
+ && (GET_CODE (insn) == BARRIER
+ /* We must make sure that the insn really is a "return" and
+ not a conditional branch. Try to match the return exactly,
+ and if it doesn't match, assume it is a conditional branch
+ (and output an epilogue). */
+ || (GET_CODE (insn) == JUMP_INSN
+ && GET_CODE (PATTERN (insn)) == RETURN)))
+ {
+ /* Emit an extra \n as is done with the normal epilogue. */
+ fputc ('\n', stream);
+ return;
+ }
+
/* Add the space for global non-register-stack registers.
It is assumed that the frame-pointer register can be one of these
registers, in which case it is excluded from the count when needed. */
*************** mmix_target_asm_function_epilogue (strea
*** 1197,1209 ****
/* The extra \n is so we have a blank line between the assembly code of
separate functions. */
! fprintf (stream, "\tPOP %d,0\n\n",
! (! TARGET_ABI_GNU
! && current_function_return_rtx != NULL
! && ! current_function_returns_struct)
! ? (GET_CODE (current_function_return_rtx) == PARALLEL
! ? GET_NUM_ELEM (XVEC (current_function_return_rtx, 0)) : 1)
! : 0);
}
/* ASM_OUTPUT_MI_THUNK. */
--- 1226,1232 ----
/* The extra \n is so we have a blank line between the assembly code of
separate functions. */
! fprintf (stream, "\tPOP %d,0\n\n", MMIX_POP_ARGUMENT ());
}
/* ASM_OUTPUT_MI_THUNK. */
*************** mmix_print_operand (stream, x, code)
*** 2098,2103 ****
--- 2121,2131 ----
}
return;
+ case '.':
+ /* For the %d in POP %d,0. */
+ fprintf (stream, "%d", MMIX_POP_ARGUMENT ());
+ return;
+
case 'B':
if (GET_CODE (x) != CONST_INT)
fatal_insn ("MMIX Internal: Expected a CONST_INT, not this", x);
*************** mmix_print_operand_punct_valid_p (code)
*** 2303,2309 ****
int code ATTRIBUTE_UNUSED;
{
/* A '+' is used for branch prediction, similar to other ports. */
! return code == '+';
}
/* PRINT_OPERAND_ADDRESS. */
--- 2331,2339 ----
int code ATTRIBUTE_UNUSED;
{
/* A '+' is used for branch prediction, similar to other ports. */
! return code == '+'
! /* A '.' is used for the %d in the POP %d,0 return insn. */
! || code == '.';
}
/* PRINT_OPERAND_ADDRESS. */
*************** mmix_dbx_register_number (regno)
*** 2452,2457 ****
--- 2482,2524 ----
/* End of target macro support functions.
Now MMIX's own functions. First the exported ones. */
+
+ /* Non-zero when the function epilogue is simple enough that a single
+ "POP %d,0" should be used. */
+
+ int
+ mmix_use_simple_return ()
+ {
+ int regno;
+
+ int stack_space_to_allocate
+ = (current_function_outgoing_args_size
+ + current_function_pretend_args_size
+ + get_frame_size () + 7) & ~7;
+
+ if (!TARGET_USE_RETURN_INSN || !reload_completed)
+ return 0;
+
+ for (regno = 255;
+ regno >= MMIX_FIRST_GLOBAL_REGNUM;
+ regno--)
+ /* Note that we assume that the frame-pointer-register is one of these
+ registers, in which case we don't count it here. */
+ if ((((regno != MMIX_FRAME_POINTER_REGNUM || !frame_pointer_needed)
+ && regs_ever_live[regno] && !call_used_regs[regno]))
+ || IS_MMIX_EH_RETURN_DATA_REG (regno))
+ return 0;
+
+ if (frame_pointer_needed)
+ stack_space_to_allocate += 8;
+
+ if (MMIX_CFUN_HAS_LANDING_PAD)
+ stack_space_to_allocate += 16;
+ else if (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS)
+ stack_space_to_allocate += 8;
+
+ return stack_space_to_allocate == 0;
+ }
/* Output an optimal sequence for setting a register to a specific
constant. Used in an alternative for const_ints in movdi, and when
Index: mmix.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/mmix/mmix.h,v
retrieving revision 1.34
diff -p -c -r1.34 mmix.h
*** mmix.h 21 Jun 2002 03:55:47 -0000 1.34
--- mmix.h 30 Jun 2002 17:52:55 -0000
*************** extern int target_flags;
*** 161,166 ****
--- 161,167 ----
#define TARGET_MASK_KNUTH_DIVISION 16
#define TARGET_MASK_TOPLEVEL_SYMBOLS 32
#define TARGET_MASK_BRANCH_PREDICT 64
+ #define TARGET_MASK_USE_RETURN_INSN 128
/* We use the term "base address" since that's what Knuth uses. The base
address goes in a global register. When addressing, it's more like
*************** extern int target_flags;
*** 183,191 ****
#define TARGET_TOPLEVEL_SYMBOLS (target_flags & TARGET_MASK_TOPLEVEL_SYMBOLS)
#define TARGET_BRANCH_PREDICT (target_flags & TARGET_MASK_BRANCH_PREDICT)
#define TARGET_BASE_ADDRESSES (target_flags & TARGET_MASK_BASE_ADDRESSES)
#define TARGET_DEFAULT \
! (TARGET_MASK_BRANCH_PREDICT | TARGET_MASK_BASE_ADDRESSES)
/* FIXME: Provide a way to *load* the epsilon register. */
#define TARGET_SWITCHES \
--- 184,194 ----
#define TARGET_TOPLEVEL_SYMBOLS (target_flags & TARGET_MASK_TOPLEVEL_SYMBOLS)
#define TARGET_BRANCH_PREDICT (target_flags & TARGET_MASK_BRANCH_PREDICT)
#define TARGET_BASE_ADDRESSES (target_flags & TARGET_MASK_BASE_ADDRESSES)
+ #define TARGET_USE_RETURN_INSN (target_flags & TARGET_MASK_USE_RETURN_INSN)
#define TARGET_DEFAULT \
! (TARGET_MASK_BRANCH_PREDICT | TARGET_MASK_BASE_ADDRESSES \
! | TARGET_MASK_USE_RETURN_INSN)
/* FIXME: Provide a way to *load* the epsilon register. */
#define TARGET_SWITCHES \
*************** extern int target_flags;
*** 220,225 ****
--- 223,232 ----
N_("Use addresses that allocate global registers")}, \
{"no-base-addresses", -TARGET_MASK_BASE_ADDRESSES, \
N_("Do not use addresses that allocate global registers")}, \
+ {"single-exit", -TARGET_MASK_USE_RETURN_INSN, \
+ N_("Generate a single exit point for each function")}, \
+ {"no-single-exit", TARGET_MASK_USE_RETURN_INSN, \
+ N_("Do not generate a single exit point for each function")}, \
{"", TARGET_DEFAULT, ""}}
/* Unfortunately, this must not reference anything in "mmix.c". */
Index: mmix.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/mmix/mmix.md,v
retrieving revision 1.13
diff -p -c -r1.13 mmix.md
*** mmix.md 21 Jun 2002 03:55:46 -0000 1.13
--- mmix.md 30 Jun 2002 17:52:55 -0000
*************** DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\
*** 1067,1074 ****
;; I hope untyped_call and untyped_return are not needed for MMIX.
;; Users of Objective C will notice.
! ;; FIXME: Add "return" pattern where the epilogue is just "pop
! ;; 0,0" or similar.
(define_insn "nop"
[(const_int 0)]
--- 1067,1076 ----
;; I hope untyped_call and untyped_return are not needed for MMIX.
;; Users of Objective C will notice.
! (define_insn "return"
! [(return)]
! "mmix_use_simple_return ()"
! "POP %.,0")
(define_insn "nop"
[(const_int 0)]
brgds, H-P
More information about the Gcc-patches
mailing list