]> gcc.gnu.org Git - gcc.git/blob - gcc/stupid.c
Include function.h in most files.
[gcc.git] / gcc / stupid.c
1 /* Dummy data flow analysis for GNU compiler in nonoptimizing mode.
2 Copyright (C) 1987, 91, 94-96, 1998 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21
22 /* This file performs stupid register allocation, which is used
23 when cc1 gets the -noreg switch (which is when cc does not get -O).
24
25 Stupid register allocation goes in place of the flow_analysis,
26 local_alloc and global_alloc passes. combine_instructions cannot
27 be done with stupid allocation because the data flow info that it needs
28 is not computed here.
29
30 In stupid allocation, the only user-defined variables that can
31 go in registers are those declared "register". They are assumed
32 to have a life span equal to their scope. Other user variables
33 are given stack slots in the rtl-generation pass and are not
34 represented as pseudo regs. A compiler-generated temporary
35 is assumed to live from its first mention to its last mention.
36
37 Since each pseudo-reg's life span is just an interval, it can be
38 represented as a pair of numbers, each of which identifies an insn by
39 its position in the function (number of insns before it). The first
40 thing done for stupid allocation is to compute such a number for each
41 insn. It is called the suid. Then the life-interval of each
42 pseudo reg is computed. Then the pseudo regs are ordered by priority
43 and assigned hard regs in priority order. */
44
45 #include "config.h"
46 #include "system.h"
47
48 #include "rtl.h"
49 #include "hard-reg-set.h"
50 #include "basic-block.h"
51 #include "regs.h"
52 #include "function.h"
53 #include "insn-config.h"
54 #include "reload.h"
55 #include "flags.h"
56 #include "toplev.h"
57 \f
58 /* Vector mapping INSN_UIDs to suids.
59 The suids are like uids but increase monotonically always.
60 We use them to see whether a subroutine call came
61 between a variable's birth and its death. */
62
63 static int *uid_suid;
64
65 /* Get the suid of an insn. */
66
67 #define INSN_SUID(INSN) (uid_suid[INSN_UID (INSN)])
68
69 /* Record the suid of the last CALL_INSN
70 so we can tell whether a pseudo reg crosses any calls. */
71
72 static int last_call_suid;
73
74 /* Record the suid of the last NOTE_INSN_SETJMP
75 so we can tell whether a pseudo reg crosses any setjmp. */
76
77 static int last_setjmp_suid;
78
79 /* Element N is suid of insn where life span of pseudo reg N ends.
80 Element is 0 if register N has not been seen yet on backward scan. */
81
82 static int *reg_where_dead;
83
84 /* Likewise, but point to the insn_chain structure of the insn at which
85 the reg dies. */
86 static struct insn_chain **reg_where_dead_chain;
87
88 /* Element N is suid of insn where life span of pseudo reg N begins. */
89 static int *reg_where_born_exact;
90
91 /* Element N is 1 if the birth of pseudo reg N is due to a CLOBBER,
92 0 otherwise. */
93 static int *reg_where_born_clobber;
94
95 /* Return the suid of the insn where the register is born, or the suid
96 of the insn before if the birth is due to a CLOBBER. */
97 #define REG_WHERE_BORN(N) \
98 (reg_where_born_exact[(N)] - reg_where_born_clobber[(N)])
99
100 /* Numbers of pseudo-regs to be allocated, highest priority first. */
101
102 static int *reg_order;
103
104 /* Indexed by reg number (hard or pseudo), nonzero if register is live
105 at the current point in the instruction stream. */
106
107 static char *regs_live;
108
109 /* Indexed by reg number, nonzero if reg was used in a SUBREG that changes
110 its size. */
111
112 static char *regs_change_size;
113
114 /* Indexed by reg number, nonzero if reg crosses a setjmp. */
115
116 static char *regs_crosses_setjmp;
117
118 /* Indexed by insn's suid, the set of hard regs live after that insn. */
119
120 static HARD_REG_SET *after_insn_hard_regs;
121
122 /* Record that hard reg REGNO is live after insn INSN. */
123
124 #define MARK_LIVE_AFTER(INSN,REGNO) \
125 SET_HARD_REG_BIT (after_insn_hard_regs[INSN_SUID (INSN)], (REGNO))
126
127 static int stupid_reg_compare PROTO((const GENERIC_PTR,const GENERIC_PTR));
128 static int stupid_find_reg PROTO((int, enum reg_class, enum machine_mode,
129 int, int, int));
130 static void stupid_mark_refs PROTO((rtx, struct insn_chain *));
131 static void find_clobbered_regs PROTO((rtx, rtx));
132 \f
133 /* For communication between stupid_life_analysis and find_clobbered_regs. */
134 static struct insn_chain *current_chain;
135
136 /* This function, called via note_stores, marks any hard registers that are
137 clobbered in an insn as being live in the live_after and live_before fields
138 of the appropriate insn_chain structure. */
139
140 static void
141 find_clobbered_regs (reg, setter)
142 rtx reg, setter;
143 {
144 int regno, nregs;
145 if (setter == 0 || GET_CODE (setter) != CLOBBER)
146 return;
147
148 if (GET_CODE (reg) == SUBREG)
149 reg = SUBREG_REG (reg);
150
151 if (GET_CODE (reg) != REG)
152 return;
153 regno = REGNO (reg);
154 if (regno >= FIRST_PSEUDO_REGISTER)
155 return;
156
157 if (GET_MODE (reg) == VOIDmode)
158 abort ();
159 else
160 nregs = HARD_REGNO_NREGS (regno, GET_MODE (reg));
161 while (nregs-- > 0)
162 {
163 SET_REGNO_REG_SET (current_chain->live_after, regno);
164 SET_REGNO_REG_SET (current_chain->live_before, regno++);
165 }
166 }
167 \f
168 /* Stupid life analysis is for the case where only variables declared
169 `register' go in registers. For this case, we mark all
170 pseudo-registers that belong to register variables as
171 dying in the last instruction of the function, and all other
172 pseudo registers as dying in the last place they are referenced.
173 Hard registers are marked as dying in the last reference before
174 the end or before each store into them. */
175
176 void
177 stupid_life_analysis (f, nregs, file)
178 rtx f;
179 int nregs;
180 FILE *file;
181 {
182 register int i;
183 register rtx last, insn;
184 int max_uid, max_suid;
185
186 current_function_has_computed_jump = 0;
187
188 bzero (regs_ever_live, sizeof regs_ever_live);
189
190 regs_live = (char *) xmalloc (nregs);
191
192 /* First find the last real insn, and count the number of insns,
193 and assign insns their suids. */
194
195 for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
196 if (INSN_UID (insn) > i)
197 i = INSN_UID (insn);
198
199 max_uid = i + 1;
200 uid_suid = (int *) xmalloc ((i + 1) * sizeof (int));
201
202 /* Compute the mapping from uids to suids.
203 Suids are numbers assigned to insns, like uids,
204 except that suids increase monotonically through the code. */
205
206 last = 0; /* In case of empty function body */
207 for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
208 {
209 if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
210 last = insn;
211
212 INSN_SUID (insn) = ++i;
213 }
214
215 last_call_suid = i + 1;
216 last_setjmp_suid = i + 1;
217 max_suid = i + 1;
218
219 max_regno = nregs;
220
221 /* Allocate tables to record info about regs. */
222
223 reg_where_dead = (int *) xmalloc (nregs * sizeof (int));
224 bzero ((char *) reg_where_dead, nregs * sizeof (int));
225
226 reg_where_born_exact = (int *) xmalloc (nregs * sizeof (int));
227 bzero ((char *) reg_where_born_exact, nregs * sizeof (int));
228
229 reg_where_born_clobber = (int *) xmalloc (nregs * sizeof (int));
230 bzero ((char *) reg_where_born_clobber, nregs * sizeof (int));
231
232 reg_where_dead_chain = (struct insn_chain **) xmalloc (nregs * sizeof (struct insn_chain *));
233 bzero ((char *) reg_where_dead_chain, nregs * sizeof (struct insn_chain *));
234
235 reg_order = (int *) xmalloc (nregs * sizeof (int));
236 bzero ((char *) reg_order, nregs * sizeof (int));
237
238 regs_change_size = (char *) xmalloc (nregs * sizeof (char));
239 bzero ((char *) regs_change_size, nregs * sizeof (char));
240
241 regs_crosses_setjmp = (char *) xmalloc (nregs * sizeof (char));
242 bzero ((char *) regs_crosses_setjmp, nregs * sizeof (char));
243
244 /* Allocate the reg_renumber array */
245 allocate_reg_info (max_regno, FALSE, TRUE);
246 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
247 reg_renumber[i] = i;
248
249 after_insn_hard_regs
250 = (HARD_REG_SET *) xmalloc (max_suid * sizeof (HARD_REG_SET));
251
252 bzero ((char *) after_insn_hard_regs, max_suid * sizeof (HARD_REG_SET));
253
254 /* Allocate and zero out many data structures
255 that will record the data from lifetime analysis. */
256
257 allocate_reg_life_data ();
258 allocate_bb_life_data ();
259
260 for (i = 0; i < max_regno; i++)
261 REG_N_DEATHS (i) = 1;
262
263 bzero (regs_live, nregs);
264
265 /* Find where each pseudo register is born and dies,
266 by scanning all insns from the end to the start
267 and noting all mentions of the registers.
268
269 Also find where each hard register is live
270 and record that info in after_insn_hard_regs.
271 regs_live[I] is 1 if hard reg I is live
272 at the current point in the scan.
273
274 Build reload_insn_chain while we're walking the insns. */
275
276 reload_insn_chain = 0;
277 for (insn = last; insn; insn = PREV_INSN (insn))
278 {
279 register HARD_REG_SET *p = after_insn_hard_regs + INSN_SUID (insn);
280 struct insn_chain *chain;
281
282 /* Copy the info in regs_live into the element of after_insn_hard_regs
283 for the current position in the rtl code. */
284
285 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
286 if (regs_live[i])
287 SET_HARD_REG_BIT (*p, i);
288
289 if (GET_CODE (insn) != NOTE && GET_CODE (insn) != BARRIER)
290 {
291 chain = new_insn_chain ();
292 if (reload_insn_chain)
293 reload_insn_chain->prev = chain;
294 chain->next = reload_insn_chain;
295 chain->prev = 0;
296 reload_insn_chain = chain;
297 chain->block = 0;
298 chain->insn = insn;
299 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
300 if (regs_live[i])
301 SET_REGNO_REG_SET (chain->live_before, i);
302 }
303
304 /* Update which hard regs are currently live
305 and also the birth and death suids of pseudo regs
306 based on the pattern of this insn. */
307
308 if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
309 stupid_mark_refs (PATTERN (insn), chain);
310
311 if (GET_CODE (insn) == NOTE
312 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_SETJMP)
313 last_setjmp_suid = INSN_SUID (insn);
314
315 /* Mark all call-clobbered regs as dead after each call insn so that
316 a pseudo whose life span includes this insn will not go in one of
317 them. If the function contains a non-local goto, mark all hard
318 registers dead (except for stack related bits).
319
320 Then mark those regs as all dead for the continuing scan
321 of the insns before the call. */
322
323 if (GET_CODE (insn) == CALL_INSN)
324 {
325 last_call_suid = INSN_SUID (insn);
326
327 if (current_function_has_nonlocal_label)
328 {
329 IOR_COMPL_HARD_REG_SET (after_insn_hard_regs[last_call_suid],
330 fixed_reg_set);
331 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
332 if (! fixed_regs[i])
333 regs_live[i] = 0;
334 }
335 else
336 {
337 IOR_HARD_REG_SET (after_insn_hard_regs[last_call_suid],
338 call_used_reg_set);
339 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
340 if (call_used_regs[i])
341 regs_live[i] = 0;
342 }
343
344 /* It is important that this be done after processing the insn's
345 pattern because we want the function result register to still
346 be live if it's also used to pass arguments. */
347 stupid_mark_refs (CALL_INSN_FUNCTION_USAGE (insn), chain);
348 }
349
350 if (GET_CODE (insn) != NOTE && GET_CODE (insn) != BARRIER)
351 {
352 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
353 if (regs_live[i])
354 SET_REGNO_REG_SET (chain->live_after, i);
355
356 /* The regs_live array doesn't say anything about hard registers
357 clobbered by this insn. So we need an extra pass over the
358 pattern. */
359 current_chain = chain;
360 if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
361 note_stores (PATTERN (insn), find_clobbered_regs);
362 }
363
364 if (GET_CODE (insn) == JUMP_INSN && computed_jump_p (insn))
365 current_function_has_computed_jump = 1;
366 }
367
368 /* Now decide the order in which to allocate the pseudo registers. */
369
370 for (i = LAST_VIRTUAL_REGISTER + 1; i < max_regno; i++)
371 reg_order[i] = i;
372
373 qsort (&reg_order[LAST_VIRTUAL_REGISTER + 1],
374 max_regno - LAST_VIRTUAL_REGISTER - 1, sizeof (int),
375 stupid_reg_compare);
376
377 /* Now, in that order, try to find hard registers for those pseudo regs. */
378
379 for (i = LAST_VIRTUAL_REGISTER + 1; i < max_regno; i++)
380 {
381 register int r = reg_order[i];
382
383 /* Some regnos disappear from the rtl. Ignore them to avoid crash.
384 Also don't allocate registers that cross a setjmp, or live across
385 a call if this function receives a nonlocal goto.
386 Also ignore registers we didn't see during the scan. */
387 if (regno_reg_rtx[r] == 0 || regs_crosses_setjmp[r]
388 || (reg_where_born_exact[r] == 0 && reg_where_dead[r] == 0)
389 || (REG_N_CALLS_CROSSED (r) > 0
390 && current_function_has_nonlocal_label))
391 continue;
392
393 /* Now find the best hard-register class for this pseudo register */
394 if (N_REG_CLASSES > 1)
395 reg_renumber[r] = stupid_find_reg (REG_N_CALLS_CROSSED (r),
396 reg_preferred_class (r),
397 PSEUDO_REGNO_MODE (r),
398 REG_WHERE_BORN (r),
399 reg_where_dead[r],
400 regs_change_size[r]);
401
402 /* If no reg available in that class, try alternate class. */
403 if (reg_renumber[r] == -1 && reg_alternate_class (r) != NO_REGS)
404 reg_renumber[r] = stupid_find_reg (REG_N_CALLS_CROSSED (r),
405 reg_alternate_class (r),
406 PSEUDO_REGNO_MODE (r),
407 REG_WHERE_BORN (r),
408 reg_where_dead[r],
409 regs_change_size[r]);
410 }
411
412 /* Fill in the pseudo reg life information into the insn chain. */
413 for (i = LAST_VIRTUAL_REGISTER + 1; i < max_regno; i++)
414 {
415 struct insn_chain *chain;
416 int regno;
417
418 regno = reg_renumber[i];
419 if (regno < 0)
420 continue;
421
422 chain = reg_where_dead_chain[i];
423 if (reg_where_dead[i] > INSN_SUID (chain->insn))
424 SET_REGNO_REG_SET (chain->live_after, i);
425
426 while (INSN_SUID (chain->insn) > reg_where_born_exact[i])
427 {
428 SET_REGNO_REG_SET (chain->live_before, i);
429 chain = chain->prev;
430 if (!chain)
431 break;
432 SET_REGNO_REG_SET (chain->live_after, i);
433 }
434
435 if (INSN_SUID (chain->insn) == reg_where_born_exact[i]
436 && reg_where_born_clobber[i])
437 SET_REGNO_REG_SET (chain->live_before, i);
438 }
439
440 if (file)
441 dump_flow_info (file);
442
443 free (regs_live);
444 free (uid_suid);
445 free (reg_where_dead);
446 free (reg_where_born_exact);
447 free (reg_where_born_clobber);
448 free (reg_where_dead_chain);
449 free (reg_order);
450 free (regs_change_size);
451 free (regs_crosses_setjmp);
452 free (after_insn_hard_regs);
453 }
454
455 /* Comparison function for qsort.
456 Returns -1 (1) if register *R1P is higher priority than *R2P. */
457
458 static int
459 stupid_reg_compare (r1p, r2p)
460 const GENERIC_PTR r1p;
461 const GENERIC_PTR r2p;
462 {
463 register int r1 = *(int *)r1p, r2 = *(int *)r2p;
464 register int len1 = reg_where_dead[r1] - REG_WHERE_BORN (r1);
465 register int len2 = reg_where_dead[r2] - REG_WHERE_BORN (r2);
466 int tem;
467
468 tem = len2 - len1;
469 if (tem != 0)
470 return tem;
471
472 tem = REG_N_REFS (r1) - REG_N_REFS (r2);
473 if (tem != 0)
474 return tem;
475
476 /* If regs are equally good, sort by regno,
477 so that the results of qsort leave nothing to chance. */
478 return r1 - r2;
479 }
480 \f
481 /* Find a block of SIZE words of hard registers in reg_class CLASS
482 that can hold a value of machine-mode MODE
483 (but actually we test only the first of the block for holding MODE)
484 currently free from after insn whose suid is BORN_INSN
485 through the insn whose suid is DEAD_INSN,
486 and return the number of the first of them.
487 Return -1 if such a block cannot be found.
488
489 If CALL_PRESERVED is nonzero, insist on registers preserved
490 over subroutine calls, and return -1 if cannot find such.
491
492 If CHANGES_SIZE is nonzero, it means this register was used as the
493 operand of a SUBREG that changes its size. */
494
495 static int
496 stupid_find_reg (call_preserved, class, mode,
497 born_insn, dead_insn, changes_size)
498 int call_preserved;
499 enum reg_class class;
500 enum machine_mode mode;
501 int born_insn, dead_insn;
502 int changes_size ATTRIBUTE_UNUSED;
503 {
504 register int i, ins;
505 #ifdef HARD_REG_SET
506 register /* Declare them register if they are scalars. */
507 #endif
508 HARD_REG_SET used, this_reg;
509 #ifdef ELIMINABLE_REGS
510 static struct {int from, to; } eliminables[] = ELIMINABLE_REGS;
511 #endif
512
513 /* If this register's life is more than 5,000 insns, we probably
514 can't allocate it, so don't waste the time trying. This avoids
515 quadratic behavior on programs that have regularly-occurring
516 SAVE_EXPRs. */
517 if (dead_insn > born_insn + 5000)
518 return -1;
519
520 COPY_HARD_REG_SET (used,
521 call_preserved ? call_used_reg_set : fixed_reg_set);
522
523 #ifdef ELIMINABLE_REGS
524 for (i = 0; i < (int)(sizeof eliminables / sizeof eliminables[0]); i++)
525 SET_HARD_REG_BIT (used, eliminables[i].from);
526 #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
527 SET_HARD_REG_BIT (used, HARD_FRAME_POINTER_REGNUM);
528 #endif
529 #else
530 SET_HARD_REG_BIT (used, FRAME_POINTER_REGNUM);
531 #endif
532
533 for (ins = born_insn; ins < dead_insn; ins++)
534 IOR_HARD_REG_SET (used, after_insn_hard_regs[ins]);
535
536 #ifdef STACK_REGS
537 if (current_function_has_computed_jump)
538 for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
539 SET_HARD_REG_BIT (used, i);
540 #endif
541
542 IOR_COMPL_HARD_REG_SET (used, reg_class_contents[(int) class]);
543
544 #ifdef CLASS_CANNOT_CHANGE_SIZE
545 if (changes_size)
546 IOR_HARD_REG_SET (used,
547 reg_class_contents[(int) CLASS_CANNOT_CHANGE_SIZE]);
548 #endif
549
550 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
551 {
552 #ifdef REG_ALLOC_ORDER
553 int regno = reg_alloc_order[i];
554 #else
555 int regno = i;
556 #endif
557
558 /* If a register has screwy overlap problems,
559 don't use it at all if not optimizing.
560 Actually this is only for the 387 stack register,
561 and it's because subsequent code won't work. */
562 #ifdef OVERLAPPING_REGNO_P
563 if (OVERLAPPING_REGNO_P (regno))
564 continue;
565 #endif
566
567 if (! TEST_HARD_REG_BIT (used, regno)
568 && HARD_REGNO_MODE_OK (regno, mode))
569 {
570 register int j;
571 register int size1 = HARD_REGNO_NREGS (regno, mode);
572 for (j = 1; j < size1 && ! TEST_HARD_REG_BIT (used, regno + j); j++);
573 if (j == size1)
574 {
575 CLEAR_HARD_REG_SET (this_reg);
576 while (--j >= 0)
577 SET_HARD_REG_BIT (this_reg, regno + j);
578 for (ins = born_insn; ins < dead_insn; ins++)
579 {
580 IOR_HARD_REG_SET (after_insn_hard_regs[ins], this_reg);
581 }
582 return regno;
583 }
584 #ifndef REG_ALLOC_ORDER
585 i += j; /* Skip starting points we know will lose */
586 #endif
587 }
588 }
589
590 return -1;
591 }
592 \f
593 /* Walk X, noting all assignments and references to registers
594 and recording what they imply about life spans.
595 INSN is the current insn, supplied so we can find its suid. */
596
597 static void
598 stupid_mark_refs (x, chain)
599 rtx x;
600 struct insn_chain *chain;
601 {
602 register RTX_CODE code;
603 register char *fmt;
604 register int regno, i;
605 rtx insn = chain->insn;
606
607 if (x == 0)
608 return;
609
610 code = GET_CODE (x);
611
612 if (code == SET || code == CLOBBER)
613 {
614 if (SET_DEST (x) != 0
615 && (GET_CODE (SET_DEST (x)) == REG
616 || (GET_CODE (SET_DEST (x)) == SUBREG
617 && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG
618 && (REGNO (SUBREG_REG (SET_DEST (x)))
619 >= FIRST_PSEUDO_REGISTER))))
620 {
621 /* Register is being assigned. */
622 /* If setting a SUBREG, we treat the entire reg as being set. */
623 if (GET_CODE (SET_DEST (x)) == SUBREG)
624 regno = REGNO (SUBREG_REG (SET_DEST (x)));
625 else
626 regno = REGNO (SET_DEST (x));
627
628 /* For hard regs, update the where-live info. */
629 if (regno < FIRST_PSEUDO_REGISTER)
630 {
631 register int j
632 = HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (x)));
633
634 while (--j >= 0)
635 {
636 regs_ever_live[regno+j] = 1;
637 regs_live[regno+j] = 0;
638
639 /* The following line is for unused outputs;
640 they do get stored even though never used again. */
641 MARK_LIVE_AFTER (insn, regno+j);
642
643 /* When a hard reg is clobbered, mark it in use
644 just before this insn, so it is live all through. */
645 if (code == CLOBBER && INSN_SUID (insn) > 0)
646 SET_HARD_REG_BIT (after_insn_hard_regs[INSN_SUID (insn) - 1],
647 regno+j);
648 }
649 }
650 /* For pseudo regs, record where born, where dead, number of
651 times used, and whether live across a call. */
652 else
653 {
654 /* Update the life-interval bounds of this pseudo reg. */
655
656 /* When a pseudo-reg is CLOBBERed, it is born just before
657 the clobbering insn. When setting, just after. */
658 int where_born = INSN_SUID (insn) - (code == CLOBBER);
659
660 reg_where_born_exact[regno] = INSN_SUID (insn);
661 reg_where_born_clobber[regno] = (code == CLOBBER);
662
663 if (reg_where_dead_chain[regno] == 0)
664 reg_where_dead_chain[regno] = chain;
665
666 /* The reg must live at least one insn even
667 in it is never again used--because it has to go
668 in SOME hard reg. Mark it as dying after the current
669 insn so that it will conflict with any other outputs of
670 this insn. */
671 if (reg_where_dead[regno] < where_born + 2)
672 {
673 reg_where_dead[regno] = where_born + 2;
674 regs_live[regno] = 1;
675 }
676
677 /* Count the refs of this reg. */
678 REG_N_REFS (regno)++;
679
680 if (last_call_suid < reg_where_dead[regno])
681 REG_N_CALLS_CROSSED (regno) += 1;
682
683 if (last_setjmp_suid < reg_where_dead[regno])
684 regs_crosses_setjmp[regno] = 1;
685
686 /* If this register is clobbered or it is only used in
687 this insn and is only set, mark it unused. We have
688 to do this even when not optimizing so that MD patterns
689 which count on this behavior (e.g., it not causing an
690 output reload on an insn setting CC) will operate
691 correctly. */
692 if (GET_CODE (SET_DEST (x)) == REG
693 && (code == CLOBBER
694 || (REGNO_FIRST_UID (regno) == INSN_UID (insn)
695 && REGNO_LAST_UID (regno) == INSN_UID (insn)
696 && ! reg_mentioned_p (SET_DEST (x),
697 SET_SRC (x)))))
698 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_UNUSED,
699 SET_DEST (x),
700 REG_NOTES (insn));
701 }
702 }
703
704 /* Record references from the value being set,
705 or from addresses in the place being set if that's not a reg.
706 If setting a SUBREG, we treat the entire reg as *used*. */
707 if (code == SET)
708 {
709 stupid_mark_refs (SET_SRC (x), chain);
710 if (GET_CODE (SET_DEST (x)) != REG)
711 stupid_mark_refs (SET_DEST (x), chain);
712 }
713 return;
714 }
715
716 else if (code == SUBREG
717 && GET_CODE (SUBREG_REG (x)) == REG
718 && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER
719 && (GET_MODE_SIZE (GET_MODE (x))
720 != GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
721 && (INTEGRAL_MODE_P (GET_MODE (x))
722 || INTEGRAL_MODE_P (GET_MODE (SUBREG_REG (x)))))
723 regs_change_size[REGNO (SUBREG_REG (x))] = 1;
724
725 /* Register value being used, not set. */
726
727 else if (code == REG)
728 {
729 regno = REGNO (x);
730 if (regno < FIRST_PSEUDO_REGISTER)
731 {
732 /* Hard reg: mark it live for continuing scan of previous insns. */
733 register int j = HARD_REGNO_NREGS (regno, GET_MODE (x));
734 while (--j >= 0)
735 {
736 regs_ever_live[regno+j] = 1;
737 regs_live[regno+j] = 1;
738 }
739 }
740 else
741 {
742 /* Pseudo reg: record first use, last use and number of uses. */
743
744 reg_where_born_exact[regno] = INSN_SUID (insn);
745 reg_where_born_clobber[regno] = 0;
746 REG_N_REFS (regno)++;
747 if (regs_live[regno] == 0)
748 {
749 regs_live[regno] = 1;
750 reg_where_dead[regno] = INSN_SUID (insn);
751 reg_where_dead_chain[regno] = chain;
752 }
753 }
754 return;
755 }
756
757 /* Recursive scan of all other rtx's. */
758
759 fmt = GET_RTX_FORMAT (code);
760 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
761 {
762 if (fmt[i] == 'e')
763 stupid_mark_refs (XEXP (x, i), chain);
764 if (fmt[i] == 'E')
765 {
766 register int j;
767 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
768 stupid_mark_refs (XVECEXP (x, i, j), chain);
769 }
770 }
771 }
This page took 0.083975 seconds and 6 git commands to generate.