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