public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* wide-int, C++ front end
@ 2013-11-23 21:09 Mike Stump
  2013-11-24 12:57 ` Jason Merrill
  0 siblings, 1 reply; 10+ messages in thread
From: Mike Stump @ 2013-11-23 21:09 UTC (permalink / raw)
  To: gcc-patches@gcc.gnu.org Patches; +Cc: Jason Merrill, Kenneth Zadeck

[-- Attachment #1: Type: text/plain, Size: 220 bytes --]

Richi has asked the we break the wide-int patch so that the individual port and front end maintainers can review their parts without have to go through the entire patch.    This patch covers the C++ front end.

Ok?


[-- Attachment #2: wide-int-cp.diffs.txt --]
[-- Type: text/plain, Size: 17293 bytes --]

cp:
	* call.c: Include wide-int.h.
	(type_passed_as): Use INT_CST_LT instead of INT_CST_LT_UNSIGNED.
	(convert_for_arg_passing): Likewise.
	* class.c: Include wide-int.h.
	(end_of_class): Use INT_CST_LT instead of INT_CST_LT_UNSIGNED.
	(include_empty_classes): Likewise
	* cvt.c: Include wide-int.h.
	(ignore_overflows): Use wide_int_to_tree.
	* decl.c: Include wide-int.h.
	(check_array_designated_initializer): Use wide-int interfaces.
	(finish_enum_value_list): Use signop.
	(build_enumerator): Use wide-int interfaces.
	* init.c: Include wide-int.h.
	(build_new_1): Use wide-int interfaces.
	* mangle.c: Include wide-int.h.
	(write_integer_cst): Use wide-int interfaces.
	(write_array_type): Likewise.
	* tree.c: Include wide-int.h.
	(cp_tree_equal): Use wide-int interfaces.
	* typeck2.c: Include wide-int.h.
	(process_init_constructor_array): Use wide-int interfaces.


diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index c529c16..00ebed4 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -41,6 +41,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "c-family/c-objc.h"
 #include "timevar.h"
 #include "cgraph.h"
+#include "wide-int.h"
 
 /* The various kinds of conversion.  */
 
@@ -6495,8 +6496,7 @@ type_passed_as (tree type)
   else if (targetm.calls.promote_prototypes (type)
 	   && INTEGRAL_TYPE_P (type)
 	   && COMPLETE_TYPE_P (type)
-	   && INT_CST_LT_UNSIGNED (TYPE_SIZE (type),
-				   TYPE_SIZE (integer_type_node)))
+	   && INT_CST_LT (TYPE_SIZE (type), TYPE_SIZE (integer_type_node)))
     type = integer_type_node;
 
   return type;
@@ -6536,8 +6536,7 @@ convert_for_arg_passing (tree type, tree val, tsubst_flags_t complain)
   else if (targetm.calls.promote_prototypes (type)
 	   && INTEGRAL_TYPE_P (type)
 	   && COMPLETE_TYPE_P (type)
-	   && INT_CST_LT_UNSIGNED (TYPE_SIZE (type),
-				   TYPE_SIZE (integer_type_node)))
+	   && INT_CST_LT (TYPE_SIZE (type), TYPE_SIZE (integer_type_node)))
     val = cp_perform_integral_promotions (val, complain);
   if ((complain & tf_warning)
       && warn_suggest_attribute_format)
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 00fec27..027d235 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "hash-table.h"
 #include "gimple.h"
 #include "gimplify.h"
+#include "wide-int.h"
 
 /* The number of nested classes being processed.  If we are not in the
    scope of any class, this is zero.  */
@@ -5831,7 +5832,7 @@ end_of_class (tree t, int include_virtuals_p)
 	continue;
 
       offset = end_of_base (base_binfo);
-      if (INT_CST_LT_UNSIGNED (result, offset))
+      if (INT_CST_LT (result, offset))
 	result = offset;
     }
 
@@ -5841,7 +5842,7 @@ end_of_class (tree t, int include_virtuals_p)
 	 vec_safe_iterate (vbases, i, &base_binfo); i++)
       {
 	offset = end_of_base (base_binfo);
-	if (INT_CST_LT_UNSIGNED (result, offset))
+	if (INT_CST_LT (result, offset))
 	  result = offset;
       }
 
@@ -5921,7 +5922,7 @@ include_empty_classes (record_layout_info rli)
 		      CLASSTYPE_AS_BASE (rli->t) != NULL_TREE);
   rli_size = rli_size_unit_so_far (rli);
   if (TREE_CODE (rli_size) == INTEGER_CST
-      && INT_CST_LT_UNSIGNED (rli_size, eoc))
+      && INT_CST_LT (rli_size, eoc))
     {
       if (!abi_version_at_least (2))
 	/* In version 1 of the ABI, the size of a class that ends with
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 5264c5d..6d0e341 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "convert.h"
 #include "decl.h"
 #include "target.h"
+#include "wide-int.h"
 
 static tree cp_convert_to_pointer (tree, tree, tsubst_flags_t);
 static tree convert_to_pointer_force (tree, tree, tsubst_flags_t);
@@ -582,9 +583,7 @@ ignore_overflows (tree expr, tree orig)
     {
       gcc_assert (!TREE_OVERFLOW (orig));
       /* Ensure constant sharing.  */
-      expr = build_int_cst_wide (TREE_TYPE (expr),
-				 TREE_INT_CST_LOW (expr),
-				 TREE_INT_CST_HIGH (expr));
+      expr = wide_int_to_tree (TREE_TYPE (expr), expr);
     }
   return expr;
 }
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 500c81f..babfc88 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -59,6 +59,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "splay-tree.h"
 #include "plugin.h"
 #include "cgraph.h"
+#include "wide-int.h"
 
 /* Possible cases of bad specifiers type used by bad_specifiers. */
 enum bad_spec_place {
@@ -4811,7 +4812,7 @@ check_array_designated_initializer (constructor_elt *ce,
       if (TREE_CODE (ce->index) == INTEGER_CST)
 	{
 	  /* A C99 designator is OK if it matches the current index.  */
-	  if (TREE_INT_CST_LOW (ce->index) == index)
+	  if (wi::eq_p (ce->index, index))
 	    return true;
 	  else
 	    sorry ("non-trivial designated initializers not supported");
@@ -12661,9 +12662,9 @@ finish_enum_value_list (tree enumtype)
 	 enumeration.  We must do this before the type of MINNODE and
 	 MAXNODE are transformed, since tree_int_cst_min_precision relies
 	 on the TREE_TYPE of the value it is passed.  */
-      bool unsignedp = tree_int_cst_sgn (minnode) >= 0;
-      int lowprec = tree_int_cst_min_precision (minnode, unsignedp);
-      int highprec = tree_int_cst_min_precision (maxnode, unsignedp);
+      signop sgn = tree_int_cst_sgn (minnode) >= 0 ? UNSIGNED : SIGNED;
+      int lowprec = tree_int_cst_min_precision (minnode, sgn);
+      int highprec = tree_int_cst_min_precision (maxnode, sgn);
       int precision = MAX (lowprec, highprec);
       unsigned int itk;
       bool use_short_enum;
@@ -12695,7 +12696,7 @@ finish_enum_value_list (tree enumtype)
           underlying_type = integer_types[itk];
           if (underlying_type != NULL_TREE
 	      && TYPE_PRECISION (underlying_type) >= precision
-              && TYPE_UNSIGNED (underlying_type) == unsignedp)
+              && TYPE_SIGN (underlying_type) == sgn)
             break;
         }
       if (itk == itk_none)
@@ -12742,12 +12743,11 @@ finish_enum_value_list (tree enumtype)
 	= build_distinct_type_copy (underlying_type);
       TYPE_PRECISION (ENUM_UNDERLYING_TYPE (enumtype)) = precision;
       set_min_and_max_values_for_integral_type
-        (ENUM_UNDERLYING_TYPE (enumtype), precision, unsignedp);
+        (ENUM_UNDERLYING_TYPE (enumtype), precision, sgn);
 
       /* If -fstrict-enums, still constrain TYPE_MIN/MAX_VALUE.  */
       if (flag_strict_enums)
-	set_min_and_max_values_for_integral_type (enumtype, precision,
-						  unsignedp);
+	set_min_and_max_values_for_integral_type (enumtype, precision, sgn);
     }
   else
     underlying_type = ENUM_UNDERLYING_TYPE (enumtype);
@@ -12871,14 +12871,14 @@ build_enumerator (tree name, tree value, tree enumtype, location_t loc)
 		value = error_mark_node;
 	      else
 		{
-		  double_int di = TREE_INT_CST (prev_value)
-				  .add_with_sign (double_int_one,
-						  false, &overflowed);
+		  tree type = TREE_TYPE (prev_value);
+		  signop sgn = TYPE_SIGN (type);
+		  widest_int wi = wi::add (wi::to_widest (prev_value), 1, sgn,
+					   &overflowed);
 		  if (!overflowed)
 		    {
-		      tree type = TREE_TYPE (prev_value);
-		      bool pos = TYPE_UNSIGNED (type) || !di.is_negative ();
-		      if (!double_int_fits_to_tree_p (type, di))
+		      bool pos = !wi::neg_p (wi, sgn);
+		      if (!wi::fits_to_tree_p (wi, type))
 			{
 			  unsigned int itk;
 			  for (itk = itk_int; itk != itk_none; itk++)
@@ -12886,7 +12886,7 @@ build_enumerator (tree name, tree value, tree enumtype, location_t loc)
 			      type = integer_types[itk];
 			      if (type != NULL_TREE
 				  && (pos || !TYPE_UNSIGNED (type))
-				  && double_int_fits_to_tree_p (type, di))
+				  && wi::fits_to_tree_p (wi, type))
 				break;
 			    }
 			  if (type && cxx_dialect < cxx11
@@ -12898,7 +12898,7 @@ incremented enumerator value is too large for %<long%>");
 		      if (type == NULL_TREE)
 			overflowed = true;
 		      else
-			value = double_int_to_tree (type, di);
+			value = wide_int_to_tree (type, wi);
 		    }
 
 		  if (overflowed)
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index fd43a4f..7b6f4e2 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "target.h"
 #include "gimple.h"
 #include "gimplify.h"
+#include "wide-int.h"
 
 static bool begin_init_stmts (tree *, tree *);
 static tree finish_init_stmts (bool, tree, tree);
@@ -2246,10 +2247,10 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
   /* For arrays, a bounds checks on the NELTS parameter. */
   tree outer_nelts_check = NULL_TREE;
   bool outer_nelts_from_type = false;
-  double_int inner_nelts_count = double_int_one;
+  offset_int inner_nelts_count = 1;
   tree alloc_call, alloc_expr;
   /* Size of the inner array elements. */
-  double_int inner_size;
+  offset_int inner_size;
   /* The address returned by the call to "operator new".  This node is
      a VAR_DECL and is therefore reusable.  */
   tree alloc_node;
@@ -2304,9 +2305,8 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
       if (TREE_CODE (inner_nelts_cst) == INTEGER_CST)
 	{
 	  bool overflow;
-	  double_int result = TREE_INT_CST (inner_nelts_cst)
-			      .mul_with_sign (inner_nelts_count,
-					      false, &overflow);
+	  offset_int result = wi::mul (wi::to_offset (inner_nelts_cst),
+				       inner_nelts_count, SIGNED, &overflow);
 	  if (overflow)
 	    {
 	      if (complain & tf_error)
@@ -2408,42 +2408,40 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
     {
       /* Maximum available size in bytes.  Half of the address space
 	 minus the cookie size.  */
-      double_int max_size
-	= double_int_one.llshift (TYPE_PRECISION (sizetype) - 1,
-				  HOST_BITS_PER_DOUBLE_INT);
+      offset_int max_size
+	= wi::set_bit_in_zero <offset_int> (TYPE_PRECISION (sizetype) - 1);
       /* Maximum number of outer elements which can be allocated. */
-      double_int max_outer_nelts;
+      offset_int max_outer_nelts;
       tree max_outer_nelts_tree;
 
       gcc_assert (TREE_CODE (size) == INTEGER_CST);
       cookie_size = targetm.cxx.get_cookie_size (elt_type);
       gcc_assert (TREE_CODE (cookie_size) == INTEGER_CST);
-      gcc_checking_assert (TREE_INT_CST (cookie_size).ult (max_size));
+      gcc_checking_assert (wi::ltu_p (wi::to_offset (cookie_size), max_size));
       /* Unconditionally subtract the cookie size.  This decreases the
 	 maximum object size and is safe even if we choose not to use
 	 a cookie after all.  */
-      max_size -= TREE_INT_CST (cookie_size);
+      max_size -= wi::to_offset (cookie_size);
       bool overflow;
-      inner_size = TREE_INT_CST (size)
-		   .mul_with_sign (inner_nelts_count, false, &overflow);
-      if (overflow || inner_size.ugt (max_size))
+      inner_size = wi::mul (wi::to_offset (size), inner_nelts_count, SIGNED,
+			    &overflow);
+      if (overflow || wi::gtu_p (inner_size, max_size))
 	{
 	  if (complain & tf_error)
 	    error ("size of array is too large");
 	  return error_mark_node;
 	}
-      max_outer_nelts = max_size.udiv (inner_size, TRUNC_DIV_EXPR);
+
+      max_outer_nelts = wi::udiv_trunc (max_size, inner_size);
       /* Only keep the top-most seven bits, to simplify encoding the
 	 constant in the instruction stream.  */
       {
-	unsigned shift = HOST_BITS_PER_DOUBLE_INT - 7
-	  - (max_outer_nelts.high ? clz_hwi (max_outer_nelts.high)
-	     : (HOST_BITS_PER_WIDE_INT + clz_hwi (max_outer_nelts.low)));
-	max_outer_nelts
-	  = max_outer_nelts.lrshift (shift, HOST_BITS_PER_DOUBLE_INT)
-	    .llshift (shift, HOST_BITS_PER_DOUBLE_INT);
+	unsigned shift = (max_outer_nelts.get_precision ()) - 7
+	  - wi::clz (max_outer_nelts);
+	max_outer_nelts = wi::lshift (wi::lrshift (max_outer_nelts, shift),
+				      shift);
       }
-      max_outer_nelts_tree = double_int_to_tree (sizetype, max_outer_nelts);
+      max_outer_nelts_tree = wide_int_to_tree (sizetype, max_outer_nelts);
 
       size = size_binop (MULT_EXPR, size, convert (sizetype, nelts));
       outer_nelts_check = fold_build2 (LE_EXPR, boolean_type_node,
@@ -2524,7 +2522,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
 	      cookie_size = NULL_TREE;
 	      /* No size arithmetic necessary, so the size check is
 		 not needed. */
-	      if (outer_nelts_check != NULL && inner_size.is_one ())
+	      if (outer_nelts_check != NULL && inner_size == 1)
 		outer_nelts_check = NULL_TREE;
 	    }
 	  /* Perform the overflow check.  */
@@ -2569,7 +2567,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
 	      cookie_size = NULL_TREE;
 	      /* No size arithmetic necessary, so the size check is
 		 not needed. */
-	      if (outer_nelts_check != NULL && inner_size.is_one ())
+	      if (outer_nelts_check != NULL && inner_size == 1)
 		outer_nelts_check = NULL_TREE;
 	    }
 
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 8a24d6c..31f78c7 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -57,6 +57,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "flags.h"
 #include "target.h"
 #include "cgraph.h"
+#include "wide-int.h"
 
 /* Debugging support.  */
 
@@ -1504,8 +1505,8 @@ static inline void
 write_integer_cst (const tree cst)
 {
   int sign = tree_int_cst_sgn (cst);
-
-  if (TREE_INT_CST_HIGH (cst) + (sign < 0))
+  widest_int abs_value = wi::abs (wi::to_widest (cst));
+  if (!wi::fits_uhwi_p (abs_value))
     {
       /* A bignum. We do this in chunks, each of which fits in a
 	 HOST_WIDE_INT.  */
@@ -1531,8 +1532,7 @@ write_integer_cst (const tree cst)
 
       type = c_common_signed_or_unsigned_type (1, TREE_TYPE (cst));
       base = build_int_cstu (type, chunk);
-      n = build_int_cst_wide (type,
-			      TREE_INT_CST_LOW (cst), TREE_INT_CST_HIGH (cst));
+      n = wide_int_to_tree (type, cst);
 
       if (sign < 0)
 	{
@@ -1559,14 +1559,9 @@ write_integer_cst (const tree cst)
   else
     {
       /* A small num.  */
-      unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (cst);
-
       if (sign < 0)
-	{
-	  write_char ('n');
-	  low = -low;
-	}
-      write_unsigned_number (low);
+	write_char ('n');
+      write_unsigned_number (abs_value.to_uhwi ());
     }
 }
 
@@ -3225,12 +3220,12 @@ write_array_type (const tree type)
 	{
 	  /* The ABI specifies that we should mangle the number of
 	     elements in the array, not the largest allowed index.  */
-	  double_int dmax = tree_to_double_int (max) + double_int_one;
+	  offset_int wmax = wi::to_offset (max) + 1;
 	  /* Truncate the result - this will mangle [0, SIZE_INT_MAX]
 	     number of elements as zero.  */
-	  dmax = dmax.zext (TYPE_PRECISION (TREE_TYPE (max)));
-	  gcc_assert (dmax.fits_uhwi ());
-	  write_unsigned_number (dmax.low);
+	  wmax = wi::zext (wmax, TYPE_PRECISION (TREE_TYPE (max)));
+	  gcc_assert (wi::fits_uhwi_p (wmax));
+	  write_unsigned_number (wmax.to_uhwi ());
 	}
       else
 	{
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index a990a79..2e3b586 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple.h"
 #include "gimplify.h"
 #include "hash-table.h"
+#include "wide-int.h"
 
 static tree bot_manip (tree *, int *, void *);
 static tree bot_replace (tree *, int *, void *);
@@ -2605,8 +2606,7 @@ cp_tree_equal (tree t1, tree t2)
   switch (code1)
     {
     case INTEGER_CST:
-      return TREE_INT_CST_LOW (t1) == TREE_INT_CST_LOW (t2)
-	&& TREE_INT_CST_HIGH (t1) == TREE_INT_CST_HIGH (t2);
+      return wi::to_widest (t1) == wi::to_widest (t2);
 
     case REAL_CST:
       return REAL_VALUES_EQUAL (TREE_REAL_CST (t1), TREE_REAL_CST (t2));
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 0f3b01d..5040226 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cp-tree.h"
 #include "flags.h"
 #include "diagnostic-core.h"
+#include "wide-int.h"
 
 static tree
 process_init_constructor (tree type, tree init, tsubst_flags_t complain);
@@ -1122,12 +1123,10 @@ process_init_constructor_array (tree type, tree init,
     {
       tree domain = TYPE_DOMAIN (type);
       if (domain && TREE_CONSTANT (TYPE_MAX_VALUE (domain)))
-	len = (tree_to_double_int (TYPE_MAX_VALUE (domain))
-	       - tree_to_double_int (TYPE_MIN_VALUE (domain))
-	       + double_int_one)
-	      .ext (TYPE_PRECISION (TREE_TYPE (domain)),
-		    TYPE_UNSIGNED (TREE_TYPE (domain)))
-	      .low;
+	len = wi::ext (wi::to_offset (TYPE_MAX_VALUE (domain))
+		       - wi::to_offset (TYPE_MIN_VALUE (domain)) + 1,
+		       TYPE_PRECISION (TREE_TYPE (domain)),
+		       TYPE_SIGN (TREE_TYPE (domain))).to_uhwi ();
       else
 	unbounded = true;  /* Take as many as there are.  */
     }

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: wide-int, C++ front end
  2013-11-23 21:09 wide-int, C++ front end Mike Stump
@ 2013-11-24 12:57 ` Jason Merrill
  2013-11-25 22:27   ` Kenneth Zadeck
  2013-11-25 23:10   ` Richard Sandiford
  0 siblings, 2 replies; 10+ messages in thread
