/* Language-dependent hooks for LTO.
- Copyright 2009, 2010 Free Software Foundation, Inc.
+ Copyright 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
Contributed by CodeSourcery, Inc.
This file is part of GCC.
static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *);
static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *);
static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *);
+static tree handle_transaction_pure_attribute (tree *, tree, tree, int, bool *);
+static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *);
+static tree ignore_attribute (tree *, tree, tree, int, bool *);
+
static tree handle_format_attribute (tree *, tree, tree, int, bool *);
static tree handle_format_arg_attribute (tree *, tree, tree, int, bool *);
handle_nonnull_attribute, false },
{ "nothrow", 0, 0, true, false, false,
handle_nothrow_attribute, false },
+ { "returns_twice", 0, 0, true, false, false,
+ handle_returns_twice_attribute, false },
{ "sentinel", 0, 1, false, true, true,
handle_sentinel_attribute, false },
{ "type generic", 0, 0, false, true, true,
handle_type_generic_attribute, false },
+ { "transaction_pure", 0, 0, false, true, true,
+ handle_transaction_pure_attribute, false },
+ /* For internal use only. The leading '*' both prevents its usage in
+ source code and signals that it may be overridden by machine tables. */
+ { "*tm regparm", 0, 0, false, true, true,
+ ignore_attribute, false },
{ NULL, 0, 0, false, false, false, NULL, false }
};
return NULL_TREE;
}
+/* Handle a "transaction_pure" attribute. */
+
+static tree
+handle_transaction_pure_attribute (tree *node, tree ARG_UNUSED (name),
+ tree ARG_UNUSED (args),
+ int ARG_UNUSED (flags),
+ bool * ARG_UNUSED (no_add_attrs))
+{
+ /* Ensure we have a function type. */
+ gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);
+
+ return NULL_TREE;
+}
+
+/* Handle a "returns_twice" attribute. */
+
+static tree
+handle_returns_twice_attribute (tree *node, tree ARG_UNUSED (name),
+ tree ARG_UNUSED (args),
+ int ARG_UNUSED (flags),
+ bool * ARG_UNUSED (no_add_attrs))
+{
+ gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
+
+ DECL_IS_RETURNS_TWICE (*node) = 1;
+
+ return NULL_TREE;
+}
+
+/* Ignore the given attribute. Used when this attribute may be usefully
+ overridden by the target, but is not used generically. */
+
+static tree
+ignore_attribute (tree * ARG_UNUSED (node), tree ARG_UNUSED (name),
+ tree ARG_UNUSED (args), int ARG_UNUSED (flags),
+ bool *no_add_attrs)
+{
+ *no_add_attrs = true;
+ return NULL_TREE;
+}
+
/* Handle a "format" attribute; arguments as in
struct attribute_spec.handler. */
static void
def_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...)
{
- tree args = NULL, t;
+ tree t;
+ tree *args = XALLOCAVEC (tree, n);
va_list list;
int i;
t = builtin_types[a];
if (t == error_mark_node)
goto egress;
- args = tree_cons (NULL_TREE, t, args);
+ args[i] = t;
}
va_end (list);
- args = nreverse (args);
- if (!var)
- args = chainon (args, void_list_node);
-
t = builtin_types[ret];
if (t == error_mark_node)
goto egress;
- t = build_function_type (t, args);
+ if (var)
+ t = build_varargs_function_type_array (t, n, args);
+ else
+ t = build_function_type_array (t, n, args);
egress:
builtin_types[def] = t;
add_builtin_function (libname, libtype, fncode, fnclass,
NULL, fnattrs);
- built_in_decls[(int) fncode] = decl;
- if (implicit_p)
- implicit_built_in_decls[(int) fncode] = decl;
+ set_builtin_decl (fncode, decl, implicit_p);
}
support. */
flag_excess_precision_cmdline = EXCESS_PRECISION_FAST;
- lto_read_all_file_options ();
-
/* Initialize the compiler back end. */
return false;
}
pid_type_node = integer_type_node;
}
+/* Re-compute TYPE_CANONICAL for NODE and related types. */
+
+static void
+lto_register_canonical_types (tree node)
+{
+ if (!node
+ || !TYPE_P (node))
+ return;
+
+ TYPE_CANONICAL (node) = NULL_TREE;
+ TYPE_CANONICAL (node) = gimple_register_canonical_type (node);
+
+ if (POINTER_TYPE_P (node)
+ || TREE_CODE (node) == COMPLEX_TYPE
+ || TREE_CODE (node) == ARRAY_TYPE)
+ lto_register_canonical_types (TREE_TYPE (node));
+}
/* Perform LTO-specific initialization. */
static bool
lto_init (void)
{
+ unsigned i;
+
/* We need to generate LTO if running in WPA mode. */
flag_generate_lto = flag_wpa;
/* Initialize libcpp line maps for gcc_assert to work. */
- linemap_add (line_table, LC_RENAME, 0, NULL, 0);
- linemap_add (line_table, LC_RENAME, 0, NULL, 0);
+ linemap_add (line_table, LC_ENTER, 0, NULL, 0);
/* Create the basic integer types. */
- build_common_tree_nodes (flag_signed_char);
-
- /* Share char_type_node with whatever would be the default for the target.
- char_type_node will be used for internal types such as
- va_list_type_node but will not be present in the lto stream. */
- /* ??? This breaks the more common case of consistent but non-standard
- setting of flag_signed_char, so share according to flag_signed_char.
- See PR42528. */
- char_type_node
- = flag_signed_char ? signed_char_type_node : unsigned_char_type_node;
-
- /* Tell the middle end what type to use for the size of objects. */
- if (strcmp (SIZE_TYPE, "unsigned int") == 0)
- {
- set_sizetype (unsigned_type_node);
- size_type_node = unsigned_type_node;
- }
- else if (strcmp (SIZE_TYPE, "long unsigned int") == 0)
- {
- set_sizetype (long_unsigned_type_node);
- size_type_node = long_unsigned_type_node;
- }
- else if (strcmp (SIZE_TYPE, "long long unsigned int") == 0)
- {
- set_sizetype (long_long_unsigned_type_node);
- size_type_node = long_long_unsigned_type_node;
- }
- else
- gcc_unreachable ();
+ build_common_tree_nodes (flag_signed_char, /*short_double=*/false);
/* The global tree for the main identifier is filled in by
language-specific front-end initialization that is not run in the
distinction should only be relevant to the front-end, so we
always use the C definition here in lto1. */
gcc_assert (fileptr_type_node == ptr_type_node);
+ gcc_assert (TYPE_MAIN_VARIANT (fileptr_type_node) == ptr_type_node);
ptrdiff_type_node = integer_type_node;
- /* Create other basic types. */
- build_common_tree_nodes_2 (/*short_double=*/false);
lto_build_c_type_nodes ();
gcc_assert (va_list_type_node);
NAME_TYPE (boolean_type_node, "bool");
#undef NAME_TYPE
+ /* Register the common node types with the canonical type machinery so
+ we properly share alias-sets across languages and TUs. Do not
+ expose the common nodes as type merge target - those that should be
+ are already exposed so by pre-loading the LTO streamer caches. */
+ for (i = 0; i < itk_none; ++i)
+ lto_register_canonical_types (integer_types[i]);
+ /* The sizetypes are not used to access data so we do not need to
+ do anything about them. */
+ for (i = 0; i < TI_MAX; ++i)
+ lto_register_canonical_types (global_trees[i]);
+
/* Initialize LTO-specific data structures. */
lto_global_var_decls = VEC_alloc (tree, gc, 256);
in_lto_p = true;