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]

[named-addr-spaces-branch] Use new tree code ADDR_SPACE_CONVERT_EXPR


Hello,

I've committed the following patch to the named-addr-spaces-branch to
use the new tree code ADDR_SPACE_CONVERT_EXPR instead of CONVERT_EXPR
to represent conversions between pointers to different address spaces,
as discussed on the list.

Tested on spu-elf and s390x-ibm-linux.

Bye,
Ulrich


ChangeLog:

	* tree.def (ADDR_SPACE_CONVERT_EXPR): New tree code.
	* expr.c (expand_expr_real_1): Expand ADDR_SPACE_CONVERT_EXPR.
	Do not handle address space conversions under CONVERT_EXPR.
	* convert.c (convert_to_pointer): Generate ADDR_SPACE_CONVERT_EXPR
	to handle conversions between different address spaces.
	* fold-const.c (fold_convert_loc): Likewise.
	(fold_unary_loc): Handle ADDR_SPACE_CONVERT_EXPR.
	* tree-pretty-print.c (dump_generic_node): Likewise.
	* gimple-pretty-print.c (dump_unary_rhs): Likewise.
	* tree-cfg.c (verify_gimple_assign_unary): Likewise.
	* tree-inline.c (estimate_operator_cost): Likewise.

	* tree.h (MIXED_ADDR_SPACE_POINTER_TYPES_P): Remove.
	* fold-const.c (operand_equal_p): Inline it.
	* tree.c (tree_nop_conversion): Revert local change.
	* fold-const.c (fold_convert_const): Likewise.
	(fold_unary_loc): Likewise.
	* tree-ssa-ccp.c (ccp_fold): Likewise.
	(fold_gimple_assign): Likewise.
	* dojump.c (do_jump): Likewise.
	* tree-ssa-ifcombine.c (get_name_for_bit_test): Likewise.
	(recognize_single_bit_test): Likewise.
	* c-typeck.c (pointer_diff): Likewise.
	* gimplify.c (gimplify_conversion): Likewise.
	* varasm.c (narrowing_initializer_constant_valid_p): Likewise.
	(initializer_constant_valid_p): Likewise.
	* tree-ssa.c (useless_type_conversion_p): Likewise.
	* builtins.c (get_memory_rtx): Likewise.


Index: gcc/tree-pretty-print.c
===================================================================
*** gcc/tree-pretty-print.c	(revision 150857)
--- gcc/tree-pretty-print.c	(working copy)
*************** dump_generic_node (pretty_printer *buffe
*** 1561,1566 ****
--- 1561,1567 ----
        NIY;
        break;
  
+     case ADDR_SPACE_CONVERT_EXPR:
      case FIXED_CONVERT_EXPR:
      case FIX_TRUNC_EXPR:
      case FLOAT_EXPR:
Index: gcc/tree.c
===================================================================
*** gcc/tree.c	(revision 150935)
--- gcc/tree.c	(working copy)
*************** tree_nop_conversion (const_tree exp)
*** 9753,9762 ****
    outer_type = TREE_TYPE (exp);
    inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
  
-   /* Keep conversions between pointers to different address spaces.  */
-   if (MIXED_ADDR_SPACE_POINTER_TYPES_P (outer_type, inner_type))
-     return false;
- 
    /* Use precision rather then machine mode when we can, which gives
       the correct answer even for submode (bit-field) types.  */
    if ((INTEGRAL_TYPE_P (outer_type)
--- 9753,9758 ----
Index: gcc/tree.h
===================================================================
*** gcc/tree.h	(revision 150935)
--- gcc/tree.h	(working copy)
*************** extern void omp_clause_range_check_faile
*** 1063,1076 ****
  #define POINTER_TYPE_P(TYPE) \
    (TREE_CODE (TYPE) == POINTER_TYPE || TREE_CODE (TYPE) == REFERENCE_TYPE)
  
- /* Nonzero if TYPE1 and TYPE2 are two pointer or reference types
-    to different address spaces.  */
- 
- #define MIXED_ADDR_SPACE_POINTER_TYPES_P(TYPE1,TYPE2) \
-   (POINTER_TYPE_P (TYPE1) && POINTER_TYPE_P (TYPE2) \
-    && (TYPE_ADDR_SPACE (TREE_TYPE (TYPE1)) \
-        != TYPE_ADDR_SPACE (TREE_TYPE (TYPE2))))
- 
  /* Nonzero if this type is a complete type.  */
  #define COMPLETE_TYPE_P(NODE) (TYPE_SIZE (NODE) != NULL_TREE)
  
--- 1063,1068 ----
Index: gcc/builtins.c
===================================================================
*** gcc/builtins.c	(revision 150857)
--- gcc/builtins.c	(working copy)
*************** get_memory_rtx (tree exp, tree len)
*** 1132,1140 ****
       If it is an ADDR_EXPR, use the operand.  Otherwise, dereference it if
       we can.  First remove any nops.  */
    while (CONVERT_EXPR_P (exp)
! 	 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0)))
! 	 && TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))))
! 	    == 0)
      exp = TREE_OPERAND (exp, 0);
  
    off = 0;
