From mboxrd@z Thu Jan 1 00:00:00 1970 From: "John David Anglin" To: dave@hiauly1.hia.nrc.ca (John David Anglin) Cc: gcc@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: Re: Simple returns are broken in gcc 3.X Date: Thu, 09 Aug 2001 15:12:00 -0000 Message-id: <200108092212.f79MC5hq009138@hiauly1.hia.nrc.ca> References: X-SW-Source: 2001-08/msg00507.html > 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 * 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.