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