(root)/
gcc-13.2.0/
gcc/
lra-int.h
       1  /* Local Register Allocator (LRA) intercommunication header file.
       2     Copyright (C) 2010-2023 Free Software Foundation, Inc.
       3     Contributed by Vladimir Makarov <vmakarov@redhat.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_LRA_INT_H
      22  #define GCC_LRA_INT_H
      23  
      24  #define lra_assert(c) gcc_checking_assert (c)
      25  
      26  /* The parameter used to prevent infinite reloading for an insn.  Each
      27     insn operands might require a reload and, if it is a memory, its
      28     base and index registers might require a reload too.	 */
      29  #define LRA_MAX_INSN_RELOADS (MAX_RECOG_OPERANDS * 3)
      30  
      31  typedef struct lra_live_range *lra_live_range_t;
      32  
      33  /* The structure describes program points where a given pseudo lives.
      34     The live ranges can be used to find conflicts with other pseudos.
      35     If the live ranges of two pseudos are intersected, the pseudos are
      36     in conflict.	 */
      37  struct lra_live_range
      38  {
      39    /* Pseudo regno whose live range is described by given
      40       structure.	 */
      41    int regno;
      42    /* Program point range.  */
      43    int start, finish;
      44    /* Next structure describing program points where the pseudo
      45       lives.  */
      46    lra_live_range_t next;
      47    /* Pointer to structures with the same start.	 */
      48    lra_live_range_t start_next;
      49  };
      50  
      51  typedef struct lra_copy *lra_copy_t;
      52  
      53  /* Copy between pseudos which affects assigning hard registers.	 */
      54  struct lra_copy
      55  {
      56    /* True if regno1 is the destination of the copy.  */
      57    bool regno1_dest_p;
      58    /* Execution frequency of the copy.  */
      59    int freq;
      60    /* Pseudos connected by the copy.  REGNO1 < REGNO2.  */
      61    int regno1, regno2;
      62    /* Next copy with correspondingly REGNO1 and REGNO2.	*/
      63    lra_copy_t regno1_next, regno2_next;
      64  };
      65  
      66  /* Common info about a register (pseudo or hard register).  */
      67  class lra_reg
      68  {
      69  public:
      70    /* Bitmap of UIDs of insns (including debug insns) referring the
      71       reg.  */
      72    bitmap_head insn_bitmap;
      73    /* The following fields are defined only for pseudos.	 */
      74    /* Hard registers with which the pseudo conflicts.  */
      75    HARD_REG_SET conflict_hard_regs;
      76    /* Pseudo allocno class hard registers which cannot be a start hard register
      77       of the pseudo.  */
      78    HARD_REG_SET exclude_start_hard_regs;
      79    /* We assign hard registers to reload pseudos which can occur in few
      80       places.  So two hard register preferences are enough for them.
      81       The following fields define the preferred hard registers.	If
      82       there are no such hard registers the first field value is
      83       negative.	If there is only one preferred hard register, the 2nd
      84       field is negative.	 */
      85    int preferred_hard_regno1, preferred_hard_regno2;
      86    /* Profits to use the corresponding preferred hard registers.	 If
      87       the both hard registers defined, the first hard register has not
      88       less profit than the second one.  */
      89    int preferred_hard_regno_profit1, preferred_hard_regno_profit2;
      90  #ifdef STACK_REGS
      91    /* True if the pseudo should not be assigned to a stack register.  */
      92    bool no_stack_p;
      93  #endif
      94    /* Number of references and execution frequencies of the register in
      95       *non-debug* insns.	 */
      96    int nrefs, freq;
      97    int last_reload;
      98    /* rtx used to undo the inheritance.  It can be non-null only
      99       between subsequent inheritance and undo inheritance passes.  */
     100    rtx restore_rtx;
     101    /* Value holding by register.	 If the pseudos have the same value
     102       they do not conflict.  */
     103    int val;
     104    /* Offset from relative eliminate register to pesudo reg.  */
     105    poly_int64 offset;
     106    /* These members are set up in lra-lives.cc and updated in
     107       lra-coalesce.cc.  */
     108    /* The biggest size mode in which each pseudo reg is referred in
     109       whole function (possibly via subreg).  */
     110    machine_mode biggest_mode;
     111    /* Live ranges of the pseudo.	 */
     112    lra_live_range_t live_ranges;
     113    /* This member is set up in lra-lives.cc for subsequent
     114       assignments.  */
     115    lra_copy_t copies;
     116  };
     117  
     118  /* References to the common info about each register.  */
     119  extern class lra_reg *lra_reg_info;
     120  
     121  extern HARD_REG_SET hard_regs_spilled_into;
     122  
     123  /* Static info about each insn operand (common for all insns with the
     124     same ICODE).	 Warning: if the structure definition is changed, the
     125     initializer for debug_operand_data in lra.cc should be changed
     126     too.	 */
     127  struct lra_operand_data
     128  {
     129    /* The machine description constraint string of the operand.	*/
     130    const char *constraint;
     131    /* Alternatives for which early_clobber can be true.  */
     132    alternative_mask early_clobber_alts;
     133    /* It is taken only from machine description (which is different
     134       from recog_data.operand_mode) and can be of VOIDmode.  */
     135    ENUM_BITFIELD(machine_mode) mode : 16;
     136    /* The type of the operand (in/out/inout).  */
     137    ENUM_BITFIELD (op_type) type : 8;
     138    /* Through if accessed through STRICT_LOW.  */
     139    unsigned int strict_low : 1;
     140    /* True if the operand is an operator.  */
     141    unsigned int is_operator : 1;
     142    /* True if the operand is an address.  */
     143    unsigned int is_address : 1;
     144  };
     145  
     146  /* Info about register occurrence in an insn.  */
     147  struct lra_insn_reg
     148  {
     149    /* Alternatives for which early_clobber can be true.  */
     150    alternative_mask early_clobber_alts;
     151    /* The biggest mode through which the insn refers to the register
     152       occurrence (remember the register can be accessed through a
     153       subreg in the insn).  */
     154    ENUM_BITFIELD(machine_mode) biggest_mode : 16;
     155    /* The type of the corresponding operand which is the register.  */
     156    ENUM_BITFIELD (op_type) type : 8;
     157    /* True if the reg is accessed through a subreg and the subreg is
     158       just a part of the register.  */
     159    unsigned int subreg_p : 1;
     160    /* The corresponding regno of the register.  */
     161    int regno;
     162    /* Next reg info of the same insn.  */
     163    struct lra_insn_reg *next;
     164  };
     165  
     166  /* Static part (common info for insns with the same ICODE) of LRA
     167     internal insn info. It exists in at most one exemplar for each
     168     non-negative ICODE. There is only one exception. Each asm insn has
     169     own structure.  Warning: if the structure definition is changed,
     170     the initializer for debug_insn_static_data in lra.cc should be
     171     changed too.  */
     172  struct lra_static_insn_data
     173  {
     174    /* Static info about each insn operand.  */
     175    struct lra_operand_data *operand;
     176    /* Each duplication refers to the number of the corresponding
     177       operand which is duplicated.  */
     178    int *dup_num;
     179    /* The number of an operand marked as commutative, -1 otherwise.  */
     180    int commutative;
     181    /* Number of operands, duplications, and alternatives of the
     182       insn.  */
     183    char n_operands;
     184    char n_dups;
     185    char n_alternatives;
     186    /* Insns in machine description (or clobbers in asm) may contain
     187       explicit hard regs which are not operands.	 The following list
     188       describes such hard registers.  */
     189    struct lra_insn_reg *hard_regs;
     190    /* Array [n_alternatives][n_operand] of static constraint info for
     191       given operand in given alternative.  This info can be changed if
     192       the target reg info is changed.  */
     193    const struct operand_alternative *operand_alternative;
     194  };
     195  
     196  /* Negative insn alternative numbers used for special cases.  */
     197  #define LRA_UNKNOWN_ALT -1
     198  #define LRA_NON_CLOBBERED_ALT -2
     199  
     200  /* LRA internal info about an insn (LRA internal insn
     201     representation).  */
     202  class lra_insn_recog_data
     203  {
     204  public:
     205    /* The insn code.  */
     206    int icode;
     207    /* The alternative should be used for the insn, LRA_UNKNOWN_ALT if
     208       unknown, or we should assume any alternative, or the insn is a
     209       debug insn.  LRA_NON_CLOBBERED_ALT means ignoring any earlier
     210       clobbers for the insn.  */
     211    int used_insn_alternative;
     212    /* SP offset before the insn relative to one at the func start.  */
     213    poly_int64 sp_offset;
     214    /* The insn itself.  */
     215    rtx_insn *insn;
     216    /* Common data for insns with the same ICODE.  Asm insns (their
     217       ICODE is negative) do not share such structures.  */
     218    struct lra_static_insn_data *insn_static_data;
     219    /* Two arrays of size correspondingly equal to the operand and the
     220       duplication numbers: */
     221    rtx **operand_loc; /* The operand locations, NULL if no operands.  */
     222    rtx **dup_loc; /* The dup locations, NULL if no dups.	 */
     223    /* Number of hard registers implicitly used/clobbered in given call
     224       insn.  The value can be NULL or points to array of the hard
     225       register numbers ending with a negative value.  To differ
     226       clobbered and used hard regs, clobbered hard regs are incremented
     227       by FIRST_PSEUDO_REGISTER.  */
     228    int *arg_hard_regs;
     229    /* Cached value of get_preferred_alternatives.  */
     230    alternative_mask preferred_alternatives;
     231    /* The following member value is always NULL for a debug insn.  */
     232    struct lra_insn_reg *regs;
     233  };
     234  
     235  typedef class lra_insn_recog_data *lra_insn_recog_data_t;
     236  
     237  /* Whether the clobber is used temporary in LRA.  */
     238  #define LRA_TEMP_CLOBBER_P(x) \
     239    (RTL_FLAG_CHECK1 ("TEMP_CLOBBER_P", (x), CLOBBER)->unchanging)
     240  
     241  /* Cost factor for each additional reload and maximal cost reject for
     242     insn reloads.  One might ask about such strange numbers.  Their
     243     values occurred historically from former reload pass.  */
     244  #define LRA_LOSER_COST_FACTOR 6
     245  #define LRA_MAX_REJECT 600
     246  
     247  /* Maximum allowed number of assignment pass iterations after the
     248     latest spill pass when any former reload pseudo was spilled.  It is
     249     for preventing LRA cycling in a bug case.  */
     250  #define LRA_MAX_ASSIGNMENT_ITERATION_NUMBER 30
     251  
     252  /* The maximal number of inheritance/split passes in LRA.  It should
     253     be more 1 in order to perform caller saves transformations and much
     254     less MAX_CONSTRAINT_ITERATION_NUMBER to prevent LRA to do as many
     255     as permitted constraint passes in some complicated cases.  The
     256     first inheritance/split pass has a biggest impact on generated code
     257     quality.  Each subsequent affects generated code in less degree.
     258     For example, the 3rd pass does not change generated SPEC2000 code
     259     at all on x86-64.  */
     260  #define LRA_MAX_INHERITANCE_PASSES 2
     261  
     262  #if LRA_MAX_INHERITANCE_PASSES <= 0 \
     263      || LRA_MAX_INHERITANCE_PASSES >= LRA_MAX_ASSIGNMENT_ITERATION_NUMBER - 8
     264  #error wrong LRA_MAX_INHERITANCE_PASSES value
     265  #endif
     266  
     267  /* Analogous macro to the above one but for rematerialization.  */
     268  #define LRA_MAX_REMATERIALIZATION_PASSES 2
     269  
     270  #if LRA_MAX_REMATERIALIZATION_PASSES <= 0 \
     271      || LRA_MAX_REMATERIALIZATION_PASSES >= LRA_MAX_ASSIGNMENT_ITERATION_NUMBER - 8
     272  #error wrong LRA_MAX_REMATERIALIZATION_PASSES value
     273  #endif
     274  
     275  /* lra.cc: */
     276  
     277  extern FILE *lra_dump_file;
     278  
     279  extern bool lra_hard_reg_split_p;
     280  extern bool lra_asm_error_p;
     281  extern bool lra_reg_spill_p;
     282  
     283  extern HARD_REG_SET lra_no_alloc_regs;
     284  
     285  extern int lra_insn_recog_data_len;
     286  extern lra_insn_recog_data_t *lra_insn_recog_data;
     287  
     288  extern int lra_curr_reload_num;
     289  
     290  extern void lra_dump_bitmap_with_title (const char *, bitmap, int);
     291  extern hashval_t lra_rtx_hash (rtx x);
     292  extern void lra_push_insn (rtx_insn *);
     293  extern void lra_push_insn_by_uid (unsigned int);
     294  extern void lra_push_insn_and_update_insn_regno_info (rtx_insn *);
     295  extern rtx_insn *lra_pop_insn (void);
     296  extern unsigned int lra_insn_stack_length (void);
     297  
     298  extern rtx lra_create_new_reg (machine_mode, rtx, enum reg_class, HARD_REG_SET *,
     299  			       const char *);
     300  extern rtx lra_create_new_reg_with_unique_value (machine_mode, rtx,
     301  						 enum reg_class, HARD_REG_SET *,
     302  						 const char *);
     303  extern void lra_set_regno_unique_value (int);
     304  extern void lra_invalidate_insn_data (rtx_insn *);
     305  extern void lra_set_insn_deleted (rtx_insn *);
     306  extern void lra_delete_dead_insn (rtx_insn *);
     307  extern void lra_emit_add (rtx, rtx, rtx);
     308  extern void lra_emit_move (rtx, rtx);
     309  extern void lra_update_dups (lra_insn_recog_data_t, signed char *);
     310  
     311  extern void lra_process_new_insns (rtx_insn *, rtx_insn *, rtx_insn *,
     312  				   const char *);
     313  
     314  extern bool lra_substitute_pseudo (rtx *, int, rtx, bool, bool);
     315  extern bool lra_substitute_pseudo_within_insn (rtx_insn *, int, rtx, bool);
     316  
     317  extern lra_insn_recog_data_t lra_set_insn_recog_data (rtx_insn *);
     318  extern lra_insn_recog_data_t lra_update_insn_recog_data (rtx_insn *);
     319  extern void lra_set_used_insn_alternative (rtx_insn *, int);
     320  extern void lra_set_used_insn_alternative_by_uid (int, int);
     321  
     322  extern void lra_invalidate_insn_regno_info (rtx_insn *);
     323  extern void lra_update_insn_regno_info (rtx_insn *);
     324  extern struct lra_insn_reg *lra_get_insn_regs (int);
     325  
     326  extern void lra_free_copies (void);
     327  extern void lra_create_copy (int, int, int);
     328  extern lra_copy_t lra_get_copy (int);
     329  
     330  extern int lra_new_regno_start;
     331  extern int lra_constraint_new_regno_start;
     332  extern int lra_bad_spill_regno_start;
     333  extern rtx lra_pmode_pseudo;
     334  extern bitmap_head lra_inheritance_pseudos;
     335  extern bitmap_head lra_split_regs;
     336  extern bitmap_head lra_subreg_reload_pseudos;
     337  extern bitmap_head lra_optional_reload_pseudos;
     338  
     339  /* lra-constraints.cc: */
     340  
     341  extern void lra_init_equiv (void);
     342  extern int lra_constraint_offset (int, machine_mode);
     343  
     344  extern int lra_constraint_iter;
     345  extern bool check_and_force_assignment_correctness_p;
     346  extern int lra_inheritance_iter;
     347  extern int lra_undo_inheritance_iter;
     348  extern bool lra_constrain_insn (rtx_insn *);
     349  extern bool lra_constraints (bool);
     350  extern void lra_constraints_init (void);
     351  extern void lra_constraints_finish (void);
     352  extern bool spill_hard_reg_in_range (int, enum reg_class, rtx_insn *, rtx_insn *);
     353  extern void lra_inheritance (void);
     354  extern bool lra_undo_inheritance (void);
     355  
     356  /* lra-lives.cc: */
     357  
     358  extern int lra_live_max_point;
     359  extern int *lra_point_freq;
     360  
     361  extern int lra_hard_reg_usage[FIRST_PSEUDO_REGISTER];
     362  
     363  extern int lra_live_range_iter;
     364  extern void lra_create_live_ranges (bool, bool);
     365  extern lra_live_range_t lra_copy_live_range_list (lra_live_range_t);
     366  extern lra_live_range_t lra_merge_live_ranges (lra_live_range_t,
     367  					       lra_live_range_t);
     368  extern bool lra_intersected_live_ranges_p (lra_live_range_t,
     369  					   lra_live_range_t);
     370  extern void lra_print_live_range_list (FILE *, lra_live_range_t);
     371  extern void debug (lra_live_range &ref);
     372  extern void debug (lra_live_range *ptr);
     373  extern void lra_debug_live_range_list (lra_live_range_t);
     374  extern void lra_debug_pseudo_live_ranges (int);
     375  extern void lra_debug_live_ranges (void);
     376  extern void lra_clear_live_ranges (void);
     377  extern void lra_live_ranges_init (void);
     378  extern void lra_live_ranges_finish (void);
     379  extern void lra_setup_reload_pseudo_preferenced_hard_reg (int, int, int);
     380  
     381  /* lra-assigns.cc: */
     382  
     383  extern int lra_assignment_iter;
     384  extern int lra_assignment_iter_after_spill;
     385  extern void lra_setup_reg_renumber (int, int, bool);
     386  extern bool lra_assign (bool &);
     387  extern bool lra_split_hard_reg_for (void);
     388  
     389  /* lra-coalesce.cc: */
     390  
     391  extern int lra_coalesce_iter;
     392  extern bool lra_coalesce (void);
     393  
     394  /* lra-spills.cc:  */
     395  
     396  extern bool lra_need_for_scratch_reg_p (void);
     397  extern bool lra_need_for_spills_p (void);
     398  extern void lra_spill (void);
     399  extern void lra_final_code_change (void);
     400  
     401  /* lra-remat.cc:  */
     402  
     403  extern int lra_rematerialization_iter;
     404  extern bool lra_remat (void);
     405  
     406  /* lra-elimination.c: */
     407  
     408  extern void lra_debug_elim_table (void);
     409  extern int lra_get_elimination_hard_regno (int);
     410  extern rtx lra_eliminate_regs_1 (rtx_insn *, rtx, machine_mode,
     411  				 bool, bool, poly_int64, bool);
     412  extern void eliminate_regs_in_insn (rtx_insn *insn, bool, bool, poly_int64);
     413  extern void lra_eliminate (bool, bool);
     414  
     415  extern void lra_eliminate_reg_if_possible (rtx *);
     416  
     417  
     418  
     419  /* Return the hard register which given pseudo REGNO assigned to.
     420     Negative value means that the register got memory or we don't know
     421     allocation yet.  */
     422  inline int
     423  lra_get_regno_hard_regno (int regno)
     424  {
     425    resize_reg_info ();
     426    return reg_renumber[regno];
     427  }
     428  
     429  /* Change class of pseudo REGNO to NEW_CLASS.  Print info about it
     430     using TITLE.  Output a new line if NL_P.  */
     431  inline void
     432  lra_change_class (int regno, enum reg_class new_class,
     433  		  const char *title, bool nl_p)
     434  {
     435    lra_assert (regno >= FIRST_PSEUDO_REGISTER);
     436    if (lra_dump_file != NULL)
     437      fprintf (lra_dump_file, "%s class %s for r%d",
     438  	     title, reg_class_names[new_class], regno);
     439    setup_reg_classes (regno, new_class, NO_REGS, new_class);
     440    if (lra_dump_file != NULL && nl_p)
     441      fprintf (lra_dump_file, "\n");
     442  }
     443  
     444  /* Update insn operands which are duplication of NOP operand.  The
     445     insn is represented by its LRA internal representation ID.  */
     446  inline void
     447  lra_update_dup (lra_insn_recog_data_t id, int nop)
     448  {
     449    int i;
     450    struct lra_static_insn_data *static_id = id->insn_static_data;
     451  
     452    for (i = 0; i < static_id->n_dups; i++)
     453      if (static_id->dup_num[i] == nop)
     454        *id->dup_loc[i] = *id->operand_loc[nop];
     455  }
     456  
     457  /* Process operator duplications in insn with ID.  We do it after the
     458     operands processing.	 Generally speaking, we could do this probably
     459     simultaneously with operands processing because a common practice
     460     is to enumerate the operators after their operands.	*/
     461  inline void
     462  lra_update_operator_dups (lra_insn_recog_data_t id)
     463  {
     464    int i;
     465    struct lra_static_insn_data *static_id = id->insn_static_data;
     466  
     467    for (i = 0; i < static_id->n_dups; i++)
     468      {
     469        int ndup = static_id->dup_num[i];
     470  
     471        if (static_id->operand[ndup].is_operator)
     472  	*id->dup_loc[i] = *id->operand_loc[ndup];
     473      }
     474  }
     475  
     476  /* Return info about INSN.  Set up the info if it is not done yet.  */
     477  inline lra_insn_recog_data_t
     478  lra_get_insn_recog_data (rtx_insn *insn)
     479  {
     480    lra_insn_recog_data_t data;
     481    unsigned int uid = INSN_UID (insn);
     482  
     483    if (lra_insn_recog_data_len > (int) uid
     484        && (data = lra_insn_recog_data[uid]) != NULL)
     485      {
     486        /* Check that we did not change insn without updating the insn
     487  	 info.	*/
     488        lra_assert (data->insn == insn
     489  		  && (INSN_CODE (insn) < 0
     490  		      || data->icode == INSN_CODE (insn)));
     491        return data;
     492      }
     493    return lra_set_insn_recog_data (insn);
     494  }
     495  
     496  /* Update offset from pseudos with VAL by INCR.  */
     497  inline void
     498  lra_update_reg_val_offset (int val, poly_int64 incr)
     499  {
     500    int i;
     501  
     502    for (i = FIRST_PSEUDO_REGISTER; i < max_reg_num (); i++)
     503      {
     504        if (lra_reg_info[i].val == val)
     505          lra_reg_info[i].offset += incr;
     506      }
     507  }
     508  
     509  /* Return true if register content is equal to VAL with OFFSET.  */
     510  inline bool
     511  lra_reg_val_equal_p (int regno, int val, poly_int64 offset)
     512  {
     513    if (lra_reg_info[regno].val == val
     514        && known_eq (lra_reg_info[regno].offset, offset))
     515      return true;
     516  
     517    return false;
     518  }
     519  
     520  /* Assign value of register FROM to TO.  */
     521  inline void
     522  lra_assign_reg_val (int from, int to)
     523  {
     524    lra_reg_info[to].val = lra_reg_info[from].val;
     525    lra_reg_info[to].offset = lra_reg_info[from].offset;
     526  }
     527  
     528  #endif /* GCC_LRA_INT_H */