This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Destrictiveness of expansion and tree inlining deadlock?
- From: Jan Hubicka <jh at suse dot cz>
- To: Mark Mitchell <mark at codesourcery dot com>, rth at redhat dot com,gcc-patches at gcc dot gnu dot org
- Cc: Jan Hubicka <jh at suse dot cz>
- Date: Mon, 3 Mar 2003 16:58:57 +0100
- Subject: Re: Destrictiveness of expansion and tree inlining deadlock?
- References: <20030222102031.GB9783@kam.mff.cuni.cz> <4060000.1046041692@localhost> <20030226181316.GG27482@kam.mff.cuni.cz> <1046412993.4832.82.camel@doubledemon.codesourcery.com>
> > Hmm, my topological sort in unit-at-a-time manages to assemble most of
> > inline functions before they are inlined and I am hitting one crash in:
> > else if (TREE_CODE (*tp) == UNSAVE_EXPR)
> > /* UNSAVE_EXPRs should not be generated until expansion time. */
> > abort ();
> > This made me believe that expansion creates those trees and thus is
> > destructive. In the case this is wrong, what happens?
>
> It's possible that something destructive is happenning with UNSAVE_EXPRs
> -- but that is really a bug. Nothing should change from expanding a
> function into RTL.
OK, I've grepped trought the sources and found one use of UNSAVE_EXPR
that is leaked into original tree. I've bootstrapped/regtested it and I
am now re-testing with unit-at-a-time mode to verify that it fixes my
problem.
OK?
Perhaps this can go into 3.3 as well - the bug is there too, just
testcase is tricky.
Mon Mar 3 16:56:00 CET 2003 Jan Hubicka <jh at suse dot cz>
* calls.c (rtx_for_function_call): Take the address as an argument
(expand_call): Do not modify the expression.
Index: calls.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/calls.c,v
retrieving revision 1.258
diff -c -3 -p -r1.258 calls.c
*** calls.c 23 Feb 2003 22:19:39 -0000 1.258
--- calls.c 3 Mar 2003 15:56:04 -0000
*************** compute_argument_addresses (args, argblo
*** 1663,1674 ****
FNDECL is the tree node for the target function. For an indirect call
FNDECL will be NULL_TREE.
! EXP is the CALL_EXPR for this call. */
static rtx
! rtx_for_function_call (fndecl, exp)
tree fndecl;
! tree exp;
{
rtx funexp;
--- 1663,1674 ----
FNDECL is the tree node for the target function. For an indirect call
FNDECL will be NULL_TREE.
! ADDR is the operand 0 of CALL_EXPR for this call. */
static rtx
! rtx_for_function_call (fndecl, addr)
tree fndecl;
! tree addr;
{
rtx funexp;
*************** rtx_for_function_call (fndecl, exp)
*** 1690,1696 ****
/* Generate an rtx (probably a pseudo-register) for the address. */
{
push_temp_slots ();
! funexp = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0);
pop_temp_slots (); /* FUNEXP can't be BLKmode. */
emit_queue ();
}
--- 1690,1696 ----
/* Generate an rtx (probably a pseudo-register) for the address. */
{
push_temp_slots ();
! funexp = expand_expr (addr, NULL_RTX, VOIDmode, 0);
pop_temp_slots (); /* FUNEXP can't be BLKmode. */
emit_queue ();
}
*************** expand_call (exp, target, ignore)
*** 2212,2217 ****
--- 2212,2218 ----
int old_stack_allocated;
rtx call_fusage;
tree p = TREE_OPERAND (exp, 0);
+ tree addr = TREE_OPERAND (exp, 0);
int i;
/* The alignment of the stack, in bits. */
HOST_WIDE_INT preferred_stack_boundary;
*************** expand_call (exp, target, ignore)
*** 2343,2349 ****
preferred_stack_boundary = PREFERRED_STACK_BOUNDARY;
/* Operand 0 is a pointer-to-function; get the type of the function. */
! funtype = TREE_TYPE (TREE_OPERAND (exp, 0));
if (! POINTER_TYPE_P (funtype))
abort ();
funtype = TREE_TYPE (funtype);
--- 2344,2350 ----
preferred_stack_boundary = PREFERRED_STACK_BOUNDARY;
/* Operand 0 is a pointer-to-function; get the type of the function. */
! funtype = TREE_TYPE (addr);
if (! POINTER_TYPE_P (funtype))
abort ();
funtype = TREE_TYPE (funtype);
*************** expand_call (exp, target, ignore)
*** 2480,2487 ****
/* Tail recursion fails, when we are not dealing with recursive calls. */
if (!try_tail_recursion
! || TREE_CODE (TREE_OPERAND (exp, 0)) != ADDR_EXPR
! || TREE_OPERAND (TREE_OPERAND (exp, 0), 0) != current_function_decl)
try_tail_recursion = 0;
/* Rest of purposes for tail call optimizations to fail. */
--- 2481,2488 ----
/* Tail recursion fails, when we are not dealing with recursive calls. */
if (!try_tail_recursion
! || TREE_CODE (addr) != ADDR_EXPR
! || TREE_OPERAND (addr, 0) != current_function_decl)
try_tail_recursion = 0;
/* Rest of purposes for tail call optimizations to fail. */
*************** expand_call (exp, target, ignore)
*** 2503,2509 ****
/* Functions that do not return exactly once may not be sibcall
optimized. */
|| (flags & (ECF_RETURNS_TWICE | ECF_LONGJMP | ECF_NORETURN))
! || TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))))
/* If this function requires more stack slots than the current
function, we cannot change it into a sibling call. */
|| args_size.constant > current_function_args_size
--- 2504,2510 ----
/* Functions that do not return exactly once may not be sibcall
optimized. */
|| (flags & (ECF_RETURNS_TWICE | ECF_LONGJMP | ECF_NORETURN))
! || TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (addr)))
/* If this function requires more stack slots than the current
function, we cannot change it into a sibling call. */
|| args_size.constant > current_function_args_size
*************** expand_call (exp, target, ignore)
*** 2558,2564 ****
}
/* Do the same for the function address if it is an expression. */
if (!fndecl)
! TREE_OPERAND (exp, 0) = fix_unsafe_tree (TREE_OPERAND (exp, 0));
/* Expanding one of those dangerous arguments could have added
cleanups, but otherwise give it a whirl. */
if (any_pending_cleanups (1))
--- 2559,2565 ----
}
/* Do the same for the function address if it is an expression. */
if (!fndecl)
! addr = fix_unsafe_tree (addr);
/* Expanding one of those dangerous arguments could have added
cleanups, but otherwise give it a whirl. */
if (any_pending_cleanups (1))
*************** expand_call (exp, target, ignore)
*** 2949,2955 ****
be deferred during the evaluation of the arguments. */
NO_DEFER_POP;
! funexp = rtx_for_function_call (fndecl, exp);
/* Figure out the register where the value, if any, will come back. */
valreg = 0;
--- 2950,2956 ----
be deferred during the evaluation of the arguments. */
NO_DEFER_POP;
! funexp = rtx_for_function_call (fndecl, addr);
/* Figure out the register where the value, if any, will come back. */
valreg = 0;