LCOV - code coverage report
Current view: top level - gcc - ipa-utils.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 98.3 % 58 57
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 10 10
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Utilities for ipa analysis.
       2              :    Copyright (C) 2004-2026 Free Software Foundation, Inc.
       3              :    Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
       4              : 
       5              : This file is part of GCC.
       6              : 
       7              : GCC is free software; you can redistribute it and/or modify it under
       8              : the terms of the GNU General Public License as published by the Free
       9              : Software Foundation; either version 3, or (at your option) any later
      10              : version.
      11              : 
      12              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      13              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      15              : for more details.
      16              : 
      17              : You should have received a copy of the GNU General Public License
      18              : along with GCC; see the file COPYING3.  If not see
      19              : <http://www.gnu.org/licenses/>.  */
      20              : 
      21              : #ifndef GCC_IPA_UTILS_H
      22              : #define GCC_IPA_UTILS_H
      23              : 
      24              : struct ipa_dfs_info {
      25              :   int dfn_number;
      26              :   int low_link;
      27              :   /* This field will have the samy value for any two nodes in the same strongly
      28              :      connected component.  */
      29              :   int scc_no;
      30              :   bool new_node;
      31              :   bool on_stack;
      32              :   struct cgraph_node* next_cycle;
      33              :   void *aux;
      34              : };
      35              : 
      36              : 
      37              : /* In ipa-utils.cc  */
      38              : void ipa_print_order (FILE*, const char *, struct cgraph_node**, int);
      39              : int ipa_reduced_postorder (struct cgraph_node **, bool,
      40              :                           bool (*ignore_edge) (struct cgraph_edge *));
      41              : void ipa_free_postorder_info (void);
      42              : vec<cgraph_node *> ipa_get_nodes_in_cycle (struct cgraph_node *);
      43              : bool ipa_edge_within_scc (struct cgraph_edge *);
      44              : int ipa_reverse_postorder (struct cgraph_node **);
      45              : tree get_base_var (tree);
      46              : void ipa_merge_profiles (struct cgraph_node *dst,
      47              :                          struct cgraph_node *src, bool preserve_body = false);
      48              : bool recursive_call_p (tree, tree);
      49              : bool stmt_may_terminate_function_p (function *fun, gimple *stmt, bool assume_return_or_eh);
      50              : bitmap find_always_executed_bbs (function *fun, bool assume_return_or_eh);
      51              : 
      52              : /* In ipa-pure-const.cc  */
      53              : bool finite_function_p ();
      54              : bool builtin_safe_for_const_function_p (bool *, tree);
      55              : bool ipa_make_function_const (cgraph_node *, bool, bool);
      56              : bool ipa_make_function_pure (cgraph_node *, bool, bool);
      57              : 
      58              : /* In ipa-profile.cc  */
      59              : bool ipa_propagate_frequency (struct cgraph_node *node);
      60              : void ipa_profile_cc_finalize (void);
      61              : 
      62              : /* In ipa-icf.cc  */
      63              : void ipa_icf_cc_finalize (void);
      64              : 
      65              : /* In ipa-sra.cc  */
      66              : void ipa_sra_cc_finalize (void);
      67              : 
      68              : /* In ipa-devirt.cc  */
      69              : 
      70              : struct odr_type_d;
      71              : typedef odr_type_d *odr_type;
      72              : extern bool thunk_expansion;
      73              : void build_type_inheritance_graph (void);
      74              : void rebuild_type_inheritance_graph (void);
      75              : void update_type_inheritance_graph (void);
      76              : vec <cgraph_node *>
      77              : possible_polymorphic_call_targets (tree, HOST_WIDE_INT,
      78              :                                    ipa_polymorphic_call_context,
      79              :                                    bool *copletep = NULL,
      80              :                                    void **cache_token = NULL,
      81              :                                    bool speuclative = false);
      82              : odr_type get_odr_type (tree, bool insert = false);
      83              : bool odr_type_p (const_tree);
      84              : bool possible_polymorphic_call_target_p (tree ref, gimple *stmt, struct cgraph_node *n);
      85              : void dump_possible_polymorphic_call_targets (FILE *, tree, HOST_WIDE_INT,
      86              :                                              const ipa_polymorphic_call_context &,
      87              :                                              bool verbose = true);
      88              : bool possible_polymorphic_call_target_p (tree, HOST_WIDE_INT,
      89              :                                          const ipa_polymorphic_call_context &,
      90              :                                          struct cgraph_node *);
      91              : tree polymorphic_ctor_dtor_p (tree, bool);
      92              : tree inlined_polymorphic_ctor_dtor_block_p (tree, bool);
      93              : bool decl_maybe_in_construction_p (tree, tree, gimple *, tree);
      94              : tree vtable_pointer_value_to_binfo (const_tree);
      95              : bool vtable_pointer_value_to_vtable (const_tree, tree *, unsigned HOST_WIDE_INT *);
      96              : tree subbinfo_with_vtable_at_offset (tree, unsigned HOST_WIDE_INT, tree);
      97              : void compare_virtual_tables (varpool_node *, varpool_node *);
      98              : bool type_all_derivations_known_p (const_tree);
      99              : bool type_known_to_have_no_derivations_p (tree);
     100              : bool contains_polymorphic_type_p (const_tree);
     101              : void register_odr_type (tree);
     102              : bool types_must_be_same_for_odr (tree, tree);
     103              : bool types_odr_comparable (tree, tree);
     104              : cgraph_node *try_speculative_devirtualization (tree, HOST_WIDE_INT,
     105              :                                                ipa_polymorphic_call_context);
     106              : void warn_types_mismatch (tree t1, tree t2, location_t loc1 = UNKNOWN_LOCATION,
     107              :                           location_t loc2 = UNKNOWN_LOCATION);
     108              : bool odr_or_derived_type_p (const_tree t);
     109              : bool odr_types_equivalent_p (tree type1, tree type2);
     110              : bool odr_type_violation_reported_p (tree type);
     111              : tree prevailing_odr_type (tree type);
     112              : void enable_odr_based_tbaa (tree type);
     113              : bool odr_based_tbaa_p (const_tree type);
     114              : void set_type_canonical_for_odr_type (tree type, tree canonical);
     115              : void warn_function_returns_nonnull (tree);
     116              : 
     117              : void register_odr_enum (tree type);
     118              : 
     119              : /* Return vector containing possible targets of polymorphic call E.
     120              :    If COMPLETEP is non-NULL, store true if the list is complete.
     121              :    CACHE_TOKEN (if non-NULL) will get stored to an unique ID of entry
     122              :    in the target cache.  If user needs to visit every target list
     123              :    just once, it can memoize them.
     124              : 
     125              :    Returned vector is placed into cache.  It is NOT caller's responsibility
     126              :    to free it.  The vector can be freed on cgraph_remove_node call if
     127              :    the particular node is a virtual function present in the cache.  */
     128              : 
     129              : inline vec <cgraph_node *>
     130       228481 : possible_polymorphic_call_targets (struct cgraph_edge *e,
     131              :                                    bool *completep = NULL,
     132              :                                    void **cache_token = NULL,
     133              :                                    bool speculative = false)
     134              : {
     135       228481 :   ipa_polymorphic_call_context context(e);
     136              : 
     137       228481 :   cgraph_polymorphic_indirect_info *pii
     138       228481 :     = as_a <cgraph_polymorphic_indirect_info *> (e->indirect_info);
     139       228481 :   gcc_checking_assert (pii->usable_p ());
     140       228481 :   return possible_polymorphic_call_targets (pii->otr_type,
     141              :                                             pii->otr_token,
     142              :                                             context,
     143              :                                             completep, cache_token,
     144       228481 :                                             speculative);
     145              : }
     146              : 
     147              : /* Same as above but taking OBJ_TYPE_REF as an parameter.  */
     148              : 
     149              : inline vec <cgraph_node *>
     150       623166 : possible_polymorphic_call_targets (tree ref,
     151              :                                    gimple *call,
     152              :                                    bool *completep = NULL,
     153              :                                    void **cache_token = NULL)
     154              : {
     155       623166 :   ipa_polymorphic_call_context context (current_function_decl, ref, call);
     156              : 
     157      1246332 :   return possible_polymorphic_call_targets (obj_type_ref_class (ref),
     158              :                                             tree_to_uhwi
     159       623166 :                                               (OBJ_TYPE_REF_TOKEN (ref)),
     160              :                                             context,
     161       623166 :                                             completep, cache_token);
     162              : }
     163              : 
     164              : /* Dump possible targets of a polymorphic call E into F.  */
     165              : 
     166              : inline void
     167           50 : dump_possible_polymorphic_call_targets (FILE *f, struct cgraph_edge *e,
     168              :                                         bool verbose = true)
     169              : {
     170           50 :   ipa_polymorphic_call_context context(e);
     171              : 
     172           50 :   cgraph_polymorphic_indirect_info *pii
     173           50 :     = as_a <cgraph_polymorphic_indirect_info *> (e->indirect_info);
     174           50 :   if (!pii->usable_p ())
     175            0 :     return;
     176           50 :   dump_possible_polymorphic_call_targets (f, pii->otr_type,
     177              :                                           pii->otr_token,
     178              :                                           context, verbose);
     179              : }
     180              : 
     181              : /* Return true if N can be possibly target of a polymorphic call of
     182              :    E.  */
     183              : 
     184              : inline bool
     185        34040 : possible_polymorphic_call_target_p (struct cgraph_edge *e,
     186              :                                     struct cgraph_node *n)
     187              : {
     188        34040 :   ipa_polymorphic_call_context context(e);
     189              : 
     190        34040 :   cgraph_polymorphic_indirect_info *pii
     191        34040 :     = as_a <cgraph_polymorphic_indirect_info *> (e->indirect_info);
     192        34040 :   if (!pii->usable_p ())
     193              :     return true;
     194        34040 :   return possible_polymorphic_call_target_p (pii->otr_type,
     195              :                                              pii->otr_token,
     196        34040 :                                              context, n);
     197              : }
     198              : 
     199              : /* Return true if BINFO corresponds to a type with virtual methods.
     200              : 
     201              :    Every type has several BINFOs.  One is the BINFO associated by the type
     202              :    while other represents bases of derived types.  The BINFOs representing
     203              :    bases do not have BINFO_VTABLE pointer set when this is the single
     204              :    inheritance (because vtables are shared).  Look up the BINFO of type
     205              :    and check presence of its vtable.  */
     206              : 
     207              : inline bool
     208     13475715 : polymorphic_type_binfo_p (const_tree binfo)
     209              : {
     210     26951430 :   return (BINFO_TYPE (binfo) && TYPE_BINFO (BINFO_TYPE (binfo))
     211     26949559 :           && BINFO_VTABLE (TYPE_BINFO (BINFO_TYPE (binfo))));
     212              : }
     213              : 
     214              : /* Return true if T is a type with linkage defined.  */
     215              : 
     216              : inline bool
     217     13783724 : type_with_linkage_p (const_tree t)
     218              : {
     219     13783724 :   gcc_checking_assert (TYPE_MAIN_VARIANT (t) == t);
     220     13783724 :   if (!TYPE_NAME (t) || TREE_CODE (TYPE_NAME (t)) != TYPE_DECL)
     221              :     return false;
     222              : 
     223              :   /* After free_lang_data was run we can recongize
     224              :      types with linkage by presence of mangled name.  */
     225     13512192 :   if (DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (t)))
     226              :     return true;
     227              : 
     228     10243738 :   if (in_lto_p)
     229              :     return false;
     230              : 
     231              :   /* We used to check for TYPE_STUB_DECL but that is set to NULL for forward
     232              :      declarations.  */
     233              : 
     234     10231387 :   if (!RECORD_OR_UNION_TYPE_P (t) && TREE_CODE (t) != ENUMERAL_TYPE)
     235              :     return false;
     236              : 
     237              :   /* Builtin types do not define linkage, their TYPE_CONTEXT is NULL.  */
     238     10145622 :   if (!TYPE_CONTEXT (t))
     239         2230 :     return false;
     240              : 
     241              :   return true;
     242              : }
     243              : 
     244              : /* Return true if T is in anonymous namespace.
     245              :    This works only on those C++ types with linkage defined.  */
     246              : 
     247              : inline bool
     248      7016005 : type_in_anonymous_namespace_p (const_tree t)
     249              : {
     250      7016005 :   gcc_checking_assert (type_with_linkage_p (t));
     251              : 
     252              :   /* free_lang_data clears TYPE_STUB_DECL but sets assembler name to
     253              :      "<anon>"  */
     254      7016005 :   if (DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (t)))
     255      3269790 :     return !strcmp ("<anon>",
     256      1634895 :                     IDENTIFIER_POINTER
     257      1634895 :                     (DECL_ASSEMBLER_NAME (TYPE_NAME (t))));
     258      5381110 :   else if (!TYPE_STUB_DECL (t))
     259              :     return false;
     260              :   else
     261      5381110 :     return !TREE_PUBLIC (TYPE_STUB_DECL (t));
     262              : }
     263              : 
     264              : /* Return true of T is type with One Definition Rule info attached.
     265              :    It means that either it is anonymous type or it has assembler name
     266              :    set.  */
     267              : 
     268              : inline bool
     269      2290753 : odr_type_p (const_tree t)
     270              : {
     271              :   /* We do not have this information when not in LTO, but we do not need
     272              :      to care, since it is used only for type merging.  */
     273      2290753 :   gcc_checking_assert (in_lto_p || flag_lto || flag_generate_offload);
     274      3212046 :   return TYPE_NAME (t) && TREE_CODE (TYPE_NAME (t)) == TYPE_DECL
     275      3042575 :          && DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (t));
     276              : }
     277              : 
     278              : /* If TYPE has mangled ODR name, return it.  Otherwise return NULL.
     279              :    The function works only when free_lang_data is run.  */
     280              : 
     281              : inline const char *
     282           66 : get_odr_name_for_type (tree type)
     283              : {
     284           66 :   tree type_name = TYPE_NAME (type);
     285           66 :   if (type_name == NULL_TREE
     286           52 :       || TREE_CODE (type_name) != TYPE_DECL
     287          116 :       || !DECL_ASSEMBLER_NAME_SET_P (type_name))
     288              :     return NULL;
     289              : 
     290           38 :   return IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (type_name));
     291              : }
     292              : 
     293              : /* Return true if we are going to do LTO streaming.  */
     294              : 
     295              : inline bool
     296     37339167 : lto_streaming_expected_p ()
     297              : {
     298              :   /* Compilation before LTO stremaing.  */
     299     37339167 :   if (flag_lto && !in_lto_p && symtab->state < IPA_SSA_AFTER_INLINING)
     300              :     return true;
     301              :   /* WPA or incremental link.  */
     302     36620959 :   return (flag_wpa || flag_incremental_link == INCREMENTAL_LINK_LTO);
     303              : }
     304              : 
     305              : #endif  /* GCC_IPA_UTILS_H  */
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.