diff options
author | Giuliano Belinassi <giuliano.belinassi@usp.br> | 2020-08-22 17:43:43 -0300 |
---|---|---|
committer | Giuliano Belinassi <giuliano.belinassi@usp.br> | 2020-08-22 17:43:43 -0300 |
commit | a926878ddbd5a98b272c22171ce58663fc04c3e0 (patch) | |
tree | 86af256e5d9a9c06263c00adc90e5fe348008c43 /gcc/tree.c | |
parent | 542730f087133690b47e036dfd43eb0db8a650ce (diff) | |
parent | 07cbaed8ba7d1b6e4ab3a9f44175502a4e1ecdb1 (diff) | |
download | gcc-devel/autopar_devel.zip gcc-devel/autopar_devel.tar.gz gcc-devel/autopar_devel.tar.bz2 |
Merge branch 'autopar_rebase2' into autopar_develdevel/autopar_devel
Quickly commit changes in the rebase branch.
Diffstat (limited to 'gcc/tree.c')
-rw-r--r-- | gcc/tree.c | 264 |
1 files changed, 148 insertions, 116 deletions
@@ -357,7 +357,6 @@ unsigned const char omp_clause_num_ops[] = 1, /* OMP_CLAUSE_NUM_WORKERS */ 1, /* OMP_CLAUSE_VECTOR_LENGTH */ 3, /* OMP_CLAUSE_TILE */ - 2, /* OMP_CLAUSE__GRIDDIM_ */ 0, /* OMP_CLAUSE_IF_PRESENT */ 0, /* OMP_CLAUSE_FINALIZE */ }; @@ -442,7 +441,6 @@ const char * const omp_clause_code_name[] = "num_workers", "vector_length", "tile", - "_griddim_", "if_present", "finalize", }; @@ -1483,6 +1481,31 @@ int_cst_hasher::equal (tree x, tree y) return true; } +/* Cache wide_int CST into the TYPE_CACHED_VALUES cache for TYPE. + SLOT is the slot entry to store it in, and MAX_SLOTS is the maximum + number of slots that can be cached for the type. */ + +static inline tree +cache_wide_int_in_type_cache (tree type, const wide_int &cst, + int slot, int max_slots) +{ + gcc_checking_assert (slot >= 0); + /* Initialize cache. */ + if (!TYPE_CACHED_VALUES_P (type)) + { + TYPE_CACHED_VALUES_P (type) = 1; + TYPE_CACHED_VALUES (type) = make_tree_vec (max_slots); + } + tree t = TREE_VEC_ELT (TYPE_CACHED_VALUES (type), slot); + if (!t) + { + /* Create a new shared int. */ + t = build_new_int_cst (type, cst); + TREE_VEC_ELT (TYPE_CACHED_VALUES (type), slot) = t; + } + return t; +} + /* Create an INT_CST node of TYPE and value CST. The returned node is always shared. For small integers we use a per-type vector cache, for larger ones we use a single hash table. @@ -1515,6 +1538,28 @@ wide_int_to_tree_1 (tree type, const wide_int_ref &pcst) wide_int cst = wide_int::from (pcst, prec, sgn); unsigned int ext_len = get_int_cst_ext_nunits (type, cst); + enum tree_code code = TREE_CODE (type); + if (code == POINTER_TYPE || code == REFERENCE_TYPE) + { + /* Cache NULL pointer and zero bounds. */ + if (cst == 0) + ix = 0; + /* Cache upper bounds of pointers. */ + else if (cst == wi::max_value (prec, sgn)) + ix = 1; + /* Cache 1 which is used for a non-zero range. */ + else if (cst == 1) + ix = 2; + + if (ix >= 0) + { + t = cache_wide_int_in_type_cache (type, cst, ix, 3); + /* Make sure no one is clobbering the shared constant. */ + gcc_checking_assert (TREE_TYPE (t) == type + && cst == wi::to_wide (t)); + return t; + } + } if (ext_len == 1) { /* We just need to store a single HOST_WIDE_INT. */ @@ -1524,7 +1569,7 @@ wide_int_to_tree_1 (tree type, const wide_int_ref &pcst) else hwi = cst.to_shwi (); - switch (TREE_CODE (type)) + switch (code) { case NULLPTR_TYPE: gcc_assert (hwi == 0); @@ -1532,12 +1577,7 @@ wide_int_to_tree_1 (tree type, const wide_int_ref &pcst) case POINTER_TYPE: case REFERENCE_TYPE: - /* Cache NULL pointer and zero bounds. */ - if (hwi == 0) - { - limit = 1; - ix = 0; - } + /* Ignore pointers, as they were already handled above. */ break; case BOOLEAN_TYPE: @@ -1574,27 +1614,14 @@ wide_int_to_tree_1 (tree type, const wide_int_ref &pcst) if (ix >= 0) { - /* Look for it in the type's vector of small shared ints. */ - if (!TYPE_CACHED_VALUES_P (type)) - { - TYPE_CACHED_VALUES_P (type) = 1; - TYPE_CACHED_VALUES (type) = make_tree_vec (limit); - } - - t = TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix); - if (t) - /* Make sure no one is clobbering the shared constant. */ - gcc_checking_assert (TREE_TYPE (t) == type - && TREE_INT_CST_NUNITS (t) == 1 - && TREE_INT_CST_OFFSET_NUNITS (t) == 1 - && TREE_INT_CST_EXT_NUNITS (t) == 1 - && TREE_INT_CST_ELT (t, 0) == hwi); - else - { - /* Create a new shared int. */ - t = build_new_int_cst (type, cst); - TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix) = t; - } + t = cache_wide_int_in_type_cache (type, cst, ix, limit); + /* Make sure no one is clobbering the shared constant. */ + gcc_checking_assert (TREE_TYPE (t) == type + && TREE_INT_CST_NUNITS (t) == 1 + && TREE_INT_CST_OFFSET_NUNITS (t) == 1 + && TREE_INT_CST_EXT_NUNITS (t) == 1 + && TREE_INT_CST_ELT (t, 0) == hwi); + return t; } else { @@ -1771,6 +1798,8 @@ cache_integer_cst (tree t) break; case ENUMERAL_TYPE: + /* The slot used by TYPE_CACHED_VALUES is used for the enum + members. */ break; default: @@ -2204,29 +2233,29 @@ build_real_from_int_cst (tree type, const_tree i) return v; } -/* Return a newly constructed STRING_CST node whose value is - the LEN characters at STR. +/* Return a newly constructed STRING_CST node whose value is the LEN + characters at STR when STR is nonnull, or all zeros otherwise. Note that for a C string literal, LEN should include the trailing NUL. The TREE_TYPE is not initialized. */ tree -build_string (int len, const char *str) +build_string (unsigned len, const char *str /*= NULL */) { - tree s; - size_t length; - /* Do not waste bytes provided by padding of struct tree_string. */ - length = len + offsetof (struct tree_string, str) + 1; + unsigned size = len + offsetof (struct tree_string, str) + 1; - record_node_allocation_statistics (STRING_CST, length); + record_node_allocation_statistics (STRING_CST, size); - s = (tree) ggc_internal_alloc (length); + tree s = (tree) ggc_internal_alloc (size); memset (s, 0, sizeof (struct tree_typed)); TREE_SET_CODE (s, STRING_CST); TREE_CONSTANT (s) = 1; TREE_STRING_LENGTH (s) = len; - memcpy (s->string.str, str, len); + if (str) + memcpy (s->string.str, str, len); + else + memset (s->string.str, 0, len); s->string.str[len] = '\0'; return s; @@ -3351,51 +3380,6 @@ int_byte_position (const_tree field) return tree_to_shwi (byte_position (field)); } -/* Return the strictest alignment, in bits, that T is known to have. */ - -unsigned int -expr_align (const_tree t) -{ - unsigned int align0, align1; - - switch (TREE_CODE (t)) - { - CASE_CONVERT: case NON_LVALUE_EXPR: - /* If we have conversions, we know that the alignment of the - object must meet each of the alignments of the types. */ - align0 = expr_align (TREE_OPERAND (t, 0)); - align1 = TYPE_ALIGN (TREE_TYPE (t)); - return MAX (align0, align1); - - case SAVE_EXPR: case COMPOUND_EXPR: case MODIFY_EXPR: - case INIT_EXPR: case TARGET_EXPR: case WITH_CLEANUP_EXPR: - case CLEANUP_POINT_EXPR: - /* These don't change the alignment of an object. */ - return expr_align (TREE_OPERAND (t, 0)); - - case COND_EXPR: - /* The best we can do is say that the alignment is the least aligned - of the two arms. */ - align0 = expr_align (TREE_OPERAND (t, 1)); - align1 = expr_align (TREE_OPERAND (t, 2)); - return MIN (align0, align1); - - /* FIXME: LABEL_DECL and CONST_DECL never have DECL_ALIGN set - meaningfully, it's always 1. */ - case LABEL_DECL: case CONST_DECL: - case VAR_DECL: case PARM_DECL: case RESULT_DECL: - case FUNCTION_DECL: - gcc_assert (DECL_ALIGN (t) != 0); - return DECL_ALIGN (t); - - default: - break; - } - - /* Otherwise take the alignment from that of the type. */ - return TYPE_ALIGN (TREE_TYPE (t)); -} - /* Return, as a tree node, the number of elements for TYPE (which is an ARRAY_TYPE) minus one. This counts only elements of the top array. */ @@ -5606,15 +5590,14 @@ free_lang_data_in_type (tree type, class free_lang_data_d *fld) /* Type values are used only for C++ ODR checking. Drop them for all type variants and non-ODR types. For ODR types the data is freed in free_odr_warning_data. */ - if (TYPE_MAIN_VARIANT (type) != type - || !type_with_linkage_p (type)) + if (!TYPE_VALUES (type)) + ; + else if (TYPE_MAIN_VARIANT (type) != type + || !type_with_linkage_p (type) + || type_in_anonymous_namespace_p (type)) TYPE_VALUES (type) = NULL; else - /* Simplify representation by recording only values rather - than const decls. */ - for (tree e = TYPE_VALUES (type); e; e = TREE_CHAIN (e)) - if (TREE_CODE (TREE_VALUE (e)) == CONST_DECL) - TREE_VALUE (e) = DECL_INITIAL (TREE_VALUE (e)); + register_odr_enum (type); } free_lang_data_in_one_sizepos (&TYPE_MIN_VALUE (type)); free_lang_data_in_one_sizepos (&TYPE_MAX_VALUE (type)); @@ -8889,12 +8872,12 @@ get_narrower (tree op, int *unsignedp_ptr) return win; auto_vec <tree, 16> v; unsigned int i; - for (tree op = win; TREE_CODE (op) == COMPOUND_EXPR; + for (op = win; TREE_CODE (op) == COMPOUND_EXPR; op = TREE_OPERAND (op, 1)) v.safe_push (op); FOR_EACH_VEC_ELT_REVERSE (v, i, op) ret = build2_loc (EXPR_LOCATION (op), COMPOUND_EXPR, - TREE_TYPE (win), TREE_OPERAND (op, 0), + TREE_TYPE (ret), TREE_OPERAND (op, 0), ret); return ret; } @@ -10394,6 +10377,8 @@ build_common_tree_nodes (bool signed_char) uint16_type_node = make_or_reuse_type (16, 1); uint32_type_node = make_or_reuse_type (32, 1); uint64_type_node = make_or_reuse_type (64, 1); + if (targetm.scalar_mode_supported_p (TImode)) + uint128_type_node = make_or_reuse_type (128, 1); /* Decimal float types. */ if (targetm.decimal_float_supported_p ()) @@ -11633,12 +11618,12 @@ build_alloca_call_expr (tree size, unsigned int align, HOST_WIDE_INT max_size) /* Create a new constant string literal of type ELTYPE[SIZE] (or LEN if SIZE == -1) and return a tree node representing char* pointer to - it as an ADDR_EXPR (ARRAY_REF (ELTYPE, ...)). The STRING_CST value - is the LEN bytes at STR (the representation of the string, which may - be wide). */ + it as an ADDR_EXPR (ARRAY_REF (ELTYPE, ...)). When STR is nonnull + the STRING_CST value is the LEN bytes at STR (the representation + of the string, which may be wide). Otherwise it's all zeros. */ tree -build_string_literal (int len, const char *str, +build_string_literal (unsigned len, const char *str /* = NULL */, tree eltype /* = char_type_node */, unsigned HOST_WIDE_INT size /* = -1 */) { @@ -12130,7 +12115,6 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data, switch (OMP_CLAUSE_CODE (*tp)) { case OMP_CLAUSE_GANG: - case OMP_CLAUSE__GRIDDIM_: WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, 1)); /* FALLTHRU */ @@ -12275,6 +12259,12 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data, Note that DECLs get walked as part of processing the BIND_EXPR. */ if (TREE_CODE (DECL_EXPR_DECL (*tp)) == TYPE_DECL) { + /* Call the function for the decl so e.g. copy_tree_body_r can + replace it with the remapped one. */ + result = (*func) (&DECL_EXPR_DECL (*tp), &walk_subtrees, data); + if (result || !walk_subtrees) + return result; + tree *type_p = &TREE_TYPE (DECL_EXPR_DECL (*tp)); if (TREE_CODE (*type_p) == ERROR_MARK) return NULL_TREE; @@ -12867,10 +12857,11 @@ lhd_gcc_personality (void) OBJ_TYPE_REF representing an virtual call of C++ method. (As opposed to OBJ_TYPE_REF representing objc calls through a cast where middle-end devirtualization machinery - can't apply.) */ + can't apply.) FOR_DUMP_P is true when being called from + the dump routines. */ bool -virtual_method_call_p (const_tree target) +virtual_method_call_p (const_tree target, bool for_dump_p) { if (TREE_CODE (target) != OBJ_TYPE_REF) return false; @@ -12883,7 +12874,7 @@ virtual_method_call_p (const_tree target) /* If we do not have BINFO associated, it means that type was built without devirtualization enabled. Do not consider this a virtual call. */ - if (!TYPE_BINFO (obj_type_ref_class (target))) + if (!TYPE_BINFO (obj_type_ref_class (target, for_dump_p))) return false; return true; } @@ -13310,7 +13301,9 @@ get_tree_code_name (enum tree_code code) { const char *invalid = "<invalid tree code>"; - if (code >= MAX_TREE_CODES) + /* The tree_code enum promotes to signed, but we could be getting + invalid values, so force an unsigned comparison. */ + if (unsigned (code) >= MAX_TREE_CODES) { if (code == 0xa5a5) return "ggc_freed"; @@ -13664,6 +13657,10 @@ component_ref_size (tree ref, bool *interior_zero_length /* = NULL */) if (!interior_zero_length) interior_zero_length = &int_0_len; + /* The object/argument referenced by the COMPONENT_REF and its type. */ + tree arg = TREE_OPERAND (ref, 0); + tree argtype = TREE_TYPE (arg); + /* The referenced member. */ tree member = TREE_OPERAND (ref, 1); tree memsize = DECL_SIZE_UNIT (member); @@ -13675,7 +13672,7 @@ component_ref_size (tree ref, bool *interior_zero_length /* = NULL */) bool trailing = array_at_struct_end_p (ref); bool zero_length = integer_zerop (memsize); - if (!trailing && (!interior_zero_length || !zero_length)) + if (!trailing && !zero_length) /* MEMBER is either an interior array or is an array with more than one element. */ return memsize; @@ -13694,9 +13691,14 @@ component_ref_size (tree ref, bool *interior_zero_length /* = NULL */) offset_int minidx = wi::to_offset (min); offset_int maxidx = wi::to_offset (max); if (maxidx - minidx > 0) - /* MEMBER is an array with more than 1 element. */ + /* MEMBER is an array with more than one element. */ return memsize; } + + /* For a refernce to a zero- or one-element array member of a union + use the size of the union instead of the size of the member. */ + if (TREE_CODE (argtype) == UNION_TYPE) + memsize = TYPE_SIZE_UNIT (argtype); } /* MEMBER is either a bona fide flexible array member, or a zero-length @@ -13711,28 +13713,27 @@ component_ref_size (tree ref, bool *interior_zero_length /* = NULL */) if (!*interior_zero_length) return NULL_TREE; - if (TREE_CODE (TREE_OPERAND (ref, 0)) != COMPONENT_REF) + if (TREE_CODE (arg) != COMPONENT_REF) return NULL_TREE; - base = TREE_OPERAND (ref, 0); + base = arg; while (TREE_CODE (base) == COMPONENT_REF) base = TREE_OPERAND (base, 0); baseoff = tree_to_poly_int64 (byte_position (TREE_OPERAND (ref, 1))); } /* BASE is the declared object of which MEMBER is either a member - or that is cast to REFTYPE (e.g., a char buffer used to store - a REFTYPE object). */ - tree reftype = TREE_TYPE (TREE_OPERAND (ref, 0)); + or that is cast to ARGTYPE (e.g., a char buffer used to store + an ARGTYPE object). */ tree basetype = TREE_TYPE (base); /* Determine the base type of the referenced object. If it's - the same as REFTYPE and MEMBER has a known size, return it. */ + the same as ARGTYPE and MEMBER has a known size, return it. */ tree bt = basetype; if (!*interior_zero_length) while (TREE_CODE (bt) == ARRAY_TYPE) bt = TREE_TYPE (bt); - bool typematch = useless_type_conversion_p (reftype, bt); + bool typematch = useless_type_conversion_p (argtype, bt); if (memsize && typematch) return memsize; @@ -13748,7 +13749,7 @@ component_ref_size (tree ref, bool *interior_zero_length /* = NULL */) if (init) { memsize = TYPE_SIZE_UNIT (TREE_TYPE (init)); - if (tree refsize = TYPE_SIZE_UNIT (reftype)) + if (tree refsize = TYPE_SIZE_UNIT (argtype)) { /* Use the larger of the initializer size and the tail padding in the enclosing struct. */ @@ -13870,6 +13871,30 @@ vector_type_mode (const_tree t) return mode; } +/* Return the size in bits of each element of vector type TYPE. */ + +unsigned int +vector_element_bits (const_tree type) +{ + gcc_checking_assert (VECTOR_TYPE_P (type)); + if (VECTOR_BOOLEAN_TYPE_P (type)) + return vector_element_size (tree_to_poly_uint64 (TYPE_SIZE (type)), + TYPE_VECTOR_SUBPARTS (type)); + return tree_to_uhwi (TYPE_SIZE (TREE_TYPE (type))); +} + +/* Calculate the size in bits of each element of vector type TYPE + and return the result as a tree of type bitsizetype. */ + +tree +vector_element_bits_tree (const_tree type) +{ + gcc_checking_assert (VECTOR_TYPE_P (type)); + if (VECTOR_BOOLEAN_TYPE_P (type)) + return bitsize_int (vector_element_bits (type)); + return TYPE_SIZE (TREE_TYPE (type)); +} + /* Verify that basic properties of T match TV and thus T can be a variant of TV. TV should be the more specified variant (i.e. the main variant). */ @@ -14990,11 +15015,18 @@ get_nonnull_args (const_tree fntype) if (fntype == NULL_TREE) return NULL; + bitmap argmap = NULL; + if (TREE_CODE (fntype) == METHOD_TYPE) + { + /* The this pointer in C++ non-static member functions is + implicitly nonnull whether or not it's declared as such. */ + argmap = BITMAP_ALLOC (NULL); + bitmap_set_bit (argmap, 0); + } + tree attrs = TYPE_ATTRIBUTES (fntype); if (!attrs) - return NULL; - - bitmap argmap = NULL; + return argmap; /* A function declaration can specify multiple attribute nonnull, each with zero or more arguments. The loop below creates a bitmap |