#include "toplev.h"
#include "ggc.h"
#include "hashtab.h"
+#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"
#ifdef GATHER_STATISTICS
/* 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];
static GTY ((if_marked ("tree_decl_map_marked_p"), param_is (struct tree_decl_map)))
htab_t value_expr_for_decl;
+static GTY ((if_marked ("tree_vec_map_marked_p"), param_is (struct tree_vec_map)))
+ htab_t debug_args_for_decl;
+
static GTY ((if_marked ("tree_priority_map_marked_p"),
param_is (struct tree_priority_map)))
htab_t init_priority_for_decl;
}
}
case tcc_type:
- return TS_TYPE;
+ return TS_TYPE_NON_COMMON;
case tcc_reference:
case tcc_comparison:
case tcc_unary:
{
unsigned i;
-#define MARK_TS_BASE(C) \
- do { \
- tree_contains_struct[C][TS_BASE] = 1; \
- } while (0)
-
-#define MARK_TS_COMMON(C) \
- do { \
- MARK_TS_BASE (C); \
- tree_contains_struct[C][TS_COMMON] = 1; \
- } while (0)
-
-#define MARK_TS_DECL_MINIMAL(C) \
- do { \
- MARK_TS_COMMON (C); \
- tree_contains_struct[C][TS_DECL_MINIMAL] = 1; \
- } while (0)
-
-#define MARK_TS_DECL_COMMON(C) \
- do { \
- MARK_TS_DECL_MINIMAL (C); \
- tree_contains_struct[C][TS_DECL_COMMON] = 1; \
- } while (0)
-
-#define MARK_TS_DECL_WRTL(C) \
- do { \
- MARK_TS_DECL_COMMON (C); \
- tree_contains_struct[C][TS_DECL_WRTL] = 1; \
- } while (0)
-
-#define MARK_TS_DECL_WITH_VIS(C) \
- do { \
- MARK_TS_DECL_WRTL (C); \
- tree_contains_struct[C][TS_DECL_WITH_VIS] = 1; \
- } while (0)
-
-#define MARK_TS_DECL_NON_COMMON(C) \
- do { \
- MARK_TS_DECL_WITH_VIS (C); \
- tree_contains_struct[C][TS_DECL_NON_COMMON] = 1; \
- } while (0)
-
for (i = ERROR_MARK; i < LAST_AND_UNUSED_TREE_CODE; i++)
{
enum tree_code code;
/* Mark all the structures that TS is derived from. */
switch (ts_code)
{
- case TS_COMMON:
+ 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:
+ case TS_TYPE_COMMON:
case TS_LIST:
case TS_VEC:
- case TS_EXP:
- case TS_SSA_NAME:
- case TS_BLOCK:
case TS_BINFO:
- case TS_STATEMENT_LIST:
- case TS_CONSTRUCTOR:
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_PARM_DECL:
case TS_LABEL_DECL:
case TS_RESULT_DECL:
- case TS_CONST_DECL:
MARK_TS_DECL_WRTL (code);
break;
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[CONST_DECL][TS_DECL_WRTL]);
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_FUNCTION_DECL]);
gcc_assert (tree_contains_struct[IMPORTED_DECL][TS_DECL_MINIMAL]);
gcc_assert (tree_contains_struct[IMPORTED_DECL][TS_DECL_COMMON]);
-
-#undef MARK_TS_BASE
-#undef MARK_TS_COMMON
-#undef MARK_TS_DECL_MINIMAL
-#undef MARK_TS_DECL_COMMON
-#undef MARK_TS_DECL_WRTL
-#undef MARK_TS_DECL_WITH_VIS
-#undef MARK_TS_DECL_NON_COMMON
}
}
case tcc_type: /* a type node */
- return sizeof (struct tree_type);
+ return sizeof (struct tree_type_non_common);
case tcc_reference: /* a reference */
case tcc_expression: /* an expression */
}
}
-/* 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 or
- OMP_CLAUSE nodes, which is enforced by asserts in tree_code_size.
-
- Achoo! I got a code in the node. */
+/* Record interesting allocation statistics for a tree node with CODE
+ and LENGTH. */
-tree
-make_node_stat (enum tree_code code MEM_STAT_DECL)
+static void
+record_node_allocation_statistics (enum tree_code code ATTRIBUTE_UNUSED,
+ size_t length ATTRIBUTE_UNUSED)
{
- tree t;
- enum tree_code_class type = TREE_CODE_CLASS (code);
- size_t length = tree_code_size (code);
#ifdef GATHER_STATISTICS
+ enum tree_code_class type = TREE_CODE_CLASS (code);
tree_node_kind kind;
switch (type)
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;
#endif
+}
+
+/* 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 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_zone_cleared_tree_node_stat (
(code == IDENTIFIER_NODE) ? &tree_id_zone : &tree_zone,
DECL_UID (t) = --next_debug_decl_uid;
else
{
- DECL_UID (t) = next_decl_uid++;
+ DECL_UID (t) = allocate_decl_uid ();
SET_DECL_PT_UID (t, -1);
}
if (TREE_CODE (t) == LABEL_DECL)
}
\f
/* Return a new node with the same contents as NODE except that its
- TREE_CHAIN is zero and it has a fresh uid. */
+ TREE_CHAIN, if it has one, is zero and it has a fresh uid. */
tree
copy_node_stat (tree node MEM_STAT_DECL)
gcc_assert (code != STATEMENT_LIST);
length = tree_size (node);
+ record_node_allocation_statistics (code, length);
t = ggc_alloc_zone_tree_node_stat (&tree_zone, length PASS_MEM_STAT);
memcpy (t, node, length);
- TREE_CHAIN (t) = 0;
+ 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_UID (t) = --next_debug_decl_uid;
else
{
- DECL_UID (t) = next_decl_uid++;
+ DECL_UID (t) = allocate_decl_uid ();
if (DECL_PT_UID_SET_P (node))
SET_DECL_PT_UID (t, DECL_PT_UID (node));
}
}
\f
-/* Create an INT_CST node with a LOW value sign extended. */
+/* Create an INT_CST node with a LOW value sign extended to TYPE. */
tree
build_int_cst (tree type, HOST_WIDE_INT low)
if (!type)
type = integer_type_node;
- return build_int_cst_wide (type, low, low < 0 ? -1 : 0);
+ return double_int_to_tree (type, shwi_to_double_int (low));
}
-/* Create an INT_CST node with a LOW value in TYPE. The value is sign extended
- if it is negative. This function is similar to build_int_cst, but
- the extra bits outside of the type precision are cleared. Constants
- with these extra bits may confuse the fold so that it detects overflows
- even in cases when they do not occur, and in general should be avoided.
- We cannot however make this a default behavior of build_int_cst without
- more intrusive changes, since there are parts of gcc that rely on the extra
- precision of the integer constants. */
+/* Create an INT_CST node with a LOW value sign extended to TYPE. */
tree
build_int_cst_type (tree type, HOST_WIDE_INT low)
if (sc == error_mark_node)
return sc;
- gcc_assert (useless_type_conversion_p (TREE_TYPE (sc),
- TREE_TYPE (vectype)));
+ /* 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)));
v = VEC_alloc (constructor_elt, gc, nunits);
for (i = 0; i < nunits; ++i)
/* Do not waste bytes provided by padding of struct tree_string. */
length = len + offsetof (struct tree_string, str) + 1;
-#ifdef GATHER_STATISTICS
- tree_node_counts[(int) c_kind]++;
- tree_node_sizes[(int) c_kind] += length;
-#endif
+ record_node_allocation_statistics (STRING_CST, length);
s = ggc_alloc_tree_node (length);
- memset (s, 0, sizeof (struct tree_common));
+ memset (s, 0, sizeof (struct tree_typed));
TREE_SET_CODE (s, STRING_CST);
TREE_CONSTANT (s) = 1;
TREE_STRING_LENGTH (s) = len;
size_t length = (offsetof (struct tree_binfo, base_binfos)
+ VEC_embedded_size (tree, base_binfos));
-#ifdef GATHER_STATISTICS
- tree_node_counts[(int) binfo_kind]++;
- tree_node_sizes[(int) binfo_kind] += length;
-#endif
+ record_node_allocation_statistics (TREE_BINFO, length);
t = ggc_alloc_zone_tree_node_stat (&tree_zone, length PASS_MEM_STAT);
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 TREE_VEC node of length LEN. */
tree t;
int length = (len - 1) * sizeof (tree) + sizeof (struct tree_vec);
-#ifdef GATHER_STATISTICS
- tree_node_counts[(int) vec_kind]++;
- tree_node_sizes[(int) vec_kind] += length;
-#endif
+ record_node_allocation_statistics (TREE_VEC, length);
t = ggc_alloc_zone_cleared_tree_node_stat (&tree_zone, length PASS_MEM_STAT);
PASS_MEM_STAT);
memset (node, 0, sizeof (struct tree_common));
-#ifdef GATHER_STATISTICS
- tree_node_counts[(int) x_kind]++;
- tree_node_sizes[(int) x_kind] += sizeof (struct tree_list);
-#endif
+ record_node_allocation_statistics (TREE_LIST, sizeof (struct tree_list));
TREE_SET_CODE (node, TREE_LIST);
TREE_CHAIN (node) = chain;
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));
build1_stat (enum tree_code code, tree type, tree node MEM_STAT_DECL)
{
int length = sizeof (struct tree_exp);
-#ifdef GATHER_STATISTICS
- tree_node_kind kind;
-#endif
tree t;
-#ifdef GATHER_STATISTICS
- switch (TREE_CODE_CLASS (code))
- {
- case tcc_statement: /* an expression with side effects */
- kind = s_kind;
- break;
- case tcc_reference: /* a reference */
- kind = r_kind;
- break;
- default:
- kind = e_kind;
- break;
- }
-
- tree_node_counts[(int) kind]++;
- tree_node_sizes[(int) kind] += length;
-#endif
+ record_node_allocation_statistics (code, length);
gcc_assert (TREE_CODE_LENGTH (code) == 1);
return build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (base)));
}
+/* Return an invariant ADDR_EXPR of type TYPE taking the address of BASE
+ offsetted by OFFSET units. */
+
+tree
+build_invariant_address (tree type, tree base, HOST_WIDE_INT offset)
+{
+ tree ref = fold_build2 (MEM_REF, TREE_TYPE (type),
+ build_fold_addr_expr (base),
+ build_int_cst (ptr_type_node, offset));
+ tree addr = build1 (ADDR_EXPR, type, ref);
+ recompute_tree_invariant_for_addr_expr (addr);
+ return addr;
+}
+
/* Similar except don't specify the TREE_TYPE
and leave the TREE_SIDE_EFFECTS as 0.
It is permissible for arguments to be null,
its canonical type, we will need to use structural equality
checks for this type. */
if (TYPE_STRUCTURAL_EQUALITY_P (ttype)
- || !targetm.comp_type_attributes (ntype, ttype))
+ || !comp_type_attributes (ntype, ttype))
SET_TYPE_STRUCTURAL_EQUALITY (ntype);
else if (TYPE_CANONICAL (ntype) == ntype)
TYPE_CANONICAL (ntype) = TYPE_CANONICAL (ttype);
return ttype;
}
+/* Compare two attributes for their value identity. Return true if the
+ attribute values are known to be equal; otherwise return false.
+*/
+
+static bool
+attribute_value_equal (const_tree attr1, const_tree attr2)
+{
+ if (TREE_VALUE (attr1) == TREE_VALUE (attr2))
+ return true;
+
+ if (TREE_VALUE (attr1) != NULL_TREE
+ && TREE_CODE (TREE_VALUE (attr1)) == TREE_LIST
+ && TREE_VALUE (attr2) != NULL
+ && TREE_CODE (TREE_VALUE (attr2)) == TREE_LIST)
+ return (simple_cst_list_equal (TREE_VALUE (attr1),
+ TREE_VALUE (attr2)) == 1);
+
+ return (simple_cst_equal (TREE_VALUE (attr1), TREE_VALUE (attr2)) == 1);
+}
+
+/* Return 0 if the attributes for two types are incompatible, 1 if they
+ are compatible, and 2 if they are nearly compatible (which causes a
+ warning to be generated). */
+int
+comp_type_attributes (const_tree type1, const_tree type2)
+{
+ const_tree a1 = TYPE_ATTRIBUTES (type1);
+ const_tree a2 = TYPE_ATTRIBUTES (type2);
+ const_tree a;
+
+ if (a1 == a2)
+ return 1;
+ for (a = a1; a != NULL_TREE; a = TREE_CHAIN (a))
+ {
+ const struct attribute_spec *as;
+ const_tree attr;
+
+ as = lookup_attribute_spec (TREE_PURPOSE (a));
+ if (!as || as->affects_type_identity == false)
+ continue;
+
+ attr = lookup_attribute (as->name, CONST_CAST_TREE (a2));
+ if (!attr || !attribute_value_equal (a, attr))
+ break;
+ }
+ if (!a)
+ {
+ for (a = a2; a != NULL_TREE; a = TREE_CHAIN (a))
+ {
+ const struct attribute_spec *as;
+
+ as = lookup_attribute_spec (TREE_PURPOSE (a));
+ if (!as || as->affects_type_identity == false)
+ continue;
+
+ if (!lookup_attribute (as->name, CONST_CAST_TREE (a1)))
+ break;
+ /* We don't need to compare trees again, as we did this
+ already in first loop. */
+ }
+ /* All types - affecting identity - are equal, so
+ there is no need to call target hook for comparison. */
+ if (!a)
+ return 1;
+ }
+ /* As some type combinations - like default calling-convention - might
+ be compatible, we have to call the target hook to get the final result. */
+ return targetm.comp_type_attributes (type1, type2);
+}
/* Return a type like TTYPE except that its TYPE_ATTRIBUTE
is ATTRIBUTE.
TREE_LANG_FLAG_5 (decl) = 0;
TREE_LANG_FLAG_6 (decl) = 0;
- /* Identifiers need not have a type. */
- if (DECL_NAME (decl))
- TREE_TYPE (DECL_NAME (decl)) = NULL_TREE;
-
free_lang_data_in_one_sizepos (&DECL_SIZE (decl));
free_lang_data_in_one_sizepos (&DECL_SIZE_UNIT (decl));
if (TREE_CODE (decl) == FIELD_DECL)
&& RECORD_OR_UNION_TYPE_P
(DECL_CONTEXT (DECL_ABSTRACT_ORIGIN (decl))))
DECL_ABSTRACT_ORIGIN (decl) = NULL_TREE;
+
+ /* Sometimes the C++ frontend doesn't manage to transform a temporary
+ DECL_VINDEX referring to itself into a vtable slot number as it
+ should. Happens with functions that are copied and then forgotten
+ about. Just clear it, it won't matter anymore. */
+ if (DECL_VINDEX (decl) && !host_integerp (DECL_VINDEX (decl), 0))
+ DECL_VINDEX (decl) = NULL_TREE;
}
else if (TREE_CODE (decl) == VAR_DECL)
{
fld_worklist_push (BLOCK_ABSTRACT_ORIGIN (t), fld);
}
- fld_worklist_push (TREE_TYPE (t), fld);
+ if (TREE_CODE (t) != IDENTIFIER_NODE
+ && CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_TYPED))
+ fld_worklist_push (TREE_TYPE (t), fld);
return NULL_TREE;
}
/* Create gimple variants for common types. */
ptrdiff_type_node = integer_type_node;
fileptr_type_node = ptr_type_node;
- if (TREE_CODE (boolean_type_node) != BOOLEAN_TYPE
- || (TYPE_MODE (boolean_type_node)
- != mode_for_size (BOOL_TYPE_SIZE, MODE_INT, 0))
- || TYPE_PRECISION (boolean_type_node) != 1
- || !TYPE_UNSIGNED (boolean_type_node))
- {
- boolean_type_node = make_unsigned_type (BOOL_TYPE_SIZE);
- TREE_SET_CODE (boolean_type_node, BOOLEAN_TYPE);
- TYPE_MAX_VALUE (boolean_type_node) = build_int_cst (boolean_type_node, 1);
- TYPE_PRECISION (boolean_type_node) = 1;
- boolean_false_node = TYPE_MIN_VALUE (boolean_type_node);
- boolean_true_node = TYPE_MAX_VALUE (boolean_type_node);
- }
-
- /* Unify char_type_node with its properly signed variant. */
- if (TYPE_UNSIGNED (char_type_node))
- unsigned_char_type_node = char_type_node;
- else
- signed_char_type_node = char_type_node;
/* 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;
- lang_hooks.set_decl_assembler_name = lhd_set_decl_assembler_name;
+ /* We do not want the default decl_assembler_name implementation,
+ rather if we have fixed everything we want a wrapper around it
+ asserting that all non-local symbols already got their assembler
+ name and only produce assembler names for local symbols. Or rather
+ make sure we never call decl_assembler_name on local symbols and
+ devise a separate, middle-end private scheme for it. */
/* Reset diagnostic machinery. */
diagnostic_starter (global_dc) = default_tree_diagnostic_starter;
}
};
-/* Return nonzero if IDENT is a valid name for attribute ATTR,
- or zero if not.
-
- We try both `text' and `__text__', ATTR may be either one. */
-/* ??? It might be a reasonable simplification to require ATTR to be only
- `text'. One might then also require attribute lists to be stored in
- their canonicalized form. */
-
-static int
-is_attribute_with_length_p (const char *attr, int attr_len, const_tree ident)
+/* The backbone of is_attribute_p(). ATTR_LEN is the string length of
+ ATTR_NAME. Also used internally by remove_attribute(). */
+bool
+private_is_attribute_p (const char *attr_name, size_t attr_len, const_tree ident)
{
- int ident_len;
- const char *p;
-
- if (TREE_CODE (ident) != IDENTIFIER_NODE)
- return 0;
+ size_t ident_len = IDENTIFIER_LENGTH (ident);
- p = IDENTIFIER_POINTER (ident);
- ident_len = IDENTIFIER_LENGTH (ident);
-
- if (ident_len == attr_len
- && strcmp (attr, p) == 0)
- return 1;
-
- /* If ATTR is `__text__', IDENT must be `text'; and vice versa. */
- if (attr[0] == '_')
+ if (ident_len == attr_len)
{
- gcc_assert (attr[1] == '_');
- gcc_assert (attr[attr_len - 2] == '_');
- gcc_assert (attr[attr_len - 1] == '_');
- if (ident_len == attr_len - 4
- && strncmp (attr + 2, p, attr_len - 4) == 0)
- return 1;
+ if (strcmp (attr_name, IDENTIFIER_POINTER (ident)) == 0)
+ return true;
}
- else
+ else if (ident_len == attr_len + 4)
{
- if (ident_len == attr_len + 4
- && p[0] == '_' && p[1] == '_'
+ /* There is the possibility that ATTR is 'text' and IDENT is
+ '__text__'. */
+ const char *p = IDENTIFIER_POINTER (ident);
+ if (p[0] == '_' && p[1] == '_'
&& p[ident_len - 2] == '_' && p[ident_len - 1] == '_'
- && strncmp (attr, p + 2, attr_len) == 0)
- return 1;
+ && strncmp (attr_name, p + 2, attr_len) == 0)
+ return true;
}
- return 0;
+ return false;
}
-/* Return nonzero if IDENT is a valid name for attribute ATTR,
- or zero if not.
+/* The backbone of lookup_attribute(). ATTR_LEN is the string length
+ of ATTR_NAME, and LIST is not NULL_TREE. */
+tree
+private_lookup_attribute (const char *attr_name, size_t attr_len, tree list)
+{
+ while (list)
+ {
+ size_t ident_len = IDENTIFIER_LENGTH (TREE_PURPOSE (list));
- We try both `text' and `__text__', ATTR may be either one. */
+ if (ident_len == attr_len)
+ {
+ if (strcmp (attr_name, IDENTIFIER_POINTER (TREE_PURPOSE (list))) == 0)
+ break;
+ }
+ /* TODO: If we made sure that attributes were stored in the
+ canonical form without '__...__' (ie, as in 'text' as opposed
+ to '__text__') then we could avoid the following case. */
+ else if (ident_len == attr_len + 4)
+ {
+ const char *p = IDENTIFIER_POINTER (TREE_PURPOSE (list));
+ if (p[0] == '_' && p[1] == '_'
+ && p[ident_len - 2] == '_' && p[ident_len - 1] == '_'
+ && strncmp (attr_name, p + 2, attr_len) == 0)
+ break;
+ }
+ list = TREE_CHAIN (list);
+ }
-int
-is_attribute_p (const char *attr, const_tree ident)
-{
- return is_attribute_with_length_p (attr, strlen (attr), ident);
+ return list;
}
-/* Given an attribute name and a list of attributes, return a pointer to the
- attribute's list element if the attribute is part of the list, or NULL_TREE
- if not found. If the attribute appears more than once, this only
- returns the first occurrence; the TREE_CHAIN of the return value should
- be passed back in if further occurrences are wanted. */
+/* A variant of lookup_attribute() that can be used with an identifier
+ as the first argument, and where the identifier can be either
+ 'text' or '__text__'.
-tree
-lookup_attribute (const char *attr_name, tree list)
+ Given an attribute ATTR_IDENTIFIER, and a list of attributes LIST,
+ return a pointer to the attribute's list element if the attribute
+ is part of the list, or NULL_TREE if not found. If the attribute
+ appears more than once, this only returns the first occurrence; the
+ TREE_CHAIN of the return value should be passed back in if further
+ occurrences are wanted. ATTR_IDENTIFIER must be an identifier but
+ can be in the form 'text' or '__text__'. */
+static tree
+lookup_ident_attribute (tree attr_identifier, tree list)
{
- tree l;
- size_t attr_len = strlen (attr_name);
+ gcc_checking_assert (TREE_CODE (attr_identifier) == IDENTIFIER_NODE);
- for (l = list; l; l = TREE_CHAIN (l))
+ while (list)
{
- gcc_assert (TREE_CODE (TREE_PURPOSE (l)) == IDENTIFIER_NODE);
- if (is_attribute_with_length_p (attr_name, attr_len, TREE_PURPOSE (l)))
- return l;
+ gcc_checking_assert (TREE_CODE (TREE_PURPOSE (list)) == IDENTIFIER_NODE);
+
+ /* Identifiers can be compared directly for equality. */
+ if (attr_identifier == TREE_PURPOSE (list))
+ break;
+
+ /* If they are not equal, they may still be one in the form
+ 'text' while the other one is in the form '__text__'. TODO:
+ If we were storing attributes in normalized 'text' form, then
+ this could all go away and we could take full advantage of
+ the fact that we're comparing identifiers. :-) */
+ {
+ size_t attr_len = IDENTIFIER_LENGTH (attr_identifier);
+ size_t ident_len = IDENTIFIER_LENGTH (TREE_PURPOSE (list));
+
+ if (ident_len == attr_len + 4)
+ {
+ const char *p = IDENTIFIER_POINTER (TREE_PURPOSE (list));
+ const char *q = IDENTIFIER_POINTER (attr_identifier);
+ if (p[0] == '_' && p[1] == '_'
+ && p[ident_len - 2] == '_' && p[ident_len - 1] == '_'
+ && strncmp (q, p + 2, attr_len) == 0)
+ break;
+ }
+ else if (ident_len + 4 == attr_len)
+ {
+ const char *p = IDENTIFIER_POINTER (TREE_PURPOSE (list));
+ const char *q = IDENTIFIER_POINTER (attr_identifier);
+ if (q[0] == '_' && q[1] == '_'
+ && q[attr_len - 2] == '_' && q[attr_len - 1] == '_'
+ && strncmp (q + 2, p, ident_len) == 0)
+ break;
+ }
+ }
+ list = TREE_CHAIN (list);
}
- return NULL_TREE;
+
+ return list;
}
/* Remove any instances of attribute ATTR_NAME in LIST and return the
tree *p;
size_t attr_len = strlen (attr_name);
+ gcc_checking_assert (attr_name[0] != '_');
+
for (p = &list; *p; )
{
tree l = *p;
- gcc_assert (TREE_CODE (TREE_PURPOSE (l)) == IDENTIFIER_NODE);
- if (is_attribute_with_length_p (attr_name, attr_len, TREE_PURPOSE (l)))
+ /* 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)))
*p = TREE_CHAIN (l);
else
p = &TREE_CHAIN (l);
for (; a2 != 0; a2 = TREE_CHAIN (a2))
{
tree a;
- for (a = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (a2)),
- attributes);
- a != NULL_TREE;
- a = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (a2)),
- TREE_CHAIN (a)))
- {
- if (TREE_VALUE (a) != NULL
- && TREE_CODE (TREE_VALUE (a)) == TREE_LIST
- && TREE_VALUE (a2) != NULL
- && TREE_CODE (TREE_VALUE (a2)) == TREE_LIST)
- {
- if (simple_cst_list_equal (TREE_VALUE (a),
- TREE_VALUE (a2)) == 1)
- break;
- }
- else if (simple_cst_equal (TREE_VALUE (a),
- TREE_VALUE (a2)) == 1)
- break;
- }
+ for (a = lookup_ident_attribute (TREE_PURPOSE (a2), attributes);
+ a != NULL_TREE && !attribute_value_equal (a, a2);
+ a = lookup_ident_attribute (TREE_PURPOSE (a2), TREE_CHAIN (a)))
+ ;
if (a == NULL_TREE)
{
a1 = copy_node (a2);
a = merge_attributes (DECL_ATTRIBUTES (old), DECL_ATTRIBUTES (new_tree));
if (delete_dllimport_p)
- {
- tree prev, t;
- const size_t attr_len = strlen ("dllimport");
-
- /* Scan the list for dllimport and delete it. */
- for (prev = NULL_TREE, t = a; t; prev = t, t = TREE_CHAIN (t))
- {
- if (is_attribute_with_length_p ("dllimport", attr_len,
- TREE_PURPOSE (t)))
- {
- if (prev == NULL_TREE)
- a = TREE_CHAIN (a);
- else
- TREE_CHAIN (prev) = TREE_CHAIN (t);
- break;
- }
- }
- }
+ a = remove_attribute ("dllimport", a);
return a;
}
struct tree_priority_map *h;
gcc_assert (VAR_OR_FUNCTION_DECL_P (decl));
+ if (priority == DEFAULT_INIT_PRIORITY)
+ return;
h = decl_priority_info (decl);
h->init = priority;
}
struct tree_priority_map *h;
gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
+ if (priority == DEFAULT_INIT_PRIORITY)
+ return;
h = decl_priority_info (decl);
h->fini = priority;
}
*(struct tree_decl_map **) loc = h;
}
+/* Lookup a vector of debug arguments for FROM, and return it if we
+ find one. */
+
+VEC(tree, gc) **
+decl_debug_args_lookup (tree from)
+{
+ struct tree_vec_map *h, in;
+
+ if (!DECL_HAS_DEBUG_ARGS_P (from))
+ return NULL;
+ gcc_checking_assert (debug_args_for_decl != NULL);
+ in.base.from = from;
+ h = (struct tree_vec_map *)
+ htab_find_with_hash (debug_args_for_decl, &in, DECL_UID (from));
+ if (h)
+ return &h->to;
+ return NULL;
+}
+
+/* Insert a mapping FROM->empty vector of debug arguments in the value
+ expression hashtable. */
+
+VEC(tree, gc) **
+decl_debug_args_insert (tree from)
+{
+ struct tree_vec_map *h;
+ void **loc;
+
+ if (DECL_HAS_DEBUG_ARGS_P (from))
+ return decl_debug_args_lookup (from);
+ if (debug_args_for_decl == NULL)
+ debug_args_for_decl = htab_create_ggc (64, tree_vec_map_hash,
+ tree_vec_map_eq, 0);
+ h = ggc_alloc_tree_vec_map ();
+ h->base.from = from;
+ h->to = NULL;
+ loc = htab_find_slot_with_hash (debug_args_for_decl, h, DECL_UID (from),
+ INSERT);
+ *(struct tree_vec_map **) loc = h;
+ DECL_HAS_DEBUG_ARGS_P (from) = 1;
+ return &h->to;
+}
+
/* Hashing of types so that we don't make duplicates.
The entry point is `type_hash_canon'. */
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);
+ tree_node_sizes[(int) t_kind] -= sizeof (struct tree_type_non_common);
#endif
return t1;
}
int
attribute_list_equal (const_tree l1, const_tree l2)
{
+ if (l1 == l2)
+ return 1;
+
return attribute_list_contained (l1, l2)
&& attribute_list_contained (l2, l1);
}
/* 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_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (t2)),
- CONST_CAST_TREE(l1));
- attr != NULL_TREE;
- attr = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (t2)),
- TREE_CHAIN (attr)))
- {
- if (TREE_VALUE (t2) != NULL
- && TREE_CODE (TREE_VALUE (t2)) == TREE_LIST
- && TREE_VALUE (attr) != NULL
- && TREE_CODE (TREE_VALUE (attr)) == TREE_LIST)
- {
- if (simple_cst_list_equal (TREE_VALUE (t2),
- TREE_VALUE (attr)) == 1)
- break;
- }
- else if (simple_cst_equal (TREE_VALUE (t2), TREE_VALUE (attr)) == 1)
- break;
- }
+ for (attr = lookup_ident_attribute (TREE_PURPOSE (t2), CONST_CAST_TREE(l1));
+ attr != NULL_TREE && !attribute_value_equal (t2, attr);
+ attr = lookup_ident_attribute (TREE_PURPOSE (t2), TREE_CHAIN (attr)))
+ ;
- if (attr == 0)
+ if (attr == NULL_TREE)
return 0;
}
return build_array_type_1 (elt_type, index_type, false);
}
+/* Return a representation of ELT_TYPE[NELTS], using indices of type
+ sizetype. */
+
+tree
+build_array_type_nelts (tree elt_type, unsigned HOST_WIDE_INT nelts)
+{
+ return build_array_type (elt_type, build_index_type (size_int (nelts - 1)));
+}
+
/* Recursively examines the array elements of TYPE, until a non-array
element type is found. */
return args;
}
+/* Build a function type. RETURN_TYPE is the type returned by the
+ function; VAARGS indicates whether the function takes varargs. The
+ function takes N named arguments, the types of which are provided in
+ ARG_TYPES. */
+
+static tree
+build_function_type_array_1 (bool vaargs, tree return_type, int n,
+ tree *arg_types)
+{
+ int i;
+ tree t = vaargs ? NULL_TREE : void_list_node;
+
+ for (i = n - 1; i >= 0; i--)
+ t = tree_cons (NULL_TREE, arg_types[i], t);
+
+ return build_function_type (return_type, t);
+}
+
+/* Build a function type. RETURN_TYPE is the type returned by the
+ function. The function takes N named arguments, the types of which
+ are provided in ARG_TYPES. */
+
+tree
+build_function_type_array (tree return_type, int n, tree *arg_types)
+{
+ return build_function_type_array_1 (false, return_type, n, arg_types);
+}
+
+/* Build a variable argument function type. RETURN_TYPE is the type
+ returned by the function. The function takes N named arguments, the
+ types of which are provided in ARG_TYPES. */
+
+tree
+build_varargs_function_type_array (tree return_type, int n, tree *arg_types)
+{
+ return build_function_type_array_1 (true, return_type, n, arg_types);
+}
+
/* Build a METHOD_TYPE for a member of BASETYPE. The RETTYPE (a TYPE)
and ARGTYPES (a TREE_LIST) are the return type and arguments types
for the method. An implicit additional parameter (of type
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
\f
#define FILE_FUNCTION_FORMAT "_GLOBAL__%s_%s"
-/* Generate a crc32 of a string. */
+/* Generate a crc32 of a byte. */
unsigned
-crc32_string (unsigned chksum, const char *string)
+crc32_byte (unsigned chksum, char byte)
{
- do
- {
- unsigned value = *string << 24;
+ unsigned value = (unsigned) byte << 24;
unsigned ix;
for (ix = 8; ix--; value <<= 1)
chksum <<= 1;
chksum ^= feedback;
}
+ return chksum;
+}
+
+
+/* Generate a crc32 of a string. */
+
+unsigned
+crc32_string (unsigned chksum, const char *string)
+{
+ do
+ {
+ chksum = crc32_byte (chksum, *string);
}
while (*string++);
return chksum;
*p = '_';
}
-/* Generate a name for a special-purpose function function.
+/* Generate a name for a special-purpose function.
The generated name may need to be unique across the whole link.
+ Changes to this function may also require corresponding changes to
+ xstrdup_mask_random.
TYPE is some string to identify the purpose of this function to the
linker or collect2; it must start with an uppercase letter,
one of:
file = input_filename;
/* Just use the file's basename, because the full pathname
might be quite long. */
- p = strrchr (file, '/');
- if (p)
- p++;
- else
- p = file;
- p = q = ASTRDUP (p);
+ p = q = ASTRDUP (lbasename (file));
}
else
{
}
/* Create nodes for all integer types (and error_mark_node) using the sizes
- of C datatypes. The caller should call set_sizetype soon after calling
- this function to select one of the types as sizetype. */
+ of C datatypes. */
void
build_common_tree_nodes (bool signed_char)
int128_unsigned_type_node = make_unsigned_type (128);
}
#endif
+
/* Define a boolean type. This type only represents boolean values but
may be larger than char depending on the value of BOOL_TYPE_SIZE.
Front ends which want to override this size (i.e. Java) can redefine
TYPE_MAX_VALUE (boolean_type_node) = build_int_cst (boolean_type_node, 1);
TYPE_PRECISION (boolean_type_node) = 1;
+ /* Define what type to use for size_t. */
+ if (strcmp (SIZE_TYPE, "unsigned int") == 0)
+ size_type_node = unsigned_type_node;
+ else if (strcmp (SIZE_TYPE, "long unsigned int") == 0)
+ size_type_node = long_unsigned_type_node;
+ else if (strcmp (SIZE_TYPE, "long long unsigned int") == 0)
+ size_type_node = long_long_unsigned_type_node;
+ else
+ gcc_unreachable ();
+
/* Fill in the rest of the sized types. Reuse existing type nodes
when possible. */
intQI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (QImode), 0);
access_private_node = get_identifier ("private");
}
-/* Call this function after calling build_common_tree_nodes and set_sizetype.
+/* Call this function after calling build_common_tree_nodes.
It will create several other common tree nodes. */
void
ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
local_define_builtin ("__builtin_unwind_resume", ftype,
BUILT_IN_UNWIND_RESUME,
- ((targetm.except_unwind_info (&global_options)
+ ((targetm_common.except_unwind_info (&global_options)
== UI_SJLJ)
? "_Unwind_SjLj_Resume" : "_Unwind_Resume"),
ECF_NORETURN);
const char *p;
enum built_in_function mcode, dcode;
tree type, inner_type;
+ const char *prefix = "__";
+
+ if (targetm.libfunc_gnu_prefix)
+ prefix = "__gnu_";
type = lang_hooks.types.type_for_mode ((enum machine_mode) mode, 0);
if (type == NULL)
*q = TOLOWER (*p);
*q = '\0';
- built_in_names[mcode] = concat ("__mul", mode_name_buf, "3", NULL);
+ built_in_names[mcode] = concat (prefix, "mul", mode_name_buf, "3",
+ NULL);
local_define_builtin (built_in_names[mcode], ftype, mcode,
- built_in_names[mcode], ECF_CONST | ECF_NOTHROW | ECF_LEAF);
+ built_in_names[mcode],
+ ECF_CONST | ECF_NOTHROW | ECF_LEAF);
- built_in_names[dcode] = concat ("__div", mode_name_buf, "3", NULL);
+ built_in_names[dcode] = concat (prefix, "div", mode_name_buf, "3",
+ NULL);
local_define_builtin (built_in_names[dcode], ftype, dcode,
- built_in_names[dcode], ECF_CONST | ECF_NOTHROW | ECF_LEAF);
+ built_in_names[dcode],
+ ECF_CONST | ECF_NOTHROW | ECF_LEAF);
}
}
}
length = omp_clause_num_ops[code];
size = (sizeof (struct tree_omp_clause) + (length - 1) * sizeof (tree));
+ record_node_allocation_statistics (OMP_CLAUSE, size);
+
t = ggc_alloc_tree_node (size);
memset (t, 0, size);
TREE_SET_CODE (t, OMP_CLAUSE);
OMP_CLAUSE_SET_CODE (t, code);
OMP_CLAUSE_LOCATION (t) = loc;
-#ifdef GATHER_STATISTICS
- tree_node_counts[(int) omp_clause_kind]++;
- tree_node_sizes[(int) omp_clause_kind] += size;
-#endif
-
return t;
}
gcc_assert (TREE_CODE_CLASS (code) == tcc_vl_exp);
gcc_assert (len >= 1);
-#ifdef GATHER_STATISTICS
- tree_node_counts[(int) e_kind]++;
- tree_node_sizes[(int) e_kind] += length;
-#endif
+ record_node_allocation_statistics (code, length);
t = ggc_alloc_zone_cleared_tree_node_stat (&tree_zone, length PASS_MEM_STAT);
return t;
}
+/* Helper function for build_call_* functions; build a CALL_EXPR with
+ indicated RETURN_TYPE, FN, and NARGS, but do not initialize any of
+ the argument slots. */
+
+static tree
+build_call_1 (tree return_type, tree fn, int nargs)
+{
+ tree t;
+
+ t = build_vl_exp (CALL_EXPR, nargs + 3);
+ TREE_TYPE (t) = return_type;
+ CALL_EXPR_FN (t) = fn;
+ CALL_EXPR_STATIC_CHAIN (t) = NULL;
+
+ return t;
+}
+
/* Build a CALL_EXPR of class tcc_vl_exp with the indicated RETURN_TYPE and
FN and a null static chain slot. NARGS is the number of call arguments
which are specified as "..." arguments. */
tree t;
int i;
- t = build_vl_exp (CALL_EXPR, nargs + 3);
- TREE_TYPE (t) = return_type;
- CALL_EXPR_FN (t) = fn;
- CALL_EXPR_STATIC_CHAIN (t) = NULL_TREE;
+ t = build_call_1 (return_type, fn, nargs);
for (i = 0; i < nargs; i++)
CALL_EXPR_ARG (t, i) = va_arg (args, tree);
process_call_operands (t);
tree t;
int i;
- t = build_vl_exp (CALL_EXPR, nargs + 3);
- TREE_TYPE (t) = return_type;
- CALL_EXPR_FN (t) = fn;
- CALL_EXPR_STATIC_CHAIN (t) = NULL_TREE;
+ t = build_call_1 (return_type, fn, nargs);
for (i = 0; i < nargs; i++)
CALL_EXPR_ARG (t, i) = args[i];
process_call_operands (t);
tree ret, t;
unsigned int ix;
- ret = build_vl_exp (CALL_EXPR, VEC_length (tree, args) + 3);
- TREE_TYPE (ret) = return_type;
- CALL_EXPR_FN (ret) = fn;
- CALL_EXPR_STATIC_CHAIN (ret) = NULL_TREE;
+ ret = build_call_1 (return_type, fn, VEC_length (tree, args));
FOR_EACH_VEC_ELT (tree, args, ix, t)
CALL_EXPR_ARG (ret, ix) = t;
process_call_operands (ret);
&& aggregate_value_p (t, current_function_decl)));
}
-/* There are situations in which a language considers record types
- compatible which have different field lists. Decide if two fields
- are compatible. It is assumed that the parent records are compatible. */
-
-bool
-fields_compatible_p (const_tree f1, const_tree f2)
-{
- if (!operand_equal_p (DECL_FIELD_BIT_OFFSET (f1),
- DECL_FIELD_BIT_OFFSET (f2), OEP_ONLY_CONST))
- return false;
-
- if (!operand_equal_p (DECL_FIELD_OFFSET (f1),
- DECL_FIELD_OFFSET (f2), OEP_ONLY_CONST))
- return false;
-
- if (!types_compatible_p (TREE_TYPE (f1), TREE_TYPE (f2)))
- return false;
-
- return true;
-}
-
-/* Locate within RECORD a field that is compatible with ORIG_FIELD. */
-
-tree
-find_compatible_field (tree record, tree orig_field)
-{
- tree f;
-
- for (f = TYPE_FIELDS (record); f ; f = TREE_CHAIN (f))
- if (TREE_CODE (f) == FIELD_DECL
- && fields_compatible_p (f, orig_field))
- return f;
-
- /* ??? Why isn't this on the main fields list? */
- f = TYPE_VFIELD (record);
- if (f && TREE_CODE (f) == FIELD_DECL
- && fields_compatible_p (f, orig_field))
- return f;
-
- /* ??? We should abort here, but Java appears to do Bad Things
- with inherited fields. */
- return orig_field;
-}
-
/* Return value of a constant X and sign-extend it. */
HOST_WIDE_INT
tree
upper_bound_in_type (tree outer, tree inner)
{
- unsigned HOST_WIDE_INT lo, hi;
+ double_int high;
unsigned int det = 0;
unsigned oprec = TYPE_PRECISION (outer);
unsigned iprec = TYPE_PRECISION (inner);
/* Compute 2^^prec - 1. */
if (prec <= HOST_BITS_PER_WIDE_INT)
{
- hi = 0;
- lo = ((~(unsigned HOST_WIDE_INT) 0)
+ high.high = 0;
+ high.low = ((~(unsigned HOST_WIDE_INT) 0)
>> (HOST_BITS_PER_WIDE_INT - prec));
}
else
{
- hi = ((~(unsigned HOST_WIDE_INT) 0)
+ high.high = ((~(unsigned HOST_WIDE_INT) 0)
>> (2 * HOST_BITS_PER_WIDE_INT - prec));
- lo = ~(unsigned HOST_WIDE_INT) 0;
+ high.low = ~(unsigned HOST_WIDE_INT) 0;
}
- return build_int_cst_wide (outer, lo, hi);
+ return double_int_to_tree (outer, high);
}
/* Returns the smallest value obtainable by casting something in INNER type to
tree
lower_bound_in_type (tree outer, tree inner)
{
- unsigned HOST_WIDE_INT lo, hi;
+ double_int low;
unsigned oprec = TYPE_PRECISION (outer);
unsigned iprec = TYPE_PRECISION (inner);
contains all values of INNER type. In particular, both INNER
and OUTER types have zero in common. */
|| (oprec > iprec && TYPE_UNSIGNED (inner)))
- lo = hi = 0;
+ low.low = low.high = 0;
else
{
/* If we are widening a signed type to another signed type, we
if (prec <= HOST_BITS_PER_WIDE_INT)
{
- hi = ~(unsigned HOST_WIDE_INT) 0;
- lo = (~(unsigned HOST_WIDE_INT) 0) << (prec - 1);
+ low.high = ~(unsigned HOST_WIDE_INT) 0;
+ low.low = (~(unsigned HOST_WIDE_INT) 0) << (prec - 1);
}
else
{
- hi = ((~(unsigned HOST_WIDE_INT) 0)
+ low.high = ((~(unsigned HOST_WIDE_INT) 0)
<< (prec - HOST_BITS_PER_WIDE_INT - 1));
- lo = 0;
+ low.low = 0;
}
}
- return build_int_cst_wide (outer, lo, hi);
+ return double_int_to_tree (outer, low);
}
/* Return nonzero if two operands that are suitable for PHI nodes are