[Committed] More convert -> fold_convert clean-ups.

Roger Sayle roger@eyesopen.com
Tue Apr 4 15:32:00 GMT 2006


The following patch removes most of the remaining uses of "convert"
from the middle-end.  Running "nm" on libbackend.a shows that the
only remaining uses of the front-end's convert function are in the
GCC source file "convert.c".

"convert.c" is a strange beast somewhere between the front-ends and
the middle-end.  For example, I suspect that its the only part of
the middle-end that may legitimately issue diagnostics.  Its functions
are front-end helper routines, much like c-common.c, that may be
shared across non-C/C++ family front-ends.  Once the parse tree is
converted to generic, this functionality is no longer required.

I'm currently evaluating strategies for dealing with this remaining
hold-out.  One simple approach might be to reclassify this file
as a front-end file, that a front-end can choose to be listed in
its OBJS rather than requiring it to be placed in libbackend.a,
forcing the front-end to provide a "convert" function to satisfy
the unresolved symbols.  My preferred approach (which may work out)
is to layer convert.c, such that:

   convert may call itself, convert.c and fold_convert.
   convert.c may call itself and fold_convert.
   fold_convert may only call itself.

which provides a nice abstraction with no routine/layer calling
into or depending upon any higher lever functionality.

Of course, I still need to check whether any backends call into
the front-end's convert API point.  Once this is done, it'll allow
front-ends that don't otherwise need "convert" to simply not
declare it, or rename it to cxx_convert, etc... as they please.
One less aspect of the front-end/middle-end interface to document.

Thoughts?


The patch below confirms that this layering aspect of gimple/generic's
type system is language independent, and that there's no need to
define a lang_hook for convert.  [Proof by implementation].


The following patch has been tested on i686-pc-linux-gnu with a
full "make bootstrap", all default languages including Ada, and
regression tested with a top-level "make -k check" with no new
failures.

Committed to mainline as revision 112670.


2006-04-04  Roger Sayle  <roger@eyesopen.com>

	* builtins.c (fold_builtin_sprintf): Use fold_convert instead of
	convert in the middle-end.
	* expr.c (store_expr, store_constructor, get_inner_reference,
	expand_expr_real_1, string_constant, try_casesi, try_tablejump):
	Likewise.
	* tree.c (build_range_type): Likewise.


