Corrections for SPLIT_COMPLEX_ARGS

Richard Henderson rth@twiddle.net
Fri Jul 11 16:32:00 GMT 2003


The split_complex_args change avoids aborts for complex types
whose base type is subject to promote_mode.  We find, in the
middle of assign_parms, that the DECL_MODE of the parameter 
is grossly off.  Calling layout_decl again solves the problem.

The assign_parms change speeds up the compiler in the case
that complex args are not used.  Which is most of the time.

Tested on alpha-linux.


r~


        * function.c (assign_parms): Don't recombine complex args if
        fnargs is unchanged from orig_fnargs.
        (split_complex_args): Return args without complex before copying.
        Re-layout the modified parameters.

Index: gcc/function.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.c,v
retrieving revision 1.444
diff -c -p -d -r1.444 function.c
*** gcc/function.c	7 Jul 2003 17:57:20 -0000	1.444
--- gcc/function.c	11 Jul 2003 16:19:36 -0000
*************** assign_parms (tree fndecl)
*** 5072,5086 ****
  	}
      }
  
!   if (SPLIT_COMPLEX_ARGS)
      {
!       parm = orig_fnargs;
! 
!       for (; parm; parm = TREE_CHAIN (parm))
  	{
! 	  tree type = TREE_TYPE (parm);
! 
! 	  if (TREE_CODE (type) == COMPLEX_TYPE)
  	    {
  	      SET_DECL_RTL (parm,
  			    gen_rtx_CONCAT (DECL_MODE (parm),
--- 5072,5082 ----
  	}
      }
  
!   if (SPLIT_COMPLEX_ARGS && fnargs != orig_fnargs)
      {
!       for (parm = orig_fnargs; parm; parm = TREE_CHAIN (parm))
  	{
! 	  if (TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE)
  	    {
  	      SET_DECL_RTL (parm,
  			    gen_rtx_CONCAT (DECL_MODE (parm),
*************** assign_parms (tree fndecl)
*** 5205,5234 ****
      }
  }
  
  static tree
  split_complex_args (tree args)
  {
    tree p;
  
    args = copy_list (args);
  
    for (p = args; p; p = TREE_CHAIN (p))
      {
!       tree complex_type = TREE_TYPE (p);
! 
!       if (TREE_CODE (complex_type) == COMPLEX_TYPE)
  	{
  	  tree decl;
! 	  tree subtype = TREE_TYPE (complex_type);
  
  	  /* Rewrite the PARM_DECL's type with its component.  */
  	  TREE_TYPE (p) = subtype;
  	  DECL_ARG_TYPE (p) = TREE_TYPE (DECL_ARG_TYPE (p));
  
  	  decl = build_decl (PARM_DECL, NULL_TREE, subtype);
  	  DECL_ARG_TYPE (decl) = DECL_ARG_TYPE (p);
  	  TREE_CHAIN (decl) = TREE_CHAIN (p);
  	  TREE_CHAIN (p) = decl;
  	}
      }
  
--- 5201,5249 ----
      }
  }
  
+ /* If ARGS contains entries with complex types, split the entry into two
+    entries of the component type.  Return a new list of substitutions are
+    needed, else the old list.  */
+ 
  static tree
  split_complex_args (tree args)
  {
    tree p;
  
+   /* Before allocating memory, check for the common case of no complex.  */
+   for (p = args; p; p = TREE_CHAIN (p))
+     if (TREE_CODE (TREE_TYPE (p)) == COMPLEX_TYPE)
+       goto found;
+   return args;
+ 
+  found:
    args = copy_list (args);
  
    for (p = args; p; p = TREE_CHAIN (p))
      {
!       tree type = TREE_TYPE (p);
!       if (TREE_CODE (type) == COMPLEX_TYPE)
  	{
  	  tree decl;
! 	  tree subtype = TREE_TYPE (type);
  
  	  /* Rewrite the PARM_DECL's type with its component.  */
  	  TREE_TYPE (p) = subtype;
  	  DECL_ARG_TYPE (p) = TREE_TYPE (DECL_ARG_TYPE (p));
+ 	  DECL_MODE (p) = VOIDmode;
+ 	  DECL_SIZE (p) = NULL;
+ 	  DECL_SIZE_UNIT (p) = NULL;
+ 	  layout_decl (p, 0);
  
+ 	  /* Build a second synthetic decl.  */
  	  decl = build_decl (PARM_DECL, NULL_TREE, subtype);
  	  DECL_ARG_TYPE (decl) = DECL_ARG_TYPE (p);
+ 	  layout_decl (decl, 0);
+ 
+ 	  /* Splice it in; skip the new decl.  */
  	  TREE_CHAIN (decl) = TREE_CHAIN (p);
  	  TREE_CHAIN (p) = decl;
+ 	  p = decl;
  	}
      }
  



More information about the Gcc-patches mailing list