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]

Applied: PATCH to use REFERENCE_TYPE for return by invisiblereference


Here's the version I'm applying to the trunk; the only change is to the
copy_body_r chunk, where I remove the now-unnecessary code rather than
adding an abort.  Bootstrap was no faster this testrun.

2004-08-06  Jason Merrill  <jason@redhat.com>

	* function.c (aggregate_value_p): Check DECL_BY_REFERENCE.
	(assign_parm_find_data_types): Remove code for old front end
	invisible reference handling.
	(assign_parms): Handle DECL_BY_REFERENCE on the RESULT_DECL.
	(expand_function_end): Likewise.
	* gimplify.c (gimplify_return_expr): Handle a dereferenced
	RESULT_DECL.
	* tree-inline.c (copy_body_r): Don't bother looking for &* anymore.
	(declare_return_variable): Handle DECL_BY_REFERENCE.
	* cp/cp-gimplify.c (is_invisiref_parm): Also handle RESULT_DECL.
	(cp_genericize_r): Use convert_from_reference.
	Don't dereference a RESULT_DECL directly inside a RETURN_EXPR.
	(cp_genericize): Handle the RESULT_DECL.  Unset TREE_ADDRESSABLE.

*** ./cp/cp-gimplify.c.~1~	2004-07-22 15:02:50.000000000 -0400
--- ./cp/cp-gimplify.c	2004-07-22 17:26:39.000000000 -0400
*************** cp_gimplify_expr (tree *expr_p, tree *pr
*** 267,273 ****
  static inline bool
  is_invisiref_parm (tree t)
  {
!   return (TREE_CODE (t) == PARM_DECL
  	  && DECL_BY_REFERENCE (t));
  }
  
--- 267,273 ----
  static inline bool
  is_invisiref_parm (tree t)
  {
!   return ((TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
  	  && DECL_BY_REFERENCE (t));
  }
  
*************** cp_genericize_r (tree *stmt_p, int *walk
*** 283,289 ****
  
    if (is_invisiref_parm (stmt))
      {
!       *stmt_p = build_fold_indirect_ref (stmt);
        *walk_subtrees = 0;
        return NULL;
      }
--- 283,289 ----
  
    if (is_invisiref_parm (stmt))
      {
!       *stmt_p = convert_from_reference (stmt);
        *walk_subtrees = 0;
        return NULL;
      }
*************** cp_genericize_r (tree *stmt_p, int *walk
*** 302,307 ****
--- 302,312 ----
        *stmt_p = convert (TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
        *walk_subtrees = 0;
      }
+   else if (TREE_CODE (stmt) == RETURN_EXPR
+ 	   && TREE_OPERAND (stmt, 0)
+ 	   && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
+     /* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR.  */
+     *walk_subtrees = 0;
    else if (DECL_P (stmt) || TYPE_P (stmt))
      *walk_subtrees = 0;
  
*************** cp_genericize (tree fndecl)
*** 331,342 ****
  	{
  	  if (DECL_ARG_TYPE (t) == TREE_TYPE (t))
  	    abort ();
- 	  DECL_BY_REFERENCE (t) = 1;
  	  TREE_TYPE (t) = DECL_ARG_TYPE (t);
  	  relayout_decl (t);
  	}
      }
  
    /* If we're a clone, the body is already GIMPLE.  */
    if (DECL_CLONED_FUNCTION_P (fndecl))
      return;
--- 336,358 ----
  	{
  	  if (DECL_ARG_TYPE (t) == TREE_TYPE (t))
  	    abort ();
  	  TREE_TYPE (t) = DECL_ARG_TYPE (t);
+ 	  DECL_BY_REFERENCE (t) = 1;
+ 	  TREE_ADDRESSABLE (t) = 0;
  	  relayout_decl (t);
  	}
      }
  
+   /* Do the same for the return value.  */
+   if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl))))
+     {
+       t = DECL_RESULT (fndecl);
+       TREE_TYPE (t) = build_reference_type (TREE_TYPE (t));
+       DECL_BY_REFERENCE (t) = 1;
+       TREE_ADDRESSABLE (t) = 0;
+       relayout_decl (t);
+     }
+ 
    /* If we're a clone, the body is already GIMPLE.  */
    if (DECL_CLONED_FUNCTION_P (fndecl))
      return;
