diff options
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/calls.c | 17 |
2 files changed, 23 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d98fbf1..dcb99bc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2000-03-20 Richard Henderson <rth@cygnus.com> + + * calls.c (expand_call): Don't bother generating tail call + sequences if there are pending cleanups. Use + expand_start_target_temps/expand_end_target_temps to elide + cleanups created during sibcall expansion. + 2000-03-20 Geoff Keating <geoffk@cygnus.com> * configure.in: Set $IFS to a value if it doesn't already have one diff --git a/gcc/calls.c b/gcc/calls.c index 21feeed..104cc07 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -2020,7 +2020,8 @@ expand_call (exp, target, ignore) safe_for_reeval = 0; if (optimize >= 2 && currently_expanding_call == 1 - && stmt_loop_nest_empty ()) + && stmt_loop_nest_empty () + && ! any_pending_cleanups (1)) { /* Verify that each argument is safe for re-evaluation. */ for (p = actparms; p; p = TREE_CHAIN (p)) @@ -2152,6 +2153,12 @@ expand_call (exp, target, ignore) || ! FUNCTION_OK_FOR_SIBCALL (fndecl)) continue; + /* We know at this point that there are not currently any + pending cleanups. If, however, in the process of evaluating + the arguments we were to create some, we'll need to be + able to get rid of them. */ + expand_start_target_temps (); + /* State variables we need to save and restore between iterations. */ save_pending_stack_adjust = pending_stack_adjust; @@ -2925,6 +2932,14 @@ expand_call (exp, target, ignore) if (args[i].aligned_regs) free (args[i].aligned_regs); + if (pass == 0) + { + /* Undo the fake expand_start_target_temps we did earlier. If + there had been any cleanups created, we've already set + sibcall_failure. */ + expand_end_target_temps (); + } + insns = get_insns (); end_sequence (); |