--- 1132,1138 ----
       If it is an ADDR_EXPR, use the operand.  Otherwise, dereference it if
       we can.  First remove any nops.  */
    while (CONVERT_EXPR_P (exp)
! 	 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
      exp = TREE_OPERAND (exp, 0);
  
    off = 0;
Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c	(revision 150935)
--- gcc/fold-const.c	(working copy)
*************** fold_convert_const (enum tree_code code,
*** 2461,2472 ****
    if (TREE_TYPE (arg1) == type)
      return arg1;
  
-   /* Conversions between non-NULL pointers to different
-      address spaces must be preserved.  */
-   if (MIXED_ADDR_SPACE_POINTER_TYPES_P (type, TREE_TYPE (arg1))
-       && !integer_zerop (arg1))
-     return NULL_TREE;
- 
    if (POINTER_TYPE_P (type) || INTEGRAL_TYPE_P (type)
        || TREE_CODE (type) == OFFSET_TYPE)
      {
--- 2461,2466 ----
*************** fold_convert_loc (location_t loc, tree t
*** 2578,2585 ****
  
    switch (TREE_CODE (type))
      {
      case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
-     case POINTER_TYPE: case REFERENCE_TYPE:
      case OFFSET_TYPE:
        if (TREE_CODE (arg) == INTEGER_CST)
  	{
--- 2572,2587 ----
  
    switch (TREE_CODE (type))
      {
+     case POINTER_TYPE:
+     case REFERENCE_TYPE:
+       /* Handle conversions between pointers to different address spaces.  */
+       if (POINTER_TYPE_P (orig)
+ 	  && (TYPE_ADDR_SPACE (TREE_TYPE (type))
+ 	      != TYPE_ADDR_SPACE (TREE_TYPE (orig))))
+ 	return fold_build1_loc (loc, ADDR_SPACE_CONVERT_EXPR, type, arg);
+       /* fall through */
+ 
      case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
      case OFFSET_TYPE:
        if (TREE_CODE (arg) == INTEGER_CST)
  	{
*************** operand_equal_p (const_tree arg0, const_
*** 3113,3119 ****
      return 0;
  
    /* We cannot consider pointers to different address space equal.  */
!   if (MIXED_ADDR_SPACE_POINTER_TYPES_P (TREE_TYPE (arg0), TREE_TYPE (arg1)))
      return 0;
  
    /* If both types don't have the same precision, then it is not safe
--- 3115,3123 ----
      return 0;
  
    /* We cannot consider pointers to different address space equal.  */
!   if (POINTER_TYPE_P (TREE_TYPE (arg0)) && POINTER_TYPE_P (TREE_TYPE (arg1))
!       && (TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (arg0)))
! 	  != TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (arg1)))))
      return 0;
  
    /* If both types don't have the same precision, then it is not safe
*************** fold_unary_loc (location_t loc, enum tre
*** 8436,8444 ****
  	     - the initial type is a pointer type and the precisions of the
  	       intermediate and final types differ, or
  	     - the final type is a pointer type and the precisions of the
! 	       initial and intermediate types differ, or
! 	     - (at least) one of the conversions is between pointers to
! 	       different address spaces.  */
  	  if (! inside_float && ! inter_float && ! final_float
  	      && ! inside_vec && ! inter_vec && ! final_vec
  	      && (inter_prec >= inside_prec || inter_prec >= final_prec)
--- 8440,8446 ----
  	     - the initial type is a pointer type and the precisions of the
  	       intermediate and final types differ, or
  	     - the final type is a pointer type and the precisions of the
! 	       initial and intermediate types differ.  */
  	  if (! inside_float && ! inter_float && ! final_float
  	      && ! inside_vec && ! inter_vec && ! final_vec
  	      && (inter_prec >= inside_prec || inter_prec >= final_prec)
*************** fold_unary_loc (location_t loc, enum tre
*** 8450,8458 ****
  	      && ! (inside_ptr && inter_prec != final_prec)
  	      && ! (final_ptr && inside_prec != inter_prec)
  	      && ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (type))
! 		    && TYPE_MODE (type) == TYPE_MODE (inter_type))
! 	      && ! MIXED_ADDR_SPACE_POINTER_TYPES_P (inter_type, inside_type)
! 	      && ! MIXED_ADDR_SPACE_POINTER_TYPES_P (type, inter_type))
  	    return fold_build1_loc (loc, code, type, TREE_OPERAND (op0, 0));
  	}
  
--- 8452,8458 ----
  	      && ! (inside_ptr && inter_prec != final_prec)
  	      && ! (final_ptr && inside_prec != inter_prec)
  	      && ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (type))
! 		    && TYPE_MODE (type) == TYPE_MODE (inter_type)))
  	    return fold_build1_loc (loc, code, type, TREE_OPERAND (op0, 0));
  	}
  
