OSDN Git Service

[pf3gnuchains/gcc-fork.git] / gcc / stupid.c
1 /* Dummy data flow analysis for GNU compiler in nonoptimizing mode.
2    Copyright (C) 1987, 91, 94, 95, 96, 1997 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_for_life_analysis ();
257
258   for (i = 0; i < max_regno; i++)
259     REG_N_DEATHS (i) = 1;
260
261   bzero (regs_live, nregs);
262
263   /* Find where each pseudo register is born and dies,
264      by scanning all insns from the end to the start
265      and noting all mentions of the registers.
266
267      Also find where each hard register is live
268      and record that info in after_insn_hard_regs.
269      regs_live[I] is 1 if hard reg I is live
270      at the current point in the scan.  
271    
272      Build reload_insn_chain while we're walking the insns.  */
273
274   reload_insn_chain = 0;
275   for (insn = last; insn; insn = PREV_INSN (insn))
276     {
277       register HARD_REG_SET *p = after_insn_hard_regs + INSN_SUID (insn);
278       struct insn_chain *chain;
279
280       /* Copy the info in regs_live into the element of after_insn_hard_regs
281          for the current position in the rtl code.  */
282
283       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
284         if (regs_live[i])
285           SET_HARD_REG_BIT (*p, i);
286
287       if (GET_CODE (insn) != NOTE && GET_CODE (insn) != BARRIER)
288         {
289           chain = new_insn_chain ();
290           if (reload_insn_chain)
291             reload_insn_chain->prev = chain;
292           chain->next = reload_insn_chain;
293           chain->prev = 0;
294           reload_insn_chain = chain;
295           chain->block = 0;
296           chain->insn = insn;
297           for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
298             if (regs_live[i])
299               SET_REGNO_REG_SET (chain->live_before, i);
300         }
301
302       /* Update which hard regs are currently live
303          and also the birth and death suids of pseudo regs
304          based on the pattern of this insn.  */
305
306       if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
307         stupid_mark_refs (PATTERN (insn), chain);
308
309       if (GET_CODE (insn) == NOTE
310           && NOTE_LINE_NUMBER (insn) == NOTE_INSN_SETJMP)
311         last_setjmp_suid = INSN_SUID (insn);
312
313       /* Mark all call-clobbered regs as dead after each call insn so that
314          a pseudo whose life span includes this insn will not go in one of
315          them.  If the function contains a non-local goto, mark all hard
316          registers dead (except for stack related bits).
317
318          Then mark those regs as all dead for the continuing scan
319          of the insns before the call.  */
320
321       if (GET_CODE (insn) == CALL_INSN)
322         {
323           last_call_suid = INSN_SUID (insn);
324
325           if (current_function_has_nonlocal_label)
326             {
327               IOR_COMPL_HARD_REG_SET (after_insn_hard_regs[last_call_suid],
328                                       fixed_reg_set);
329               for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
330                 if (! fixed_regs[i])
331                   regs_live[i] = 0;
332             }
333           else
334             {
335               IOR_HARD_REG_SET (after_insn_hard_regs[last_call_suid],
336                                 call_used_reg_set);
337               for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
338                 if (call_used_regs[i])
339                   regs_live[i] = 0;
340             }
341
342           /* It is important that this be done after processing the insn's
343              pattern because we want the function result register to still
344              be live if it's also used to pass arguments.  */
345           stupid_mark_refs (CALL_INSN_FUNCTION_USAGE (insn), chain);
346         }
347
348       if (GET_CODE (insn) != NOTE && GET_CODE (insn) != BARRIER)
349         {         
350           for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
351             if (regs_live[i])
352               SET_REGNO_REG_SET (chain->live_after, i);
353
354           /* The regs_live array doesn't say anything about hard registers
355              clobbered by this insn.  So we need an extra pass over the
356              pattern.  */
357           current_chain = chain;
358           if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
359             note_stores (PATTERN (insn), find_clobbered_regs);
360         }
361
362       if (GET_CODE (insn) == JUMP_INSN && computed_jump_p (insn))
363         current_function_has_computed_jump = 1;
364     }
365
366   /* Now decide the order in which to allocate the pseudo registers.  */
367
368   for (i = LAST_VIRTUAL_REGISTER + 1; i < max_regno; i++)
369     reg_order[i] = i;
370
371   qsort (&reg_order[LAST_VIRTUAL_REGISTER + 1],
372          max_regno - LAST_VIRTUAL_REGISTER - 1, sizeof (int),
373          stupid_reg_compare);
374
375   /* Now, in that order, try to find hard registers for those pseudo regs.  */
376
377   for (i = LAST_VIRTUAL_REGISTER + 1; i < max_regno; i++)
378     {
379       register int r = reg_order[i];
380
381       /* Some regnos disappear from the rtl.  Ignore them to avoid crash. 
382          Also don't allocate registers that cross a setjmp, or live across
383          a call if this function receives a nonlocal goto.
384          Also ignore registers we didn't see during the scan.  */
385       if (regno_reg_rtx[r] == 0 || regs_crosses_setjmp[r]
386           || (reg_where_born_exact[r] == 0 && reg_where_dead[r] == 0)
387           || (REG_N_CALLS_CROSSED (r) > 0 
388               && current_function_has_nonlocal_label))
389         continue;
390
391       /* Now find the best hard-register class for this pseudo register */
392       if (N_REG_CLASSES > 1)
393         reg_renumber[r] = stupid_find_reg (REG_N_CALLS_CROSSED (r), 
394                                            reg_preferred_class (r),
395                                            PSEUDO_REGNO_MODE (r),
396                                            REG_WHERE_BORN (r),
397                                            reg_where_dead[r],
398                                            regs_change_size[r]);
399
400       /* If no reg available in that class, try alternate class.  */
401       if (reg_renumber[r] == -1 && reg_alternate_class (r) != NO_REGS)
402         reg_renumber[r] = stupid_find_reg (REG_N_CALLS_CROSSED (r),
403                                            reg_alternate_class (r),
404                                            PSEUDO_REGNO_MODE (r),
405                                            REG_WHERE_BORN (r),
406                                            reg_where_dead[r],
407                                            regs_change_size[r]);
408     }
409
410   /* Fill in the pseudo reg life information into the insn chain.  */
411   for (i = LAST_VIRTUAL_REGISTER + 1; i < max_regno; i++)
412     {
413       struct insn_chain *chain;
414       int regno;
415
416       regno = reg_renumber[i];
417       if (regno < 0)
418         continue;
419
420       chain = reg_where_dead_chain[i];
421       if (reg_where_dead[i] > INSN_SUID (chain->insn))
422         SET_REGNO_REG_SET (chain->live_after, i);
423
424       while (INSN_SUID (chain->insn) > reg_where_born_exact[i])
425         {
426           SET_REGNO_REG_SET (chain->live_before, i);
427           chain = chain->prev;
428           if (!chain)
429             break;
430           SET_REGNO_REG_SET (chain->live_after, i);
431         }
432
433       if (INSN_SUID (chain->insn) == reg_where_born_exact[i]
434           && reg_where_born_clobber[i])
435         SET_REGNO_REG_SET (chain->live_before, i);
436     }
437
438   if (file)
439     dump_flow_info (file);
440
441   free (regs_live);
442   free (uid_suid);
443   free (reg_where_dead);
444   free (reg_where_born_exact);
445   free (reg_where_born_clobber);
446   free (reg_where_dead_chain);
447   free (reg_order);
448   free (regs_change_size);
449   free (regs_crosses_setjmp);
450   free (after_insn_hard_regs);
451 }
452
453 /* Comparison function for qsort.
454    Returns -1 (1) if register *R1P is higher priority than *R2P.  */
455
456 static int
457 stupid_reg_compare (r1p, r2p)
458      const GENERIC_PTR r1p;
459      const GENERIC_PTR r2p;
460 {
461   register int r1 = *(int *)r1p, r2 = *(int *)r2p;
462   register int len1 = reg_where_dead[r1] - REG_WHERE_BORN (r1);
463   register int len2 = reg_where_dead[r2] - REG_WHERE_BORN (r2);
464   int tem;
465
466   tem = len2 - len1;
467   if (tem != 0)
468     return tem;
469
470   tem = REG_N_REFS (r1) - REG_N_REFS (r2);
471   if (tem != 0)
472     return tem;
473
474   /* If regs are equally good, sort by regno,
475      so that the results of qsort leave nothing to chance.  */
476   return r1 - r2;
477 }
478 \f
479 /* Find a block of SIZE words of hard registers in reg_class CLASS
480    that can hold a value of machine-mode MODE
481      (but actually we test only the first of the block for holding MODE)
482    currently free from after insn whose suid is BORN_INSN
483    through the insn whose suid is DEAD_INSN,
484    and return the number of the first of them.
485    Return -1 if such a block cannot be found.
486
487    If CALL_PRESERVED is nonzero, insist on registers preserved
488    over subroutine calls, and return -1 if cannot find such.
489
490    If CHANGES_SIZE is nonzero, it means this register was used as the
491    operand of a SUBREG that changes its size.  */
492
493 static int
494 stupid_find_reg (call_preserved, class, mode,
495                  born_insn, dead_insn, changes_size)
496      int call_preserved;
497      enum reg_class class;
498      enum machine_mode mode;
499      int born_insn, dead_insn;
500      int changes_size ATTRIBUTE_UNUSED;
501 {
502   register int i, ins;
503 #ifdef HARD_REG_SET
504   register              /* Declare them register if they are scalars.  */
505 #endif
506     HARD_REG_SET used, this_reg;
507 #ifdef ELIMINABLE_REGS
508   static struct {int from, to; } eliminables[] = ELIMINABLE_REGS;
509 #endif
510
511   /* If this register's life is more than 5,000 insns, we probably
512      can't allocate it, so don't waste the time trying.  This avoids
513      quadratic behavior on programs that have regularly-occurring
514      SAVE_EXPRs.  */
515   if (dead_insn > born_insn + 5000)
516     return -1;
517
518   COPY_HARD_REG_SET (used,
519                      call_preserved ? call_used_reg_set : fixed_reg_set);
520
521 #ifdef ELIMINABLE_REGS
522   for (i = 0; i < (int)(sizeof eliminables / sizeof eliminables[0]); i++)
523     SET_HARD_REG_BIT (used, eliminables[i].from);
524 #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
525   SET_HARD_REG_BIT (used, HARD_FRAME_POINTER_REGNUM);
526 #endif
527 #else
528   SET_HARD_REG_BIT (used, FRAME_POINTER_REGNUM);
529 #endif
530
531   for (ins = born_insn; ins < dead_insn; ins++)
532     IOR_HARD_REG_SET (used, after_insn_hard_regs[ins]);
533
534 #ifdef STACK_REGS
535   if (current_function_has_computed_jump)
536     for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
537       SET_HARD_REG_BIT (used, i);
538 #endif
539   
540   IOR_COMPL_HARD_REG_SET (used, reg_class_contents[(int) class]);
541
542 #ifdef CLASS_CANNOT_CHANGE_SIZE
543   if (changes_size)
544     IOR_HARD_REG_SET (used,
545                       reg_class_contents[(int) CLASS_CANNOT_CHANGE_SIZE]);
546 #endif
547
548   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
549     {
550 #ifdef REG_ALLOC_ORDER
551       int regno = reg_alloc_order[i];
552 #else
553       int regno = i;
554 #endif
555
556       /* If a register has screwy overlap problems,
557          don't use it at all if not optimizing.
558          Actually this is only for the 387 stack register,
559          and it's because subsequent code won't work.  */
560 #ifdef OVERLAPPING_REGNO_P
561       if (OVERLAPPING_REGNO_P (regno))
562         continue;
563 #endif
564
565       if (! TEST_HARD_REG_BIT (used, regno)
566           && HARD_REGNO_MODE_OK (regno, mode))
567         {
568           register int j;
569           register int size1 = HARD_REGNO_NREGS (regno, mode);
570           for (j = 1; j < size1 && ! TEST_HARD_REG_BIT (used, regno + j); j++);
571           if (j == size1)
572             {
573               CLEAR_HARD_REG_SET (this_reg);
574               while (--j >= 0)
575                 SET_HARD_REG_BIT (this_reg, regno + j);
576               for (ins = born_insn; ins < dead_insn; ins++)
577                 {
578                   IOR_HARD_REG_SET (after_insn_hard_regs[ins], this_reg);
579                 }
580               return regno;
581             }
582 #ifndef REG_ALLOC_ORDER
583           i += j;               /* Skip starting points we know will lose */
584 #endif
585         }
586     }
587
588   return -1;
589 }
590 \f
591 /* Walk X, noting all assignments and references to registers
592    and recording what they imply about life spans.
593    INSN is the current insn, supplied so we can find its suid.  */
594
595 static void
596 stupid_mark_refs (x, chain)
597      rtx x;
598      struct insn_chain *chain;
599 {
600   register RTX_CODE code;
601   register char *fmt;
602   register int regno, i;
603   rtx insn = chain->insn;
604
605   if (x == 0)
606     return;
607
608   code = GET_CODE (x);
609
610   if (code == SET || code == CLOBBER)
611     {
612       if (SET_DEST (x) != 0
613           && (GET_CODE (SET_DEST (x)) == REG
614               || (GET_CODE (SET_DEST (x)) == SUBREG
615                   && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG
616                   && (REGNO (SUBREG_REG (SET_DEST (x)))
617                       >= FIRST_PSEUDO_REGISTER))))
618         {
619           /* Register is being assigned.  */
620           /* If setting a SUBREG, we treat the entire reg as being set.  */
621           if (GET_CODE (SET_DEST (x)) == SUBREG)
622             regno = REGNO (SUBREG_REG (SET_DEST (x)));
623           else
624             regno = REGNO (SET_DEST (x));
625
626           /* For hard regs, update the where-live info.  */
627           if (regno < FIRST_PSEUDO_REGISTER)
628             {
629               register int j
630                 = HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (x)));
631
632               while (--j >= 0)
633                 {
634                   regs_ever_live[regno+j] = 1;
635                   regs_live[regno+j] = 0;
636
637                   /* The following line is for unused outputs;
638                      they do get stored even though never used again.  */
639                   MARK_LIVE_AFTER (insn, regno+j);
640
641                   /* When a hard reg is clobbered, mark it in use
642                      just before this insn, so it is live all through.  */
643                   if (code == CLOBBER && INSN_SUID (insn) > 0)
644                     SET_HARD_REG_BIT (after_insn_hard_regs[INSN_SUID (insn) - 1],
645                                       regno+j);
646                 }
647             }
648           /* For pseudo regs, record where born, where dead, number of
649              times used, and whether live across a call.  */
650           else
651             {
652               /* Update the life-interval bounds of this pseudo reg.  */
653
654               /* When a pseudo-reg is CLOBBERed, it is born just before
655                  the clobbering insn.  When setting, just after.  */
656               int where_born = INSN_SUID (insn) - (code == CLOBBER);
657
658               reg_where_born_exact[regno] = INSN_SUID (insn);
659               reg_where_born_clobber[regno] = (code == CLOBBER);
660
661               if (reg_where_dead_chain[regno] == 0)
662                 reg_where_dead_chain[regno] = chain;
663
664               /* The reg must live at least one insn even
665                  in it is never again used--because it has to go
666                  in SOME hard reg.  Mark it as dying after the current
667                  insn so that it will conflict with any other outputs of
668                  this insn.  */
669               if (reg_where_dead[regno] < where_born + 2)
670                 {
671                   reg_where_dead[regno] = where_born + 2;
672                   regs_live[regno] = 1;
673                 }
674
675               /* Count the refs of this reg.  */
676               REG_N_REFS (regno)++;
677
678               if (last_call_suid < reg_where_dead[regno])
679                 REG_N_CALLS_CROSSED (regno) += 1;
680
681               if (last_setjmp_suid < reg_where_dead[regno])
682                 regs_crosses_setjmp[regno] = 1;
683
684               /* If this register is only used in this insn and is only
685                  set, mark it unused.  We have to do this even when not 
686                  optimizing so that MD patterns which count on this
687                  behavior (e.g., it not causing an output reload on
688                  an insn setting CC) will operate correctly.  */
689               if (GET_CODE (SET_DEST (x)) == REG
690                   && REGNO_FIRST_UID (regno) == INSN_UID (insn)
691                   && REGNO_LAST_UID (regno) == INSN_UID (insn)
692                   && (code == CLOBBER || ! reg_mentioned_p (SET_DEST (x),
693                                                             SET_SRC (x))))
694                 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_UNUSED,
695                                                       SET_DEST (x),
696                                                       REG_NOTES (insn));
697             }
698         }
699
700       /* Record references from the value being set,
701          or from addresses in the place being set if that's not a reg.
702          If setting a SUBREG, we treat the entire reg as *used*.  */
703       if (code == SET)
704         {
705           stupid_mark_refs (SET_SRC (x), chain);
706           if (GET_CODE (SET_DEST (x)) != REG)
707             stupid_mark_refs (SET_DEST (x), chain);
708         }
709       return;
710     }
711
712   else if (code == SUBREG
713            && GET_CODE (SUBREG_REG (x)) == REG
714            && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER
715            && (GET_MODE_SIZE (GET_MODE (x))
716                != GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
717            && (INTEGRAL_MODE_P (GET_MODE (x))
718                || INTEGRAL_MODE_P (GET_MODE (SUBREG_REG (x)))))
719     regs_change_size[REGNO (SUBREG_REG (x))] = 1;
720
721   /* Register value being used, not set.  */
722
723   else if (code == REG)
724     {
725       regno = REGNO (x);
726       if (regno < FIRST_PSEUDO_REGISTER)
727         {
728           /* Hard reg: mark it live for continuing scan of previous insns.  */
729           register int j = HARD_REGNO_NREGS (regno, GET_MODE (x));
730           while (--j >= 0)
731             {
732               regs_ever_live[regno+j] = 1;
733               regs_live[regno+j] = 1;
734             }
735         }
736       else
737         {
738           /* Pseudo reg: record first use, last use and number of uses.  */
739
740           reg_where_born_exact[regno] = INSN_SUID (insn);
741           reg_where_born_clobber[regno] = 0;
742           REG_N_REFS (regno)++;
743           if (regs_live[regno] == 0)
744             {
745               regs_live[regno] = 1;
746               reg_where_dead[regno] = INSN_SUID (insn);
747               reg_where_dead_chain[regno] = chain;
748             }
749         }
750       return;
751     }
752
753   /* Recursive scan of all other rtx's.  */
754
755   fmt = GET_RTX_FORMAT (code);
756   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
757     {
758       if (fmt[i] == 'e')
759         stupid_mark_refs (XEXP (x, i), chain);
760       if (fmt[i] == 'E')
761         {
762           register int j;
763           for (j = XVECLEN (x, i) - 1; j >= 0; j--)
764             stupid_mark_refs (XVECEXP (x, i, j), chain);
765         }
766     }
767 }