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

            Line data    Source code
       1              : /* Hooks for cfg representation specific functions.
       2              :    Copyright (C) 2003-2026 Free Software Foundation, Inc.
       3              :    Contributed by Sebastian Pop <s.pop@laposte.net>
       4              : 
       5              : This file is part of GCC.
       6              : 
       7              : GCC is free software; you can redistribute it and/or modify
       8              : it under the terms of the GNU General Public License as published by
       9              : the Free Software Foundation; either version 3, or (at your option)
      10              : any later version.
      11              : 
      12              : GCC is distributed in the hope that it will be useful,
      13              : but WITHOUT ANY WARRANTY; without even the implied warranty of
      14              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15              : GNU General Public License 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_CFGHOOKS_H
      22              : #define GCC_CFGHOOKS_H
      23              : 
      24              : #include "predict.h"
      25              : 
      26              : namespace diagnostics { class sarif_builder; }
      27              : namespace json { class object; }
      28              : 
      29              : /* Structure to gather statistic about profile consistency, per pass.
      30              :    An array of this structure, indexed by pass static number, is allocated
      31              :    in passes.cc.  The structure is defined here so that different CFG modes
      32              :    can do their book-keeping via CFG hooks.
      33              : 
      34              :    For every field[2], field[0] is the count before the pass runs, and
      35              :    field[1] is the post-pass count.  This allows us to monitor the effect
      36              :    of each individual pass on the profile consistency.
      37              : 
      38              :    This structure is not supposed to be used by anything other than passes.cc
      39              :    and one CFG hook per CFG mode.  */
      40              : struct profile_record
      41              : {
      42              :   /* A weighted cost of the run-time of the function body.  */
      43              :   double time;
      44              :   /* Frequency of execution of basic blocks where sum(prob) of the block's
      45              :      predecessors doesn't match reasonably probability 1.  */
      46              :   double dyn_mismatched_prob_out;
      47              :   /* Frequency of execution basic blocks where sum(count) of the block's
      48              :      predecessors doesn't match reasonably well with the incoming frequency.  */
      49              :   double dyn_mismatched_count_in;
      50              :   /* The number of basic blocks where sum(prob) of the block's predecessors
      51              :      doesn't match reasonably probability 1.  */
      52              :   int num_mismatched_prob_out;
      53              :   /* The number of basic blocks where sum(count) of the block's predecessors
      54              :      doesn't match reasonably well with the incoming frequency.  */
      55              :   int num_mismatched_count_in;
      56              :   /* A weighted cost of the size of the function body.  */
      57              :   int size;
      58              :   /* True iff this pass actually was run.  */
      59              :   bool run;
      60              :   bool fdo;
      61              : };
      62              : 
      63              : typedef int_hash <unsigned short, 0> dependence_hash;
      64              : 
      65              : /* Optional data for duplicate_block.   */
      66              : 
      67              : class copy_bb_data
      68              : {
      69              : public:
      70      2402435 :   copy_bb_data() : dependence_map (NULL) {}
      71      2416770 :   ~copy_bb_data () { delete dependence_map; }
      72              : 
      73              :   /* A map from the copied BBs dependence info cliques to
      74              :      equivalents in the BBs duplicated to.  */
      75              :   hash_map<dependence_hash, unsigned short> *dependence_map;
      76              : };
      77              : 
      78              : struct cfg_hooks
      79              : {
      80              :   /* Name of the corresponding ir.  */
      81              :   const char *name;
      82              : 
      83              :   /* Debugging.  */
      84              :   bool (*verify_flow_info) (void);
      85              :   void (*dump_bb) (FILE *, basic_block, int, dump_flags_t);
      86              :   void (*dump_bb_for_graph) (pretty_printer *, basic_block);
      87              :   void
      88              :   (*dump_bb_as_sarif_properties) (diagnostics::sarif_builder *,
      89              :                                   json::object &,
      90              :                                   basic_block);
      91              : 
      92              :   /* Basic CFG manipulation.  */
      93              : 
      94              :   /* Return new basic block.  */
      95              :   basic_block (*create_basic_block) (void *head, void *end, basic_block after);
      96              : 
      97              :   /* Redirect edge E to the given basic block B and update underlying program
      98              :      representation.  Returns edge representing redirected branch (that may not
      99              :      be equivalent to E in the case of duplicate edges being removed) or NULL
     100              :      if edge is not easily redirectable for whatever reason.  */
     101              :   edge (*redirect_edge_and_branch) (edge e, basic_block b);
     102              : 
     103              :   /* Same as the above but allows redirecting of fallthru edges.  In that case
     104              :      newly created forwarder basic block is returned.  The edge must
     105              :      not be abnormal.  */
     106              :   basic_block (*redirect_edge_and_branch_force) (edge, basic_block);
     107              : 
     108              :   /* Returns true if it is possible to remove the edge by redirecting it
     109              :      to the destination of the other edge going from its source.  */
     110              :   bool (*can_remove_branch_p) (const_edge);
     111              : 
     112              :   /* Remove statements corresponding to a given basic block.  */
     113              :   void (*delete_basic_block) (basic_block);
     114              : 
     115              :   /* Creates a new basic block just after basic block B by splitting
     116              :      everything after specified instruction I.  */
     117              :   basic_block (*split_block) (basic_block b, void * i);
     118              : 
     119              :   /* Move block B immediately after block A.  */
     120              :   bool (*move_block_after) (basic_block b, basic_block a);
     121              : 
     122              :   /* Return true when blocks A and B can be merged into single basic block.  */
     123              :   bool (*can_merge_blocks_p) (basic_block a, basic_block b);
     124              : 
     125              :   /* Merge blocks A and B.  */
     126              :   void (*merge_blocks) (basic_block a, basic_block b);
     127              : 
     128              :   /* Predict edge E using PREDICTOR to given PROBABILITY.  */
     129              :   void (*predict_edge) (edge e, enum br_predictor predictor, int probability);
     130              : 
     131              :   /* Return true if the one of outgoing edges is already predicted by
     132              :      PREDICTOR.  */
     133              :   bool (*predicted_by_p) (const_basic_block bb, enum br_predictor predictor);
     134              : 
     135              :   /* Return true when block A can be duplicated.  */
     136              :   bool (*can_duplicate_block_p) (const_basic_block a);
     137              : 
     138              :   /* Duplicate block A.  */
     139              :   basic_block (*duplicate_block) (basic_block a, copy_bb_data *);
     140              : 
     141              :   /* Higher level functions representable by primitive operations above if
     142              :      we didn't have some oddities in RTL and Tree representations.  */
     143              :   basic_block (*split_edge) (edge);
     144              :   void (*make_forwarder_block) (edge);
     145              : 
     146              :   /* Try to make the edge fallthru.  */
     147              :   void (*tidy_fallthru_edge) (edge);
     148              : 
     149              :   /* Make the edge non-fallthru.  */
     150              :   basic_block (*force_nonfallthru) (edge);
     151              : 
     152              :   /* Say whether a block ends with a call, possibly followed by some
     153              :      other code that must stay with the call.  */
     154              :   bool (*block_ends_with_call_p) (basic_block);
     155              : 
     156              :   /* Say whether a block ends with a conditional branch.  Switches
     157              :      and unconditional branches do not qualify.  */
     158              :   bool (*block_ends_with_condjump_p) (const_basic_block);
     159              : 
     160              :   /* Add fake edges to the function exit for any non constant and non noreturn
     161              :      calls, volatile inline assembly in the bitmap of blocks specified by
     162              :      BLOCKS or to the whole CFG if BLOCKS is zero.  Return the number of blocks
     163              :      that were split.
     164              : 
     165              :      The goal is to expose cases in which entering a basic block does not imply
     166              :      that all subsequent instructions must be executed.  */
     167              :   int (*flow_call_edges_add) (sbitmap);
     168              : 
     169              :   /* This function is called immediately after edge E is added to the
     170              :      edge vector E->dest->preds.  */
     171              :   void (*execute_on_growing_pred) (edge);
     172              : 
     173              :   /* This function is called immediately before edge E is removed from
     174              :      the edge vector E->dest->preds.  */
     175              :   void (*execute_on_shrinking_pred) (edge);
     176              : 
     177              :   /* A hook for duplicating loop in CFG, currently this is used
     178              :      in loop versioning.  */
     179              :   bool (*cfg_hook_duplicate_loop_body_to_header_edge) (class loop *, edge,
     180              :                                                        unsigned, sbitmap, edge,
     181              :                                                        vec<edge> *, int);
     182              : 
     183              :   /* Add condition to new basic block and update CFG used in loop
     184              :      versioning.  */
     185              :   void (*lv_add_condition_to_bb) (basic_block, basic_block, basic_block,
     186              :                                   void *);
     187              :   /* Update the PHI nodes in case of loop versioning.  */
     188              :   void (*lv_adjust_loop_header_phi) (basic_block, basic_block,
     189              :                                      basic_block, edge);
     190              : 
     191              :   /* Given a condition BB extract the true/false taken/not taken edges
     192              :      (depending if we are on tree's or RTL). */
     193              :   void (*extract_cond_bb_edges) (basic_block, edge *, edge *);
     194              : 
     195              : 
     196              :   /* Add PHI arguments queued in PENDINT_STMT list on edge E to edge
     197              :      E->dest (only in tree-ssa loop versioning.  */
     198              :   void (*flush_pending_stmts) (edge);
     199              : 
     200              :   /* True if a block contains no executable instructions.  */
     201              :   bool (*empty_block_p) (basic_block);
     202              : 
     203              :   /* Split a basic block if it ends with a conditional branch and if
     204              :      the other part of the block is not empty.  */
     205              :   basic_block (*split_block_before_cond_jump) (basic_block);
     206              : 
     207              :   /* Do book-keeping of a basic block for the profile consistency checker.  */
     208              :   void (*account_profile_record) (basic_block, struct profile_record *);
     209              : };
     210              : 
     211              : extern void verify_flow_info (void);
     212              : 
     213              : /* Check control flow invariants, if internal consistency checks are
     214              :    enabled.  */
     215              : 
     216              : inline void
     217     43250521 : checking_verify_flow_info (void)
     218              : {
     219              :   /* TODO: Add a separate option for -fchecking=cfg.  */
     220     43250521 :   if (flag_checking)
     221     43249867 :     verify_flow_info ();
     222              : }
     223              : 
     224              : extern void dump_bb (FILE *, basic_block, int, dump_flags_t);
     225              : extern void dump_bb_for_graph (pretty_printer *, basic_block);
     226              : extern void dump_bb_as_sarif_properties (diagnostics::sarif_builder *,
     227              :                                          json::object &,
     228              :                                          basic_block);
     229              : extern void dump_flow_info (FILE *, dump_flags_t);
     230              : 
     231              : extern edge redirect_edge_and_branch (edge, basic_block);
     232              : extern basic_block redirect_edge_and_branch_force (edge, basic_block);
     233              : extern edge redirect_edge_succ_nodup (edge, basic_block);
     234              : extern bool can_remove_branch_p (const_edge);
     235              : extern void remove_branch (edge);
     236              : extern void remove_edge (edge);
     237              : extern edge split_block (basic_block, rtx);
     238              : extern edge split_block (basic_block, gimple *);
     239              : extern edge split_block_after_labels (basic_block);
     240              : extern bool move_block_after (basic_block, basic_block);
     241              : extern void delete_basic_block (basic_block);
     242              : extern basic_block split_edge (edge);
     243              : extern basic_block create_basic_block (rtx, rtx, basic_block);
     244              : extern basic_block create_basic_block (gimple_seq, basic_block);
     245              : extern basic_block create_empty_bb (basic_block);
     246              : extern bool can_merge_blocks_p (basic_block, basic_block);
     247              : extern void merge_blocks (basic_block, basic_block);
     248              : extern edge make_forwarder_block (basic_block, bool (*)(edge),
     249              :                                   void (*) (basic_block));
     250              : extern basic_block force_nonfallthru (edge);
     251              : extern void tidy_fallthru_edge (edge);
     252              : extern void tidy_fallthru_edges (void);
     253              : extern void predict_edge (edge e, enum br_predictor predictor, int probability);
     254              : extern bool predicted_by_p (const_basic_block bb, enum br_predictor predictor);
     255              : extern bool can_duplicate_block_p (const_basic_block);
     256              : extern basic_block duplicate_block (basic_block, edge, basic_block,
     257              :                                     copy_bb_data * = NULL);
     258              : extern bool block_ends_with_call_p (basic_block bb);
     259              : extern bool empty_block_p (basic_block);
     260              : extern basic_block split_block_before_cond_jump (basic_block);
     261              : extern bool block_ends_with_condjump_p (const_basic_block bb);
     262              : extern int flow_call_edges_add (sbitmap);
     263              : extern void execute_on_growing_pred (edge);
     264              : extern void execute_on_shrinking_pred (edge);
     265              : extern bool
     266              : cfg_hook_duplicate_loop_body_to_header_edge (class loop *loop, edge,
     267              :                                              unsigned int ndupl,
     268              :                                              sbitmap wont_exit, edge orig,
     269              :                                              vec<edge> *to_remove, int flags);
     270              : 
     271              : extern void lv_flush_pending_stmts (edge);
     272              : extern void extract_cond_bb_edges (basic_block, edge *, edge*);
     273              : extern void lv_adjust_loop_header_phi (basic_block, basic_block, basic_block,
     274              :                                        edge);
     275              : extern void lv_add_condition_to_bb (basic_block, basic_block, basic_block,
     276              :                                     void *);
     277              : 
     278              : extern bool can_copy_bbs_p (basic_block *, unsigned);
     279              : extern void copy_bbs (basic_block *, unsigned, basic_block *,
     280              :                       edge *, unsigned, edge *, class loop *,
     281              :                       basic_block, bool);
     282              : 
     283              : void profile_record_check_consistency (profile_record *);
     284              : void profile_record_account_profile (profile_record *);
     285              : 
     286              : /* Hooks containers.  */
     287              : extern struct cfg_hooks gimple_cfg_hooks;
     288              : extern struct cfg_hooks rtl_cfg_hooks;
     289              : extern struct cfg_hooks cfg_layout_rtl_cfg_hooks;
     290              : 
     291              : /* Declarations.  */
     292              : extern enum ir_type current_ir_type (void);
     293              : extern void rtl_register_cfg_hooks (void);
     294              : extern void cfg_layout_rtl_register_cfg_hooks (void);
     295              : extern void gimple_register_cfg_hooks (void);
     296              : extern struct cfg_hooks get_cfg_hooks (void);
     297              : extern void set_cfg_hooks (struct cfg_hooks);
     298              : 
     299              : #endif /* GCC_CFGHOOKS_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.