summaryrefslogtreecommitdiff
path: root/gcc/tree.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree.h')
-rw-r--r--gcc/tree.h289
1 files changed, 228 insertions, 61 deletions
diff --git a/gcc/tree.h b/gcc/tree.h
index 94f112f43d7..8a665346c17 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -469,7 +469,7 @@ struct GTY(()) tree_base {
/* The following fields are present in tree_base to save space. The
nodes using them do not require any of the flags above and so can
make better use of the 4-byte sized word. */
- /* VEC length. This field is only used with TREE_VEC. */
+ /* VEC length. This field is only used with TREE_VEC and TREE_INT_CST. */
int length;
/* SSA version number. This field is only used with SSA_NAME. */
unsigned int version;
@@ -735,6 +735,8 @@ enum tree_node_structure_enum {
};
#undef DEFTREESTRUCT
+#define NULL_TREE (tree) NULL
+
/* Define accessors for the fields that all tree nodes have
(though some fields are not used for all kinds of nodes). */
@@ -806,6 +808,9 @@ enum tree_node_structure_enum {
#define NON_TYPE_CHECK(T) \
(non_type_check ((T), __FILE__, __LINE__, __FUNCTION__))
+#define TREE_INT_CST_ELT_CHECK(T, I) \
+(*tree_int_cst_elt_check ((T), (I), __FILE__, __LINE__, __FUNCTION__))
+
#define TREE_VEC_ELT_CHECK(T, I) \
(*(CONST_CAST2 (tree *, typeof (T)*, \
tree_vec_elt_check ((T), (I), __FILE__, __LINE__, __FUNCTION__))))
@@ -861,6 +866,9 @@ extern void tree_not_class_check_failed (const_tree,
const enum tree_code_class,
const char *, int, const char *)
ATTRIBUTE_NORETURN;
+extern void tree_int_cst_elt_check_failed (int, int, const char *,
+ int, const char *)
+ ATTRIBUTE_NORETURN;
extern void tree_vec_elt_check_failed (int, int, const char *,
int, const char *)
ATTRIBUTE_NORETURN;
@@ -898,6 +906,7 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
#define TREE_RANGE_CHECK(T, CODE1, CODE2) (T)
#define EXPR_CHECK(T) (T)
#define NON_TYPE_CHECK(T) (T)
+#define TREE_INT_CST_ELT_CHECK(T, I) ((T)->int_cst.val[I])
#define TREE_VEC_ELT_CHECK(T, I) ((T)->vec.a[I])
#define TREE_OPERAND_CHECK(T, I) ((T)->exp.operands[I])
#define TREE_OPERAND_CHECK_CODE(T, CODE, I) ((T)->exp.operands[I])
@@ -1123,7 +1132,7 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
#define SET_PREDICT_EXPR_OUTCOME(NODE, OUTCOME) \
(PREDICT_EXPR_CHECK(NODE)->base.addressable_flag = (int) OUTCOME)
#define PREDICT_EXPR_PREDICTOR(NODE) \
- ((enum br_predictor)tree_low_cst (TREE_OPERAND (PREDICT_EXPR_CHECK (NODE), 0), 0))
+ ((enum br_predictor)tree_to_shwi (TREE_OPERAND (PREDICT_EXPR_CHECK (NODE), 0)))
/* In a VAR_DECL, nonzero means allocate static storage.
In a FUNCTION_DECL, nonzero if function has been defined.
@@ -1267,6 +1276,9 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
/* In integral and pointer types, means an unsigned type. */
#define TYPE_UNSIGNED(NODE) (TYPE_CHECK (NODE)->base.u.bits.unsigned_flag)
+/* Same as TYPE_UNSIGNED but converted to SIGNOP. */
+#define TYPE_SIGN(NODE) ((signop)TYPE_UNSIGNED(NODE))
+
/* True if overflow wraps around for the given integral type. That
is, TYPE_MAX + 1 == TYPE_MIN. */
#define TYPE_OVERFLOW_WRAPS(TYPE) \
@@ -1398,29 +1410,18 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
/* Define additional fields and accessors for nodes representing constants. */
-/* In an INTEGER_CST node. These two together make a 2-word integer.
- If the data type is signed, the value is sign-extended to 2 words
- even though not all of them may really be in use.
- In an unsigned constant shorter than 2 words, the extra bits are 0. */
-#define TREE_INT_CST(NODE) (INTEGER_CST_CHECK (NODE)->int_cst.int_cst)
-#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)))
+ (wide_int::lts_p (A, B))
+
+#define INT_CST_LT_UNSIGNED(A, B) \
+ (wide_int::ltu_p (A, 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)))
+#define TREE_INT_CST_NUNITS(NODE) (INTEGER_CST_CHECK (NODE)->base.u.length)
+#define TREE_INT_CST_ELT(NODE, I) TREE_INT_CST_ELT_CHECK (NODE, I)
struct GTY(()) tree_int_cst {
struct tree_typed typed;
- double_int int_cst;
+ HOST_WIDE_INT val[1];
};
/* In a REAL_CST node. struct real_value is an opaque entity, with
@@ -1605,7 +1606,7 @@ struct GTY(()) tree_constructor {
Note that we have to bypass the use of TREE_OPERAND to access
that field to avoid infinite recursion in expanding the macros. */
#define VL_EXP_OPERAND_LENGTH(NODE) \
- ((int)TREE_INT_CST_LOW (VL_EXP_CHECK (NODE)->exp.operands[0]))
+ ((int)tree_to_hwi (VL_EXP_CHECK (NODE)->exp.operands[0]))
/* Nonzero if is_gimple_debug() may possibly hold. */
#define MAY_HAVE_DEBUG_STMTS (flag_var_tracking_assignments)
@@ -1707,7 +1708,7 @@ extern void protected_set_expr_location (tree, location_t);
#define CHREC_VAR(NODE) TREE_OPERAND (POLYNOMIAL_CHREC_CHECK (NODE), 0)
#define CHREC_LEFT(NODE) TREE_OPERAND (POLYNOMIAL_CHREC_CHECK (NODE), 1)
#define CHREC_RIGHT(NODE) TREE_OPERAND (POLYNOMIAL_CHREC_CHECK (NODE), 2)
-#define CHREC_VARIABLE(NODE) TREE_INT_CST_LOW (CHREC_VAR (NODE))
+#define CHREC_VARIABLE(NODE) tree_to_hwi (CHREC_VAR (NODE))
/* LABEL_EXPR accessor. This gives access to the label associated with
the given label expression. */
@@ -3870,6 +3871,28 @@ non_type_check (tree __t, const char *__f, int __l, const char *__g)
return __t;
}
+inline const HOST_WIDE_INT *
+tree_int_cst_elt_check (const_tree __t, int __i,
+ const char *__f, int __l, const char *__g)
+{
+ if (TREE_CODE (__t) != INTEGER_CST)
+ tree_check_failed (__t, __f, __l, __g, INTEGER_CST, 0);
+ if (__i < 0 || __i >= __t->base.u.length)
+ tree_int_cst_elt_check_failed (__i, __t->base.u.length, __f, __l, __g);
+ return &CONST_CAST_TREE (__t)->int_cst.val[__i];
+}
+
+inline HOST_WIDE_INT *
+tree_int_cst_elt_check (tree __t, int __i,
+ const char *__f, int __l, const char *__g)
+{
+ if (TREE_CODE (__t) != INTEGER_CST)
+ tree_check_failed (__t, __f, __l, __g, INTEGER_CST, 0);
+ if (__i < 0 || __i >= __t->base.u.length)
+ tree_int_cst_elt_check_failed (__i, __t->base.u.length, __f, __l, __g);
+ return &CONST_CAST_TREE (__t)->int_cst.val[__i];
+}
+
inline tree *
tree_vec_elt_check (tree __t, int __i,
const char *__f, int __l, const char *__g)
@@ -4101,6 +4124,174 @@ omp_clause_elt_check (const_tree __t, int __i,
#endif
+/* Checks that X is integer constant that can be expressed in signed
+ HOST_WIDE_INT without loss of precision. This function differs
+ from the tree_fits_* versions in that the type of signedness of the
+ type of X is not considered. */
+
+static inline bool
+cst_fits_shwi_p (const_tree x)
+{
+ if (TREE_CODE (x) != INTEGER_CST)
+ return false;
+
+ return TREE_INT_CST_NUNITS (x) == 1;
+}
+
+/* Checks that X is integer constant that can be expressed in signed
+ HOST_WIDE_INT without loss of precision. This function differs
+ from the tree_fits_* versions in that the type of signedness of the
+ type of X is not considered. */
+
+static inline bool
+cst_fits_uhwi_p (const_tree x)
+{
+ if (TREE_CODE (x) != INTEGER_CST)
+ return false;
+
+ return TREE_INT_CST_NUNITS (x) == 1 && TREE_INT_CST_ELT (x, 0) >= 0;
+}
+
+/* Return true if T is an INTEGER_CST whose value must be non-negative
+ and can be represented in a single unsigned HOST_WIDE_INT. This
+ function differs from the cst_fits versions in that the signedness
+ of the type of cst is considered. */
+
+static inline bool
+tree_fits_uhwi_p (const_tree cst)
+{
+ tree type;
+ if (cst == NULL_TREE)
+ return false;
+
+ type = TREE_TYPE (cst);
+
+ if (TREE_CODE (cst) != INTEGER_CST)
+ return false;
+
+ if (TREE_INT_CST_NUNITS (cst) == 1)
+ {
+ if ((TYPE_SIGN (type) == UNSIGNED)
+ && (TYPE_PRECISION (type) <= HOST_BITS_PER_WIDE_INT))
+ return true;
+
+ /* For numbers of unsigned type that are longer than a HWI, if
+ the top bit of the bottom word is set, and there is not
+ another element, then this is too large to fit in a single
+ hwi. */
+ if (TREE_INT_CST_ELT (cst, 0) >= 0)
+ return true;
+ }
+ else if (TREE_INT_CST_NUNITS (cst) == 2)
+ {
+ if (TREE_INT_CST_ELT (cst, 1) == 0)
+ return true;
+ }
+ return false;
+}
+
+/* Return true if CST is an INTEGER_CST whose value can be represented
+ in a single HOST_WIDE_INT. This function differs from the cst_fits
+ versions in that the signedness of the type of cst is
+ considered. */
+
+static inline bool
+tree_fits_shwi_p (const_tree cst)
+{
+ if (cst == NULL_TREE)
+ return false;
+
+ if (TREE_CODE (cst) != INTEGER_CST)
+ return false;
+
+ if (TREE_INT_CST_NUNITS (cst) != 1)
+ return false;
+
+ if (TYPE_SIGN (TREE_TYPE (cst)) == SIGNED)
+ return true;
+
+ if (TREE_INT_CST_ELT (cst, 0) >= 0)
+ return true;
+
+ return false;
+}
+
+/* Return true if T is an INTEGER_CST that can be manipulated
+ efficiently on the host. If SIGN is SIGNED, the value can be
+ represented in a single HOST_WIDE_INT. If SIGN is UNSIGNED, the
+ value must be non-negative and can be represented in a single
+ unsigned HOST_WIDE_INT. */
+
+static inline bool
+tree_fits_hwi_p (const_tree cst, signop sign)
+{
+ return sign ? tree_fits_uhwi_p (cst) : tree_fits_shwi_p (cst);
+}
+
+/* Return true if T is an INTEGER_CST that can be manipulated
+ efficiently on the host. If the sign of CST is SIGNED, the value
+ can be represented in a single HOST_WIDE_INT. If the sign of CST
+ is UNSIGNED, the value must be non-negative and can be represented
+ in a single unsigned HOST_WIDE_INT. */
+
+static inline bool
+tree_fits_hwi_p (const_tree cst)
+{
+ if (cst == NULL_TREE)
+ return false;
+
+ if (TREE_CODE (cst) != INTEGER_CST)
+ return false;
+
+ return TYPE_UNSIGNED (TREE_TYPE (cst))
+ ? tree_fits_uhwi_p (cst) : tree_fits_shwi_p (cst);
+}
+
+/* Return the unsigned HOST_WIDE_INT least significant bits of CST.
+ If checking is enabled, this ices if the value does not fit. */
+
+static inline unsigned HOST_WIDE_INT
+tree_to_uhwi (const_tree cst)
+{
+ gcc_checking_assert (tree_fits_uhwi_p (cst));
+
+ return (unsigned HOST_WIDE_INT)TREE_INT_CST_ELT (cst, 0);
+}
+
+/* Return the HOST_WIDE_INT least significant bits of CST. If
+ checking is enabled, this ices if the value does not fit. */
+
+static inline HOST_WIDE_INT
+tree_to_shwi (const_tree cst)
+{
+ gcc_checking_assert (tree_fits_shwi_p (cst));
+
+ return (HOST_WIDE_INT)TREE_INT_CST_ELT (cst, 0);
+}
+
+/* Return the HOST_WIDE_INT least significant bits of CST. No
+ checking is done to assure that it fits. It is assumed that one of
+ tree_fits_uhwi_p or tree_fits_shwi_p was done before this call. */
+
+static inline HOST_WIDE_INT
+tree_to_hwi (const_tree cst)
+{
+ return TREE_INT_CST_ELT (cst, 0);
+}
+
+/* Return the HOST_WIDE_INT least significant bits of CST. The sign
+ of the checking is based on SIGNOP. */
+
+static inline HOST_WIDE_INT
+tree_to_hwi (const_tree cst, signop sgn)
+{
+ if (sgn == SIGNED)
+ return tree_to_shwi (cst);
+ else
+ return tree_to_uhwi (cst);
+}
+
+
/* Compute the number of operands in an expression node NODE. For
tcc_vl_exp nodes like CALL_EXPRs, this is stored in the node itself,
otherwise it is looked up from the node's code. */
@@ -4568,8 +4759,6 @@ enum ptrmemfunc_vbit_where_t
ptrmemfunc_vbit_in_delta
};
-#define NULL_TREE (tree) NULL
-
/* True if NODE is an erroneous expression. */
#define error_operand_p(NODE) \
@@ -4585,9 +4774,9 @@ extern hashval_t decl_assembler_name_hash (const_tree asmname);
extern size_t tree_size (const_tree);
-/* Compute the number of bytes occupied by a tree with code CODE. This
- function cannot be used for TREE_VEC codes, which are of variable
- length. */
+/* Compute the number of bytes occupied by a tree with code CODE.
+ This function cannot be used for TREE_VEC or INTEGER_CST nodes,
+ which are of variable length. */
extern size_t tree_code_size (enum tree_code);
/* Allocate and return a new UID from the DECL_UID namespace. */
@@ -4617,6 +4806,11 @@ extern tree build_case_label (tree, tree, tree);
extern tree make_tree_binfo_stat (unsigned MEM_STAT_DECL);
#define make_tree_binfo(t) make_tree_binfo_stat (t MEM_STAT_INFO)
+/* Make a INTEGER_CST. */
+
+extern tree make_int_cst_stat (int MEM_STAT_DECL);
+#define make_int_cst(t) make_int_cst_stat (t MEM_STAT_INFO)
+
/* Make a TREE_VEC. */
extern tree make_tree_vec_stat (int MEM_STAT_DECL);
@@ -4733,27 +4927,16 @@ extern tree build_var_debug_value_stat (tree, tree MEM_STAT_DECL);
/* Constructs double_int from tree CST. */
-static inline double_int
-tree_to_double_int (const_tree cst)
-{
- return TREE_INT_CST (cst);
-}
-
extern tree double_int_to_tree (tree, double_int);
-extern bool double_int_fits_to_tree_p (const_tree, double_int);
-extern tree force_fit_type_double (tree, double_int, int, bool);
+class wide_int;
+extern tree force_fit_type (tree, const wide_int&, int, bool);
/* Create an INT_CST node with a CST value zero extended. */
-static inline tree
-build_int_cstu (tree type, unsigned HOST_WIDE_INT cst)
-{
- return double_int_to_tree (type, double_int::from_uhwi (cst));
-}
-
+/* static inline */
extern tree build_int_cst (tree, HOST_WIDE_INT);
+extern tree build_int_cstu (tree type, unsigned HOST_WIDE_INT cst);
extern tree build_int_cst_type (tree, HOST_WIDE_INT);
-extern tree build_int_cst_wide (tree, unsigned HOST_WIDE_INT, HOST_WIDE_INT);
extern tree make_vector_stat (unsigned MEM_STAT_DECL);
#define make_vector(n) make_vector_stat (n MEM_STAT_INFO)
extern tree build_vector_stat (tree, tree * MEM_STAT_DECL);
@@ -4845,24 +5028,10 @@ extern int attribute_list_contained (const_tree, const_tree);
extern int tree_int_cst_equal (const_tree, const_tree);
extern int tree_int_cst_lt (const_tree, const_tree);
extern int tree_int_cst_compare (const_tree, const_tree);
-extern int host_integerp (const_tree, int)
-#ifndef ENABLE_TREE_CHECKING
- ATTRIBUTE_PURE /* host_integerp is pure only when checking is disabled. */
-#endif
- ;
-extern HOST_WIDE_INT tree_low_cst (const_tree, int);
-#if !defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 4003)
-extern inline __attribute__ ((__gnu_inline__)) HOST_WIDE_INT
-tree_low_cst (const_tree t, int pos)
-{
- gcc_assert (host_integerp (t, pos));
- return TREE_INT_CST_LOW (t);
-}
-#endif
extern HOST_WIDE_INT size_low_cst (const_tree);
extern int tree_int_cst_sgn (const_tree);
extern int tree_int_cst_sign_bit (const_tree);
-extern unsigned int tree_int_cst_min_precision (tree, bool);
+extern unsigned int tree_int_cst_min_precision (tree, signop);
extern bool tree_expr_nonnegative_p (tree);
extern bool tree_expr_nonnegative_warnv_p (tree, bool *);
extern bool may_negate_without_overflow_p (const_tree);
@@ -5334,7 +5503,6 @@ extern int integer_pow2p (const_tree);
extern int integer_nonzerop (const_tree);
-extern bool cst_and_fits_in_hwi (const_tree);
extern tree num_ending_zeros (const_tree);
/* fixed_zerop (tree x) is nonzero if X is a fixed-point constant of
@@ -5793,11 +5961,10 @@ extern tree fold_indirect_ref_loc (location_t, tree);
extern tree build_simple_mem_ref_loc (location_t, tree);
#define build_simple_mem_ref(T)\
build_simple_mem_ref_loc (UNKNOWN_LOCATION, T)
-extern double_int mem_ref_offset (const_tree);
extern tree reference_alias_ptr_type (const_tree);
extern tree build_invariant_address (tree, tree, HOST_WIDE_INT);
extern tree constant_boolean_node (bool, tree);
-extern tree div_if_zero_remainder (enum tree_code, const_tree, const_tree);
+extern tree div_if_zero_remainder (const_tree, const_tree);
extern bool tree_swap_operands_p (const_tree, const_tree, bool);
extern enum tree_code swap_tree_comparison (enum tree_code);
@@ -6139,7 +6306,7 @@ extern tree get_attribute_namespace (const_tree);
extern void apply_tm_attr (tree, tree);
/* In stor-layout.c */
-extern void set_min_and_max_values_for_integral_type (tree, int, bool);
+extern void set_min_and_max_values_for_integral_type (tree, int, signop);
extern void fixup_signed_type (tree);
extern void internal_reference_types (void);
extern unsigned int update_alignment_for_field (record_layout_info, tree,