*************** fold_unary_loc (location_t loc, enum tre
*** 8611,8616 ****
--- 8611,8621 ----
        tem = fold_convert_const (code, type, op0);
        return tem ? tem : NULL_TREE;
  
+     case ADDR_SPACE_CONVERT_EXPR:
+       if (integer_zerop (arg0))
+ 	return fold_convert_const (code, type, arg0);
+       return NULL_TREE;
+ 
      case FIXED_CONVERT_EXPR:
        tem = fold_convert_const (code, type, arg0);
        return tem ? tem : NULL_TREE;
*************** fold_unary_loc (location_t loc, enum tre
*** 8638,8646 ****
  	  && (INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0)))
  	      || POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0))))
  	  && (TYPE_PRECISION (TREE_TYPE (op0))
! 	      == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0))))
! 	  && !MIXED_ADDR_SPACE_POINTER_TYPES_P
! 		(TREE_TYPE (op0), TREE_TYPE (TREE_OPERAND (op0, 0))))
  	return fold_build1_loc (loc, VIEW_CONVERT_EXPR,
  			    type, TREE_OPERAND (op0, 0));
  
--- 8643,8649 ----
  	  && (INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0)))
  	      || POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0))))
  	  && (TYPE_PRECISION (TREE_TYPE (op0))
! 	      == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0)))))
  	return fold_build1_loc (loc, VIEW_CONVERT_EXPR,
  			    type, TREE_OPERAND (op0, 0));
  