*** ./function.c.~1~	2004-07-22 15:02:50.000000000 -0400
--- ./function.c	2004-07-22 16:59:10.000000000 -0400
*************** aggregate_value_p (tree exp, tree fntype
*** 1961,1966 ****
--- 1961,1971 ----
  
    if (TREE_CODE (type) == VOID_TYPE)
      return 0;
+   /* If the front end has decided that this needs to be passed by
+      reference, do so.  */
+   if ((TREE_CODE (exp) == PARM_DECL || TREE_CODE (exp) == RESULT_DECL)
+       && DECL_BY_REFERENCE (exp))
+     return 1;
    if (targetm.calls.return_in_memory (type, fntype))
      return 1;
    /* Types that are TREE_ADDRESSABLE must be constructed in memory,
*************** assign_parm_find_data_types (struct assi
*** 2265,2279 ****
        data->passed_pointer = true;
        passed_mode = nominal_mode = Pmode;
      }
-   /* See if the frontend wants to pass this by invisible reference.  */
-   else if (passed_type != nominal_type
- 	   && POINTER_TYPE_P (passed_type)
- 	   && TREE_TYPE (passed_type) == nominal_type)
-     {
-       nominal_type = passed_type;
-       data->passed_pointer = 1;
-       passed_mode = nominal_mode = Pmode;
-     }
  
    /* Find mode as it is passed by the ABI.  */
    promoted_mode = passed_mode;
--- 2270,2275 ----
*************** assign_parms (tree fndecl)
*** 3173,3181 ****
        rtx addr = DECL_RTL (all.function_result_decl);
        rtx x;
  
!       addr = convert_memory_address (Pmode, addr);
!       x = gen_rtx_MEM (DECL_MODE (result), addr);
!       set_mem_attributes (x, result, 1);
        SET_DECL_RTL (result, x);
      }
  
--- 3169,3182 ----
        rtx addr = DECL_RTL (all.function_result_decl);
        rtx x;
  
!       if (DECL_BY_REFERENCE (result))
! 	x = addr;
!       else
! 	{
! 	  addr = convert_memory_address (Pmode, addr);
! 	  x = gen_rtx_MEM (DECL_MODE (result), addr);
! 	  set_mem_attributes (x, result, 1);
! 	}
        SET_DECL_RTL (result, x);
      }
  
*************** expand_function_end (void)
*** 4501,4517 ****
    if (current_function_returns_struct
        || current_function_returns_pcc_struct)
      {
!       rtx value_address
! 	= XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
        tree type = TREE_TYPE (DECL_RESULT (current_function_decl));
  #ifdef FUNCTION_OUTGOING_VALUE
!       rtx outgoing
! 	= FUNCTION_OUTGOING_VALUE (build_pointer_type (type),
! 				   current_function_decl);
  #else
!       rtx outgoing
! 	= FUNCTION_VALUE (build_pointer_type (type), current_function_decl);
! #endif
  
        /* Mark this as a function return value so integrate will delete the
  	 assignment and USE below when inlining this function.  */
--- 4502,4523 ----
    if (current_function_returns_struct
        || current_function_returns_pcc_struct)
      {
!       rtx value_address = DECL_RTL (DECL_RESULT (current_function_decl));
        tree type = TREE_TYPE (DECL_RESULT (current_function_decl));
+       rtx outgoing;
+ 
+       if (DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)))
+ 	type = TREE_TYPE (type);
+       else
+ 	value_address = XEXP (value_address, 0);
+ 
  #ifdef FUNCTION_OUTGOING_VALUE
