X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gcc%2Ftree.c;h=9075664954c4e17dfb8ba2fcb6068435298e1a24;hb=refs%2Fheads%2Fdevel;hp=72a284c4c0ccb80196555c5c41722545c1f35869;hpb=b209d8dc611f3cd793491b8490522bdaf819622b;p=platform%2Fupstream%2Fgcc48.git diff --git a/gcc/tree.c b/gcc/tree.c index 72a284c..9075664 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -1,7 +1,5 @@ /* Language-independent node constructors for parse phase of GNU compiler. - Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, - 2011, 2012 Free Software Foundation, Inc. + Copyright (C) 1987-2013 Free Software Foundation, Inc. This file is part of GCC. @@ -38,7 +36,7 @@ along with GCC; see the file COPYING3. If not see #include "tm_p.h" #include "function.h" #include "obstack.h" -#include "toplev.h" +#include "toplev.h" /* get_random_seed */ #include "ggc.h" #include "hashtab.h" #include "filenames.h" @@ -58,7 +56,6 @@ along with GCC; see the file COPYING3. If not see #include "tree-diagnostic.h" #include "tree-pretty-print.h" #include "cgraph.h" -#include "timevar.h" #include "except.h" #include "debug.h" #include "intl.h" @@ -122,7 +119,6 @@ const char *const tree_code_class_strings[] = /* obstack.[ch] explicitly declined to prototype this. */ extern int _obstack_allocated_p (struct obstack *h, void *obj); -#ifdef GATHER_STATISTICS /* Statistics-gathering stuff. */ static int tree_code_counts[MAX_TREE_CODES]; @@ -148,7 +144,6 @@ static const char * const tree_node_kind_names[] = { "lang_type kinds", "omp clauses", }; -#endif /* GATHER_STATISTICS */ /* Unique id for next decl created. */ static GTY(()) int next_decl_uid; @@ -718,12 +713,17 @@ tree_size (const_tree node) { case TREE_BINFO: return (offsetof (struct tree_binfo, base_binfos) - + VEC_embedded_size (tree, BINFO_N_BASE_BINFOS (node))); + + vec + ::embedded_size (BINFO_N_BASE_BINFOS (node))); case TREE_VEC: return (sizeof (struct tree_vec) + (TREE_VEC_LENGTH (node) - 1) * sizeof (tree)); + case VECTOR_CST: + return (sizeof (struct tree_vector) + + (TYPE_VECTOR_SUBPARTS (TREE_TYPE (node)) - 1) * sizeof (tree)); + case STRING_CST: return TREE_STRING_LENGTH (node) + offsetof (struct tree_string, str) + 1; @@ -748,10 +748,12 @@ static void record_node_allocation_statistics (enum tree_code code ATTRIBUTE_UNUSED, size_t length ATTRIBUTE_UNUSED) { -#ifdef GATHER_STATISTICS enum tree_code_class type = TREE_CODE_CLASS (code); tree_node_kind kind; + if (!GATHER_STATISTICS) + return; + switch (type) { case tcc_declaration: /* A decl node */ @@ -829,7 +831,6 @@ record_node_allocation_statistics (enum tree_code code ATTRIBUTE_UNUSED, tree_code_counts[(int) code]++; tree_node_counts[(int) kind]++; tree_node_sizes[(int) kind] += length; -#endif } /* Allocate and return a new UID from the DECL_UID namespace. */ @@ -856,9 +857,7 @@ make_node_stat (enum tree_code code MEM_STAT_DECL) record_node_allocation_statistics (code, length); - t = ggc_alloc_zone_cleared_tree_node_stat ( - (code == IDENTIFIER_NODE) ? &tree_id_zone : &tree_zone, - length PASS_MEM_STAT); + t = ggc_alloc_cleared_tree_node_stat (length PASS_MEM_STAT); TREE_SET_CODE (t, code); switch (type) @@ -952,15 +951,13 @@ copy_node_stat (tree node MEM_STAT_DECL) length = tree_size (node); record_node_allocation_statistics (code, length); - t = ggc_alloc_zone_tree_node_stat (&tree_zone, length PASS_MEM_STAT); + t = ggc_alloc_tree_node_stat (length PASS_MEM_STAT); memcpy (t, node, length); if (CODE_CONTAINS_STRUCT (code, TS_COMMON)) TREE_CHAIN (t) = 0; TREE_ASM_WRITTEN (t) = 0; TREE_VISITED (t) = 0; - if (code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL) - *DECL_VAR_ANN_PTR (t) = 0; if (TREE_CODE_CLASS (code) == tcc_declaration) { @@ -983,6 +980,8 @@ copy_node_stat (tree node MEM_STAT_DECL) SET_DECL_INIT_PRIORITY (t, DECL_INIT_PRIORITY (node)); DECL_HAS_INIT_PRIORITY_P (t) = 1; } + if (TREE_CODE (node) == FUNCTION_DECL) + DECL_STRUCT_FUNCTION (t) = NULL; } else if (TREE_CODE_CLASS (code) == tcc_type) { @@ -1039,7 +1038,7 @@ build_int_cst (tree type, HOST_WIDE_INT low) if (!type) type = integer_type_node; - return double_int_to_tree (type, shwi_to_double_int (low)); + return double_int_to_tree (type, double_int::from_shwi (low)); } /* Create an INT_CST node with a LOW value sign extended to TYPE. */ @@ -1049,7 +1048,7 @@ build_int_cst_type (tree type, HOST_WIDE_INT low) { gcc_assert (type); - return double_int_to_tree (type, shwi_to_double_int (low)); + return double_int_to_tree (type, double_int::from_shwi (low)); } /* Constructs tree in type TYPE from with value given by CST. Signedness @@ -1058,12 +1057,9 @@ build_int_cst_type (tree type, HOST_WIDE_INT low) tree double_int_to_tree (tree type, double_int cst) { - /* Size types *are* sign extended. */ - bool sign_extended_type = (!TYPE_UNSIGNED (type) - || (TREE_CODE (type) == INTEGER_TYPE - && TYPE_IS_SIZETYPE (type))); + bool sign_extended_type = !TYPE_UNSIGNED (type); - cst = double_int_ext (cst, TYPE_PRECISION (type), !sign_extended_type); + cst = cst.ext (TYPE_PRECISION (type), !sign_extended_type); return build_int_cst_wide (type, cst.low, cst.high); } @@ -1074,15 +1070,12 @@ double_int_to_tree (tree type, double_int cst) bool double_int_fits_to_tree_p (const_tree type, double_int cst) { - /* Size types *are* sign extended. */ - bool sign_extended_type = (!TYPE_UNSIGNED (type) - || (TREE_CODE (type) == INTEGER_TYPE - && TYPE_IS_SIZETYPE (type))); + bool sign_extended_type = !TYPE_UNSIGNED (type); double_int ext - = double_int_ext (cst, TYPE_PRECISION (type), !sign_extended_type); + = cst.ext (TYPE_PRECISION (type), !sign_extended_type); - return double_int_equal_p (cst, ext); + return cst == ext; } /* We force the double_int CST to the range of the type TYPE by sign or @@ -1104,12 +1097,7 @@ tree force_fit_type_double (tree type, double_int cst, int overflowable, bool overflowed) { - bool sign_extended_type; - - /* Size types *are* sign extended. */ - sign_extended_type = (!TYPE_UNSIGNED (type) - || (TREE_CODE (type) == INTEGER_TYPE - && TYPE_IS_SIZETYPE (type))); + bool sign_extended_type = !TYPE_UNSIGNED (type); /* If we need to set overflow flags, return a new unshared node. */ if (overflowed || !double_int_fits_to_tree_p(type, cst)) @@ -1119,8 +1107,8 @@ force_fit_type_double (tree type, double_int cst, int overflowable, || (overflowable > 0 && sign_extended_type)) { tree t = make_node (INTEGER_CST); - TREE_INT_CST (t) = double_int_ext (cst, TYPE_PRECISION (type), - !sign_extended_type); + TREE_INT_CST (t) + = cst.ext (TYPE_PRECISION (type), !sign_extended_type); TREE_TYPE (t) = type; TREE_OVERFLOW (t) = 1; return t; @@ -1290,7 +1278,7 @@ build_low_bits_mask (tree type, unsigned bits) /* Sign extended all-ones mask. */ mask = double_int_minus_one; else - mask = double_int_mask (bits); + mask = double_int::mask (bits); return build_int_cst_wide (type, mask.low, mask.high); } @@ -1311,25 +1299,41 @@ cst_and_fits_in_hwi (const_tree x) || TREE_INT_CST_HIGH (x) == -1); } +/* Build a newly constructed TREE_VEC node of length LEN. */ + +tree +make_vector_stat (unsigned len MEM_STAT_DECL) +{ + tree t; + unsigned length = (len - 1) * sizeof (tree) + sizeof (struct tree_vector); + + record_node_allocation_statistics (VECTOR_CST, length); + + t = ggc_alloc_cleared_tree_node_stat (length PASS_MEM_STAT); + + TREE_SET_CODE (t, VECTOR_CST); + TREE_CONSTANT (t) = 1; + + return t; +} + /* Return a new VECTOR_CST node whose type is TYPE and whose values are in a list pointed to by VALS. */ tree -build_vector (tree type, tree vals) +build_vector_stat (tree type, tree *vals MEM_STAT_DECL) { - tree v = make_node (VECTOR_CST); int over = 0; - tree link; unsigned cnt = 0; - - TREE_VECTOR_CST_ELTS (v) = vals; + tree v = make_vector (TYPE_VECTOR_SUBPARTS (type)); TREE_TYPE (v) = type; /* Iterate through elements and check for overflow. */ - for (link = vals; link; link = TREE_CHAIN (link)) + for (cnt = 0; cnt < TYPE_VECTOR_SUBPARTS (type); ++cnt) { - tree value = TREE_VALUE (link); - cnt++; + tree value = vals[cnt]; + + VECTOR_CST_ELT (v, cnt) = value; /* Don't crash if we get an address constant. */ if (!CONSTANT_CLASS_P (value)) @@ -1338,8 +1342,6 @@ build_vector (tree type, tree vals) over |= TREE_OVERFLOW (value); } - gcc_assert (cnt == TYPE_VECTOR_SUBPARTS (type)); - TREE_OVERFLOW (v) = over; return v; } @@ -1348,18 +1350,18 @@ build_vector (tree type, tree vals) are extracted from V, a vector of CONSTRUCTOR_ELT. */ tree -build_vector_from_ctor (tree type, VEC(constructor_elt,gc) *v) +build_vector_from_ctor (tree type, vec *v) { - tree list = NULL_TREE; + tree *vec = XALLOCAVEC (tree, TYPE_VECTOR_SUBPARTS (type)); unsigned HOST_WIDE_INT idx; tree value; FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value) - list = tree_cons (NULL_TREE, value, list); + vec[idx] = value; for (; idx < TYPE_VECTOR_SUBPARTS (type); ++idx) - list = tree_cons (NULL_TREE, - build_zero_cst (TREE_TYPE (type)), list); - return build_vector (type, nreverse (list)); + vec[idx] = build_zero_cst (TREE_TYPE (type)); + + return build_vector (type, vec); } /* Build a vector of type VECTYPE where all the elements are SCs. */ @@ -1367,7 +1369,6 @@ tree build_vector_from_val (tree vectype, tree sc) { int i, nunits = TYPE_VECTOR_SUBPARTS (vectype); - VEC(constructor_elt, gc) *v = NULL; if (sc == error_mark_node) return sc; @@ -1381,36 +1382,50 @@ build_vector_from_val (tree vectype, tree sc) gcc_checking_assert (types_compatible_p (TYPE_MAIN_VARIANT (TREE_TYPE (sc)), TREE_TYPE (vectype))); - v = VEC_alloc (constructor_elt, gc, nunits); - for (i = 0; i < nunits; ++i) - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, sc); - if (CONSTANT_CLASS_P (sc)) - return build_vector_from_ctor (vectype, v); - else - return build_constructor (vectype, v); + { + tree *v = XALLOCAVEC (tree, nunits); + for (i = 0; i < nunits; ++i) + v[i] = sc; + return build_vector (vectype, v); + } + else + { + vec *v; + vec_alloc (v, nunits); + for (i = 0; i < nunits; ++i) + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, sc); + return build_constructor (vectype, v); + } } /* Return a new CONSTRUCTOR node whose type is TYPE and whose values - are in the VEC pointed to by VALS. */ + are in the vec pointed to by VALS. */ tree -build_constructor (tree type, VEC(constructor_elt,gc) *vals) +build_constructor (tree type, vec *vals) { tree c = make_node (CONSTRUCTOR); unsigned int i; constructor_elt *elt; bool constant_p = true; + bool side_effects_p = false; TREE_TYPE (c) = type; CONSTRUCTOR_ELTS (c) = vals; - FOR_EACH_VEC_ELT (constructor_elt, vals, i, elt) - if (!TREE_CONSTANT (elt->value)) - { + FOR_EACH_VEC_SAFE_ELT (vals, i, elt) + { + /* Mostly ctors will have elts that don't have side-effects, so + the usual case is to scan all the elements. Hence a single + loop for both const and side effects, rather than one loop + each (with early outs). */ + if (!TREE_CONSTANT (elt->value)) constant_p = false; - break; - } + if (TREE_SIDE_EFFECTS (elt->value)) + side_effects_p = true; + } + TREE_SIDE_EFFECTS (c) = side_effects_p; TREE_CONSTANT (c) = constant_p; return c; @@ -1421,13 +1436,11 @@ build_constructor (tree type, VEC(constructor_elt,gc) *vals) tree build_constructor_single (tree type, tree index, tree value) { - VEC(constructor_elt,gc) *v; - constructor_elt *elt; + vec *v; + constructor_elt elt = {index, value}; - v = VEC_alloc (constructor_elt, gc, 1); - elt = VEC_quick_push (constructor_elt, v, NULL); - elt->index = index; - elt->value = value; + vec_alloc (v, 1); + v->quick_push (elt); return build_constructor (type, v); } @@ -1439,11 +1452,11 @@ tree build_constructor_from_list (tree type, tree vals) { tree t; - VEC(constructor_elt,gc) *v = NULL; + vec *v = NULL; if (vals) { - v = VEC_alloc (constructor_elt, gc, list_length (vals)); + vec_alloc (v, list_length (vals)); for (t = vals; t; t = TREE_CHAIN (t)) CONSTRUCTOR_APPEND_ELT (v, TREE_PURPOSE (t), TREE_VALUE (t)); } @@ -1655,17 +1668,17 @@ make_tree_binfo_stat (unsigned base_binfos MEM_STAT_DECL) { tree t; size_t length = (offsetof (struct tree_binfo, base_binfos) - + VEC_embedded_size (tree, base_binfos)); + + vec::embedded_size (base_binfos)); record_node_allocation_statistics (TREE_BINFO, length); - t = ggc_alloc_zone_tree_node_stat (&tree_zone, length PASS_MEM_STAT); + t = ggc_alloc_tree_node_stat (length PASS_MEM_STAT); memset (t, 0, offsetof (struct tree_binfo, base_binfos)); TREE_SET_CODE (t, TREE_BINFO); - VEC_embedded_init (tree, BINFO_BASE_BINFOS (t), base_binfos); + BINFO_BASE_BINFOS (t)->embedded_init (base_binfos); return t; } @@ -1698,7 +1711,7 @@ make_tree_vec_stat (int len MEM_STAT_DECL) record_node_allocation_statistics (TREE_VEC, length); - t = ggc_alloc_zone_cleared_tree_node_stat (&tree_zone, length PASS_MEM_STAT); + t = ggc_alloc_cleared_tree_node_stat (length PASS_MEM_STAT); TREE_SET_CODE (t, TREE_VEC); TREE_VEC_LENGTH (t) = len; @@ -1714,12 +1727,25 @@ integer_zerop (const_tree expr) { STRIP_NOPS (expr); - return ((TREE_CODE (expr) == INTEGER_CST - && TREE_INT_CST_LOW (expr) == 0 - && TREE_INT_CST_HIGH (expr) == 0) - || (TREE_CODE (expr) == COMPLEX_CST - && integer_zerop (TREE_REALPART (expr)) - && integer_zerop (TREE_IMAGPART (expr)))); + switch (TREE_CODE (expr)) + { + case INTEGER_CST: + return (TREE_INT_CST_LOW (expr) == 0 + && TREE_INT_CST_HIGH (expr) == 0); + case COMPLEX_CST: + return (integer_zerop (TREE_REALPART (expr)) + && integer_zerop (TREE_IMAGPART (expr))); + case VECTOR_CST: + { + unsigned i; + for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) + if (!integer_zerop (VECTOR_CST_ELT (expr, i))) + return false; + return true; + } + default: + return false; + } } /* Return 1 if EXPR is the integer constant one or the corresponding @@ -1730,12 +1756,25 @@ integer_onep (const_tree expr) { STRIP_NOPS (expr); - return ((TREE_CODE (expr) == INTEGER_CST - && TREE_INT_CST_LOW (expr) == 1 - && TREE_INT_CST_HIGH (expr) == 0) - || (TREE_CODE (expr) == COMPLEX_CST - && integer_onep (TREE_REALPART (expr)) - && integer_zerop (TREE_IMAGPART (expr)))); + switch (TREE_CODE (expr)) + { + case INTEGER_CST: + return (TREE_INT_CST_LOW (expr) == 1 + && TREE_INT_CST_HIGH (expr) == 0); + case COMPLEX_CST: + return (integer_onep (TREE_REALPART (expr)) + && integer_zerop (TREE_IMAGPART (expr))); + case VECTOR_CST: + { + unsigned i; + for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) + if (!integer_onep (VECTOR_CST_ELT (expr, i))) + return false; + return true; + } + default: + return false; + } } /* Return 1 if EXPR is an integer containing all 1's in as much precision as @@ -1754,6 +1793,15 @@ integer_all_onesp (const_tree expr) && integer_zerop (TREE_IMAGPART (expr))) return 1; + else if (TREE_CODE (expr) == VECTOR_CST) + { + unsigned i; + for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) + if (!integer_all_onesp (VECTOR_CST_ELT (expr, i))) + return 0; + return 1; + } + else if (TREE_CODE (expr) != INTEGER_CST) return 0; @@ -1795,7 +1843,7 @@ int integer_pow2p (const_tree expr) { int prec; - HOST_WIDE_INT high, low; + unsigned HOST_WIDE_INT high, low; STRIP_NOPS (expr); @@ -1814,7 +1862,7 @@ integer_pow2p (const_tree expr) /* First clear all bits that are beyond the type's precision in case we've been sign extended. */ - if (prec == 2 * HOST_BITS_PER_WIDE_INT) + if (prec == HOST_BITS_PER_DOUBLE_INT) ; else if (prec > HOST_BITS_PER_WIDE_INT) high &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT)); @@ -1854,7 +1902,7 @@ int fixed_zerop (const_tree expr) { return (TREE_CODE (expr) == FIXED_CST - && double_int_zero_p (TREE_FIXED_CST (expr).data)); + && TREE_FIXED_CST (expr).data.is_zero ()); } /* Return the power of two represented by a tree node known to be a @@ -1878,7 +1926,7 @@ tree_log2 (const_tree expr) /* First clear all bits that are beyond the type's precision in case we've been sign extended. */ - if (prec == 2 * HOST_BITS_PER_WIDE_INT) + if (prec == HOST_BITS_PER_DOUBLE_INT) ; else if (prec > HOST_BITS_PER_WIDE_INT) high &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT)); @@ -1915,7 +1963,7 @@ tree_floor_log2 (const_tree expr) we've been sign extended. Ignore if type's precision hasn't been set since what we are doing is setting it. */ - if (prec == 2 * HOST_BITS_PER_WIDE_INT || prec == 0) + if (prec == HOST_BITS_PER_DOUBLE_INT || prec == 0) ; else if (prec > HOST_BITS_PER_WIDE_INT) high &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT)); @@ -1938,12 +1986,25 @@ real_zerop (const_tree expr) { STRIP_NOPS (expr); - return ((TREE_CODE (expr) == REAL_CST - && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst0) - && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr))))) - || (TREE_CODE (expr) == COMPLEX_CST - && real_zerop (TREE_REALPART (expr)) - && real_zerop (TREE_IMAGPART (expr)))); + switch (TREE_CODE (expr)) + { + case REAL_CST: + return REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst0) + && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr)))); + case COMPLEX_CST: + return real_zerop (TREE_REALPART (expr)) + && real_zerop (TREE_IMAGPART (expr)); + case VECTOR_CST: + { + unsigned i; + for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) + if (!real_zerop (VECTOR_CST_ELT (expr, i))) + return false; + return true; + } + default: + return false; + } } /* Return 1 if EXPR is the real constant one in real or complex form. @@ -1955,12 +2016,25 @@ real_onep (const_tree expr) { STRIP_NOPS (expr); - return ((TREE_CODE (expr) == REAL_CST - && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst1) - && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr))))) - || (TREE_CODE (expr) == COMPLEX_CST - && real_onep (TREE_REALPART (expr)) - && real_zerop (TREE_IMAGPART (expr)))); + switch (TREE_CODE (expr)) + { + case REAL_CST: + return REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst1) + && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr)))); + case COMPLEX_CST: + return real_onep (TREE_REALPART (expr)) + && real_zerop (TREE_IMAGPART (expr)); + case VECTOR_CST: + { + unsigned i; + for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) + if (!real_onep (VECTOR_CST_ELT (expr, i))) + return false; + return true; + } + default: + return false; + } } /* Return 1 if EXPR is the real constant two. Trailing zeroes matter @@ -1971,12 +2045,25 @@ real_twop (const_tree expr) { STRIP_NOPS (expr); - return ((TREE_CODE (expr) == REAL_CST - && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst2) - && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr))))) - || (TREE_CODE (expr) == COMPLEX_CST - && real_twop (TREE_REALPART (expr)) - && real_zerop (TREE_IMAGPART (expr)))); + switch (TREE_CODE (expr)) + { + case REAL_CST: + return REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst2) + && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr)))); + case COMPLEX_CST: + return real_twop (TREE_REALPART (expr)) + && real_zerop (TREE_IMAGPART (expr)); + case VECTOR_CST: + { + unsigned i; + for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) + if (!real_twop (VECTOR_CST_ELT (expr, i))) + return false; + return true; + } + default: + return false; + } } /* Return 1 if EXPR is the real constant minus one. Trailing zeroes @@ -1987,12 +2074,25 @@ real_minus_onep (const_tree expr) { STRIP_NOPS (expr); - return ((TREE_CODE (expr) == REAL_CST - && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconstm1) - && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr))))) - || (TREE_CODE (expr) == COMPLEX_CST - && real_minus_onep (TREE_REALPART (expr)) - && real_zerop (TREE_IMAGPART (expr)))); + switch (TREE_CODE (expr)) + { + case REAL_CST: + return REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconstm1) + && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr)))); + case COMPLEX_CST: + return real_minus_onep (TREE_REALPART (expr)) + && real_zerop (TREE_IMAGPART (expr)); + case VECTOR_CST: + { + unsigned i; + for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) + if (!real_minus_onep (VECTOR_CST_ELT (expr, i))) + return false; + return true; + } + default: + return false; + } } /* Nonzero if EXP is a constant or a cast of a constant. */ @@ -2040,11 +2140,11 @@ purpose_member (const_tree elem, tree list) /* Return true if ELEM is in V. */ bool -vec_member (const_tree elem, VEC(tree,gc) *v) +vec_member (const_tree elem, vec *v) { unsigned ix; tree t; - FOR_EACH_VEC_ELT (tree, v, ix, t) + FOR_EACH_VEC_SAFE_ELT (v, ix, t) if (elem == t) return true; return false; @@ -2205,13 +2305,13 @@ build_tree_list_stat (tree parm, tree value MEM_STAT_DECL) /* Build a chain of TREE_LIST nodes from a vector. */ tree -build_tree_list_vec_stat (const VEC(tree,gc) *vec MEM_STAT_DECL) +build_tree_list_vec_stat (const vec *vec MEM_STAT_DECL) { tree ret = NULL_TREE; tree *pp = &ret; unsigned int i; tree t; - FOR_EACH_VEC_ELT (tree, vec, i, t) + FOR_EACH_VEC_SAFE_ELT (vec, i, t) { *pp = build_tree_list_stat (NULL, t PASS_MEM_STAT); pp = &TREE_CHAIN (*pp); @@ -2228,8 +2328,7 @@ tree_cons_stat (tree purpose, tree value, tree chain MEM_STAT_DECL) { tree node; - node = ggc_alloc_zone_tree_node_stat (&tree_zone, sizeof (struct tree_list) - PASS_MEM_STAT); + node = ggc_alloc_tree_node_stat (sizeof (struct tree_list) PASS_MEM_STAT); memset (node, 0, sizeof (struct tree_common)); record_node_allocation_statistics (TREE_LIST, sizeof (struct tree_list)); @@ -2244,15 +2343,16 @@ tree_cons_stat (tree purpose, tree value, tree chain MEM_STAT_DECL) /* Return the values of the elements of a CONSTRUCTOR as a vector of trees. */ -VEC(tree,gc) * +vec * ctor_to_vec (tree ctor) { - VEC(tree, gc) *vec = VEC_alloc (tree, gc, CONSTRUCTOR_NELTS (ctor)); + vec *vec; + vec_alloc (vec, CONSTRUCTOR_NELTS (ctor)); unsigned int ix; tree val; FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), ix, val) - VEC_quick_push (tree, vec, val); + vec->quick_push (val); return vec; } @@ -2987,20 +3087,20 @@ type_contains_placeholder_p (tree type) /* Push tree EXP onto vector QUEUE if it is not already present. */ static void -push_without_duplicates (tree exp, VEC (tree, heap) **queue) +push_without_duplicates (tree exp, vec *queue) { unsigned int i; tree iter; - FOR_EACH_VEC_ELT (tree, *queue, i, iter) + FOR_EACH_VEC_ELT (*queue, i, iter) if (simple_cst_equal (iter, exp) == 1) break; if (!iter) - VEC_safe_push (tree, heap, *queue, exp); + queue->safe_push (exp); } -/* Given a tree EXP, find all occurences of references to fields +/* Given a tree EXP, find all occurrences of references to fields in a PLACEHOLDER_EXPR and place them in vector REFS without duplicates. Also record VAR_DECLs and CONST_DECLs. Note that we assume here that EXP contains only arithmetic expressions @@ -3008,7 +3108,7 @@ push_without_duplicates (tree exp, VEC (tree, heap) **queue) argument list. */ void -find_placeholder_in_expr (tree exp, VEC (tree, heap) **refs) +find_placeholder_in_expr (tree exp, vec *refs) { enum tree_code code = TREE_CODE (exp); tree inner; @@ -3469,8 +3569,7 @@ stabilize_reference (tree ref) case BIT_FIELD_REF: result = build_nt (BIT_FIELD_REF, stabilize_reference (TREE_OPERAND (ref, 0)), - stabilize_reference_1 (TREE_OPERAND (ref, 1)), - stabilize_reference_1 (TREE_OPERAND (ref, 2))); + TREE_OPERAND (ref, 1), TREE_OPERAND (ref, 2)); break; case ARRAY_REF: @@ -3640,8 +3739,6 @@ do { tree _node = (NODE); \ if (TREE_OPERAND (node, 2)) UPDATE_FLAGS (TREE_OPERAND (node, 2)); } - else if (TREE_CODE (node) == BIT_FIELD_REF) - UPDATE_FLAGS (TREE_OPERAND (node, 2)); } node = lang_hooks.expr_to_decl (node, &tc, &se); @@ -3700,7 +3797,7 @@ build1_stat (enum tree_code code, tree type, tree node MEM_STAT_DECL) gcc_assert (TREE_CODE_LENGTH (code) == 1); - t = ggc_alloc_zone_tree_node_stat (&tree_zone, length PASS_MEM_STAT); + t = ggc_alloc_tree_node_stat (length PASS_MEM_STAT); memset (t, 0, sizeof (struct tree_common)); @@ -3709,7 +3806,6 @@ build1_stat (enum tree_code code, tree type, tree node MEM_STAT_DECL) TREE_TYPE (t) = type; SET_EXPR_LOCATION (t, UNKNOWN_LOCATION); TREE_OPERAND (t, 0) = node; - TREE_BLOCK (t) = NULL_TREE; if (node && !TYPE_P (node)) { TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (node); @@ -3913,37 +4009,6 @@ build5_stat (enum tree_code code, tree tt, tree arg0, tree arg1, return t; } -tree -build6_stat (enum tree_code code, tree tt, tree arg0, tree arg1, - tree arg2, tree arg3, tree arg4, tree arg5 MEM_STAT_DECL) -{ - bool constant, read_only, side_effects; - tree t; - - gcc_assert (code == TARGET_MEM_REF); - - t = make_node_stat (code PASS_MEM_STAT); - TREE_TYPE (t) = tt; - - side_effects = TREE_SIDE_EFFECTS (t); - - PROCESS_ARG(0); - PROCESS_ARG(1); - PROCESS_ARG(2); - PROCESS_ARG(3); - PROCESS_ARG(4); - if (code == TARGET_MEM_REF) - side_effects = 0; - PROCESS_ARG(5); - - TREE_SIDE_EFFECTS (t) = side_effects; - TREE_THIS_VOLATILE (t) - = (code == TARGET_MEM_REF - && arg5 && TREE_THIS_VOLATILE (arg5)); - - return t; -} - /* Build a simple MEM_REF tree with the sematics of a plain INDIRECT_REF on the pointer PTR. */ @@ -3976,8 +4041,7 @@ double_int mem_ref_offset (const_tree t) { tree toff = TREE_OPERAND (t, 1); - return double_int_sext (tree_to_double_int (toff), - TYPE_PRECISION (TREE_TYPE (toff))); + return tree_to_double_int (toff).sext (TYPE_PRECISION (TREE_TYPE (toff))); } /* Return the pointer-type relevant for TBAA purposes from the @@ -4040,18 +4104,18 @@ build_nt (enum tree_code code, ...) } /* Similar to build_nt, but for creating a CALL_EXPR object with a - tree VEC. */ + tree vec. */ tree -build_nt_call_vec (tree fn, VEC(tree,gc) *args) +build_nt_call_vec (tree fn, vec *args) { tree ret, t; unsigned int ix; - ret = build_vl_exp (CALL_EXPR, VEC_length (tree, args) + 3); + ret = build_vl_exp (CALL_EXPR, vec_safe_length (args) + 3); CALL_EXPR_FN (ret) = fn; CALL_EXPR_STATIC_CHAIN (ret) = NULL_TREE; - FOR_EACH_VEC_ELT (tree, args, ix, t) + FOR_EACH_VEC_SAFE_ELT (args, ix, t) CALL_EXPR_ARG (ret, ix) = t; return ret; } @@ -4103,7 +4167,7 @@ build_fn_decl (const char *name, tree type) return decl; } -VEC(tree,gc) *all_translation_units; +vec *all_translation_units; /* Builds a new translation-unit decl with name NAME, queues it in the global list of translation-unit decls and returns it. */ @@ -4114,7 +4178,7 @@ build_translation_unit_decl (tree name) tree tu = build_decl (UNKNOWN_LOCATION, TRANSLATION_UNIT_DECL, name, NULL_TREE); TRANSLATION_UNIT_LANGUAGE (tu) = lang_hooks.name; - VEC_safe_push (tree, gc, all_translation_units, tu); + vec_safe_push (all_translation_units, tu); return tu; } @@ -4332,7 +4396,7 @@ comp_type_attributes (const_tree type1, const_tree type2) const struct attribute_spec *as; const_tree attr; - as = lookup_attribute_spec (TREE_PURPOSE (a)); + as = lookup_attribute_spec (get_attribute_name (a)); if (!as || as->affects_type_identity == false) continue; @@ -4346,7 +4410,7 @@ comp_type_attributes (const_tree type1, const_tree type2) { const struct attribute_spec *as; - as = lookup_attribute_spec (TREE_PURPOSE (a)); + as = lookup_attribute_spec (get_attribute_name (a)); if (!as || as->affects_type_identity == false) continue; @@ -4414,7 +4478,7 @@ free_lang_data_in_binfo (tree binfo) BINFO_INHERITANCE_CHAIN (binfo) = NULL_TREE; BINFO_SUBVTT_INDEX (binfo) = NULL_TREE; - FOR_EACH_VEC_ELT (tree, BINFO_BASE_BINFOS (binfo), i, t) + FOR_EACH_VEC_ELT (*BINFO_BASE_BINFOS (binfo), i, t) free_lang_data_in_binfo (t); } @@ -4684,16 +4748,16 @@ free_lang_data_in_decl (tree decl) struct free_lang_data_d { /* Worklist to avoid excessive recursion. */ - VEC(tree,heap) *worklist; + vec worklist; /* Set of traversed objects. Used to avoid duplicate visits. */ struct pointer_set_t *pset; /* Array of symbols to process with free_lang_data_in_decl. */ - VEC(tree,heap) *decls; + vec decls; /* Array of types to process with free_lang_data_in_type. */ - VEC(tree,heap) *types; + vec types; }; @@ -4733,13 +4797,13 @@ add_tree_to_fld_list (tree t, struct free_lang_data_d *fld) { if (DECL_P (t)) { - VEC_safe_push (tree, heap, fld->decls, t); + fld->decls.safe_push (t); if (debug_info_level > DINFO_LEVEL_TERSE) save_debug_info_for_decl (t); } else if (TYPE_P (t)) { - VEC_safe_push (tree, heap, fld->types, t); + fld->types.safe_push (t); if (debug_info_level > DINFO_LEVEL_TERSE) save_debug_info_for_type (t); } @@ -4753,7 +4817,7 @@ static inline void fld_worklist_push (tree t, struct free_lang_data_d *fld) { if (t && !is_lang_specific (t) && !pointer_set_contains (fld->pset, t)) - VEC_safe_push (tree, heap, fld->worklist, (t)); + fld->worklist.safe_push ((t)); } @@ -4869,8 +4933,7 @@ find_decls_types_r (tree *tp, int *ws, void *data) { unsigned i; tree tem; - for (i = 0; VEC_iterate (tree, BINFO_BASE_BINFOS (TYPE_BINFO (t)), - i, tem); ++i) + FOR_EACH_VEC_ELT (*BINFO_BASE_BINFOS (TYPE_BINFO (t)), i, tem) fld_worklist_push (TREE_TYPE (tem), fld); tem = BINFO_VIRTUALS (TYPE_BINFO (t)); if (tem @@ -4928,9 +4991,9 @@ find_decls_types (tree t, struct free_lang_data_d *fld) { if (!pointer_set_contains (fld->pset, t)) walk_tree (&t, find_decls_types_r, fld, fld->pset); - if (VEC_empty (tree, fld->worklist)) + if (fld->worklist.is_empty ()) break; - t = VEC_pop (tree, fld->worklist); + t = fld->worklist.pop (); } } @@ -5014,14 +5077,14 @@ find_decls_types_in_node (struct cgraph_node *n, struct free_lang_data_d *fld) unsigned ix; tree t; - find_decls_types (n->decl, fld); + find_decls_types (n->symbol.decl, fld); - if (!gimple_has_body_p (n->decl)) + if (!gimple_has_body_p (n->symbol.decl)) return; gcc_assert (current_function_decl == NULL_TREE && cfun == NULL); - fn = DECL_STRUCT_FUNCTION (n->decl); + fn = DECL_STRUCT_FUNCTION (n->symbol.decl); /* Traverse locals. */ FOR_EACH_LOCAL_DECL (fn, ix, t) @@ -5077,7 +5140,7 @@ find_decls_types_in_node (struct cgraph_node *n, struct free_lang_data_d *fld) static void find_decls_types_in_var (struct varpool_node *v, struct free_lang_data_d *fld) { - find_decls_types (v->decl, fld); + find_decls_types (v->symbol.decl, fld); } /* If T needs an assembler name, have one created for it. */ @@ -5137,39 +5200,39 @@ free_lang_data_in_cgraph (void) /* Initialize sets and arrays to store referenced decls and types. */ fld.pset = pointer_set_create (); - fld.worklist = NULL; - fld.decls = VEC_alloc (tree, heap, 100); - fld.types = VEC_alloc (tree, heap, 100); + fld.worklist.create (0); + fld.decls.create (100); + fld.types.create (100); /* Find decls and types in the body of every function in the callgraph. */ - for (n = cgraph_nodes; n; n = n->next) + FOR_EACH_FUNCTION (n) find_decls_types_in_node (n, &fld); - FOR_EACH_VEC_ELT (alias_pair, alias_pairs, i, p) + FOR_EACH_VEC_SAFE_ELT (alias_pairs, i, p) find_decls_types (p->decl, &fld); /* Find decls and types in every varpool symbol. */ - for (v = varpool_nodes; v; v = v->next) + FOR_EACH_VARIABLE (v) find_decls_types_in_var (v, &fld); /* Set the assembler name on every decl found. We need to do this now because free_lang_data_in_decl will invalidate data needed for mangling. This breaks mangling on interdependent decls. */ - FOR_EACH_VEC_ELT (tree, fld.decls, i, t) + FOR_EACH_VEC_ELT (fld.decls, i, t) assign_assembler_name_if_neeeded (t); /* Traverse every decl found freeing its language data. */ - FOR_EACH_VEC_ELT (tree, fld.decls, i, t) + FOR_EACH_VEC_ELT (fld.decls, i, t) free_lang_data_in_decl (t); /* Traverse every type found freeing its language data. */ - FOR_EACH_VEC_ELT (tree, fld.types, i, t) + FOR_EACH_VEC_ELT (fld.types, i, t) free_lang_data_in_type (t); pointer_set_destroy (fld.pset); - VEC_free (tree, heap, fld.worklist); - VEC_free (tree, heap, fld.decls); - VEC_free (tree, heap, fld.types); + fld.worklist.release (); + fld.decls.release (); + fld.types.release (); } @@ -5201,7 +5264,6 @@ free_lang_data (void) /* Reset some langhooks. Do not reset types_compatible_p, it may still be used indirectly via the get_alias_set langhook. */ - lang_hooks.callgraph.analyze_expr = NULL; lang_hooks.dwarf_name = lhd_dwarf_name; lang_hooks.decl_printable_name = gimple_decl_printable_name; /* We do not want the default decl_assembler_name implementation, @@ -5212,9 +5274,7 @@ free_lang_data (void) devise a separate, middle-end private scheme for it. */ /* Reset diagnostic machinery. */ - diagnostic_starter (global_dc) = default_tree_diagnostic_starter; - diagnostic_finalizer (global_dc) = default_diagnostic_finalizer; - diagnostic_format_decoder (global_dc) = default_tree_printer; + tree_diagnostics_defaults (global_dc); return 0; } @@ -5225,6 +5285,7 @@ struct simple_ipa_opt_pass pass_ipa_free_lang_data = { SIMPLE_IPA_PASS, "*free_lang_data", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ NULL, /* gate */ free_lang_data, /* execute */ NULL, /* sub */ @@ -5272,11 +5333,12 @@ private_lookup_attribute (const char *attr_name, size_t attr_len, tree list) { while (list) { - size_t ident_len = IDENTIFIER_LENGTH (TREE_PURPOSE (list)); + size_t ident_len = IDENTIFIER_LENGTH (get_attribute_name (list)); if (ident_len == attr_len) { - if (strcmp (attr_name, IDENTIFIER_POINTER (TREE_PURPOSE (list))) == 0) + if (!strcmp (attr_name, + IDENTIFIER_POINTER (get_attribute_name (list)))) break; } /* TODO: If we made sure that attributes were stored in the @@ -5284,7 +5346,7 @@ private_lookup_attribute (const char *attr_name, size_t attr_len, tree list) to '__text__') then we could avoid the following case. */ else if (ident_len == attr_len + 4) { - const char *p = IDENTIFIER_POINTER (TREE_PURPOSE (list)); + const char *p = IDENTIFIER_POINTER (get_attribute_name (list)); if (p[0] == '_' && p[1] == '_' && p[ident_len - 2] == '_' && p[ident_len - 1] == '_' && strncmp (attr_name, p + 2, attr_len) == 0) @@ -5314,10 +5376,11 @@ lookup_ident_attribute (tree attr_identifier, tree list) while (list) { - gcc_checking_assert (TREE_CODE (TREE_PURPOSE (list)) == IDENTIFIER_NODE); + gcc_checking_assert (TREE_CODE (get_attribute_name (list)) + == IDENTIFIER_NODE); /* Identifiers can be compared directly for equality. */ - if (attr_identifier == TREE_PURPOSE (list)) + if (attr_identifier == get_attribute_name (list)) break; /* If they are not equal, they may still be one in the form @@ -5327,11 +5390,11 @@ lookup_ident_attribute (tree attr_identifier, tree list) the fact that we're comparing identifiers. :-) */ { size_t attr_len = IDENTIFIER_LENGTH (attr_identifier); - size_t ident_len = IDENTIFIER_LENGTH (TREE_PURPOSE (list)); + size_t ident_len = IDENTIFIER_LENGTH (get_attribute_name (list)); if (ident_len == attr_len + 4) { - const char *p = IDENTIFIER_POINTER (TREE_PURPOSE (list)); + const char *p = IDENTIFIER_POINTER (get_attribute_name (list)); const char *q = IDENTIFIER_POINTER (attr_identifier); if (p[0] == '_' && p[1] == '_' && p[ident_len - 2] == '_' && p[ident_len - 1] == '_' @@ -5340,7 +5403,7 @@ lookup_ident_attribute (tree attr_identifier, tree list) } else if (ident_len + 4 == attr_len) { - const char *p = IDENTIFIER_POINTER (TREE_PURPOSE (list)); + const char *p = IDENTIFIER_POINTER (get_attribute_name (list)); const char *q = IDENTIFIER_POINTER (attr_identifier); if (q[0] == '_' && q[1] == '_' && q[attr_len - 2] == '_' && q[attr_len - 1] == '_' @@ -5370,7 +5433,7 @@ remove_attribute (const char *attr_name, tree list) tree l = *p; /* TODO: If we were storing attributes in normalized form, here we could use a simple strcmp(). */ - if (private_is_attribute_p (attr_name, attr_len, TREE_PURPOSE (l))) + if (private_is_attribute_p (attr_name, attr_len, get_attribute_name (l))) *p = TREE_CHAIN (l); else p = &TREE_CHAIN (l); @@ -5407,9 +5470,11 @@ merge_attributes (tree a1, tree a2) for (; a2 != 0; a2 = TREE_CHAIN (a2)) { tree a; - for (a = lookup_ident_attribute (TREE_PURPOSE (a2), attributes); + for (a = lookup_ident_attribute (get_attribute_name (a2), + attributes); a != NULL_TREE && !attribute_value_equal (a, a2); - a = lookup_ident_attribute (TREE_PURPOSE (a2), TREE_CHAIN (a))) + a = lookup_ident_attribute (get_attribute_name (a2), + TREE_CHAIN (a))) ; if (a == NULL_TREE) { @@ -6040,7 +6105,7 @@ decl_value_expr_insert (tree from, tree to) /* Lookup a vector of debug arguments for FROM, and return it if we find one. */ -VEC(tree, gc) ** +vec ** decl_debug_args_lookup (tree from) { struct tree_vec_map *h, in; @@ -6059,7 +6124,7 @@ decl_debug_args_lookup (tree from) /* Insert a mapping FROM->empty vector of debug arguments in the value expression hashtable. */ -VEC(tree, gc) ** +vec ** decl_debug_args_insert (tree from) { struct tree_vec_map *h; @@ -6283,11 +6348,12 @@ type_hash_canon (unsigned int hashcode, tree type) t1 = type_hash_lookup (hashcode, type); if (t1 != 0) { -#ifdef GATHER_STATISTICS - tree_code_counts[(int) TREE_CODE (type)]--; - tree_node_counts[(int) t_kind]--; - tree_node_sizes[(int) t_kind] -= sizeof (struct tree_type_non_common); -#endif + if (GATHER_STATISTICS) + { + tree_code_counts[(int) TREE_CODE (type)]--; + tree_node_counts[(int) t_kind]--; + tree_node_sizes[(int) t_kind] -= sizeof (struct tree_type_non_common); + } return t1; } else @@ -6330,7 +6396,7 @@ attribute_hash_list (const_tree list, hashval_t hashcode) for (tail = list; tail; tail = TREE_CHAIN (tail)) /* ??? Do we want to add in TREE_VALUE too? */ hashcode = iterative_hash_object - (IDENTIFIER_HASH_VALUE (TREE_PURPOSE (tail)), hashcode); + (IDENTIFIER_HASH_VALUE (get_attribute_name (tail)), hashcode); return hashcode; } @@ -6367,7 +6433,7 @@ attribute_list_contained (const_tree l1, const_tree l2) /* Maybe the lists are similar. */ for (t1 = l1, t2 = l2; t1 != 0 && t2 != 0 - && TREE_PURPOSE (t1) == TREE_PURPOSE (t2) + && get_attribute_name (t1) == get_attribute_name (t2) && TREE_VALUE (t1) == TREE_VALUE (t2); t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2)) ; @@ -6382,9 +6448,9 @@ attribute_list_contained (const_tree l1, const_tree l2) /* This CONST_CAST is okay because lookup_attribute does not modify its argument and the return value is assigned to a const_tree. */ - for (attr = lookup_ident_attribute (TREE_PURPOSE (t2), CONST_CAST_TREE(l1)); + for (attr = lookup_ident_attribute (get_attribute_name (t2), CONST_CAST_TREE(l1)); attr != NULL_TREE && !attribute_value_equal (t2, attr); - attr = lookup_ident_attribute (TREE_PURPOSE (t2), TREE_CHAIN (attr))) + attr = lookup_ident_attribute (get_attribute_name (t2), TREE_CHAIN (attr))) ; if (attr == NULL_TREE) @@ -6514,9 +6580,7 @@ host_integerp (const_tree t, int pos) && (HOST_WIDE_INT) TREE_INT_CST_LOW (t) >= 0) || (! pos && TREE_INT_CST_HIGH (t) == -1 && (HOST_WIDE_INT) TREE_INT_CST_LOW (t) < 0 - && (!TYPE_UNSIGNED (TREE_TYPE (t)) - || (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE - && TYPE_IS_SIZETYPE (TREE_TYPE (t))))) + && !TYPE_UNSIGNED (TREE_TYPE (t))) || (pos && TREE_INT_CST_HIGH (t) == 0))); } @@ -6539,7 +6603,7 @@ HOST_WIDE_INT size_low_cst (const_tree t) { double_int d = tree_to_double_int (t); - return double_int_sext (d, TYPE_PRECISION (TREE_TYPE (t))).low; + return d.sext (TYPE_PRECISION (TREE_TYPE (t))).low; } /* Return the most significant (sign) bit of T. */ @@ -6680,16 +6744,15 @@ simple_cst_equal (const_tree t1, const_tree t2) case CONSTRUCTOR: { unsigned HOST_WIDE_INT idx; - VEC(constructor_elt, gc) *v1 = CONSTRUCTOR_ELTS (t1); - VEC(constructor_elt, gc) *v2 = CONSTRUCTOR_ELTS (t2); + vec *v1 = CONSTRUCTOR_ELTS (t1); + vec *v2 = CONSTRUCTOR_ELTS (t2); - if (VEC_length (constructor_elt, v1) != VEC_length (constructor_elt, v2)) + if (vec_safe_length (v1) != vec_safe_length (v2)) return false; - for (idx = 0; idx < VEC_length (constructor_elt, v1); ++idx) + for (idx = 0; idx < vec_safe_length (v1); ++idx) /* ??? Should we handle also fields here? */ - if (!simple_cst_equal (VEC_index (constructor_elt, v1, idx)->value, - VEC_index (constructor_elt, v2, idx)->value)) + if (!simple_cst_equal ((*v1)[idx].value, (*v2)[idx].value)) return false; return true; } @@ -6811,6 +6874,20 @@ compare_tree_int (const_tree t, unsigned HOST_WIDE_INT u) return 1; } +/* Return true if SIZE represents a constant size that is in bounds of + what the middle-end and the backend accepts (covering not more than + half of the address-space). */ + +bool +valid_constant_size_p (const_tree size) +{ + if (! host_integerp (size, 1) + || TREE_OVERFLOW (size) + || tree_int_cst_sign_bit (size) != 0) + return false; + return true; +} + /* Return true if CODE represents an associative tree code. Otherwise return false. */ bool @@ -6842,6 +6919,7 @@ commutative_tree_code (enum tree_code code) { case PLUS_EXPR: case MULT_EXPR: + case MULT_HIGHPART_EXPR: case MIN_EXPR: case MAX_EXPR: case BIT_IOR_EXPR: @@ -6856,6 +6934,11 @@ commutative_tree_code (enum tree_code code) case TRUTH_AND_EXPR: case TRUTH_XOR_EXPR: case TRUTH_OR_EXPR: + case WIDEN_MULT_EXPR: + case VEC_WIDEN_MULT_HI_EXPR: + case VEC_WIDEN_MULT_LO_EXPR: + case VEC_WIDEN_MULT_EVEN_EXPR: + case VEC_WIDEN_MULT_ODD_EXPR: return true; default: @@ -6925,7 +7008,12 @@ iterative_hash_expr (const_tree t, hashval_t val) val = iterative_hash_expr (TREE_REALPART (t), val); return iterative_hash_expr (TREE_IMAGPART (t), val); case VECTOR_CST: - return iterative_hash_expr (TREE_VECTOR_CST_ELTS (t), val); + { + unsigned i; + for (i = 0; i < VECTOR_CST_NELTS (t); ++i) + val = iterative_hash_expr (VECTOR_CST_ELT (t, i), val); + return val; + } case SSA_NAME: /* We can just compare by pointer. */ return iterative_hash_host_wide_int (SSA_NAME_VERSION (t), val); @@ -8232,18 +8320,6 @@ int_fits_type_p (const_tree c, const_tree type) dc = tree_to_double_int (c); unsc = TYPE_UNSIGNED (TREE_TYPE (c)); - if (TREE_CODE (TREE_TYPE (c)) == INTEGER_TYPE - && TYPE_IS_SIZETYPE (TREE_TYPE (c)) - && unsc) - /* So c is an unsigned integer whose type is sizetype and type is not. - sizetype'd integers are sign extended even though they are - unsigned. If the integer value fits in the lower end word of c, - and if the higher end word has all its bits set to 1, that - means the higher end bits are set to 1 only for sign extension. - So let's convert c into an equivalent zero extended unsigned - integer. */ - dc = double_int_zext (dc, TYPE_PRECISION (TREE_TYPE (c))); - retry: type_low_bound = TYPE_MIN_VALUE (type); type_high_bound = TYPE_MAX_VALUE (type); @@ -8262,21 +8338,17 @@ retry: if (type_low_bound && TREE_CODE (type_low_bound) == INTEGER_CST) { dd = tree_to_double_int (type_low_bound); - if (TREE_CODE (type) == INTEGER_TYPE - && TYPE_IS_SIZETYPE (type) - && TYPE_UNSIGNED (type)) - dd = double_int_zext (dd, TYPE_PRECISION (type)); if (unsc != TYPE_UNSIGNED (TREE_TYPE (type_low_bound))) { - int c_neg = (!unsc && double_int_negative_p (dc)); - int t_neg = (unsc && double_int_negative_p (dd)); + int c_neg = (!unsc && dc.is_negative ()); + int t_neg = (unsc && dd.is_negative ()); if (c_neg && !t_neg) return false; - if ((c_neg || !t_neg) && double_int_ucmp (dc, dd) < 0) + if ((c_neg || !t_neg) && dc.ult (dd)) return false; } - else if (double_int_cmp (dc, dd, unsc) < 0) + else if (dc.cmp (dd, unsc) < 0) return false; ok_for_low_bound = true; } @@ -8287,21 +8359,17 @@ retry: if (type_high_bound && TREE_CODE (type_high_bound) == INTEGER_CST) { dd = tree_to_double_int (type_high_bound); - if (TREE_CODE (type) == INTEGER_TYPE - && TYPE_IS_SIZETYPE (type) - && TYPE_UNSIGNED (type)) - dd = double_int_zext (dd, TYPE_PRECISION (type)); if (unsc != TYPE_UNSIGNED (TREE_TYPE (type_high_bound))) { - int c_neg = (!unsc && double_int_negative_p (dc)); - int t_neg = (unsc && double_int_negative_p (dd)); + int c_neg = (!unsc && dc.is_negative ()); + int t_neg = (unsc && dd.is_negative ()); if (t_neg && !c_neg) return false; - if ((t_neg || !c_neg) && double_int_ucmp (dc, dd) > 0) + if ((t_neg || !c_neg) && dc.ugt (dd)) return false; } - else if (double_int_cmp (dc, dd, unsc) > 0) + else if (dc.cmp (dd, unsc) > 0) return false; ok_for_high_bound = true; } @@ -8315,7 +8383,7 @@ retry: /* Perform some generic filtering which may allow making a decision even if the bounds are not constant. First, negative integers never fit in unsigned types, */ - if (TYPE_UNSIGNED (type) && !unsc && double_int_negative_p (dc)) + if (TYPE_UNSIGNED (type) && !unsc && dc.is_negative ()) return false; /* Second, narrower types always fit in wider ones. */ @@ -8370,9 +8438,8 @@ get_type_static_bounds (const_tree type, mpz_t min, mpz_t max) else { double_int mn; - mn = double_int_mask (TYPE_PRECISION (type) - 1); - mn = double_int_sext (double_int_add (mn, double_int_one), - TYPE_PRECISION (type)); + mn = double_int::mask (TYPE_PRECISION (type) - 1); + mn = (mn + double_int_one).sext (TYPE_PRECISION (type)); mpz_set_double_int (min, mn, false); } } @@ -8384,10 +8451,10 @@ get_type_static_bounds (const_tree type, mpz_t min, mpz_t max) else { if (TYPE_UNSIGNED (type)) - mpz_set_double_int (max, double_int_mask (TYPE_PRECISION (type)), + mpz_set_double_int (max, double_int::mask (TYPE_PRECISION (type)), true); else - mpz_set_double_int (max, double_int_mask (TYPE_PRECISION (type) - 1), + mpz_set_double_int (max, double_int::mask (TYPE_PRECISION (type) - 1), true); } } @@ -8445,14 +8512,19 @@ variably_modified_type_p (tree type, tree fn) tree t; /* Test if T is either variable (if FN is zero) or an expression containing - a variable in FN. */ + a variable in FN. If TYPE isn't gimplified, return true also if + gimplify_one_sizepos would gimplify the expression into a local + variable. */ #define RETURN_TRUE_IF_VAR(T) \ do { tree _t = (T); \ if (_t != NULL_TREE \ && _t != error_mark_node \ && TREE_CODE (_t) != INTEGER_CST \ && TREE_CODE (_t) != PLACEHOLDER_EXPR \ - && (!fn || walk_tree (&_t, find_var_from_fn, fn, NULL))) \ + && (!fn \ + || (!TYPE_SIZES_GIMPLIFIED (type) \ + && !is_gimple_sizepos (_t)) \ + || walk_tree (&_t, find_var_from_fn, fn, NULL))) \ return true; } while (0) if (type == error_mark_node) @@ -8652,36 +8724,34 @@ get_callee_fndecl (const_tree call) void dump_tree_statistics (void) { -#ifdef GATHER_STATISTICS - int i; - int total_nodes, total_bytes; -#endif + if (GATHER_STATISTICS) + { + int i; + int total_nodes, total_bytes; + fprintf (stderr, "Kind Nodes Bytes\n"); + fprintf (stderr, "---------------------------------------\n"); + total_nodes = total_bytes = 0; + for (i = 0; i < (int) all_kinds; i++) + { + fprintf (stderr, "%-20s %7d %10d\n", tree_node_kind_names[i], + tree_node_counts[i], tree_node_sizes[i]); + total_nodes += tree_node_counts[i]; + total_bytes += tree_node_sizes[i]; + } + fprintf (stderr, "---------------------------------------\n"); + fprintf (stderr, "%-20s %7d %10d\n", "Total", total_nodes, total_bytes); + fprintf (stderr, "---------------------------------------\n"); + fprintf (stderr, "Code Nodes\n"); + fprintf (stderr, "----------------------------\n"); + for (i = 0; i < (int) MAX_TREE_CODES; i++) + fprintf (stderr, "%-20s %7d\n", tree_code_name[i], tree_code_counts[i]); + fprintf (stderr, "----------------------------\n"); + ssanames_print_statistics (); + phinodes_print_statistics (); + } + else + fprintf (stderr, "(No per-node statistics)\n"); - fprintf (stderr, "\n??? tree nodes created\n\n"); -#ifdef GATHER_STATISTICS - fprintf (stderr, "Kind Nodes Bytes\n"); - fprintf (stderr, "---------------------------------------\n"); - total_nodes = total_bytes = 0; - for (i = 0; i < (int) all_kinds; i++) - { - fprintf (stderr, "%-20s %7d %10d\n", tree_node_kind_names[i], - tree_node_counts[i], tree_node_sizes[i]); - total_nodes += tree_node_counts[i]; - total_bytes += tree_node_sizes[i]; - } - fprintf (stderr, "---------------------------------------\n"); - fprintf (stderr, "%-20s %7d %10d\n", "Total", total_nodes, total_bytes); - fprintf (stderr, "---------------------------------------\n"); - fprintf (stderr, "Code Nodes\n"); - fprintf (stderr, "----------------------------\n"); - for (i = 0; i < (int) MAX_TREE_CODES; i++) - fprintf (stderr, "%-20s %7d\n", tree_code_name[i], tree_code_counts[i]); - fprintf (stderr, "----------------------------\n"); - ssanames_print_statistics (); - phinodes_print_statistics (); -#else - fprintf (stderr, "(No per-node statistics)\n"); -#endif print_type_hash_statistics (); print_debug_expr_statistics (); print_value_expr_statistics (); @@ -8692,23 +8762,37 @@ dump_tree_statistics (void) /* Generate a crc32 of a byte. */ -unsigned -crc32_byte (unsigned chksum, char byte) +static unsigned +crc32_unsigned_bits (unsigned chksum, unsigned value, unsigned bits) { - unsigned value = (unsigned) byte << 24; - unsigned ix; - - for (ix = 8; ix--; value <<= 1) - { - unsigned feedback; + unsigned ix; - feedback = (value ^ chksum) & 0x80000000 ? 0x04c11db7 : 0; - chksum <<= 1; - chksum ^= feedback; - } + for (ix = bits; ix--; value <<= 1) + { + unsigned feedback; + + feedback = (value ^ chksum) & 0x80000000 ? 0x04c11db7 : 0; + chksum <<= 1; + chksum ^= feedback; + } return chksum; } +/* Generate a crc32 of a 32-bit unsigned. */ + +unsigned +crc32_unsigned (unsigned chksum, unsigned value) +{ + return crc32_unsigned_bits (chksum, value, 32); +} + +/* Generate a crc32 of a byte. */ + +unsigned +crc32_byte (unsigned chksum, char byte) +{ + return crc32_unsigned_bits (chksum, (unsigned) byte << 24, 8); +} /* Generate a crc32 of a string. */ @@ -9353,6 +9437,7 @@ build_common_tree_nodes (bool signed_char, bool short_double) integer_ptr_type_node = build_pointer_type (integer_type_node); /* Fixed size integer types. */ + uint16_type_node = build_nonstandard_integer_type (16, true); uint32_type_node = build_nonstandard_integer_type (32, true); uint64_type_node = build_nonstandard_integer_type (64, true); @@ -9448,6 +9533,39 @@ build_common_tree_nodes (bool signed_char, bool short_double) } } +/* Modify DECL for given flags. */ +void +set_call_expr_flags (tree decl, int flags) +{ + if (flags & ECF_NOTHROW) + TREE_NOTHROW (decl) = 1; + if (flags & ECF_CONST) + TREE_READONLY (decl) = 1; + if (flags & ECF_PURE) + DECL_PURE_P (decl) = 1; + if (flags & ECF_LOOPING_CONST_OR_PURE) + DECL_LOOPING_CONST_OR_PURE_P (decl) = 1; + if (flags & ECF_NOVOPS) + DECL_IS_NOVOPS (decl) = 1; + if (flags & ECF_NORETURN) + TREE_THIS_VOLATILE (decl) = 1; + if (flags & ECF_MALLOC) + DECL_IS_MALLOC (decl) = 1; + if (flags & ECF_RETURNS_TWICE) + DECL_IS_RETURNS_TWICE (decl) = 1; + if (flags & ECF_LEAF) + DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("leaf"), + NULL, DECL_ATTRIBUTES (decl)); + if ((flags & ECF_TM_PURE) && flag_tm) + DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("transaction_pure"), + NULL, DECL_ATTRIBUTES (decl)); + /* Looping const or pure is implied by noreturn. + There is currently no way to declare looping const or looping pure alone. */ + gcc_assert (!(flags & ECF_LOOPING_CONST_OR_PURE) + || ((flags & ECF_NORETURN) && (flags & (ECF_CONST | ECF_PURE)))); +} + + /* A subroutine of build_common_builtin_nodes. Define a builtin function. */ static void @@ -9458,23 +9576,7 @@ local_define_builtin (const char *name, tree type, enum built_in_function code, decl = add_builtin_function (name, type, code, BUILT_IN_NORMAL, library_name, NULL_TREE); - if (ecf_flags & ECF_CONST) - TREE_READONLY (decl) = 1; - if (ecf_flags & ECF_PURE) - DECL_PURE_P (decl) = 1; - if (ecf_flags & ECF_LOOPING_CONST_OR_PURE) - DECL_LOOPING_CONST_OR_PURE_P (decl) = 1; - if (ecf_flags & ECF_NORETURN) - TREE_THIS_VOLATILE (decl) = 1; - if (ecf_flags & ECF_NOTHROW) - TREE_NOTHROW (decl) = 1; - if (ecf_flags & ECF_MALLOC) - DECL_IS_MALLOC (decl) = 1; - if (ecf_flags & ECF_LEAF) - DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("leaf"), - NULL, DECL_ATTRIBUTES (decl)); - if ((ecf_flags & ECF_TM_PURE) && flag_tm) - apply_tm_attr (decl, get_identifier ("transaction_pure")); + set_call_expr_flags (decl, ecf_flags); set_builtin_decl (code, decl, true); } @@ -9489,6 +9591,15 @@ build_common_builtin_nodes (void) tree tmp, ftype; int ecf_flags; + if (!builtin_decl_explicit_p (BUILT_IN_UNREACHABLE)) + { + ftype = build_function_type (void_type_node, void_list_node); + local_define_builtin ("__builtin_unreachable", ftype, BUILT_IN_UNREACHABLE, + "__builtin_unreachable", + ECF_NOTHROW | ECF_LEAF | ECF_NORETURN + | ECF_CONST | ECF_LEAF); + } + if (!builtin_decl_explicit_p (BUILT_IN_MEMCPY) || !builtin_decl_explicit_p (BUILT_IN_MEMMOVE)) { @@ -9873,10 +9984,13 @@ initializer_zerop (const_tree init) && ! REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (TREE_IMAGPART (init)))); case VECTOR_CST: - for (elt = TREE_VECTOR_CST_ELTS (init); elt; elt = TREE_CHAIN (elt)) - if (!initializer_zerop (TREE_VALUE (elt))) - return false; - return true; + { + unsigned i; + for (i = 0; i < VECTOR_CST_NELTS (init); ++i) + if (!initializer_zerop (VECTOR_CST_ELT (init, i))) + return false; + return true; + } case CONSTRUCTOR: { @@ -9956,7 +10070,7 @@ build_vl_exp_stat (enum tree_code code, int len MEM_STAT_DECL) record_node_allocation_statistics (code, length); - t = ggc_alloc_zone_cleared_tree_node_stat (&tree_zone, length PASS_MEM_STAT); + t = ggc_alloc_cleared_tree_node_stat (length PASS_MEM_STAT); TREE_SET_CODE (t, code); @@ -10035,16 +10149,16 @@ build_call_array_loc (location_t loc, tree return_type, tree fn, return t; } -/* Like build_call_array, but takes a VEC. */ +/* Like build_call_array, but takes a vec. */ tree -build_call_vec (tree return_type, tree fn, VEC(tree,gc) *args) +build_call_vec (tree return_type, tree fn, vec *args) { tree ret, t; unsigned int ix; - ret = build_call_1 (return_type, fn, VEC_length (tree, args)); - FOR_EACH_VEC_ELT (tree, args, ix, t) + ret = build_call_1 (return_type, fn, vec_safe_length (args)); + FOR_EACH_VEC_SAFE_ELT (args, ix, t) CALL_EXPR_ARG (ret, ix) = t; process_call_operands (ret); return ret; @@ -10118,9 +10232,6 @@ range_in_array_bounds_p (tree ref) bool needs_to_live_in_memory (const_tree t) { - if (TREE_CODE (t) == SSA_NAME) - t = SSA_NAME_VAR (t); - return (TREE_ADDRESSABLE (t) || is_global_var (t) || (TREE_CODE (t) == RESULT_DECL @@ -10161,7 +10272,7 @@ widest_int_cst_value (const_tree x) unsigned HOST_WIDEST_INT val = TREE_INT_CST_LOW (x); #if HOST_BITS_PER_WIDEST_INT > HOST_BITS_PER_WIDE_INT - gcc_assert (HOST_BITS_PER_WIDEST_INT >= 2 * HOST_BITS_PER_WIDE_INT); + gcc_assert (HOST_BITS_PER_WIDEST_INT >= HOST_BITS_PER_DOUBLE_INT); val |= (((unsigned HOST_WIDEST_INT) TREE_INT_CST_HIGH (x)) << HOST_BITS_PER_WIDE_INT); #else @@ -10182,32 +10293,37 @@ widest_int_cst_value (const_tree x) return val; } -/* If TYPE is an integral type, return an equivalent type which is - unsigned iff UNSIGNEDP is true. If TYPE is not an integral type, - return TYPE itself. */ +/* If TYPE is an integral or pointer type, return an integer type with + the same precision which is unsigned iff UNSIGNEDP is true, or itself + if TYPE is already an integer type of signedness UNSIGNEDP. */ tree signed_or_unsigned_type_for (int unsignedp, tree type) { - tree t = type; - if (POINTER_TYPE_P (type)) + if (TREE_CODE (type) == INTEGER_TYPE && TYPE_UNSIGNED (type) == unsignedp) + return type; + + if (TREE_CODE (type) == VECTOR_TYPE) { - /* If the pointer points to the normal address space, use the - size_type_node. Otherwise use an appropriate size for the pointer - based on the named address space it points to. */ - if (!TYPE_ADDR_SPACE (TREE_TYPE (t))) - t = size_type_node; - else - return lang_hooks.types.type_for_size (TYPE_PRECISION (t), unsignedp); + tree inner = TREE_TYPE (type); + tree inner2 = signed_or_unsigned_type_for (unsignedp, inner); + if (!inner2) + return NULL_TREE; + if (inner == inner2) + return type; + return build_vector_type (inner2, TYPE_VECTOR_SUBPARTS (type)); } - if (!INTEGRAL_TYPE_P (t) || TYPE_UNSIGNED (t) == unsignedp) - return t; + if (!INTEGRAL_TYPE_P (type) + && !POINTER_TYPE_P (type)) + return NULL_TREE; - return lang_hooks.types.type_for_size (TYPE_PRECISION (t), unsignedp); + return build_nonstandard_integer_type (TYPE_PRECISION (type), unsignedp); } -/* Returns unsigned variant of TYPE. */ +/* If TYPE is an integral or pointer type, return an integer type with + the same precision which is unsigned, or itself if TYPE is already an + unsigned integer type. */ tree unsigned_type_for (tree type) @@ -10215,7 +10331,9 @@ unsigned_type_for (tree type) return signed_or_unsigned_type_for (1, type); } -/* Returns signed variant of TYPE. */ +/* If TYPE is an integral or pointer type, return an integer type with + the same precision which is signed, or itself if TYPE is already a + signed integer type. */ tree signed_type_for (tree type) @@ -10223,6 +10341,22 @@ signed_type_for (tree type) return signed_or_unsigned_type_for (0, type); } +/* If TYPE is a vector type, return a signed integer vector type with the + same width and number of subparts. Otherwise return boolean_type_node. */ + +tree +truth_type_for (tree type) +{ + if (TREE_CODE (type) == VECTOR_TYPE) + { + tree elem = lang_hooks.types.type_for_size + (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (type))), 0); + return build_opaque_vector_type (elem, TYPE_VECTOR_SUBPARTS (type)); + } + else + return boolean_type_node; +} + /* Returns the largest value obtainable by casting something in INNER type to OUTER type. */ @@ -10283,7 +10417,7 @@ upper_bound_in_type (tree outer, tree inner) else { high.high = ((~(unsigned HOST_WIDE_INT) 0) - >> (2 * HOST_BITS_PER_WIDE_INT - prec)); + >> (HOST_BITS_PER_DOUBLE_INT - prec)); high.low = ~(unsigned HOST_WIDE_INT) 0; } @@ -10584,9 +10718,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data, unsigned HOST_WIDE_INT idx; constructor_elt *ce; - for (idx = 0; - VEC_iterate(constructor_elt, CONSTRUCTOR_ELTS (*tp), idx, ce); - idx++) + for (idx = 0; vec_safe_iterate(CONSTRUCTOR_ELTS (*tp), idx, &ce); idx++) WALK_SUBTREE (ce->value); } break; @@ -10798,17 +10930,33 @@ walk_tree_without_duplicates_1 (tree *tp, walk_tree_fn func, void *data, } -tree * +tree tree_block (tree t) { char const c = TREE_CODE_CLASS (TREE_CODE (t)); if (IS_EXPR_CODE_CLASS (c)) - return &t->exp.block; + return LOCATION_BLOCK (t->exp.locus); gcc_unreachable (); return NULL; } +void +tree_set_block (tree t, tree b) +{ + char const c = TREE_CODE_CLASS (TREE_CODE (t)); + + if (IS_EXPR_CODE_CLASS (c)) + { + if (b) + t->exp.locus = COMBINE_LOCATION_DATA (line_table, t->exp.locus, b); + else + t->exp.locus = LOCATION_LOCUS (t->exp.locus); + } + else + gcc_unreachable (); +} + /* Create a nameless artificial label and put it in the current function context. The label has a location of LOC. Returns the newly created label. */ @@ -10838,6 +10986,13 @@ get_name (tree t) STRIP_NOPS (stripped_decl); if (DECL_P (stripped_decl) && DECL_NAME (stripped_decl)) return IDENTIFIER_POINTER (DECL_NAME (stripped_decl)); + else if (TREE_CODE (stripped_decl) == SSA_NAME) + { + tree name = SSA_NAME_IDENTIFIER (stripped_decl); + if (!name) + return NULL; + return IDENTIFIER_POINTER (name); + } else { switch (TREE_CODE (stripped_decl)) @@ -11198,6 +11353,52 @@ tree_strip_sign_nop_conversions (tree exp) return exp; } +/* Avoid any floating point extensions from EXP. */ +tree +strip_float_extensions (tree exp) +{ + tree sub, expt, subt; + + /* For floating point constant look up the narrowest type that can hold + it properly and handle it like (type)(narrowest_type)constant. + This way we can optimize for instance a=a*2.0 where "a" is float + but 2.0 is double constant. */ + if (TREE_CODE (exp) == REAL_CST && !DECIMAL_FLOAT_TYPE_P (TREE_TYPE (exp))) + { + REAL_VALUE_TYPE orig; + tree type = NULL; + + orig = TREE_REAL_CST (exp); + if (TYPE_PRECISION (TREE_TYPE (exp)) > TYPE_PRECISION (float_type_node) + && exact_real_truncate (TYPE_MODE (float_type_node), &orig)) + type = float_type_node; + else if (TYPE_PRECISION (TREE_TYPE (exp)) + > TYPE_PRECISION (double_type_node) + && exact_real_truncate (TYPE_MODE (double_type_node), &orig)) + type = double_type_node; + if (type) + return build_real (type, real_value_truncate (TYPE_MODE (type), orig)); + } + + if (!CONVERT_EXPR_P (exp)) + return exp; + + sub = TREE_OPERAND (exp, 0); + subt = TREE_TYPE (sub); + expt = TREE_TYPE (exp); + + if (!FLOAT_TYPE_P (subt)) + return exp; + + if (DECIMAL_FLOAT_TYPE_P (expt) != DECIMAL_FLOAT_TYPE_P (subt)) + return exp; + + if (TYPE_PRECISION (subt) > TYPE_PRECISION (expt)) + return exp; + + return strip_float_extensions (sub); +} + /* Strip out all handled components that produce invariant offsets. */ @@ -11423,4 +11624,21 @@ warn_deprecated_use (tree node, tree attr) } } +/* Return true if REF has a COMPONENT_REF with a bit-field field declaration + somewhere in it. */ + +bool +contains_bitfld_component_ref_p (const_tree ref) +{ + while (handled_component_p (ref)) + { + if (TREE_CODE (ref) == COMPONENT_REF + && DECL_BIT_FIELD (TREE_OPERAND (ref, 1))) + return true; + ref = TREE_OPERAND (ref, 0); + } + + return false; +} + #include "gt-tree.h"