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

            Line data    Source code
       1              : /* Define per-register tables for data flow info and register allocation.
       2              :    Copyright (C) 1987-2026 Free Software Foundation, Inc.
       3              : 
       4              : This file is part of GCC.
       5              : 
       6              : GCC is free software; you can redistribute it and/or modify it under
       7              : the terms of the GNU General Public License as published by the Free
       8              : Software Foundation; either version 3, or (at your option) any later
       9              : version.
      10              : 
      11              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14              : for more details.
      15              : 
      16              : You should have received a copy of the GNU General Public License
      17              : along with GCC; see the file COPYING3.  If not see
      18              : <http://www.gnu.org/licenses/>.  */
      19              : 
      20              : #ifndef GCC_REGS_H
      21              : #define GCC_REGS_H
      22              : 
      23              : #define REG_BYTES(R) mode_size[(int) GET_MODE (R)]
      24              : 
      25              : /* When you only have the mode of a pseudo register before it has a hard
      26              :    register chosen for it, this reports the size of each hard register
      27              :    a pseudo in such a mode would get allocated to.  A target may
      28              :    override this.  */
      29              : 
      30              : #ifndef REGMODE_NATURAL_SIZE
      31              : #define REGMODE_NATURAL_SIZE(MODE)      UNITS_PER_WORD
      32              : #endif
      33              : 
      34              : /* Maximum register number used in this function, plus one.  */
      35              : 
      36              : extern int max_regno;
      37              : 
      38              : /* REG_N_REFS and REG_N_SETS are initialized by a call to
      39              :    regstat_init_n_sets_and_refs from the current values of
      40              :    DF_REG_DEF_COUNT and DF_REG_USE_COUNT.  REG_N_REFS and REG_N_SETS
      41              :    should only be used if a pass need to change these values in some
      42              :    magical way or the pass needs to have accurate values for these
      43              :    and is not using incremental df scanning.
      44              : 
      45              :    At the end of a pass that uses REG_N_REFS and REG_N_SETS, a call
      46              :    should be made to regstat_free_n_sets_and_refs.
      47              : 
      48              :    Local alloc seems to play pretty loose with these values.
      49              :    REG_N_REFS is set to 0 if the register is used in an asm.
      50              :    Furthermore, local_alloc calls regclass to hack both REG_N_REFS and
      51              :    REG_N_SETS for three address insns.  Other passes seem to have
      52              :    other special values.  */
      53              : 
      54              : 
      55              : 
      56              : /* Structure to hold values for REG_N_SETS (i) and REG_N_REFS (i). */
      57              : 
      58              : struct regstat_n_sets_and_refs_t
      59              : {
      60              :   int sets;                     /* # of times (REG n) is set */
      61              :   int refs;                     /* # of times (REG n) is used or set */
      62              : };
      63              : 
      64              : extern struct regstat_n_sets_and_refs_t *regstat_n_sets_and_refs;
      65              : 
      66              : /* Indexed by n, gives number of times (REG n) is used or set.  */
      67              : inline int
      68      4602988 : REG_N_REFS (int regno)
      69              : {
      70      4602988 :   return regstat_n_sets_and_refs[regno].refs;
      71              : }
      72              : 
      73              : /* Indexed by n, gives number of times (REG n) is used or set.  */
      74              : #define SET_REG_N_REFS(N,V) (regstat_n_sets_and_refs[N].refs = V)
      75              : #define INC_REG_N_REFS(N,V) (regstat_n_sets_and_refs[N].refs += V)
      76              : 
      77              : /* Indexed by n, gives number of times (REG n) is set.  */
      78              : inline int
      79    886975772 : REG_N_SETS (int regno)
      80              : {
      81    886975772 :   return regstat_n_sets_and_refs[regno].sets;
      82              : }
      83              : 
      84              : /* Indexed by n, gives number of times (REG n) is set.  */
      85              : #define SET_REG_N_SETS(N,V) (regstat_n_sets_and_refs[N].sets = V)
      86              : #define INC_REG_N_SETS(N,V) (regstat_n_sets_and_refs[N].sets += V)
      87              : 
      88              : /* Given a REG, return TRUE if the reg is a PARM_DECL, FALSE otherwise.  */
      89              : extern bool reg_is_parm_p (rtx);
      90              : 
      91              : /* Functions defined in regstat.cc.  */
      92              : extern void regstat_init_n_sets_and_refs (void);
      93              : extern void regstat_free_n_sets_and_refs (void);
      94              : extern void regstat_compute_ri (void);
      95              : extern void regstat_free_ri (void);
      96              : extern bitmap regstat_get_setjmp_crosses (void);
      97              : extern void regstat_compute_calls_crossed (void);
      98              : extern void regstat_free_calls_crossed (void);
      99              : extern void dump_reg_info (FILE *);
     100              : 
     101              : /* Register information indexed by register number.  This structure is
     102              :    initialized by calling regstat_compute_ri and is destroyed by
     103              :    calling regstat_free_ri.  */
     104              : struct reg_info_t
     105              : {
     106              :   int freq;                     /* # estimated frequency (REG n) is used or set */
     107              :   int deaths;                   /* # of times (REG n) dies */
     108              :   int calls_crossed;            /* # of calls (REG n) is live across */
     109              :   int basic_block;              /* # of basic blocks (REG n) is used in */
     110              : };
     111              : 
     112              : extern struct reg_info_t *reg_info_p;
     113              : 
     114              : /* The number allocated elements of reg_info_p.  */
     115              : extern size_t reg_info_p_size;
     116              : 
     117              : /* Estimate frequency of references to register N.  */
     118              : 
     119              : #define REG_FREQ(N) (reg_info_p[N].freq)
     120              : 
     121              : /* The weights for each insn varies from 0 to REG_FREQ_BASE.
     122              :    This constant does not need to be high, as in infrequently executed
     123              :    regions we want to count instructions equivalently to optimize for
     124              :    size instead of speed.  */
     125              : #define REG_FREQ_MAX 1000
     126              : 
     127              : /* Compute register frequency from the BB frequency.  When optimizing for size,
     128              :    or profile driven feedback is available and the function is never executed,
     129              :    frequency is always equivalent.  Otherwise rescale the basic block
     130              :    frequency.  */
     131              : #define REG_FREQ_FROM_BB(bb) ((optimize_function_for_size_p (cfun)            \
     132              :                                || !cfun->cfg->count_max.initialized_p ())     \
     133              :                               ? REG_FREQ_MAX                                  \
     134              :                               : ((bb)->count.to_frequency (cfun)           \
     135              :                                 * REG_FREQ_MAX / BB_FREQ_MAX)                 \
     136              :                               ? ((bb)->count.to_frequency (cfun)           \
     137              :                                  * REG_FREQ_MAX / BB_FREQ_MAX)                \
     138              :                               : 1)
     139              : 
     140              : /* Indexed by N, gives number of insns in which register N dies.
     141              :    Note that if register N is live around loops, it can die
     142              :    in transitions between basic blocks, and that is not counted here.
     143              :    So this is only a reliable indicator of how many regions of life there are
     144              :    for registers that are contained in one basic block.  */
     145              : 
     146              : #define REG_N_DEATHS(N) (reg_info_p[N].deaths)
     147              : 
     148              : /* Get the number of consecutive words required to hold pseudo-reg N.  */
     149              : 
     150              : #define PSEUDO_REGNO_SIZE(N) \
     151              :   ((GET_MODE_SIZE (PSEUDO_REGNO_MODE (N)) + UNITS_PER_WORD - 1)         \
     152              :    / UNITS_PER_WORD)
     153              : 
     154              : /* Get the number of bytes required to hold pseudo-reg N.  */
     155              : 
     156              : #define PSEUDO_REGNO_BYTES(N) \
     157              :   GET_MODE_SIZE (PSEUDO_REGNO_MODE (N))
     158              : 
     159              : /* Get the machine mode of pseudo-reg N.  */
     160              : 
     161              : #define PSEUDO_REGNO_MODE(N) GET_MODE (regno_reg_rtx[N])
     162              : 
     163              : /* Indexed by N, gives number of CALL_INSNS across which (REG n) is live.  */
     164              : 
     165              : #define REG_N_CALLS_CROSSED(N)  (reg_info_p[N].calls_crossed)
     166              : 
     167              : /* Indexed by n, gives number of basic block that  (REG n) is used in.
     168              :    If the value is REG_BLOCK_GLOBAL (-1),
     169              :    it means (REG n) is used in more than one basic block.
     170              :    REG_BLOCK_UNKNOWN (0) means it hasn't been seen yet so we don't know.
     171              :    This information remains valid for the rest of the compilation
     172              :    of the current function; it is used to control register allocation.  */
     173              : 
     174              : #define REG_BLOCK_UNKNOWN 0
     175              : #define REG_BLOCK_GLOBAL -1
     176              : 
     177              : #define REG_BASIC_BLOCK(N) (reg_info_p[N].basic_block)
     178              : 
     179              : /* Vector of substitutions of register numbers,
     180              :    used to map pseudo regs into hardware regs.
     181              : 
     182              :    This can't be folded into reg_n_info without changing all of the
     183              :    machine dependent directories, since the reload functions
     184              :    in the machine dependent files access it.  */
     185              : 
     186              : extern short *reg_renumber;
     187              : 
     188              : /* Flag set by local-alloc or global-alloc if they decide to allocate
     189              :    something in a call-clobbered register.  */
     190              : 
     191              : extern int caller_save_needed;
     192              : 
     193              : /* Select a register mode required for caller save of hard regno REGNO.  */
     194              : #ifndef HARD_REGNO_CALLER_SAVE_MODE
     195              : #define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \
     196              :   choose_hard_reg_mode (REGNO, NREGS, NULL)
     197              : #endif
     198              : 
     199              : /* Target-dependent globals.  */
     200              : struct target_regs {
     201              :   /* For each starting hard register, the number of consecutive hard
     202              :      registers that a given machine mode occupies.  */
     203              :   unsigned char x_hard_regno_nregs[FIRST_PSEUDO_REGISTER][MAX_MACHINE_MODE];
     204              : 
     205              :   /* The max value found in x_hard_regno_nregs.  */
     206              :   unsigned char x_hard_regno_max_nregs;
     207              : 
     208              :   /* For each hard register, the widest mode object that it can contain.
     209              :      This will be a MODE_INT mode if the register can hold integers.  Otherwise
     210              :      it will be a MODE_FLOAT or a MODE_CC mode, whichever is valid for the
     211              :      register.  */
     212              :   machine_mode x_reg_raw_mode[FIRST_PSEUDO_REGISTER];
     213              : 
     214              :   /* Vector indexed by machine mode saying whether there are regs of
     215              :      that mode.  */
     216              :   bool x_have_regs_of_mode[MAX_MACHINE_MODE];
     217              : 
     218              :   /* 1 if the corresponding class contains a register of the given mode.  */
     219              :   char x_contains_reg_of_mode[N_REG_CLASSES][MAX_MACHINE_MODE];
     220              : 
     221              :   /* 1 if the corresponding class contains a register of the given mode
     222              :      which is not global and can therefore be allocated.  */
     223              :   char x_contains_allocatable_reg_of_mode[N_REG_CLASSES][MAX_MACHINE_MODE];
     224              : 
     225              :   /* Record for each mode whether we can move a register directly to or
     226              :      from an object of that mode in memory.  If we can't, we won't try
     227              :      to use that mode directly when accessing a field of that mode.  */
     228              :   char x_direct_load[NUM_MACHINE_MODES];
     229              :   char x_direct_store[NUM_MACHINE_MODES];
     230              : 
     231              :   /* Record for each mode whether we can float-extend from memory.  */
     232              :   bool x_float_extend_from_mem[NUM_MACHINE_MODES][NUM_MACHINE_MODES];
     233              : };
     234              : 
     235              : extern struct target_regs default_target_regs;
     236              : #if SWITCHABLE_TARGET
     237              : extern struct target_regs *this_target_regs;
     238              : #else
     239              : #define this_target_regs (&default_target_regs)
     240              : #endif
     241              : #define hard_regno_max_nregs \
     242              :   (this_target_regs->x_hard_regno_max_nregs)
     243              : #define reg_raw_mode \
     244              :   (this_target_regs->x_reg_raw_mode)
     245              : #define have_regs_of_mode \
     246              :   (this_target_regs->x_have_regs_of_mode)
     247              : #define contains_reg_of_mode \
     248              :   (this_target_regs->x_contains_reg_of_mode)
     249              : #define contains_allocatable_reg_of_mode \
     250              :   (this_target_regs->x_contains_allocatable_reg_of_mode)
     251              : #define direct_load \
     252              :   (this_target_regs->x_direct_load)
     253              : #define direct_store \
     254              :   (this_target_regs->x_direct_store)
     255              : #define float_extend_from_mem \
     256              :   (this_target_regs->x_float_extend_from_mem)
     257              : 
     258              : /* Return the number of hard registers in (reg:MODE REGNO).  */
     259              : 
     260              : ALWAYS_INLINE unsigned char
     261  30203813411 : hard_regno_nregs (unsigned int regno, machine_mode mode)
     262              : {
     263  17939350827 :   return this_target_regs->x_hard_regno_nregs[regno][mode];
     264              : }
     265              : 
     266              : /* Return an exclusive upper bound on the registers occupied by hard
     267              :    register (reg:MODE REGNO).  */
     268              : 
     269              : inline unsigned int
     270  13100444413 : end_hard_regno (machine_mode mode, unsigned int regno)
     271              : {
     272  12619996786 :   return regno + hard_regno_nregs (regno, mode);
     273              : }
     274              : 
     275              : /* Add to REGS all the registers required to store a value of mode MODE
     276              :    in register REGNO.  */
     277              : 
     278              : inline void
     279   3068223098 : add_to_hard_reg_set (HARD_REG_SET *regs, machine_mode mode,
     280              :                      unsigned int regno)
     281              : {
     282   3068223098 :   unsigned int end_regno;
     283              : 
     284   3068223098 :   end_regno = end_hard_regno (mode, regno);
     285   3585667475 :   do
     286   3585667475 :     SET_HARD_REG_BIT (*regs, regno);
     287   3585667475 :   while (++regno < end_regno);
     288   3068223098 : }
     289              : 
     290              : /* Likewise, but remove the registers.  */
     291              : 
     292              : inline void
     293    365393780 : remove_from_hard_reg_set (HARD_REG_SET *regs, machine_mode mode,
     294              :                           unsigned int regno)
     295              : {
     296    365393780 :   unsigned int end_regno;
     297              : 
     298    365393780 :   end_regno = end_hard_regno (mode, regno);
     299    400916631 :   do
     300    400916631 :     CLEAR_HARD_REG_BIT (*regs, regno);
     301    400916631 :   while (++regno < end_regno);
     302    365393780 : }
     303              : 
     304              : /* Return true if REGS contains the whole of (reg:MODE REGNO).  */
     305              : 
     306              : inline bool
     307   8376909915 : in_hard_reg_set_p (const_hard_reg_set regs, machine_mode mode,
     308              :                    unsigned int regno)
     309              : {
     310   8376909915 :   unsigned int end_regno;
     311              : 
     312   8376909915 :   gcc_assert (HARD_REGISTER_NUM_P (regno));
     313              : 
     314   8376909915 :   if (!TEST_HARD_REG_BIT (regs, regno))
     315              :     return false;
     316              : 
     317   7068659448 :   end_regno = end_hard_regno (mode, regno);
     318              : 
     319   7068659448 :   if (!HARD_REGISTER_NUM_P (end_regno - 1))
     320              :     return false;
     321              : 
     322   7584289050 :   while (++regno < end_regno)
     323    617106038 :     if (!TEST_HARD_REG_BIT (regs, regno))
     324              :       return false;
     325              : 
     326              :   return true;
     327              : }
     328              : 
     329              : /* Return true if (reg:MODE REGNO) includes an element of REGS.  */
     330              : 
     331              : inline bool
     332   4420487517 : overlaps_hard_reg_set_p (const_hard_reg_set regs, machine_mode mode,
     333              :                          unsigned int regno)
     334              : {
     335   4420487517 :   unsigned int end_regno;
     336              : 
     337   4420487517 :   if (TEST_HARD_REG_BIT (regs, regno))
     338              :     return true;
     339              : 
     340   1167142679 :   end_regno = end_hard_regno (mode, regno);
     341   1265491183 :   while (++regno < end_regno)
     342    189614723 :     if (TEST_HARD_REG_BIT (regs, regno))
     343              :       return true;
     344              : 
     345              :   return false;
     346              : }
     347              : 
     348              : /* Like add_to_hard_reg_set, but use a REGNO/NREGS range instead of
     349              :    REGNO and MODE.  */
     350              : 
     351              : inline void
     352        41543 : add_range_to_hard_reg_set (HARD_REG_SET *regs, unsigned int regno,
     353              :                            int nregs)
     354              : {
     355        83086 :   while (nregs-- > 0)
     356        41543 :     SET_HARD_REG_BIT (*regs, regno + nregs);
     357        41543 : }
     358              : 
     359              : /* Likewise, but remove the registers.  */
     360              : 
     361              : inline void
     362      3225528 : remove_range_from_hard_reg_set (HARD_REG_SET *regs, unsigned int regno,
     363              :                                 int nregs)
     364              : {
     365      6451056 :   while (nregs-- > 0)
     366      3225528 :     CLEAR_HARD_REG_BIT (*regs, regno + nregs);
     367      3225528 : }
     368              : 
     369              : /* Like overlaps_hard_reg_set_p, but use a REGNO/NREGS range instead of
     370              :    REGNO and MODE.  */
     371              : inline bool
     372     10301386 : range_overlaps_hard_reg_set_p (const_hard_reg_set set, unsigned regno,
     373              :                                int nregs)
     374              : {
     375     11244122 :   while (nregs-- > 0)
     376     10301386 :     if (TEST_HARD_REG_BIT (set, regno + nregs))
     377              :       return true;
     378              :   return false;
     379              : }
     380              : 
     381              : /* Like in_hard_reg_set_p, but use a REGNO/NREGS range instead of
     382              :    REGNO and MODE.  */
     383              : inline bool
     384      3675769 : range_in_hard_reg_set_p (const_hard_reg_set set, unsigned regno, int nregs)
     385              : {
     386      6901297 :   while (nregs-- > 0)
     387      3675769 :     if (!TEST_HARD_REG_BIT (set, regno + nregs))
     388              :       return false;
     389              :   return true;
     390              : }
     391              : 
     392              : #endif /* GCC_REGS_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.