This patch replaces all instances of INT_CST_LT and INT_CST_LT_UNSIGNED
with
the new functions tree_int_cst_lts_p and tree_int_cst_ltu_p. With the
new implementation of int_cst these functions will be too big to do inline.
This is a small patch that has no prerequisites.
Tested on x86-64.
kenny
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 930d5e5..5f235fb 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -3902,17 +3902,17 @@ shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr,
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);
+ min_gt = tree_int_cst_ltu_p (primop1, minval);
+ max_gt = tree_int_cst_ltu_p (primop1, maxval);
+ min_lt = tree_int_cst_ltu_p (minval, primop1);
+ max_lt = tree_int_cst_ltu_p (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 = tree_int_cst_lts_p (primop1, minval);
+ max_gt = tree_int_cst_lts_p (primop1, maxval);
+ min_lt = tree_int_cst_lts_p (minval, primop1);
+ max_lt = tree_int_cst_lts_p (maxval, primop1);
}
val = 0;
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index f888d32..2ee6eca 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -6317,8 +6317,8 @@ 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)))
+ && tree_int_cst_ltu_p (TYPE_SIZE (type),
+ TYPE_SIZE (integer_type_node)))
type = integer_type_node;
return type;
@@ -6358,8 +6358,8 @@ 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)))
+ && tree_int_cst_ltu_p (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 c62a33e..8183e85 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -3427,7 +3427,7 @@ walk_subobject_offsets (tree type,
/* If this OFFSET is bigger than the MAX_OFFSET, then we should
stop. */
- if (max_offset && INT_CST_LT (max_offset, offset))
+ if (max_offset && tree_int_cst_lts_p (max_offset, offset))
return 0;
if (type == error_mark_node)
@@ -3582,8 +3582,8 @@ walk_subobject_offsets (tree type,
for (index = size_zero_node;
/* G++ 3.2 had an off-by-one error here. */
(abi_version_at_least (2)
- ? !INT_CST_LT (TYPE_MAX_VALUE (domain), index)
- : INT_CST_LT (index, TYPE_MAX_VALUE (domain)));
+ ? !tree_int_cst_lts_p (TYPE_MAX_VALUE (domain), index)
+ : tree_int_cst_lts_p (index, TYPE_MAX_VALUE (domain)));
index = size_binop (PLUS_EXPR, index, size_one_node))
{
r = walk_subobject_offsets (TREE_TYPE (type),
@@ -3599,7 +3599,7 @@ walk_subobject_offsets (tree type,
/* If this new OFFSET is bigger than the MAX_OFFSET, then
there's no point in iterating through the remaining
elements of the array. */
- if (max_offset && INT_CST_LT (max_offset, offset))
+ if (max_offset && tree_int_cst_lts_p (max_offset, offset))
break;
}
}
@@ -5432,7 +5432,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 (tree_int_cst_ltu_p (result, offset))
result = offset;
}
@@ -5442,7 +5442,7 @@ end_of_class (tree t, int include_virtuals_p)
VEC_iterate (tree, vbases, i, base_binfo); i++)
{
offset = end_of_base (base_binfo);
- if (INT_CST_LT_UNSIGNED (result, offset))
+ if (tree_int_cst_ltu_p (result, offset))
result = offset;
}
@@ -5522,7 +5522,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))
+ && tree_int_cst_ltu_p (rli_size, eoc))
{
if (!abi_version_at_least (2))
/* In version 1 of the ABI, the size of a class that ends with
@@ -5638,7 +5638,7 @@ layout_class_type (tree t, tree *virtuals_p)
type, then there are some special rules for allocating
it. */
if (DECL_C_BIT_FIELD (field)
- && INT_CST_LT (TYPE_SIZE (type), DECL_SIZE (field)))
+ && tree_int_cst_lts_p (TYPE_SIZE (type), DECL_SIZE (field)))
{
unsigned int itk;
tree integer_type;
@@ -5649,10 +5649,10 @@ layout_class_type (tree t, tree *virtuals_p)
bits as additional padding. */
for (itk = itk_char; itk != itk_none; ++itk)
if (integer_types[itk] != NULL_TREE
- && (INT_CST_LT (size_int (MAX_FIXED_MODE_SIZE),
- TYPE_SIZE (integer_types[itk]))
- || INT_CST_LT (DECL_SIZE (field),
- TYPE_SIZE (integer_types[itk]))))
+ && (tree_int_cst_lts_p (size_int (MAX_FIXED_MODE_SIZE),
+ TYPE_SIZE (integer_types[itk]))
+ || tree_int_cst_lts_p (DECL_SIZE (field),
+ TYPE_SIZE (integer_types[itk]))))
break;
/* ITK now indicates a type that is too large for the
@@ -5668,7 +5668,7 @@ layout_class_type (tree t, tree *virtuals_p)
3.2 always created a padding field, even if it had zero
width. */
if (!abi_version_at_least (2)
- || INT_CST_LT (TYPE_SIZE (integer_type), DECL_SIZE (field)))
+ || tree_int_cst_lts_p (TYPE_SIZE (integer_type), DECL_SIZE (field)))
{
if (abi_version_at_least (2) && TREE_CODE (t) == UNION_TYPE)
/* In a union, the padding field must have the full width
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 368d738..ce852ac 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -8075,7 +8075,7 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
constant_expression_error (size);
/* An array must have a positive number of elements. */
- if (INT_CST_LT (size, integer_zero_node))
+ if (tree_int_cst_lts_p (size, integer_zero_node))
{
if (!(complain & tf_error))
return error_mark_node;
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 03eeac2..20fd53c 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -16118,10 +16118,8 @@ fold_relational_const (enum tree_code code, tree type, tree op0, tree op1)
{
if (code == EQ_EXPR)
result = tree_int_cst_equal (op0, op1);
- else if (TYPE_UNSIGNED (TREE_TYPE (op0)))
- result = INT_CST_LT_UNSIGNED (op0, op1);
- else
- result = INT_CST_LT (op0, op1);
+ else
+ result = tree_int_cst_lt (op0, op1);
}
else
return NULL_TREE;
diff --git a/gcc/java/expr.c b/gcc/java/expr.c
index 055d3a6..8f8c928 100644
--- a/gcc/java/expr.c
+++ b/gcc/java/expr.c
@@ -1716,7 +1716,7 @@ build_field_ref (tree self_value, tree self_class, tree name)
tree field_offset = byte_position (field_decl);
if (! page_size)
page_size = size_int (4096);
- check = ! INT_CST_LT_UNSIGNED (field_offset, page_size);
+ check = ! tree_int_cst_ltu_p (field_offset, page_size);
}
if (base_type != TREE_TYPE (self_value))
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index 0d7f3e4..8837bda 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -290,7 +290,7 @@ default_cxx_get_cookie_size (tree type)
sizetype_size = size_in_bytes (sizetype);
type_align = size_int (TYPE_ALIGN_UNIT (type));
- if (INT_CST_LT_UNSIGNED (type_align, sizetype_size))
+ if (tree_int_cst_ltu_p (type_align, sizetype_size))
cookie_size = sizetype_size;
else
cookie_size = type_align;
diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c
index cc58870..14df6e2 100644
--- a/gcc/tree-ssa-uninit.c
+++ b/gcc/tree-ssa-uninit.c
@@ -699,12 +699,12 @@ is_value_included_in (tree val, tree boundary, enum tree_code cmpc)
if (cmpc == EQ_EXPR)
result = tree_int_cst_equal (val, boundary);
else if (cmpc == LT_EXPR)
- result = INT_CST_LT_UNSIGNED (val, boundary);
+ result = tree_int_cst_ltu_p (val, boundary);
else
{
gcc_assert (cmpc == LE_EXPR);
result = (tree_int_cst_equal (val, boundary)
- || INT_CST_LT_UNSIGNED (val, boundary));
+ || tree_int_cst_ltu_p (val, boundary));
}
}
else
@@ -712,12 +712,12 @@ is_value_included_in (tree val, tree boundary, enum tree_code cmpc)
if (cmpc == EQ_EXPR)
result = tree_int_cst_equal (val, boundary);
else if (cmpc == LT_EXPR)
- result = INT_CST_LT (val, boundary);
+ result = tree_int_cst_lts_p (val, boundary);
else
{
gcc_assert (cmpc == LE_EXPR);
result = (tree_int_cst_equal (val, boundary)
- || INT_CST_LT (val, boundary));
+ || tree_int_cst_lts_p (val, boundary));
}
}
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index b75d85a..9003ac5 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -1117,10 +1117,10 @@ operand_less_p (tree val, tree val2)
if (TREE_CODE (val) == INTEGER_CST && TREE_CODE (val2) == INTEGER_CST)
{
if (TYPE_UNSIGNED (TREE_TYPE (val)))
- return INT_CST_LT_UNSIGNED (val, val2);
+ return tree_int_cst_ltu_p (val, val2);
else
{
- if (INT_CST_LT (val, val2))
+ if (tree_int_cst_lts_p (val, val2))
return 1;
}
}
diff --git a/gcc/tree.c b/gcc/tree.c
index d85f9a6..84f2cbc 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -1085,6 +1085,31 @@ wide_int_to_tree (tree type, const wide_int &cst)
return build_int_cst_wide (type, v.elt (0), v.elt (1));
}
+/* Return 0 or -1 depending on the sign of the cst. */
+
+HOST_WIDE_INT
+int_cst_sign_mask (const_tree op0, int prec)
+{
+ int rec = prec / HOST_BITS_PER_WIDE_INT;
+
+ prec = prec % HOST_BITS_PER_WIDE_INT;
+
+#ifdef NEW_REP_FOR_INT_CST
+ if (rec > TREE_INT_CST_LEN (op0) - 1)
+ rec = TREE_INT_CST_LEN (op0) - 1;
+
+ return (TREE_INT_CST_ELT (op0, rec) << (HOST_BITS_PER_WIDE_INT - prec))
+ >> (HOST_BITS_PER_WIDE_INT - 1);
+#else
+ if (rec)
+ return ((HOST_WIDE_INT)TREE_INT_CST_HIGH (op0) << (HOST_BITS_PER_WIDE_INT - prec))
+ >> (HOST_BITS_PER_WIDE_INT - 1);
+ else
+ return ((HOST_WIDE_INT)TREE_INT_CST_LOW (op0) << (HOST_BITS_PER_WIDE_INT - prec))
+ >> (HOST_BITS_PER_WIDE_INT - 1);
+#endif
+}
+
/* Returns true if CST fits into range of TYPE. Signedness of CST is assumed
to be the same as the signedness of TYPE. */
@@ -1100,6 +1125,102 @@ double_int_fits_to_tree_p (const_tree type, double_int cst)
return cst == ext;
}
+/* Return true if OP0 < OP1 using signed comparisons. */
+
+bool
+tree_int_cst_lts_p (const_tree op0, const_tree op1)
+{
+#ifdef NEW_REP_FOR_INT_CST
+ int l0 = TREE_INT_CST_NUNITS (op0) - 1;
+ int l1 = TREE_INT_CST_NUNITS (op1) - 1;
+ int prec = TYPE_PRECISION (TREE_TYPE (op0));
+
+ if (op0 == op1)
+ return false;
+
+ if (prec <= HOST_BITS_PER_WIDE_INT)
+ /* The values are already logically sign extended. */
+ return TREE_INT_CST_ELT (op0, 0) < TREE_INT_CST_ELT (op1, 0);
+
+ while (l0 > l1)
+ if (TREE_INT_CST_ELT (op0, l0--) < int_cst_sign_mask (op1, prec))
+ return true;
+
+ while (l1 > l0)
+ if (int_cst_sign_mask (op0, prec) < TREE_INT_CST_ELT (op1, l1--))
+ return true;
+
+ while (l0 >= 0)
+ if (TREE_INT_CST_ELT (op0, l0--) < TREE_INT_CST_ELT (op1, l1--))
+ return true;
+
+ return false;
+#else
+ return (TREE_INT_CST_HIGH (op0) < TREE_INT_CST_HIGH (op1)
+ || (TREE_INT_CST_HIGH (op0) == TREE_INT_CST_HIGH (op1)
+ && TREE_INT_CST_LOW (op0) < TREE_INT_CST_LOW (op1)));
+#endif
+}
+
+
+/* Return true if OP0 < OP1 using unsigned comparisons. */
+
+bool
+tree_int_cst_ltu_p (const_tree op0, const_tree op1)
+{
+#ifdef NEW_REP_FOR_INT_CST
+ unsigned HOST_WIDE_INT x0;
+ unsigned HOST_WIDE_INT x1;
+ int l0 = TREE_INT_CST_NUNITS (op0) - 1;
+ int l1 = TREE_INT_CST_NUNITS (op1) - 1;
+ int prec = TYPE_PRECISION (TREE_TYPE (op0));
+
+ if (op0 == op1)
+ return false;
+
+ if (prec < HOST_BITS_PER_WIDE_INT)
+ {
+ x0 = wide_int::zext (TREE_INT_CST_ELT (op0, 0), prec);
+ x1 = wide_int::zext (TREE_INT_CST_ELT (op1, 0), prec);
+
+ return x0 < x1;
+ }
+
+ while (l0 > l1)
+ {
+ x0 = TREE_INT_CST_ELT (op0, l0--);
+ x1 = int_cst_sign_mask (op1, prec);
+ if (x0 < x1)
+ return true;
+ }
+
+ while (l1 > l0)
+ {
+ x0 = int_cst_sign_mask (op0, prec);
+ x1 = TREE_INT_CST_ELT (op1, l1--);
+ if (x0 < x1)
+ return true;
+ }
+
+ while (l0 >= 0)
+ {
+ x0 = TREE_INT_CST_ELT (op0, l0--);
+ x1 = TREE_INT_CST_ELT (op1, l1--);
+ if (x0 < x1)
+ return true;
+ }
+
+ return false;
+#else
+ return (((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (op0)
+ < (unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (op1))
+ || (((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (op0)
+ == (unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (op1))
+ && TREE_INT_CST_LOW (op0) < TREE_INT_CST_LOW (op1)));
+#endif
+}
+
+
/* We force the double_int CST to the range of the type TYPE by sign or
zero extending it. OVERFLOWABLE indicates if we are interested in
overflow of the value, when >0 we are only interested in signed
@@ -6513,9 +6634,9 @@ tree_int_cst_lt (const_tree t1, const_tree t2)
type. */
}
else if (!TYPE_UNSIGNED (TREE_TYPE (t1)))
- return INT_CST_LT (t1, t2);
+ return tree_int_cst_lts_p (t1, t2);
- return INT_CST_LT_UNSIGNED (t1, t2);
+ return tree_int_cst_ltu_p (t1, t2);
}
/* Returns -1 if T1 < T2, 0 if T1 == T2, and 1 if T1 > T2. */
diff --git a/gcc/tree.h b/gcc/tree.h
index c9c5869..f5497cd 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1402,18 +1402,6 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
#define TREE_INT_CST_LOW(NODE) (TREE_INT_CST (NODE).low)
#define TREE_INT_CST_HIGH(NODE) (TREE_INT_CST (NODE).high)
-#define INT_CST_LT(A, B) \
- (TREE_INT_CST_HIGH (A) < TREE_INT_CST_HIGH (B) \
- || (TREE_INT_CST_HIGH (A) == TREE_INT_CST_HIGH (B) \
- && TREE_INT_CST_LOW (A) < TREE_INT_CST_LOW (B)))
-
-#define INT_CST_LT_UNSIGNED(A, B) \
- (((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (A) \
- < (unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (B)) \
- || (((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (A) \
- == (unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (B)) \
- && TREE_INT_CST_LOW (A) < TREE_INT_CST_LOW (B)))
-
struct GTY(()) tree_int_cst {
struct tree_typed typed;
double_int int_cst;
@@ -5689,6 +5677,9 @@ extern const_tree strip_invariant_refs (const_tree);
extern tree lhd_gcc_personality (void);
extern void assign_assembler_name_if_neeeded (tree);
extern void warn_deprecated_use (tree, tree);
+extern HOST_WIDE_INT int_cst_sign_mask (const_tree, int);
+extern bool tree_int_cst_lts_p (const_tree, const_tree);
+extern bool tree_int_cst_ltu_p (const_tree, const_tree);
/* In cgraph.c */
2012-10-18 Kenneth Zadeck <zad...@naturalbridge.com>
* c-family/c-common.c (shorten_compare): Now uses
tree_int_cst_ltu_p and tree_int_cst_lts_p.
* cp/call.c (type_passed_as, convert_for_arg_passing): Ditto.
* cp/class.c (walk_subobject_offsets, walk_subobject_offsets,
end_of_class, include_empty_classes, layout_class_type): Ditto.
* cp/decl.c (compute_array_index_type): Ditto.
* fold-const.c (fold_relational_const): Ditto.
* java/expr.c (build_field_ref): Ditto.
* targhooks.c (default_cxx_get_cookie_size): Ditto.
* tree-ssa-uninit.c (is_value_included_in): Ditto.
* tree-vrp.c (operand_less_p): Ditto.
* tree.c (tree_int_cst_lt): Ditto.
(int_cst_sign_mask, tree_int_cst_lts_p)
(tree_int_cst_ltu_p): New functions.
* tree.h (INT_CST_LT, INT_CST_LT_UNSIGNED): Remove.