diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-08-12 16:28:10 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-08-12 16:28:10 +0000 |
commit | cd921bcba43652e6b18c23c7cf4080eefa6e24e6 (patch) | |
tree | 0b58003a89bb66321aeaebb663ee8fe8ba653669 /gcc/sibcall.c | |
parent | 00608ffd7a7cca92a16d5c42e900dbe5fe56cd16 (diff) | |
download | gcc-cd921bcba43652e6b18c23c7cf4080eefa6e24e6.tar.gz |
* sibcall.c (uses_addressof): Accept both addressof and
current_function_internal_arg_pointer inside a mem.
(optimize_sibling_and_tail_recursive_call): Fail tail recursion
if current_function_uses_addressof.
* stmt.c (expand_return): Kill tail recursion and HAVE_return
optimizations.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@35657 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/sibcall.c')
-rw-r--r-- | gcc/sibcall.c | 37 |
1 files changed, 16 insertions, 21 deletions
diff --git a/gcc/sibcall.c b/gcc/sibcall.c index 78e855eef78..42a9d70fb81 100644 --- a/gcc/sibcall.c +++ b/gcc/sibcall.c @@ -37,7 +37,7 @@ static rtx skip_copy_to_return_value PARAMS ((rtx, rtx, rtx)); static rtx skip_use_of_return_value PARAMS ((rtx, enum rtx_code)); static rtx skip_stack_adjustment PARAMS ((rtx)); static rtx skip_jump_insn PARAMS ((rtx)); -static int uses_addressof PARAMS ((rtx, int)); +static int uses_addressof PARAMS ((rtx)); static int sequence_uses_addressof PARAMS ((rtx)); static void purge_reg_equiv_notes PARAMS ((void)); @@ -237,16 +237,12 @@ skip_jump_insn (orig_insn) /* Scan the rtx X for ADDRESSOF expressions or current_function_internal_arg_pointer registers. - INMEM argument should be 1 if we're looking at inner part of some - MEM expression, otherwise 0. - Return nonzero if an ADDRESSOF expresion is found or if - current_function_internal_arg_pointer is found outside of some MEM - expression, else return zero. */ + Return nonzero if an ADDRESSOF or current_function_internal_arg_pointer + is found outside of some MEM expression, else return zero. */ static int -uses_addressof (x, inmem) +uses_addressof (x) rtx x; - int inmem; { RTX_CODE code; int i, j; @@ -257,14 +253,11 @@ uses_addressof (x, inmem) code = GET_CODE (x); - if (code == ADDRESSOF) - return 1; - - if (x == current_function_internal_arg_pointer && ! inmem) + if (code == ADDRESSOF || x == current_function_internal_arg_pointer) return 1; if (code == MEM) - return uses_addressof (XEXP (x, 0), 1); + return 0; /* Scan all subexpressions. */ fmt = GET_RTX_FORMAT (code); @@ -272,13 +265,13 @@ uses_addressof (x, inmem) { if (*fmt == 'e') { - if (uses_addressof (XEXP (x, i), inmem)) + if (uses_addressof (XEXP (x, i))) return 1; } else if (*fmt == 'E') { for (j = 0; j < XVECLEN (x, i); j++) - if (uses_addressof (XVECEXP (x, i, j), inmem)) + if (uses_addressof (XVECEXP (x, i, j))) return 1; } } @@ -318,8 +311,8 @@ sequence_uses_addressof (seq) && sequence_uses_addressof (XEXP (PATTERN (insn), 2))) return 1; } - else if (uses_addressof (PATTERN (insn), 0) - || (REG_NOTES (insn) && uses_addressof (REG_NOTES (insn), 0))) + else if (uses_addressof (PATTERN (insn)) + || (REG_NOTES (insn) && uses_addressof (REG_NOTES (insn)))) return 1; } return 0; @@ -490,14 +483,16 @@ optimize_sibling_and_tail_recursive_calls () if (frame_offset) goto failure; + /* Taking the address of a local variable is fatal to tail + recursion if the address is used by the recursive call. */ + if (current_function_uses_addressof) + goto failure; + /* alloca (until we have stack slot life analysis) inhibits sibling call optimizations, but not tail recursion. - - Similarly if we have ADDRESSOF expressions. - Similarly if we use varargs or stdarg since they implicitly may take the address of an argument. */ - if (current_function_calls_alloca || current_function_uses_addressof + if (current_function_calls_alloca || current_function_varargs || current_function_stdarg) sibcall = 0; |