/* 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.
#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"
#include "tree-diagnostic.h"
#include "tree-pretty-print.h"
#include "cgraph.h"
-#include "timevar.h"
#include "except.h"
#include "debug.h"
#include "intl.h"
/* 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];
"lang_type kinds",
"omp clauses",
};
-#endif /* GATHER_STATISTICS */
/* Unique id for next decl created. */
static GTY(()) int next_decl_uid;
{
case TREE_BINFO:
return (offsetof (struct tree_binfo, base_binfos)
- + VEC_embedded_size (tree, BINFO_N_BASE_BINFOS (node)));
+ + vec<tree, va_gc>
+ ::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;
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 */
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. */
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)
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)
{
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)
{
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. */
{
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
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);
}
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
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))
|| (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;
/* 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);
}
|| 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))
over |= TREE_OVERFLOW (value);
}
- gcc_assert (cnt == TYPE_VECTOR_SUBPARTS (type));
-
TREE_OVERFLOW (v) = over;
return v;
}
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<constructor_elt, va_gc> *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. */
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;
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<constructor_elt, va_gc> *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<constructor_elt, va_gc> *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;
tree
build_constructor_single (tree type, tree index, tree value)
{
- VEC(constructor_elt,gc) *v;
- constructor_elt *elt;
+ vec<constructor_elt, va_gc> *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);
}
build_constructor_from_list (tree type, tree vals)
{
tree t;
- VEC(constructor_elt,gc) *v = NULL;
+ vec<constructor_elt, va_gc> *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));
}
{
tree t;
size_t length = (offsetof (struct tree_binfo, base_binfos)
- + VEC_embedded_size (tree, base_binfos));
+ + vec<tree, va_gc>::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;
}
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;
{
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
{
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
&& 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;
integer_pow2p (const_tree expr)
{
int prec;
- HOST_WIDE_INT high, low;
+ unsigned HOST_WIDE_INT high, low;
STRIP_NOPS (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));
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
/* 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));
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));
{
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.
{
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
{
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
{
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. */
/* Return true if ELEM is in V. */
bool
-vec_member (const_tree elem, VEC(tree,gc) *v)
+vec_member (const_tree elem, vec<tree, va_gc> *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;
/* 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<tree, va_gc> *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);
{
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));
/* Return the values of the elements of a CONSTRUCTOR as a vector of
trees. */
-VEC(tree,gc) *
+vec<tree, va_gc> *
ctor_to_vec (tree ctor)
{
- VEC(tree, gc) *vec = VEC_alloc (tree, gc, CONSTRUCTOR_NELTS (ctor));
+ vec<tree, va_gc> *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;
}
/* 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<tree> *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
argument list. */
void
-find_placeholder_in_expr (tree exp, VEC (tree, heap) **refs)
+find_placeholder_in_expr (tree exp, vec<tree> *refs)
{
enum tree_code code = TREE_CODE (exp);
tree inner;
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:
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);
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));
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);
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. */
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
}
/* 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<tree, va_gc> *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;
}
return decl;
}
-VEC(tree,gc) *all_translation_units;
+vec<tree, va_gc> *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. */
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;
}
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;
{
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;
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);
}
struct free_lang_data_d
{
/* Worklist to avoid excessive recursion. */
- VEC(tree,heap) *worklist;
+ vec<tree> 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<tree> decls;
/* Array of types to process with free_lang_data_in_type. */
- VEC(tree,heap) *types;
+ vec<tree> types;
};
{
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);
}
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));
}
{
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
{
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 ();
}
}
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)
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. */
/* 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 ();
}
/* 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,
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;
}
{
SIMPLE_IPA_PASS,
"*free_lang_data", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
NULL, /* gate */
free_lang_data, /* execute */
NULL, /* sub */
{
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
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)
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
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] == '_'
}
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] == '_'
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);
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)
{
/* Lookup a vector of debug arguments for FROM, and return it if we
find one. */
-VEC(tree, gc) **
+vec<tree, va_gc> **
decl_debug_args_lookup (tree from)
{
struct tree_vec_map *h, in;
/* Insert a mapping FROM->empty vector of debug arguments in the value
expression hashtable. */
-VEC(tree, gc) **
+vec<tree, va_gc> **
decl_debug_args_insert (tree from)
{
struct tree_vec_map *h;
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
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;
}
/* 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))
;
/* 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)
&& (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)));
}
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. */
case CONSTRUCTOR:
{
unsigned HOST_WIDE_INT idx;
- VEC(constructor_elt, gc) *v1 = CONSTRUCTOR_ELTS (t1);
- VEC(constructor_elt, gc) *v2 = CONSTRUCTOR_ELTS (t2);
+ vec<constructor_elt, va_gc> *v1 = CONSTRUCTOR_ELTS (t1);
+ vec<constructor_elt, va_gc> *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;
}
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
{
case PLUS_EXPR:
case MULT_EXPR:
+ case MULT_HIGHPART_EXPR:
case MIN_EXPR:
case MAX_EXPR:
case BIT_IOR_EXPR:
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:
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);
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);
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;
}
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;
}
/* 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. */
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);
}
}
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);
}
}
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)
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 ();
/* 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. */
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);
}
}
+/* 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
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);
}
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))
{
&& ! 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:
{
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);
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<tree, va_gc> *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;
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
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
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)
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)
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. */
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;
}
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;
}
-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. */
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))
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. */
}
}
+/* 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"