/* Local Register Allocator (LRA) intercommunication header file.
- Copyright (C) 2010-2016 Free Software Foundation, Inc.
+ Copyright (C) 2010-2020 Free Software Foundation, Inc.
Contributed by Vladimir Makarov <vmakarov@redhat.com>.
This file is part of GCC.
};
/* Common info about a register (pseudo or hard register). */
-struct lra_reg
+class lra_reg
{
+public:
/* Bitmap of UIDs of insns (including debug insns) referring the
reg. */
bitmap_head insn_bitmap;
/* The following fields are defined only for pseudos. */
/* Hard registers with which the pseudo conflicts. */
HARD_REG_SET conflict_hard_regs;
- /* Call used registers with which the pseudo conflicts, taking into account
- the registers used by functions called from calls which cross the
- pseudo. */
- HARD_REG_SET actual_call_used_reg_set;
/* We assign hard registers to reload pseudos which can occur in few
places. So two hard register preferences are enough for them.
The following fields define the preferred hard registers. If
/* True if the pseudo should not be assigned to a stack register. */
bool no_stack_p;
#endif
- /* True if the pseudo crosses a call. It is setup in lra-lives.c
- and used to check that the pseudo crossing a call did not get a
- call used hard register. */
- bool call_p;
/* Number of references and execution frequencies of the register in
*non-debug* insns. */
int nrefs, freq;
int last_reload;
- /* Regno used to undo the inheritance. It can be non-zero only
- between couple of inheritance and undo inheritance passes. */
- int restore_regno;
+ /* rtx used to undo the inheritance. It can be non-null only
+ between subsequent inheritance and undo inheritance passes. */
+ rtx restore_rtx;
/* Value holding by register. If the pseudos have the same value
they do not conflict. */
int val;
/* Offset from relative eliminate register to pesudo reg. */
- int offset;
+ poly_int64 offset;
/* These members are set up in lra-lives.c and updated in
lra-coalesce.c. */
/* The biggest size mode in which each pseudo reg is referred in
};
/* References to the common info about each register. */
-extern struct lra_reg *lra_reg_info;
+extern class lra_reg *lra_reg_info;
+
+extern HARD_REG_SET hard_regs_spilled_into;
/* Static info about each insn operand (common for all insns with the
same ICODE). Warning: if the structure definition is changed, the
{
/* The machine description constraint string of the operand. */
const char *constraint;
+ /* Alternatives for which early_clobber can be true. */
+ alternative_mask early_clobber_alts;
/* It is taken only from machine description (which is different
from recog_data.operand_mode) and can be of VOIDmode. */
ENUM_BITFIELD(machine_mode) mode : 16;
unsigned int strict_low : 1;
/* True if the operand is an operator. */
unsigned int is_operator : 1;
- /* True if there is an early clobber alternative for this operand.
- This field is set up every time when corresponding
- operand_alternative in lra_static_insn_data is set up. */
- unsigned int early_clobber : 1;
/* True if the operand is an address. */
unsigned int is_address : 1;
};
/* Info about register occurrence in an insn. */
struct lra_insn_reg
{
+ /* Alternatives for which early_clobber can be true. */
+ alternative_mask early_clobber_alts;
/* The biggest mode through which the insn refers to the register
occurrence (remember the register can be accessed through a
subreg in the insn). */
/* True if the reg is accessed through a subreg and the subreg is
just a part of the register. */
unsigned int subreg_p : 1;
- /* True if there is an early clobber alternative for this
- operand. */
- unsigned int early_clobber : 1;
/* The corresponding regno of the register. */
int regno;
/* Next reg info of the same insn. */
const struct operand_alternative *operand_alternative;
};
+/* Negative insn alternative numbers used for special cases. */
+#define LRA_UNKNOWN_ALT -1
+#define LRA_NON_CLOBBERED_ALT -2
+
/* LRA internal info about an insn (LRA internal insn
representation). */
-struct lra_insn_recog_data
+class lra_insn_recog_data
{
+public:
/* The insn code. */
int icode;
- /* The alternative should be used for the insn, -1 if invalid, or we
- should try to use any alternative, or the insn is a debug
- insn. */
+ /* The alternative should be used for the insn, LRA_UNKNOWN_ALT if
+ unknown, or we should assume any alternative, or the insn is a
+ debug insn. LRA_NON_CLOBBERED_ALT means ignoring any earlier
+ clobbers for the insn. */
int used_insn_alternative;
/* SP offset before the insn relative to one at the func start. */
- HOST_WIDE_INT sp_offset;
+ poly_int64 sp_offset;
/* The insn itself. */
rtx_insn *insn;
/* Common data for insns with the same ICODE. Asm insns (their
struct lra_insn_reg *regs;
};
-typedef struct lra_insn_recog_data *lra_insn_recog_data_t;
+typedef class lra_insn_recog_data *lra_insn_recog_data_t;
/* Whether the clobber is used temporary in LRA. */
#define LRA_TEMP_CLOBBER_P(x) \
extern FILE *lra_dump_file;
+extern bool lra_asm_error_p;
extern bool lra_reg_spill_p;
extern HARD_REG_SET lra_no_alloc_regs;
extern int lra_curr_reload_num;
extern void lra_dump_bitmap_with_title (const char *, bitmap, int);
+extern hashval_t lra_rtx_hash (rtx x);
extern void lra_push_insn (rtx_insn *);
extern void lra_push_insn_by_uid (unsigned int);
extern void lra_push_insn_and_update_insn_regno_info (rtx_insn *);
extern void lra_process_new_insns (rtx_insn *, rtx_insn *, rtx_insn *,
const char *);
-extern bool lra_substitute_pseudo (rtx *, int, rtx, bool);
+extern bool lra_substitute_pseudo (rtx *, int, rtx, bool, bool);
extern bool lra_substitute_pseudo_within_insn (rtx_insn *, int, rtx, bool);
extern lra_insn_recog_data_t lra_set_insn_recog_data (rtx_insn *);
extern lra_copy_t lra_get_copy (int);
extern bool lra_former_scratch_p (int);
extern bool lra_former_scratch_operand_p (rtx_insn *, int);
-extern void lra_register_new_scratch_op (rtx_insn *, int);
+extern void lra_register_new_scratch_op (rtx_insn *, int, int);
extern int lra_new_regno_start;
extern int lra_constraint_new_regno_start;
extern int lra_constraint_offset (int, machine_mode);
extern int lra_constraint_iter;
-extern bool lra_risky_transformations_p;
+extern bool check_and_force_assignment_correctness_p;
extern int lra_inheritance_iter;
extern int lra_undo_inheritance_iter;
extern bool lra_constrain_insn (rtx_insn *);
extern bool lra_constraints (bool);
extern void lra_constraints_init (void);
extern void lra_constraints_finish (void);
+extern bool spill_hard_reg_in_range (int, enum reg_class, rtx_insn *, rtx_insn *);
extern void lra_inheritance (void);
extern bool lra_undo_inheritance (void);
extern int lra_assignment_iter;
extern int lra_assignment_iter_after_spill;
extern void lra_setup_reg_renumber (int, int, bool);
-extern bool lra_assign (void);
-
+extern bool lra_assign (bool &);
+extern bool lra_split_hard_reg_for (void);
/* lra-coalesce.c: */
/* lra-spills.c: */
+extern bool lra_need_for_scratch_reg_p (void);
extern bool lra_need_for_spills_p (void);
extern void lra_spill (void);
extern void lra_final_code_change (void);
extern void lra_debug_elim_table (void);
extern int lra_get_elimination_hard_regno (int);
extern rtx lra_eliminate_regs_1 (rtx_insn *, rtx, machine_mode,
- bool, bool, HOST_WIDE_INT, bool);
-extern void eliminate_regs_in_insn (rtx_insn *insn, bool, bool, HOST_WIDE_INT);
+ bool, bool, poly_int64, bool);
+extern void eliminate_regs_in_insn (rtx_insn *insn, bool, bool, poly_int64);
extern void lra_eliminate (bool, bool);
extern void lra_eliminate_reg_if_possible (rtx *);
/* Update offset from pseudos with VAL by INCR. */
static inline void
-lra_update_reg_val_offset (int val, int incr)
+lra_update_reg_val_offset (int val, poly_int64 incr)
{
int i;
/* Return true if register content is equal to VAL with OFFSET. */
static inline bool
-lra_reg_val_equal_p (int regno, int val, int offset)
+lra_reg_val_equal_p (int regno, int val, poly_int64 offset)
{
if (lra_reg_info[regno].val == val
- && lra_reg_info[regno].offset == offset)
+ && known_eq (lra_reg_info[regno].offset, offset))
return true;
return false;