Index: gcc/tree-ssa-ccp.c
===================================================================
*** gcc/tree-ssa-ccp.c	(revision 150935)
--- gcc/tree-ssa-ccp.c	(working copy)
*************** ccp_fold (gimple stmt)
*** 1043,1050 ****
  	      if (CONVERT_EXPR_CODE_P (subcode)
  		  && POINTER_TYPE_P (TREE_TYPE (lhs))
  		  && POINTER_TYPE_P (TREE_TYPE (op0))
- 		  && (TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (lhs)))
- 		      == TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (op0))))
  		  /* Do not allow differences in volatile qualification
  		     as this might get us confused as to whether a
  		     propagation destination statement is volatile
--- 1043,1048 ----
*************** fold_gimple_assign (gimple_stmt_iterator
*** 2801,2810 ****
  	  }
  	else if (CONVERT_EXPR_CODE_P (subcode)
  		 && POINTER_TYPE_P (gimple_expr_type (stmt))
! 		 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt)))
! 		 && (TYPE_ADDR_SPACE (TREE_TYPE (gimple_expr_type (stmt)))
! 		     == TYPE_ADDR_SPACE
! 			 (TREE_TYPE (TREE_TYPE (gimple_assign_rhs1 (stmt))))))
  	  {
  	    tree type = gimple_expr_type (stmt);
  	    tree t = maybe_fold_offset_to_address (loc,
--- 2799,2805 ----
  	  }
  	else if (CONVERT_EXPR_CODE_P (subcode)
  		 && POINTER_TYPE_P (gimple_expr_type (stmt))
! 		 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt))))
  	  {
  	    tree type = gimple_expr_type (stmt);
  	    tree t = maybe_fold_offset_to_address (loc,
Index: gcc/dojump.c
===================================================================
*** gcc/dojump.c	(revision 150935)
--- gcc/dojump.c	(working copy)
*************** do_jump (tree exp, rtx if_false_label, r
*** 392,399 ****
  	  /* Strip narrowing integral type conversions.  */
  	  while (CONVERT_EXPR_P (exp0)
  		 && TREE_OPERAND (exp0, 0) != error_mark_node
- 		 && !MIXED_ADDR_SPACE_POINTER_TYPES_P
- 		       (TREE_TYPE (exp0), TREE_TYPE (TREE_OPERAND (exp0, 0)))
  		 && TYPE_PRECISION (TREE_TYPE (exp0))
  		    <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp0, 0))))
  	    exp0 = TREE_OPERAND (exp0, 0);
--- 392,397 ----
Index: gcc/expr.c
===================================================================
*** gcc/expr.c	(revision 150961)
--- gcc/expr.c	(working copy)
*************** expand_expr_real_1 (tree exp, rtx target
*** 8197,8202 ****
--- 8197,8238 ----
        }
        return expand_call (exp, target, ignore);
  
+     case ADDR_SPACE_CONVERT_EXPR:
+       {
+ 	tree subexp0_type;
+ 	addr_space_t as_to;
+ 	addr_space_t as_from;
+ 
+ 	subexp0 = TREE_OPERAND (exp, 0);
+ 	subexp0_type = TREE_TYPE (subexp0);
+ 
+ 	gcc_assert (POINTER_TYPE_P (type));
+ 	gcc_assert (POINTER_TYPE_P (subexp0_type));
+ 
+ 	as_to = TYPE_ADDR_SPACE (TREE_TYPE (type));
+ 	as_from = TYPE_ADDR_SPACE (TREE_TYPE (subexp0_type));
+ 
+         /* Conversions between pointers to the same address space should
+ 	   have been implemented via CONVERT_EXPR / NOP_EXPR.  */
+ 	gcc_assert (as_to != as_from);
+ 
+         /* Ask target code to handle conversion between pointers
+ 	   to overlapping address spaces.  */
+ 	if (targetm.addr_space.subset_p (as_to, as_from)
+ 	    || targetm.addr_space.subset_p (as_from, as_to))
+ 	  {
+ 	    op0 = expand_expr (subexp0, NULL_RTX, VOIDmode, modifier);
+ 	    op0 = targetm.addr_space.convert (op0, subexp0_type, type);
+ 	    gcc_assert (op0);
+ 	    return op0;
+ 	  }
+ 
+ 	/* For disjoint address spaces, converting anything but
+ 	   a null pointer invokes undefined behaviour.  We simply
+ 	   always return a null pointer here.  */
+ 	return CONST0_RTX (mode);
+       }
+ 
      case PAREN_EXPR:
      CASE_CONVERT:
        if (TREE_OPERAND (exp, 0) == error_mark_node)
*************** expand_expr_real_1 (tree exp, rtx target
*** 8251,8288 ****
  	  return target;
  	}
  