Index: builtins.c
===================================================================
*** builtins.c	(revision 112633)
--- builtins.c	(working copy)
*************** fold_builtin_sprintf (tree arglist, int
*** 9657,9663 ****

    if (call && retval)
      {
!       retval = convert
  	(TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
  	 retval);
        return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
--- 9657,9663 ----

    if (call && retval)
      {
!       retval = fold_convert
  	(TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
  	 retval);
        return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
Index: expr.c
===================================================================
*** expr.c	(revision 112633)
--- expr.c	(working copy)
*************** store_expr (tree exp, rtx target, int ca
*** 4288,4301 ****
  	{
  	  if (TYPE_UNSIGNED (TREE_TYPE (exp))
  	      != SUBREG_PROMOTED_UNSIGNED_P (target))
! 	    exp = convert
  	      (lang_hooks.types.signed_or_unsigned_type
  	       (SUBREG_PROMOTED_UNSIGNED_P (target), TREE_TYPE (exp)), exp);

! 	  exp = convert (lang_hooks.types.type_for_mode
! 			 (GET_MODE (SUBREG_REG (target)),
! 			  SUBREG_PROMOTED_UNSIGNED_P (target)),
! 			 exp);

  	  inner_target = SUBREG_REG (target);
  	}
--- 4288,4301 ----
  	{
  	  if (TYPE_UNSIGNED (TREE_TYPE (exp))
  	      != SUBREG_PROMOTED_UNSIGNED_P (target))
! 	    exp = fold_convert
  	      (lang_hooks.types.signed_or_unsigned_type
  	       (SUBREG_PROMOTED_UNSIGNED_P (target), TREE_TYPE (exp)), exp);

! 	  exp = fold_convert (lang_hooks.types.type_for_mode
! 				(GET_MODE (SUBREG_REG (target)),
! 				 SUBREG_PROMOTED_UNSIGNED_P (target)),
! 			      exp);

  	  inner_target = SUBREG_REG (target);
  	}
*************** store_constructor (tree exp, rtx target,
*** 4963,4975 ****
  		  {
  		    type = lang_hooks.types.type_for_size
  		      (BITS_PER_WORD, TYPE_UNSIGNED (type));
! 		    value = convert (type, value);
  		  }

  		if (BYTES_BIG_ENDIAN)
  		  value
  		   = fold_build2 (LSHIFT_EXPR, type, value,
! 				   build_int_cst (NULL_TREE,
  						  BITS_PER_WORD - bitsize));
  		bitsize = BITS_PER_WORD;
  		mode = word_mode;
--- 4963,4975 ----
  		  {
  		    type = lang_hooks.types.type_for_size
  		      (BITS_PER_WORD, TYPE_UNSIGNED (type));
! 		    value = fold_convert (type, value);
  		  }

  		if (BYTES_BIG_ENDIAN)
  		  value
  		   = fold_build2 (LSHIFT_EXPR, type, value,
! 				   build_int_cst (type,
  						  BITS_PER_WORD - bitsize));
  		bitsize = BITS_PER_WORD;
  		mode = word_mode;
*************** store_constructor (tree exp, rtx target,
*** 5167,5179 ****
  		    emit_label (loop_start);

  		    /* Assign value to element index.  */
! 		    position
! 		      = convert (ssizetype,
! 				 fold_build2 (MINUS_EXPR, TREE_TYPE (index),
! 					      index, TYPE_MIN_VALUE (domain)));
! 		    position = size_binop (MULT_EXPR, position,
! 					   convert (ssizetype,
! 						    TYPE_SIZE_UNIT (elttype)));

  		    pos_rtx = expand_normal (position);
  		    xtarget = offset_address (target, pos_rtx,
--- 5167,5183 ----
  		    emit_label (loop_start);

  		    /* Assign value to element index.  */
! 		    position =
! 		      fold_convert (ssizetype,
! 				    fold_build2 (MINUS_EXPR,
! 						 TREE_TYPE (index),
! 						 index,
! 						 TYPE_MIN_VALUE (domain)));
!
! 		    position =
! 			size_binop (MULT_EXPR, position,
! 				    fold_convert (ssizetype,
! 						  TYPE_SIZE_UNIT (elttype)));

  		    pos_rtx = expand_normal (position);
  		    xtarget = offset_address (target, pos_rtx,
*************** store_constructor (tree exp, rtx target,
*** 5217,5225 ****
  						     index,
  						     TYPE_MIN_VALUE (domain)));

! 		position = size_binop (MULT_EXPR, index,
! 				       convert (ssizetype,
! 						TYPE_SIZE_UNIT (elttype)));
  		xtarget = offset_address (target,
  					  expand_normal (position),
  					  highest_pow2_factor (position));
--- 5221,5230 ----
  						     index,
  						     TYPE_MIN_VALUE (domain)));

! 		position =
! 		  size_binop (MULT_EXPR, index,
! 			      fold_convert (ssizetype,
! 					    TYPE_SIZE_UNIT (elttype)));
  		xtarget = offset_address (target,
  					  expand_normal (position),
  					  highest_pow2_factor (position));
*************** get_inner_reference (tree exp, HOST_WIDE
*** 5672,5678 ****

  	    offset = size_binop (PLUS_EXPR, offset,
  			         size_binop (MULT_EXPR,
! 					     convert (sizetype, index),
  					     unit_size));
  	  }
  	  break;
--- 5677,5683 ----

  	    offset = size_binop (PLUS_EXPR, offset,
  			         size_binop (MULT_EXPR,
! 					     fold_convert (sizetype, index),
  					     unit_size));
  	  }
  	  break;
*************** get_inner_reference (tree exp, HOST_WIDE
*** 5711,5717 ****
    /* If OFFSET is constant, see if we can return the whole thing as a
       constant bit position.  Otherwise, split it up.  */
    if (host_integerp (offset, 0)
!       && 0 != (tem = size_binop (MULT_EXPR, convert (bitsizetype, offset),
  				 bitsize_unit_node))
        && 0 != (tem = size_binop (PLUS_EXPR, tem, bit_offset))
        && host_integerp (tem, 0))
--- 5716,5723 ----
    /* If OFFSET is constant, see if we can return the whole thing as a
       constant bit position.  Otherwise, split it up.  */
    if (host_integerp (offset, 0)
!       && 0 != (tem = size_binop (MULT_EXPR,
! 				 fold_convert (bitsizetype, offset),
  				 bitsize_unit_node))
        && 0 != (tem = size_binop (PLUS_EXPR, tem, bit_offset))
        && host_integerp (tem, 0))
*************** expand_expr_real_1 (tree exp, rtx target
*** 8500,8513 ****
  	    && integer_onep (DECL_SIZE (TREE_OPERAND (TREE_OPERAND (rhs, 1), 1))))
  	  {
  	    rtx label = gen_label_rtx ();
!
  	    do_jump (TREE_OPERAND (rhs, 1),
! 		     TREE_CODE (rhs) == BIT_IOR_EXPR ? label : 0,
! 		     TREE_CODE (rhs) == BIT_AND_EXPR ? label : 0);
! 	    expand_assignment (lhs, convert (TREE_TYPE (rhs),
! 					     (TREE_CODE (rhs) == BIT_IOR_EXPR
! 					      ? integer_one_node
! 					      : integer_zero_node)));
  	    do_pending_stack_adjust ();
  	    emit_label (label);
  	    return const0_rtx;
--- 8506,8516 ----
  	    && integer_onep (DECL_SIZE (TREE_OPERAND (TREE_OPERAND (rhs, 1), 1))))
  	  {
  	    rtx label = gen_label_rtx ();
! 	    int value = TREE_CODE (rhs) == BIT_IOR_EXPR;
  	    do_jump (TREE_OPERAND (rhs, 1),
! 		     value ? label : 0,
! 		     value ? 0 : label);
! 	    expand_assignment (lhs, build_int_cst (TREE_TYPE (rhs), value));
  	    do_pending_stack_adjust ();
  	    emit_label (label);
  	    return const0_rtx;
*************** string_constant (tree arg, tree *ptr_off
*** 8827,8833 ****

    if (TREE_CODE (array) == STRING_CST)
      {
!       *ptr_offset = convert (sizetype, offset);
        return array;
      }
    else if (TREE_CODE (array) == VAR_DECL)
--- 8830,8836 ----

    if (TREE_CODE (array) == STRING_CST)
      {
!       *ptr_offset = fold_convert (sizetype, offset);
        return array;
      }
    else if (TREE_CODE (array) == VAR_DECL)
*************** string_constant (tree arg, tree *ptr_off
*** 8854,8860 ****

        /* If variable is bigger than the string literal, OFFSET must be constant
  	 and inside of the bounds of the string literal.  */
!       offset = convert (sizetype, offset);
        if (compare_tree_int (DECL_SIZE_UNIT (array), length) > 0
  	  && (! host_integerp (offset, 1)
  	      || compare_tree_int (offset, length) >= 0))
--- 8857,8863 ----

        /* If variable is bigger than the string literal, OFFSET must be constant
  	 and inside of the bounds of the string literal.  */
!       offset = fold_convert (sizetype, offset);
        if (compare_tree_int (DECL_SIZE_UNIT (array), length) > 0
  	  && (! host_integerp (offset, 1)
  	      || compare_tree_int (offset, length) >= 0))
*************** try_casesi (tree index_type, tree index_
*** 9166,9174 ****
      {
        if (TYPE_MODE (index_type) != index_mode)
  	{
! 	  index_expr = convert (lang_hooks.types.type_for_size
! 				(index_bits, 0), index_expr);
! 	  index_type = TREE_TYPE (index_expr);
  	}

        index = expand_normal (index_expr);
--- 9169,9176 ----
      {
        if (TYPE_MODE (index_type) != index_mode)
  	{
! 	  index_type = lang_hooks.types.type_for_size (index_bits, 0);
! 	  index_expr = fold_convert (index_type, index_expr);
  	}

        index = expand_normal (index_expr);
*************** try_tablejump (tree index_type, tree ind
*** 9294,9301 ****
      return 0;

    index_expr = fold_build2 (MINUS_EXPR, index_type,
! 			    convert (index_type, index_expr),
! 			    convert (index_type, minval));
    index = expand_normal (index_expr);
    do_pending_stack_adjust ();

--- 9296,9303 ----
      return 0;

    index_expr = fold_build2 (MINUS_EXPR, index_type,
! 			    fold_convert (index_type, index_expr),
! 			    fold_convert (index_type, minval));
    index = expand_normal (index_expr);
    do_pending_stack_adjust ();

Index: tree.c
===================================================================
*** tree.c	(revision 112633)
--- tree.c	(working copy)
*************** build_range_type (tree type, tree lowval
*** 5021,5028 ****
    if (type == NULL_TREE)
      type = sizetype;

!   TYPE_MIN_VALUE (itype) = convert (type, lowval);
!   TYPE_MAX_VALUE (itype) = highval ? convert (type, highval) : NULL;

    TYPE_PRECISION (itype) = TYPE_PRECISION (type);
    TYPE_MODE (itype) = TYPE_MODE (type);
--- 5021,5028 ----
    if (type == NULL_TREE)
      type = sizetype;

!   TYPE_MIN_VALUE (itype) = fold_convert (type, lowval);
!   TYPE_MAX_VALUE (itype) = highval ? fold_convert (type, highval) : NULL;

    TYPE_PRECISION (itype) = TYPE_PRECISION (type);
    TYPE_MODE (itype) = TYPE_MODE (type);


Roger
--



More information about the Gcc-patches mailing list