aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/calls.c17
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 ();