FreeBSD/contrib/gcc/varasm.c
/* Compare t1 and t2, and return 1 only if they are known to result in
   the same bit pattern on output.  */
Compare t1 and t2, and return 1 only if they are known to result in
the same bit pattern on output.
Compare t1 and t2 and return 1 only if they are known to result in the same bit pattern on output .
static int
compare_constant (const tree t1, const tree t2)
{
  enum tree_code typecode;
  if (t1 == NULL_TREE)
    return t2 == NULL_TREE;
  if (t2 == NULL_TREE)
    return 0;
  if (TREE_CODE (t1) != TREE_CODE (t2))
    return 0;
  switch (TREE_CODE (t1))
    {
    case INTEGER_CST:
      if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2)))
	return 0;
      if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2)))
	return 0;
      return tree_int_cst_equal (t1, t2);
    case REAL_CST:
      if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2)))
	return 0;
      return REAL_VALUES_IDENTICAL (TREE_REAL_CST (t1), TREE_REAL_CST (t2));
    case STRING_CST:
      if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2)))
	return 0;
      return (TREE_STRING_LENGTH (t1) == TREE_STRING_LENGTH (t2)
	      && ! memcmp (TREE_STRING_POINTER (t1), TREE_STRING_POINTER (t2),
			 TREE_STRING_LENGTH (t1)));
    case COMPLEX_CST:
      return (compare_constant (TREE_REALPART (t1), TREE_REALPART (t2))
	      && compare_constant (TREE_IMAGPART (t1), TREE_IMAGPART (t2)));
    case CONSTRUCTOR:
      {
	VEC(constructor_elt, gc) *v1, *v2;
	unsigned HOST_WIDE_INT idx;
	typecode = TREE_CODE (TREE_TYPE (t1));
	if (typecode != TREE_CODE (TREE_TYPE (t2)))
	  return 0;
	if (typecode == ARRAY_TYPE)
	  {
	    HOST_WIDE_INT size_1 = int_size_in_bytes (TREE_TYPE (t1));
	    if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2))
		|| size_1 == -1
		|| size_1 != int_size_in_bytes (TREE_TYPE (t2)))
	      return 0;
	  }
	else
	  {
	    if (TREE_TYPE (t1) != TREE_TYPE (t2))
	      return 0;
	  }
	v1 = CONSTRUCTOR_ELTS (t1);
	v2 = CONSTRUCTOR_ELTS (t2);
	if (VEC_length (constructor_elt, v1)
	    != VEC_length (constructor_elt, v2))
	    return 0;
	for (idx = 0; idx < VEC_length (constructor_elt, v1); ++idx)
	  {
	    constructor_elt *c1 = VEC_index (constructor_elt, v1, idx);
	    constructor_elt *c2 = VEC_index (constructor_elt, v2, idx);
	    if (!compare_constant (c1->value, c2->value))
	      return 0;
	    if (typecode == ARRAY_TYPE)
	      {
		if (!compare_constant (c1->index, c2->index))
		  return 0;
	      }
	    else
	      {
		if (c1->index != c2->index)
		  return 0;
	      }
	  }
	return 1;
      }
    case ADDR_EXPR:
    case FDESC_EXPR:
      {
	struct addr_const value1, value2;
	decode_addr_const (t1, &value1);
	decode_addr_const (t2, &value2);
	return (value1.offset == value2.offset
		&& strcmp (XSTR (value1.base, 0), XSTR (value2.base, 0)) == 0);
      }
    case PLUS_EXPR:
    case MINUS_EXPR:
    case RANGE_EXPR:
      return (compare_constant (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0))
	      && compare_constant(TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1)));
    case NOP_EXPR:
    case CONVERT_EXPR:
    case NON_LVALUE_EXPR:
    case VIEW_CONVERT_EXPR:
      return compare_constant (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
    default:
      {
	tree nt1, nt2;
	nt1 = lang_hooks.expand_constant (t1);
	nt2 = lang_hooks.expand_constant (t2);
	if (nt1 != t1 || nt2 != t2)
	  return compare_constant (nt1, nt2);
	else
	  return 0;
      }
    }
  gcc_unreachable ();
}
static int compare_constant ( const tree t1 , const tree t2 ) { enum tree_code typecode ; if ( t1 == NULL_TREE ) return t2 == NULL_TREE ; if ( t2 == NULL_TREE ) return 0 ; if ( TREE_CODE ( t1 ) != TREE_CODE ( t2 ) ) return 0 ; switch ( TREE_CODE ( t1 ) ) { case INTEGER_CST : if ( TYPE_PRECISION ( TREE_TYPE ( t1 ) ) != TYPE_PRECISION ( TREE_TYPE ( t2 ) ) ) return 0 ; if ( TYPE_MODE ( TREE_TYPE ( t1 ) ) != TYPE_MODE ( TREE_TYPE ( t2 ) ) ) return 0 ; return tree_int_cst_equal ( t1 , t2 ) ; case REAL_CST : if ( TYPE_PRECISION ( TREE_TYPE ( t1 ) ) != TYPE_PRECISION ( TREE_TYPE ( t2 ) ) ) return 0 ; return REAL_VALUES_IDENTICAL ( TREE_REAL_CST ( t1 ) , TREE_REAL_CST ( t2 ) ) ; case STRING_CST : if ( TYPE_MODE ( TREE_TYPE ( t1 ) ) != TYPE_MODE ( TREE_TYPE ( t2 ) ) ) return 0 ; return ( TREE_STRING_LENGTH ( t1 ) == TREE_STRING_LENGTH ( t2 ) && ! memcmp ( TREE_STRING_POINTER ( t1 ) , TREE_STRING_POINTER ( t2 ) , TREE_STRING_LENGTH ( t1 ) ) ) ; case COMPLEX_CST : return ( compare_constant ( TREE_REALPART ( t1 ) , TREE_REALPART ( t2 ) ) && compare_constant ( TREE_IMAGPART ( t1 ) , TREE_IMAGPART ( t2 ) ) ) ; case CONSTRUCTOR : { VEC ( constructor_elt , gc ) * v1 , * v2 ; unsigned HOST_WIDE_INT idx ; typecode = TREE_CODE ( TREE_TYPE ( t1 ) ) ; if ( typecode != TREE_CODE ( TREE_TYPE ( t2 ) ) ) return 0 ; if ( typecode == ARRAY_TYPE ) { HOST_WIDE_INT size_1 = int_size_in_bytes ( TREE_TYPE ( t1 ) ) ; if ( TYPE_MODE ( TREE_TYPE ( t1 ) ) != TYPE_MODE ( TREE_TYPE ( t2 ) ) || size_1 == -1 || size_1 != int_size_in_bytes ( TREE_TYPE ( t2 ) ) ) return 0 ; } else { if ( TREE_TYPE ( t1 ) != TREE_TYPE ( t2 ) ) return 0 ; } v1 = CONSTRUCTOR_ELTS ( t1 ) ; v2 = CONSTRUCTOR_ELTS ( t2 ) ; if ( VEC_length ( constructor_elt , v1 ) != VEC_length ( constructor_elt , v2 ) ) return 0 ; for ( idx = 0 ; idx < VEC_length ( constructor_elt , v1 ) ; ++ idx ) { constructor_elt * c1 = VEC_index ( constructor_elt , v1 , idx ) ; constructor_elt * c2 = VEC_index ( constructor_elt , v2 , idx ) ; if ( ! compare_constant ( c1 -> value , c2 -> value ) ) return 0 ; if ( typecode == ARRAY_TYPE ) { if ( ! compare_constant ( c1 -> index , c2 -> index ) ) return 0 ; } else { if ( c1 -> index != c2 -> index ) return 0 ; } } return 1 ; } case ADDR_EXPR : case FDESC_EXPR : { struct addr_const value1 , value2 ; decode_addr_const ( t1 , & value1 ) ; decode_addr_const ( t2 , & value2 ) ; return ( value1 . offset == value2 . offset && strcmp ( XSTR ( value1 . base , 0 ) , XSTR ( value2 . base , 0 ) ) == 0 ) ; } case PLUS_EXPR : case MINUS_EXPR : case RANGE_EXPR : return ( compare_constant ( TREE_OPERAND ( t1 , 0 ) , TREE_OPERAND ( t2 , 0 ) ) && compare_constant ( TREE_OPERAND ( t1 , 1 ) , TREE_OPERAND ( t2 , 1 ) ) ) ; case NOP_EXPR : case CONVERT_EXPR : case NON_LVALUE_EXPR : case VIEW_CONVERT_EXPR : return compare_constant ( TREE_OPERAND ( t1 , 0 ) , TREE_OPERAND ( t2 , 0 ) ) ; default : { tree nt1 , nt2 ; nt1 = lang_hooks . expand_constant ( t1 ) ; nt2 = lang_hooks . expand_constant ( t2 ) ; if ( nt1 != t1 || nt2 != t2 ) return compare_constant ( nt1 , nt2 ) ; else return 0 ; } } gcc_unreachable ( ) ; }
Compare t1 and t2, and return 1 only if they are known to result in
the same bit pattern on output.
Compare t1 and t2 and return 1 only if they are known to result in the same bit pattern on output .
/* Integer constants are the same only if the same width of type.  */ /* Real constants are the same only if the same width of type.  */ /* For arrays, check that the sizes all match.  */ /* For record and union constructors, require exact type
               equality.  */ /* Check that each value is the same...  */ /* ... and that they apply to the same fields!  */