-       /* Handle casts of pointers to/from address space qualified
- 	 pointers.  */
-       subexp0 = TREE_OPERAND (exp, 0);
-       if (POINTER_TYPE_P (type) && POINTER_TYPE_P (TREE_TYPE (subexp0)))
- 	{
- 	  tree subexp0_type = TREE_TYPE (subexp0);
- 	  addr_space_t as_to = TYPE_ADDR_SPACE (TREE_TYPE (type));
- 	  addr_space_t as_from = TYPE_ADDR_SPACE (TREE_TYPE (subexp0_type));
- 
- 	  /* Conversion between pointers to the same address space
- 	     is handled by the code below.  */
- 	  if (as_to == as_from)
- 	    ;
- 
- 	  /* Ask target code to handle conversion between pointers
- 	     to overlapping address spaces.  */
- 	  else if (targetm.addr_space.subset_p (as_to, as_from)
- 		   || targetm.addr_space.subset_p (as_from, as_to))
- 	    {
- 	      op0 = expand_expr (subexp0, NULL_RTX, VOIDmode, modifier);
- 	      op0 = targetm.addr_space.convert (op0, subexp0_type, type);
- 	      gcc_assert (op0);
- 	      return op0;
- 	    }
- 
- 	  /* For disjoint address spaces, converting anything but
- 	     a null pointer invokes undefined behaviour.  We simply
- 	     always return a null pointer here.  */
- 	  else
- 	    return CONST0_RTX (mode);
- 	}
- 
        if (mode == TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))))
  	{
  	  op0 = expand_expr (TREE_OPERAND (exp, 0), target, VOIDmode,
--- 8287,8292 ----
Index: gcc/tree-ssa-ifcombine.c
===================================================================
*** gcc/tree-ssa-ifcombine.c	(revision 150935)
--- gcc/tree-ssa-ifcombine.c	(working copy)
*************** get_name_for_bit_test (tree candidate)
*** 151,160 ****
      {
        gimple def_stmt = SSA_NAME_DEF_STMT (candidate);
        if (is_gimple_assign (def_stmt)
! 	  && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt))
! 	  && !MIXED_ADDR_SPACE_POINTER_TYPES_P
! 	        (TREE_TYPE (candidate),
! 		 TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
  	{
  	  if (TYPE_PRECISION (TREE_TYPE (candidate))
  	      <= TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
--- 151,157 ----
      {
        gimple def_stmt = SSA_NAME_DEF_STMT (candidate);
        if (is_gimple_assign (def_stmt)
! 	  && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
  	{
  	  if (TYPE_PRECISION (TREE_TYPE (candidate))
  	      <= TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
*************** recognize_single_bit_test (gimple cond, 
*** 201,209 ****
  
        while (is_gimple_assign (stmt)
  	     && ((CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
- 		  && !MIXED_ADDR_SPACE_POINTER_TYPES_P
- 		       (TREE_TYPE (gimple_assign_lhs (stmt)),
- 			TREE_TYPE (gimple_assign_rhs1 (stmt)))
  		  && (TYPE_PRECISION (TREE_TYPE (gimple_assign_lhs (stmt)))
  		      <= TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (stmt)))))
  		 || gimple_assign_ssa_name_copy_p (stmt)))
--- 198,203 ----
Index: gcc/gimple-pretty-print.c
===================================================================
*** gcc/gimple-pretty-print.c	(revision 150857)
--- gcc/gimple-pretty-print.c	(working copy)
*************** dump_unary_rhs (pretty_printer *buffer, 
*** 254,259 ****
--- 254,260 ----
        break;
  
      case FIXED_CONVERT_EXPR:
+     case ADDR_SPACE_CONVERT_EXPR:
      case FIX_TRUNC_EXPR:
      case FLOAT_EXPR:
      CASE_CONVERT:
Index: gcc/c-typeck.c
===================================================================
*** gcc/c-typeck.c	(revision 150961)
--- gcc/c-typeck.c	(working copy)
*************** pointer_diff (location_t loc, tree op0, 
*** 3181,3198 ****
       So first try to find a common term here 'by hand'; we want to cover
       at least the cases that occur in legal static initializers.  */
    if (CONVERT_EXPR_P (op0)
-       && (!POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0)))
-           || TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (op0))) ==
-              TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (op0, 0)))))
        && (TYPE_PRECISION (TREE_TYPE (op0))
  	  == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0)))))
      con0 = TREE_OPERAND (op0, 0);
    else
      con0 = op0;
    if (CONVERT_EXPR_P (op1)
-       && (!POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (op1, 0)))
-           || TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (op1))) ==
-              TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (op1, 0)))))
        && (TYPE_PRECISION (TREE_TYPE (op1))
  	  == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op1, 0)))))
      con1 = TREE_OPERAND (op1, 0);
