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