X-Git-Url: https://gcc.gnu.org/git/?a=blobdiff_plain;f=gcc%2Ftree.h;h=e000e4e26d338d0e2e927201c1b6435a5c385673;hb=6e2830c3dbe0d4972519ddd44bd1b15b2b274ba2;hp=9fbc5c4ec2c3bf8adcfbc04a45ae4310af916293;hpb=400a4f6ca21e539aecb66f570d769f4579a6482c;p=gcc.git diff --git a/gcc/tree.h b/gcc/tree.h index 9fbc5c4ec2c..e000e4e26d3 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -21,6 +21,9 @@ along with GCC; see the file COPYING3. If not see #define GCC_TREE_H #include "tree-core.h" +#include "hash-set.h" +#include "wide-int.h" +#include "inchash.h" /* These includes are required here because they provide declarations used by inline functions in this file. @@ -207,6 +210,8 @@ along with GCC; see the file COPYING3. If not see #define CASE_FLT_FN_REENT(FN) case FN##_R: case FN##F_R: case FN##L_R #define CASE_INT_FN(FN) case FN: case FN##L: case FN##LL: case FN##IMAX +#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). */ @@ -278,6 +283,9 @@ along with GCC; see the file COPYING3. If not see #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__)))) @@ -333,6 +341,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; @@ -370,6 +381,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]) @@ -738,6 +750,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) \ @@ -872,25 +887,15 @@ 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))) - -#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.int_length.unextended) +#define TREE_INT_CST_EXT_NUNITS(NODE) \ + (INTEGER_CST_CHECK (NODE)->base.u.int_length.extended) +#define TREE_INT_CST_OFFSET_NUNITS(NODE) \ + (INTEGER_CST_CHECK (NODE)->base.u.int_length.offset) +#define TREE_INT_CST_ELT(NODE, I) TREE_INT_CST_ELT_CHECK (NODE, I) +#define TREE_INT_CST_LOW(NODE) \ + ((unsigned HOST_WIDE_INT) TREE_INT_CST_ELT (NODE, 0)) #define TREE_REAL_CST_PTR(NODE) (REAL_CST_CHECK (NODE)->real_cst.real_cst_ptr) #define TREE_REAL_CST(NODE) (*TREE_REAL_CST_PTR (NODE)) @@ -1131,12 +1136,12 @@ extern void protected_set_expr_location (tree, location_t); #define ASSERT_EXPR_VAR(NODE) TREE_OPERAND (ASSERT_EXPR_CHECK (NODE), 0) #define ASSERT_EXPR_COND(NODE) TREE_OPERAND (ASSERT_EXPR_CHECK (NODE), 1) -/* CALL_EXPR accessors. - */ +/* CALL_EXPR accessors. */ #define CALL_EXPR_FN(NODE) TREE_OPERAND (CALL_EXPR_CHECK (NODE), 1) #define CALL_EXPR_STATIC_CHAIN(NODE) TREE_OPERAND (CALL_EXPR_CHECK (NODE), 2) #define CALL_EXPR_ARG(NODE, I) TREE_OPERAND (CALL_EXPR_CHECK (NODE), (I) + 3) #define call_expr_nargs(NODE) (VL_EXP_OPERAND_LENGTH (NODE) - 3) +#define CALL_EXPR_IFN(NODE) (CALL_EXPR_CHECK (NODE)->base.u.ifn) /* CALL_EXPR_ARGP returns a pointer to the argument vector for NODE. We can't use &CALL_EXPR_ARG (NODE, 0) because that will complain if @@ -1327,9 +1332,20 @@ extern void protected_set_expr_location (tree, location_t); #define OMP_CLAUSE_LINEAR_VARIABLE_STRIDE(NODE) \ TREE_PROTECTED (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_LINEAR)) +/* True if a LINEAR clause is for an array or allocatable variable that + needs special handling by the frontend. */ +#define OMP_CLAUSE_LINEAR_ARRAY(NODE) \ + (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_LINEAR)->base.deprecated_flag) + #define OMP_CLAUSE_LINEAR_STEP(NODE) \ OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_LINEAR), 1) +#define OMP_CLAUSE_LINEAR_STMT(NODE) \ + OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_LINEAR), 2) + +#define OMP_CLAUSE_LINEAR_GIMPLE_SEQ(NODE) \ + (OMP_CLAUSE_CHECK (NODE))->omp_clause.gimple_reduction_init + #define OMP_CLAUSE_ALIGNED_ALIGNMENT(NODE) \ OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_ALIGNED), 1) @@ -1491,6 +1507,11 @@ extern void protected_set_expr_location (tree, location_t); #define BLOCK_SOURCE_LOCATION(NODE) (BLOCK_CHECK (NODE)->block.locus) +/* This gives the location of the end of the block, useful to attach + code implicitly generated for outgoing paths. */ + +#define BLOCK_SOURCE_END_LOCATION(NODE) (BLOCK_CHECK (NODE)->block.end_locus) + /* Define fields and accessors for nodes representing data types. */ /* See tree.def for documentation of the use of these fields. @@ -1906,6 +1927,11 @@ extern void protected_set_expr_location (tree, location_t); It is an IDENTIFIER_NODE. */ #define DECL_NAME(NODE) (DECL_MINIMAL_CHECK (NODE)->decl_minimal.name) +/* The IDENTIFIER_NODE associated with the TYPE_NAME field. */ +#define TYPE_IDENTIFIER(NODE) \ + (TYPE_NAME (NODE) && DECL_P (TYPE_NAME (NODE)) \ + ? DECL_NAME (TYPE_NAME (NODE)) : TYPE_NAME (NODE)) + /* Every ..._DECL node gets a unique number. */ #define DECL_UID(NODE) (DECL_MINIMAL_CHECK (NODE)->decl_minimal.uid) @@ -2309,11 +2335,12 @@ extern void decl_value_expr_insert (tree, tree); (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.comdat_flag) #define DECL_COMDAT_GROUP(NODE) \ - (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.comdat_group) + decl_comdat_group (NODE) /* Used in TREE_PUBLIC decls to indicate that copies of this DECL in multiple translation units should be merged. */ -#define DECL_ONE_ONLY(NODE) (DECL_COMDAT_GROUP (NODE) != NULL_TREE) +#define DECL_ONE_ONLY(NODE) (DECL_COMDAT_GROUP (NODE) != NULL_TREE \ + && (TREE_PUBLIC (NODE) || DECL_EXTERNAL (NODE))) /* The name of the object as the assembler will see it (but before any translations made by ASM_OUTPUT_LABELREF). Often this is the same @@ -2353,8 +2380,7 @@ extern void decl_value_expr_insert (tree, tree); /* Records the section name in a section attribute. Used to pass the name from decl_attributes to make_function_rtl and make_decl_rtl. */ -#define DECL_SECTION_NAME(NODE) \ - (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.section_name) +#define DECL_SECTION_NAME(NODE) decl_section_name (NODE) /* Nonzero in a decl means that the gimplifier has seen (or placed) this variable in a BIND_EXPR. */ @@ -2372,12 +2398,12 @@ extern void decl_value_expr_insert (tree, tree); /* In a VAR_DECL, the model to use if the data should be allocated from thread-local storage. */ -#define DECL_TLS_MODEL(NODE) (VAR_DECL_CHECK (NODE)->decl_with_vis.tls_model) +#define DECL_TLS_MODEL(NODE) decl_tls_model (NODE) /* In a VAR_DECL, nonzero if the data should be allocated from thread-local storage. */ #define DECL_THREAD_LOCAL_P(NODE) \ - (VAR_DECL_CHECK (NODE)->decl_with_vis.tls_model >= TLS_MODEL_REAL) + ((TREE_STATIC (NODE) || DECL_EXTERNAL (NODE)) && decl_tls_model (NODE) >= TLS_MODEL_REAL) /* In a non-local VAR_DECL with static storage duration, true if the variable has an initialization priority. If false, the variable @@ -2385,11 +2411,6 @@ extern void decl_value_expr_insert (tree, tree); #define DECL_HAS_INIT_PRIORITY_P(NODE) \ (VAR_DECL_CHECK (NODE)->decl_with_vis.init_priority_p) -/* Specify whether the section name was set by user or by - compiler via -ffunction-sections. */ -#define DECL_HAS_IMPLICIT_SECTION_NAME_P(NODE) \ - (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.implicit_section_name_p) - extern tree decl_debug_expr_lookup (tree); extern void decl_debug_expr_insert (tree, tree); @@ -2456,10 +2477,9 @@ extern void decl_fini_priority_insert (tree, priority_type); is the FUNCTION_DECL which this FUNCTION_DECL will replace as a virtual function. When the class is laid out, this pointer is changed to an INTEGER_CST node which is suitable for use as an index - into the virtual function table. - C++ also uses this field in namespaces, hence the DECL_NON_COMMON_CHECK. */ + into the virtual function table. */ #define DECL_VINDEX(NODE) \ - (DECL_NON_COMMON_CHECK (NODE)->decl_non_common.vindex) + (FUNCTION_DECL_CHECK (NODE)->function_decl.vindex) /* In FUNCTION_DECL, holds the decl for the return value. */ #define DECL_RESULT(NODE) (FUNCTION_DECL_CHECK (NODE)->decl_non_common.result) @@ -2471,7 +2491,7 @@ extern void decl_fini_priority_insert (tree, priority_type); /* In a FUNCTION_DECL, the saved representation of the body of the entire function. */ #define DECL_SAVED_TREE(NODE) \ - (FUNCTION_DECL_CHECK (NODE)->decl_non_common.saved_tree) + (FUNCTION_DECL_CHECK (NODE)->function_decl.saved_tree) /* Nonzero in a FUNCTION_DECL means this function should be treated as if it were a malloc, meaning it returns a pointer that is @@ -2603,13 +2623,9 @@ extern vec **decl_debug_args_insert (tree); #define DECL_BUILT_IN_CLASS(NODE) \ (FUNCTION_DECL_CHECK (NODE)->function_decl.built_in_class) -/* In FUNCTION_DECL, a chain of ..._DECL nodes. - VAR_DECL and PARM_DECL reserve the arguments slot for language-specific - uses. */ +/* In FUNCTION_DECL, a chain of ..._DECL nodes. */ #define DECL_ARGUMENTS(NODE) \ - (FUNCTION_DECL_CHECK (NODE)->decl_non_common.arguments) -#define DECL_ARGUMENT_FLD(NODE) \ - (DECL_NON_COMMON_CHECK (NODE)->decl_non_common.arguments) + (FUNCTION_DECL_CHECK (NODE)->function_decl.arguments) /* In FUNCTION_DECL, the function specific target options to use when compiling this function. */ @@ -2893,6 +2909,30 @@ 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.int_length.extended) + tree_int_cst_elt_check_failed (__i, __t->base.u.int_length.extended, + __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.int_length.extended) + tree_int_cst_elt_check_failed (__i, __t->base.u.int_length.extended, + __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) @@ -3207,6 +3247,8 @@ tree_operand_check_code (const_tree __t, enum tree_code __code, int __i, #define uint32_type_node global_trees[TI_UINT32_TYPE] #define uint64_type_node global_trees[TI_UINT64_TYPE] +#define void_node global_trees[TI_VOID] + #define integer_zero_node global_trees[TI_INTEGER_ZERO] #define integer_one_node global_trees[TI_INTEGER_ONE] #define integer_three_node global_trees[TI_INTEGER_THREE] @@ -3383,8 +3425,6 @@ tree_operand_check_code (const_tree __t, enum tree_code __code, int __i, #define int128_integer_type_node integer_types[itk_int128] #define int128_unsigned_type_node integer_types[itk_unsigned_int128] -#define NULL_TREE (tree) NULL - /* True if NODE is an erroneous expression. */ #define error_operand_p(NODE) \ @@ -3392,15 +3432,21 @@ tree_operand_check_code (const_tree __t, enum tree_code __code, int __i, || ((NODE) && TREE_TYPE ((NODE)) == error_mark_node)) extern tree decl_assembler_name (tree); +extern tree decl_comdat_group (const_tree); +extern tree decl_comdat_group_id (const_tree); +extern const char *decl_section_name (const_tree); +extern void set_decl_section_name (tree, const char *); +extern enum tls_model decl_tls_model (const_tree); +extern void set_decl_tls_model (tree, enum tls_model); /* Compute the number of bytes occupied by 'node'. This routine only looks at TREE_CODE and, if the code is TREE_VEC, TREE_VEC_LENGTH. */ 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. */ @@ -3430,6 +3476,12 @@ 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 an INTEGER_CST. */ + +extern tree make_int_cst_stat (int, int MEM_STAT_DECL); +#define make_int_cst(LEN, EXT_LEN) \ + make_int_cst_stat (LEN, EXT_LEN MEM_STAT_INFO) + /* Make a TREE_VEC. */ extern tree make_tree_vec_stat (int MEM_STAT_DECL); @@ -3527,27 +3579,17 @@ 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); -/* Create an INT_CST node with a CST value zero extended. */ +extern tree wide_int_to_tree (tree type, const wide_int_ref &cst); +extern tree force_fit_type (tree, const wide_int_ref &, int, bool); -static inline tree -build_int_cstu (tree type, unsigned HOST_WIDE_INT cst) -{ - return double_int_to_tree (type, double_int::from_uhwi (cst)); -} +/* Create an INT_CST node with a CST value zero extended. */ +/* 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); @@ -3587,6 +3629,13 @@ extern tree build_call_valist (tree, tree, int, va_list); build_call_array_loc (UNKNOWN_LOCATION, T1, T2, N, T3) extern tree build_call_array_loc (location_t, tree, tree, int, const tree *); extern tree build_call_vec (tree, tree, vec *); +extern tree build_call_expr_loc_array (location_t, tree, int, tree *); +extern tree build_call_expr_loc_vec (location_t, tree, vec *); +extern tree build_call_expr_loc (location_t, tree, int, ...); +extern tree build_call_expr (tree, int, ...); +extern tree build_call_expr_internal_loc (location_t, enum internal_fn, + tree, int, ...); +extern tree build_string_literal (int, const char *); /* Construct various nodes representing data types. */ @@ -3629,8 +3678,7 @@ extern tree chain_index (int, tree); extern int attribute_list_equal (const_tree, const_tree); 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 bool tree_fits_shwi_p (const_tree) #ifndef ENABLE_TREE_CHECKING ATTRIBUTE_PURE /* tree_fits_shwi_p is pure only when checking is disabled. */ @@ -3660,7 +3708,7 @@ tree_to_uhwi (const_tree t) #endif 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 tree strip_array_types (tree); extern tree excess_precision_type (tree); extern bool valid_constant_size_p (const_tree); @@ -3695,6 +3743,10 @@ extern tree merge_type_attributes (tree, tree); and you should never call it directly. */ extern tree private_lookup_attribute (const char *, size_t, tree); +/* This function is a private implementation detail + of lookup_attribute_by_prefix() and you should never call it directly. */ +extern tree private_lookup_attribute_by_prefix (const char *, size_t, tree); + /* Given an attribute name ATTR_NAME and a list of attributes LIST, return a pointer to the attribute's list element if the attribute is part of the list, or NULL_TREE if not found. If the attribute @@ -3717,6 +3769,24 @@ lookup_attribute (const char *attr_name, tree list) return private_lookup_attribute (attr_name, strlen (attr_name), list); } +/* Given an attribute name ATTR_NAME and a list of attributes LIST, + return a pointer to the attribute's list first element if the attribute + starts with ATTR_NAME. ATTR_NAME must be in the form 'text' (not + '__text__'). */ + +static inline tree +lookup_attribute_by_prefix (const char *attr_name, tree list) +{ + gcc_checking_assert (attr_name[0] != '_'); + /* In most cases, list is NULL_TREE. */ + if (list == NULL_TREE) + return NULL_TREE; + else + return private_lookup_attribute_by_prefix (attr_name, strlen (attr_name), + list); +} + + /* This function is a private implementation detail of is_attribute_p() and you should never call it directly. */ extern bool private_is_attribute_p (const char *, size_t, const_tree); @@ -4187,7 +4257,7 @@ static inline tree fold_build_pointer_plus_loc (location_t loc, tree ptr, tree off) { return fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (ptr), - ptr, fold_convert_loc (loc, sizetype, off)); + ptr, convert_to_ptrofftype_loc (loc, off)); } #define fold_build_pointer_plus(p,o) \ fold_build_pointer_plus_loc (UNKNOWN_LOCATION, p, o) @@ -4215,10 +4285,23 @@ extern int tree_log2 (const_tree); extern int tree_floor_log2 (const_tree); extern unsigned int tree_ctz (const_tree); extern int simple_cst_equal (const_tree, const_tree); -extern hashval_t iterative_hash_expr (const_tree, hashval_t); -extern hashval_t iterative_hash_host_wide_int (HOST_WIDE_INT, hashval_t); -extern hashval_t iterative_hash_hashval_t (hashval_t, hashval_t); -extern hashval_t iterative_hash_host_wide_int (HOST_WIDE_INT, hashval_t); + +namespace inchash +{ + +extern void add_expr (const_tree, hash &); + +} + +/* Compat version until all callers are converted. Return hash for + TREE with SEED. */ +static inline hashval_t iterative_hash_expr(const_tree tree, hashval_t seed) +{ + inchash::hash hstate (seed); + inchash::add_expr (tree, hstate); + return hstate.end (); +} + extern int compare_tree_int (const_tree, unsigned HOST_WIDE_INT); extern int type_list_equal (const_tree, const_tree); extern int chain_member (const_tree, const_tree); @@ -4236,7 +4319,6 @@ extern tree build_range_type (tree, tree, tree); extern tree build_nonshared_range_type (tree, tree, tree); extern bool subrange_type_for_debug_p (const_tree, tree *, tree *); extern HOST_WIDE_INT int_cst_value (const_tree); -extern HOST_WIDEST_INT widest_int_cst_value (const_tree); extern tree tree_block (tree); extern void tree_set_block (tree, tree); extern location_t *block_nonartificial_location (tree); @@ -4245,15 +4327,15 @@ extern tree block_ultimate_origin (const_tree); extern tree get_binfo_at_offset (tree, HOST_WIDE_INT, tree); extern bool virtual_method_call_p (tree); extern tree obj_type_ref_class (tree ref); -extern bool types_same_for_odr (tree type1, tree type2); +extern bool types_same_for_odr (const_tree type1, const_tree type2); extern bool contains_bitfld_component_ref_p (const_tree); -extern bool type_in_anonymous_namespace_p (tree); +extern bool type_in_anonymous_namespace_p (const_tree); extern bool block_may_fallthru (const_tree); extern void using_eh_for_cleanups (void); extern bool using_eh_for_cleanups_p (void); extern const char *get_tree_code_name (enum tree_code); extern void set_call_expr_flags (tree, int); -extern tree walk_tree_1 (tree*, walk_tree_fn, void*, struct pointer_set_t*, +extern tree walk_tree_1 (tree*, walk_tree_fn, void*, hash_set*, walk_tree_lh); extern tree walk_tree_without_duplicates_1 (tree*, walk_tree_fn, void*, walk_tree_lh); @@ -4280,10 +4362,6 @@ extern unsigned int tree_decl_map_hash (const void *); #define tree_int_map_hash tree_map_base_hash #define tree_int_map_marked_p tree_map_base_marked_p -#define tree_priority_map_eq tree_map_base_eq -#define tree_priority_map_hash tree_map_base_hash -#define tree_priority_map_marked_p tree_map_base_marked_p - #define tree_vec_map_eq tree_map_base_eq #define tree_vec_map_hash tree_decl_map_hash #define tree_vec_map_marked_p tree_map_base_marked_p @@ -4511,6 +4589,179 @@ opts_for_fn (const_tree fndecl) #endif /* NO_DOLLAR_IN_LABEL */ #endif /* NO_DOT_IN_LABEL */ +/* The tree and const_tree overload templates. */ +namespace wi +{ + template <> + struct int_traits + { + static const enum precision_type precision_type = VAR_PRECISION; + static const bool host_dependent_precision = false; + static const bool is_sign_extended = false; + static unsigned int get_precision (const_tree); + static wi::storage_ref decompose (HOST_WIDE_INT *, unsigned int, + const_tree); + }; + + template <> + struct int_traits : public int_traits {}; + + template + class extended_tree + { + private: + const_tree m_t; + + public: + extended_tree (const_tree); + + unsigned int get_precision () const; + const HOST_WIDE_INT *get_val () const; + unsigned int get_len () const; + }; + + template + struct int_traits > + { + static const enum precision_type precision_type = CONST_PRECISION; + static const bool host_dependent_precision = false; + static const bool is_sign_extended = true; + static const unsigned int precision = N; + }; + + generic_wide_int > + to_widest (const_tree); + + generic_wide_int > to_offset (const_tree); +} + +inline unsigned int +wi::int_traits ::get_precision (const_tree tcst) +{ + return TYPE_PRECISION (TREE_TYPE (tcst)); +} + +/* Convert the tree_cst X into a wide_int of PRECISION. */ +inline wi::storage_ref +wi::int_traits ::decompose (HOST_WIDE_INT *, + unsigned int precision, const_tree x) +{ + return wi::storage_ref (&TREE_INT_CST_ELT (x, 0), TREE_INT_CST_NUNITS (x), + precision); +} + +inline generic_wide_int > +wi::to_widest (const_tree t) +{ + return t; +} + +inline generic_wide_int > +wi::to_offset (const_tree t) +{ + return t; +} + +template +inline wi::extended_tree ::extended_tree (const_tree t) + : m_t (t) +{ + gcc_checking_assert (TYPE_PRECISION (TREE_TYPE (t)) <= N); +} + +template +inline unsigned int +wi::extended_tree ::get_precision () const +{ + return N; +} + +template +inline const HOST_WIDE_INT * +wi::extended_tree ::get_val () const +{ + return &TREE_INT_CST_ELT (m_t, 0); +} + +template +inline unsigned int +wi::extended_tree ::get_len () const +{ + if (N == ADDR_MAX_PRECISION) + return TREE_INT_CST_OFFSET_NUNITS (m_t); + else if (N >= WIDE_INT_MAX_PRECISION) + return TREE_INT_CST_EXT_NUNITS (m_t); + else + /* This class is designed to be used for specific output precisions + and needs to be as fast as possible, so there is no fallback for + other casees. */ + gcc_unreachable (); +} + +namespace wi +{ + template + bool fits_to_tree_p (const T &x, const_tree); + + wide_int min_value (const_tree); + wide_int max_value (const_tree); + wide_int from_mpz (const_tree, mpz_t, bool); +} + +template +bool +wi::fits_to_tree_p (const T &x, const_tree type) +{ + if (TYPE_SIGN (type) == UNSIGNED) + return eq_p (x, zext (x, TYPE_PRECISION (type))); + else + return eq_p (x, sext (x, TYPE_PRECISION (type))); +} + +/* Produce the smallest number that is represented in TYPE. The precision + and sign are taken from TYPE. */ +inline wide_int +wi::min_value (const_tree type) +{ + return min_value (TYPE_PRECISION (type), TYPE_SIGN (type)); +} + +/* Produce the largest number that is represented in TYPE. The precision + and sign are taken from TYPE. */ +inline wide_int +wi::max_value (const_tree type) +{ + return max_value (TYPE_PRECISION (type), TYPE_SIGN (type)); +} + +/* Return true if INTEGER_CST T1 is less than INTEGER_CST T2, + extending both according to their respective TYPE_SIGNs. */ + +inline bool +tree_int_cst_lt (const_tree t1, const_tree t2) +{ + return wi::lts_p (wi::to_widest (t1), wi::to_widest (t2)); +} + +/* Return true if INTEGER_CST T1 is less than or equal to INTEGER_CST T2, + extending both according to their respective TYPE_SIGNs. */ + +inline bool +tree_int_cst_le (const_tree t1, const_tree t2) +{ + return wi::les_p (wi::to_widest (t1), wi::to_widest (t2)); +} + +/* Returns -1 if T1 < T2, 0 if T1 == T2, and 1 if T1 > T2. T1 and T2 + are both INTEGER_CSTs and their values are extended according to their + respective TYPE_SIGNs. */ + +inline int +tree_int_cst_compare (const_tree t1, const_tree t2) +{ + return wi::cmps (wi::to_widest (t1), wi::to_widest (t2)); +} + /* FIXME - These declarations belong in builtins.h, expr.h and emit-rtl.h, but none of these files are allowed to be included from front ends. They should be split in two. One suitable for the FEs, the other suitable @@ -4537,46 +4788,4 @@ extern tree get_inner_reference (tree, HOST_WIDE_INT *, HOST_WIDE_INT *, EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */ extern tree array_ref_low_bound (tree); -/* In builtins.c. */ - -/* Non-zero if __builtin_constant_p should be folded right away. */ -extern bool force_folding_builtin_constant_p; - -extern bool avoid_folding_inline_builtin (tree); -extern tree fold_call_expr (location_t, tree, bool); -extern tree fold_builtin_fputs (location_t, tree, tree, bool, bool, tree); -extern tree fold_builtin_strcpy (location_t, tree, tree, tree, tree); -extern tree fold_builtin_strncpy (location_t, tree, tree, tree, tree, tree); -extern tree fold_builtin_strcat (location_t, tree, tree, tree); -extern tree fold_builtin_memory_chk (location_t, tree, tree, tree, tree, tree, tree, bool, - enum built_in_function); -extern tree fold_builtin_stxcpy_chk (location_t, tree, tree, tree, tree, tree, bool, - enum built_in_function); -extern tree fold_builtin_stxncpy_chk (location_t, tree, tree, tree, tree, tree, bool, - enum built_in_function); -extern tree fold_builtin_expect (location_t, tree, tree, tree); -extern bool fold_builtin_next_arg (tree, bool); -extern enum built_in_function builtin_mathfn_code (const_tree); -extern tree fold_builtin_call_array (location_t, tree, tree, int, tree *); -extern tree build_call_expr_loc_array (location_t, tree, int, tree *); -extern tree build_call_expr_loc_vec (location_t, tree, vec *); -extern tree build_call_expr_loc (location_t, tree, int, ...); -extern tree build_call_expr (tree, int, ...); -extern tree mathfn_built_in (tree, enum built_in_function fn); -extern tree c_strlen (tree, int); -extern tree build_string_literal (int, const char *); -extern rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode); -extern bool is_builtin_fn (tree); -extern bool get_object_alignment_1 (tree, unsigned int *, - unsigned HOST_WIDE_INT *); -extern unsigned int get_object_alignment (tree); -extern bool get_pointer_alignment_1 (tree, unsigned int *, - unsigned HOST_WIDE_INT *); -extern unsigned int get_pointer_alignment (tree); -extern tree fold_call_stmt (gimple, bool); -extern tree gimple_fold_builtin_snprintf_chk (gimple, tree, enum built_in_function); -extern void set_builtin_user_assembler_name (tree decl, const char *asmspec); -extern bool is_simple_builtin (tree); -extern bool is_inexpensive_builtin (tree); - #endif /* GCC_TREE_H */