1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390 |
- /* Language-dependent hooks for LTO.
- Copyright (C) 2009-2015 Free Software Foundation, Inc.
- Contributed by CodeSourcery, 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/>. */
- #include "config.h"
- #include "system.h"
- #include "coretypes.h"
- #include "flags.h"
- #include "tm.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 "stringpool.h"
- #include "stor-layout.h"
- #include "target.h"
- #include "langhooks.h"
- #include "langhooks-def.h"
- #include "debug.h"
- #include "lto-tree.h"
- #include "lto.h"
- #include "tree-inline.h"
- #include "predict.h"
- #include "hard-reg-set.h"
- #include "input.h"
- #include "function.h"
- #include "basic-block.h"
- #include "tree-ssa-alias.h"
- #include "internal-fn.h"
- #include "gimple-expr.h"
- #include "is-a.h"
- #include "gimple.h"
- #include "diagnostic-core.h"
- #include "toplev.h"
- #include "hash-map.h"
- #include "plugin-api.h"
- #include "ipa-ref.h"
- #include "cgraph.h"
- #include "lto-streamer.h"
- #include "cilk.h"
- static tree lto_type_for_size (unsigned, int);
- static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
- static tree handle_leaf_attribute (tree *, tree, tree, int, bool *);
- static tree handle_const_attribute (tree *, tree, tree, int, bool *);
- static tree handle_malloc_attribute (tree *, tree, tree, int, bool *);
- static tree handle_pure_attribute (tree *, tree, tree, int, bool *);
- static tree handle_novops_attribute (tree *, tree, tree, int, bool *);
- static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *);
- 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_fnspec_attribute (tree *, tree, tree, int, bool *);
- static tree handle_format_arg_attribute (tree *, tree, tree, int, bool *);
- /* Table of machine-independent attributes supported in GIMPLE. */
- const struct attribute_spec lto_attribute_table[] =
- {
- /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
- do_diagnostic } */
- { "noreturn", 0, 0, true, false, false,
- handle_noreturn_attribute, false },
- { "leaf", 0, 0, true, false, false,
- handle_leaf_attribute, false },
- /* The same comments as for noreturn attributes apply to const ones. */
- { "const", 0, 0, true, false, false,
- handle_const_attribute, false },
- { "malloc", 0, 0, true, false, false,
- handle_malloc_attribute, false },
- { "pure", 0, 0, true, false, false,
- handle_pure_attribute, false },
- { "no vops", 0, 0, true, false, false,
- handle_novops_attribute, false },
- { "nonnull", 0, -1, false, true, true,
- 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 },
- { "fn spec", 1, 1, false, true, true,
- handle_fnspec_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 }
- };
- /* Give the specifications for the format attributes, used by C and all
- descendants. */
- const struct attribute_spec lto_format_attribute_table[] =
- {
- /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
- affects_type_identity } */
- { "format", 3, 3, false, true, true,
- handle_format_attribute, false },
- { "format_arg", 1, 1, false, true, true,
- handle_format_arg_attribute, false },
- { NULL, 0, 0, false, false, false, NULL, false }
- };
- enum built_in_attribute
- {
- #define DEF_ATTR_NULL_TREE(ENUM) ENUM,
- #define DEF_ATTR_INT(ENUM, VALUE) ENUM,
- #define DEF_ATTR_STRING(ENUM, VALUE) ENUM,
- #define DEF_ATTR_IDENT(ENUM, STRING) ENUM,
- #define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) ENUM,
- #include "builtin-attrs.def"
- #undef DEF_ATTR_NULL_TREE
- #undef DEF_ATTR_INT
- #undef DEF_ATTR_STRING
- #undef DEF_ATTR_IDENT
- #undef DEF_ATTR_TREE_LIST
- ATTR_LAST
- };
- static GTY(()) tree built_in_attributes[(int) ATTR_LAST];
- /* Builtin types. */
- enum lto_builtin_type
- {
- #define DEF_PRIMITIVE_TYPE(NAME, VALUE) NAME,
- #define DEF_FUNCTION_TYPE_0(NAME, RETURN) NAME,
- #define DEF_FUNCTION_TYPE_1(NAME, RETURN, ARG1) NAME,
- #define DEF_FUNCTION_TYPE_2(NAME, RETURN, ARG1, ARG2) NAME,
- #define DEF_FUNCTION_TYPE_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
- #define DEF_FUNCTION_TYPE_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
- #define DEF_FUNCTION_TYPE_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) NAME,
- #define DEF_FUNCTION_TYPE_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
- ARG6) NAME,
- #define DEF_FUNCTION_TYPE_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
- ARG6, ARG7) NAME,
- #define DEF_FUNCTION_TYPE_8(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
- ARG6, ARG7, ARG8) NAME,
- #define DEF_FUNCTION_TYPE_VAR_0(NAME, RETURN) NAME,
- #define DEF_FUNCTION_TYPE_VAR_1(NAME, RETURN, ARG1) NAME,
- #define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME,
- #define DEF_FUNCTION_TYPE_VAR_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
- #define DEF_FUNCTION_TYPE_VAR_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
- #define DEF_FUNCTION_TYPE_VAR_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG6) \
- NAME,
- #define DEF_FUNCTION_TYPE_VAR_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
- ARG6, ARG7) NAME,
- #define DEF_FUNCTION_TYPE_VAR_11(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
- ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) NAME,
- #define DEF_POINTER_TYPE(NAME, TYPE) NAME,
- #include "builtin-types.def"
- #undef DEF_PRIMITIVE_TYPE
- #undef DEF_FUNCTION_TYPE_0
- #undef DEF_FUNCTION_TYPE_1
- #undef DEF_FUNCTION_TYPE_2
- #undef DEF_FUNCTION_TYPE_3
- #undef DEF_FUNCTION_TYPE_4
- #undef DEF_FUNCTION_TYPE_5
- #undef DEF_FUNCTION_TYPE_6
- #undef DEF_FUNCTION_TYPE_7
- #undef DEF_FUNCTION_TYPE_8
- #undef DEF_FUNCTION_TYPE_VAR_0
- #undef DEF_FUNCTION_TYPE_VAR_1
- #undef DEF_FUNCTION_TYPE_VAR_2
- #undef DEF_FUNCTION_TYPE_VAR_3
- #undef DEF_FUNCTION_TYPE_VAR_4
- #undef DEF_FUNCTION_TYPE_VAR_5
- #undef DEF_FUNCTION_TYPE_VAR_7
- #undef DEF_FUNCTION_TYPE_VAR_11
- #undef DEF_POINTER_TYPE
- BT_LAST
- };
- typedef enum lto_builtin_type builtin_type;
- static GTY(()) tree builtin_types[(int) BT_LAST + 1];
- static GTY(()) tree string_type_node;
- static GTY(()) tree const_string_type_node;
- static GTY(()) tree wint_type_node;
- static GTY(()) tree intmax_type_node;
- static GTY(()) tree uintmax_type_node;
- static GTY(()) tree signed_size_type_node;
- /* Flags needed to process builtins.def. */
- int flag_isoc94;
- int flag_isoc99;
- int flag_isoc11;
- /* Attribute handlers. */
- /* Handle a "noreturn" attribute; arguments as in
- struct attribute_spec.handler. */
- static tree
- handle_noreturn_attribute (tree *node, tree ARG_UNUSED (name),
- tree ARG_UNUSED (args), int ARG_UNUSED (flags),
- bool * ARG_UNUSED (no_add_attrs))
- {
- tree type = TREE_TYPE (*node);
- if (TREE_CODE (*node) == FUNCTION_DECL)
- TREE_THIS_VOLATILE (*node) = 1;
- else if (TREE_CODE (type) == POINTER_TYPE
- && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
- TREE_TYPE (*node)
- = build_pointer_type
- (build_type_variant (TREE_TYPE (type),
- TYPE_READONLY (TREE_TYPE (type)), 1));
- else
- gcc_unreachable ();
- return NULL_TREE;
- }
- /* Handle a "leaf" attribute; arguments as in
- struct attribute_spec.handler. */
- static tree
- handle_leaf_attribute (tree *node, tree name,
- tree ARG_UNUSED (args),
- int ARG_UNUSED (flags), bool *no_add_attrs)
- {
- if (TREE_CODE (*node) != FUNCTION_DECL)
- {
- warning (OPT_Wattributes, "%qE attribute ignored", name);
- *no_add_attrs = true;
- }
- if (!TREE_PUBLIC (*node))
- {
- warning (OPT_Wattributes, "%qE attribute has no effect on unit local functions", name);
- *no_add_attrs = true;
- }
- return NULL_TREE;
- }
- /* Handle a "const" attribute; arguments as in
- struct attribute_spec.handler. */
- static tree
- handle_const_attribute (tree *node, tree ARG_UNUSED (name),
- tree ARG_UNUSED (args), int ARG_UNUSED (flags),
- bool * ARG_UNUSED (no_add_attrs))
- {
- tree type = TREE_TYPE (*node);
- /* See FIXME comment on noreturn in c_common_attribute_table. */
- if (TREE_CODE (*node) == FUNCTION_DECL)
- TREE_READONLY (*node) = 1;
- else if (TREE_CODE (type) == POINTER_TYPE
- && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
- TREE_TYPE (*node)
- = build_pointer_type
- (build_type_variant (TREE_TYPE (type), 1,
- TREE_THIS_VOLATILE (TREE_TYPE (type))));
- else
- gcc_unreachable ();
- return NULL_TREE;
- }
- /* Handle a "malloc" attribute; arguments as in
- struct attribute_spec.handler. */
- static tree
- handle_malloc_attribute (tree *node, tree ARG_UNUSED (name),
- tree ARG_UNUSED (args), int ARG_UNUSED (flags),
- bool * ARG_UNUSED (no_add_attrs))
- {
- if (TREE_CODE (*node) == FUNCTION_DECL
- && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (*node))))
- DECL_IS_MALLOC (*node) = 1;
- else
- gcc_unreachable ();
- return NULL_TREE;
- }
- /* Handle a "pure" attribute; arguments as in
- struct attribute_spec.handler. */
- static tree
- handle_pure_attribute (tree *node, tree ARG_UNUSED (name),
- tree ARG_UNUSED (args), int ARG_UNUSED (flags),
- bool * ARG_UNUSED (no_add_attrs))
- {
- if (TREE_CODE (*node) == FUNCTION_DECL)
- DECL_PURE_P (*node) = 1;
- else
- gcc_unreachable ();
- return NULL_TREE;
- }
- /* Handle a "no vops" attribute; arguments as in
- struct attribute_spec.handler. */
- static tree
- handle_novops_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_NOVOPS (*node) = 1;
- return NULL_TREE;
- }
- /* Helper for nonnull attribute handling; fetch the operand number
- from the attribute argument list. */
- static bool
- get_nonnull_operand (tree arg_num_expr, unsigned HOST_WIDE_INT *valp)
- {
- /* Verify the arg number is a constant. */
- if (!tree_fits_uhwi_p (arg_num_expr))
- return false;
- *valp = TREE_INT_CST_LOW (arg_num_expr);
- return true;
- }
- /* Handle the "nonnull" attribute. */
- static tree
- handle_nonnull_attribute (tree *node, tree ARG_UNUSED (name),
- tree args, int ARG_UNUSED (flags),
- bool * ARG_UNUSED (no_add_attrs))
- {
- tree type = *node;
- /* If no arguments are specified, all pointer arguments should be
- non-null. Verify a full prototype is given so that the arguments
- will have the correct types when we actually check them later. */
- if (!args)
- {
- gcc_assert (prototype_p (type));
- return NULL_TREE;
- }
- /* Argument list specified. Verify that each argument number references
- a pointer argument. */
- for (; args; args = TREE_CHAIN (args))
- {
- tree argument;
- unsigned HOST_WIDE_INT arg_num = 0, ck_num;
- if (!get_nonnull_operand (TREE_VALUE (args), &arg_num))
- gcc_unreachable ();
- argument = TYPE_ARG_TYPES (type);
- if (argument)
- {
- for (ck_num = 1; ; ck_num++)
- {
- if (!argument || ck_num == arg_num)
- break;
- argument = TREE_CHAIN (argument);
- }
- gcc_assert (argument
- && TREE_CODE (TREE_VALUE (argument)) == POINTER_TYPE);
- }
- }
- return NULL_TREE;
- }
- /* Handle a "nothrow" attribute; arguments as in
- struct attribute_spec.handler. */
- static tree
- handle_nothrow_attribute (tree *node, tree ARG_UNUSED (name),
- tree ARG_UNUSED (args), int ARG_UNUSED (flags),
- bool * ARG_UNUSED (no_add_attrs))
- {
- if (TREE_CODE (*node) == FUNCTION_DECL)
- TREE_NOTHROW (*node) = 1;
- else
- gcc_unreachable ();
- return NULL_TREE;
- }
- /* Handle a "sentinel" attribute. */
- static tree
- handle_sentinel_attribute (tree *node, tree ARG_UNUSED (name), tree args,
- int ARG_UNUSED (flags),
- bool * ARG_UNUSED (no_add_attrs))
- {
- gcc_assert (stdarg_p (*node));
- if (args)
- {
- tree position = TREE_VALUE (args);
- gcc_assert (TREE_CODE (position) == INTEGER_CST);
- if (tree_int_cst_lt (position, integer_zero_node))
- gcc_unreachable ();
- }
- return NULL_TREE;
- }
- /* Handle a "type_generic" attribute. */
- static tree
- handle_type_generic_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);
-
- /* Ensure we have a variadic function. */
- gcc_assert (!prototype_p (*node) || stdarg_p (*node));
- 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 tree
- handle_format_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_arg" attribute; arguments as in
- struct attribute_spec.handler. */
- tree
- handle_format_arg_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 "fn spec" attribute; arguments as in
- struct attribute_spec.handler. */
- static tree
- handle_fnspec_attribute (tree *node ATTRIBUTE_UNUSED, tree ARG_UNUSED (name),
- tree args, int ARG_UNUSED (flags),
- bool *no_add_attrs ATTRIBUTE_UNUSED)
- {
- gcc_assert (args
- && TREE_CODE (TREE_VALUE (args)) == STRING_CST
- && !TREE_CHAIN (args));
- return NULL_TREE;
- }
- /* Cribbed from c-common.c. */
- static void
- def_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...)
- {
- tree t;
- tree *args = XALLOCAVEC (tree, n);
- va_list list;
- int i;
- bool err = false;
- va_start (list, n);
- for (i = 0; i < n; ++i)
- {
- builtin_type a = (builtin_type) va_arg (list, int);
- t = builtin_types[a];
- if (t == error_mark_node)
- err = true;
- args[i] = t;
- }
- va_end (list);
- t = builtin_types[ret];
- if (err)
- t = error_mark_node;
- if (t == error_mark_node)
- ;
- else if (var)
- t = build_varargs_function_type_array (t, n, args);
- else
- t = build_function_type_array (t, n, args);
- builtin_types[def] = t;
- }
- /* Used to help initialize the builtin-types.def table. When a type of
- the correct size doesn't exist, use error_mark_node instead of NULL.
- The later results in segfaults even when a decl using the type doesn't
- get invoked. */
- static tree
- builtin_type_for_size (int size, bool unsignedp)
- {
- tree type = lto_type_for_size (size, unsignedp);
- return type ? type : error_mark_node;
- }
- /* Support for DEF_BUILTIN. */
- static void
- def_builtin_1 (enum built_in_function fncode, const char *name,
- enum built_in_class fnclass, tree fntype, tree libtype,
- bool both_p, bool fallback_p, bool nonansi_p,
- tree fnattrs, bool implicit_p)
- {
- tree decl;
- const char *libname;
- if (fntype == error_mark_node)
- return;
- libname = name + strlen ("__builtin_");
- decl = add_builtin_function (name, fntype, fncode, fnclass,
- (fallback_p ? libname : NULL),
- fnattrs);
- if (both_p
- && !flag_no_builtin
- && !(nonansi_p && flag_no_nonansi_builtin))
- add_builtin_function (libname, libtype, fncode, fnclass,
- NULL, fnattrs);
- set_builtin_decl (fncode, decl, implicit_p);
- }
- /* Initialize the attribute table for all the supported builtins. */
- static void
- lto_init_attributes (void)
- {
- /* Fill in the built_in_attributes array. */
- #define DEF_ATTR_NULL_TREE(ENUM) \
- built_in_attributes[(int) ENUM] = NULL_TREE;
- #define DEF_ATTR_INT(ENUM, VALUE) \
- built_in_attributes[(int) ENUM] = build_int_cst (NULL_TREE, VALUE);
- #define DEF_ATTR_STRING(ENUM, VALUE) \
- built_in_attributes[(int) ENUM] = build_string (strlen (VALUE), VALUE);
- #define DEF_ATTR_IDENT(ENUM, STRING) \
- built_in_attributes[(int) ENUM] = get_identifier (STRING);
- #define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) \
- built_in_attributes[(int) ENUM] \
- = tree_cons (built_in_attributes[(int) PURPOSE], \
- built_in_attributes[(int) VALUE], \
- built_in_attributes[(int) CHAIN]);
- #include "builtin-attrs.def"
- #undef DEF_ATTR_NULL_TREE
- #undef DEF_ATTR_INT
- #undef DEF_ATTR_STRING
- #undef DEF_ATTR_IDENT
- #undef DEF_ATTR_TREE_LIST
- }
- /* Create builtin types and functions. VA_LIST_REF_TYPE_NODE and
- VA_LIST_ARG_TYPE_NODE are used in builtin-types.def. */
- static void
- lto_define_builtins (tree va_list_ref_type_node ATTRIBUTE_UNUSED,
- tree va_list_arg_type_node ATTRIBUTE_UNUSED)
- {
- #define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
- builtin_types[ENUM] = VALUE;
- #define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
- def_fn_type (ENUM, RETURN, 0, 0);
- #define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
- def_fn_type (ENUM, RETURN, 0, 1, ARG1);
- #define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
- def_fn_type (ENUM, RETURN, 0, 2, ARG1, ARG2);
- #define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
- def_fn_type (ENUM, RETURN, 0, 3, ARG1, ARG2, ARG3);
- #define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
- def_fn_type (ENUM, RETURN, 0, 4, ARG1, ARG2, ARG3, ARG4);
- #define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
- def_fn_type (ENUM, RETURN, 0, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
- #define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
- ARG6) \
- def_fn_type (ENUM, RETURN, 0, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
- #define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
- ARG6, ARG7) \
- def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
- #define DEF_FUNCTION_TYPE_8(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
- ARG6, ARG7, ARG8) \
- def_fn_type (ENUM, RETURN, 0, 8, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
- ARG7, ARG8);
- #define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
- def_fn_type (ENUM, RETURN, 1, 0);
- #define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \
- def_fn_type (ENUM, RETURN, 1, 1, ARG1);
- #define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \
- def_fn_type (ENUM, RETURN, 1, 2, ARG1, ARG2);
- #define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
- def_fn_type (ENUM, RETURN, 1, 3, ARG1, ARG2, ARG3);
- #define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
- def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4);
- #define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
- def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
- #define DEF_FUNCTION_TYPE_VAR_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
- ARG6, ARG7) \
- def_fn_type (ENUM, RETURN, 1, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
- #define DEF_FUNCTION_TYPE_VAR_11(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
- ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) \
- def_fn_type (ENUM, RETURN, 1, 11, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
- ARG7, ARG8, ARG9, ARG10, ARG11);
- #define DEF_POINTER_TYPE(ENUM, TYPE) \
- builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);
- #include "builtin-types.def"
- #undef DEF_PRIMITIVE_TYPE
- #undef DEF_FUNCTION_TYPE_0
- #undef DEF_FUNCTION_TYPE_1
- #undef DEF_FUNCTION_TYPE_2
- #undef DEF_FUNCTION_TYPE_3
- #undef DEF_FUNCTION_TYPE_4
- #undef DEF_FUNCTION_TYPE_5
- #undef DEF_FUNCTION_TYPE_6
- #undef DEF_FUNCTION_TYPE_7
- #undef DEF_FUNCTION_TYPE_8
- #undef DEF_FUNCTION_TYPE_VAR_0
- #undef DEF_FUNCTION_TYPE_VAR_1
- #undef DEF_FUNCTION_TYPE_VAR_2
- #undef DEF_FUNCTION_TYPE_VAR_3
- #undef DEF_FUNCTION_TYPE_VAR_4
- #undef DEF_FUNCTION_TYPE_VAR_5
- #undef DEF_FUNCTION_TYPE_VAR_7
- #undef DEF_FUNCTION_TYPE_VAR_11
- #undef DEF_POINTER_TYPE
- builtin_types[(int) BT_LAST] = NULL_TREE;
- lto_init_attributes ();
- #define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, FALLBACK_P,\
- NONANSI_P, ATTRS, IMPLICIT, COND) \
- if (NAME && COND) \
- def_builtin_1 (ENUM, NAME, CLASS, builtin_types[(int) TYPE], \
- builtin_types[(int) LIBTYPE], BOTH_P, FALLBACK_P, \
- NONANSI_P, built_in_attributes[(int) ATTRS], IMPLICIT);
- #include "builtins.def"
- #undef DEF_BUILTIN
- }
- static GTY(()) tree registered_builtin_types;
- /* Language hooks. */
- static unsigned int
- lto_option_lang_mask (void)
- {
- return CL_LTO;
- }
- static bool
- lto_complain_wrong_lang_p (const struct cl_option *option ATTRIBUTE_UNUSED)
- {
- /* The LTO front end inherits all the options from the first front
- end that was used. However, not all the original front end
- options make sense in LTO.
- A real solution would be to filter this in collect2, but collect2
- does not have access to all the option attributes to know what to
- filter. So, in lto1 we silently accept inherited flags and do
- nothing about it. */
- return false;
- }
- static void
- lto_init_options_struct (struct gcc_options *opts)
- {
- /* By default, C99-like requirements for complex multiply and divide.
- ??? Until the complex method is encoded in the IL this is the only
- safe choice. This will pessimize Fortran code with LTO unless
- people specify a complex method manually or use -ffast-math. */
- opts->x_flag_complex_method = 2;
- }
- /* Handle command-line option SCODE. If the option takes an argument, it is
- stored in ARG, which is otherwise NULL. VALUE holds either a numerical
- argument or a binary value indicating whether the positive or negative form
- of the option was supplied. */
- const char *resolution_file_name;
- static bool
- lto_handle_option (size_t scode, const char *arg,
- int value ATTRIBUTE_UNUSED, int kind ATTRIBUTE_UNUSED,
- location_t loc ATTRIBUTE_UNUSED,
- const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
- {
- enum opt_code code = (enum opt_code) scode;
- bool result = true;
- switch (code)
- {
- case OPT_fresolution_:
- resolution_file_name = arg;
- break;
- case OPT_Wabi:
- warn_psabi = value;
- break;
- case OPT_fwpa:
- flag_wpa = value ? "" : NULL;
- break;
- default:
- break;
- }
- return result;
- }
- /* Perform post-option processing. Does additional initialization based on
- command-line options. PFILENAME is the main input filename. Returns false
- to enable subsequent back-end initialization. */
- static bool
- lto_post_options (const char **pfilename ATTRIBUTE_UNUSED)
- {
- /* -fltrans and -fwpa are mutually exclusive. Check for that here. */
- if (flag_wpa && flag_ltrans)
- error ("-fwpa and -fltrans are mutually exclusive");
- if (flag_ltrans)
- {
- flag_generate_lto = 0;
- /* During LTRANS, we are not looking at the whole program, only
- a subset of the whole callgraph. */
- flag_whole_program = 0;
- }
- if (flag_wpa)
- flag_generate_lto = 1;
- /* Excess precision other than "fast" requires front-end
- support. */
- flag_excess_precision_cmdline = EXCESS_PRECISION_FAST;
- /* Initialize the compiler back end. */
- return false;
- }
- /* Return an integer type with PRECISION bits of precision,
- that is unsigned if UNSIGNEDP is nonzero, otherwise signed. */
- static tree
- lto_type_for_size (unsigned precision, int unsignedp)
- {
- if (precision == TYPE_PRECISION (integer_type_node))
- return unsignedp ? unsigned_type_node : integer_type_node;
- if (precision == TYPE_PRECISION (signed_char_type_node))
- return unsignedp ? unsigned_char_type_node : signed_char_type_node;
- if (precision == TYPE_PRECISION (short_integer_type_node))
- return unsignedp ? short_unsigned_type_node : short_integer_type_node;
- if (precision == TYPE_PRECISION (long_integer_type_node))
- return unsignedp ? long_unsigned_type_node : long_integer_type_node;
- if (precision == TYPE_PRECISION (long_long_integer_type_node))
- return unsignedp
- ? long_long_unsigned_type_node
- : long_long_integer_type_node;
- if (precision <= TYPE_PRECISION (intQI_type_node))
- return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
- if (precision <= TYPE_PRECISION (intHI_type_node))
- return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
- if (precision <= TYPE_PRECISION (intSI_type_node))
- return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
- if (precision <= TYPE_PRECISION (intDI_type_node))
- return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
- if (precision <= TYPE_PRECISION (intTI_type_node))
- return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
- return NULL_TREE;
- }
- /* Return a data type that has machine mode MODE.
- If the mode is an integer,
- then UNSIGNEDP selects between signed and unsigned types.
- If the mode is a fixed-point mode,
- then UNSIGNEDP selects between saturating and nonsaturating types. */
- static tree
- lto_type_for_mode (machine_mode mode, int unsigned_p)
- {
- tree t;
- if (mode == TYPE_MODE (integer_type_node))
- return unsigned_p ? unsigned_type_node : integer_type_node;
- if (mode == TYPE_MODE (signed_char_type_node))
- return unsigned_p ? unsigned_char_type_node : signed_char_type_node;
- if (mode == TYPE_MODE (short_integer_type_node))
- return unsigned_p ? short_unsigned_type_node : short_integer_type_node;
- if (mode == TYPE_MODE (long_integer_type_node))
- return unsigned_p ? long_unsigned_type_node : long_integer_type_node;
- if (mode == TYPE_MODE (long_long_integer_type_node))
- return unsigned_p ? long_long_unsigned_type_node : long_long_integer_type_node;
- if (mode == QImode)
- return unsigned_p ? unsigned_intQI_type_node : intQI_type_node;
- if (mode == HImode)
- return unsigned_p ? unsigned_intHI_type_node : intHI_type_node;
- if (mode == SImode)
- return unsigned_p ? unsigned_intSI_type_node : intSI_type_node;
- if (mode == DImode)
- return unsigned_p ? unsigned_intDI_type_node : intDI_type_node;
- #if HOST_BITS_PER_WIDE_INT >= 64
- if (mode == TYPE_MODE (intTI_type_node))
- return unsigned_p ? unsigned_intTI_type_node : intTI_type_node;
- #endif
- if (mode == TYPE_MODE (float_type_node))
- return float_type_node;
- if (mode == TYPE_MODE (double_type_node))
- return double_type_node;
- if (mode == TYPE_MODE (long_double_type_node))
- return long_double_type_node;
- if (mode == TYPE_MODE (void_type_node))
- return void_type_node;
- if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
- return (unsigned_p
- ? make_unsigned_type (GET_MODE_PRECISION (mode))
- : make_signed_type (GET_MODE_PRECISION (mode)));
- if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
- return (unsigned_p
- ? make_unsigned_type (GET_MODE_PRECISION (mode))
- : make_signed_type (GET_MODE_PRECISION (mode)));
- if (COMPLEX_MODE_P (mode))
- {
- machine_mode inner_mode;
- tree inner_type;
- if (mode == TYPE_MODE (complex_float_type_node))
- return complex_float_type_node;
- if (mode == TYPE_MODE (complex_double_type_node))
- return complex_double_type_node;
- if (mode == TYPE_MODE (complex_long_double_type_node))
- return complex_long_double_type_node;
- if (mode == TYPE_MODE (complex_integer_type_node) && !unsigned_p)
- return complex_integer_type_node;
- inner_mode = GET_MODE_INNER (mode);
- inner_type = lto_type_for_mode (inner_mode, unsigned_p);
- if (inner_type != NULL_TREE)
- return build_complex_type (inner_type);
- }
- else if (VECTOR_MODE_P (mode))
- {
- machine_mode inner_mode = GET_MODE_INNER (mode);
- tree inner_type = lto_type_for_mode (inner_mode, unsigned_p);
- if (inner_type != NULL_TREE)
- return build_vector_type_for_mode (inner_type, mode);
- }
- if (mode == TYPE_MODE (dfloat32_type_node))
- return dfloat32_type_node;
- if (mode == TYPE_MODE (dfloat64_type_node))
- return dfloat64_type_node;
- if (mode == TYPE_MODE (dfloat128_type_node))
- return dfloat128_type_node;
- if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
- {
- if (mode == TYPE_MODE (short_fract_type_node))
- return unsigned_p ? sat_short_fract_type_node : short_fract_type_node;
- if (mode == TYPE_MODE (fract_type_node))
- return unsigned_p ? sat_fract_type_node : fract_type_node;
- if (mode == TYPE_MODE (long_fract_type_node))
- return unsigned_p ? sat_long_fract_type_node : long_fract_type_node;
- if (mode == TYPE_MODE (long_long_fract_type_node))
- return unsigned_p ? sat_long_long_fract_type_node
- : long_long_fract_type_node;
- if (mode == TYPE_MODE (unsigned_short_fract_type_node))
- return unsigned_p ? sat_unsigned_short_fract_type_node
- : unsigned_short_fract_type_node;
- if (mode == TYPE_MODE (unsigned_fract_type_node))
- return unsigned_p ? sat_unsigned_fract_type_node
- : unsigned_fract_type_node;
- if (mode == TYPE_MODE (unsigned_long_fract_type_node))
- return unsigned_p ? sat_unsigned_long_fract_type_node
- : unsigned_long_fract_type_node;
- if (mode == TYPE_MODE (unsigned_long_long_fract_type_node))
- return unsigned_p ? sat_unsigned_long_long_fract_type_node
- : unsigned_long_long_fract_type_node;
- if (mode == TYPE_MODE (short_accum_type_node))
- return unsigned_p ? sat_short_accum_type_node : short_accum_type_node;
- if (mode == TYPE_MODE (accum_type_node))
- return unsigned_p ? sat_accum_type_node : accum_type_node;
- if (mode == TYPE_MODE (long_accum_type_node))
- return unsigned_p ? sat_long_accum_type_node : long_accum_type_node;
- if (mode == TYPE_MODE (long_long_accum_type_node))
- return unsigned_p ? sat_long_long_accum_type_node
- : long_long_accum_type_node;
- if (mode == TYPE_MODE (unsigned_short_accum_type_node))
- return unsigned_p ? sat_unsigned_short_accum_type_node
- : unsigned_short_accum_type_node;
- if (mode == TYPE_MODE (unsigned_accum_type_node))
- return unsigned_p ? sat_unsigned_accum_type_node
- : unsigned_accum_type_node;
- if (mode == TYPE_MODE (unsigned_long_accum_type_node))
- return unsigned_p ? sat_unsigned_long_accum_type_node
- : unsigned_long_accum_type_node;
- if (mode == TYPE_MODE (unsigned_long_long_accum_type_node))
- return unsigned_p ? sat_unsigned_long_long_accum_type_node
- : unsigned_long_long_accum_type_node;
- if (mode == QQmode)
- return unsigned_p ? sat_qq_type_node : qq_type_node;
- if (mode == HQmode)
- return unsigned_p ? sat_hq_type_node : hq_type_node;
- if (mode == SQmode)
- return unsigned_p ? sat_sq_type_node : sq_type_node;
- if (mode == DQmode)
- return unsigned_p ? sat_dq_type_node : dq_type_node;
- if (mode == TQmode)
- return unsigned_p ? sat_tq_type_node : tq_type_node;
- if (mode == UQQmode)
- return unsigned_p ? sat_uqq_type_node : uqq_type_node;
- if (mode == UHQmode)
- return unsigned_p ? sat_uhq_type_node : uhq_type_node;
- if (mode == USQmode)
- return unsigned_p ? sat_usq_type_node : usq_type_node;
- if (mode == UDQmode)
- return unsigned_p ? sat_udq_type_node : udq_type_node;
- if (mode == UTQmode)
- return unsigned_p ? sat_utq_type_node : utq_type_node;
- if (mode == HAmode)
- return unsigned_p ? sat_ha_type_node : ha_type_node;
- if (mode == SAmode)
- return unsigned_p ? sat_sa_type_node : sa_type_node;
- if (mode == DAmode)
- return unsigned_p ? sat_da_type_node : da_type_node;
- if (mode == TAmode)
- return unsigned_p ? sat_ta_type_node : ta_type_node;
- if (mode == UHAmode)
- return unsigned_p ? sat_uha_type_node : uha_type_node;
- if (mode == USAmode)
- return unsigned_p ? sat_usa_type_node : usa_type_node;
- if (mode == UDAmode)
- return unsigned_p ? sat_uda_type_node : uda_type_node;
- if (mode == UTAmode)
- return unsigned_p ? sat_uta_type_node : uta_type_node;
- }
- for (t = registered_builtin_types; t; t = TREE_CHAIN (t))
- if (TYPE_MODE (TREE_VALUE (t)) == mode)
- return TREE_VALUE (t);
- return NULL_TREE;
- }
- /* Return true if we are in the global binding level. */
- static bool
- lto_global_bindings_p (void)
- {
- return cfun == NULL;
- }
- static void
- lto_set_decl_assembler_name (tree decl)
- {
- /* This is almost the same as lhd_set_decl_assembler_name, except that
- we need to uniquify file-scope names, even if they are not
- TREE_PUBLIC, to avoid conflicts between individual files. */
- tree id;
- if (TREE_PUBLIC (decl))
- id = targetm.mangle_decl_assembler_name (decl, DECL_NAME (decl));
- else
- {
- const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
- char *label;
- ASM_FORMAT_PRIVATE_NAME (label, name, DECL_UID (decl));
- id = get_identifier (label);
- }
- SET_DECL_ASSEMBLER_NAME (decl, id);
- }
- static tree
- lto_pushdecl (tree t ATTRIBUTE_UNUSED)
- {
- /* Do nothing, since we get all information from DWARF and LTO
- sections. */
- return NULL_TREE;
- }
- static tree
- lto_getdecls (void)
- {
- /* We have our own write_globals langhook, hence the getdecls
- langhook shouldn't be used, except by dbxout.c, so we can't
- just abort here. */
- return NULL_TREE;
- }
- static void
- lto_write_globals (void)
- {
- if (flag_wpa)
- return;
- /* Output debug info for global variables. */
- varpool_node *vnode;
- FOR_EACH_DEFINED_VARIABLE (vnode)
- if (!decl_function_context (vnode->decl))
- debug_hooks->global_decl (vnode->decl);
- }
- static tree
- lto_builtin_function (tree decl)
- {
- return decl;
- }
- static void
- lto_register_builtin_type (tree type, const char *name)
- {
- tree decl;
- if (!TYPE_NAME (type))
- {
- decl = build_decl (UNKNOWN_LOCATION, TYPE_DECL,
- get_identifier (name), type);
- DECL_ARTIFICIAL (decl) = 1;
- TYPE_NAME (type) = decl;
- }
- registered_builtin_types = tree_cons (0, type, registered_builtin_types);
- }
- /* Build nodes that would have be created by the C front-end; necessary
- for including builtin-types.def and ultimately builtins.def. */
- static void
- lto_build_c_type_nodes (void)
- {
- gcc_assert (void_type_node);
- void_list_node = build_tree_list (NULL_TREE, void_type_node);
- string_type_node = build_pointer_type (char_type_node);
- const_string_type_node
- = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
- if (strcmp (SIZE_TYPE, "unsigned int") == 0)
- {
- intmax_type_node = integer_type_node;
- uintmax_type_node = unsigned_type_node;
- signed_size_type_node = integer_type_node;
- }
- else if (strcmp (SIZE_TYPE, "long unsigned int") == 0)
- {
- intmax_type_node = long_integer_type_node;
- uintmax_type_node = long_unsigned_type_node;
- signed_size_type_node = long_integer_type_node;
- }
- else if (strcmp (SIZE_TYPE, "long long unsigned int") == 0)
- {
- intmax_type_node = long_long_integer_type_node;
- uintmax_type_node = long_long_unsigned_type_node;
- signed_size_type_node = long_long_integer_type_node;
- }
- else
- {
- int i;
- signed_size_type_node = NULL_TREE;
- for (i = 0; i < NUM_INT_N_ENTS; i++)
- if (int_n_enabled_p[i])
- {
- char name[50];
- sprintf (name, "__int%d unsigned", int_n_data[i].bitsize);
- if (strcmp (name, SIZE_TYPE) == 0)
- {
- intmax_type_node = int_n_trees[i].signed_type;
- uintmax_type_node = int_n_trees[i].unsigned_type;
- signed_size_type_node = int_n_trees[i].signed_type;
- }
- }
- if (signed_size_type_node == NULL_TREE)
- gcc_unreachable ();
- }
- wint_type_node = unsigned_type_node;
- pid_type_node = integer_type_node;
- }
- /* Perform LTO-specific initialization. */
- static bool
- lto_init (void)
- {
- int i;
- /* We need to generate LTO if running in WPA mode. */
- flag_generate_lto = (flag_wpa != NULL);
- /* Create the basic integer types. */
- build_common_tree_nodes (flag_signed_char, flag_short_double);
- /* The global tree for the main identifier is filled in by
- language-specific front-end initialization that is not run in the
- LTO back-end. It appears that all languages that perform such
- initialization currently do so in the same way, so we do it here. */
- if (main_identifier_node == NULL_TREE)
- main_identifier_node = get_identifier ("main");
- /* In the C++ front-end, fileptr_type_node is defined as a variant
- copy of of ptr_type_node, rather than ptr_node itself. 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;
- lto_build_c_type_nodes ();
- gcc_assert (va_list_type_node);
- if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
- {
- tree x = build_pointer_type (TREE_TYPE (va_list_type_node));
- lto_define_builtins (x, x);
- }
- else
- {
- lto_define_builtins (build_reference_type (va_list_type_node),
- va_list_type_node);
- }
- if (flag_cilkplus)
- cilk_init_builtins ();
- targetm.init_builtins ();
- build_common_builtin_nodes ();
- /* Assign names to the builtin types, otherwise they'll end up
- as __unknown__ in debug info.
- ??? We simply need to stop pre-seeding the streamer cache.
- Below is modeled after from c-common.c:c_common_nodes_and_builtins */
- #define NAME_TYPE(t,n) \
- if (t) \
- TYPE_NAME (t) = build_decl (UNKNOWN_LOCATION, TYPE_DECL, \
- get_identifier (n), t)
- NAME_TYPE (integer_type_node, "int");
- NAME_TYPE (char_type_node, "char");
- NAME_TYPE (long_integer_type_node, "long int");
- NAME_TYPE (unsigned_type_node, "unsigned int");
- NAME_TYPE (long_unsigned_type_node, "long unsigned int");
- NAME_TYPE (long_long_integer_type_node, "long long int");
- NAME_TYPE (long_long_unsigned_type_node, "long long unsigned int");
- NAME_TYPE (short_integer_type_node, "short int");
- NAME_TYPE (short_unsigned_type_node, "short unsigned int");
- if (signed_char_type_node != char_type_node)
- NAME_TYPE (signed_char_type_node, "signed char");
- if (unsigned_char_type_node != char_type_node)
- NAME_TYPE (unsigned_char_type_node, "unsigned char");
- NAME_TYPE (float_type_node, "float");
- NAME_TYPE (double_type_node, "double");
- NAME_TYPE (long_double_type_node, "long double");
- NAME_TYPE (void_type_node, "void");
- NAME_TYPE (boolean_type_node, "bool");
- NAME_TYPE (complex_float_type_node, "complex float");
- NAME_TYPE (complex_double_type_node, "complex double");
- NAME_TYPE (complex_long_double_type_node, "complex long double");
- for (i = 0; i < NUM_INT_N_ENTS; i++)
- if (int_n_enabled_p[i])
- {
- char name[50];
- sprintf (name, "__int%d", int_n_data[i].bitsize);
- NAME_TYPE (int_n_trees[i].signed_type, name);
- }
- #undef NAME_TYPE
- /* Initialize LTO-specific data structures. */
- in_lto_p = true;
- return true;
- }
- /* Initialize tree structures required by the LTO front end. */
- static void lto_init_ts (void)
- {
- tree_contains_struct[NAMESPACE_DECL][TS_DECL_MINIMAL] = 1;
- }
- #undef LANG_HOOKS_NAME
- #define LANG_HOOKS_NAME "GNU GIMPLE"
- #undef LANG_HOOKS_OPTION_LANG_MASK
- #define LANG_HOOKS_OPTION_LANG_MASK lto_option_lang_mask
- #undef LANG_HOOKS_COMPLAIN_WRONG_LANG_P
- #define LANG_HOOKS_COMPLAIN_WRONG_LANG_P lto_complain_wrong_lang_p
- #undef LANG_HOOKS_INIT_OPTIONS_STRUCT
- #define LANG_HOOKS_INIT_OPTIONS_STRUCT lto_init_options_struct
- #undef LANG_HOOKS_HANDLE_OPTION
- #define LANG_HOOKS_HANDLE_OPTION lto_handle_option
- #undef LANG_HOOKS_POST_OPTIONS
- #define LANG_HOOKS_POST_OPTIONS lto_post_options
- #undef LANG_HOOKS_GET_ALIAS_SET
- #define LANG_HOOKS_GET_ALIAS_SET gimple_get_alias_set
- #undef LANG_HOOKS_TYPE_FOR_MODE
- #define LANG_HOOKS_TYPE_FOR_MODE lto_type_for_mode
- #undef LANG_HOOKS_TYPE_FOR_SIZE
- #define LANG_HOOKS_TYPE_FOR_SIZE lto_type_for_size
- #undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME
- #define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME lto_set_decl_assembler_name
- #undef LANG_HOOKS_GLOBAL_BINDINGS_P
- #define LANG_HOOKS_GLOBAL_BINDINGS_P lto_global_bindings_p
- #undef LANG_HOOKS_PUSHDECL
- #define LANG_HOOKS_PUSHDECL lto_pushdecl
- #undef LANG_HOOKS_GETDECLS
- #define LANG_HOOKS_GETDECLS lto_getdecls
- #undef LANG_HOOKS_WRITE_GLOBALS
- #define LANG_HOOKS_WRITE_GLOBALS lto_write_globals
- #undef LANG_HOOKS_REGISTER_BUILTIN_TYPE
- #define LANG_HOOKS_REGISTER_BUILTIN_TYPE lto_register_builtin_type
- #undef LANG_HOOKS_BUILTIN_FUNCTION
- #define LANG_HOOKS_BUILTIN_FUNCTION lto_builtin_function
- #undef LANG_HOOKS_INIT
- #define LANG_HOOKS_INIT lto_init
- #undef LANG_HOOKS_PARSE_FILE
- #define LANG_HOOKS_PARSE_FILE lto_main
- #undef LANG_HOOKS_REDUCE_BIT_FIELD_OPERATIONS
- #define LANG_HOOKS_REDUCE_BIT_FIELD_OPERATIONS true
- #undef LANG_HOOKS_TYPES_COMPATIBLE_P
- #define LANG_HOOKS_TYPES_COMPATIBLE_P NULL
- #undef LANG_HOOKS_EH_PERSONALITY
- #define LANG_HOOKS_EH_PERSONALITY lto_eh_personality
- /* Attribute hooks. */
- #undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
- #define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE lto_attribute_table
- #undef LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE
- #define LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE lto_format_attribute_table
- #undef LANG_HOOKS_BEGIN_SECTION
- #define LANG_HOOKS_BEGIN_SECTION lto_obj_begin_section
- #undef LANG_HOOKS_APPEND_DATA
- #define LANG_HOOKS_APPEND_DATA lto_obj_append_data
- #undef LANG_HOOKS_END_SECTION
- #define LANG_HOOKS_END_SECTION lto_obj_end_section
- #undef LANG_HOOKS_INIT_TS
- #define LANG_HOOKS_INIT_TS lto_init_ts
- struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
- /* Language hooks that are not part of lang_hooks. */
- tree
- convert (tree type ATTRIBUTE_UNUSED, tree expr ATTRIBUTE_UNUSED)
- {
- gcc_unreachable ();
- }
- /* Tree walking support. */
- static enum lto_tree_node_structure_enum
- lto_tree_node_structure (union lang_tree_node *t ATTRIBUTE_UNUSED)
- {
- return TS_LTO_GENERIC;
- }
- #include "gtype-lto.h"
- #include "gt-lto-lto-lang.h"
|