]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/regrename.c
* Makefile.in, alias.c, basic-block.h, bb-reorder.c, bitmap.c,
[thirdparty/gcc.git] / gcc / regrename.c
CommitLineData
b9a06185 1/* Register renaming for the GNU compiler.
df831ba5 2 Copyright (C) 2000, 2001 Free Software Foundation, Inc.
b9a06185 3
f12b58b3 4 This file is part of GCC.
b9a06185 5
f12b58b3 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
b9a06185 8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
f12b58b3 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.
b9a06185 15
16 You should have received a copy of the GNU General Public License
f12b58b3 17 along with GCC; see the file COPYING. If not, write to the Free
18 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA. */
b9a06185 20
1140e77e 21#define REG_OK_STRICT
22
b9a06185 23#include "config.h"
24#include "system.h"
b9a06185 25#include "rtl.h"
1140e77e 26#include "tm_p.h"
b9a06185 27#include "insn-config.h"
28#include "regs.h"
1140e77e 29#include "hard-reg-set.h"
30#include "basic-block.h"
31#include "reload.h"
b9a06185 32#include "output.h"
33#include "function.h"
34#include "recog.h"
1140e77e 35#include "flags.h"
36#include "obstack.h"
37
38#define obstack_chunk_alloc xmalloc
39#define obstack_chunk_free free
40
41#ifndef REGNO_MODE_OK_FOR_BASE_P
42#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) REGNO_OK_FOR_BASE_P (REGNO)
43#endif
44
45#ifndef REG_MODE_OK_FOR_BASE_P
46#define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
47#endif
b9a06185 48
49static const char *const reg_class_names[] = REG_CLASS_NAMES;
50
1140e77e 51struct du_chain
b9a06185 52{
1140e77e 53 struct du_chain *next_chain;
54 struct du_chain *next_use;
b9a06185 55
1140e77e 56 rtx insn;
57 rtx *loc;
58 enum reg_class class;
59 unsigned int need_caller_save_reg:1;
d5dfb455 60 unsigned int earlyclobber:1;
1140e77e 61};
b9a06185 62
1140e77e 63enum scan_actions
64{
1140e77e 65 terminate_all_read,
66 terminate_overlapping_read,
67 terminate_write,
68 terminate_dead,
69 mark_read,
70 mark_write
71};
72
73static const char * const scan_actions_name[] =
74{
1140e77e 75 "terminate_all_read",
76 "terminate_overlapping_read",
77 "terminate_write",
78 "terminate_dead",
79 "mark_read",
80 "mark_write"
81};
82
83static struct obstack rename_obstack;
84
85static void do_replace PARAMS ((struct du_chain *, int));
86static void scan_rtx_reg PARAMS ((rtx, rtx *, enum reg_class,
d5dfb455 87 enum scan_actions, enum op_type, int));
1140e77e 88static void scan_rtx_address PARAMS ((rtx, rtx *, enum reg_class,
1f6f74af 89 enum scan_actions, enum machine_mode));
1140e77e 90static void scan_rtx PARAMS ((rtx, rtx *, enum reg_class,
d5dfb455 91 enum scan_actions, enum op_type, int));
92static struct du_chain *build_def_use PARAMS ((basic_block));
1140e77e 93static void dump_def_use_chain PARAMS ((struct du_chain *));
d5dfb455 94static void note_sets PARAMS ((rtx, rtx, void *));
95static void clear_dead_regs PARAMS ((HARD_REG_SET *, enum machine_mode, rtx));
96static void merge_overlapping_regs PARAMS ((basic_block, HARD_REG_SET *,
97 struct du_chain *));
98
99/* Called through note_stores from update_life. Find sets of registers, and
100 record them in *DATA (which is actually a HARD_REG_SET *). */
101
102static void
103note_sets (x, set, data)
104 rtx x;
105 rtx set ATTRIBUTE_UNUSED;
106 void *data;
107{
108 HARD_REG_SET *pset = (HARD_REG_SET *) data;
109 unsigned int regno;
110 int nregs;
111 if (GET_CODE (x) != REG)
112 return;
113 regno = REGNO (x);
114 nregs = HARD_REGNO_NREGS (regno, GET_MODE (x));
115 while (nregs-- > 0)
116 SET_HARD_REG_BIT (*pset, regno + nregs);
117}
118
119/* Clear all registers from *PSET for which a note of kind KIND can be found
120 in the list NOTES. */
121
122static void
123clear_dead_regs (pset, kind, notes)
124 HARD_REG_SET *pset;
125 enum machine_mode kind;
126 rtx notes;
127{
128 rtx note;
129 for (note = notes; note; note = XEXP (note, 1))
130 if (REG_NOTE_KIND (note) == kind && REG_P (XEXP (note, 0)))
131 {
132 rtx reg = XEXP (note, 0);
133 unsigned int regno = REGNO (reg);
134 int nregs = HARD_REGNO_NREGS (regno, GET_MODE (reg));
135 while (nregs-- > 0)
136 CLEAR_HARD_REG_BIT (*pset, regno + nregs);
137 }
138}
139
140/* For a def-use chain CHAIN in basic block B, find which registers overlap
141 its lifetime and set the corresponding bits in *PSET. */
142
143static void
144merge_overlapping_regs (b, pset, chain)
145 basic_block b;
146 HARD_REG_SET *pset;
147 struct du_chain *chain;
148{
149 struct du_chain *t = chain;
150 rtx insn;
151 HARD_REG_SET live;
152
153 REG_SET_TO_HARD_REG_SET (live, b->global_live_at_start);
154 insn = b->head;
155 while (t)
156 {
157 /* Search forward until the next reference to the register to be
158 renamed. */
159 while (insn != t->insn)
160 {
161 if (INSN_P (insn))
162 {
163 clear_dead_regs (&live, REG_DEAD, REG_NOTES (insn));
164 note_stores (PATTERN (insn), note_sets, (void *) &live);
165 /* Only record currently live regs if we are inside the
166 reg's live range. */
167 if (t != chain)
168 IOR_HARD_REG_SET (*pset, live);
169 clear_dead_regs (&live, REG_UNUSED, REG_NOTES (insn));
170 }
171 insn = NEXT_INSN (insn);
172 }
173
174 IOR_HARD_REG_SET (*pset, live);
175
176 /* For the last reference, also merge in all registers set in the
177 same insn.
178 @@@ We only have take earlyclobbered sets into account. */
179 if (! t->next_use)
180 note_stores (PATTERN (insn), note_sets, (void *) pset);
181
182 t = t->next_use;
183 }
184}
185
186/* Perform register renaming on the current function. */
b9a06185 187
1140e77e 188void
189regrename_optimize ()
190{
d5dfb455 191 int tick[FIRST_PSEUDO_REGISTER];
192 int this_tick = 0;
1140e77e 193 int b;
194 char *first_obj;
b9a06185 195
d5dfb455 196 memset (tick, 0, sizeof tick);
197
1140e77e 198 gcc_obstack_init (&rename_obstack);
199 first_obj = (char *) obstack_alloc (&rename_obstack, 0);
b9a06185 200
1140e77e 201 for (b = 0; b < n_basic_blocks; b++)
202 {
203 basic_block bb = BASIC_BLOCK (b);
204 struct du_chain *all_chains = 0;
1140e77e 205 HARD_REG_SET unavailable;
206 HARD_REG_SET regs_seen;
b9a06185 207
1140e77e 208 CLEAR_HARD_REG_SET (unavailable);
b9a06185 209
1140e77e 210 if (rtl_dump_file)
211 fprintf (rtl_dump_file, "\nBasic block %d:\n", b);
b9a06185 212
d5dfb455 213 all_chains = build_def_use (bb);
b9a06185 214
1140e77e 215 if (rtl_dump_file)
216 dump_def_use_chain (all_chains);
b9a06185 217
d5dfb455 218 CLEAR_HARD_REG_SET (unavailable);
1140e77e 219 /* Don't clobber traceback for noreturn functions. */
220 if (frame_pointer_needed)
221 {
df831ba5 222 int i;
223
224 for (i = HARD_REGNO_NREGS (FRAME_POINTER_REGNUM, Pmode); i--;)
225 SET_HARD_REG_BIT (unavailable, FRAME_POINTER_REGNUM + i);
226
1140e77e 227#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
df831ba5 228 for (i = HARD_REGNO_NREGS (HARD_FRAME_POINTER_REGNUM, Pmode); i--;)
229 SET_HARD_REG_BIT (unavailable, HARD_FRAME_POINTER_REGNUM + i);
1140e77e 230#endif
231 }
b9a06185 232
1140e77e 233 CLEAR_HARD_REG_SET (regs_seen);
234 while (all_chains)
235 {
d5dfb455 236 int new_reg, best_new_reg = -1;
1140e77e 237 int n_uses;
238 struct du_chain *this = all_chains;
239 struct du_chain *tmp, *last;
240 HARD_REG_SET this_unavailable;
68ec8b7d 241 int reg = REGNO (*this->loc);
1f6f74af 242 int i;
b9a06185 243
1140e77e 244 all_chains = this->next_chain;
d5dfb455 245
246#if 0 /* This just disables optimization opportunities. */
1140e77e 247 /* Only rename once we've seen the reg more than once. */
248 if (! TEST_HARD_REG_BIT (regs_seen, reg))
d98fed9f 249 {
1140e77e 250 SET_HARD_REG_BIT (regs_seen, reg);
251 continue;
252 }
d5dfb455 253#endif
d98fed9f 254
940fa57f 255 if (fixed_regs[reg] || global_regs[reg]
256#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
257 || (frame_pointer_needed && reg == HARD_FRAME_POINTER_REGNUM)
258#else
259 || (frame_pointer_needed && reg == FRAME_POINTER_REGNUM)
260#endif
261 )
1140e77e 262 continue;
d98fed9f 263
1140e77e 264 COPY_HARD_REG_SET (this_unavailable, unavailable);
d98fed9f 265
1140e77e 266 /* Find last entry on chain (which has the need_caller_save bit),
267 count number of uses, and narrow the set of registers we can
268 use for renaming. */
269 n_uses = 0;
270 for (last = this; last->next_use; last = last->next_use)
271 {
272 n_uses++;
273 IOR_COMPL_HARD_REG_SET (this_unavailable,
274 reg_class_contents[last->class]);
d98fed9f 275 }
1140e77e 276 if (n_uses < 1)
277 continue;
b9a06185 278
1140e77e 279 IOR_COMPL_HARD_REG_SET (this_unavailable,
280 reg_class_contents[last->class]);
b9a06185 281
d5dfb455 282 if (this->need_caller_save_reg)
1140e77e 283 IOR_HARD_REG_SET (this_unavailable, call_used_reg_set);
284
d5dfb455 285 merge_overlapping_regs (bb, &this_unavailable, this);
286
1140e77e 287 /* Now potential_regs is a reasonable approximation, let's
288 have a closer look at each register still in there. */
68ec8b7d 289 for (new_reg = 0; new_reg < FIRST_PSEUDO_REGISTER; new_reg++)
d98fed9f 290 {
68ec8b7d 291 int nregs = HARD_REGNO_NREGS (new_reg, GET_MODE (*this->loc));
292
1f6f74af 293 for (i = nregs - 1; i >= 0; --i)
d5dfb455 294 if (TEST_HARD_REG_BIT (this_unavailable, new_reg + i)
295 || fixed_regs[new_reg + i]
296 || global_regs[new_reg + i]
1f6f74af 297 /* Can't use regs which aren't saved by the prologue. */
d5dfb455 298 || (! regs_ever_live[new_reg + i]
299 && ! call_used_regs[new_reg + i])
f5100774 300#ifdef LEAF_REGISTERS
301 /* We can't use a non-leaf register if we're in a
302 leaf function. */
303 || (current_function_is_leaf
304 && !LEAF_REGISTERS[new_reg + i])
305#endif
1140e77e 306#ifdef HARD_REGNO_RENAME_OK
d5dfb455 307 || ! HARD_REGNO_RENAME_OK (reg + i, new_reg + i)
1140e77e 308#endif
1f6f74af 309 )
310 break;
311 if (i >= 0)
1140e77e 312 continue;
d98fed9f 313
1f6f74af 314 /* See whether it accepts all modes that occur in
315 definition and uses. */
1140e77e 316 for (tmp = this; tmp; tmp = tmp->next_use)
d5dfb455 317 if (! HARD_REGNO_MODE_OK (new_reg, GET_MODE (*tmp->loc)))
1140e77e 318 break;
319 if (! tmp)
d5dfb455 320 {
321 if (best_new_reg == -1
322 || tick[best_new_reg] > tick[new_reg])
323 best_new_reg = new_reg;
324 }
d98fed9f 325 }
b9a06185 326
1140e77e 327 if (rtl_dump_file)
328 {
329 fprintf (rtl_dump_file, "Register %s in insn %d",
330 reg_names[reg], INSN_UID (last->insn));
331 if (last->need_caller_save_reg)
332 fprintf (rtl_dump_file, " crosses a call");
333 }
d98fed9f 334
d5dfb455 335 if (best_new_reg == -1)
1140e77e 336 {
337 if (rtl_dump_file)
338 fprintf (rtl_dump_file, "; no available registers\n");
b9a06185 339 continue;
1140e77e 340 }
b9a06185 341
d5dfb455 342 do_replace (this, best_new_reg);
343 tick[best_new_reg] = this_tick++;
d98fed9f 344
1140e77e 345 if (rtl_dump_file)
d5dfb455 346 fprintf (rtl_dump_file, ", renamed as %s\n", reg_names[best_new_reg]);
1140e77e 347 }
d98fed9f 348
1140e77e 349 obstack_free (&rename_obstack, first_obj);
350 }
d98fed9f 351
1140e77e 352 obstack_free (&rename_obstack, NULL);
b9a06185 353
1140e77e 354 if (rtl_dump_file)
355 fputc ('\n', rtl_dump_file);
b9a06185 356
1140e77e 357 count_or_remove_death_notes (NULL, 1);
358 update_life_info (NULL, UPDATE_LIFE_LOCAL,
359 PROP_REG_INFO | PROP_DEATH_NOTES);
b9a06185 360}
361
b9a06185 362static void
1140e77e 363do_replace (chain, reg)
364 struct du_chain *chain;
365 int reg;
b9a06185 366{
1140e77e 367 while (chain)
b9a06185 368 {
22cf44bc 369 unsigned int regno = ORIGINAL_REGNO (*chain->loc);
370 *chain->loc = gen_raw_REG (GET_MODE (*chain->loc), reg);
940fa57f 371 if (regno >= FIRST_PSEUDO_REGISTER)
372 ORIGINAL_REGNO (*chain->loc) = regno;
1140e77e 373 chain = chain->next_use;
b9a06185 374 }
b9a06185 375}
376
b9a06185 377
1140e77e 378static struct du_chain *open_chains;
379static struct du_chain *closed_chains;
380
381static void
d5dfb455 382scan_rtx_reg (insn, loc, class, action, type, earlyclobber)
1140e77e 383 rtx insn;
384 rtx *loc;
385 enum reg_class class;
386 enum scan_actions action;
387 enum op_type type;
d5dfb455 388 int earlyclobber;
b9a06185 389{
1140e77e 390 struct du_chain **p;
391 rtx x = *loc;
392 enum machine_mode mode = GET_MODE (x);
393 int this_regno = REGNO (x);
394 int this_nregs = HARD_REGNO_NREGS (this_regno, mode);
395
1140e77e 396 if (action == mark_write)
b9a06185 397 {
1140e77e 398 if (type == OP_OUT)
b9a06185 399 {
1140e77e 400 struct du_chain *this = (struct du_chain *)
401 obstack_alloc (&rename_obstack, sizeof (struct du_chain));
402 this->next_use = 0;
403 this->next_chain = open_chains;
404 this->loc = loc;
405 this->insn = insn;
406 this->class = class;
407 this->need_caller_save_reg = 0;
d5dfb455 408 this->earlyclobber = earlyclobber;
1140e77e 409 open_chains = this;
b9a06185 410 }
1140e77e 411 return;
b9a06185 412 }
d98fed9f 413
1140e77e 414 if ((type == OP_OUT && action != terminate_write)
415 || (type != OP_OUT && action == terminate_write))
416 return;
ceba8bb1 417
1140e77e 418 for (p = &open_chains; *p;)
ceba8bb1 419 {
1140e77e 420 struct du_chain *this = *p;
1140e77e 421
77b2358d 422 /* Check if the chain has been terminated if it has then skip to
423 the next chain.
1140e77e 424
77b2358d 425 This can happen when we've already appended the location to
426 the chain in Step 3, but are trying to hide in-out operands
427 from terminate_write in Step 5. */
ceba8bb1 428
77b2358d 429 if (*this->loc == cc0_rtx)
430 p = &this->next_chain;
431 else
432 {
433 int regno = REGNO (*this->loc);
434 int nregs = HARD_REGNO_NREGS (regno, GET_MODE (*this->loc));
435 int exact_match = (regno == this_regno && nregs == this_nregs);
436
437 if (regno + nregs <= this_regno
438 || this_regno + this_nregs <= regno)
a292cb6e 439 {
440 p = &this->next_chain;
441 continue;
442 }
443
444 if (action == mark_read)
1140e77e 445 {
77b2358d 446 if (! exact_match)
447 abort ();
77b2358d 448
a292cb6e 449 /* ??? Class NO_REGS can happen if the md file makes use of
450 EXTRA_CONSTRAINTS to match registers. Which is arguably
451 wrong, but there we are. Since we know not what this may
452 be replaced with, terminate the chain. */
453 if (class != NO_REGS)
454 {
455 this = (struct du_chain *)
456 obstack_alloc (&rename_obstack, sizeof (struct du_chain));
d5dfb455 457 this->next_use = 0;
a292cb6e 458 this->next_chain = (*p)->next_chain;
459 this->loc = loc;
460 this->insn = insn;
461 this->class = class;
462 this->need_caller_save_reg = 0;
d5dfb455 463 while (*p)
464 p = &(*p)->next_use;
a292cb6e 465 *p = this;
466 return;
467 }
1140e77e 468 }
a292cb6e 469
470 if (action != terminate_overlapping_read || ! exact_match)
1140e77e 471 {
77b2358d 472 struct du_chain *next = this->next_chain;
473
474 /* Whether the terminated chain can be used for renaming
475 depends on the action and this being an exact match.
476 In either case, we remove this element from open_chains. */
477
478 if ((action == terminate_dead || action == terminate_write)
479 && exact_match)
480 {
481 this->next_chain = closed_chains;
482 closed_chains = this;
483 if (rtl_dump_file)
484 fprintf (rtl_dump_file,
485 "Closing chain %s at insn %d (%s)\n",
486 reg_names[REGNO (*this->loc)], INSN_UID (insn),
487 scan_actions_name[(int) action]);
488 }
489 else
490 {
491 if (rtl_dump_file)
492 fprintf (rtl_dump_file,
493 "Discarding chain %s at insn %d (%s)\n",
494 reg_names[REGNO (*this->loc)], INSN_UID (insn),
495 scan_actions_name[(int) action]);
496 }
497 *p = next;
1140e77e 498 }
77b2358d 499 else
500 p = &this->next_chain;
1140e77e 501 }
1140e77e 502 }
b9a06185 503}
504
1140e77e 505/* Adapted from find_reloads_address_1. CLASS is INDEX_REG_CLASS or
506 BASE_REG_CLASS depending on how the register is being considered. */
b9a06185 507
31659b75 508static void
1f6f74af 509scan_rtx_address (insn, loc, class, action, mode)
b9a06185 510 rtx insn;
1140e77e 511 rtx *loc;
512 enum reg_class class;
513 enum scan_actions action;
1f6f74af 514 enum machine_mode mode;
b9a06185 515{
1140e77e 516 rtx x = *loc;
517 RTX_CODE code = GET_CODE (x);
518 const char *fmt;
519 int i, j;
b9a06185 520
1140e77e 521 if (action == mark_write)
522 return;
b9a06185 523
1140e77e 524 switch (code)
b9a06185 525 {
1140e77e 526 case PLUS:
527 {
528 rtx orig_op0 = XEXP (x, 0);
529 rtx orig_op1 = XEXP (x, 1);
530 RTX_CODE code0 = GET_CODE (orig_op0);
531 RTX_CODE code1 = GET_CODE (orig_op1);
532 rtx op0 = orig_op0;
533 rtx op1 = orig_op1;
534 rtx *locI = NULL;
535 rtx *locB = NULL;
536
537 if (GET_CODE (op0) == SUBREG)
538 {
539 op0 = SUBREG_REG (op0);
540 code0 = GET_CODE (op0);
541 }
b9a06185 542
1140e77e 543 if (GET_CODE (op1) == SUBREG)
544 {
545 op1 = SUBREG_REG (op1);
546 code1 = GET_CODE (op1);
547 }
b9a06185 548
1140e77e 549 if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE
550 || code0 == ZERO_EXTEND || code1 == MEM)
551 {
552 locI = &XEXP (x, 0);
553 locB = &XEXP (x, 1);
554 }
555 else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
556 || code1 == ZERO_EXTEND || code0 == MEM)
557 {
558 locI = &XEXP (x, 1);
559 locB = &XEXP (x, 0);
560 }
561 else if (code0 == CONST_INT || code0 == CONST
562 || code0 == SYMBOL_REF || code0 == LABEL_REF)
563 locB = &XEXP (x, 1);
564 else if (code1 == CONST_INT || code1 == CONST
565 || code1 == SYMBOL_REF || code1 == LABEL_REF)
566 locB = &XEXP (x, 0);
567 else if (code0 == REG && code1 == REG)
568 {
569 int index_op;
570
571 if (REG_OK_FOR_INDEX_P (op0)
572 && REG_MODE_OK_FOR_BASE_P (op1, mode))
573 index_op = 0;
574 else if (REG_OK_FOR_INDEX_P (op1)
575 && REG_MODE_OK_FOR_BASE_P (op0, mode))
576 index_op = 1;
577 else if (REG_MODE_OK_FOR_BASE_P (op1, mode))
578 index_op = 0;
579 else if (REG_MODE_OK_FOR_BASE_P (op0, mode))
580 index_op = 1;
581 else if (REG_OK_FOR_INDEX_P (op1))
582 index_op = 1;
583 else
584 index_op = 0;
585
586 locI = &XEXP (x, index_op);
587 locB = &XEXP (x, !index_op);
588 }
589 else if (code0 == REG)
590 {
591 locI = &XEXP (x, 0);
592 locB = &XEXP (x, 1);
593 }
594 else if (code1 == REG)
595 {
596 locI = &XEXP (x, 1);
597 locB = &XEXP (x, 0);
598 }
b9a06185 599
1140e77e 600 if (locI)
1f6f74af 601 scan_rtx_address (insn, locI, INDEX_REG_CLASS, action, mode);
1140e77e 602 if (locB)
1f6f74af 603 scan_rtx_address (insn, locB, BASE_REG_CLASS, action, mode);
1140e77e 604 return;
605 }
b9a06185 606
1140e77e 607 case POST_INC:
608 case POST_DEC:
609 case POST_MODIFY:
610 case PRE_INC:
611 case PRE_DEC:
612 case PRE_MODIFY:
613#ifndef AUTO_INC_DEC
8f758362 614 /* If the target doesn't claim to handle autoinc, this must be
615 something special, like a stack push. Kill this chain. */
616 action = terminate_all_read;
1140e77e 617#endif
618 break;
b9a06185 619
1140e77e 620 case MEM:
1f6f74af 621 scan_rtx_address (insn, &XEXP (x, 0), BASE_REG_CLASS, action,
622 GET_MODE (x));
1140e77e 623 return;
d98fed9f 624
1140e77e 625 case REG:
d5dfb455 626 scan_rtx_reg (insn, loc, class, action, OP_IN, 0);
31659b75 627 return;
d98fed9f 628
1140e77e 629 default:
630 break;
31659b75 631 }
1140e77e 632
633 fmt = GET_RTX_FORMAT (code);
634 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
31659b75 635 {
1140e77e 636 if (fmt[i] == 'e')
1f6f74af 637 scan_rtx_address (insn, &XEXP (x, i), class, action, mode);
1140e77e 638 else if (fmt[i] == 'E')
639 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1f6f74af 640 scan_rtx_address (insn, &XVECEXP (x, i, j), class, action, mode);
31659b75 641 }
b9a06185 642}
643
1140e77e 644static void
d5dfb455 645scan_rtx (insn, loc, class, action, type, earlyclobber)
b9a06185 646 rtx insn;
1140e77e 647 rtx *loc;
648 enum reg_class class;
649 enum scan_actions action;
650 enum op_type type;
d5dfb455 651 int earlyclobber;
b9a06185 652{
1140e77e 653 const char *fmt;
654 rtx x = *loc;
655 enum rtx_code code = GET_CODE (x);
656 int i, j;
b9a06185 657
1140e77e 658 code = GET_CODE (x);
659 switch (code)
b9a06185 660 {
1140e77e 661 case CONST:
662 case CONST_INT:
663 case CONST_DOUBLE:
664 case SYMBOL_REF:
665 case LABEL_REF:
666 case CC0:
667 case PC:
668 return;
22d9265e 669
1140e77e 670 case REG:
d5dfb455 671 scan_rtx_reg (insn, loc, class, action, type, earlyclobber);
1140e77e 672 return;
b9a06185 673
1140e77e 674 case MEM:
1f6f74af 675 scan_rtx_address (insn, &XEXP (x, 0), BASE_REG_CLASS, action,
676 GET_MODE (x));
1140e77e 677 return;
b9a06185 678
1140e77e 679 case SET:
d5dfb455 680 scan_rtx (insn, &SET_SRC (x), class, action, OP_IN, 0);
681 scan_rtx (insn, &SET_DEST (x), class, action, OP_OUT, 0);
1140e77e 682 return;
b9a06185 683
1140e77e 684 case STRICT_LOW_PART:
d5dfb455 685 scan_rtx (insn, &XEXP (x, 0), class, action, OP_INOUT, earlyclobber);
1140e77e 686 return;
b9a06185 687
1140e77e 688 case ZERO_EXTRACT:
689 case SIGN_EXTRACT:
690 scan_rtx (insn, &XEXP (x, 0), class, action,
d5dfb455 691 type == OP_IN ? OP_IN : OP_INOUT, earlyclobber);
692 scan_rtx (insn, &XEXP (x, 1), class, action, OP_IN, 0);
693 scan_rtx (insn, &XEXP (x, 2), class, action, OP_IN, 0);
1140e77e 694 return;
b9a06185 695
1140e77e 696 case POST_INC:
697 case PRE_INC:
698 case POST_DEC:
699 case PRE_DEC:
700 case POST_MODIFY:
701 case PRE_MODIFY:
702 /* Should only happen inside MEM. */
703 abort ();
704
705 case CLOBBER:
d5dfb455 706 scan_rtx (insn, &SET_DEST (x), class, action, OP_OUT, 1);
1140e77e 707 return;
b9a06185 708
1140e77e 709 case EXPR_LIST:
d5dfb455 710 scan_rtx (insn, &XEXP (x, 0), class, action, type, 0);
1140e77e 711 if (XEXP (x, 1))
d5dfb455 712 scan_rtx (insn, &XEXP (x, 1), class, action, type, 0);
1140e77e 713 return;
b9a06185 714
1140e77e 715 default:
716 break;
717 }
b9a06185 718
1140e77e 719 fmt = GET_RTX_FORMAT (code);
720 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
b9a06185 721 {
722 if (fmt[i] == 'e')
d5dfb455 723 scan_rtx (insn, &XEXP (x, i), class, action, type, 0);
b9a06185 724 else if (fmt[i] == 'E')
725 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
d5dfb455 726 scan_rtx (insn, &XVECEXP (x, i, j), class, action, type, 0);
b9a06185 727 }
b9a06185 728}
729
1140e77e 730/* Build def/use chain */
b9a06185 731
1140e77e 732static struct du_chain *
d5dfb455 733build_def_use (bb)
1140e77e 734 basic_block bb;
b9a06185 735{
1140e77e 736 rtx insn;
d98fed9f 737
1140e77e 738 open_chains = closed_chains = NULL;
d98fed9f 739
1140e77e 740 for (insn = bb->head; ; insn = NEXT_INSN (insn))
741 {
742 if (INSN_P (insn))
743 {
744 int n_ops;
745 rtx note;
746 rtx old_operands[MAX_RECOG_OPERANDS];
747 rtx old_dups[MAX_DUP_OPERANDS];
748 int i;
749 int alt;
750 int predicated;
751
1140e77e 752 /* Process the insn, determining its effect on the def-use
753 chains. We perform the following steps with the register
754 references in the insn:
755 (1) Any read that overlaps an open chain, but doesn't exactly
756 match, causes that chain to be closed. We can't deal
757 with overlaps yet.
758 (2) Any read outside an operand causes any chain it overlaps
759 with to be closed, since we can't replace it.
760 (3) Any read inside an operand is added if there's already
761 an open chain for it.
762 (4) For any REG_DEAD note we find, close open chains that
763 overlap it.
764 (5) For any write we find, close open chains that overlap it.
765 (6) For any write we find in an operand, make a new chain.
766 (7) For any REG_UNUSED, close any chains we just opened. */
767
768 extract_insn (insn);
769 constrain_operands (1);
770 preprocess_constraints ();
771 alt = which_alternative;
772 n_ops = recog_data.n_operands;
773
774 /* Simplify the code below by rewriting things to reflect
775 matching constraints. Also promote OP_OUT to OP_INOUT
776 in predicated instructions. */
777
778 predicated = GET_CODE (PATTERN (insn)) == COND_EXEC;
779 for (i = 0; i < n_ops; ++i)
b9a06185 780 {
1140e77e 781 int matches = recog_op_alt[i][alt].matches;
782 if (matches >= 0)
783 recog_op_alt[i][alt].class = recog_op_alt[matches][alt].class;
784 if (matches >= 0 || recog_op_alt[i][alt].matched >= 0
785 || (predicated && recog_data.operand_type[i] == OP_OUT))
786 recog_data.operand_type[i] = OP_INOUT;
b9a06185 787 }
d98fed9f 788
1140e77e 789 /* Step 1: Close chains for which we have overlapping reads. */
790 for (i = 0; i < n_ops; i++)
791 scan_rtx (insn, recog_data.operand_loc[i],
792 NO_REGS, terminate_overlapping_read,
d5dfb455 793 recog_data.operand_type[i], 0);
d98fed9f 794
1140e77e 795 /* Step 2: Close chains for which we have reads outside operands.
796 We do this by munging all operands into CC0, and closing
797 everything remaining. */
b9a06185 798
1140e77e 799 for (i = 0; i < n_ops; i++)
d98fed9f 800 {
1140e77e 801 old_operands[i] = recog_data.operand[i];
802 /* Don't squash match_operator or match_parallel here, since
803 we don't know that all of the contained registers are
804 reachable by proper operands. */
805 if (recog_data.constraints[i][0] == '\0')
806 continue;
807 *recog_data.operand_loc[i] = cc0_rtx;
808 }
809 for (i = 0; i < recog_data.n_dups; i++)
810 {
811 old_dups[i] = *recog_data.dup_loc[i];
812 *recog_data.dup_loc[i] = cc0_rtx;
d98fed9f 813 }
d98fed9f 814
d5dfb455 815 scan_rtx (insn, &PATTERN (insn), NO_REGS, terminate_all_read,
816 OP_IN, 0);
d98fed9f 817
1140e77e 818 for (i = 0; i < recog_data.n_dups; i++)
819 *recog_data.dup_loc[i] = old_dups[i];
820 for (i = 0; i < n_ops; i++)
821 *recog_data.operand_loc[i] = old_operands[i];
b9a06185 822
1140e77e 823 /* Step 2B: Can't rename function call argument registers. */
824 if (GET_CODE (insn) == CALL_INSN && CALL_INSN_FUNCTION_USAGE (insn))
825 scan_rtx (insn, &CALL_INSN_FUNCTION_USAGE (insn),
d5dfb455 826 NO_REGS, terminate_all_read, OP_IN, 0);
b9a06185 827
1140e77e 828 /* Step 3: Append to chains for reads inside operands. */
829 for (i = 0; i < n_ops + recog_data.n_dups; i++)
830 {
831 int opn = i < n_ops ? i : recog_data.dup_num[i - n_ops];
832 rtx *loc = (i < n_ops
833 ? recog_data.operand_loc[opn]
834 : recog_data.dup_loc[i - n_ops]);
835 enum reg_class class = recog_op_alt[opn][alt].class;
836 enum op_type type = recog_data.operand_type[opn];
837
838 /* Don't scan match_operand here, since we've no reg class
839 information to pass down. Any operands that we could
840 substitute in will be represented elsewhere. */
841 if (recog_data.constraints[opn][0] == '\0')
842 continue;
b9a06185 843
1140e77e 844 if (recog_op_alt[opn][alt].is_address)
1f6f74af 845 scan_rtx_address (insn, loc, class, mark_read, VOIDmode);
1140e77e 846 else
d5dfb455 847 scan_rtx (insn, loc, class, mark_read, type, 0);
1140e77e 848 }
b9a06185 849
47dcd064 850 /* Step 4: Close chains for registers that die here.
851 Also record updates for REG_INC notes. */
1140e77e 852 for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
47dcd064 853 {
854 if (REG_NOTE_KIND (note) == REG_DEAD)
d5dfb455 855 scan_rtx (insn, &XEXP (note, 0), NO_REGS, terminate_dead,
856 OP_IN, 0);
47dcd064 857 else if (REG_NOTE_KIND (note) == REG_INC)
d5dfb455 858 scan_rtx (insn, &XEXP (note, 0), ALL_REGS, mark_read,
859 OP_INOUT, 0);
47dcd064 860 }
d98fed9f 861
1140e77e 862 /* Step 4B: If this is a call, any chain live at this point
863 requires a caller-saved reg. */
864 if (GET_CODE (insn) == CALL_INSN)
865 {
866 struct du_chain *p;
867 for (p = open_chains; p; p = p->next_chain)
d5dfb455 868 p->need_caller_save_reg = 1;
1140e77e 869 }
b9a06185 870
1140e77e 871 /* Step 5: Close open chains that overlap writes. Similar to
872 step 2, we hide in-out operands, since we do not want to
873 close these chains. */
b9a06185 874
1140e77e 875 for (i = 0; i < n_ops; i++)
876 {
877 old_operands[i] = recog_data.operand[i];
878 if (recog_data.operand_type[i] == OP_INOUT)
879 *recog_data.operand_loc[i] = cc0_rtx;
880 }
881 for (i = 0; i < recog_data.n_dups; i++)
882 {
883 int opn = recog_data.dup_num[i];
884 old_dups[i] = *recog_data.dup_loc[i];
885 if (recog_data.operand_type[opn] == OP_INOUT)
886 *recog_data.dup_loc[i] = cc0_rtx;
887 }
b9a06185 888
d5dfb455 889 scan_rtx (insn, &PATTERN (insn), NO_REGS, terminate_write, OP_IN, 0);
b9a06185 890
1140e77e 891 for (i = 0; i < recog_data.n_dups; i++)
892 *recog_data.dup_loc[i] = old_dups[i];
893 for (i = 0; i < n_ops; i++)
894 *recog_data.operand_loc[i] = old_operands[i];
b9a06185 895
1140e77e 896 /* Step 6: Begin new chains for writes inside operands. */
897 /* ??? Many targets have output constraints on the SET_DEST
898 of a call insn, which is stupid, since these are certainly
899 ABI defined hard registers. Don't change calls at all. */
900 if (GET_CODE (insn) != CALL_INSN)
901 for (i = 0; i < n_ops + recog_data.n_dups; i++)
902 {
903 int opn = i < n_ops ? i : recog_data.dup_num[i - n_ops];
904 rtx *loc = (i < n_ops
905 ? recog_data.operand_loc[opn]
906 : recog_data.dup_loc[i - n_ops]);
907 enum reg_class class = recog_op_alt[opn][alt].class;
908
909 if (recog_data.operand_type[opn] == OP_OUT)
d5dfb455 910 scan_rtx (insn, loc, class, mark_write, OP_OUT,
911 recog_op_alt[opn][alt].earlyclobber);
1140e77e 912 }
b9a06185 913
1140e77e 914 /* Step 7: Close chains for registers that were never
915 really used here. */
916 for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
917 if (REG_NOTE_KIND (note) == REG_UNUSED)
d5dfb455 918 scan_rtx (insn, &XEXP (note, 0), NO_REGS, terminate_dead,
919 OP_IN, 0);
1140e77e 920 }
921 if (insn == bb->end)
922 break;
923 }
b9a06185 924
1140e77e 925 /* Since we close every chain when we find a REG_DEAD note, anything that
926 is still open lives past the basic block, so it can't be renamed. */
927 return closed_chains;
928}
b9a06185 929
1140e77e 930/* Dump all def/use chains in CHAINS to RTL_DUMP_FILE. They are
931 printed in reverse order as that's how we build them. */
b9a06185 932
1140e77e 933static void
934dump_def_use_chain (chains)
935 struct du_chain *chains;
936{
937 while (chains)
d98fed9f 938 {
1140e77e 939 struct du_chain *this = chains;
940 int r = REGNO (*this->loc);
941 int nregs = HARD_REGNO_NREGS (r, GET_MODE (*this->loc));
942 fprintf (rtl_dump_file, "Register %s (%d):", reg_names[r], nregs);
943 while (this)
944 {
945 fprintf (rtl_dump_file, " %d [%s]", INSN_UID (this->insn),
946 reg_class_names[this->class]);
947 this = this->next_use;
948 }
949 fprintf (rtl_dump_file, "\n");
950 chains = chains->next_chain;
d98fed9f 951 }
b9a06185 952}