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: 2024-12-21 13:15:12 Functions: 100.0 % 6 6
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Define per-register tables for data flow info and register allocation.
       2                 :             :    Copyright (C) 1987-2024 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                 :     4426680 : REG_N_REFS (int regno)
      69                 :             : {
      70                 :     4426680 :   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                 :   832184459 : REG_N_SETS (int regno)
      80                 :             : {
      81                 :   832184459 :   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                 : 30424183083 : hard_regno_nregs (unsigned int regno, machine_mode mode)
     262                 :             : {
     263                 : 18673202436 :   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                 : 12464863093 : end_hard_regno (machine_mode mode, unsigned int regno)
     271                 :             : {
     272                 : 12008098675 :   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                 :  2880173616 : add_to_hard_reg_set (HARD_REG_SET *regs, machine_mode mode,
     280                 :             :                      unsigned int regno)
     281                 :             : {
     282                 :  2880173616 :   unsigned int end_regno;
     283                 :             : 
     284                 :  2880173616 :   end_regno = end_hard_regno (mode, regno);
     285                 :  3383920124 :   do
     286                 :  3383920124 :     SET_HARD_REG_BIT (*regs, regno);
     287                 :  3383920124 :   while (++regno < end_regno);
     288                 :  2880173616 : }
     289                 :             : 
     290                 :             : /* Likewise, but remove the registers.  */
     291                 :             : 
     292                 :             : inline void
     293                 :   368931135 : remove_from_hard_reg_set (HARD_REG_SET *regs, machine_mode mode,
     294                 :             :                           unsigned int regno)
     295                 :             : {
     296                 :   368931135 :   unsigned int end_regno;
     297                 :             : 
     298                 :   368931135 :   end_regno = end_hard_regno (mode, regno);
     299                 :   406072717 :   do
     300                 :   406072717 :     CLEAR_HARD_REG_BIT (*regs, regno);
     301                 :   406072717 :   while (++regno < end_regno);
     302                 :   368931135 : }
     303                 :             : 
     304                 :             : /* Return true if REGS contains the whole of (reg:MODE REGNO).  */
     305                 :             : 
     306                 :             : inline bool
     307                 :  8015424964 : in_hard_reg_set_p (const_hard_reg_set regs, machine_mode mode,
     308                 :             :                    unsigned int regno)
     309                 :             : {
     310                 :  8015424964 :   unsigned int end_regno;
     311                 :             : 
     312                 :  8015424964 :   gcc_assert (HARD_REGISTER_NUM_P (regno));
     313                 :             : 
     314                 :  8015424964 :   if (!TEST_HARD_REG_BIT (regs, regno))
     315                 :             :     return false;
     316                 :             : 
     317                 :  6731872906 :   end_regno = end_hard_regno (mode, regno);
     318                 :             : 
     319                 :  6731872906 :   if (!HARD_REGISTER_NUM_P (end_regno - 1))
     320                 :             :     return false;
     321                 :             : 
     322                 :  7233421273 :   while (++regno < end_regno)
     323                 :   600271146 :     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                 :  4643702480 : overlaps_hard_reg_set_p (const_hard_reg_set regs, machine_mode mode,
     333                 :             :                          unsigned int regno)
     334                 :             : {
     335                 :  4643702480 :   unsigned int end_regno;
     336                 :             : 
     337                 :  4643702480 :   if (TEST_HARD_REG_BIT (regs, regno))
     338                 :             :     return true;
     339                 :             : 
     340                 :  1168650807 :   end_regno = end_hard_regno (mode, regno);
     341                 :  1271457866 :   while (++regno < end_regno)
     342                 :   200670559 :     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                 :       41471 : add_range_to_hard_reg_set (HARD_REG_SET *regs, unsigned int regno,
     353                 :             :                            int nregs)
     354                 :             : {
     355                 :       82942 :   while (nregs-- > 0)
     356                 :       41471 :     SET_HARD_REG_BIT (*regs, regno + nregs);
     357                 :       41471 : }
     358                 :             : 
     359                 :             : /* Likewise, but remove the registers.  */
     360                 :             : 
     361                 :             : inline void
     362                 :     2936540 : remove_range_from_hard_reg_set (HARD_REG_SET *regs, unsigned int regno,
     363                 :             :                                 int nregs)
     364                 :             : {
     365                 :     5873080 :   while (nregs-- > 0)
     366                 :     2936540 :     CLEAR_HARD_REG_BIT (*regs, regno + nregs);
     367                 :     2936540 : }
     368                 :             : 
     369                 :             : /* Like overlaps_hard_reg_set_p, but use a REGNO/NREGS range instead of
     370                 :             :    REGNO and MODE.  */
     371                 :             : inline bool
     372                 :     9381306 : range_overlaps_hard_reg_set_p (const_hard_reg_set set, unsigned regno,
     373                 :             :                                int nregs)
     374                 :             : {
     375                 :    10215098 :   while (nregs-- > 0)
     376                 :     9381306 :     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                 :     3352655 : range_in_hard_reg_set_p (const_hard_reg_set set, unsigned regno, int nregs)
     385                 :             : {
     386                 :     6289195 :   while (nregs-- > 0)
     387                 :     3352655 :     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.1-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.