--- 3181,3192 ----
Index: gcc/gimplify.c
===================================================================
*** gcc/gimplify.c	(revision 150935)
--- gcc/gimplify.c	(working copy)
*************** gimplify_conversion (tree *expr_p)
*** 1808,1815 ****
    if (CONVERT_EXPR_P (*expr_p)
        && POINTER_TYPE_P (TREE_TYPE (*expr_p))
        && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (*expr_p, 0)))
-       && TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (*expr_p)))
- 	 == TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
        && (tem = maybe_fold_offset_to_address
  	  (EXPR_LOCATION (*expr_p), TREE_OPERAND (*expr_p, 0),
  	   integer_zero_node, TREE_TYPE (*expr_p))) != NULL_TREE)
--- 1808,1813 ----
Index: gcc/tree.def
===================================================================
*** gcc/tree.def	(revision 150857)
--- gcc/tree.def	(working copy)
*************** DEFTREECODE (PAREN_EXPR, "paren_expr", t
*** 764,769 ****
--- 764,773 ----
     represented by CONVERT_EXPR or NOP_EXPR nodes.  */
  DEFTREECODE (CONVERT_EXPR, "convert_expr", tcc_unary, 1)
  
+ /* Conversion of a pointer value to a pointer to a different
+    address space.  */
+ DEFTREECODE (ADDR_SPACE_CONVERT_EXPR, "addr_space_convert_expr", tcc_unary, 1)
+ 
  /* Conversion of a fixed-point value to an integer, a real, or a fixed-point
     value.  Or conversion of a fixed-point value from an integer, a real, or
     a fixed-point value.  */
Index: gcc/varasm.c
===================================================================
*** gcc/varasm.c	(revision 150935)
--- gcc/varasm.c	(working copy)
*************** narrowing_initializer_constant_valid_p (
*** 4123,4134 ****
  	  || (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0)))
  	      > GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (inner)))))
  	break;
- 
-       /* Keep conversions between pointers to different address spaces.  */
-       if (MIXED_ADDR_SPACE_POINTER_TYPES_P (TREE_TYPE (op0),
- 					    TREE_TYPE (inner)))
- 	break;
- 
        op0 = inner;
      }
  
--- 4123,4128 ----
*************** narrowing_initializer_constant_valid_p (
*** 4141,4152 ****
  	  || (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op1)))
  	      > GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (inner)))))
  	break;
- 
-       /* Keep conversions between pointers to different address spaces.  */
-       if (MIXED_ADDR_SPACE_POINTER_TYPES_P (TREE_TYPE (op1),
- 					    TREE_TYPE (inner)))
- 	break;
- 
        op1 = inner;
      }
  