!       outgoing = FUNCTION_OUTGOING_VALUE (build_pointer_type (type),
! 					  current_function_decl);
  #else
!       outgoing = FUNCTION_VALUE (build_pointer_type (type),
! 				 current_function_decl);
! #endif 
  
        /* Mark this as a function return value so integrate will delete the
  	 assignment and USE below when inlining this function.  */
*** ./gimplify.c.~1~	2004-07-22 15:02:50.000000000 -0400
--- ./gimplify.c	2004-07-22 16:30:55.000000000 -0400
*************** gimplify_return_expr (tree stmt, tree *p
*** 895,900 ****
--- 895,903 ----
    else
      {
        result_decl = TREE_OPERAND (ret_expr, 0);
+       if (TREE_CODE (result_decl) == INDIRECT_REF)
+ 	/* See through a return by reference.  */
+ 	result_decl = TREE_OPERAND (result_decl, 0);
  #ifdef ENABLE_CHECKING
        if ((TREE_CODE (ret_expr) != MODIFY_EXPR
  	   && TREE_CODE (ret_expr) != INIT_EXPR)
*** tree-inline.c.~1~	2004-08-02 16:09:13.000000000 -0400
--- tree-inline.c	2004-08-06 16:17:25.000000000 -0400
*************** copy_body_r (tree *tp, int *walk_subtree
*** 573,605 ****
  		}
  	    }
  	}
-       else if (TREE_CODE (*tp) == ADDR_EXPR
- 	       && (lang_hooks.tree_inlining.auto_var_in_fn_p
- 		   (TREE_OPERAND (*tp, 0), fn)))
- 	{
- 	  /* Get rid of &* from inline substitutions.  It can occur when
- 	     someone takes the address of a parm or return slot passed by
- 	     invisible reference.  */
- 	  tree decl = TREE_OPERAND (*tp, 0), value;
- 	  splay_tree_node n;
- 
- 	  n = splay_tree_lookup (id->decl_map, (splay_tree_key) decl);
- 	  if (n)
- 	    {
- 	      value = (tree) n->value;
- 	      if (TREE_CODE (value) == INDIRECT_REF)
- 		{
- 		  if  (!lang_hooks.types_compatible_p
- 		       (TREE_TYPE (*tp), TREE_TYPE (TREE_OPERAND (value, 0))))
- 		    *tp = fold_convert (TREE_TYPE (*tp),
- 					TREE_OPERAND (value, 0));
- 		  else
- 		    *tp = TREE_OPERAND (value, 0);
- 
- 		  return copy_body_r (tp, walk_subtrees, data);
- 		}
- 	    }
- 	}
        else if (TREE_CODE (*tp) == INDIRECT_REF)
  	{
  	  /* Get rid of *& from inline substitutions that can happen when a
--- 573,578 ----
*************** declare_return_variable (inline_data *id
*** 861,867 ****
        return NULL_TREE;
      }
  
!   /* If there was a return slot, then the return value the the
       dereferenced address of that object.  */
    if (return_slot_addr)
      {
--- 834,840 ----
        return NULL_TREE;
      }
  
!   /* If there was a return slot, then the return value is the
       dereferenced address of that object.  */
    if (return_slot_addr)
      {
*************** declare_return_variable (inline_data *id
*** 869,875 ****
  	 a modify expression.  */
        if (modify_dest)
  	abort ();
!       var = build_fold_indirect_ref (return_slot_addr);
        use = NULL;
        goto done;
      }
--- 842,851 ----
  	 a modify expression.  */
        if (modify_dest)
  	abort ();
!       if (DECL_BY_REFERENCE (result))
! 	var = return_slot_addr;
!       else
! 	var = build_fold_indirect_ref (return_slot_addr);
        use = NULL;
        goto done;
      }

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