diff options
Diffstat (limited to 'lib/gcc/arm-none-eabi/13.2.1/plugin/include/ipa-utils.h')
-rw-r--r-- | lib/gcc/arm-none-eabi/13.2.1/plugin/include/ipa-utils.h | 286 |
1 files changed, 286 insertions, 0 deletions
diff --git a/lib/gcc/arm-none-eabi/13.2.1/plugin/include/ipa-utils.h b/lib/gcc/arm-none-eabi/13.2.1/plugin/include/ipa-utils.h new file mode 100644 index 0000000..0eefcf4 --- /dev/null +++ b/lib/gcc/arm-none-eabi/13.2.1/plugin/include/ipa-utils.h @@ -0,0 +1,286 @@ +/* Utilities for ipa analysis. + Copyright (C) 2004-2023 Free Software Foundation, Inc. + Contributed by Kenneth Zadeck <zadeck@naturalbridge.com> + +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/>. */ + +#ifndef GCC_IPA_UTILS_H +#define GCC_IPA_UTILS_H + +struct ipa_dfs_info { + int dfn_number; + int low_link; + /* This field will have the samy value for any two nodes in the same strongly + connected component. */ + int scc_no; + bool new_node; + bool on_stack; + struct cgraph_node* next_cycle; + void *aux; +}; + + +/* In ipa-utils.cc */ +void ipa_print_order (FILE*, const char *, struct cgraph_node**, int); +int ipa_reduced_postorder (struct cgraph_node **, bool, + bool (*ignore_edge) (struct cgraph_edge *)); +void ipa_free_postorder_info (void); +vec<cgraph_node *> ipa_get_nodes_in_cycle (struct cgraph_node *); +bool ipa_edge_within_scc (struct cgraph_edge *); +int ipa_reverse_postorder (struct cgraph_node **); +tree get_base_var (tree); +void ipa_merge_profiles (struct cgraph_node *dst, + struct cgraph_node *src, bool preserve_body = false); +bool recursive_call_p (tree, tree); +bool stmt_may_terminate_function_p (function *fun, gimple *stmt, bool assume_return_or_eh); +bitmap find_always_executed_bbs (function *fun, bool assume_return_or_eh); + +/* In ipa-pure-const.cc */ +bool finite_function_p (); +bool builtin_safe_for_const_function_p (bool *, tree); +bool ipa_make_function_const (cgraph_node *, bool, bool); +bool ipa_make_function_pure (cgraph_node *, bool, bool); + +/* In ipa-profile.cc */ +bool ipa_propagate_frequency (struct cgraph_node *node); + +/* In ipa-devirt.cc */ + +struct odr_type_d; +typedef odr_type_d *odr_type; +extern bool thunk_expansion; +void build_type_inheritance_graph (void); +void rebuild_type_inheritance_graph (void); +void update_type_inheritance_graph (void); +vec <cgraph_node *> +possible_polymorphic_call_targets (tree, HOST_WIDE_INT, + ipa_polymorphic_call_context, + bool *copletep = NULL, + void **cache_token = NULL, + bool speuclative = false); +odr_type get_odr_type (tree, bool insert = false); +bool odr_type_p (const_tree); +bool possible_polymorphic_call_target_p (tree ref, gimple *stmt, struct cgraph_node *n); +void dump_possible_polymorphic_call_targets (FILE *, tree, HOST_WIDE_INT, + const ipa_polymorphic_call_context &, + bool verbose = true); +bool possible_polymorphic_call_target_p (tree, HOST_WIDE_INT, + const ipa_polymorphic_call_context &, + struct cgraph_node *); +tree polymorphic_ctor_dtor_p (tree, bool); +tree inlined_polymorphic_ctor_dtor_block_p (tree, bool); +bool decl_maybe_in_construction_p (tree, tree, gimple *, tree); +tree vtable_pointer_value_to_binfo (const_tree); +bool vtable_pointer_value_to_vtable (const_tree, tree *, unsigned HOST_WIDE_INT *); +tree subbinfo_with_vtable_at_offset (tree, unsigned HOST_WIDE_INT, tree); +void compare_virtual_tables (varpool_node *, varpool_node *); +bool type_all_derivations_known_p (const_tree); +bool type_known_to_have_no_derivations_p (tree); +bool contains_polymorphic_type_p (const_tree); +void register_odr_type (tree); +bool types_must_be_same_for_odr (tree, tree); +bool types_odr_comparable (tree, tree); +cgraph_node *try_speculative_devirtualization (tree, HOST_WIDE_INT, + ipa_polymorphic_call_context); +void warn_types_mismatch (tree t1, tree t2, location_t loc1 = UNKNOWN_LOCATION, + location_t loc2 = UNKNOWN_LOCATION); +bool odr_or_derived_type_p (const_tree t); +bool odr_types_equivalent_p (tree type1, tree type2); +bool odr_type_violation_reported_p (tree type); +tree prevailing_odr_type (tree type); +void enable_odr_based_tbaa (tree type); +bool odr_based_tbaa_p (const_tree type); +void set_type_canonical_for_odr_type (tree type, tree canonical); + +void register_odr_enum (tree type); + +/* Return vector containing possible targets of polymorphic call E. + If COMPLETEP is non-NULL, store true if the list is complete. + CACHE_TOKEN (if non-NULL) will get stored to an unique ID of entry + in the target cache. If user needs to visit every target list + just once, it can memoize them. + + Returned vector is placed into cache. It is NOT caller's responsibility + to free it. The vector can be freed on cgraph_remove_node call if + the particular node is a virtual function present in the cache. */ + +inline vec <cgraph_node *> +possible_polymorphic_call_targets (struct cgraph_edge *e, + bool *completep = NULL, + void **cache_token = NULL, + bool speculative = false) +{ + ipa_polymorphic_call_context context(e); + + return possible_polymorphic_call_targets (e->indirect_info->otr_type, + e->indirect_info->otr_token, + context, + completep, cache_token, + speculative); +} + +/* Same as above but taking OBJ_TYPE_REF as an parameter. */ + +inline vec <cgraph_node *> +possible_polymorphic_call_targets (tree ref, + gimple *call, + bool *completep = NULL, + void **cache_token = NULL) +{ + ipa_polymorphic_call_context context (current_function_decl, ref, call); + + return possible_polymorphic_call_targets (obj_type_ref_class (ref), + tree_to_uhwi + (OBJ_TYPE_REF_TOKEN (ref)), + context, + completep, cache_token); +} + +/* Dump possible targets of a polymorphic call E into F. */ + +inline void +dump_possible_polymorphic_call_targets (FILE *f, struct cgraph_edge *e, + bool verbose = true) +{ + ipa_polymorphic_call_context context(e); + + dump_possible_polymorphic_call_targets (f, e->indirect_info->otr_type, + e->indirect_info->otr_token, + context, verbose); +} + +/* Return true if N can be possibly target of a polymorphic call of + E. */ + +inline bool +possible_polymorphic_call_target_p (struct cgraph_edge *e, + struct cgraph_node *n) +{ + ipa_polymorphic_call_context context(e); + + return possible_polymorphic_call_target_p (e->indirect_info->otr_type, + e->indirect_info->otr_token, + context, n); +} + +/* Return true if BINFO corresponds to a type with virtual methods. + + Every type has several BINFOs. One is the BINFO associated by the type + while other represents bases of derived types. The BINFOs representing + bases do not have BINFO_VTABLE pointer set when this is the single + inheritance (because vtables are shared). Look up the BINFO of type + and check presence of its vtable. */ + +inline bool +polymorphic_type_binfo_p (const_tree binfo) +{ + return (BINFO_TYPE (binfo) && TYPE_BINFO (BINFO_TYPE (binfo)) + && BINFO_VTABLE (TYPE_BINFO (BINFO_TYPE (binfo)))); +} + +/* Return true if T is a type with linkage defined. */ + +inline bool +type_with_linkage_p (const_tree t) +{ + gcc_checking_assert (TYPE_MAIN_VARIANT (t) == t); + if (!TYPE_NAME (t) || TREE_CODE (TYPE_NAME (t)) != TYPE_DECL) + return false; + + /* After free_lang_data was run we can recongize + types with linkage by presence of mangled name. */ + if (DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (t))) + return true; + + if (in_lto_p) + return false; + + /* We used to check for TYPE_STUB_DECL but that is set to NULL for forward + declarations. */ + + if (!RECORD_OR_UNION_TYPE_P (t) && TREE_CODE (t) != ENUMERAL_TYPE) + return false; + + /* Builtin types do not define linkage, their TYPE_CONTEXT is NULL. */ + if (!TYPE_CONTEXT (t)) + return false; + + return true; +} + +/* Return true if T is in anonymous namespace. + This works only on those C++ types with linkage defined. */ + +inline bool +type_in_anonymous_namespace_p (const_tree t) +{ + gcc_checking_assert (type_with_linkage_p (t)); + + /* free_lang_data clears TYPE_STUB_DECL but sets assembler name to + "<anon>" */ + if (DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (t))) + return !strcmp ("<anon>", + IDENTIFIER_POINTER + (DECL_ASSEMBLER_NAME (TYPE_NAME (t)))); + else if (!TYPE_STUB_DECL (t)) + return false; + else + return !TREE_PUBLIC (TYPE_STUB_DECL (t)); +} + +/* Return true of T is type with One Definition Rule info attached. + It means that either it is anonymous type or it has assembler name + set. */ + +inline bool +odr_type_p (const_tree t) +{ + /* We do not have this information when not in LTO, but we do not need + to care, since it is used only for type merging. */ + gcc_checking_assert (in_lto_p || flag_lto || flag_generate_offload); + return TYPE_NAME (t) && TREE_CODE (TYPE_NAME (t)) == TYPE_DECL + && DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (t)); +} + +/* If TYPE has mangled ODR name, return it. Otherwise return NULL. + The function works only when free_lang_data is run. */ + +inline const char * +get_odr_name_for_type (tree type) +{ + tree type_name = TYPE_NAME (type); + if (type_name == NULL_TREE + || TREE_CODE (type_name) != TYPE_DECL + || !DECL_ASSEMBLER_NAME_SET_P (type_name)) + return NULL; + + return IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (type_name)); +} + +/* Return true if we are going to do LTO streaming. */ + +inline bool +lto_streaming_expected_p () +{ + /* Compilation before LTO stremaing. */ + if (flag_lto && !in_lto_p && symtab->state < IPA_SSA_AFTER_INLINING) + return true; + /* WPA or incremental link. */ + return (flag_wpa || flag_incremental_link == INCREMENTAL_LINK_LTO); +} + +#endif /* GCC_IPA_UTILS_H */ |