--- 4135,4140 ----
*************** initializer_constant_valid_p (tree value
*** 4281,4291 ****
  	tree src_type = TREE_TYPE (src);
  	tree dest_type = TREE_TYPE (value);
  
! 	/* Allow conversions between pointer types to the same address space,
! 	   floating-point types, and offset types.  */
! 	if ((POINTER_TYPE_P (dest_type) && POINTER_TYPE_P (src_type)
! 	     && TYPE_ADDR_SPACE (TREE_TYPE (dest_type))
! 		== TYPE_ADDR_SPACE (TREE_TYPE (src_type)))
  	    || (FLOAT_TYPE_P (dest_type) && FLOAT_TYPE_P (src_type))
  	    || (TREE_CODE (dest_type) == OFFSET_TYPE
  		&& TREE_CODE (src_type) == OFFSET_TYPE))
--- 4269,4277 ----
  	tree src_type = TREE_TYPE (src);
  	tree dest_type = TREE_TYPE (value);
  
! 	/* Allow conversions between pointer types, floating-point
! 	   types, and offset types.  */
! 	if ((POINTER_TYPE_P (dest_type) && POINTER_TYPE_P (src_type))
  	    || (FLOAT_TYPE_P (dest_type) && FLOAT_TYPE_P (src_type))
  	    || (TREE_CODE (dest_type) == OFFSET_TYPE
  		&& TREE_CODE (src_type) == OFFSET_TYPE))
Index: gcc/tree-ssa.c
===================================================================
*** gcc/tree-ssa.c	(revision 150935)
--- gcc/tree-ssa.c	(working copy)
*************** useless_type_conversion_p (tree outer_ty
*** 874,883 ****
    if (POINTER_TYPE_P (inner_type)
        && POINTER_TYPE_P (outer_type))
      {
-       /* Do not lose casts between pointers to different address spaces.  */
-       if (MIXED_ADDR_SPACE_POINTER_TYPES_P (inner_type, outer_type))
- 	return false;
- 
        /* If the outer type is (void *) or a pointer to an incomplete
  	 record type, then the conversion is not necessary.  */
        if (VOID_TYPE_P (TREE_TYPE (outer_type))
--- 874,879 ----
Index: gcc/tree-inline.c
===================================================================
*** gcc/tree-inline.c	(revision 150857)
--- gcc/tree-inline.c	(working copy)
*************** estimate_operator_cost (enum tree_code c
*** 2851,2856 ****
--- 2851,2857 ----
      case MINUS_EXPR:
      case MULT_EXPR:
  
+     case ADDR_SPACE_CONVERT_EXPR:
      case FIXED_CONVERT_EXPR:
      case FIX_TRUNC_EXPR:
  
Index: gcc/tree-cfg.c
===================================================================
*** gcc/tree-cfg.c	(revision 150857)
--- gcc/tree-cfg.c	(working copy)
*************** verify_gimple_assign_unary (gimple stmt)
*** 3516,3521 ****
--- 3516,3536 ----
  	return false;
        }
  
+     case ADDR_SPACE_CONVERT_EXPR:
+       {
+ 	if (!POINTER_TYPE_P (rhs1_type) || !POINTER_TYPE_P (lhs_type)
+ 	    || (TYPE_ADDR_SPACE (TREE_TYPE (rhs1_type))
+ 		== TYPE_ADDR_SPACE (TREE_TYPE (lhs_type))))
+ 	  {
+ 	    error ("invalid types in address space conversion");
+ 	    debug_generic_expr (lhs_type);
+ 	    debug_generic_expr (rhs1_type);
+ 	    return true;
+ 	  }
+ 
+ 	return false;
+       }
+ 
      case FIXED_CONVERT_EXPR:
        {
  	if (!valid_fixed_convert_types_p (lhs_type, rhs1_type)
Index: gcc/convert.c
===================================================================
*** gcc/convert.c	(revision 150857)
--- gcc/convert.c	(working copy)
*************** convert_to_pointer (tree type, tree expr
*** 56,70 ****
      case POINTER_TYPE:
      case REFERENCE_TYPE:
        {
!         /* If the pointers point to different address spaces, conversion
! 	   needs to be done via a CONVERT_EXP instead of a NOP_EXPR.  */
  	addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (type));
  	addr_space_t from_as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (expr)));
  
  	if (to_as == from_as)
  	  return fold_build1_loc (loc, NOP_EXPR, type, expr);
  	else
! 	  return fold_build1_loc (loc, CONVERT_EXPR, type, expr);
        }
  
      case INTEGER_TYPE:
--- 56,70 ----
      case POINTER_TYPE:
      case REFERENCE_TYPE:
        {
!         /* If the pointers point to different address spaces, conversion needs
! 	   to be done via a ADDR_SPACE_CONVERT_EXPR instead of a NOP_EXPR.  */
  	addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (type));
  	addr_space_t from_as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (expr)));
  
  	if (to_as == from_as)
  	  return fold_build1_loc (loc, NOP_EXPR, type, expr);
  	else
! 	  return fold_build1_loc (loc, ADDR_SPACE_CONVERT_EXPR, type, expr);
        }
  
      case INTEGER_TYPE:
-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


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