This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Simple returns are broken in gcc 3.X


> In looking into why g++ didn't work for vax-dec-ultrix4.3, I have found
> that simple returns are broken.  Compiling this small test program
> 
> static char *
> srealloc (char *p, char *q, int i)
> {
>   if (i == 0)
>     return p;
>   else
>     return q;
> }
> 
> yields
> 
> #NO_APP
> 	.text
> 	.align 1
> __Z8sreallocPcS_i:
> 	.word 0x0
> 	subl2 $12,sp
> 	tstl 12(ap)
> 	jneq L2
> 	ret
> L2:
> 	ret

This patch fixes the above problem by always forcing a "goto" return.
The patch only affects the vax since it is the only remaining port that
doesn't define an epilogue and allows the expansion of simple returns
prior to reload.  This patch changes the vax port to use the same
code patch for return generation as all others.  As a side benefit, the
change also fixes function instrumentation on the vax.

The above behavior is a regression versus previous gcc versions since
g++ was functional on the vax in version 2.8.1.

Full bootstrap has been done with vax-dec-ultrix4.3 with 3.0 branch.
Bootstrap and regression checked with 3.0 branch on hppa1.1-hp-hpux10.20
and i686-pc-linux-gnu.  Bootstrap and regression checked with 3.1
mainline on i686-pc-linux-gnu.

OK for main?  I would like it on the branch as well but there are a
couple of other patches needed before C++ will be fully functional
on the vax.  Thus, it can wait until after 3.0.1 is released.

Dave
-- 
J. David Anglin                                  dave.anglin@nrc.ca
National Research Council of Canada              (613) 990-0752 (FAX: 952-6605)

2001-08-09  John David Anglin  <dave@hiauly1.hia.nrc.ca>

	* stmt.c (expand_null_return_1): Remove code to generate simple returns 
	and "use_goto" argument.
	(expand_null_return, expand_value_return): Update all callers.
	* function.c (expand_function_end): Remove code to generate simple
	return.
	* config/vax/vax.md (epilogue): New expander for function return.
	* doc/md.texi (epilogue): Remove "if defined".

--- stmt.c.orig	Tue Jul 31 10:22:56 2001
+++ stmt.c	Wed Aug  1 15:52:05 2001
@@ -403,7 +403,7 @@
 static void expand_nl_goto_receivers	PARAMS ((struct nesting *));
 static void fixup_gotos			PARAMS ((struct nesting *, rtx, tree,
 					       rtx, int));
-static void expand_null_return_1	PARAMS ((rtx, int));
+static void expand_null_return_1	PARAMS ((rtx));
 static void expand_value_return		PARAMS ((rtx));
 static int tail_recursion_args		PARAMS ((tree, tree));
 static void expand_cleanups		PARAMS ((tree, tree, int, int));
@@ -2863,7 +2863,6 @@
 void
 expand_null_return ()
 {
-  struct nesting *block = block_stack;
   rtx last_insn = get_last_insn ();
 
   /* If this function was declared to return a value, but we
@@ -2871,13 +2870,7 @@
      propogated live to the rest of the function.  */
   clobber_return_register ();
 
-  /* Does any pending block have cleanups?  */
-  while (block && block->data.block.cleanups == 0)
-    block = block->next;
-
-  /* If yes, use a goto to return, since that runs cleanups.  */
-
-  expand_null_return_1 (last_insn, block != 0);
+  expand_null_return_1 (last_insn);
 }
 
 /* Generate RTL to return from the current function, with value VAL.  */
@@ -2886,7 +2879,6 @@
 expand_value_return (val)
      rtx val;
 {
-  struct nesting *block = block_stack;
   rtx last_insn = get_last_insn ();
   rtx return_reg = DECL_RTL (DECL_RESULT (current_function_decl));
 
@@ -2913,27 +2905,15 @@
 	emit_move_insn (return_reg, val);
     }
 
-  /* Does any pending block have cleanups?  */
-
-  while (block && block->data.block.cleanups == 0)
-    block = block->next;
-
-  /* If yes, use a goto to return, since that runs cleanups.
-     Use LAST_INSN to put cleanups *before* the move insn emitted above.  */
-
-  expand_null_return_1 (last_insn, block != 0);
+  expand_null_return_1 (last_insn);
 }
 
 /* Output a return with no value.  If LAST_INSN is nonzero,
-   pretend that the return takes place after LAST_INSN.
-   If USE_GOTO is nonzero then don't use a return instruction;
-   go to the return label instead.  This causes any cleanups
-   of pending blocks to be executed normally.  */
+   pretend that the return takes place after LAST_INSN.  */
 
 static void
-expand_null_return_1 (last_insn, use_goto)
+expand_null_return_1 (last_insn)
      rtx last_insn;
-     int use_goto;
 {
   rtx end_label = cleanup_label ? cleanup_label : return_label;
 
@@ -2941,27 +2921,8 @@
   do_pending_stack_adjust ();
   last_expr_type = 0;
 
-  /* PCC-struct return always uses an epilogue.  */
-  if (current_function_returns_pcc_struct || use_goto)
-    {
-      if (end_label == 0)
-	end_label = return_label = gen_label_rtx ();
-      expand_goto_internal (NULL_TREE, end_label, last_insn);
-      return;
-    }
-
-  /* Otherwise output a simple return-insn if one is available,
-     unless it won't do the job.  */
-#ifdef HAVE_return
-  if (HAVE_return && use_goto == 0 && cleanup_label == 0)
-    {
-      emit_jump_insn (gen_return ());
-      emit_barrier ();
-      return;
-    }
-#endif
-
-  /* Otherwise jump to the epilogue.  */
+  if (end_label == 0)
+     end_label = return_label = gen_label_rtx ();
   expand_goto_internal (NULL_TREE, end_label, last_insn);
 }
 
--- function.c.orig	Sat Jun  9 15:22:26 2001
+++ function.c	Wed Aug  1 12:40:23 2001
@@ -6949,18 +6949,6 @@
      instead of using the general framework.  */
   use_return_register ();
 
-  /* Output a return insn if we are using one.
-     Otherwise, let the rtl chain end here, to drop through
-     into the epilogue.  */
-
-#ifdef HAVE_return
-  if (HAVE_return)
-    {
-      emit_jump_insn (gen_return ());
-      emit_barrier ();
-    }
-#endif
-
   /* Fix up any gotos that jumped out to the outermost
      binding level of the function.
      Must follow emitting RETURN_LABEL.  */
--- config/vax/vax.md.orig	Sun Jan 14 04:08:51 2001
+++ config/vax/vax.md	Tue Jul 31 22:08:45 2001
@@ -1926,6 +1926,15 @@
   ""
   "ret")
 
+(define_expand "epilogue"
+  [(return)]
+  ""
+  "
+{
+  emit_jump_insn (gen_return ());
+  DONE;
+}")
+
 (define_insn "nop"
   [(const_int 0)]
   ""
--- doc/md.texi.orig	Thu Jun 14 18:54:21 2001
+++ doc/md.texi	Thu Aug  9 12:24:04 2001
@@ -2859,7 +2859,7 @@
 
 @cindex @code{epilogue} instruction pattern
 @item @samp{epilogue}
-This pattern, if defined, emits RTL for exit from a function.  The function
+This pattern emits RTL for exit from a function.  The function
 exit is responsible for deallocating the stack frame, restoring callee saved
 registers and emitting the return instruction.
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]