1/* Register renaming for the GNU compiler.
2 Copyright (C) 2000-2023 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
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License 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#include "config.h"
21#include "system.h"
22#include "coretypes.h"
23#include "backend.h"
24#include "target.h"
25#include "rtl.h"
26#include "df.h"
27#include "memmodel.h"
28#include "tm_p.h"
29#include "insn-config.h"
30#include "regs.h"
31#include "emit-rtl.h"
32#include "recog.h"
33#include "addresses.h"
34#include "cfganal.h"
35#include "tree-pass.h"
36#include "function-abi.h"
37#include "regrename.h"
38
39/* This file implements the RTL register renaming pass of the compiler. It is
40 a semi-local pass whose goal is to maximize the usage of the register file
41 of the processor by substituting registers for others in the solution given
42 by the register allocator. The algorithm is as follows:
43
44 1. Local def/use chains are built: within each basic block, chains are
45 opened and closed; if a chain isn't closed at the end of the block,
46 it is dropped. We pre-open chains if we have already examined a
47 predecessor block and found chains live at the end which match
48 live registers at the start of the new block.
49
50 2. We try to combine the local chains across basic block boundaries by
51 comparing chains that were open at the start or end of a block to
52 those in successor/predecessor blocks.
53
54 3. For each chain, the set of possible renaming registers is computed.
55 This takes into account the renaming of previously processed chains.
56 Optionally, a preferred class is computed for the renaming register.
57
58 4. The best renaming register is computed for the chain in the above set,
59 using a round-robin allocation. If a preferred class exists, then the
60 round-robin allocation is done within the class first, if possible.
61 The round-robin allocation of renaming registers itself is global.
62
63 5. If a renaming register has been found, it is substituted in the chain.
64
65 Targets can parameterize the pass by specifying a preferred class for the
66 renaming register for a given (super)class of registers to be renamed.
67
68 DEBUG_INSNs are treated specially, in particular registers occurring inside
69 them are treated as requiring ALL_REGS as a class. */
70
71#if HOST_BITS_PER_WIDE_INT <= MAX_RECOG_OPERANDS
72#error "Use a different bitmap implementation for untracked_operands."
73#endif
74
75enum scan_actions
76{
77 terminate_write,
78 terminate_dead,
79 mark_all_read,
80 mark_read,
81 mark_write,
82 /* mark_access is for marking the destination regs in
83 REG_FRAME_RELATED_EXPR notes (as if they were read) so that the
84 note is updated properly. */
85 mark_access
86};
87
88static const char * const scan_actions_name[] =
89{
90 "terminate_write",
91 "terminate_dead",
92 "mark_all_read",
93 "mark_read",
94 "mark_write",
95 "mark_access"
96};
97
98/* TICK and THIS_TICK are used to record the last time we saw each
99 register. */
100static int tick[FIRST_PSEUDO_REGISTER];
101static int this_tick = 0;
102
103static struct obstack rename_obstack;
104
105/* If nonnull, the code calling into the register renamer requested
106 information about insn operands, and we store it here. */
107vec<insn_rr_info> insn_rr;
108
109static void scan_rtx (rtx_insn *, rtx *, enum reg_class, enum scan_actions,
110 enum op_type);
111static bool build_def_use (basic_block);
112
113/* The id to be given to the next opened chain. */
114static unsigned current_id;
115
116/* A mapping of unique id numbers to chains. */
117static vec<du_head_p> id_to_chain;
118
119/* List of currently open chains. */
120static class du_head *open_chains;
121
122/* Bitmap of open chains. The bits set always match the list found in
123 open_chains. */
124static bitmap_head open_chains_set;
125
126/* Record the registers being tracked in open_chains. */
127static HARD_REG_SET live_in_chains;
128
129/* Record the registers that are live but not tracked. The intersection
130 between this and live_in_chains is empty. */
131static HARD_REG_SET live_hard_regs;
132
133/* Set while scanning RTL if INSN_RR is nonnull, i.e. if the current analysis
134 is for a caller that requires operand data. Used in
135 record_operand_use. */
136static operand_rr_info *cur_operand;
137
138/* Set while scanning RTL if a register dies. Used to tie chains. */
139static class du_head *terminated_this_insn;
140
141/* Return the chain corresponding to id number ID. Take into account that
142 chains may have been merged. */
143du_head_p
144regrename_chain_from_id (unsigned int id)
145{
146 du_head_p first_chain = id_to_chain[id];
147 du_head_p chain = first_chain;
148 while (chain->id != id)
149 {
150 id = chain->id;
151 chain = id_to_chain[id];
152 }
153 first_chain->id = id;
154 return chain;
155}
156
157/* Dump all def/use chains, starting at id FROM. */
158
159static void
160dump_def_use_chain (int from)
161{
162 du_head_p head;
163 int i;
164 FOR_EACH_VEC_ELT_FROM (id_to_chain, i, head, from)
165 {
166 struct du_chain *this_du = head->first;
167
168 fprintf (stream: dump_file, format: "Register %s (%d):",
169 reg_names[head->regno], head->nregs);
170 while (this_du)
171 {
172 fprintf (stream: dump_file, format: " %d [%s]", INSN_UID (insn: this_du->insn),
173 reg_class_names[this_du->cl]);
174 this_du = this_du->next_use;
175 }
176 fprintf (stream: dump_file, format: "\n");
177 head = head->next_chain;
178 }
179}
180
181static void
182free_chain_data (void)
183{
184 int i;
185 du_head_p ptr;
186 for (i = 0; id_to_chain.iterate (ix: i, ptr: &ptr); i++)
187 bitmap_clear (&ptr->conflicts);
188
189 id_to_chain.release ();
190}
191
192/* Walk all chains starting with CHAINS and record that they conflict with
193 another chain whose id is ID. */
194
195static void
196mark_conflict (class du_head *chains, unsigned id)
197{
198 while (chains)
199 {
200 bitmap_set_bit (&chains->conflicts, id);
201 chains = chains->next_chain;
202 }
203}
204
205/* Examine cur_operand, and if it is nonnull, record information about the
206 use THIS_DU which is part of the chain HEAD. */
207
208static void
209record_operand_use (class du_head *head, struct du_chain *this_du)
210{
211 if (cur_operand == NULL || cur_operand->failed)
212 return;
213 if (head->cannot_rename)
214 {
215 cur_operand->failed = true;
216 return;
217 }
218 gcc_assert (cur_operand->n_chains < MAX_REGS_PER_ADDRESS);
219 cur_operand->heads[cur_operand->n_chains] = head;
220 cur_operand->chains[cur_operand->n_chains++] = this_du;
221}
222
223/* Create a new chain for THIS_NREGS registers starting at THIS_REGNO,
224 and record its occurrence in *LOC, which is being written to in INSN.
225 This access requires a register of class CL. */
226
227static du_head_p
228create_new_chain (unsigned this_regno, unsigned this_nregs, rtx *loc,
229 rtx_insn *insn, enum reg_class cl)
230{
231 class du_head *head = XOBNEW (&rename_obstack, class du_head);
232 struct du_chain *this_du;
233 int nregs;
234
235 memset (s: (void *)head, c: 0, n: sizeof *head);
236 head->next_chain = open_chains;
237 head->regno = this_regno;
238 head->nregs = this_nregs;
239
240 id_to_chain.safe_push (obj: head);
241 head->id = current_id++;
242
243 bitmap_initialize (head: &head->conflicts, obstack: &bitmap_default_obstack);
244 bitmap_copy (&head->conflicts, &open_chains_set);
245 mark_conflict (chains: open_chains, id: head->id);
246
247 /* Since we're tracking this as a chain now, remove it from the
248 list of conflicting live hard registers and track it in
249 live_in_chains instead. */
250 nregs = head->nregs;
251 while (nregs-- > 0)
252 {
253 SET_HARD_REG_BIT (set&: live_in_chains, bit: head->regno + nregs);
254 CLEAR_HARD_REG_BIT (set&: live_hard_regs, bit: head->regno + nregs);
255 }
256
257 head->hard_conflicts = live_hard_regs;
258 bitmap_set_bit (&open_chains_set, head->id);
259
260 open_chains = head;
261
262 if (dump_file)
263 {
264 fprintf (stream: dump_file, format: "Creating chain %s (%d)",
265 reg_names[head->regno], head->id);
266 if (insn != NULL_RTX)
267 fprintf (stream: dump_file, format: " at insn %d", INSN_UID (insn));
268 fprintf (stream: dump_file, format: "\n");
269 }
270
271 if (insn == NULL_RTX)
272 {
273 head->first = head->last = NULL;
274 return head;
275 }
276
277 this_du = XOBNEW (&rename_obstack, struct du_chain);
278 head->first = head->last = this_du;
279
280 this_du->next_use = 0;
281 this_du->loc = loc;
282 this_du->insn = insn;
283 this_du->cl = cl;
284 record_operand_use (head, this_du);
285 return head;
286}
287
288/* For a def-use chain HEAD, find which registers overlap its lifetime and
289 set the corresponding bits in *PSET. */
290
291static void
292merge_overlapping_regs (HARD_REG_SET *pset, class du_head *head)
293{
294 bitmap_iterator bi;
295 unsigned i;
296 *pset |= head->hard_conflicts;
297 EXECUTE_IF_SET_IN_BITMAP (&head->conflicts, 0, i, bi)
298 {
299 du_head_p other = regrename_chain_from_id (id: i);
300 unsigned j = other->nregs;
301 gcc_assert (other != head);
302 while (j-- > 0)
303 SET_HARD_REG_BIT (set&: *pset, bit: other->regno + j);
304 }
305}
306
307/* Return true if (reg:MODE REGNO) would be clobbered by a call covered
308 by THIS_HEAD. */
309
310static bool
311call_clobbered_in_chain_p (du_head *this_head, machine_mode mode,
312 unsigned int regno)
313{
314 return call_clobbered_in_region_p (abis: this_head->call_abis,
315 mask: this_head->call_clobber_mask,
316 mode, regno);
317}
318
319/* Check if NEW_REG can be the candidate register to rename for
320 REG in THIS_HEAD chain. THIS_UNAVAILABLE is a set of unavailable hard
321 registers. */
322
323static bool
324check_new_reg_p (int reg ATTRIBUTE_UNUSED, int new_reg,
325 class du_head *this_head, HARD_REG_SET this_unavailable)
326{
327 int nregs = this_head->nregs;
328 int i;
329 struct du_chain *tmp;
330
331 for (i = nregs - 1; i >= 0; --i)
332 if (TEST_HARD_REG_BIT (set: this_unavailable, bit: new_reg + i)
333 || fixed_regs[new_reg + i]
334 || global_regs[new_reg + i]
335 /* Can't use regs which aren't saved by the prologue. */
336 || (! df_regs_ever_live_p (new_reg + i)
337 && ! crtl->abi->clobbers_full_reg_p (regno: new_reg + i))
338#ifdef LEAF_REGISTERS
339 /* We can't use a non-leaf register if we're in a
340 leaf function. */
341 || (crtl->is_leaf
342 && !LEAF_REGISTERS[new_reg + i])
343#endif
344 || ! HARD_REGNO_RENAME_OK (reg + i, new_reg + i))
345 return false;
346
347 /* See whether it accepts all modes that occur in
348 definition and uses. */
349 for (tmp = this_head->first; tmp; tmp = tmp->next_use)
350 {
351 /* Completely ignore DEBUG_INSNs, otherwise we can get
352 -fcompare-debug failures. */
353 if (DEBUG_INSN_P (tmp->insn))
354 continue;
355
356 if (!targetm.hard_regno_mode_ok (new_reg, GET_MODE (*tmp->loc))
357 || call_clobbered_in_chain_p (this_head, GET_MODE (*tmp->loc),
358 regno: new_reg))
359 return false;
360 }
361
362 return true;
363}
364
365/* For the chain THIS_HEAD, compute and return the best register to
366 rename to. SUPER_CLASS is the superunion of register classes in
367 the chain. UNAVAILABLE is a set of registers that cannot be used.
368 OLD_REG is the register currently used for the chain. BEST_RENAME
369 controls whether the register chosen must be better than the
370 current one or just respect the given constraint. */
371
372int
373find_rename_reg (du_head_p this_head, enum reg_class super_class,
374 HARD_REG_SET *unavailable, int old_reg, bool best_rename)
375{
376 bool has_preferred_class;
377 enum reg_class preferred_class;
378 int pass;
379 int best_new_reg = old_reg;
380
381 /* Mark registers that overlap this chain's lifetime as unavailable. */
382 merge_overlapping_regs (pset: unavailable, head: this_head);
383
384 /* Compute preferred rename class of super union of all the classes
385 in the chain. */
386 preferred_class
387 = (enum reg_class) targetm.preferred_rename_class (super_class);
388
389 /* Pick and check the register from the tied chain iff the tied chain
390 is not renamed. */
391 if (this_head->tied_chain && !this_head->tied_chain->renamed
392 && check_new_reg_p (reg: old_reg, new_reg: this_head->tied_chain->regno,
393 this_head, this_unavailable: *unavailable))
394 return this_head->tied_chain->regno;
395
396 /* If the first non-debug insn is a noop move, then do not rename in this
397 chain as doing so would inhibit removal of the noop move. */
398 for (struct du_chain *tmp = this_head->first; tmp; tmp = tmp->next_use)
399 if (DEBUG_INSN_P (tmp->insn))
400 continue;
401 else if (noop_move_p (tmp->insn))
402 return best_new_reg;
403 else
404 break;
405
406 /* If PREFERRED_CLASS is not NO_REGS, we iterate in the first pass
407 over registers that belong to PREFERRED_CLASS and try to find the
408 best register within the class. If that failed, we iterate in
409 the second pass over registers that don't belong to the class.
410 If PREFERRED_CLASS is NO_REGS, we iterate over all registers in
411 ascending order without any preference. */
412 has_preferred_class = (preferred_class != NO_REGS);
413 for (pass = (has_preferred_class ? 0 : 1); pass < 2; pass++)
414 {
415 int new_reg;
416 for (new_reg = 0; new_reg < FIRST_PSEUDO_REGISTER; new_reg++)
417 {
418 if (has_preferred_class
419 && (pass == 0)
420 != TEST_HARD_REG_BIT (reg_class_contents[preferred_class],
421 bit: new_reg))
422 continue;
423
424 if (!check_new_reg_p (reg: old_reg, new_reg, this_head, this_unavailable: *unavailable))
425 continue;
426
427 if (!best_rename)
428 return new_reg;
429
430 /* In the first pass, we force the renaming of registers that
431 don't belong to PREFERRED_CLASS to registers that do, even
432 though the latters were used not very long ago. */
433 if ((pass == 0
434 && !TEST_HARD_REG_BIT (reg_class_contents[preferred_class],
435 bit: best_new_reg))
436 || tick[best_new_reg] > tick[new_reg])
437 best_new_reg = new_reg;
438 }
439 if (pass == 0 && best_new_reg != old_reg)
440 break;
441 }
442 return best_new_reg;
443}
444
445/* Iterate over elements in the chain HEAD in order to:
446 1. Count number of uses, storing it in *PN_USES.
447 2. Narrow the set of registers we can use for renaming, adding
448 unavailable registers to *PUNAVAILABLE, which must be
449 initialized by the caller.
450 3. Compute the superunion of register classes in this chain
451 and return it. */
452reg_class
453regrename_find_superclass (du_head_p head, int *pn_uses,
454 HARD_REG_SET *punavailable)
455{
456 int n_uses = 0;
457 reg_class super_class = NO_REGS;
458 for (du_chain *tmp = head->first; tmp; tmp = tmp->next_use)
459 {
460 if (DEBUG_INSN_P (tmp->insn))
461 continue;
462 n_uses++;
463 *punavailable |= ~reg_class_contents[tmp->cl];
464 super_class
465 = reg_class_superunion[(int) super_class][(int) tmp->cl];
466 }
467 *pn_uses = n_uses;
468 return super_class;
469}
470
471/* Perform register renaming on the current function. */
472static void
473rename_chains (void)
474{
475 HARD_REG_SET unavailable;
476 du_head_p this_head;
477 int i;
478
479 memset (s: tick, c: 0, n: sizeof tick);
480
481 CLEAR_HARD_REG_SET (set&: unavailable);
482 /* Don't clobber traceback for noreturn functions. */
483 if (frame_pointer_needed)
484 {
485 add_to_hard_reg_set (regs: &unavailable, Pmode, FRAME_POINTER_REGNUM);
486 if (!HARD_FRAME_POINTER_IS_FRAME_POINTER)
487 add_to_hard_reg_set (regs: &unavailable, Pmode, HARD_FRAME_POINTER_REGNUM);
488 }
489
490 FOR_EACH_VEC_ELT (id_to_chain, i, this_head)
491 {
492 int best_new_reg;
493 int n_uses;
494 HARD_REG_SET this_unavailable;
495 int reg = this_head->regno;
496
497 if (this_head->cannot_rename)
498 continue;
499
500 if (fixed_regs[reg] || global_regs[reg]
501 || (!HARD_FRAME_POINTER_IS_FRAME_POINTER && frame_pointer_needed
502 && reg == HARD_FRAME_POINTER_REGNUM)
503 || (HARD_FRAME_POINTER_IS_FRAME_POINTER && frame_pointer_needed
504 && reg == FRAME_POINTER_REGNUM))
505 continue;
506
507 this_unavailable = unavailable;
508
509 reg_class super_class = regrename_find_superclass (head: this_head, pn_uses: &n_uses,
510 punavailable: &this_unavailable);
511 if (n_uses < 2)
512 continue;
513
514 best_new_reg = find_rename_reg (this_head, super_class,
515 unavailable: &this_unavailable, old_reg: reg, best_rename: true);
516
517 if (dump_file)
518 {
519 fprintf (stream: dump_file, format: "Register %s in insn %d",
520 reg_names[reg], INSN_UID (insn: this_head->first->insn));
521 if (this_head->call_abis)
522 fprintf (stream: dump_file, format: " crosses a call");
523 }
524
525 if (best_new_reg == reg)
526 {
527 tick[reg] = ++this_tick;
528 if (dump_file)
529 fprintf (stream: dump_file, format: "; no available better choice\n");
530 continue;
531 }
532
533 if (regrename_do_replace (this_head, best_new_reg))
534 {
535 if (dump_file)
536 fprintf (stream: dump_file, format: ", renamed as %s\n", reg_names[best_new_reg]);
537 tick[best_new_reg] = ++this_tick;
538 df_set_regs_ever_live (best_new_reg, true);
539 }
540 else
541 {
542 if (dump_file)
543 fprintf (stream: dump_file, format: ", renaming as %s failed\n",
544 reg_names[best_new_reg]);
545 tick[reg] = ++this_tick;
546 }
547 }
548}
549
550/* A structure to record information for each hard register at the start of
551 a basic block. */
552struct incoming_reg_info {
553 /* Holds the number of registers used in the chain that gave us information
554 about this register. Zero means no information known yet, while a
555 negative value is used for something that is part of, but not the first
556 register in a multi-register value. */
557 int nregs;
558 /* Set to true if we have accesses that conflict in the number of registers
559 used. */
560 bool unusable;
561};
562
563/* A structure recording information about each basic block. It is saved
564 and restored around basic block boundaries.
565 A pointer to such a structure is stored in each basic block's aux field
566 during regrename_analyze, except for blocks we know can't be optimized
567 (such as entry and exit blocks). */
568class bb_rename_info
569{
570public:
571 /* The basic block corresponding to this structure. */
572 basic_block bb;
573 /* Copies of the global information. */
574 bitmap_head open_chains_set;
575 bitmap_head incoming_open_chains_set;
576 struct incoming_reg_info incoming[FIRST_PSEUDO_REGISTER];
577};
578
579/* Initialize a rename_info structure P for basic block BB, which starts a new
580 scan. */
581static void
582init_rename_info (class bb_rename_info *p, basic_block bb)
583{
584 int i;
585 df_ref def;
586 HARD_REG_SET start_chains_set;
587
588 p->bb = bb;
589 bitmap_initialize (head: &p->open_chains_set, obstack: &bitmap_default_obstack);
590 bitmap_initialize (head: &p->incoming_open_chains_set, obstack: &bitmap_default_obstack);
591
592 open_chains = NULL;
593 bitmap_clear (&open_chains_set);
594
595 CLEAR_HARD_REG_SET (set&: live_in_chains);
596 REG_SET_TO_HARD_REG_SET (live_hard_regs, df_get_live_in (bb));
597 FOR_EACH_ARTIFICIAL_DEF (def, bb->index)
598 if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
599 SET_HARD_REG_BIT (set&: live_hard_regs, DF_REF_REGNO (def));
600
601 /* Open chains based on information from (at least one) predecessor
602 block. This gives us a chance later on to combine chains across
603 basic block boundaries. Inconsistencies (in access sizes) will
604 be caught normally and dealt with conservatively by disabling the
605 chain for renaming, and there is no risk of losing optimization
606 opportunities by opening chains either: if we did not open the
607 chains, we'd have to track the live register as a hard reg, and
608 we'd be unable to rename it in any case. */
609 CLEAR_HARD_REG_SET (set&: start_chains_set);
610 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
611 {
612 struct incoming_reg_info *iri = p->incoming + i;
613 if (iri->nregs > 0 && !iri->unusable
614 && range_in_hard_reg_set_p (set: live_hard_regs, regno: i, nregs: iri->nregs))
615 {
616 SET_HARD_REG_BIT (set&: start_chains_set, bit: i);
617 remove_range_from_hard_reg_set (regs: &live_hard_regs, regno: i, nregs: iri->nregs);
618 }
619 }
620 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
621 {
622 struct incoming_reg_info *iri = p->incoming + i;
623 if (TEST_HARD_REG_BIT (set: start_chains_set, bit: i))
624 {
625 du_head_p chain;
626 if (dump_file)
627 fprintf (stream: dump_file, format: "opening incoming chain\n");
628 chain = create_new_chain (this_regno: i, this_nregs: iri->nregs, NULL, NULL, cl: NO_REGS);
629 bitmap_set_bit (&p->incoming_open_chains_set, chain->id);
630 }
631 }
632}
633
634/* Record in RI that the block corresponding to it has an incoming
635 live value, described by CHAIN. */
636static void
637set_incoming_from_chain (class bb_rename_info *ri, du_head_p chain)
638{
639 int i;
640 int incoming_nregs = ri->incoming[chain->regno].nregs;
641 int nregs;
642
643 /* If we've recorded the same information before, everything is fine. */
644 if (incoming_nregs == chain->nregs)
645 {
646 if (dump_file)
647 fprintf (stream: dump_file, format: "reg %d/%d already recorded\n",
648 chain->regno, chain->nregs);
649 return;
650 }
651
652 /* If we have no information for any of the involved registers, update
653 the incoming array. */
654 nregs = chain->nregs;
655 while (nregs-- > 0)
656 if (ri->incoming[chain->regno + nregs].nregs != 0
657 || ri->incoming[chain->regno + nregs].unusable)
658 break;
659 if (nregs < 0)
660 {
661 nregs = chain->nregs;
662 ri->incoming[chain->regno].nregs = nregs;
663 while (nregs-- > 1)
664 ri->incoming[chain->regno + nregs].nregs = -nregs;
665 if (dump_file)
666 fprintf (stream: dump_file, format: "recorded reg %d/%d\n",
667 chain->regno, chain->nregs);
668 return;
669 }
670
671 /* There must be some kind of conflict. Prevent both the old and
672 new ranges from being used. */
673 if (incoming_nregs < 0)
674 ri->incoming[chain->regno + incoming_nregs].unusable = true;
675 for (i = 0; i < chain->nregs; i++)
676 ri->incoming[chain->regno + i].unusable = true;
677}
678
679/* Merge the two chains C1 and C2 so that all conflict information is
680 recorded and C1, and the id of C2 is changed to that of C1. */
681static void
682merge_chains (du_head_p c1, du_head_p c2)
683{
684 if (c1 == c2)
685 return;
686
687 if (c2->first != NULL)
688 {
689 if (c1->first == NULL)
690 c1->first = c2->first;
691 else
692 c1->last->next_use = c2->first;
693 c1->last = c2->last;
694 }
695
696 c2->first = c2->last = NULL;
697 c2->id = c1->id;
698
699 c1->hard_conflicts |= c2->hard_conflicts;
700 bitmap_ior_into (&c1->conflicts, &c2->conflicts);
701
702 c1->call_clobber_mask |= c2->call_clobber_mask;
703 c1->call_abis |= c2->call_abis;
704 c1->cannot_rename |= c2->cannot_rename;
705}
706
707/* Analyze the current function and build chains for renaming.
708 If INCLUDE_ALL_BLOCKS_P is set to true, process all blocks,
709 ignoring BB_DISABLE_SCHEDULE. The default value is true. */
710
711void
712regrename_analyze (bitmap bb_mask, bool include_all_block_p)
713{
714 class bb_rename_info *rename_info;
715 int i;
716 basic_block bb;
717 int n_bbs;
718 int *inverse_postorder;
719
720 inverse_postorder = XNEWVEC (int, last_basic_block_for_fn (cfun));
721 n_bbs = pre_and_rev_post_order_compute (NULL, inverse_postorder, false);
722
723 /* Gather some information about the blocks in this function. */
724 rename_info = XCNEWVEC (class bb_rename_info, n_basic_blocks_for_fn (cfun));
725 i = 0;
726 FOR_EACH_BB_FN (bb, cfun)
727 {
728 class bb_rename_info *ri = rename_info + i;
729 ri->bb = bb;
730 if (bb_mask != NULL && !bitmap_bit_p (bb_mask, bb->index))
731 bb->aux = NULL;
732 else
733 bb->aux = ri;
734 i++;
735 }
736
737 current_id = 0;
738 id_to_chain.create (nelems: 0);
739 bitmap_initialize (head: &open_chains_set, obstack: &bitmap_default_obstack);
740
741 /* The order in which we visit blocks ensures that whenever
742 possible, we only process a block after at least one of its
743 predecessors, which provides a "seeding" effect to make the logic
744 in set_incoming_from_chain and init_rename_info useful. */
745
746 for (i = 0; i < n_bbs; i++)
747 {
748 basic_block bb1 = BASIC_BLOCK_FOR_FN (cfun, inverse_postorder[i]);
749 class bb_rename_info *this_info;
750 bool success;
751 edge e;
752 edge_iterator ei;
753 int old_length = id_to_chain.length ();
754
755 this_info = (class bb_rename_info *) bb1->aux;
756 if (this_info == NULL)
757 continue;
758
759 if (dump_file)
760 fprintf (stream: dump_file, format: "\nprocessing block %d:\n", bb1->index);
761
762 if (!include_all_block_p && (bb1->flags & BB_DISABLE_SCHEDULE) != 0)
763 {
764 if (dump_file)
765 fprintf (stream: dump_file, format: "avoid disrupting the sms schedule of bb %d\n",
766 bb1->index);
767 continue;
768 }
769
770 init_rename_info (p: this_info, bb: bb1);
771
772 success = build_def_use (bb1);
773 if (!success)
774 {
775 if (dump_file)
776 fprintf (stream: dump_file, format: "failed\n");
777 bb1->aux = NULL;
778 id_to_chain.truncate (size: old_length);
779 current_id = old_length;
780 bitmap_clear (&this_info->incoming_open_chains_set);
781 open_chains = NULL;
782 if (insn_rr.exists ())
783 {
784 rtx_insn *insn;
785 FOR_BB_INSNS (bb1, insn)
786 {
787 insn_rr_info *p = &insn_rr[INSN_UID (insn)];
788 p->op_info = NULL;
789 }
790 }
791 continue;
792 }
793
794 if (dump_file)
795 dump_def_use_chain (from: old_length);
796 bitmap_copy (&this_info->open_chains_set, &open_chains_set);
797
798 /* Add successor blocks to the worklist if necessary, and record
799 data about our own open chains at the end of this block, which
800 will be used to pre-open chains when processing the successors. */
801 FOR_EACH_EDGE (e, ei, bb1->succs)
802 {
803 class bb_rename_info *dest_ri;
804 class du_head *chain;
805
806 if (dump_file)
807 fprintf (stream: dump_file, format: "successor block %d\n", e->dest->index);
808
809 if (e->flags & (EDGE_EH | EDGE_ABNORMAL))
810 continue;
811 dest_ri = (class bb_rename_info *)e->dest->aux;
812 if (dest_ri == NULL)
813 continue;
814 for (chain = open_chains; chain; chain = chain->next_chain)
815 set_incoming_from_chain (ri: dest_ri, chain);
816 }
817 }
818
819 free (ptr: inverse_postorder);
820
821 /* Now, combine the chains data we have gathered across basic block
822 boundaries.
823
824 For every basic block, there may be chains open at the start, or at the
825 end. Rather than exclude them from renaming, we look for open chains
826 with matching registers at the other side of the CFG edge.
827
828 For a given chain using register R, open at the start of block B, we
829 must find an open chain using R on the other side of every edge leading
830 to B, if the register is live across this edge. In the code below,
831 N_PREDS_USED counts the number of edges where the register is live, and
832 N_PREDS_JOINED counts those where we found an appropriate chain for
833 joining.
834
835 We perform the analysis for both incoming and outgoing edges, but we
836 only need to merge once (in the second part, after verifying outgoing
837 edges). */
838 FOR_EACH_BB_FN (bb, cfun)
839 {
840 class bb_rename_info *bb_ri = (class bb_rename_info *) bb->aux;
841 unsigned j;
842 bitmap_iterator bi;
843
844 if (bb_ri == NULL)
845 continue;
846
847 if (dump_file)
848 fprintf (stream: dump_file, format: "processing bb %d in edges\n", bb->index);
849
850 EXECUTE_IF_SET_IN_BITMAP (&bb_ri->incoming_open_chains_set, 0, j, bi)
851 {
852 edge e;
853 edge_iterator ei;
854 class du_head *chain = regrename_chain_from_id (id: j);
855 int n_preds_used = 0, n_preds_joined = 0;
856
857 FOR_EACH_EDGE (e, ei, bb->preds)
858 {
859 class bb_rename_info *src_ri;
860 unsigned k;
861 bitmap_iterator bi2;
862 HARD_REG_SET live;
863 bool success = false;
864
865 REG_SET_TO_HARD_REG_SET (live, df_get_live_out (e->src));
866 if (!range_overlaps_hard_reg_set_p (set: live, regno: chain->regno,
867 nregs: chain->nregs))
868 continue;
869 n_preds_used++;
870
871 if (e->flags & (EDGE_EH | EDGE_ABNORMAL))
872 continue;
873
874 src_ri = (class bb_rename_info *)e->src->aux;
875 if (src_ri == NULL)
876 continue;
877
878 EXECUTE_IF_SET_IN_BITMAP (&src_ri->open_chains_set,
879 0, k, bi2)
880 {
881 class du_head *outgoing_chain = regrename_chain_from_id (id: k);
882
883 if (outgoing_chain->regno == chain->regno
884 && outgoing_chain->nregs == chain->nregs)
885 {
886 n_preds_joined++;
887 success = true;
888 break;
889 }
890 }
891 if (!success && dump_file)
892 fprintf (stream: dump_file, format: "failure to match with pred block %d\n",
893 e->src->index);
894 }
895 if (n_preds_joined < n_preds_used)
896 {
897 if (dump_file)
898 fprintf (stream: dump_file, format: "cannot rename chain %d\n", j);
899 chain->cannot_rename = 1;
900 }
901 }
902 }
903 FOR_EACH_BB_FN (bb, cfun)
904 {
905 class bb_rename_info *bb_ri = (class bb_rename_info *) bb->aux;
906 unsigned j;
907 bitmap_iterator bi;
908
909 if (bb_ri == NULL)
910 continue;
911
912 if (dump_file)
913 fprintf (stream: dump_file, format: "processing bb %d out edges\n", bb->index);
914
915 EXECUTE_IF_SET_IN_BITMAP (&bb_ri->open_chains_set, 0, j, bi)
916 {
917 edge e;
918 edge_iterator ei;
919 class du_head *chain = regrename_chain_from_id (id: j);
920 int n_succs_used = 0, n_succs_joined = 0;
921
922 FOR_EACH_EDGE (e, ei, bb->succs)
923 {
924 bool printed = false;
925 class bb_rename_info *dest_ri;
926 unsigned k;
927 bitmap_iterator bi2;
928 HARD_REG_SET live;
929
930 REG_SET_TO_HARD_REG_SET (live, df_get_live_in (e->dest));
931 if (!range_overlaps_hard_reg_set_p (set: live, regno: chain->regno,
932 nregs: chain->nregs))
933 continue;
934
935 n_succs_used++;
936
937 dest_ri = (class bb_rename_info *)e->dest->aux;
938 if (dest_ri == NULL)
939 continue;
940
941 EXECUTE_IF_SET_IN_BITMAP (&dest_ri->incoming_open_chains_set,
942 0, k, bi2)
943 {
944 class du_head *incoming_chain = regrename_chain_from_id (id: k);
945
946 if (incoming_chain->regno == chain->regno
947 && incoming_chain->nregs == chain->nregs)
948 {
949 if (dump_file)
950 {
951 if (!printed)
952 fprintf (stream: dump_file,
953 format: "merging blocks for edge %d -> %d\n",
954 e->src->index, e->dest->index);
955 printed = true;
956 fprintf (stream: dump_file,
957 format: " merging chains %d (->%d) and %d (->%d) [%s]\n",
958 k, incoming_chain->id, j, chain->id,
959 reg_names[incoming_chain->regno]);
960 }
961
962 merge_chains (c1: chain, c2: incoming_chain);
963 n_succs_joined++;
964 break;
965 }
966 }
967 }
968 if (n_succs_joined < n_succs_used)
969 {
970 if (dump_file)
971 fprintf (stream: dump_file, format: "cannot rename chain %d\n",
972 j);
973 chain->cannot_rename = 1;
974 }
975 }
976 }
977
978 free (ptr: rename_info);
979
980 FOR_EACH_BB_FN (bb, cfun)
981 bb->aux = NULL;
982}
983
984/* Attempt to replace all uses of the register in the chain beginning with
985 HEAD with REG. Returns true on success and false if the replacement is
986 rejected because the insns would not validate. The latter can happen
987 e.g. if a match_parallel predicate enforces restrictions on register
988 numbering in its subpatterns. */
989
990bool
991regrename_do_replace (class du_head *head, int reg)
992{
993 struct du_chain *chain;
994 unsigned int base_regno = head->regno;
995 machine_mode mode;
996 rtx last_reg = NULL_RTX, last_repl = NULL_RTX;
997
998 for (chain = head->first; chain; chain = chain->next_use)
999 {
1000 unsigned int regno = ORIGINAL_REGNO (*chain->loc);
1001 class reg_attrs *attr = REG_ATTRS (*chain->loc);
1002 int reg_ptr = REG_POINTER (*chain->loc);
1003
1004 if (DEBUG_INSN_P (chain->insn) && REGNO (*chain->loc) != base_regno)
1005 validate_change (chain->insn, &(INSN_VAR_LOCATION_LOC (chain->insn)),
1006 gen_rtx_UNKNOWN_VAR_LOC (), true);
1007 else
1008 {
1009 if (*chain->loc != last_reg)
1010 {
1011 last_repl = gen_raw_REG (GET_MODE (*chain->loc), reg);
1012 if (regno >= FIRST_PSEUDO_REGISTER)
1013 ORIGINAL_REGNO (last_repl) = regno;
1014 REG_ATTRS (last_repl) = attr;
1015 REG_POINTER (last_repl) = reg_ptr;
1016 last_reg = *chain->loc;
1017 }
1018 validate_change (chain->insn, chain->loc, last_repl, true);
1019 }
1020 }
1021
1022 if (!apply_change_group ())
1023 return false;
1024
1025 mode = GET_MODE (*head->first->loc);
1026 head->renamed = 1;
1027 head->regno = reg;
1028 head->nregs = hard_regno_nregs (regno: reg, mode);
1029 return true;
1030}
1031
1032
1033/* True if we found a register with a size mismatch, which means that we
1034 can't track its lifetime accurately. If so, we abort the current block
1035 without renaming. */
1036static bool fail_current_block;
1037
1038/* Return true if OP is a reg for which all bits are set in PSET, false
1039 if all bits are clear.
1040 In other cases, set fail_current_block and return false. */
1041
1042static bool
1043verify_reg_in_set (rtx op, HARD_REG_SET *pset)
1044{
1045 unsigned regno, nregs;
1046 bool all_live, all_dead;
1047 if (!REG_P (op))
1048 return false;
1049
1050 regno = REGNO (op);
1051 nregs = REG_NREGS (op);
1052 all_live = all_dead = true;
1053 while (nregs-- > 0)
1054 if (TEST_HARD_REG_BIT (set: *pset, bit: regno + nregs))
1055 all_dead = false;
1056 else
1057 all_live = false;
1058 if (!all_dead && !all_live)
1059 {
1060 fail_current_block = true;
1061 return false;
1062 }
1063 return all_live;
1064}
1065
1066/* Return true if OP is a reg that is being tracked already in some form.
1067 May set fail_current_block if it sees an unhandled case of overlap. */
1068
1069static bool
1070verify_reg_tracked (rtx op)
1071{
1072 return (verify_reg_in_set (op, pset: &live_hard_regs)
1073 || verify_reg_in_set (op, pset: &live_in_chains));
1074}
1075
1076/* Called through note_stores. DATA points to a rtx_code, either SET or
1077 CLOBBER, which tells us which kind of rtx to look at. If we have a
1078 match, record the set register in live_hard_regs and in the hard_conflicts
1079 bitmap of open chains. */
1080
1081static void
1082note_sets_clobbers (rtx x, const_rtx set, void *data)
1083{
1084 enum rtx_code code = *(enum rtx_code *)data;
1085 class du_head *chain;
1086
1087 if (GET_CODE (x) == SUBREG)
1088 x = SUBREG_REG (x);
1089 if (!REG_P (x) || GET_CODE (set) != code)
1090 return;
1091 /* There must not be pseudos at this point. */
1092 gcc_assert (HARD_REGISTER_P (x));
1093 add_to_hard_reg_set (regs: &live_hard_regs, GET_MODE (x), REGNO (x));
1094 for (chain = open_chains; chain; chain = chain->next_chain)
1095 add_to_hard_reg_set (regs: &chain->hard_conflicts, GET_MODE (x), REGNO (x));
1096}
1097
1098static void
1099scan_rtx_reg (rtx_insn *insn, rtx *loc, enum reg_class cl, enum scan_actions action,
1100 enum op_type type)
1101{
1102 class du_head **p;
1103 rtx x = *loc;
1104 unsigned this_regno = REGNO (x);
1105 int this_nregs = REG_NREGS (x);
1106
1107 if (action == mark_write)
1108 {
1109 if (type == OP_OUT)
1110 {
1111 du_head_p c;
1112 rtx pat = PATTERN (insn);
1113
1114 c = create_new_chain (this_regno, this_nregs, loc, insn, cl);
1115
1116 /* We try to tie chains in a move instruction for
1117 a single output. */
1118 if (recog_data.n_operands == 2
1119 && GET_CODE (pat) == SET
1120 && GET_CODE (SET_DEST (pat)) == REG
1121 && GET_CODE (SET_SRC (pat)) == REG
1122 && terminated_this_insn
1123 && terminated_this_insn->nregs
1124 == REG_NREGS (recog_data.operand[1]))
1125 {
1126 gcc_assert (terminated_this_insn->regno
1127 == REGNO (recog_data.operand[1]));
1128
1129 c->tied_chain = terminated_this_insn;
1130 terminated_this_insn->tied_chain = c;
1131
1132 if (dump_file)
1133 fprintf (stream: dump_file, format: "Tying chain %s (%d) with %s (%d)\n",
1134 reg_names[c->regno], c->id,
1135 reg_names[terminated_this_insn->regno],
1136 terminated_this_insn->id);
1137 }
1138 }
1139
1140 return;
1141 }
1142
1143 if ((type == OP_OUT) != (action == terminate_write || action == mark_access))
1144 return;
1145
1146 for (p = &open_chains; *p;)
1147 {
1148 class du_head *head = *p;
1149 class du_head *next = head->next_chain;
1150 int exact_match = (head->regno == this_regno
1151 && head->nregs == this_nregs);
1152 int superset = (this_regno <= head->regno
1153 && this_regno + this_nregs >= head->regno + head->nregs);
1154 int subset = (this_regno >= head->regno
1155 && this_regno + this_nregs <= head->regno + head->nregs);
1156
1157 if (!bitmap_bit_p (&open_chains_set, head->id)
1158 || head->regno + head->nregs <= this_regno
1159 || this_regno + this_nregs <= head->regno)
1160 {
1161 p = &head->next_chain;
1162 continue;
1163 }
1164
1165 if (action == mark_read || action == mark_access)
1166 {
1167 /* ??? Class NO_REGS can happen if the md file makes use of
1168 EXTRA_CONSTRAINTS to match registers. Which is arguably
1169 wrong, but there we are. */
1170
1171 if (cl == NO_REGS || (!exact_match && !DEBUG_INSN_P (insn)))
1172 {
1173 if (dump_file)
1174 fprintf (stream: dump_file,
1175 format: "Cannot rename chain %s (%d) at insn %d (%s)\n",
1176 reg_names[head->regno], head->id, INSN_UID (insn),
1177 scan_actions_name[(int) action]);
1178 head->cannot_rename = 1;
1179 if (superset)
1180 {
1181 unsigned nregs = this_nregs;
1182 head->regno = this_regno;
1183 head->nregs = this_nregs;
1184 while (nregs-- > 0)
1185 SET_HARD_REG_BIT (set&: live_in_chains, bit: head->regno + nregs);
1186 if (dump_file)
1187 fprintf (stream: dump_file,
1188 format: "Widening register in chain %s (%d) at insn %d\n",
1189 reg_names[head->regno], head->id, INSN_UID (insn));
1190 }
1191 else if (!subset)
1192 {
1193 fail_current_block = true;
1194 if (dump_file)
1195 fprintf (stream: dump_file,
1196 format: "Failing basic block due to unhandled overlap\n");
1197 }
1198 }
1199 else
1200 {
1201 struct du_chain *this_du;
1202 this_du = XOBNEW (&rename_obstack, struct du_chain);
1203 this_du->next_use = 0;
1204 this_du->loc = loc;
1205 this_du->insn = insn;
1206 this_du->cl = cl;
1207 if (head->first == NULL)
1208 head->first = this_du;
1209 else
1210 head->last->next_use = this_du;
1211 record_operand_use (head, this_du);
1212 head->last = this_du;
1213 }
1214 /* Avoid adding the same location in a DEBUG_INSN multiple times,
1215 which could happen with non-exact overlap. */
1216 if (DEBUG_INSN_P (insn))
1217 return;
1218 /* Otherwise, find any other chains that do not match exactly;
1219 ensure they all get marked unrenamable. */
1220 p = &head->next_chain;
1221 continue;
1222 }
1223
1224 /* Whether the terminated chain can be used for renaming
1225 depends on the action and this being an exact match.
1226 In either case, we remove this element from open_chains. */
1227
1228 if ((action == terminate_dead || action == terminate_write)
1229 && (superset || subset))
1230 {
1231 unsigned nregs;
1232
1233 if (subset && !superset)
1234 head->cannot_rename = 1;
1235 bitmap_clear_bit (&open_chains_set, head->id);
1236
1237 nregs = head->nregs;
1238 while (nregs-- > 0)
1239 {
1240 CLEAR_HARD_REG_BIT (set&: live_in_chains, bit: head->regno + nregs);
1241 if (subset && !superset
1242 && (head->regno + nregs < this_regno
1243 || head->regno + nregs >= this_regno + this_nregs))
1244 SET_HARD_REG_BIT (set&: live_hard_regs, bit: head->regno + nregs);
1245 }
1246
1247 if (action == terminate_dead)
1248 terminated_this_insn = *p;
1249 *p = next;
1250 if (dump_file)
1251 fprintf (stream: dump_file,
1252 format: "Closing chain %s (%d) at insn %d (%s%s)\n",
1253 reg_names[head->regno], head->id, INSN_UID (insn),
1254 scan_actions_name[(int) action],
1255 superset ? ", superset" : subset ? ", subset" : "");
1256 }
1257 else if (action == terminate_dead || action == terminate_write)
1258 {
1259 /* In this case, tracking liveness gets too hard. Fail the
1260 entire basic block. */
1261 if (dump_file)
1262 fprintf (stream: dump_file,
1263 format: "Failing basic block due to unhandled overlap\n");
1264 fail_current_block = true;
1265 return;
1266 }
1267 else
1268 {
1269 head->cannot_rename = 1;
1270 if (dump_file)
1271 fprintf (stream: dump_file,
1272 format: "Cannot rename chain %s (%d) at insn %d (%s)\n",
1273 reg_names[head->regno], head->id, INSN_UID (insn),
1274 scan_actions_name[(int) action]);
1275 p = &head->next_chain;
1276 }
1277 }
1278}
1279
1280/* A wrapper around base_reg_class which returns ALL_REGS if INSN is a
1281 DEBUG_INSN. The arguments MODE, AS, CODE and INDEX_CODE are as for
1282 base_reg_class. */
1283
1284static reg_class
1285base_reg_class_for_rename (rtx_insn *insn, machine_mode mode, addr_space_t as,
1286 rtx_code code, rtx_code index_code)
1287{
1288 if (DEBUG_INSN_P (insn))
1289 return ALL_REGS;
1290 return base_reg_class (mode, as, outer_code: code, index_code);
1291}
1292
1293/* Adapted from find_reloads_address_1. CL is INDEX_REG_CLASS or
1294 BASE_REG_CLASS depending on how the register is being considered. */
1295
1296static void
1297scan_rtx_address (rtx_insn *insn, rtx *loc, enum reg_class cl,
1298 enum scan_actions action, machine_mode mode,
1299 addr_space_t as)
1300{
1301 rtx x = *loc;
1302 RTX_CODE code = GET_CODE (x);
1303 const char *fmt;
1304 int i, j;
1305
1306 if (action == mark_write || action == mark_access)
1307 return;
1308
1309 switch (code)
1310 {
1311 case PLUS:
1312 {
1313 rtx orig_op0 = XEXP (x, 0);
1314 rtx orig_op1 = XEXP (x, 1);
1315 RTX_CODE code0 = GET_CODE (orig_op0);
1316 RTX_CODE code1 = GET_CODE (orig_op1);
1317 rtx op0 = orig_op0;
1318 rtx op1 = orig_op1;
1319 rtx *locI = NULL;
1320 rtx *locB = NULL;
1321 enum rtx_code index_code = SCRATCH;
1322
1323 if (GET_CODE (op0) == SUBREG)
1324 {
1325 op0 = SUBREG_REG (op0);
1326 code0 = GET_CODE (op0);
1327 }
1328
1329 if (GET_CODE (op1) == SUBREG)
1330 {
1331 op1 = SUBREG_REG (op1);
1332 code1 = GET_CODE (op1);
1333 }
1334
1335 if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE
1336 || code0 == ZERO_EXTEND || code1 == MEM)
1337 {
1338 locI = &XEXP (x, 0);
1339 locB = &XEXP (x, 1);
1340 index_code = GET_CODE (*locI);
1341 }
1342 else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
1343 || code1 == ZERO_EXTEND || code0 == MEM)
1344 {
1345 locI = &XEXP (x, 1);
1346 locB = &XEXP (x, 0);
1347 index_code = GET_CODE (*locI);
1348 }
1349 else if (code0 == CONST_INT || code0 == CONST
1350 || code0 == SYMBOL_REF || code0 == LABEL_REF)
1351 {
1352 locB = &XEXP (x, 1);
1353 index_code = GET_CODE (XEXP (x, 0));
1354 }
1355 else if (code1 == CONST_INT || code1 == CONST
1356 || code1 == SYMBOL_REF || code1 == LABEL_REF)
1357 {
1358 locB = &XEXP (x, 0);
1359 index_code = GET_CODE (XEXP (x, 1));
1360 }
1361 else if (code0 == REG && code1 == REG)
1362 {
1363 int index_op;
1364 unsigned regno0 = REGNO (op0), regno1 = REGNO (op1);
1365
1366 if (REGNO_OK_FOR_INDEX_P (regno1)
1367 && regno_ok_for_base_p (regno: regno0, mode, as, outer_code: PLUS, index_code: REG))
1368 index_op = 1;
1369 else if (REGNO_OK_FOR_INDEX_P (regno0)
1370 && regno_ok_for_base_p (regno: regno1, mode, as, outer_code: PLUS, index_code: REG))
1371 index_op = 0;
1372 else if (regno_ok_for_base_p (regno: regno0, mode, as, outer_code: PLUS, index_code: REG)
1373 || REGNO_OK_FOR_INDEX_P (regno1))
1374 index_op = 1;
1375 else if (regno_ok_for_base_p (regno: regno1, mode, as, outer_code: PLUS, index_code: REG))
1376 index_op = 0;
1377 else
1378 index_op = 1;
1379
1380 locI = &XEXP (x, index_op);
1381 locB = &XEXP (x, !index_op);
1382 index_code = GET_CODE (*locI);
1383 }
1384 else if (code0 == REG)
1385 {
1386 locI = &XEXP (x, 0);
1387 locB = &XEXP (x, 1);
1388 index_code = GET_CODE (*locI);
1389 }
1390 else if (code1 == REG)
1391 {
1392 locI = &XEXP (x, 1);
1393 locB = &XEXP (x, 0);
1394 index_code = GET_CODE (*locI);
1395 }
1396
1397 if (locI)
1398 {
1399 reg_class iclass = DEBUG_INSN_P (insn) ? ALL_REGS : INDEX_REG_CLASS;
1400 scan_rtx_address (insn, loc: locI, cl: iclass, action, mode, as);
1401 }
1402 if (locB)
1403 {
1404 reg_class bclass = base_reg_class_for_rename (insn, mode, as, code: PLUS,
1405 index_code);
1406 scan_rtx_address (insn, loc: locB, cl: bclass, action, mode, as);
1407 }
1408 return;
1409 }
1410
1411 case POST_INC:
1412 case POST_DEC:
1413 case POST_MODIFY:
1414 case PRE_INC:
1415 case PRE_DEC:
1416 case PRE_MODIFY:
1417 /* If the target doesn't claim to handle autoinc, this must be
1418 something special, like a stack push. Kill this chain. */
1419 if (!AUTO_INC_DEC)
1420 action = mark_all_read;
1421
1422 break;
1423
1424 case MEM:
1425 {
1426 reg_class bclass = base_reg_class_for_rename (insn, GET_MODE (x),
1427 MEM_ADDR_SPACE (x),
1428 code: MEM, index_code: SCRATCH);
1429 scan_rtx_address (insn, loc: &XEXP (x, 0), cl: bclass, action, GET_MODE (x),
1430 MEM_ADDR_SPACE (x));
1431 }
1432 return;
1433
1434 case REG:
1435 scan_rtx_reg (insn, loc, cl, action, type: OP_IN);
1436 return;
1437
1438 default:
1439 break;
1440 }
1441
1442 fmt = GET_RTX_FORMAT (code);
1443 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1444 {
1445 if (fmt[i] == 'e')
1446 scan_rtx_address (insn, loc: &XEXP (x, i), cl, action, mode, as);
1447 else if (fmt[i] == 'E')
1448 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1449 scan_rtx_address (insn, loc: &XVECEXP (x, i, j), cl, action, mode, as);
1450 }
1451}
1452
1453static void
1454scan_rtx (rtx_insn *insn, rtx *loc, enum reg_class cl, enum scan_actions action,
1455 enum op_type type)
1456{
1457 const char *fmt;
1458 rtx x = *loc;
1459 int i, j;
1460
1461 enum rtx_code code = GET_CODE (x);
1462 switch (code)
1463 {
1464 case CONST:
1465 CASE_CONST_ANY:
1466 case SYMBOL_REF:
1467 case LABEL_REF:
1468 case PC:
1469 return;
1470
1471 case REG:
1472 scan_rtx_reg (insn, loc, cl, action, type);
1473 return;
1474
1475 case MEM:
1476 {
1477 reg_class bclass = base_reg_class_for_rename (insn, GET_MODE (x),
1478 MEM_ADDR_SPACE (x),
1479 code: MEM, index_code: SCRATCH);
1480
1481 scan_rtx_address (insn, loc: &XEXP (x, 0), cl: bclass, action, GET_MODE (x),
1482 MEM_ADDR_SPACE (x));
1483 }
1484 return;
1485
1486 case SET:
1487 scan_rtx (insn, loc: &SET_SRC (x), cl, action, type: OP_IN);
1488 scan_rtx (insn, loc: &SET_DEST (x), cl, action,
1489 type: (GET_CODE (PATTERN (insn)) == COND_EXEC
1490 && verify_reg_tracked (SET_DEST (x))) ? OP_INOUT : OP_OUT);
1491 return;
1492
1493 case STRICT_LOW_PART:
1494 scan_rtx (insn, loc: &XEXP (x, 0), cl, action,
1495 type: verify_reg_tracked (XEXP (x, 0)) ? OP_INOUT : OP_OUT);
1496 return;
1497
1498 case ZERO_EXTRACT:
1499 case SIGN_EXTRACT:
1500 scan_rtx (insn, loc: &XEXP (x, 0), cl, action,
1501 type: (type == OP_IN ? OP_IN :
1502 verify_reg_tracked (XEXP (x, 0)) ? OP_INOUT : OP_OUT));
1503 scan_rtx (insn, loc: &XEXP (x, 1), cl, action, type: OP_IN);
1504 scan_rtx (insn, loc: &XEXP (x, 2), cl, action, type: OP_IN);
1505 return;
1506
1507 case POST_INC:
1508 case PRE_INC:
1509 case POST_DEC:
1510 case PRE_DEC:
1511 case POST_MODIFY:
1512 case PRE_MODIFY:
1513 /* Should only happen inside MEM. */
1514 gcc_unreachable ();
1515
1516 case CLOBBER:
1517 scan_rtx (insn, loc: &SET_DEST (x), cl, action,
1518 type: (GET_CODE (PATTERN (insn)) == COND_EXEC
1519 && verify_reg_tracked (SET_DEST (x))) ? OP_INOUT : OP_OUT);
1520 return;
1521
1522 case EXPR_LIST:
1523 scan_rtx (insn, loc: &XEXP (x, 0), cl, action, type);
1524 if (XEXP (x, 1))
1525 scan_rtx (insn, loc: &XEXP (x, 1), cl, action, type);
1526 return;
1527
1528 default:
1529 break;
1530 }
1531
1532 fmt = GET_RTX_FORMAT (code);
1533 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1534 {
1535 if (fmt[i] == 'e')
1536 scan_rtx (insn, loc: &XEXP (x, i), cl, action, type);
1537 else if (fmt[i] == 'E')
1538 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1539 scan_rtx (insn, loc: &XVECEXP (x, i, j), cl, action, type);
1540 }
1541}
1542
1543/* Hide operands of the current insn (of which there are N_OPS) by
1544 substituting pc for them.
1545 Previous values are stored in the OLD_OPERANDS and OLD_DUPS.
1546 For every bit set in DO_NOT_HIDE, we leave the operand alone.
1547 If INOUT_AND_EC_ONLY is set, we only do this for OP_INOUT type operands
1548 and earlyclobbers. */
1549
1550static void
1551hide_operands (int n_ops, rtx *old_operands, rtx *old_dups,
1552 unsigned HOST_WIDE_INT do_not_hide, bool inout_and_ec_only)
1553{
1554 int i;
1555 const operand_alternative *op_alt = which_op_alt ();
1556 for (i = 0; i < n_ops; i++)
1557 {
1558 old_operands[i] = recog_data.operand[i];
1559 /* Don't squash match_operator or match_parallel here, since
1560 we don't know that all of the contained registers are
1561 reachable by proper operands. */
1562 if (recog_data.constraints[i][0] == '\0')
1563 continue;
1564 if (do_not_hide & (1 << i))
1565 continue;
1566 if (!inout_and_ec_only || recog_data.operand_type[i] == OP_INOUT
1567 || op_alt[i].earlyclobber)
1568 *recog_data.operand_loc[i] = pc_rtx;
1569 }
1570 for (i = 0; i < recog_data.n_dups; i++)
1571 {
1572 int opn = recog_data.dup_num[i];
1573 old_dups[i] = *recog_data.dup_loc[i];
1574 if (do_not_hide & (1 << opn))
1575 continue;
1576 if (!inout_and_ec_only || recog_data.operand_type[opn] == OP_INOUT
1577 || op_alt[opn].earlyclobber)
1578 *recog_data.dup_loc[i] = pc_rtx;
1579 }
1580}
1581
1582/* Undo the substitution performed by hide_operands. INSN is the insn we
1583 are processing; the arguments are the same as in hide_operands. */
1584
1585static void
1586restore_operands (rtx_insn *insn, int n_ops, rtx *old_operands, rtx *old_dups)
1587{
1588 int i;
1589 for (i = 0; i < recog_data.n_dups; i++)
1590 *recog_data.dup_loc[i] = old_dups[i];
1591 for (i = 0; i < n_ops; i++)
1592 *recog_data.operand_loc[i] = old_operands[i];
1593 if (recog_data.n_dups)
1594 df_insn_rescan (insn);
1595}
1596
1597/* For each output operand of INSN, call scan_rtx to create a new
1598 open chain. Do this only for normal or earlyclobber outputs,
1599 depending on EARLYCLOBBER. If INSN_INFO is nonnull, use it to
1600 record information about the operands in the insn. */
1601
1602static void
1603record_out_operands (rtx_insn *insn, bool earlyclobber, insn_rr_info *insn_info)
1604{
1605 int n_ops = recog_data.n_operands;
1606 const operand_alternative *op_alt = which_op_alt ();
1607
1608 int i;
1609
1610 for (i = 0; i < n_ops + recog_data.n_dups; i++)
1611 {
1612 int opn = i < n_ops ? i : recog_data.dup_num[i - n_ops];
1613 rtx *loc = (i < n_ops
1614 ? recog_data.operand_loc[opn]
1615 : recog_data.dup_loc[i - n_ops]);
1616 rtx op = *loc;
1617 enum reg_class cl = alternative_class (alt: op_alt, i: opn);
1618
1619 class du_head *prev_open;
1620
1621 if (recog_data.operand_type[opn] != OP_OUT
1622 || op_alt[opn].earlyclobber != earlyclobber)
1623 continue;
1624
1625 if (insn_info)
1626 cur_operand = insn_info->op_info + i;
1627
1628 prev_open = open_chains;
1629 if (earlyclobber)
1630 scan_rtx (insn, loc, cl, action: terminate_write, type: OP_OUT);
1631 scan_rtx (insn, loc, cl, action: mark_write, type: OP_OUT);
1632
1633 /* ??? Many targets have output constraints on the SET_DEST
1634 of a call insn, which is stupid, since these are certainly
1635 ABI defined hard registers. For these, and for asm operands
1636 that originally referenced hard registers, we must record that
1637 the chain cannot be renamed. */
1638 if (CALL_P (insn)
1639 || (asm_noperands (PATTERN (insn)) > 0
1640 && REG_P (op)
1641 && REGNO (op) == ORIGINAL_REGNO (op)))
1642 {
1643 if (prev_open != open_chains)
1644 open_chains->cannot_rename = 1;
1645 }
1646 }
1647 cur_operand = NULL;
1648}
1649
1650/* Build def/use chain. */
1651
1652static bool
1653build_def_use (basic_block bb)
1654{
1655 rtx_insn *insn;
1656 unsigned HOST_WIDE_INT untracked_operands;
1657
1658 fail_current_block = false;
1659
1660 for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
1661 {
1662 if (NONDEBUG_INSN_P (insn))
1663 {
1664 int n_ops;
1665 rtx note;
1666 rtx old_operands[MAX_RECOG_OPERANDS];
1667 rtx old_dups[MAX_DUP_OPERANDS];
1668 int i;
1669 int predicated;
1670 enum rtx_code set_code = SET;
1671 enum rtx_code clobber_code = CLOBBER;
1672 insn_rr_info *insn_info = NULL;
1673 terminated_this_insn = NULL;
1674
1675 /* Process the insn, determining its effect on the def-use
1676 chains and live hard registers. We perform the following
1677 steps with the register references in the insn, simulating
1678 its effect:
1679 (1) Deal with earlyclobber operands and CLOBBERs of non-operands
1680 by creating chains and marking hard regs live.
1681 (2) Any read outside an operand causes any chain it overlaps
1682 with to be marked unrenamable.
1683 (3) Any read inside an operand is added if there's already
1684 an open chain for it.
1685 (4) For any REG_DEAD note we find, close open chains that
1686 overlap it.
1687 (5) For any non-earlyclobber write we find, close open chains
1688 that overlap it.
1689 (6) For any non-earlyclobber write we find in an operand, make
1690 a new chain or mark the hard register as live.
1691 (7) For any REG_UNUSED, close any chains we just opened.
1692 (8) For any REG_CFA_RESTORE or REG_CFA_REGISTER, kill any chain
1693 containing its dest.
1694
1695 We cannot deal with situations where we track a reg in one mode
1696 and see a reference in another mode; these will cause the chain
1697 to be marked unrenamable or even cause us to abort the entire
1698 basic block. */
1699
1700 extract_constrain_insn (insn);
1701 preprocess_constraints (insn);
1702 const operand_alternative *op_alt = which_op_alt ();
1703 n_ops = recog_data.n_operands;
1704 untracked_operands = 0;
1705
1706 if (insn_rr.exists ())
1707 {
1708 insn_info = &insn_rr[INSN_UID (insn)];
1709 insn_info->op_info = XOBNEWVEC (&rename_obstack, operand_rr_info,
1710 recog_data.n_operands);
1711 memset (s: insn_info->op_info, c: 0,
1712 n: sizeof (operand_rr_info) * recog_data.n_operands);
1713 }
1714
1715 /* Simplify the code below by promoting OP_OUT to OP_INOUT in
1716 predicated instructions, but only for register operands
1717 that are already tracked, so that we can create a chain
1718 when the first SET makes a register live. */
1719
1720 predicated = GET_CODE (PATTERN (insn)) == COND_EXEC;
1721 for (i = 0; i < n_ops; ++i)
1722 {
1723 rtx op = recog_data.operand[i];
1724 int matches = op_alt[i].matches;
1725 if (matches >= 0 || op_alt[i].matched >= 0
1726 || (predicated && recog_data.operand_type[i] == OP_OUT))
1727 {
1728 recog_data.operand_type[i] = OP_INOUT;
1729 /* A special case to deal with instruction patterns that
1730 have matching operands with different modes. If we're
1731 not already tracking such a reg, we won't start here,
1732 and we must instead make sure to make the operand visible
1733 to the machinery that tracks hard registers. */
1734 machine_mode i_mode = recog_data.operand_mode[i];
1735 if (matches >= 0)
1736 {
1737 machine_mode matches_mode
1738 = recog_data.operand_mode[matches];
1739
1740 if (maybe_ne (a: GET_MODE_SIZE (mode: i_mode),
1741 b: GET_MODE_SIZE (mode: matches_mode))
1742 && !verify_reg_in_set (op, pset: &live_in_chains))
1743 {
1744 untracked_operands |= 1 << i;
1745 untracked_operands |= 1 << matches;
1746 }
1747 }
1748 }
1749#ifdef STACK_REGS
1750 if (regstack_completed
1751 && REG_P (op)
1752 && IN_RANGE (REGNO (op), FIRST_STACK_REG, LAST_STACK_REG))
1753 untracked_operands |= 1 << i;
1754#endif
1755 /* If there's an in-out operand with a register that is not
1756 being tracked at all yet, open a chain. */
1757 if (recog_data.operand_type[i] == OP_INOUT
1758 && !(untracked_operands & (1 << i))
1759 && REG_P (op)
1760 && !verify_reg_tracked (op))
1761 create_new_chain (REGNO (op), REG_NREGS (op), NULL, NULL,
1762 cl: NO_REGS);
1763 }
1764
1765 if (fail_current_block)
1766 break;
1767
1768 /* Step 1a: Mark hard registers that are clobbered in this insn,
1769 outside an operand, as live. */
1770 hide_operands (n_ops, old_operands, old_dups, do_not_hide: untracked_operands,
1771 inout_and_ec_only: false);
1772 note_stores (insn, note_sets_clobbers, &clobber_code);
1773 restore_operands (insn, n_ops, old_operands, old_dups);
1774
1775 /* Step 1b: Begin new chains for earlyclobbered writes inside
1776 operands. */
1777 record_out_operands (insn, earlyclobber: true, insn_info);
1778
1779 /* Step 2: Mark chains for which we have reads outside operands
1780 as unrenamable.
1781 We do this by munging all operands into PC, and closing
1782 everything remaining. */
1783
1784 hide_operands (n_ops, old_operands, old_dups, do_not_hide: untracked_operands,
1785 inout_and_ec_only: false);
1786 scan_rtx (insn, loc: &PATTERN (insn), cl: NO_REGS, action: mark_all_read, type: OP_IN);
1787 restore_operands (insn, n_ops, old_operands, old_dups);
1788
1789 /* Step 2B: Can't rename function call argument registers. */
1790 if (CALL_P (insn) && CALL_INSN_FUNCTION_USAGE (insn))
1791 scan_rtx (insn, loc: &CALL_INSN_FUNCTION_USAGE (insn),
1792 cl: NO_REGS, action: mark_all_read, type: OP_IN);
1793
1794 /* Step 2C: Can't rename asm operands that were originally
1795 hard registers. */
1796 if (asm_noperands (PATTERN (insn)) > 0)
1797 for (i = 0; i < n_ops; i++)
1798 {
1799 rtx *loc = recog_data.operand_loc[i];
1800 rtx op = *loc;
1801
1802 if (REG_P (op)
1803 && REGNO (op) == ORIGINAL_REGNO (op)
1804 && (recog_data.operand_type[i] == OP_IN
1805 || recog_data.operand_type[i] == OP_INOUT))
1806 scan_rtx (insn, loc, cl: NO_REGS, action: mark_all_read, type: OP_IN);
1807 }
1808
1809 /* Step 3: Append to chains for reads inside operands. */
1810 for (i = 0; i < n_ops + recog_data.n_dups; i++)
1811 {
1812 int opn = i < n_ops ? i : recog_data.dup_num[i - n_ops];
1813 rtx *loc = (i < n_ops
1814 ? recog_data.operand_loc[opn]
1815 : recog_data.dup_loc[i - n_ops]);
1816 enum reg_class cl = alternative_class (alt: op_alt, i: opn);
1817 enum op_type type = recog_data.operand_type[opn];
1818
1819 /* Don't scan match_operand here, since we've no reg class
1820 information to pass down. Any operands that we could
1821 substitute in will be represented elsewhere. */
1822 if (recog_data.constraints[opn][0] == '\0'
1823 || untracked_operands & (1 << opn))
1824 continue;
1825
1826 if (insn_info)
1827 cur_operand = i == opn ? insn_info->op_info + i : NULL;
1828 if (op_alt[opn].is_address)
1829 scan_rtx_address (insn, loc, cl, action: mark_read,
1830 VOIDmode, ADDR_SPACE_GENERIC);
1831 else
1832 scan_rtx (insn, loc, cl, action: mark_read, type);
1833 }
1834 cur_operand = NULL;
1835
1836 /* Step 3B: Record updates for regs in REG_INC notes, and
1837 source regs in REG_FRAME_RELATED_EXPR notes. */
1838 for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
1839 if (REG_NOTE_KIND (note) == REG_INC
1840 || REG_NOTE_KIND (note) == REG_FRAME_RELATED_EXPR)
1841 scan_rtx (insn, loc: &XEXP (note, 0), cl: ALL_REGS, action: mark_read,
1842 type: OP_INOUT);
1843
1844 /* Step 4: Close chains for registers that die here, unless
1845 the register is mentioned in a REG_UNUSED note. In that
1846 case we keep the chain open until step #7 below to ensure
1847 it conflicts with other output operands of this insn.
1848 See PR 52573. Arguably the insn should not have both
1849 notes; it has proven difficult to fix that without
1850 other undesirable side effects. */
1851 for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
1852 if (REG_NOTE_KIND (note) == REG_DEAD
1853 && !find_regno_note (insn, REG_UNUSED, REGNO (XEXP (note, 0))))
1854 {
1855 remove_from_hard_reg_set (regs: &live_hard_regs,
1856 GET_MODE (XEXP (note, 0)),
1857 REGNO (XEXP (note, 0)));
1858 scan_rtx (insn, loc: &XEXP (note, 0), cl: NO_REGS, action: terminate_dead,
1859 type: OP_IN);
1860 }
1861
1862 /* Step 4B: If this is a call, any chain live at this point
1863 requires a caller-saved reg. */
1864 if (CALL_P (insn))
1865 {
1866 function_abi callee_abi = insn_callee_abi (insn);
1867 class du_head *p;
1868 for (p = open_chains; p; p = p->next_chain)
1869 {
1870 p->call_abis |= (1 << callee_abi.id ());
1871 p->call_clobber_mask
1872 |= callee_abi.full_and_partial_reg_clobbers ();
1873 p->hard_conflicts |= callee_abi.full_reg_clobbers ();
1874 }
1875 }
1876
1877 /* Step 5: Close open chains that overlap writes. Similar to
1878 step 2, we hide in-out operands, since we do not want to
1879 close these chains. We also hide earlyclobber operands,
1880 since we've opened chains for them in step 1, and earlier
1881 chains they would overlap with must have been closed at
1882 the previous insn at the latest, as such operands cannot
1883 possibly overlap with any input operands. */
1884
1885 hide_operands (n_ops, old_operands, old_dups, do_not_hide: untracked_operands,
1886 inout_and_ec_only: true);
1887 scan_rtx (insn, loc: &PATTERN (insn), cl: NO_REGS, action: terminate_write, type: OP_IN);
1888 restore_operands (insn, n_ops, old_operands, old_dups);
1889
1890 /* Step 6a: Mark hard registers that are set in this insn,
1891 outside an operand, as live. */
1892 hide_operands (n_ops, old_operands, old_dups, do_not_hide: untracked_operands,
1893 inout_and_ec_only: false);
1894 note_stores (insn, note_sets_clobbers, &set_code);
1895 restore_operands (insn, n_ops, old_operands, old_dups);
1896
1897 /* Step 6b: Begin new chains for writes inside operands. */
1898 record_out_operands (insn, earlyclobber: false, insn_info);
1899
1900 /* Step 6c: Record destination regs in REG_FRAME_RELATED_EXPR
1901 notes for update. */
1902 for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
1903 if (REG_NOTE_KIND (note) == REG_FRAME_RELATED_EXPR)
1904 scan_rtx (insn, loc: &XEXP (note, 0), cl: ALL_REGS, action: mark_access,
1905 type: OP_INOUT);
1906
1907 /* Step 7: Close chains for registers that were never
1908 really used here. */
1909 for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
1910 if (REG_NOTE_KIND (note) == REG_UNUSED)
1911 {
1912 remove_from_hard_reg_set (regs: &live_hard_regs,
1913 GET_MODE (XEXP (note, 0)),
1914 REGNO (XEXP (note, 0)));
1915 scan_rtx (insn, loc: &XEXP (note, 0), cl: NO_REGS, action: terminate_dead,
1916 type: OP_IN);
1917 }
1918
1919 /* Step 8: Kill the chains involving register restores. Those
1920 should restore _that_ register. Similar for REG_CFA_REGISTER. */
1921 for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
1922 if (REG_NOTE_KIND (note) == REG_CFA_RESTORE
1923 || REG_NOTE_KIND (note) == REG_CFA_REGISTER)
1924 {
1925 rtx *x = &XEXP (note, 0);
1926 if (!*x)
1927 x = &PATTERN (insn);
1928 if (GET_CODE (*x) == PARALLEL)
1929 x = &XVECEXP (*x, 0, 0);
1930 if (GET_CODE (*x) == SET)
1931 x = &SET_DEST (*x);
1932 scan_rtx (insn, loc: x, cl: NO_REGS, action: mark_all_read, type: OP_IN);
1933 }
1934 }
1935 else if (DEBUG_BIND_INSN_P (insn)
1936 && !VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (insn)))
1937 {
1938 scan_rtx (insn, loc: &INSN_VAR_LOCATION_LOC (insn),
1939 cl: ALL_REGS, action: mark_read, type: OP_IN);
1940 }
1941 if (insn == BB_END (bb))
1942 break;
1943 }
1944
1945 if (fail_current_block)
1946 return false;
1947
1948 return true;
1949}
1950
1951/* Initialize the register renamer. If INSN_INFO is true, ensure that
1952 insn_rr is nonnull. */
1953void
1954regrename_init (bool insn_info)
1955{
1956 gcc_obstack_init (&rename_obstack);
1957 insn_rr.create (nelems: 0);
1958 if (insn_info)
1959 insn_rr.safe_grow_cleared (len: get_max_uid (), exact: true);
1960}
1961
1962/* Free all global data used by the register renamer. */
1963void
1964regrename_finish (void)
1965{
1966 insn_rr.release ();
1967 free_chain_data ();
1968 obstack_free (&rename_obstack, NULL);
1969}
1970
1971/* Perform register renaming on the current function. */
1972
1973static unsigned int
1974regrename_optimize (void)
1975{
1976 df_set_flags (DF_LR_RUN_DCE);
1977 df_note_add_problem ();
1978 df_analyze ();
1979 df_set_flags (DF_DEFER_INSN_RESCAN);
1980
1981 regrename_init (insn_info: false);
1982
1983 regrename_analyze (NULL, include_all_block_p: false);
1984
1985 rename_chains ();
1986
1987 regrename_finish ();
1988
1989 return 0;
1990}
1991
1992namespace {
1993
1994const pass_data pass_data_regrename =
1995{
1996 .type: RTL_PASS, /* type */
1997 .name: "rnreg", /* name */
1998 .optinfo_flags: OPTGROUP_NONE, /* optinfo_flags */
1999 .tv_id: TV_RENAME_REGISTERS, /* tv_id */
2000 .properties_required: 0, /* properties_required */
2001 .properties_provided: 0, /* properties_provided */
2002 .properties_destroyed: 0, /* properties_destroyed */
2003 .todo_flags_start: 0, /* todo_flags_start */
2004 TODO_df_finish, /* todo_flags_finish */
2005};
2006
2007class pass_regrename : public rtl_opt_pass
2008{
2009public:
2010 pass_regrename (gcc::context *ctxt)
2011 : rtl_opt_pass (pass_data_regrename, ctxt)
2012 {}
2013
2014 /* opt_pass methods: */
2015 bool gate (function *) final override
2016 {
2017 return (optimize > 0 && (flag_rename_registers));
2018 }
2019
2020 unsigned int execute (function *) final override
2021 {
2022 return regrename_optimize ();
2023 }
2024
2025}; // class pass_regrename
2026
2027} // anon namespace
2028
2029rtl_opt_pass *
2030make_pass_regrename (gcc::context *ctxt)
2031{
2032 return new pass_regrename (ctxt);
2033}
2034

source code of gcc/regrename.cc