summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/sibcall.c
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2002-05-09 20:02:13 +0000
committerobrien <obrien@FreeBSD.org>2002-05-09 20:02:13 +0000
commitc8f5fc7032940ad6633f932ac40cade82ec4d0cc (patch)
tree29a0f0a6c79a69ecc64f612947a0fe5904311713 /contrib/gcc/sibcall.c
parentc9ab9ae440a8066b2c2b85b157b1fdadcf09916a (diff)
downloadFreeBSD-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.c31
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
OpenPOWER on IntegriCloud