diff options
author | obrien <obrien@FreeBSD.org> | 2002-05-09 20:02:13 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2002-05-09 20:02:13 +0000 |
commit | c8f5fc7032940ad6633f932ac40cade82ec4d0cc (patch) | |
tree | 29a0f0a6c79a69ecc64f612947a0fe5904311713 /contrib/gcc/sibcall.c | |
parent | c9ab9ae440a8066b2c2b85b157b1fdadcf09916a (diff) | |
download | FreeBSD-src-c8f5fc7032940ad6633f932ac40cade82ec4d0cc.zip FreeBSD-src-c8f5fc7032940ad6633f932ac40cade82ec4d0cc.tar.gz |
Gcc 3.1.0 pre-release from the FSF anoncvs repo on 9-May-2002 15:57:15 EDT.
Diffstat (limited to 'contrib/gcc/sibcall.c')
-rw-r--r-- | contrib/gcc/sibcall.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/contrib/gcc/sibcall.c b/contrib/gcc/sibcall.c index 6c2dc5c..6e753fa 100644 --- a/contrib/gcc/sibcall.c +++ b/contrib/gcc/sibcall.c @@ -31,6 +31,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "basic-block.h" #include "output.h" #include "except.h" +#include "tree.h" /* In case alternate_exit_block contains copy from pseudo, to return value, record the pseudo here. In such case the pseudo must be set to function @@ -572,7 +573,7 @@ optimize_sibling_and_tail_recursive_calls () { rtx insn, insns; basic_block alternate_exit = EXIT_BLOCK_PTR; - int current_function_uses_addressof; + bool no_sibcalls_this_function = false; int successful_sibling_call = 0; int replaced_call_placeholder = 0; edge e; @@ -595,6 +596,12 @@ optimize_sibling_and_tail_recursive_calls () if (n_basic_blocks == 0) return; + /* If we are using sjlj exceptions, we may need to add a call to + _Unwind_SjLj_Unregister at exit of the function. Which means + that we cannot do any sibcall transformations. */ + if (USING_SJLJ_EXCEPTIONS && current_function_has_exception_handlers ()) + no_sibcalls_this_function = true; + return_value_pseudo = NULL_RTX; /* Find the exit block. @@ -655,7 +662,7 @@ optimize_sibling_and_tail_recursive_calls () /* If the function uses ADDRESSOF, we can't (easily) determine at this point if the value will end up on the stack. */ - current_function_uses_addressof = sequence_uses_addressof (insns); + no_sibcalls_this_function |= sequence_uses_addressof (insns); /* Walk the insn chain and find any CALL_PLACEHOLDER insns. We need to select one of the insn sequences attached to each CALL_PLACEHOLDER. @@ -685,11 +692,10 @@ optimize_sibling_and_tail_recursive_calls () /* See if there are any reasons we can't perform either sibling or tail call optimizations. We must be careful with stack slots - which are live at potential optimization sites. ??? The first - test is overly conservative and should be replaced. */ - if (frame_offset - /* Can't take address of local var if used by recursive call. */ - || current_function_uses_addressof + which are live at potential optimization sites. */ + if (no_sibcalls_this_function + /* ??? Overly conservative. */ + || frame_offset /* Any function that calls setjmp might have longjmp called from any called function. ??? We really should represent this properly in the CFG so that this needn't be special cased. */ @@ -725,6 +731,7 @@ optimize_sibling_and_tail_recursive_calls () if (successful_sibling_call) { rtx insn; + tree arg; /* A sibling call sequence invalidates any REG_EQUIV notes made for this function's incoming arguments. @@ -749,6 +756,16 @@ optimize_sibling_and_tail_recursive_calls () if (INSN_P (insn)) purge_mem_unchanging_flag (PATTERN (insn)); } + + /* Similarly, invalidate RTX_UNCHANGING_P for any incoming + arguments passed in registers. */ + for (arg = DECL_ARGUMENTS (current_function_decl); + arg; + arg = TREE_CHAIN (arg)) + { + if (REG_P (DECL_RTL (arg))) + RTX_UNCHANGING_P (DECL_RTL (arg)) = false; + } } /* There may have been NOTE_INSN_BLOCK_{BEGIN,END} notes in the |