From: Jason Merrill @ 2013-11-24 12:57 UTC (permalink / raw)
  To: Mike Stump, gcc-patches@gcc.gnu.org Patches; +Cc: Kenneth Zadeck

On 11/23/2013 02:20 PM, Mike Stump wrote:
> @@ -2605,8 +2606,7 @@ cp_tree_equal (tree t1, tree t2)
>     switch (code1)
>       {
>       case INTEGER_CST:
> -      return TREE_INT_CST_LOW (t1) == TREE_INT_CST_LOW (t2)
> -	&& TREE_INT_CST_HIGH (t1) == TREE_INT_CST_HIGH (t2);
> +      return wi::to_widest (t1) == wi::to_widest (t2);

Why not use wi::eq_p like you do in the C front end?

Jason

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: wide-int, C++ front end
  2013-11-24 12:57 ` Jason Merrill
@ 2013-11-25 22:27   ` Kenneth Zadeck
  2013-11-25 23:10   ` Richard Sandiford
  1 sibling, 0 replies; 10+ messages in thread
From: Kenneth Zadeck @ 2013-11-25 22:27 UTC (permalink / raw)
  To: Jason Merrill, Mike Stump, gcc-patches@gcc.gnu.org Patches

[-- Attachment #1: Type: text/plain, Size: 498 bytes --]

fixed on the wide-int branch 205363.
On 11/23/2013 09:00 PM, Jason Merrill wrote:
> On 11/23/2013 02:20 PM, Mike Stump wrote:
>> @@ -2605,8 +2606,7 @@ cp_tree_equal (tree t1, tree t2)
>>     switch (code1)
>>       {
>>       case INTEGER_CST:
>> -      return TREE_INT_CST_LOW (t1) == TREE_INT_CST_LOW (t2)
>> -    && TREE_INT_CST_HIGH (t1) == TREE_INT_CST_HIGH (t2);
>> +      return wi::to_widest (t1) == wi::to_widest (t2);
>
> Why not use wi::eq_p like you do in the C front end?
>
> Jason
>


[-- Attachment #2: dwarfcomment.diff --]
[-- Type: text/x-patch, Size: 1077 bytes --]

Index: dwarf2out.c
===================================================================
--- dwarf2out.c	(revision 205360)
+++ dwarf2out.c	(working copy)
@@ -12880,10 +12880,15 @@ mem_loc_descriptor (rtx rtl, enum machin
 	{
 	  dw_die_ref type_die;
 
-	  /* Note that a CONST_DOUBLE rtx could represent either an integer
-	     or a floating-point constant.  A CONST_DOUBLE is used whenever
-	     the constant requires more than one word in order to be
-	     adequately represented.  We output CONST_DOUBLEs as blocks.  */
+	  /* Note that if TARGET_SUPPORTS_WIDE_INT == 0, a
+	     CONST_DOUBLE rtx could represent either an large integer
+	     or a floating-point constant.  If
+	     TARGET_SUPPORTS_WIDE_INT != 0, the value is always a
+	     floating point constant.
+
+	     When it is an integer, a CONST_DOUBLE is used whenever
+	     the constant requires 2 HWIs to be adequately
+	     represented.  We output CONST_DOUBLEs as blocks.  */
 	  if (mode == VOIDmode
 	      || (GET_MODE (rtl) == VOIDmode
 		  && GET_MODE_BITSIZE (mode) != HOST_BITS_PER_DOUBLE_INT))

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: wide-int, C++ front end
  2013-11-24 12:57 ` Jason Merrill
  2013-11-25 22:27   ` Kenneth Zadeck
@ 2013-11-25 23:10   ` Richard Sandiford
  2013-11-26  0:31     ` Jason Merrill
  2013-11-26 10:52     ` Richard Biener
  1 sibling, 2 replies; 10+ messages in thread
From: Richard Sandiford @ 2013-11-25 23:10 UTC (permalink / raw)
  To: Jason Merrill; +Cc: Mike Stump, gcc-patches@gcc.gnu.org Patches, Kenneth Zadeck

Jason Merrill <jason@redhat.com> writes:
> On 11/23/2013 02:20 PM, Mike Stump wrote:
>> @@ -2605,8 +2606,7 @@ cp_tree_equal (tree t1, tree t2)
>>     switch (code1)
>>       {
>>       case INTEGER_CST:
>> -      return TREE_INT_CST_LOW (t1) == TREE_INT_CST_LOW (t2)
>> -	&& TREE_INT_CST_HIGH (t1) == TREE_INT_CST_HIGH (t2);
>> +      return wi::to_widest (t1) == wi::to_widest (t2);
>
> Why not use wi::eq_p like you do in the C front end?

Thanks for noticing the difference.  I think c_tree_equal should change
to use to_widest too.

wi::eq_p (t1, t2) asserts that t1 and t2 are the same precision and
ignores signedness; it just tests whether they are the same bitstring.
wi::to_widest (t1) == wi::to_widest (t2) compares them as logical numbers,
taking sign into account and allowing different types.  I think that's
what the original TREE_INT_CST_LOW and TREE_INT_CST_HIGH tests did too.

Richard

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: wide-int, C++ front end
  2013-11-25 23:10   ` Richard Sandiford
@ 2013-11-26  0:31     ` Jason Merrill
  2013-11-26 10:52     ` Richard Biener
  1 sibling, 0 replies; 10+ messages in thread
From: Jason Merrill @ 2013-11-26  0:31 UTC (permalink / raw)
  To: Mike Stump, gcc-patches@gcc.gnu.org Patches, Kenneth Zadeck, rdsandiford

On 11/25/2013 03:05 PM, Richard Sandiford wrote:
> wi::eq_p (t1, t2) asserts that t1 and t2 are the same precision and
> ignores signedness; it just tests whether they are the same bitstring.
> wi::to_widest (t1) == wi::to_widest (t2) compares them as logical numbers,
> taking sign into account and allowing different types.  I think that's
> what the original TREE_INT_CST_LOW and TREE_INT_CST_HIGH tests did too.

That seems reasonable, though I don't think allowing different types is 
actually a goal.  In most cases the type is required to be the same by 
the context.

Jason

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: wide-int, C++ front end
  2013-11-25 23:10   ` Richard Sandiford
  2013-11-26  0:31     ` Jason Merrill
@ 2013-11-26 10:52     ` Richard Biener
  2014-01-02  2:41       ` Mike Stump
  1 sibling, 1 reply; 10+ messages in thread
From: Richard Biener @ 2013-11-26 10:52 UTC (permalink / raw)
  To: Jason Merrill, Mike Stump, gcc-patches@gcc.gnu.org Patches,
	Kenneth Zadeck, Richard Sandiford

On Mon, Nov 25, 2013 at 9:05 PM, Richard Sandiford
<rdsandiford@googlemail.com> wrote:
> Jason Merrill <jason@redhat.com> writes:
>> On 11/23/2013 02:20 PM, Mike Stump wrote:
>>> @@ -2605,8 +2606,7 @@ cp_tree_equal (tree t1, tree t2)
>>>     switch (code1)
>>>       {
>>>       case INTEGER_CST:
>>> -      return TREE_INT_CST_LOW (t1) == TREE_INT_CST_LOW (t2)
>>> -    && TREE_INT_CST_HIGH (t1) == TREE_INT_CST_HIGH (t2);
>>> +      return wi::to_widest (t1) == wi::to_widest (t2);
>>
>> Why not use wi::eq_p like you do in the C front end?
>
> Thanks for noticing the difference.  I think c_tree_equal should change
> to use to_widest too.
>
> wi::eq_p (t1, t2) asserts that t1 and t2 are the same precision and
> ignores signedness; it just tests whether they are the same bitstring.
> wi::to_widest (t1) == wi::to_widest (t2) compares them as logical numbers,
> taking sign into account and allowing different types.  I think that's
> what the original TREE_INT_CST_LOW and TREE_INT_CST_HIGH tests did too.

Though in this case (comparing two INTEGER_CSTs) it would be better
to use a tree abstraction - thus tree_int_cst_equal.  It saves us from
making the decision on what to map this in wide-int to multiple times.

Note that tree_int_cst_equal tests for "same constant value" - in tree
terms this includes sign information and thus requires to_widest.

Richard.

> Richard

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: wide-int, C++ front end
  2013-11-26 10:52     ` Richard Biener
@ 2014-01-02  2:41       ` Mike Stump
  2014-01-02 16:50         ` Jason Merrill
  0 siblings, 1 reply; 10+ messages in thread
From: Mike Stump @ 2014-01-02  2:41 UTC (permalink / raw)
  To: Jason Merrill
  Cc: gcc-patches@gcc.gnu.org Patches, Kenneth Zadeck,
	Richard Sandiford, Richard Biener

On Nov 26, 2013, at 1:34 AM, Richard Biener <richard.guenther@gmail.com> wrote:
> On Mon, Nov 25, 2013 at 9:05 PM, Richard Sandiford
> <rdsandiford@googlemail.com> wrote:
>> Jason Merrill <jason@redhat.com> writes:
>>> On 11/23/2013 02:20 PM, Mike Stump wrote:
>>>> @@ -2605,8 +2606,7 @@ cp_tree_equal (tree t1, tree t2)
>>>>    switch (code1)
>>>>      {
>>>>      case INTEGER_CST:
>>>> -      return TREE_INT_CST_LOW (t1) == TREE_INT_CST_LOW (t2)
>>>> -    && TREE_INT_CST_HIGH (t1) == TREE_INT_CST_HIGH (t2);
>>>> +      return wi::to_widest (t1) == wi::to_widest (t2);
>>> 
>>> Why not use wi::eq_p like you do in the C front end?
>> 
>> Thanks for noticing the difference.  I think c_tree_equal should change
>> to use to_widest too.
>> 
>> wi::eq_p (t1, t2) asserts that t1 and t2 are the same precision and
>> ignores signedness; it just tests whether they are the same bitstring.
>> wi::to_widest (t1) == wi::to_widest (t2) compares them as logical numbers,
>> taking sign into account and allowing different types.  I think that's
>> what the original TREE_INT_CST_LOW and TREE_INT_CST_HIGH tests did too.
> 
> Though in this case (comparing two INTEGER_CSTs) it would be better
> to use a tree abstraction - thus tree_int_cst_equal.  It saves us from
> making the decision on what to map this in wide-int to multiple times.

Seems like a good idea to me:

Index: cp/tree.c
===================================================================
--- cp/tree.c	(revision 206183)
+++ cp/tree.c	(working copy)
@@ -2606,7 +2606,7 @@ cp_tree_equal (tree t1, tree t2)
   switch (code1)
     {
     case INTEGER_CST:
-      return wi::to_widest (t1) == wi::to_widest (t2);
+      return tree_int_cst_equal (t1, t2);
 
     case REAL_CST:
       return REAL_VALUES_EQUAL (TREE_REAL_CST (t1), TREE_REAL_CST (t2));

Jason, are the C++ patches with this change to them Ok?

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: wide-int, C++ front end
  2014-01-02  2:41       ` Mike Stump
@ 2014-01-02 16:50         ` Jason Merrill
  0 siblings, 0 replies; 10+ messages in thread
From: Jason Merrill @ 2014-01-02 16:50 UTC (permalink / raw)
  To: Mike Stump
  Cc: gcc-patches@gcc.gnu.org Patches, Kenneth Zadeck,
	Richard Sandiford, Richard Biener

On 01/01/2014 09:41 PM, Mike Stump wrote:
> Jason, are the C++ patches with this change to them Ok?

Yes.

Jason


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: wide-int, c front end
  2013-11-23 19:23 wide-int, c " Mike Stump
@ 2013-11-25 18:31 ` Joseph S. Myers
  0 siblings, 0 replies; 10+ messages in thread
From: Joseph S. Myers @ 2013-11-25 18:31 UTC (permalink / raw)
  To: Mike Stump; +Cc: gcc-patches@gcc.gnu.org Patches, Kenneth Zadeck

On Sat, 23 Nov 2013, Mike Stump wrote:

> Richi has asked the we break the wide-int patch so that the individual 
> port and front end maintainers can review their parts without have to go 
> through the entire patch.  This patch covers the c front end.
> 
> Ok?

OK.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 10+ messages in thread

* wide-int, c front end
@ 2013-11-23 19:23 Mike Stump
  2013-11-25 18:31 ` Joseph S. Myers
  0 siblings, 1 reply; 10+ messages in thread
From: Mike Stump @ 2013-11-23 19:23 UTC (permalink / raw)
  To: gcc-patches@gcc.gnu.org Patches; +Cc: Joseph S. Myers, Kenneth Zadeck

[-- Attachment #1: Type: text/plain, Size: 218 bytes --]

Richi has asked the we break the wide-int patch so that the individual port and front end maintainers can review their parts without have to go through the entire patch.    This patch covers the c front end.

Ok?


[-- Attachment #2: wide-int-c.diffs.txt --]
[-- Type: text/plain, Size: 22058 bytes --]

c:
	* c-decl.c
	(check_bitfield_type_and_width): Use TYPE_SIGN.
	(finish_enum): Use wide-int interfaces.
	* c-parser.c
	(c_parser_cilk_clause_vectorlength): Use wide-int interfaces.
	* c-typeck.c
	(build_c_cast): Use wide-int interfaces.
	(set_nonincremental_init_from_string): Likewise.
	(c_tree_equal): Likewise.


c-family:
	* c-ada-spec.c: Include wide-int.h.
	(ADA_HOST_WIDE_INT_PRINT_DOUBLE_HEX): Remove.
	(dump_generic_ada_node): Use wide-int interfaces.
	* c-common.c: Include wide-int-print.h.
	(shorten_compare): Use wide-int interfaces.
	(pointer_int_sum): Likewise.
	(c_common_nodes_and_builtins): Use make_int_cst.
	(match_case_to_enum_1): Use tree_fits_uhwi_p and tree_fits_shwi_p.
	(handle_alloc_size_attribute): Use wide-int interfaces.
	(get_nonnull_operand): Likewise.
	* c-format.c
	(get_constant): Use tree_fits_uhwi_p.
	* c-lex.c: Include wide-int.h.
	(narrowest_unsigned_type): Take a widest_int rather than two
	HOST_WIDE_INTs.
	(narrowest_signed_type): Likewise.
	(interpret_integer): Update accordingly.  Use wide-int interfaces.
	(lex_charconst): Use wide-int interfaces.
	* c-pretty-print.c: Include wide-int.h.
	(pp_c_integer_constant): Use wide-int interfaces.
	* cilk.c
	(declare_one_free_variable): Use INT_CST_LT instead of
	INT_CST_LT_UNSIGNED.


diff --git a/gcc/c-family/c-ada-spec.c b/gcc/c-family/c-ada-spec.c
index 1724c74..e194d28 100644
--- a/gcc/c-family/c-ada-spec.c
+++ b/gcc/c-family/c-ada-spec.c
@@ -29,21 +29,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cpplib.h"
 #include "c-pragma.h"
 #include "cpp-id-data.h"
-
-/* Adapted from hwint.h to use the Ada prefix.  */
-#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
-# if HOST_BITS_PER_WIDE_INT == 64
-#  define ADA_HOST_WIDE_INT_PRINT_DOUBLE_HEX \
-     "16#%" HOST_LONG_FORMAT "x%016" HOST_LONG_FORMAT "x#"
-# else
-#  define ADA_HOST_WIDE_INT_PRINT_DOUBLE_HEX \
-     "16#%" HOST_LONG_FORMAT "x%08" HOST_LONG_FORMAT "x#"
-# endif
-#else
-  /* We can assume that 'long long' is at least 64 bits.  */
-# define ADA_HOST_WIDE_INT_PRINT_DOUBLE_HEX \
-    "16#%" HOST_LONG_LONG_FORMAT "x%016" HOST_LONG_LONG_FORMAT "x#"
-#endif /* HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG */
+#include "wide-int.h"
 
 /* Local functions, macros and variables.  */
 static int dump_generic_ada_node (pretty_printer *, tree, tree, int, int,
@@ -2211,19 +2197,18 @@ dump_generic_ada_node (pretty_printer *buffer, tree node, tree type, int spc,
 	pp_unsigned_wide_integer (buffer, tree_to_uhwi (node));
       else
 	{
-	  tree val = node;
-	  unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (val);
-	  HOST_WIDE_INT high = TREE_INT_CST_HIGH (val);
-
-	  if (tree_int_cst_sgn (val) < 0)
+	  wide_int val = node;
+	  int i;
+	  if (wi::neg_p (val))
 	    {
 	      pp_minus (buffer);
-	      high = ~high + !low;
-	      low = -low;
+	      val = -val;
 	    }
 	  sprintf (pp_buffer (buffer)->digit_buffer,
-		   ADA_HOST_WIDE_INT_PRINT_DOUBLE_HEX,
-		   (unsigned HOST_WIDE_INT) high, low);
+		   "16#%" HOST_LONG_FORMAT "x", val.elt (val.get_len () - 1));
+	  for (i = val.get_len () - 2; i <= 0; i--)
+	    sprintf (pp_buffer (buffer)->digit_buffer,
+		     HOST_WIDE_INT_PRINT_PADDED_HEX, val.elt (i));
 	  pp_string (buffer, pp_buffer (buffer)->digit_buffer);
 	}
       break;
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 97f33c1..e5e9389 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -51,6 +51,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "target-def.h"
 #include "gimple.h"
 #include "gimplify.h"
+#include "wide-int-print.h"
 
 cpp_reader *parse_in;		/* Declared in c-pragma.h.  */
 
@@ -4117,9 +4118,12 @@ shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr,
 	{
 	  /* Convert primop1 to target type, but do not introduce
 	     additional overflow.  We know primop1 is an int_cst.  */
-	  primop1 = force_fit_type_double (*restype_ptr,
-					   tree_to_double_int (primop1),
-					   0, TREE_OVERFLOW (primop1));
+	  primop1 = force_fit_type (*restype_ptr,
+				    wide_int::from
+				      (primop1,
+				       TYPE_PRECISION (*restype_ptr),
+				       TYPE_SIGN (TREE_TYPE (primop1))),
+				    0, TREE_OVERFLOW (primop1));
 	}
       if (type != *restype_ptr)
 	{
@@ -4127,20 +4131,10 @@ shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr,
 	  maxval = convert (*restype_ptr, maxval);
 	}
 
-      if (unsignedp && unsignedp0)
-	{
-	  min_gt = INT_CST_LT_UNSIGNED (primop1, minval);
-	  max_gt = INT_CST_LT_UNSIGNED (primop1, maxval);
-	  min_lt = INT_CST_LT_UNSIGNED (minval, primop1);
-	  max_lt = INT_CST_LT_UNSIGNED (maxval, primop1);
-	}
-      else
-	{
-	  min_gt = INT_CST_LT (primop1, minval);
-	  max_gt = INT_CST_LT (primop1, maxval);
-	  min_lt = INT_CST_LT (minval, primop1);
-	  max_lt = INT_CST_LT (maxval, primop1);
-	}
+      min_gt = INT_CST_LT (primop1, minval);
+      max_gt = INT_CST_LT (primop1, maxval);
+      min_lt = INT_CST_LT (minval, primop1);
+      max_lt = INT_CST_LT (maxval, primop1);
 
       val = 0;
       /* This used to be a switch, but Genix compiler can't handle that.  */
@@ -4431,8 +4425,7 @@ pointer_int_sum (location_t loc, enum tree_code resultcode,
 			      convert (TREE_TYPE (intop), size_exp), 1);
     intop = convert (sizetype, t);
     if (TREE_OVERFLOW_P (intop) && !TREE_OVERFLOW (t))
-      intop = build_int_cst_wide (TREE_TYPE (intop), TREE_INT_CST_LOW (intop),
-				  TREE_INT_CST_HIGH (intop));
+      intop = wide_int_to_tree (TREE_TYPE (intop), intop);
   }
 
   /* Create the sum or difference.  */
@@ -5490,7 +5483,7 @@ c_common_nodes_and_builtins (void)
   }
 
   /* This node must not be shared.  */
-  void_zero_node = make_node (INTEGER_CST);
+  void_zero_node = make_int_cst (1, 1);
   TREE_TYPE (void_zero_node) = void_type_node;
 
   void_list_node = build_void_list_node ();
@@ -5701,7 +5694,7 @@ c_common_nodes_and_builtins (void)
 
   /* Create the built-in __null node.  It is important that this is
      not shared.  */
-  null_node = make_node (INTEGER_CST);
+  null_node = make_int_cst (1, 1);
   TREE_TYPE (null_node) = c_common_type_for_size (POINTER_SIZE, 0);
 
   /* Since builtin_types isn't gc'ed, don't export these nodes.  */
@@ -6079,22 +6072,14 @@ c_add_case_label (location_t loc, splay_tree cases, tree cond, tree orig_type,
 static void
 match_case_to_enum_1 (tree key, tree type, tree label)
 {
-  char buf[2 + 2*HOST_BITS_PER_WIDE_INT/4 + 1];
-
-  /* ??? Not working too hard to print the double-word value.
-     Should perhaps be done with %lwd in the diagnostic routines?  */
-  if (TREE_INT_CST_HIGH (key) == 0)
-    snprintf (buf, sizeof (buf), HOST_WIDE_INT_PRINT_UNSIGNED,
-	      TREE_INT_CST_LOW (key));
-  else if (!TYPE_UNSIGNED (type)
-	   && TREE_INT_CST_HIGH (key) == -1
-	   && TREE_INT_CST_LOW (key) != 0)
-    snprintf (buf, sizeof (buf), "-" HOST_WIDE_INT_PRINT_UNSIGNED,
-	      -TREE_INT_CST_LOW (key));
+  char buf[WIDE_INT_PRINT_BUFFER_SIZE];
+
+  if (tree_fits_uhwi_p (key))
+    print_dec (key, buf, UNSIGNED);
+  else if (tree_fits_shwi_p (key))
+    print_dec (key, buf, SIGNED);
   else
-    snprintf (buf, sizeof (buf), HOST_WIDE_INT_PRINT_DOUBLE_HEX,
-	      (unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (key),
-	      (unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (key));
+    print_hex (key, buf);
 
   if (TYPE_NAME (type) == 0)
     warning_at (DECL_SOURCE_LOCATION (CASE_LABEL (label)),
@@ -8020,9 +8005,8 @@ handle_alloc_size_attribute (tree *node, tree ARG_UNUSED (name), tree args,
       tree position = TREE_VALUE (args);
 
       if (TREE_CODE (position) != INTEGER_CST
-	  || TREE_INT_CST_HIGH (position)
-	  || TREE_INT_CST_LOW (position) < 1
-	  || TREE_INT_CST_LOW (position) > arg_count )
+	  || wi::ltu_p (position, 1)
+	  || wi::gtu_p (position, arg_count))
 	{
 	  warning (OPT_Wattributes,
 	           "alloc_size parameter outside range");
@@ -8783,13 +8767,14 @@ check_nonnull_arg (void * ARG_UNUSED (ctx), tree param,
 static bool
 get_nonnull_operand (tree arg_num_expr, unsigned HOST_WIDE_INT *valp)
 {
-  /* Verify the arg number is a constant.  */
-  if (TREE_CODE (arg_num_expr) != INTEGER_CST
-      || TREE_INT_CST_HIGH (arg_num_expr) != 0)
+  /* Verify the arg number is a small constant.  */
+  if (tree_fits_uhwi_p (arg_num_expr))
+    {
+      *valp = TREE_INT_CST_LOW (arg_num_expr);
+      return true;
+    }
+  else
     return false;
-
-  *valp = TREE_INT_CST_LOW (arg_num_expr);
-  return true;
 }
 
 /* Handle a "nothrow" attribute; arguments as in
diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c
index 0552c84..b99e281 100644
--- a/gcc/c-family/c-format.c
+++ b/gcc/c-family/c-format.c
@@ -227,7 +227,7 @@ check_format_string (tree fntype, unsigned HOST_WIDE_INT format_num,
 static bool
 get_constant (tree expr, unsigned HOST_WIDE_INT *value, int validated_p)
 {
-  if (TREE_CODE (expr) != INTEGER_CST || TREE_INT_CST_HIGH (expr) != 0)
+  if (!tree_fits_uhwi_p (expr))
     {
       gcc_assert (!validated_p);
       return false;
diff --git a/gcc/c-family/c-lex.c b/gcc/c-family/c-lex.c
index 85fa426..4594a5a 100644
--- a/gcc/c-family/c-lex.c
+++ b/gcc/c-family/c-lex.c
@@ -35,6 +35,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "splay-tree.h"
 #include "debug.h"
 #include "target.h"
+#include "wide-int.h"
 
 /* We may keep statistics about how long which files took to compile.  */
 static int header_time, body_time;
@@ -49,9 +50,9 @@ static tree interpret_float (const cpp_token *, unsigned int, const char *,
 			     enum overflow_type *);
 static tree interpret_fixed (const cpp_token *, unsigned int);
 static enum integer_type_kind narrowest_unsigned_type
-	(unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, unsigned int);
+	(const widest_int &, unsigned int);
 static enum integer_type_kind narrowest_signed_type
-	(unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, unsigned int);
+	(const widest_int &, unsigned int);
 static enum cpp_ttype lex_string (const cpp_token *, tree *, bool, bool);
 static tree lex_charconst (const cpp_token *);
 static void update_header_times (const char *);
@@ -527,9 +528,7 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
    there isn't one.  */
 
 static enum integer_type_kind
-narrowest_unsigned_type (unsigned HOST_WIDE_INT low,
-			 unsigned HOST_WIDE_INT high,
-			 unsigned int flags)
+narrowest_unsigned_type (const widest_int &val, unsigned int flags)
 {
   int itk;
 
@@ -548,9 +547,7 @@ narrowest_unsigned_type (unsigned HOST_WIDE_INT low,
 	continue;
       upper = TYPE_MAX_VALUE (integer_types[itk]);
 
-      if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) > high
-	  || ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) == high
-	      && TREE_INT_CST_LOW (upper) >= low))
+      if (wi::geu_p (wi::to_widest (upper), val))
 	return (enum integer_type_kind) itk;
     }
 
@@ -559,8 +556,7 @@ narrowest_unsigned_type (unsigned HOST_WIDE_INT low,
 
 /* Ditto, but narrowest signed type.  */
 static enum integer_type_kind
-narrowest_signed_type (unsigned HOST_WIDE_INT low,
-		       unsigned HOST_WIDE_INT high, unsigned int flags)
+narrowest_signed_type (const widest_int &val, unsigned int flags)
 {
   int itk;
 
@@ -571,7 +567,6 @@ narrowest_signed_type (unsigned HOST_WIDE_INT low,
   else
     itk = itk_long_long;
 
-
   for (; itk < itk_none; itk += 2 /* skip signed types */)
     {
       tree upper;
@@ -580,9 +575,7 @@ narrowest_signed_type (unsigned HOST_WIDE_INT low,
 	continue;
       upper = TYPE_MAX_VALUE (integer_types[itk]);
 
-      if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) > high
-	  || ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) == high
-	      && TREE_INT_CST_LOW (upper) >= low))
+      if (wi::geu_p (wi::to_widest (upper), val))
 	return (enum integer_type_kind) itk;
     }
 
@@ -597,6 +590,7 @@ interpret_integer (const cpp_token *token, unsigned int flags,
   tree value, type;
   enum integer_type_kind itk;
   cpp_num integer;
+  HOST_WIDE_INT ival[3];
 
   *overflow = OT_NONE;
 
@@ -604,18 +598,23 @@ interpret_integer (const cpp_token *token, unsigned int flags,
   if (integer.overflow)
     *overflow = OT_OVERFLOW;
 
+  ival[0] = integer.low;
+  ival[1] = integer.high;
+  ival[2] = 0;
+  widest_int wval = widest_int::from_array (ival, 3);
+
   /* The type of a constant with a U suffix is straightforward.  */
   if (flags & CPP_N_UNSIGNED)
-    itk = narrowest_unsigned_type (integer.low, integer.high, flags);
+    itk = narrowest_unsigned_type (wval, flags);
   else
     {
       /* The type of a potentially-signed integer constant varies
 	 depending on the base it's in, the standard in use, and the
 	 length suffixes.  */
       enum integer_type_kind itk_u
-	= narrowest_unsigned_type (integer.low, integer.high, flags);
+	= narrowest_unsigned_type (wval, flags);
       enum integer_type_kind itk_s
-	= narrowest_signed_type (integer.low, integer.high, flags);
+	= narrowest_signed_type (wval, flags);
 
       /* In both C89 and C99, octal and hex constants may be signed or
 	 unsigned, whichever fits tighter.  We do not warn about this
@@ -667,7 +666,7 @@ interpret_integer (const cpp_token *token, unsigned int flags,
 	   : "integer constant is too large for %<long%> type");
     }
 
-  value = build_int_cst_wide (type, integer.low, integer.high);
+  value = wide_int_to_tree (type, wval);
 
   /* Convert imaginary to a complex type.  */
   if (flags & CPP_N_IMAGINARY)
@@ -1165,9 +1164,9 @@ lex_charconst (const cpp_token *token)
   /* Cast to cppchar_signed_t to get correct sign-extension of RESULT
      before possibly widening to HOST_WIDE_INT for build_int_cst.  */
   if (unsignedp || (cppchar_signed_t) result >= 0)
-    value = build_int_cst_wide (type, result, 0);
+    value = build_int_cst (type, result);
   else
-    value = build_int_cst_wide (type, (cppchar_signed_t) result, -1);
+    value = build_int_cst (type, (cppchar_signed_t) result);
 
   return value;
 }
diff --git a/gcc/c-family/c-pretty-print.c b/gcc/c-family/c-pretty-print.c
index d1b5880..bd3b381 100644
--- a/gcc/c-family/c-pretty-print.c
+++ b/gcc/c-family/c-pretty-print.c
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-pretty-print.h"
 #include "tree-iterator.h"
 #include "diagnostic.h"
+#include "wide-int-print.h"
 
 /* The pretty-printer code is primarily designed to closely follow
    (GNU) C and C++ grammars.  That is to be contrasted with spaghetti
@@ -923,16 +924,14 @@ pp_c_integer_constant (c_pretty_printer *pp, tree i)
     pp_unsigned_wide_integer (pp, tree_to_uhwi (i));
   else
     {
-      unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (i);
-      HOST_WIDE_INT high = TREE_INT_CST_HIGH (i);
-      if (tree_int_cst_sgn (i) < 0)
+      wide_int wi = i;
+
+      if (wi::lt_p (i, 0, TYPE_SIGN (TREE_TYPE (i))))
 	{
 	  pp_minus (pp);
-	  high = ~high + !low;
-	  low = -low;
+	  wi = -wi;
 	}
-      sprintf (pp_buffer (pp)->digit_buffer, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
-	       (unsigned HOST_WIDE_INT) high, (unsigned HOST_WIDE_INT) low);
+      print_hex (wi, pp_buffer (pp)->digit_buffer);
       pp_string (pp, pp_buffer (pp)->digit_buffer);
     }
   if (TYPE_UNSIGNED (type))
diff --git a/gcc/c-family/cilk.c b/gcc/c-family/cilk.c
index 894a352..a663c45 100644
--- a/gcc/c-family/cilk.c
+++ b/gcc/c-family/cilk.c
@@ -665,8 +665,7 @@ declare_one_free_variable (const void *var0, void **map0,
 
   /* Maybe promote to int.  */
   if (INTEGRAL_TYPE_P (var_type) && COMPLETE_TYPE_P (var_type)
-      && INT_CST_LT_UNSIGNED (TYPE_SIZE (var_type),
-			      TYPE_SIZE (integer_type_node)))
+      && INT_CST_LT (TYPE_SIZE (var_type), TYPE_SIZE (integer_type_node)))
     arg_type = integer_type_node;
   else
     arg_type = var_type;
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 4125bd9..d2d54b0 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -4843,8 +4843,8 @@ check_bitfield_type_and_width (tree *type, tree *width, tree orig_name)
     {
       struct lang_type *lt = TYPE_LANG_SPECIFIC (*type);
       if (!lt
-	  || w < tree_int_cst_min_precision (lt->enum_min, TYPE_UNSIGNED (*type))
-	  || w < tree_int_cst_min_precision (lt->enum_max, TYPE_UNSIGNED (*type)))
+	  || w < tree_int_cst_min_precision (lt->enum_min, TYPE_SIGN (*type))
+	  || w < tree_int_cst_min_precision (lt->enum_max, TYPE_SIGN (*type)))
 	warning (0, "%qs is narrower than values of its type", name);
     }
 }
@@ -7565,7 +7565,8 @@ finish_enum (tree enumtype, tree values, tree attributes)
 {
   tree pair, tem;
   tree minnode = 0, maxnode = 0;
-  int precision, unsign;
+  int precision;
+  signop sign;
   bool toplevel = (file_scope == current_scope);
   struct lang_type *lt;
 
@@ -7592,13 +7593,13 @@ finish_enum (tree enumtype, tree values, tree attributes)
      as one of the integral types - the narrowest one that fits, except
      that normally we only go as narrow as int - and signed iff any of
      the values are negative.  */
-  unsign = (tree_int_cst_sgn (minnode) >= 0);
-  precision = MAX (tree_int_cst_min_precision (minnode, unsign),
-		   tree_int_cst_min_precision (maxnode, unsign));
+  sign = (tree_int_cst_sgn (minnode) >= 0) ? UNSIGNED : SIGNED;
+  precision = MAX (tree_int_cst_min_precision (minnode, sign),
+		   tree_int_cst_min_precision (maxnode, sign));
 
   if (TYPE_PACKED (enumtype) || precision > TYPE_PRECISION (integer_type_node))
     {
-      tem = c_common_type_for_size (precision, unsign);
+      tem = c_common_type_for_size (precision, sign == UNSIGNED ? 1 : 0);
       if (tem == NULL)
 	{
 	  warning (0, "enumeration values exceed range of largest integer");
@@ -7606,7 +7607,7 @@ finish_enum (tree enumtype, tree values, tree attributes)
 	}
     }
   else
-    tem = unsign ? unsigned_type_node : integer_type_node;
+    tem = sign == UNSIGNED ? unsigned_type_node : integer_type_node;
 
   TYPE_MIN_VALUE (enumtype) = TYPE_MIN_VALUE (tem);
   TYPE_MAX_VALUE (enumtype) = TYPE_MAX_VALUE (tem);
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index ea3aa9a..d08d1d0 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -13380,7 +13380,7 @@ c_parser_cilk_clause_vectorlength (c_parser *parser, tree clauses)
       || !TREE_CONSTANT (expr)
       || !INTEGRAL_TYPE_P (TREE_TYPE (expr)))
     error_at (loc, "vectorlength must be an integer constant");
-  else if (exact_log2 (TREE_INT_CST_LOW (expr)) == -1)
+  else if (wi::exact_log2 (expr) == -1)
     error_at (loc, "vectorlength must be a power of 2");
   else
     {
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 8e74b7b..7a0d664 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "c-family/c-objc.h"
 #include "c-family/c-common.h"
 #include "c-family/c-ubsan.h"
+#include "wide-int.h"
 
 /* Possible cases of implicit bad conversions.  Used to select
    diagnostic messages in convert_for_assignment.  */
@@ -5098,9 +5099,7 @@ build_c_cast (location_t loc, tree type, tree expr)
 	    }
 	  else if (TREE_OVERFLOW (value))
 	    /* Reset VALUE's overflow flags, ensuring constant sharing.  */
-	    value = build_int_cst_wide (TREE_TYPE (value),
-					TREE_INT_CST_LOW (value),
-					TREE_INT_CST_HIGH (value));
+	    value = wide_int_to_tree (TREE_TYPE (value), value);
 	}
     }
 
@@ -8013,20 +8012,20 @@ set_nonincremental_init_from_string (tree str,
     {
       if (wchar_bytes == 1)
 	{
-	  val[1] = (unsigned char) *p++;
-	  val[0] = 0;
+	  val[0] = (unsigned char) *p++;
+	  val[1] = 0;
 	}
       else
 	{
-	  val[0] = 0;
 	  val[1] = 0;
+	  val[0] = 0;
 	  for (byte = 0; byte < wchar_bytes; byte++)
 	    {
 	      if (BYTES_BIG_ENDIAN)
 		bitpos = (wchar_bytes - byte - 1) * charwidth;
 	      else
 		bitpos = byte * charwidth;
-	      val[bitpos < HOST_BITS_PER_WIDE_INT]
+	      val[bitpos % HOST_BITS_PER_WIDE_INT]
 		|= ((unsigned HOST_WIDE_INT) ((unsigned char) *p++))
 		   << (bitpos % HOST_BITS_PER_WIDE_INT);
 	    }
@@ -8037,24 +8036,26 @@ set_nonincremental_init_from_string (tree str,
 	  bitpos = ((wchar_bytes - 1) * charwidth) + HOST_BITS_PER_CHAR;
 	  if (bitpos < HOST_BITS_PER_WIDE_INT)
 	    {
-	      if (val[1] & (((HOST_WIDE_INT) 1) << (bitpos - 1)))
+	      if (val[0] & (((HOST_WIDE_INT) 1) << (bitpos - 1)))
 		{
-		  val[1] |= ((HOST_WIDE_INT) -1) << bitpos;
-		  val[0] = -1;
+		  val[0] |= ((HOST_WIDE_INT) -1) << bitpos;
+		  val[1] = -1;
 		}
 	    }
 	  else if (bitpos == HOST_BITS_PER_WIDE_INT)
 	    {
-	      if (val[1] < 0)
-		val[0] = -1;
+	      if (val[0] < 0)
+		val[1] = -1;
 	    }
-	  else if (val[0] & (((HOST_WIDE_INT) 1)
+	  else if (val[1] & (((HOST_WIDE_INT) 1)
 			     << (bitpos - 1 - HOST_BITS_PER_WIDE_INT)))
-	    val[0] |= ((HOST_WIDE_INT) -1)
+	    val[1] |= ((HOST_WIDE_INT) -1)
 		      << (bitpos - HOST_BITS_PER_WIDE_INT);
 	}
 
-      value = build_int_cst_wide (type, val[1], val[0]);
+      value = wide_int_to_tree (type,
+				wide_int::from_array (val, 2,
+						      HOST_BITS_PER_WIDE_INT * 2));
       add_pending_init (purpose, value, NULL_TREE, true,
                         braced_init_obstack);
     }
@@ -12257,8 +12258,7 @@ c_tree_equal (tree t1, tree t2)
   switch (code1)
     {
     case INTEGER_CST:
-      return TREE_INT_CST_LOW (t1) == TREE_INT_CST_LOW (t2)
-	&& TREE_INT_CST_HIGH (t1) == TREE_INT_CST_HIGH (t2);
+      return wi::eq_p (t1, t2);
 
     case REAL_CST:
       return REAL_VALUES_EQUAL (TREE_REAL_CST (t1), TREE_REAL_CST (t2));

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2014-01-02 16:50 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-23 21:09 wide-int, C++ front end Mike Stump
2013-11-24 12:57 ` Jason Merrill
2013-11-25 22:27   ` Kenneth Zadeck
2013-11-25 23:10   ` Richard Sandiford
2013-11-26  0:31     ` Jason Merrill
2013-11-26 10:52     ` Richard Biener
2014-01-02  2:41       ` Mike Stump
2014-01-02 16:50         ` Jason Merrill
  -- strict thread matches above, loose matches on Subject: below --
2013-11-23 19:23 wide-int, c " Mike Stump
2013-11-25 18:31 ` Joseph S. Myers

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).