* 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).