This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Destrictiveness of expansion and tree inlining deadlock?


> > 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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]