|
|
1.1 root 1: /* Compute register class preferences for pseudo-registers.
2: Copyright (C) 1987 Free Software Foundation, Inc.
3:
4: This file is part of GNU CC.
5:
6: GNU CC is distributed in the hope that it will be useful,
7: but WITHOUT ANY WARRANTY. No author or distributor
8: accepts responsibility to anyone for the consequences of using it
9: or for whether it serves any particular purpose or works at all,
10: unless he says so in writing. Refer to the GNU CC General Public
11: License for full details.
12:
13: Everyone is granted permission to copy, modify and redistribute
14: GNU CC, but only under the conditions described in the
15: GNU CC General Public License. A copy of this license is
16: supposed to have been given to you along with GNU CC so you
17: can know your rights and responsibilities. It should be in a
18: file named COPYING. Among other things, the copyright notice
19: and this notice must be preserved on all copies. */
20:
21:
22: /* This file contains two passes of the compiler: reg_scan and reg_class.
23: It also defines some tables of information about the hardware registers
24: and a function init_reg_sets to initialize the tables. */
25:
26: #include "config.h"
27: #include "rtl.h"
28: #include "hard-reg-set.h"
29: #include "flags.h"
30: #include "basic-block.h"
31: #include "regs.h"
32: #include "insn-config.h"
33: #include "recog.h"
34:
35: #define max(A,B) ((A) > (B) ? (A) : (B))
36: #define min(A,B) ((A) < (B) ? (A) : (B))
37:
38: /* Register tables used by many passes. */
39:
40: /* Indexed by hard register number, contains 1 for registers
41: that are fixed use (stack pointer, pc, frame pointer, etc.).
42: These are the registers that cannot be used to allocate
43: a pseudo reg whose life does not cross calls. */
44:
45: char fixed_regs[FIRST_PSEUDO_REGISTER];
46:
47: /* Same info as a HARD_REG_SET. */
48:
49: HARD_REG_SET fixed_reg_set;
50:
51: /* Data for initializing the above. */
52:
53: static char initial_fixed_regs[] = FIXED_REGISTERS;
54:
55: /* Indexed by hard register number, contains 1 for registers
56: that are fixed use or are clobbered by function calls.
57: These are the registers that cannot be used to allocate
58: a pseudo reg whose life crosses calls. */
59:
60: char call_used_regs[FIRST_PSEUDO_REGISTER];
61:
62: /* Same info as a HARD_REG_SET. */
63:
64: HARD_REG_SET call_used_reg_set;
65:
66: /* Data for initializing the above. */
67:
68: static char initial_call_used_regs[] = CALL_USED_REGISTERS;
69:
70: /* For each reg class, a HARD_REG_SET saying which registers are in it. */
71:
72: HARD_REG_SET reg_class_contents[] = REG_CLASS_CONTENTS;
73:
74: /* For each reg class, table listing all the containing classes. */
75:
76: enum reg_class reg_class_superclasses[N_REG_CLASSES][N_REG_CLASSES];
77:
78: /* For each reg class, table listing all the classes contained in it. */
79:
80: enum reg_class reg_class_subclasses[N_REG_CLASSES][N_REG_CLASSES];
81:
82: /* For each pair of reg classes,
83: a largest reg class contained in their union. */
84:
85: enum reg_class reg_class_subunion[N_REG_CLASSES][N_REG_CLASSES];
86:
87:
88: /* Function called only once to initialize the tables above. */
89:
90: void
91: init_reg_sets ()
92: {
93: register int i, j;
94:
95: bcopy (initial_fixed_regs, fixed_regs, sizeof fixed_regs);
96: bcopy (initial_call_used_regs, call_used_regs, sizeof call_used_regs);
97:
98: /* This macro allows the fixed or call-used registers
99: to depend on target flags. */
100:
101: #ifdef CONDITIONAL_REGISTER_USAGE
102: CONDITIONAL_REGISTER_USAGE
103: #endif
104:
105: /* Initialize "constant" tables. */
106:
107: CLEAR_HARD_REG_SET (fixed_reg_set);
108: CLEAR_HARD_REG_SET (call_used_reg_set);
109:
110: for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
111: {
112: if (fixed_regs[i])
113: SET_HARD_REG_BIT (fixed_reg_set, i);
114: if (call_used_regs[i])
115: SET_HARD_REG_BIT (call_used_reg_set, i);
116: }
117:
118: /* Initialize the table of subunions.
119: reg_class_subunion[I][J] gets the largest-numbered reg-class
120: that is contained in the union of classes I and J. */
121:
122: for (i = 0; i < N_REG_CLASSES; i++)
123: {
124: for (j = 0; j < N_REG_CLASSES; j++)
125: {
126: #ifdef HARD_REG_SET
127: register /* Declare it register if it's a scalar. */
128: #endif
129: HARD_REG_SET c;
130: register int k;
131:
132: COPY_HARD_REG_SET (c, reg_class_contents[i]);
133: IOR_HARD_REG_SET (c, reg_class_contents[j]);
134: for (k = 0; k < N_REG_CLASSES; k++)
135: {
136: GO_IF_HARD_REG_SUBSET (reg_class_contents[k], c,
137: subclass1);
138: continue;
139:
140: subclass1:
141: reg_class_subunion[i][j] = (enum reg_class) k;
142: }
143: }
144: }
145:
146: /* Initialize the tables of subclasses and superclasses of each reg class.
147: First clear the whole table, then add the elements as they are found. */
148:
149: for (i = 0; i < N_REG_CLASSES; i++)
150: {
151: for (j = 0; j < N_REG_CLASSES; j++)
152: {
153: reg_class_superclasses[i][j] = LIM_REG_CLASSES;
154: reg_class_subclasses[i][j] = LIM_REG_CLASSES;
155: }
156: }
157:
158: for (i = 0; i < N_REG_CLASSES; i++)
159: {
160: if (i == (int) NO_REGS)
161: continue;
162:
163: for (j = i + 1; j < N_REG_CLASSES; j++)
164: {
165: enum reg_class *p;
166:
167: GO_IF_HARD_REG_SUBSET (reg_class_contents[i], reg_class_contents[j],
168: subclass);
169: continue;
170: subclass:
171: /* Reg class I is a subclass of J.
172: Add J to the table of superclasses of I. */
173: p = ®_class_superclasses[i][0];
174: while (*p != LIM_REG_CLASSES) p++;
175: *p = (enum reg_class) j;
176: /* Add I to the table of superclasses of J. */
177: p = ®_class_subclasses[j][0];
178: while (*p != LIM_REG_CLASSES) p++;
179: *p = (enum reg_class) i;
180: }
181: }
182: }
183:
184: /* Specify the usage characteristics of the register named NAME.
185: It should be a fixed register if FIXED and a
186: call-used register if CALL_USED. */
187:
188: void
189: fix_register (name, fixed, call_used)
190: char *name;
191: int fixed, call_used;
192: {
193: static char *reg_names[] = REGISTER_NAMES;
194: int i;
195:
196: /* Decode the name and update the primary form of
197: the register info. */
198:
199: for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
200: if (!strcmp (reg_names[i], name))
201: {
202: fixed_regs[i] = fixed;
203: call_used_regs[i] = call_used;
204: break;
205: }
206:
207: if (i == FIRST_PSEUDO_REGISTER)
208: {
209: warning ("unknown register name: %s", name);
210: return;
211: }
212:
213: /* Reinitialize the HARD_REG_SETs that have the same info. */
214:
215: CLEAR_HARD_REG_SET (fixed_reg_set);
216: CLEAR_HARD_REG_SET (call_used_reg_set);
217:
218: for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
219: {
220: if (fixed_regs[i])
221: SET_HARD_REG_BIT (fixed_reg_set, i);
222: if (call_used_regs[i])
223: SET_HARD_REG_BIT (call_used_reg_set, i);
224: }
225: }
226:
227: /* Now the data and code for the `regclass' pass, which happens
228: just before local-alloc. */
229:
230: /* savings[R].savings[CL] is twice the amount saved by putting register R
231: in class CL. This data is used within `regclass' and freed
232: when it is finished. */
233:
234: struct savings
235: {
236: short savings[N_REG_CLASSES];
237: short memcost;
238: };
239:
240: static struct savings *savings;
241:
242: /* (enum reg_class) prefclass[R] is the preferred class for pseudo number R.
243: This is available after `regclass' is run. */
244:
245: static char *prefclass;
246:
247: /* preferred_or_nothing[R] is nonzero if we should put pseudo number R
248: in memory if we can't get its perferred class.
249: This is available after `regclass' is run. */
250:
251: static char *preferred_or_nothing;
252:
253: void reg_class_record ();
254: void record_address_regs ();
255:
256:
257: /* Return the reg_class in which pseudo reg number REGNO is best allocated.
258: This function is sometimes called before the info has been computed.
259: When that happens, just return GENERAL_REGS, which is innocuous. */
260:
261: enum reg_class
262: reg_preferred_class (regno)
263: int regno;
264: {
265: if (prefclass == 0)
266: return GENERAL_REGS;
267: return (enum reg_class) prefclass[regno];
268: }
269:
270: int
271: reg_preferred_or_nothing (regno)
272: {
273: if (prefclass == 0)
274: return 0;
275: return preferred_or_nothing[regno];
276: }
277:
278: /* This prevents dump_flow_info from losing if called
279: before regclass is run. */
280:
281: int
282: regclass_init ()
283: {
284: prefclass = 0;
285: }
286:
287: /* This is a pass of the compiler that scans all instructions
288: and calculates the preferred class for each pseudo-register.
289: This information can be accessed later by calling `reg_preferred_class'.
290: This pass comes just before local register allocation. */
291:
292: void
293: regclass (f, nregs)
294: rtx f;
295: int nregs;
296: {
297: #ifdef REGISTER_CONSTRAINTS
298: register rtx insn;
299: register int i;
300:
301: init_recog ();
302:
303: /* Zero out our accumulation of the cost of each class for each reg. */
304:
305: savings = (struct savings *) alloca (nregs * sizeof (struct savings));
306: bzero (savings, nregs * sizeof (struct savings));
307:
308: /* Scan the instructions and record each time it would
309: save code to put a certain register in a certain class. */
310:
311: for (insn = f; insn; insn = NEXT_INSN (insn))
312: if ((GET_CODE (insn) == INSN
313: && GET_CODE (PATTERN (insn)) != USE
314: && GET_CODE (PATTERN (insn)) != CLOBBER
315: && GET_CODE (PATTERN (insn)) != ASM_INPUT)
316: || (GET_CODE (insn) == JUMP_INSN
317: && GET_CODE (PATTERN (insn)) != ADDR_VEC
318: && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC)
319: || GET_CODE (insn) == CALL_INSN)
320: {
321: if (GET_CODE (insn) == INSN && asm_noperands (PATTERN (insn)) > 0)
322: {
323: int noperands = asm_noperands (PATTERN (insn));
324: rtx *operands = (rtx *) oballoc (noperands * sizeof (rtx));
325: char **constraints
326: = (char **) oballoc (noperands * sizeof (char *));
327:
328: decode_asm_operands (PATTERN (insn), operands, 0, constraints, 0);
329:
330: for (i = noperands - 1; i >= 0; i--)
331: reg_class_record (operands[i],
332: &constraints[i]);
333:
334: obfree (operands);
335: }
336: else
337: {
338: int insn_code_number = recog_memoized (insn);
339:
340: insn_extract (insn);
341:
342: for (i = insn_n_operands[insn_code_number] - 1; i >= 0; i--)
343: reg_class_record (recog_operand[i],
344: &insn_operand_constraint[insn_code_number][i]);
345:
346: /* Improve handling of two-address insns such as
347: (set X (ashift CONST Y)) where CONST must be made to match X.
348: Change it into two insns: (set X CONST) (set X (ashift X Y)).
349: If we left this for reloading, it would probably get three insns
350: because X and Y might go in the same place.
351: This prevents X and Y from receiving the same hard reg. */
352:
353: if (optimize
354: && insn_n_operands[insn_code_number] >= 3
355: && insn_operand_constraint[insn_code_number][1][0] == '0'
356: && insn_operand_constraint[insn_code_number][1][1] == 0
357: && CONSTANT_P (recog_operand[1])
358: && ! rtx_equal_p (recog_operand[0], recog_operand[1])
359: && ! rtx_equal_p (recog_operand[0], recog_operand[2])
360: && GET_CODE (recog_operand[0]) == REG)
361: {
362: rtx previnsn = prev_real_insn (insn);
363: rtx newinsn
364: = emit_insn_before (gen_move_insn (recog_operand[0],
365: recog_operand[1]),
366: insn);
367:
368: /* If this insn was the start of a basic block,
369: include the new insn in that block. */
370: if (previnsn == 0 || GET_CODE (previnsn) == JUMP_INSN)
371: {
372: int b;
373: for (b = 0; b < n_basic_blocks; b++)
374: if (insn == basic_block_head[b])
375: basic_block_head[b] = newinsn;
376: }
377:
378: /* This makes one more setting of new insns's destination. */
379: reg_n_sets[REGNO (recog_operand[0])]++;
380:
381: *recog_operand_loc[1] = recog_operand[0];
382: for (i = insn_n_dups[insn_code_number] - 1; i >= 0; i--)
383: if (recog_dup_num[i] == 1)
384: *recog_dup_loc[i] = recog_operand[0];
385:
386:
387: }
388: }
389: }
390:
391: /* Now for each register look at how desirable each class is
392: and find which class is preferred. Store that in `prefclass[REGNO]'. */
393:
394: prefclass = (char *) oballoc (nregs);
395:
396: preferred_or_nothing = (char *) oballoc (nregs);
397:
398: for (i = FIRST_PSEUDO_REGISTER; i < nregs; i++)
399: {
400: register int best_savings = 0;
401: enum reg_class best = ALL_REGS;
402:
403: /* This is an enum reg_class, but we call it an int
404: to save lots of casts. */
405: register int class;
406: register struct savings *p = &savings[i];
407:
408: for (class = (int) ALL_REGS - 1; class > 0; class--)
409: {
410: if (p->savings[class] > best_savings)
411: {
412: best_savings = p->savings[class];
413: best = (enum reg_class) class;
414: }
415: else if (p->savings[class] == best_savings)
416: {
417: best = reg_class_subunion[(int)best][class];
418: }
419: }
420:
421: #if 0
422: /* Note that best_savings is twice number of places something
423: is saved. */
424: if ((best_savings - p->savings[(int) GENERAL_REGS]) * 5 < reg_n_refs[i])
425: prefclass[i] = (char) GENERAL_REGS;
426: else
427: prefclass[i] = (char) best;
428: #else
429: prefclass[i] = (char) best;
430: #endif
431:
432: /* reg_n_refs + p->memcost measures the cost of putting in memory.
433: If a GENERAL_REG is no better, don't even try for one. */
434: if (reg_n_refs != 0)
435: preferred_or_nothing[i]
436: = ((best_savings - p->savings[(int) GENERAL_REGS]) / 2
437: >= reg_n_refs[i] + p->memcost);
438: }
439: #endif /* REGISTER_CONSTRAINTS */
440: }
441:
442: #ifdef REGISTER_CONSTRAINTS
443:
444: /* Scan an operand OP to which the constraint *CONSTRAINT_LOC should apply
445: and record the preferred register classes from the constraint for OP
446: if OP is a register. If OP is a memory reference, record suitable
447: preferences for registers used in the address.
448:
449: We can deduce both the insn code number and which operand in the insn
450: this is supposed to be from the position of CONSTRAINT_LOC
451: in the table of constraints. */
452:
453: void
454: reg_class_record (op, constraint_loc)
455: rtx op;
456: char **constraint_loc;
457: {
458: char *constraint = *constraint_loc;
459: register char *p;
460: register enum reg_class class = NO_REGS;
461: char *next = 0;
462: int insn_code = (constraint_loc - insn_operand_constraint[0]) / MAX_RECOG_OPERANDS;
463: int memok = 0;
464: int double_cost = 0;
465:
466: while (1)
467: {
468: if (GET_CODE (op) == SUBREG)
469: op = SUBREG_REG (op);
470: else break;
471: }
472:
473: /* Memory reference: scan the address. */
474:
475: if (GET_CODE (op) == MEM)
476: record_address_regs (XEXP (op, 0), 2, 0);
477:
478: if (GET_CODE (op) != REG)
479: {
480: /* If the constraint says the operand is supposed to BE an address,
481: scan it as one. */
482:
483: if (constraint != 0 && constraint[0] == 'p')
484: record_address_regs (op, 2, 0);
485: return;
486: }
487:
488: /* Operand is a register: examine the constraint for specified classes. */
489:
490: for (p = constraint; *p || next; p++)
491: {
492: if (*p == 0)
493: {
494: p = next;
495: next = 0;
496: }
497: switch (*p)
498: {
499: case '=':
500: case '?':
501: case '#':
502: case '!':
503: case '%':
504: case 'F':
505: case 'G':
506: case 'H':
507: case 'i':
508: case 'n':
509: case 's':
510: case 'p':
511: case ',':
512: break;
513:
514: case '+':
515: /* An input-output operand is twice as costly if it loses. */
516: double_cost = 1;
517: break;
518:
519: case 'm':
520: case 'o':
521: memok = 1;
522: break;
523:
524: /* * means ignore following letter
525: when choosing register preferences. */
526: case '*':
527: p++;
528: break;
529:
530: case 'g':
531: case 'r':
532: class
533: = reg_class_subunion[(int) class][(int) GENERAL_REGS];
534: break;
535:
536: case '0':
537: case '1':
538: case '2':
539: case '3':
540: case '4':
541: /* If constraint says "match another operand",
542: use that operand's constraint to choose preferences. */
543: next = insn_operand_constraint[insn_code][*p - '0'];
544: break;
545:
546: default:
547: class
548: = reg_class_subunion[(int) class][(int) REG_CLASS_FROM_LETTER (*p)];
549: }
550: }
551:
552: {
553: register int i;
554: register struct savings *pp;
555: register enum reg_class class1;
556: int cost = 2 * (1 + double_cost);
557: pp = &savings[REGNO (op)];
558:
559: /* Increment the savings for this reg
560: for each class contained in the one the constraint asks for. */
561:
562: if (class != NO_REGS && class != ALL_REGS)
563: {
564: pp->savings[(int) class] += cost;
565: for (i = 0; ; i++)
566: {
567: class1 = reg_class_subclasses[(int)class][i];
568: if (class1 == LIM_REG_CLASSES)
569: break;
570: pp->savings[(int) class1] += cost;
571: }
572: }
573:
574: if (! memok)
575: pp->memcost += 1 + 2 * double_cost;
576: }
577: }
578:
579: /* Record the pseudo registers we must reload into hard registers
580: in a subexpression of a memory address, X.
581: BCOST is the cost if X is a register and it fails to be in BASE_REG_CLASS.
582: ICOST is the cost if it fails to be in INDEX_REG_CLASS. */
583:
584: void
585: record_address_regs (x, bcost, icost)
586: rtx x;
587: int bcost, icost;
588: {
589: register RTX_CODE code = GET_CODE (x);
590:
591: switch (code)
592: {
593: case CONST_INT:
594: case CONST:
595: case CC0:
596: case PC:
597: case SYMBOL_REF:
598: case LABEL_REF:
599: return;
600:
601: case PLUS:
602: /* When we have an address that is a sum,
603: we must determine whether registers are "base" or "index" regs.
604: If there is a sum of two registers, we must choose one to be
605: the "base". Luckily, we can use the REGNO_POINTER_FLAG
606: to make a good choice most of the time. */
607: {
608: register RTX_CODE code0 = GET_CODE (XEXP (x, 0));
609: register RTX_CODE code1 = GET_CODE (XEXP (x, 1));
610: int icost0 = 0;
611: int icost1 = 0;
612: int suppress1 = 0;
613: int suppress0 = 0;
614:
615: if (code0 == MULT || code1 == MEM)
616: icost0 = 2;
617: else if (code1 == MULT || code0 == MEM)
618: icost1 = 2;
619: else if (code0 == CONST_INT)
620: suppress0 = 1;
621: else if (code1 == CONST_INT)
622: suppress1 = 1;
623: else if (code0 == REG && code1 == REG)
624: {
625: if (REGNO_POINTER_FLAG (REGNO (XEXP (x, 0))))
626: icost1 = 2;
627: else if (REGNO_POINTER_FLAG (REGNO (XEXP (x, 1))))
628: icost0 = 2;
629: else
630: icost0 = icost1 = 1;
631: }
632: else if (code0 == REG)
633: {
634: if (code1 == PLUS
635: && ! REGNO_POINTER_FLAG (REGNO (XEXP (x, 0))))
636: icost0 = 2;
637: else
638: REGNO_POINTER_FLAG (REGNO (XEXP (x, 0))) = 1;
639: }
640: else if (code1 == REG)
641: {
642: if (code0 == PLUS
643: && ! REGNO_POINTER_FLAG (REGNO (XEXP (x, 1))))
644: icost1 = 2;
645: else
646: REGNO_POINTER_FLAG (REGNO (XEXP (x, 1))) = 1;
647: }
648:
649: /* ICOST0 determines whether we are treating operand 0
650: as a base register or as an index register.
651: SUPPRESS0 nonzero means it isn't a register at all.
652: ICOST1 and SUPPRESS1 are likewise for operand 1. */
653:
654: if (! suppress0)
655: record_address_regs (XEXP (x, 0), 2 - icost0, icost0);
656: if (! suppress1)
657: record_address_regs (XEXP (x, 1), 2 - icost1, icost1);
658: }
659: break;
660:
661: case POST_INC:
662: case PRE_INC:
663: case POST_DEC:
664: case PRE_DEC:
665: /* Double the importance of a pseudo register that is incremented
666: or decremented, since it would take two extra insns
667: if it ends up in the wrong place. */
668: record_address_regs (XEXP (x, 0), 2 * bcost, 2 * icost);
669: break;
670:
671: case REG:
672: {
673: register struct savings *pp;
674: register enum reg_class class, class1;
675: pp = &savings[REGNO (x)];
676:
677: /* We have an address (or part of one) that is just one register. */
678:
679: /* Record BCOST worth of savings for classes contained
680: in BASE_REG_CLASS. */
681:
682: class = BASE_REG_CLASS;
683: if (class != NO_REGS && class != ALL_REGS)
684: {
685: register int i;
686: pp->savings[(int) class] += bcost;
687: for (i = 0; ; i++)
688: {
689: class1 = reg_class_subclasses[(int)class][i];
690: if (class1 == LIM_REG_CLASSES)
691: break;
692: pp->savings[(int) class1] += bcost;
693: }
694: }
695:
696: /* Record ICOST worth of savings for classes contained
697: in INDEX_REG_CLASS. */
698:
699: class = INDEX_REG_CLASS;
700: if (icost != 0 && class != NO_REGS && class != ALL_REGS)
701: {
702: register int i;
703: pp->savings[(int) class] += icost;
704: for (i = 0; ; i++)
705: {
706: class1 = reg_class_subclasses[(int)class][i];
707: if (class1 == LIM_REG_CLASSES)
708: break;
709: pp->savings[(int) class1] += icost;
710: }
711: }
712: }
713: break;
714:
715: default:
716: {
717: register char *fmt = GET_RTX_FORMAT (code);
718: register int i;
719: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
720: if (fmt[i] == 'e')
721: record_address_regs (XEXP (x, i), bcost, icost);
722: }
723: }
724: }
725: #endif /* REGISTER_CONSTRAINTS */
726:
727: /* This is the `regscan' pass of the compiler, run just before cse
728: and again just before loop.
729:
730: It finds the first and last use of each pseudo-register
731: and records them in the vectors regno_first_uid, regno_last_uid.
732: REPEAT is nonzero the second time this is called. */
733:
734: /* Indexed by pseudo register number, gives uid of first insn using the reg
735: (as of the time reg_scan is called). */
736:
737: short *regno_first_uid;
738:
739: /* Indexed by pseudo register number, gives uid of last insn using the reg
740: (as of the time reg_scan is called). */
741:
742: short *regno_last_uid;
743:
744: void reg_scan_mark_refs ();
745:
746: void
747: reg_scan (f, nregs, repeat)
748: rtx f;
749: int nregs;
750: int repeat;
751: {
752: register rtx insn;
753:
754: if (!repeat)
755: regno_first_uid = (short *) oballoc (nregs * sizeof (short));
756: bzero (regno_first_uid, nregs * sizeof (short));
757:
758: if (!repeat)
759: regno_last_uid = (short *) oballoc (nregs * sizeof (short));
760: bzero (regno_last_uid, nregs * sizeof (short));
761:
762: for (insn = f; insn; insn = NEXT_INSN (insn))
763: if (GET_CODE (insn) == INSN
764: || GET_CODE (insn) == CALL_INSN
765: || GET_CODE (insn) == JUMP_INSN)
766: reg_scan_mark_refs (PATTERN (insn), INSN_UID (insn));
767: }
768:
769: void
770: reg_scan_mark_refs (x, uid)
771: rtx x;
772: int uid;
773: {
774: register RTX_CODE code = GET_CODE (x);
775:
776: switch (code)
777: {
778: case CONST_INT:
779: case CONST:
780: case CONST_DOUBLE:
781: case CC0:
782: case PC:
783: case SYMBOL_REF:
784: case LABEL_REF:
785: return;
786:
787: case REG:
788: {
789: register int regno = REGNO (x);
790:
791: regno_last_uid[regno] = uid;
792: if (regno_first_uid[regno] == 0)
793: regno_first_uid[regno] = uid;
794: }
795: break;
796:
797: default:
798: {
799: register char *fmt = GET_RTX_FORMAT (code);
800: register int i;
801: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
802: {
803: if (fmt[i] == 'e')
804: reg_scan_mark_refs (XEXP (x, i), uid);
805: else if (fmt[i] == 'E')
806: {
807: register int j;
808: for (j = XVECLEN (x, i) - 1; j >= 0; j--)
809: reg_scan_mark_refs (XVECEXP (x, i, j), uid);
810: }
811: }
812: }
813: }
814: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.