blob: 665143716b50c6a01754808662bde2f37514eede [file] [log] [blame]
/* Language-independent node constructors for parse phase of GNU compiler.
Copyright (C) 1987-2015 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
/* This file contains the low level primitives for operating on tree nodes,
including allocation, list operations, interning of identifiers,
construction of data type nodes and statement nodes,
and construction of type conversion nodes. It also contains
tables index by tree code that describe how to take apart
nodes of that code.
It is intended to be language-independent, but occasionally
calls language-dependent routines defined (for C) in typecheck.c. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "flags.h"
#include "hash-set.h"
#include "machmode.h"
#include "vec.h"
#include "double-int.h"
#include "input.h"
#include "alias.h"
#include "symtab.h"
#include "wide-int.h"
#include "inchash.h"
#include "tree.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "calls.h"
#include "attribs.h"
#include "varasm.h"
#include "tm_p.h"
#include "hashtab.h"
#include "hard-reg-set.h"
#include "function.h"
#include "obstack.h"
#include "toplev.h" /* get_random_seed */
#include "filenames.h"
#include "output.h"
#include "target.h"
#include "common/common-target.h"
#include "langhooks.h"
#include "tree-inline.h"
#include "tree-iterator.h"
#include "predict.h"
#include "dominance.h"
#include "cfg.h"
#include "basic-block.h"
#include "bitmap.h"
#include "tree-ssa-alias.h"
#include "internal-fn.h"
#include "gimple-expr.h"
#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimplify.h"
#include "gimple-ssa.h"
#include "hash-map.h"
#include "plugin-api.h"
#include "ipa-ref.h"
#include "cgraph.h"
#include "tree-phinodes.h"
#include "stringpool.h"
#include "tree-ssanames.h"
#include "rtl.h"
#include "statistics.h"
#include "real.h"
#include "fixed-value.h"
#include "insn-config.h"
#include "expmed.h"
#include "dojump.h"
#include "explow.h"
#include "emit-rtl.h"
#include "stmt.h"
#include "expr.h"
#include "tree-dfa.h"
#include "params.h"
#include "tree-pass.h"
#include "langhooks-def.h"
#include "diagnostic.h"
#include "tree-diagnostic.h"
#include "tree-pretty-print.h"
#include "except.h"
#include "debug.h"
#include "intl.h"
#include "builtins.h"
/* Tree code classes. */
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
#define END_OF_BASE_TREE_CODES tcc_exceptional,
const enum tree_code_class tree_code_type[] = {
#include "all-tree.def"
};
#undef DEFTREECODE
#undef END_OF_BASE_TREE_CODES
/* Table indexed by tree code giving number of expression
operands beyond the fixed part of the node structure.
Not used for types or decls. */
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
#define END_OF_BASE_TREE_CODES 0,
const unsigned char tree_code_length[] = {
#include "all-tree.def"
};
#undef DEFTREECODE
#undef END_OF_BASE_TREE_CODES
/* Names of tree components.
Used for printing out the tree and error messages. */
#define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
#define END_OF_BASE_TREE_CODES "@dummy",
static const char *const tree_code_name[] = {
#include "all-tree.def"
};
#undef DEFTREECODE
#undef END_OF_BASE_TREE_CODES
/* Each tree code class has an associated string representation.
These must correspond to the tree_code_class entries. */
const char *const tree_code_class_strings[] =
{
"exceptional",
"constant",
"type",
"declaration",
"reference",
"comparison",
"unary",
"binary",
"statement",
"vl_exp",
"expression"
};
/* obstack.[ch] explicitly declined to prototype this. */
extern int _obstack_allocated_p (struct obstack *h, void *obj);
/* Statistics-gathering stuff. */
static int tree_code_counts[MAX_TREE_CODES];
int tree_node_counts[(int) all_kinds];
int tree_node_sizes[(int) all_kinds];
/* Keep in sync with tree.h:enum tree_node_kind. */
static const char * const tree_node_kind_names[] = {
"decls",
"types",
"blocks",
"stmts",
"refs",
"exprs",
"constants",
"identifiers",
"vecs",
"binfos",
"ssa names",
"constructors",
"random kinds",
"lang_decl kinds",
"lang_type kinds",
"omp clauses",
};
/* Unique id for next decl created. */
static GTY(()) int next_decl_uid;
/* Unique id for next type created. */
static GTY(()) int next_type_uid = 1;
/* Unique id for next debug decl created. Use negative numbers,
to catch erroneous uses. */
static GTY(()) int next_debug_decl_uid;
/* Since we cannot rehash a type after it is in the table, we have to
keep the hash code. */
struct GTY((for_user)) type_hash {
unsigned long hash;
tree type;
};
/* Initial size of the hash table (rounded to next prime). */
#define TYPE_HASH_INITIAL_SIZE 1000
struct type_cache_hasher : ggc_cache_hasher<type_hash *>
{
static hashval_t hash (type_hash *t) { return t->hash; }
static bool equal (type_hash *a, type_hash *b);
static void
handle_cache_entry (type_hash *&t)
{
extern void gt_ggc_mx (type_hash *&);
if (t == HTAB_DELETED_ENTRY || t == HTAB_EMPTY_ENTRY)
return;
else if (ggc_marked_p (t->type))
gt_ggc_mx (t);
else
t = static_cast<type_hash *> (HTAB_DELETED_ENTRY);
}
};
/* Now here is the hash table. When recording a type, it is added to
the slot whose index is the hash code. Note that the hash table is
used for several kinds of types (function types, array types and
array index range types, for now). While all these live in the
same table, they are completely independent, and the hash code is
computed differently for each of these. */
static GTY ((cache)) hash_table<type_cache_hasher> *type_hash_table;
/* Hash table and temporary node for larger integer const values. */
static GTY (()) tree int_cst_node;
struct int_cst_hasher : ggc_cache_hasher<tree>
{
static hashval_t hash (tree t);
static bool equal (tree x, tree y);
};
static GTY ((cache)) hash_table<int_cst_hasher> *int_cst_hash_table;
/* Hash table for optimization flags and target option flags. Use the same
hash table for both sets of options. Nodes for building the current
optimization and target option nodes. The assumption is most of the time
the options created will already be in the hash table, so we avoid
allocating and freeing up a node repeatably. */
static GTY (()) tree cl_optimization_node;
static GTY (()) tree cl_target_option_node;
struct cl_option_hasher : ggc_cache_hasher<tree>
{
static hashval_t hash (tree t);
static bool equal (tree x, tree y);
};
static GTY ((cache)) hash_table<cl_option_hasher> *cl_option_hash_table;
/* General tree->tree mapping structure for use in hash tables. */
static GTY ((cache))
hash_table<tree_decl_map_cache_hasher> *debug_expr_for_decl;
static GTY ((cache))
hash_table<tree_decl_map_cache_hasher> *value_expr_for_decl;
struct tree_vec_map_cache_hasher : ggc_cache_hasher<tree_vec_map *>
{
static hashval_t hash (tree_vec_map *m) { return DECL_UID (m->base.from); }
static bool
equal (tree_vec_map *a, tree_vec_map *b)
{
return a->base.from == b->base.from;
}
static void
handle_cache_entry (tree_vec_map *&m)
{
extern void gt_ggc_mx (tree_vec_map *&);
if (m == HTAB_EMPTY_ENTRY || m == HTAB_DELETED_ENTRY)
return;
else if (ggc_marked_p (m->base.from))
gt_ggc_mx (m);
else
m = static_cast<tree_vec_map *> (HTAB_DELETED_ENTRY);
}
};
static GTY ((cache))
hash_table<tree_vec_map_cache_hasher> *debug_args_for_decl;
static void set_type_quals (tree, int);
static void print_type_hash_statistics (void);
static void print_debug_expr_statistics (void);
static void print_value_expr_statistics (void);
static void type_hash_list (const_tree, inchash::hash &);
static void attribute_hash_list (const_tree, inchash::hash &);
tree global_trees[TI_MAX];
tree integer_types[itk_none];
bool int_n_enabled_p[NUM_INT_N_ENTS];
struct int_n_trees_t int_n_trees [NUM_INT_N_ENTS];
unsigned char tree_contains_struct[MAX_TREE_CODES][64];
/* Number of operands for each OpenMP clause. */
unsigned const char omp_clause_num_ops[] =
{
0, /* OMP_CLAUSE_ERROR */
1, /* OMP_CLAUSE_PRIVATE */
1, /* OMP_CLAUSE_SHARED */
1, /* OMP_CLAUSE_FIRSTPRIVATE */
2, /* OMP_CLAUSE_LASTPRIVATE */
4, /* OMP_CLAUSE_REDUCTION */
1, /* OMP_CLAUSE_COPYIN */
1, /* OMP_CLAUSE_COPYPRIVATE */
3, /* OMP_CLAUSE_LINEAR */
2, /* OMP_CLAUSE_ALIGNED */
1, /* OMP_CLAUSE_DEPEND */
1, /* OMP_CLAUSE_UNIFORM */
2, /* OMP_CLAUSE_FROM */
2, /* OMP_CLAUSE_TO */
2, /* OMP_CLAUSE_MAP */
2, /* OMP_CLAUSE__CACHE_ */
1, /* OMP_CLAUSE_DEVICE_RESIDENT */
1, /* OMP_CLAUSE_USE_DEVICE */
2, /* OMP_CLAUSE_GANG */
1, /* OMP_CLAUSE_ASYNC */
1, /* OMP_CLAUSE_WAIT */
0, /* OMP_CLAUSE_AUTO */
0, /* OMP_CLAUSE_SEQ */
1, /* OMP_CLAUSE__LOOPTEMP_ */
1, /* OMP_CLAUSE_IF */
1, /* OMP_CLAUSE_NUM_THREADS */
1, /* OMP_CLAUSE_SCHEDULE */
0, /* OMP_CLAUSE_NOWAIT */
0, /* OMP_CLAUSE_ORDERED */
0, /* OMP_CLAUSE_DEFAULT */
3, /* OMP_CLAUSE_COLLAPSE */
0, /* OMP_CLAUSE_UNTIED */
1, /* OMP_CLAUSE_FINAL */
0, /* OMP_CLAUSE_MERGEABLE */
1, /* OMP_CLAUSE_DEVICE */
1, /* OMP_CLAUSE_DIST_SCHEDULE */
0, /* OMP_CLAUSE_INBRANCH */
0, /* OMP_CLAUSE_NOTINBRANCH */
1, /* OMP_CLAUSE_NUM_TEAMS */
1, /* OMP_CLAUSE_THREAD_LIMIT */
0, /* OMP_CLAUSE_PROC_BIND */
1, /* OMP_CLAUSE_SAFELEN */
1, /* OMP_CLAUSE_SIMDLEN */
0, /* OMP_CLAUSE_FOR */
0, /* OMP_CLAUSE_PARALLEL */
0, /* OMP_CLAUSE_SECTIONS */
0, /* OMP_CLAUSE_TASKGROUP */
1, /* OMP_CLAUSE__SIMDUID_ */
1, /* OMP_CLAUSE__CILK_FOR_COUNT_ */
0, /* OMP_CLAUSE_INDEPENDENT */
1, /* OMP_CLAUSE_WORKER */
1, /* OMP_CLAUSE_VECTOR */
1, /* OMP_CLAUSE_NUM_GANGS */
1, /* OMP_CLAUSE_NUM_WORKERS */
1, /* OMP_CLAUSE_VECTOR_LENGTH */
};
const char * const omp_clause_code_name[] =
{
"error_clause",
"private",
"shared",
"firstprivate",
"lastprivate",
"reduction",
"copyin",
"copyprivate",
"linear",
"aligned",
"depend",
"uniform",
"from",
"to",
"map",
"_cache_",
"device_resident",
"use_device",
"gang",
"async",
"wait",
"auto",
"seq",
"_looptemp_",
"if",
"num_threads",
"schedule",
"nowait",
"ordered",
"default",
"collapse",
"untied",
"final",
"mergeable",
"device",
"dist_schedule",
"inbranch",
"notinbranch",
"num_teams",
"thread_limit",
"proc_bind",
"safelen",
"simdlen",
"for",
"parallel",
"sections",
"taskgroup",
"_simduid_",
"_Cilk_for_count_",
"independent",
"worker",
"vector",
"num_gangs",
"num_workers",
"vector_length"
};
/* Return the tree node structure used by tree code CODE. */
static inline enum tree_node_structure_enum
tree_node_structure_for_code (enum tree_code code)
{
switch (TREE_CODE_CLASS (code))
{
case tcc_declaration:
{
switch (code)
{
case FIELD_DECL:
return TS_FIELD_DECL;
case PARM_DECL:
return TS_PARM_DECL;
case VAR_DECL:
return TS_VAR_DECL;
case LABEL_DECL:
return TS_LABEL_DECL;
case RESULT_DECL:
return TS_RESULT_DECL;
case DEBUG_EXPR_DECL:
return TS_DECL_WRTL;
case CONST_DECL:
return TS_CONST_DECL;
case TYPE_DECL:
return TS_TYPE_DECL;
case FUNCTION_DECL:
return TS_FUNCTION_DECL;
case TRANSLATION_UNIT_DECL:
return TS_TRANSLATION_UNIT_DECL;
default:
return TS_DECL_NON_COMMON;
}
}
case tcc_type:
return TS_TYPE_NON_COMMON;
case tcc_reference:
case tcc_comparison:
case tcc_unary:
case tcc_binary:
case tcc_expression:
case tcc_statement:
case tcc_vl_exp:
return TS_EXP;
default: /* tcc_constant and tcc_exceptional */
break;
}
switch (code)
{
/* tcc_constant cases. */
case VOID_CST: return TS_TYPED;
case INTEGER_CST: return TS_INT_CST;
case REAL_CST: return TS_REAL_CST;
case FIXED_CST: return TS_FIXED_CST;
case COMPLEX_CST: return TS_COMPLEX;
case VECTOR_CST: return TS_VECTOR;
case STRING_CST: return TS_STRING;
/* tcc_exceptional cases. */
case ERROR_MARK: return TS_COMMON;
case IDENTIFIER_NODE: return TS_IDENTIFIER;
case TREE_LIST: return TS_LIST;
case TREE_VEC: return TS_VEC;
case SSA_NAME: return TS_SSA_NAME;
case PLACEHOLDER_EXPR: return TS_COMMON;
case STATEMENT_LIST: return TS_STATEMENT_LIST;
case BLOCK: return TS_BLOCK;
case CONSTRUCTOR: return TS_CONSTRUCTOR;
case TREE_BINFO: return TS_BINFO;
case OMP_CLAUSE: return TS_OMP_CLAUSE;
case OPTIMIZATION_NODE: return TS_OPTIMIZATION;
case TARGET_OPTION_NODE: return TS_TARGET_OPTION;
default:
gcc_unreachable ();
}
}
/* Initialize tree_contains_struct to describe the hierarchy of tree
nodes. */
static void
initialize_tree_contains_struct (void)
{
unsigned i;
for (i = ERROR_MARK; i < LAST_AND_UNUSED_TREE_CODE; i++)
{
enum tree_code code;
enum tree_node_structure_enum ts_code;
code = (enum tree_code) i;
ts_code = tree_node_structure_for_code (code);
/* Mark the TS structure itself. */
tree_contains_struct[code][ts_code] = 1;
/* Mark all the structures that TS is derived from. */
switch (ts_code)
{
case TS_TYPED:
case TS_BLOCK:
MARK_TS_BASE (code);
break;
case TS_COMMON:
case TS_INT_CST:
case TS_REAL_CST:
case TS_FIXED_CST:
case TS_VECTOR:
case TS_STRING:
case TS_COMPLEX:
case TS_SSA_NAME:
case TS_CONSTRUCTOR:
case TS_EXP:
case TS_STATEMENT_LIST:
MARK_TS_TYPED (code);
break;
case TS_IDENTIFIER:
case TS_DECL_MINIMAL:
case TS_TYPE_COMMON:
case TS_LIST:
case TS_VEC:
case TS_BINFO:
case TS_OMP_CLAUSE:
case TS_OPTIMIZATION:
case TS_TARGET_OPTION:
MARK_TS_COMMON (code);
break;
case TS_TYPE_WITH_LANG_SPECIFIC:
MARK_TS_TYPE_COMMON (code);
break;
case TS_TYPE_NON_COMMON:
MARK_TS_TYPE_WITH_LANG_SPECIFIC (code);
break;
case TS_DECL_COMMON:
MARK_TS_DECL_MINIMAL (code);
break;
case TS_DECL_WRTL:
case TS_CONST_DECL:
MARK_TS_DECL_COMMON (code);
break;
case TS_DECL_NON_COMMON:
MARK_TS_DECL_WITH_VIS (code);
break;
case TS_DECL_WITH_VIS:
case TS_PARM_DECL:
case TS_LABEL_DECL:
case TS_RESULT_DECL:
MARK_TS_DECL_WRTL (code);
break;
case TS_FIELD_DECL:
MARK_TS_DECL_COMMON (code);
break;
case TS_VAR_DECL:
MARK_TS_DECL_WITH_VIS (code);
break;
case TS_TYPE_DECL:
case TS_FUNCTION_DECL:
MARK_TS_DECL_NON_COMMON (code);
break;
case TS_TRANSLATION_UNIT_DECL:
MARK_TS_DECL_COMMON (code);
break;
default:
gcc_unreachable ();
}
}
/* Basic consistency checks for attributes used in fold. */
gcc_assert (tree_contains_struct[FUNCTION_DECL][TS_DECL_NON_COMMON]);
gcc_assert (tree_contains_struct[TYPE_DECL][TS_DECL_NON_COMMON]);
gcc_assert (tree_contains_struct[CONST_DECL][TS_DECL_COMMON]);
gcc_assert (tree_contains_struct[VAR_DECL][TS_DECL_COMMON]);
gcc_assert (tree_contains_struct[PARM_DECL][TS_DECL_COMMON]);
gcc_assert (tree_contains_struct[RESULT_DECL][TS_DECL_COMMON]);
gcc_assert (tree_contains_struct[FUNCTION_DECL][TS_DECL_COMMON]);
gcc_assert (tree_contains_struct[TYPE_DECL][TS_DECL_COMMON]);
gcc_assert (tree_contains_struct[TRANSLATION_UNIT_DECL][TS_DECL_COMMON]);
gcc_assert (tree_contains_struct[LABEL_DECL][TS_DECL_COMMON]);
gcc_assert (tree_contains_struct[FIELD_DECL][TS_DECL_COMMON]);
gcc_assert (tree_contains_struct[VAR_DECL][TS_DECL_WRTL]);
gcc_assert (tree_contains_struct[PARM_DECL][TS_DECL_WRTL]);
gcc_assert (tree_contains_struct[RESULT_DECL][TS_DECL_WRTL]);
gcc_assert (tree_contains_struct[FUNCTION_DECL][TS_DECL_WRTL]);
gcc_assert (tree_contains_struct[LABEL_DECL][TS_DECL_WRTL]);
gcc_assert (tree_contains_struct[CONST_DECL][TS_DECL_MINIMAL]);
gcc_assert (tree_contains_struct[VAR_DECL][TS_DECL_MINIMAL]);
gcc_assert (tree_contains_struct[PARM_DECL][TS_DECL_MINIMAL]);
gcc_assert (tree_contains_struct[RESULT_DECL][TS_DECL_MINIMAL]);
gcc_assert (tree_contains_struct[FUNCTION_DECL][TS_DECL_MINIMAL]);
gcc_assert (tree_contains_struct[TYPE_DECL][TS_DECL_MINIMAL]);
gcc_assert (tree_contains_struct[TRANSLATION_UNIT_DECL][TS_DECL_MINIMAL]);
gcc_assert (tree_contains_struct[LABEL_DECL][TS_DECL_MINIMAL]);
gcc_assert (tree_contains_struct[FIELD_DECL][TS_DECL_MINIMAL]);
gcc_assert (tree_contains_struct[VAR_DECL][TS_DECL_WITH_VIS]);
gcc_assert (tree_contains_struct[FUNCTION_DECL][TS_DECL_WITH_VIS]);
gcc_assert (tree_contains_struct[TYPE_DECL][TS_DECL_WITH_VIS]);
gcc_assert (tree_contains_struct[VAR_DECL][TS_VAR_DECL]);
gcc_assert (tree_contains_struct[FIELD_DECL][TS_FIELD_DECL]);
gcc_assert (tree_contains_struct[PARM_DECL][TS_PARM_DECL]);
gcc_assert (tree_contains_struct[LABEL_DECL][TS_LABEL_DECL]);
gcc_assert (tree_contains_struct[RESULT_DECL][TS_RESULT_DECL]);
gcc_assert (tree_contains_struct[CONST_DECL][TS_CONST_DECL]);
gcc_assert (tree_contains_struct[TYPE_DECL][TS_TYPE_DECL]);
gcc_assert (tree_contains_struct[FUNCTION_DECL][TS_FUNCTION_DECL]);
gcc_assert (tree_contains_struct[IMPORTED_DECL][TS_DECL_MINIMAL]);
gcc_assert (tree_contains_struct[IMPORTED_DECL][TS_DECL_COMMON]);
gcc_assert (tree_contains_struct[NAMELIST_DECL][TS_DECL_MINIMAL]);
gcc_assert (tree_contains_struct[NAMELIST_DECL][TS_DECL_COMMON]);
}
/* Init tree.c. */
void
init_ttree (void)
{
/* Initialize the hash table of types. */
type_hash_table
= hash_table<type_cache_hasher>::create_ggc (TYPE_HASH_INITIAL_SIZE);
debug_expr_for_decl
= hash_table<tree_decl_map_cache_hasher>::create_ggc (512);
value_expr_for_decl
= hash_table<tree_decl_map_cache_hasher>::create_ggc (512);
int_cst_hash_table = hash_table<int_cst_hasher>::create_ggc (1024);
int_cst_node = make_int_cst (1, 1);
cl_option_hash_table = hash_table<cl_option_hasher>::create_ggc (64);
cl_optimization_node = make_node (OPTIMIZATION_NODE);
cl_target_option_node = make_node (TARGET_OPTION_NODE);
/* Initialize the tree_contains_struct array. */
initialize_tree_contains_struct ();
lang_hooks.init_ts ();
}
/* The name of the object as the assembler will see it (but before any
translations made by ASM_OUTPUT_LABELREF). Often this is the same
as DECL_NAME. It is an IDENTIFIER_NODE. */
tree
decl_assembler_name (tree decl)
{
if (!DECL_ASSEMBLER_NAME_SET_P (decl))
lang_hooks.set_decl_assembler_name (decl);
return DECL_WITH_VIS_CHECK (decl)->decl_with_vis.assembler_name;
}
/* When the target supports COMDAT groups, this indicates which group the
DECL is associated with. This can be either an IDENTIFIER_NODE or a
decl, in which case its DECL_ASSEMBLER_NAME identifies the group. */
tree
decl_comdat_group (const_tree node)
{
struct symtab_node *snode = symtab_node::get (node);
if (!snode)
return NULL;
return snode->get_comdat_group ();
}
/* Likewise, but make sure it's been reduced to an IDENTIFIER_NODE. */
tree
decl_comdat_group_id (const_tree node)
{
struct symtab_node *snode = symtab_node::get (node);
if (!snode)
return NULL;
return snode->get_comdat_group_id ();
}
/* When the target supports named section, return its name as IDENTIFIER_NODE
or NULL if it is in no section. */
const char *
decl_section_name (const_tree node)
{
struct symtab_node *snode = symtab_node::get (node);
if (!snode)
return NULL;
return snode->get_section ();
}
/* Set section section name of NODE to VALUE (that is expected to
be identifier node) */
void
set_decl_section_name (tree node, const char *value)
{
struct symtab_node *snode;
if (value == NULL)
{
snode = symtab_node::get (node);
if (!snode)
return;
}
else if (TREE_CODE (node) == VAR_DECL)
snode = varpool_node::get_create (node);
else
snode = cgraph_node::get_create (node);
snode->set_section (value);
}
/* Return TLS model of a variable NODE. */
enum tls_model
decl_tls_model (const_tree node)
{
struct varpool_node *snode = varpool_node::get (node);
if (!snode)
return TLS_MODEL_NONE;
return snode->tls_model;
}
/* Set TLS model of variable NODE to MODEL. */
void
set_decl_tls_model (tree node, enum tls_model model)
{
struct varpool_node *vnode;
if (model == TLS_MODEL_NONE)
{
vnode = varpool_node::get (node);
if (!vnode)
return;
}
else
vnode = varpool_node::get_create (node);
vnode->tls_model = model;
}
/* Compute the number of bytes occupied by a tree with code CODE.
This function cannot be used for nodes that have variable sizes,
including TREE_VEC, INTEGER_CST, STRING_CST, and CALL_EXPR. */
size_t
tree_code_size (enum tree_code code)
{
switch (TREE_CODE_CLASS (code))
{
case tcc_declaration: /* A decl node */
{
switch (code)
{
case FIELD_DECL:
return sizeof (struct tree_field_decl);
case PARM_DECL:
return sizeof (struct tree_parm_decl);
case VAR_DECL:
return sizeof (struct tree_var_decl);
case LABEL_DECL:
return sizeof (struct tree_label_decl);
case RESULT_DECL:
return sizeof (struct tree_result_decl);
case CONST_DECL:
return sizeof (struct tree_const_decl);
case TYPE_DECL:
return sizeof (struct tree_type_decl);
case FUNCTION_DECL:
return sizeof (struct tree_function_decl);
case DEBUG_EXPR_DECL:
return sizeof (struct tree_decl_with_rtl);
case TRANSLATION_UNIT_DECL:
return sizeof (struct tree_translation_unit_decl);
case NAMESPACE_DECL:
case IMPORTED_DECL:
case NAMELIST_DECL:
return sizeof (struct tree_decl_non_common);
default:
return lang_hooks.tree_size (code);
}
}
case tcc_type: /* a type node */
return sizeof (struct tree_type_non_common);
case tcc_reference: /* a reference */
case tcc_expression: /* an expression */
case tcc_statement: /* an expression with side effects */
case tcc_comparison: /* a comparison expression */
case tcc_unary: /* a unary arithmetic expression */
case tcc_binary: /* a binary arithmetic expression */
return (sizeof (struct tree_exp)
+ (TREE_CODE_LENGTH (code) - 1) * sizeof (tree));
case tcc_constant: /* a constant */
switch (code)
{
case VOID_CST: return sizeof (struct tree_typed);
case INTEGER_CST: gcc_unreachable ();
case REAL_CST: return sizeof (struct tree_real_cst);
case FIXED_CST: return sizeof (struct tree_fixed_cst);
case COMPLEX_CST: return sizeof (struct tree_complex);
case VECTOR_CST: return sizeof (struct tree_vector);
case STRING_CST: gcc_unreachable ();
default:
return lang_hooks.tree_size (code);
}
case tcc_exceptional: /* something random, like an identifier. */
switch (code)
{
case IDENTIFIER_NODE: return lang_hooks.identifier_size;
case TREE_LIST: return sizeof (struct tree_list);
case ERROR_MARK:
case PLACEHOLDER_EXPR: return sizeof (struct tree_common);
case TREE_VEC:
case OMP_CLAUSE: gcc_unreachable ();
case SSA_NAME: return sizeof (struct tree_ssa_name);
case STATEMENT_LIST: return sizeof (struct tree_statement_list);
case BLOCK: return sizeof (struct tree_block);
case CONSTRUCTOR: return sizeof (struct tree_constructor);
case OPTIMIZATION_NODE: return sizeof (struct tree_optimization_option);
case TARGET_OPTION_NODE: return sizeof (struct tree_target_option);
default:
return lang_hooks.tree_size (code);
}
default:
gcc_unreachable ();
}
}
/* Compute the number of bytes occupied by NODE. This routine only
looks at TREE_CODE, except for those nodes that have variable sizes. */
size_t
tree_size (const_tree node)
{
const enum tree_code code = TREE_CODE (node);
switch (code)
{
case INTEGER_CST:
return (sizeof (struct tree_int_cst)
+ (TREE_INT_CST_EXT_NUNITS (node) - 1) * sizeof (HOST_WIDE_INT));
case TREE_BINFO:
return (offsetof (struct tree_binfo, base_binfos)
+ 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;
case OMP_CLAUSE:
return (sizeof (struct tree_omp_clause)
+ (omp_clause_num_ops[OMP_CLAUSE_CODE (node)] - 1)
* sizeof (tree));
default:
if (TREE_CODE_CLASS (code) == tcc_vl_exp)
return (sizeof (struct tree_exp)
+ (VL_EXP_OPERAND_LENGTH (node) - 1) * sizeof (tree));
else
return tree_code_size (code);
}
}
/* Record interesting allocation statistics for a tree node with CODE
and LENGTH. */
static void
record_node_allocation_statistics (enum tree_code code ATTRIBUTE_UNUSED,
size_t length ATTRIBUTE_UNUSED)
{
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 */
kind = d_kind;
break;
case tcc_type: /* a type node */
kind = t_kind;
break;
case tcc_statement: /* an expression with side effects */
kind = s_kind;
break;
case tcc_reference: /* a reference */
kind = r_kind;
break;
case tcc_expression: /* an expression */
case tcc_comparison: /* a comparison expression */
case tcc_unary: /* a unary arithmetic expression */
case tcc_binary: /* a binary arithmetic expression */
kind = e_kind;
break;
case tcc_constant: /* a constant */
kind = c_kind;
break;
case tcc_exceptional: /* something random, like an identifier. */
switch (code)
{
case IDENTIFIER_NODE:
kind = id_kind;
break;
case TREE_VEC:
kind = vec_kind;
break;
case TREE_BINFO:
kind = binfo_kind;
break;
case SSA_NAME:
kind = ssa_name_kind;
break;
case BLOCK:
kind = b_kind;
break;
case CONSTRUCTOR:
kind = constr_kind;
break;
case OMP_CLAUSE:
kind = omp_clause_kind;
break;
default:
kind = x_kind;
break;
}
break;
case tcc_vl_exp:
kind = e_kind;
break;
default:
gcc_unreachable ();
}
tree_code_counts[(int) code]++;
tree_node_counts[(int) kind]++;
tree_node_sizes[(int) kind] += length;
}
/* Allocate and return a new UID from the DECL_UID namespace. */
int
allocate_decl_uid (void)
{
return next_decl_uid++;
}
/* Return a newly allocated node of code CODE. For decl and type
nodes, some other fields are initialized. The rest of the node is
initialized to zero. This function cannot be used for TREE_VEC,
INTEGER_CST or OMP_CLAUSE nodes, which is enforced by asserts in
tree_code_size.
Achoo! I got a code in the node. */
tree
make_node_stat (enum tree_code code MEM_STAT_DECL)
{
tree t;
enum tree_code_class type = TREE_CODE_CLASS (code);
size_t length = tree_code_size (code);
record_node_allocation_statistics (code, length);
t = ggc_alloc_cleared_tree_node_stat (length PASS_MEM_STAT);
TREE_SET_CODE (t, code);
switch (type)
{
case tcc_statement:
TREE_SIDE_EFFECTS (t) = 1;
break;
case tcc_declaration:
if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
{
if (code == FUNCTION_DECL)
{
DECL_ALIGN (t) = FUNCTION_BOUNDARY;
DECL_MODE (t) = FUNCTION_MODE;
}
else
DECL_ALIGN (t) = 1;
}
DECL_SOURCE_LOCATION (t) = input_location;
if (TREE_CODE (t) == DEBUG_EXPR_DECL)
DECL_UID (t) = --next_debug_decl_uid;
else
{
DECL_UID (t) = allocate_decl_uid ();
SET_DECL_PT_UID (t, -1);
}
if (TREE_CODE (t) == LABEL_DECL)
LABEL_DECL_UID (t) = -1;
break;
case tcc_type:
TYPE_UID (t) = next_type_uid++;
TYPE_ALIGN (t) = BITS_PER_UNIT;
TYPE_USER_ALIGN (t) = 0;
TYPE_MAIN_VARIANT (t) = t;
TYPE_CANONICAL (t) = t;
/* Default to no attributes for type, but let target change that. */
TYPE_ATTRIBUTES (t) = NULL_TREE;
targetm.set_default_type_attributes (t);
/* We have not yet computed the alias set for this type. */
TYPE_ALIAS_SET (t) = -1;
break;
case tcc_constant:
TREE_CONSTANT (t) = 1;
break;
case tcc_expression:
switch (code)
{
case INIT_EXPR:
case MODIFY_EXPR:
case VA_ARG_EXPR:
case PREDECREMENT_EXPR:
case PREINCREMENT_EXPR:
case POSTDECREMENT_EXPR:
case POSTINCREMENT_EXPR:
/* All of these have side-effects, no matter what their
operands are. */
TREE_SIDE_EFFECTS (t) = 1;
break;
default:
break;
}
break;
default:
/* Other classes need no special treatment. */
break;
}
return t;
}
/* Return a new node with the same contents as NODE except that its
TREE_CHAIN, if it has one, is zero and it has a fresh uid. */
tree
copy_node_stat (tree node MEM_STAT_DECL)
{
tree t;
enum tree_code code = TREE_CODE (node);
size_t length;
gcc_assert (code != STATEMENT_LIST);
length = tree_size (node);
record_node_allocation_statistics (code, length);
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 (TREE_CODE_CLASS (code) == tcc_declaration)
{
if (code == DEBUG_EXPR_DECL)
DECL_UID (t) = --next_debug_decl_uid;
else
{
DECL_UID (t) = allocate_decl_uid ();
if (DECL_PT_UID_SET_P (node))
SET_DECL_PT_UID (t, DECL_PT_UID (node));
}
if ((TREE_CODE (node) == PARM_DECL || TREE_CODE (node) == VAR_DECL)
&& DECL_HAS_VALUE_EXPR_P (node))
{
SET_DECL_VALUE_EXPR (t, DECL_VALUE_EXPR (node));
DECL_HAS_VALUE_EXPR_P (t) = 1;
}
/* DECL_DEBUG_EXPR is copied explicitely by callers. */
if (TREE_CODE (node) == VAR_DECL)
{
DECL_HAS_DEBUG_EXPR_P (t) = 0;
t->decl_with_vis.symtab_node = NULL;
}
if (TREE_CODE (node) == VAR_DECL && DECL_HAS_INIT_PRIORITY_P (node))
{
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;
t->decl_with_vis.symtab_node = NULL;
}
}
else if (TREE_CODE_CLASS (code) == tcc_type)
{
TYPE_UID (t) = next_type_uid++;
/* The following is so that the debug code for
the copy is different from the original type.
The two statements usually duplicate each other
(because they clear fields of the same union),
but the optimizer should catch that. */
TYPE_SYMTAB_POINTER (t) = 0;
TYPE_SYMTAB_ADDRESS (t) = 0;
/* Do not copy the values cache. */
if (TYPE_CACHED_VALUES_P (t))
{
TYPE_CACHED_VALUES_P (t) = 0;
TYPE_CACHED_VALUES (t) = NULL_TREE;
}
}
return t;
}
/* Return a copy of a chain of nodes, chained through the TREE_CHAIN field.
For example, this can copy a list made of TREE_LIST nodes. */
tree
copy_list (tree list)
{
tree head;
tree prev, next;
if (list == 0)
return 0;
head = prev = copy_node (list);
next = TREE_CHAIN (list);
while (next)
{
TREE_CHAIN (prev) = copy_node (next);
prev = TREE_CHAIN (prev);
next = TREE_CHAIN (next);
}
return head;
}
/* Return the value that TREE_INT_CST_EXT_NUNITS should have for an
INTEGER_CST with value CST and type TYPE. */
static unsigned int
get_int_cst_ext_nunits (tree type, const wide_int &cst)
{
gcc_checking_assert (cst.get_precision () == TYPE_PRECISION (type));
/* We need extra HWIs if CST is an unsigned integer with its
upper bit set. */
if (TYPE_UNSIGNED (type) && wi::neg_p (cst))
return cst.get_precision () / HOST_BITS_PER_WIDE_INT + 1;
return cst.get_len ();
}
/* Return a new INTEGER_CST with value CST and type TYPE. */
static tree
build_new_int_cst (tree type, const wide_int &cst)
{
unsigned int len = cst.get_len ();
unsigned int ext_len = get_int_cst_ext_nunits (type, cst);
tree nt = make_int_cst (len, ext_len);
if (len < ext_len)
{
--ext_len;
TREE_INT_CST_ELT (nt, ext_len)
= zext_hwi (-1, cst.get_precision () % HOST_BITS_PER_WIDE_INT);
for (unsigned int i = len; i < ext_len; ++i)
TREE_INT_CST_ELT (nt, i) = -1;
}
else if (TYPE_UNSIGNED (type)
&& cst.get_precision () < len * HOST_BITS_PER_WIDE_INT)
{
len--;
TREE_INT_CST_ELT (nt, len)
= zext_hwi (cst.elt (len),
cst.get_precision () % HOST_BITS_PER_WIDE_INT);
}
for (unsigned int i = 0; i < len; i++)
TREE_INT_CST_ELT (nt, i) = cst.elt (i);
TREE_TYPE (nt) = type;
return nt;
}
/* Create an INT_CST node with a LOW value sign extended to TYPE. */
tree
build_int_cst (tree type, HOST_WIDE_INT low)
{
/* Support legacy code. */
if (!type)
type = integer_type_node;
return wide_int_to_tree (type, wi::shwi (low, TYPE_PRECISION (type)));
}
tree
build_int_cstu (tree type, unsigned HOST_WIDE_INT cst)
{
return wide_int_to_tree (type, wi::uhwi (cst, TYPE_PRECISION (type)));
}
/* Create an INT_CST node with a LOW value sign extended to TYPE. */
tree
build_int_cst_type (tree type, HOST_WIDE_INT low)
{
gcc_assert (type);
return wide_int_to_tree (type, wi::shwi (low, TYPE_PRECISION (type)));
}
/* Constructs tree in type TYPE from with value given by CST. Signedness
of CST is assumed to be the same as the signedness of TYPE. */
tree
double_int_to_tree (tree type, double_int cst)
{
return wide_int_to_tree (type, widest_int::from (cst, TYPE_SIGN (type)));
}
/* We force the wide_int CST to the range of the type TYPE by sign or
zero extending it. OVERFLOWABLE indicates if we are interested in
overflow of the value, when >0 we are only interested in signed
overflow, for <0 we are interested in any overflow. OVERFLOWED
indicates whether overflow has already occurred. CONST_OVERFLOWED
indicates whether constant overflow has already occurred. We force
T's value to be within range of T's type (by setting to 0 or 1 all
the bits outside the type's range). We set TREE_OVERFLOWED if,
OVERFLOWED is nonzero,
or OVERFLOWABLE is >0 and signed overflow occurs
or OVERFLOWABLE is <0 and any overflow occurs
We return a new tree node for the extended wide_int. The node
is shared if no overflow flags are set. */
tree
force_fit_type (tree type, const wide_int_ref &cst,
int overflowable, bool overflowed)
{
signop sign = TYPE_SIGN (type);
/* If we need to set overflow flags, return a new unshared node. */
if (overflowed || !wi::fits_to_tree_p (cst, type))
{
if (overflowed
|| overflowable < 0
|| (overflowable > 0 && sign == SIGNED))
{
wide_int tmp = wide_int::from (cst, TYPE_PRECISION (type), sign);
tree t = build_new_int_cst (type, tmp);
TREE_OVERFLOW (t) = 1;
return t;
}
}
/* Else build a shared node. */
return wide_int_to_tree (type, cst);
}
/* These are the hash table functions for the hash table of INTEGER_CST
nodes of a sizetype. */
/* Return the hash code code X, an INTEGER_CST. */
hashval_t
int_cst_hasher::hash (tree x)
{
const_tree const t = x;
hashval_t code = TYPE_UID (TREE_TYPE (t));
int i;
for (i = 0; i < TREE_INT_CST_NUNITS (t); i++)
code = iterative_hash_host_wide_int (TREE_INT_CST_ELT(t, i), code);
return code;
}
/* Return nonzero if the value represented by *X (an INTEGER_CST tree node)
is the same as that given by *Y, which is the same. */
bool
int_cst_hasher::equal (tree x, tree y)
{
const_tree const xt = x;
const_tree const yt = y;
if (TREE_TYPE (xt) != TREE_TYPE (yt)
|| TREE_INT_CST_NUNITS (xt) != TREE_INT_CST_NUNITS (yt)
|| TREE_INT_CST_EXT_NUNITS (xt) != TREE_INT_CST_EXT_NUNITS (yt))
return false;
for (int i = 0; i < TREE_INT_CST_NUNITS (xt); i++)
if (TREE_INT_CST_ELT (xt, i) != TREE_INT_CST_ELT (yt, i))
return false;
return true;
}
/* Create an INT_CST node of TYPE and value CST.
The returned node is always shared. For small integers we use a
per-type vector cache, for larger ones we use a single hash table.
The value is extended from its precision according to the sign of
the type to be a multiple of HOST_BITS_PER_WIDE_INT. This defines
the upper bits and ensures that hashing and value equality based
upon the underlying HOST_WIDE_INTs works without masking. */
tree
wide_int_to_tree (tree type, const wide_int_ref &pcst)
{
tree t;
int ix = -1;
int limit = 0;
gcc_assert (type);
unsigned int prec = TYPE_PRECISION (type);
signop sgn = TYPE_SIGN (type);
/* Verify that everything is canonical. */
int l = pcst.get_len ();
if (l > 1)
{
if (pcst.elt (l - 1) == 0)
gcc_checking_assert (pcst.elt (l - 2) < 0);
if (pcst.elt (l - 1) == (HOST_WIDE_INT) -1)
gcc_checking_assert (pcst.elt (l - 2) >= 0);
}
wide_int cst = wide_int::from (pcst, prec, sgn);
unsigned int ext_len = get_int_cst_ext_nunits (type, cst);
if (ext_len == 1)
{
/* We just need to store a single HOST_WIDE_INT. */
HOST_WIDE_INT hwi;
if (TYPE_UNSIGNED (type))
hwi = cst.to_uhwi ();
else
hwi = cst.to_shwi ();
switch (TREE_CODE (type))
{
case NULLPTR_TYPE:
gcc_assert (hwi == 0);
/* Fallthru. */
case POINTER_TYPE:
case REFERENCE_TYPE:
case POINTER_BOUNDS_TYPE:
/* Cache NULL pointer and zero bounds. */
if (hwi == 0)
{
limit = 1;
ix = 0;
}
break;
case BOOLEAN_TYPE:
/* Cache false or true. */
limit = 2;
if (hwi < 2)
ix = hwi;
break;
case INTEGER_TYPE:
case OFFSET_TYPE:
if (TYPE_SIGN (type) == UNSIGNED)
{
/* Cache [0, N). */
limit = INTEGER_SHARE_LIMIT;
if (IN_RANGE (hwi, 0, INTEGER_SHARE_LIMIT - 1))
ix = hwi;
}
else
{
/* Cache [-1, N). */
limit = INTEGER_SHARE_LIMIT + 1;
if (IN_RANGE (hwi, -1, INTEGER_SHARE_LIMIT - 1))
ix = hwi + 1;
}
break;
case ENUMERAL_TYPE:
break;
default:
gcc_unreachable ();
}
if (ix >= 0)
{
/* Look for it in the type's vector of small shared ints. */
if (!TYPE_CACHED_VALUES_P (type))
{
TYPE_CACHED_VALUES_P (type) = 1;
TYPE_CACHED_VALUES (type) = make_tree_vec (limit);
}
t = TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix);
if (t)
/* Make sure no one is clobbering the shared constant. */
gcc_checking_assert (TREE_TYPE (t) == type
&& TREE_INT_CST_NUNITS (t) == 1
&& TREE_INT_CST_OFFSET_NUNITS (t) == 1
&& TREE_INT_CST_EXT_NUNITS (t) == 1
&& TREE_INT_CST_ELT (t, 0) == hwi);
else
{
/* Create a new shared int. */
t = build_new_int_cst (type, cst);
TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix) = t;
}
}
else
{
/* Use the cache of larger shared ints, using int_cst_node as
a temporary. */
TREE_INT_CST_ELT (int_cst_node, 0) = hwi;
TREE_TYPE (int_cst_node) = type;
tree *slot = int_cst_hash_table->find_slot (int_cst_node, INSERT);
t = *slot;
if (!t)
{
/* Insert this one into the hash table. */
t = int_cst_node;
*slot = t;
/* Make a new node for next time round. */
int_cst_node = make_int_cst (1, 1);
}
}
}
else
{
/* The value either hashes properly or we drop it on the floor
for the gc to take care of. There will not be enough of them
to worry about. */
tree nt = build_new_int_cst (type, cst);
tree *slot = int_cst_hash_table->find_slot (nt, INSERT);
t = *slot;
if (!t)
{
/* Insert this one into the hash table. */
t = nt;
*slot = t;
}
}
return t;
}
void
cache_integer_cst (tree t)
{
tree type = TREE_TYPE (t);
int ix = -1;
int limit = 0;
int prec = TYPE_PRECISION (type);
gcc_assert (!TREE_OVERFLOW (t));
switch (TREE_CODE (type))
{
case NULLPTR_TYPE:
gcc_assert (integer_zerop (t));
/* Fallthru. */
case POINTER_TYPE:
case REFERENCE_TYPE:
/* Cache NULL pointer. */
if (integer_zerop (t))
{
limit = 1;
ix = 0;
}
break;
case BOOLEAN_TYPE:
/* Cache false or true. */
limit = 2;
if (wi::ltu_p (t, 2))
ix = TREE_INT_CST_ELT (t, 0);
break;
case INTEGER_TYPE:
case OFFSET_TYPE:
if (TYPE_UNSIGNED (type))
{
/* Cache 0..N */
limit = INTEGER_SHARE_LIMIT;
/* This is a little hokie, but if the prec is smaller than
what is necessary to hold INTEGER_SHARE_LIMIT, then the
obvious test will not get the correct answer. */
if (prec < HOST_BITS_PER_WIDE_INT)
{
if (tree_to_uhwi (t) < (unsigned HOST_WIDE_INT) INTEGER_SHARE_LIMIT)
ix = tree_to_uhwi (t);
}
else if (wi::ltu_p (t, INTEGER_SHARE_LIMIT))
ix = tree_to_uhwi (t);
}
else
{
/* Cache -1..N */
limit = INTEGER_SHARE_LIMIT + 1;
if (integer_minus_onep (t))
ix = 0;
else if (!wi::neg_p (t))
{
if (prec < HOST_BITS_PER_WIDE_INT)
{
if (tree_to_shwi (t) < INTEGER_SHARE_LIMIT)
ix = tree_to_shwi (t) + 1;
}
else if (wi::ltu_p (t, INTEGER_SHARE_LIMIT))
ix = tree_to_shwi (t) + 1;
}
}
break;
case ENUMERAL_TYPE:
break;
default:
gcc_unreachable ();
}
if (ix >= 0)
{
/* Look for it in the type's vector of small shared ints. */
if (!TYPE_CACHED_VALUES_P (type))
{
TYPE_CACHED_VALUES_P (type) = 1;
TYPE_CACHED_VALUES (type) = make_tree_vec (limit);
}
gcc_assert (TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix) == NULL_TREE);
TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix) = t;
}
else
{
/* Use the cache of larger shared ints. */
tree *slot = int_cst_hash_table->find_slot (t, INSERT);
/* If there is already an entry for the number verify it's the
same. */
if (*slot)
gcc_assert (wi::eq_p (tree (*slot), t));
else
/* Otherwise insert this one into the hash table. */
*slot = t;
}
}
/* Builds an integer constant in TYPE such that lowest BITS bits are ones
and the rest are zeros. */
tree
build_low_bits_mask (tree type, unsigned bits)
{
gcc_assert (bits <= TYPE_PRECISION (type));
return wide_int_to_tree (type, wi::mask (bits, false,
TYPE_PRECISION (type)));
}
/* Checks that X is integer constant that can be expressed in (unsigned)
HOST_WIDE_INT without loss of precision. */
bool
cst_and_fits_in_hwi (const_tree x)
{
if (TREE_CODE (x) != INTEGER_CST)
return false;
if (TYPE_PRECISION (TREE_TYPE (x)) > HOST_BITS_PER_WIDE_INT)
return false;
return TREE_INT_CST_NUNITS (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_stat (tree type, tree *vals MEM_STAT_DECL)
{
int over = 0;
unsigned cnt = 0;
tree v = make_vector (TYPE_VECTOR_SUBPARTS (type));
TREE_TYPE (v) = type;
/* Iterate through elements and check for overflow. */
for (cnt = 0; cnt < TYPE_VECTOR_SUBPARTS (type); ++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))
continue;
over |= TREE_OVERFLOW (value);
}
TREE_OVERFLOW (v) = over;
return v;
}
/* Return a new VECTOR_CST node whose type is TYPE and whose values
are extracted from V, a vector of CONSTRUCTOR_ELT. */
tree
build_vector_from_ctor (tree type, vec<constructor_elt, va_gc> *v)
{
tree *vec = XALLOCAVEC (tree, TYPE_VECTOR_SUBPARTS (type));
unsigned HOST_WIDE_INT idx;
tree value;
FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value)
vec[idx] = value;
for (; idx < TYPE_VECTOR_SUBPARTS (type); ++idx)
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. */
tree
build_vector_from_val (tree vectype, tree sc)
{
int i, nunits = TYPE_VECTOR_SUBPARTS (vectype);
if (sc == error_mark_node)
return sc;
/* Verify that the vector type is suitable for SC. Note that there
is some inconsistency in the type-system with respect to restrict
qualifications of pointers. Vector types always have a main-variant
element type and the qualification is applied to the vector-type.
So TREE_TYPE (vector-type) does not return a properly qualified
vector element-type. */
gcc_checking_assert (types_compatible_p (TYPE_MAIN_VARIANT (TREE_TYPE (sc)),
TREE_TYPE (vectype)));
if (CONSTANT_CLASS_P (sc))
{
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. */
tree
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_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;
if (TREE_SIDE_EFFECTS (elt->value))
side_effects_p = true;
}
TREE_SIDE_EFFECTS (c) = side_effects_p;
TREE_CONSTANT (c) = constant_p;
return c;
}
/* Build a CONSTRUCTOR node made of a single initializer, with the specified
INDEX and VALUE. */
tree
build_constructor_single (tree type, tree index, tree value)
{
vec<constructor_elt, va_gc> *v;
constructor_elt elt = {index, value};
vec_alloc (v, 1);
v->quick_push (elt);
return build_constructor (type, v);
}
/* Return a new CONSTRUCTOR node whose type is TYPE and whose values
are in a list pointed to by VALS. */
tree
build_constructor_from_list (tree type, tree vals)
{
tree t;
vec<constructor_elt, va_gc> *v = NULL;
if (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));
}
return build_constructor (type, v);
}
/* Return a new CONSTRUCTOR node whose type is TYPE. NELTS is the number
of elements, provided as index/value pairs. */
tree
build_constructor_va (tree type, int nelts, ...)
{
vec<constructor_elt, va_gc> *v = NULL;
va_list p;
va_start (p, nelts);
vec_alloc (v, nelts);
while (nelts--)
{
tree index = va_arg (p, tree);
tree value = va_arg (p, tree);
CONSTRUCTOR_APPEND_ELT (v, index, value);
}
va_end (p);
return build_constructor (type, v);
}
/* Return a new FIXED_CST node whose type is TYPE and value is F. */
tree
build_fixed (tree type, FIXED_VALUE_TYPE f)
{
tree v;
FIXED_VALUE_TYPE *fp;
v = make_node (FIXED_CST);
fp = ggc_alloc<fixed_value> ();
memcpy (fp, &f, sizeof (FIXED_VALUE_TYPE));
TREE_TYPE (v) = type;
TREE_FIXED_CST_PTR (v) = fp;
return v;
}
/* Return a new REAL_CST node whose type is TYPE and value is D. */
tree
build_real (tree type, REAL_VALUE_TYPE d)
{
tree v;
REAL_VALUE_TYPE *dp;
int overflow = 0;
/* ??? Used to check for overflow here via CHECK_FLOAT_TYPE.
Consider doing it via real_convert now. */
v = make_node (REAL_CST);
dp = ggc_alloc<real_value> ();
memcpy (dp, &d, sizeof (REAL_VALUE_TYPE));
TREE_TYPE (v) = type;
TREE_REAL_CST_PTR (v) = dp;
TREE_OVERFLOW (v) = overflow;
return v;
}
/* Return a new REAL_CST node whose type is TYPE
and whose value is the integer value of the INTEGER_CST node I. */
REAL_VALUE_TYPE
real_value_from_int_cst (const_tree type, const_tree i)
{
REAL_VALUE_TYPE d;
/* Clear all bits of the real value type so that we can later do
bitwise comparisons to see if two values are the same. */
memset (&d, 0, sizeof d);
real_from_integer (&d, type ? TYPE_MODE (type) : VOIDmode, i,
TYPE_SIGN (TREE_TYPE (i)));
return d;
}
/* Given a tree representing an integer constant I, return a tree
representing the same value as a floating-point constant of type TYPE. */
tree
build_real_from_int_cst (tree type, const_tree i)
{
tree v;
int overflow = TREE_OVERFLOW (i);
v = build_real (type, real_value_from_int_cst (type, i));
TREE_OVERFLOW (v) |= overflow;
return v;
}
/* Return a newly constructed STRING_CST node whose value is
the LEN characters at STR.
Note that for a C string literal, LEN should include the trailing NUL.
The TREE_TYPE is not initialized. */
tree
build_string (int len, const char *str)
{
tree s;
size_t length;
/* Do not waste bytes provided by padding of struct tree_string. */
length = len + offsetof (struct tree_string, str) + 1;
record_node_allocation_statistics (STRING_CST, length);
s = (tree) ggc_internal_alloc (length);
memset (s, 0, sizeof (struct tree_typed));
TREE_SET_CODE (s, STRING_CST);
TREE_CONSTANT (s) = 1;
TREE_STRING_LENGTH (s) = len;
memcpy (s->string.str, str, len);
s->string.str[len] = '\0';
return s;
}
/* Return a newly constructed COMPLEX_CST node whose value is
specified by the real and imaginary parts REAL and IMAG.
Both REAL and IMAG should be constant nodes. TYPE, if specified,
will be the type of the COMPLEX_CST; otherwise a new type will be made. */
tree
build_complex (tree type, tree real, tree imag)
{
tree t = make_node (COMPLEX_CST);
TREE_REALPART (t) = real;
TREE_IMAGPART (t) = imag;
TREE_TYPE (t) = type ? type : build_complex_type (TREE_TYPE (real));
TREE_OVERFLOW (t) = TREE_OVERFLOW (real) | TREE_OVERFLOW (imag);
return t;
}
/* Return a constant of arithmetic type TYPE which is the
multiplicative identity of the set TYPE. */
tree
build_one_cst (tree type)
{
switch (TREE_CODE (type))
{
case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
case POINTER_TYPE: case REFERENCE_TYPE:
case OFFSET_TYPE:
return build_int_cst (type, 1);
case REAL_TYPE:
return build_real (type, dconst1);
case FIXED_POINT_TYPE:
/* We can only generate 1 for accum types. */
gcc_assert (ALL_SCALAR_ACCUM_MODE_P (TYPE_MODE (type)));
return build_fixed (type, FCONST1 (TYPE_MODE (type)));
case VECTOR_TYPE:
{
tree scalar = build_one_cst (TREE_TYPE (type));
return build_vector_from_val (type, scalar);
}
case COMPLEX_TYPE:
return build_complex (type,
build_one_cst (TREE_TYPE (type)),
build_zero_cst (TREE_TYPE (type)));
default:
gcc_unreachable ();
}
}
/* Return an integer of type TYPE containing all 1's in as much precision as
it contains, or a complex or vector whose subparts are such integers. */
tree
build_all_ones_cst (tree type)
{
if (TREE_CODE (type) == COMPLEX_TYPE)
{
tree scalar = build_all_ones_cst (TREE_TYPE (type));
return build_complex (type, scalar, scalar);
}
else
return build_minus_one_cst (type);
}
/* Return a constant of arithmetic type TYPE which is the
opposite of the multiplicative identity of the set TYPE. */
tree
build_minus_one_cst (tree type)
{
switch (TREE_CODE (type))
{
case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
case POINTER_TYPE: case REFERENCE_TYPE:
case OFFSET_TYPE:
return build_int_cst (type, -1);
case REAL_TYPE:
return build_real (type, dconstm1);
case FIXED_POINT_TYPE:
/* We can only generate 1 for accum types. */
gcc_assert (ALL_SCALAR_ACCUM_MODE_P (TYPE_MODE (type)));
return build_fixed (type, fixed_from_double_int (double_int_minus_one,
TYPE_MODE (type)));
case VECTOR_TYPE:
{
tree scalar = build_minus_one_cst (TREE_TYPE (type));
return build_vector_from_val (type, scalar);
}
case COMPLEX_TYPE:
return build_complex (type,
build_minus_one_cst (TREE_TYPE (type)),
build_zero_cst (TREE_TYPE (type)));
default:
gcc_unreachable ();
}
}
/* Build 0 constant of type TYPE. This is used by constructor folding
and thus the constant should be represented in memory by
zero(es). */
tree
build_zero_cst (tree type)
{
switch (TREE_CODE (type))
{
case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
case POINTER_TYPE: case REFERENCE_TYPE:
case OFFSET_TYPE: case NULLPTR_TYPE:
return build_int_cst (type, 0);
case REAL_TYPE:
return build_real (type, dconst0);
case FIXED_POINT_TYPE:
return build_fixed (type, FCONST0 (TYPE_MODE (type)));
case VECTOR_TYPE:
{
tree scalar = build_zero_cst (TREE_TYPE (type));
return build_vector_from_val (type, scalar);
}
case COMPLEX_TYPE:
{
tree zero = build_zero_cst (TREE_TYPE (type));
return build_complex (type, zero, zero);
}
default:
if (!AGGREGATE_TYPE_P (type))
return fold_convert (type, integer_zero_node);
return build_constructor (type, NULL);
}
}
/* Build a BINFO with LEN language slots. */
tree
make_tree_binfo_stat (unsigned base_binfos MEM_STAT_DECL)
{
tree t;
size_t length = (offsetof (struct tree_binfo, base_binfos)
+ vec<tree, va_gc>::embedded_size (base_binfos));
record_node_allocation_statistics (TREE_BINFO, length);
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);
BINFO_BASE_BINFOS (t)->embedded_init (base_binfos);
return t;
}
/* Create a CASE_LABEL_EXPR tree node and return it. */
tree
build_case_label (tree low_value, tree high_value, tree label_decl)
{
tree t = make_node (CASE_LABEL_EXPR);
TREE_TYPE (t) = void_type_node;
SET_EXPR_LOCATION (t, DECL_SOURCE_LOCATION (label_decl));
CASE_LOW (t) = low_value;
CASE_HIGH (t) = high_value;
CASE_LABEL (t) = label_decl;
CASE_CHAIN (t) = NULL_TREE;
return t;
}
/* Build a newly constructed INTEGER_CST node. LEN and EXT_LEN are the
values of TREE_INT_CST_NUNITS and TREE_INT_CST_EXT_NUNITS respectively.
The latter determines the length of the HOST_WIDE_INT vector. */
tree
make_int_cst_stat (int len, int ext_len MEM_STAT_DECL)
{
tree t;
int length = ((ext_len - 1) * sizeof (HOST_WIDE_INT)
+ sizeof (struct tree_int_cst));
gcc_assert (len);
record_node_allocation_statistics (INTEGER_CST, length);
t = ggc_alloc_cleared_tree_node_stat (length PASS_MEM_STAT);
TREE_SET_CODE (t, INTEGER_CST);
TREE_INT_CST_NUNITS (t) = len;
TREE_INT_CST_EXT_NUNITS (t) = ext_len;
/* to_offset can only be applied to trees that are offset_int-sized
or smaller. EXT_LEN is correct if it fits, otherwise the constant
must be exactly the precision of offset_int and so LEN is correct. */
if (ext_len <= OFFSET_INT_ELTS)
TREE_INT_CST_OFFSET_NUNITS (t) = ext_len;
else
TREE_INT_CST_OFFSET_NUNITS (t) = len;
TREE_CONSTANT (t) = 1;
return t;
}
/* Build a newly constructed TREE_VEC node of length LEN. */
tree
make_tree_vec_stat (int len MEM_STAT_DECL)
{
tree t;
int length = (len - 1) * sizeof (tree) + sizeof (struct tree_vec);
record_node_allocation_statistics (TREE_VEC, length);
t = ggc_alloc_cleared_tree_node_stat (length PASS_MEM_STAT);
TREE_SET_CODE (t, TREE_VEC);
TREE_VEC_LENGTH (t) = len;
return t;
}
/* Grow a TREE_VEC node to new length LEN. */
tree
grow_tree_vec_stat (tree v, int len MEM_STAT_DECL)
{
gcc_assert (TREE_CODE (v) == TREE_VEC);
int oldlen = TREE_VEC_LENGTH (v);
gcc_assert (len > oldlen);
int oldlength = (oldlen - 1) * sizeof (tree) + sizeof (struct tree_vec);
int length = (len - 1) * sizeof (tree) + sizeof (struct tree_vec);
record_node_allocation_statistics (TREE_VEC, length - oldlength);
v = (tree) ggc_realloc (v, length PASS_MEM_STAT);
TREE_VEC_LENGTH (v) = len;
return v;
}
/* Return 1 if EXPR is the integer constant zero or a complex constant
of zero. */
int
integer_zerop (const_tree expr)
{
STRIP_NOPS (expr);
switch (TREE_CODE (expr))
{
case INTEGER_CST:
return wi::eq_p (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
complex constant. */
int
integer_onep (const_tree expr)
{
STRIP_NOPS (expr);
switch (TREE_CODE (expr))
{
case INTEGER_CST:
return wi::eq_p (wi::to_widest (expr), 1);
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 the integer constant one. For complex and vector,
return 1 if every piece is the integer constant one. */
int
integer_each_onep (const_tree expr)
{
STRIP_NOPS (expr);
if (TREE_CODE (expr) == COMPLEX_CST)
return (integer_onep (TREE_REALPART (expr))
&& integer_onep (TREE_IMAGPART (expr)));
else
return integer_onep (expr);
}
/* Return 1 if EXPR is an integer containing all 1's in as much precision as
it contains, or a complex or vector whose subparts are such integers. */
int
integer_all_onesp (const_tree expr)
{
STRIP_NOPS (expr);
if (TREE_CODE (expr) == COMPLEX_CST
&& integer_all_onesp (TREE_REALPART (expr))
&& integer_all_onesp (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;
return wi::max_value (TYPE_PRECISION (TREE_TYPE (expr)), UNSIGNED) == expr;
}
/* Return 1 if EXPR is the integer constant minus one. */
int
integer_minus_onep (const_tree expr)
{
STRIP_NOPS (expr);
if (TREE_CODE (expr) == COMPLEX_CST)
return (integer_all_onesp (TREE_REALPART (expr))
&& integer_zerop (TREE_IMAGPART (expr)));
else
return integer_all_onesp (expr);
}
/* Return 1 if EXPR is an integer constant that is a power of 2 (i.e., has only
one bit on). */
int
integer_pow2p (const_tree expr)
{
STRIP_NOPS (expr);
if (TREE_CODE (expr) == COMPLEX_CST
&& integer_pow2p (TREE_REALPART (expr))
&& integer_zerop (TREE_IMAGPART (expr)))
return 1;
if (TREE_CODE (expr) != INTEGER_CST)
return 0;
return wi::popcount (expr) == 1;
}
/* Return 1 if EXPR is an integer constant other than zero or a
complex constant other than zero. */
int
integer_nonzerop (const_tree expr)
{
STRIP_NOPS (expr);
return ((TREE_CODE (expr) == INTEGER_CST
&& !wi::eq_p (expr, 0))
|| (TREE_CODE (expr) == COMPLEX_CST
&& (integer_nonzerop (TREE_REALPART (expr))
|| integer_nonzerop (TREE_IMAGPART (expr)))));
}
/* Return 1 if EXPR is the integer constant one. For vector,
return 1 if every piece is the integer constant minus one
(representing the value TRUE). */
int
integer_truep (const_tree expr)
{
STRIP_NOPS (expr);
if (TREE_CODE (expr) == VECTOR_CST)
return integer_all_onesp (expr);
return integer_onep (expr);
}
/* Return 1 if EXPR is the fixed-point constant zero. */
int
fixed_zerop (const_tree expr)
{
return (TREE_CODE (expr) == FIXED_CST
&& TREE_FIXED_CST (expr).data.is_zero ());
}
/* Return the power of two represented by a tree node known to be a
power of two. */
int
tree_log2 (const_tree expr)
{
STRIP_NOPS (expr);
if (TREE_CODE (expr) == COMPLEX_CST)
return tree_log2 (TREE_REALPART (expr));
return wi::exact_log2 (expr);
}
/* Similar, but return the largest integer Y such that 2 ** Y is less
than or equal to EXPR. */
int
tree_floor_log2 (const_tree expr)
{
STRIP_NOPS (expr);
if (TREE_CODE (expr) == COMPLEX_CST)
return tree_log2 (TREE_REALPART (expr));
return wi::floor_log2 (expr);
}
/* Return number of known trailing zero bits in EXPR, or, if the value of
EXPR is known to be zero, the precision of it's type. */
unsigned int
tree_ctz (const_tree expr)
{
if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
&& !POINTER_TYPE_P (TREE_TYPE (expr)))
return 0;
unsigned int ret1, ret2, prec = TYPE_PRECISION (TREE_TYPE (expr));
switch (TREE_CODE (expr))
{
case INTEGER_CST:
ret1 = wi::ctz (expr);
return MIN (ret1, prec);
case SSA_NAME:
ret1 = wi::ctz (get_nonzero_bits (expr));
return MIN (ret1, prec);
case PLUS_EXPR:
case MINUS_EXPR:
case BIT_IOR_EXPR:
case BIT_XOR_EXPR:
case MIN_EXPR:
case MAX_EXPR:
ret1 = tree_ctz (TREE_OPERAND (expr, 0));
if (ret1 == 0)
return ret1;
ret2 = tree_ctz (TREE_OPERAND (expr, 1));
return MIN (ret1, ret2);
case POINTER_PLUS_EXPR:
ret1 = tree_ctz (TREE_OPERAND (expr, 0));
ret2 = tree_ctz (TREE_OPERAND (expr, 1));
/* Second operand is sizetype, which could be in theory
wider than pointer's precision. Make sure we never
return more than prec. */
ret2 = MIN (ret2, prec);
return MIN (ret1, ret2);
case BIT_AND_EXPR:
ret1 = tree_ctz (TREE_OPERAND (expr, 0));
ret2 = tree_ctz (TREE_OPERAND (expr, 1));
return MAX (ret1, ret2);
case MULT_EXPR:
ret1 = tree_ctz (TREE_OPERAND (expr, 0));
ret2 = tree_ctz (TREE_OPERAND (expr, 1));
return MIN (ret1 + ret2, prec);
case LSHIFT_EXPR:
ret1 = tree_ctz (TREE_OPERAND (expr, 0));
if (tree_fits_uhwi_p (TREE_OPERAND (expr, 1))
&& (tree_to_uhwi (TREE_OPERAND (expr, 1)) < prec))
{
ret2 = tree_to_uhwi (TREE_OPERAND (expr, 1));
return MIN (ret1 + ret2, prec);
}
return ret1;
case RSHIFT_EXPR:
if (tree_fits_uhwi_p (TREE_OPERAND (expr, 1))
&& (tree_to_uhwi (TREE_OPERAND (expr, 1)) < prec))
{
ret1 = tree_ctz (TREE_OPERAND (expr, 0));
ret2 = tree_to_uhwi (TREE_OPERAND (expr, 1));
if (ret1 > ret2)
return ret1 - ret2;
}
return 0;
case TRUNC_DIV_EXPR:
case CEIL_DIV_EXPR:
case FLOOR_DIV_EXPR:
case ROUND_DIV_EXPR:
case EXACT_DIV_EXPR:
if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
&& tree_int_cst_sgn (TREE_OPERAND (expr, 1)) == 1)
{
int l = tree_log2 (TREE_OPERAND (expr, 1));
if (l >= 0)
{
ret1 = tree_ctz (TREE_OPERAND (expr, 0));
ret2 = l;
if (ret1 > ret2)
return ret1 - ret2;
}
}
return 0;
CASE_CONVERT:
ret1 = tree_ctz (TREE_OPERAND (expr, 0));
if (ret1 && ret1 == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
ret1 = prec;
return MIN (ret1, prec);
case SAVE_EXPR:
return tree_ctz (TREE_OPERAND (expr, 0));
case COND_EXPR:
ret1 = tree_ctz (TREE_OPERAND (expr, 1));
if (ret1 == 0)
return 0;
ret2 = tree_ctz (TREE_OPERAND (expr, 2));
return MIN (ret1, ret2);
case COMPOUND_EXPR:
return tree_ctz (TREE_OPERAND (expr, 1));
case ADDR_EXPR:
ret1 = get_pointer_alignment (CONST_CAST_TREE (expr));
if (ret1 > BITS_PER_UNIT)
{
ret1 = ctz_hwi (ret1 / BITS_PER_UNIT);
return MIN (ret1, prec);
}
return 0;
default:
return 0;
}
}
/* Return 1 if EXPR is the real constant zero. Trailing zeroes matter for
decimal float constants, so don't return 1 for them. */
int
real_zerop (const_tree expr)
{
STRIP_NOPS (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.
Trailing zeroes matter for decimal float constants, so don't return
1 for them. */
int
real_onep (const_tree expr)
{
STRIP_NOPS (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 minus one. Trailing zeroes
matter for decimal float constants, so don't return 1 for them. */
int
real_minus_onep (const_tree expr)
{
STRIP_NOPS (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. */
int
really_constant_p (const_tree exp)
{
/* This is not quite the same as STRIP_NOPS. It does more. */
while (CONVERT_EXPR_P (exp)
|| TREE_CODE (exp) == NON_LVALUE_EXPR)
exp = TREE_OPERAND (exp, 0);
return TREE_CONSTANT (exp);
}
/* Return first list element whose TREE_VALUE is ELEM.
Return 0 if ELEM is not in LIST. */
tree
value_member (tree elem, tree list)
{
while (list)
{
if (elem == TREE_VALUE (list))
return list;
list = TREE_CHAIN (list);
}
return NULL_TREE;
}
/* Return first list element whose TREE_PURPOSE is ELEM.
Return 0 if ELEM is not in LIST. */
tree
purpose_member (const_tree elem, tree list)
{
while (list)
{
if (elem == TREE_PURPOSE (list))
return list;
list = TREE_CHAIN (list);
}
return NULL_TREE;
}
/* Return true if ELEM is in V. */
bool
vec_member (const_tree elem, vec<tree, va_gc> *v)
{
unsigned ix;
tree t;
FOR_EACH_VEC_SAFE_ELT (v, ix, t)
if (elem == t)
return true;
return false;
}
/* Returns element number IDX (zero-origin) of chain CHAIN, or
NULL_TREE. */
tree
chain_index (int idx, tree chain)
{
for (; chain && idx > 0; --idx)
chain = TREE_CHAIN (chain);
return chain;
}
/* Return nonzero if ELEM is part of the chain CHAIN. */
int
chain_member (const_tree elem, const_tree chain)
{
while (chain)
{
if (elem == chain)
return 1;
chain = DECL_CHAIN (chain);
}
return 0;
}
/* Return the length of a chain of nodes chained through TREE_CHAIN.
We expect a null pointer to mark the end of the chain.
This is the Lisp primitive `length'. */
int
list_length (const_tree t)
{
const_tree p = t;
#ifdef ENABLE_TREE_CHECKING
const_tree q = t;
#endif
int len = 0;
while (p)
{
p = TREE_CHAIN (p);
#ifdef ENABLE_TREE_CHECKING
if (len % 2)
q = TREE_CHAIN (q);
gcc_assert (p != q);
#endif
len++;
}
return len;
}
/* Returns the first FIELD_DECL in the TYPE_FIELDS of the RECORD_TYPE or
UNION_TYPE TYPE, or NULL_TREE if none. */
tree
first_field (const_tree type)
{
tree t = TYPE_FIELDS (type);
while (t && TREE_CODE (t) != FIELD_DECL)
t = TREE_CHAIN (t);
return t;
}
/* Concatenate two chains of nodes (chained through TREE_CHAIN)
by modifying the last node in chain 1 to point to chain 2.
This is the Lisp primitive `nconc'. */
tree
chainon (tree op1, tree op2)
{
tree t1;
if (!op1)
return op2;
if (!op2)
return op1;
for (t1 = op1; TREE_CHAIN (t1); t1 = TREE_CHAIN (t1))
continue;
TREE_CHAIN (t1) = op2;
#ifdef ENABLE_TREE_CHECKING
{
tree t2;
for (t2 = op2; t2; t2 = TREE_CHAIN (t2))
gcc_assert (t2 != t1);
}
#endif
return op1;
}
/* Return the last node in a chain of nodes (chained through TREE_CHAIN). */
tree
tree_last (tree chain)
{
tree next;
if (chain)
while ((next = TREE_CHAIN (chain)))
chain = next;
return chain;
}
/* Reverse the order of elements in the chain T,
and return the new head of the chain (old last element). */
tree
nreverse (tree t)
{
tree prev = 0, decl, next;
for (decl = t; decl; decl = next)
{
/* We shouldn't be using this function to reverse BLOCK chains; we
have blocks_nreverse for that. */
gcc_checking_assert (TREE_CODE (decl) != BLOCK);
next = TREE_CHAIN (decl);
TREE_CHAIN (decl) = prev;
prev = decl;
}
return prev;
}
/* Return a newly created TREE_LIST node whose
purpose and value fields are PARM and VALUE. */
tree
build_tree_list_stat (tree parm, tree value MEM_STAT_DECL)
{
tree t = make_node_stat (TREE_LIST PASS_MEM_STAT);
TREE_PURPOSE (t) = parm;
TREE_VALUE (t) = value;
return t;
}
/* Build a chain of TREE_LIST nodes from a vector. */
tree
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_SAFE_ELT (vec, i, t)
{
*pp = build_tree_list_stat (NULL, t PASS_MEM_STAT);
pp = &TREE_CHAIN (*pp);
}
return ret;
}
/* Return a newly created TREE_LIST node whose
purpose and value fields are PURPOSE and VALUE
and whose TREE_CHAIN is CHAIN. */
tree
tree_cons_stat (tree purpose, tree value, tree chain MEM_STAT_DECL)
{
tree node;
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));
TREE_SET_CODE (node, TREE_LIST);
TREE_CHAIN (node) = chain;
TREE_PURPOSE (node) = purpose;
TREE_VALUE (node) = value;
return node;
}
/* Return the values of the elements of a CONSTRUCTOR as a vector of
trees. */
vec<tree, va_gc> *
ctor_to_vec (tree 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 (val);
return vec;
}
/* Return the size nominally occupied by an object of type TYPE
when it resides in memory. The value is measured in units of bytes,
and its data type is that normally used for type sizes
(which is the first type created by make_signed_type or
make_unsigned_type). */
tree
size_in_bytes (const_tree type)
{
tree t;
if (type == error_mark_node)
return integer_zero_node;
type = TYPE_MAIN_VARIANT (type);
t = TYPE_SIZE_UNIT (type);
if (t == 0)
{
lang_hooks.types.incomplete_type_error (NULL_TREE, type);
return size_zero_node;
}
return t;
}
/* Return the size of TYPE (in bytes) as a wide integer
or return -1 if the size can vary or is larger than an integer. */
HOST_WIDE_INT
int_size_in_bytes (const_tree type)
{
tree t;
if (type == error_mark_node)
return 0;
type = TYPE_MAIN_VARIANT (type);
t = TYPE_SIZE_UNIT (type);
if (t && tree_fits_uhwi_p (t))
return TREE_INT_CST_LOW (t);
else
return -1;
}
/* Return the maximum size of TYPE (in bytes) as a wide integer
or return -1 if the size can vary or is larger than an integer. */
HOST_WIDE_INT
max_int_size_in_bytes (const_tree type)
{
HOST_WIDE_INT size = -1;
tree size_tree;
/* If this is an array type, check for a possible MAX_SIZE attached. */
if (TREE_CODE (type) == ARRAY_TYPE)
{
size_tree = TYPE_ARRAY_MAX_SIZE (type);
if (size_tree && tree_fits_uhwi_p (size_tree))
size = tree_to_uhwi (size_tree);
}
/* If we still haven't been able to get a size, see if the language
can compute a maximum size. */
if (size == -1)
{
size_tree = lang_hooks.types.max_size (type);
if (size_tree && tree_fits_uhwi_p (size_tree))
size = tree_to_uhwi (size_tree);
}
return size;
}
/* Return the bit position of FIELD, in bits from the start of the record.
This is a tree of type bitsizetype. */
tree
bit_position (const_tree field)
{
return bit_from_pos (DECL_FIELD_OFFSET (field),
DECL_FIELD_BIT_OFFSET (field));
}
/* Return the byte position of FIELD, in bytes from the start of the record.
This is a tree of type sizetype. */
tree
byte_position (const_tree field)
{
return byte_from_pos (DECL_FIELD_OFFSET (field),
DECL_FIELD_BIT_OFFSET (field));
}
/* Likewise, but return as an integer. It must be representable in
that way (since it could be a signed value, we don't have the
option of returning -1 like int_size_in_byte can. */
HOST_WIDE_INT
int_byte_position (const_tree field)
{
return tree_to_shwi (byte_position (field));
}
/* Return the strictest alignment, in bits, that T is known to have. */
unsigned int
expr_align (const_tree t)
{
unsigned int align0, align1;
switch (TREE_CODE (t))
{
CASE_CONVERT: case NON_LVALUE_EXPR:
/* If we have conversions, we know that the alignment of the
object must meet each of the alignments of the types. */
align0 = expr_align (TREE_OPERAND (t, 0));
align1 = TYPE_ALIGN (TREE_TYPE (t));
return MAX (align0, align1);
case SAVE_EXPR: case COMPOUND_EXPR: case MODIFY_EXPR:
case INIT_EXPR: case TARGET_EXPR: case WITH_CLEANUP_EXPR:
case CLEANUP_POINT_EXPR:
/* These don't change the alignment of an object. */
return expr_align (TREE_OPERAND (t, 0));
case COND_EXPR:
/* The best we can do is say that the alignment is the least aligned
of the two arms. */
align0 = expr_align (TREE_OPERAND (t, 1));
align1 = expr_align (TREE_OPERAND (t, 2));
return MIN (align0, align1);
/* FIXME: LABEL_DECL and CONST_DECL never have DECL_ALIGN set
meaningfully, it's always 1. */
case LABEL_DECL: case CONST_DECL:
case VAR_DECL: case PARM_DECL: case RESULT_DECL:
case FUNCTION_DECL:
gcc_assert (DECL_ALIGN (t) != 0);
return DECL_ALIGN (t);
default:
break;
}
/* Otherwise take the alignment from that of the type. */
return TYPE_ALIGN (TREE_TYPE (t));
}
/* Return, as a tree node, the number of elements for TYPE (which is an
ARRAY_TYPE) minus one. This counts only elements of the top array. */
tree
array_type_nelts (const_tree type)
{
tree index_type, min, max;
/* If they did it with unspecified bounds, then we should have already
given an error about it before we got here. */
if (! TYPE_DOMAIN (type))
return error_mark_node;
index_type = TYPE_DOMAIN (type);
min = TYPE_MIN_VALUE (index_type);
max = TYPE_MAX_VALUE (index_type);
/* TYPE_MAX_VALUE may not be set if the array has unknown length. */
if (!max)
return error_mark_node;
return (integer_zerop (min)
? max
: fold_build2 (MINUS_EXPR, TREE_TYPE (max), max, min));
}
/* If arg is static -- a reference to an object in static storage -- then
return the object. This is not the same as the C meaning of `static'.
If arg isn't static, return NULL. */
tree
staticp (tree arg)
{
switch (TREE_CODE (arg))
{
case FUNCTION_DECL:
/* Nested functions are static, even though taking their address will
involve a trampoline as we unnest the nested function and create
the trampoline on the tree level. */
return arg;
case VAR_DECL:
return ((TREE_STATIC (arg) || DECL_EXTERNAL (arg))
&& ! DECL_THREAD_LOCAL_P (arg)
&& ! DECL_DLLIMPORT_P (arg)
? arg : NULL);
case CONST_DECL:
return ((TREE_STATIC (arg) || DECL_EXTERNAL (arg))
? arg : NULL);
case CONSTRUCTOR:
return TREE_STATIC (arg) ? arg : NULL;
case LABEL_DECL:
case STRING_CST:
return arg;
case COMPONENT_REF:
/* If the thing being referenced is not a field, then it is
something language specific. */
gcc_assert (TREE_CODE (TREE_OPERAND (arg, 1)) == FIELD_DECL);
/* If we are referencing a bitfield, we can't evaluate an
ADDR_EXPR at compile time and so it isn't a constant. */
if (DECL_BIT_FIELD (TREE_OPERAND (arg, 1)))
return NULL;
return staticp (TREE_OPERAND (arg, 0));
case BIT_FIELD_REF:
return NULL;
case INDIRECT_REF:
return TREE_CONSTANT (TREE_OPERAND (arg, 0)) ? arg : NULL;
case ARRAY_REF:
case ARRAY_RANGE_REF:
if (TREE_CODE (TYPE_SIZE (TREE_TYPE (arg))) == INTEGER_CST
&& TREE_CODE (TREE_OPERAND (arg, 1)) == INTEGER_CST)
return staticp (TREE_OPERAND (arg, 0));
else
return NULL;
case COMPOUND_LITERAL_EXPR:
return TREE_STATIC (COMPOUND_LITERAL_EXPR_DECL (arg)) ? arg : NULL;
default:
return NULL;
}
}
/* Return whether OP is a DECL whose address is function-invariant. */
bool
decl_address_invariant_p (const_tree op)
{
/* The conditions below are slightly less strict than the one in
staticp. */
switch (TREE_CODE (op))
{
case PARM_DECL:
case RESULT_DECL:
case LABEL_DECL:
case FUNCTION_DECL:
return true;
case VAR_DECL:
if ((TREE_STATIC (op) || DECL_EXTERNAL (op))
|| DECL_THREAD_LOCAL_P (op)
|| DECL_CONTEXT (op) == current_function_decl
|| decl_function_context (op) == current_function_decl)
return true;
break;
case CONST_DECL:
if ((TREE_STATIC (op) || DECL_EXTERNAL (op))
|| decl_function_context (op) == current_function_decl)
return true;
break;
default:
break;
}
return false;
}
/* Return whether OP is a DECL whose address is interprocedural-invariant. */
bool
decl_address_ip_invariant_p (const_tree op)
{
/* The conditions below are slightly less strict than the one in
staticp. */
switch (TREE_CODE (op))
{
case LABEL_DECL:
case FUNCTION_DECL:
case STRING_CST:
return true;
case VAR_DECL:
if (((TREE_STATIC (op) || DECL_EXTERNAL (op))
&& !DECL_DLLIMPORT_P (op))
|| DECL_THREAD_LOCAL_P (op))
return true;
break;
case CONST_DECL:
if ((TREE_STATIC (op) || DECL_EXTERNAL (op)))
return true;
break;
default:
break;
}
return false;
}
/* Return true if T is function-invariant (internal function, does
not handle arithmetic; that's handled in skip_simple_arithmetic and
tree_invariant_p). */
static bool tree_invariant_p (tree t);
static bool
tree_invariant_p_1 (tree t)
{
tree op;
if (TREE_CONSTANT (t)
|| (TREE_READONLY (t) && !TREE_SIDE_EFFECTS (t)))
return true;
switch (TREE_CODE (t))
{
case SAVE_EXPR:
return true;
case ADDR_EXPR:
op = TREE_OPERAND (t, 0);
while (handled_component_p (op))
{
switch (TREE_CODE (op))
{
case ARRAY_REF:
case ARRAY_RANGE_REF:
if (!tree_invariant_p (TREE_OPERAND (op, 1))
|| TREE_OPERAND (op, 2) != NULL_TREE
|| TREE_OPERAND (op, 3) != NULL_TREE)
return false;
break;
case COMPONENT_REF:
if (TREE_OPERAND (op, 2) != NULL_TREE)
return false;
break;
default:;
}
op = TREE_OPERAND (op, 0);
}
return CONSTANT_CLASS_P (op) || decl_address_invariant_p (op);
default:
break;
}
return false;
}
/* Return true if T is function-invariant. */
static bool
tree_invariant_p (tree t)
{
tree inner = skip_simple_arithmetic (t);
return tree_invariant_p_1 (inner);
}
/* Wrap a SAVE_EXPR around EXPR, if appropriate.
Do this to any expression which may be used in more than one place,
but must be evaluated only once.
Normally, expand_expr would reevaluate the expression each time.
Calling save_expr produces something that is evaluated and recorded
the first time expand_expr is called on it. Subsequent calls to
expand_expr just reuse the recorded value.
The call to expand_expr that generates code that actually computes
the value is the first call *at compile time*. Subsequent calls
*at compile time* generate code to use the saved value.
This produces correct result provided that *at run time* control
always flows through the insns made by the first expand_expr
before reaching the other places where the save_expr was evaluated.
You, the caller of save_expr, must make sure this is so.
Constants, and certain read-only nodes, are returned with no
SAVE_EXPR because that is safe. Expressions containing placeholders
are not touched; see tree.def for an explanation of what these
are used for. */
tree
save_expr (tree expr)
{
tree t = fold (expr);
tree inner;
/* If the tree evaluates to a constant, then we don't want to hide that
fact (i.e. this allows further folding, and direct checks for constants).
However, a read-only object that has side effects cannot be bypassed.
Since it is no problem to reevaluate literals, we just return the
literal node. */
inner = skip_simple_arithmetic (t);
if (TREE_CODE (inner) == ERROR_MARK)
return inner;
if (tree_invariant_p_1 (inner))
return t;
/* If INNER contains a PLACEHOLDER_EXPR, we must evaluate it each time, since
it means that the size or offset of some field of an object depends on
the value within another field.
Note that it must not be the case that T contains both a PLACEHOLDER_EXPR
and some variable since it would then need to be both evaluated once and
evaluated more than once. Front-ends must assure this case cannot
happen by surrounding any such subexpressions in their own SAVE_EXPR
and forcing evaluation at the proper time. */
if (contains_placeholder_p (inner))
return t;
t = build1 (SAVE_EXPR, TREE_TYPE (expr), t);
SET_EXPR_LOCATION (t, EXPR_LOCATION (expr));
/* This expression might be placed ahead of a jump to ensure that the
value was computed on both sides of the jump. So make sure it isn't
eliminated as dead. */
TREE_SIDE_EFFECTS (t) = 1;
return t;
}
/* Look inside EXPR into any simple arithmetic operations. Return the
outermost non-arithmetic or non-invariant node. */
tree
skip_simple_arithmetic (tree expr)
{
/* We don't care about whether this can be used as an lvalue in this
context. */
while (TREE_CODE (expr) == NON_LVALUE_EXPR)
expr = TREE_OPERAND (expr, 0);
/* If we have simple operations applied to a SAVE_EXPR or to a SAVE_EXPR and
a constant, it will be more efficient to not make another SAVE_EXPR since
it will allow better simplification and GCSE will be able to merge the
computations if they actually occur. */
while (true)
{
if (UNARY_CLASS_P (expr))
expr = TREE_OPERAND (expr, 0);
else if (BINARY_CLASS_P (expr))
{
if (tree_invariant_p (TREE_OPERAND (expr, 1)))
expr = TREE_OPERAND (expr, 0);
else if (tree_invariant_p (TREE_OPERAND