OSDN Git Service

* rtlanal.c (reg_referenced_p): A CLOBBER of a MEM uses any REGs
[pf3gnuchains/gcc-fork.git] / gcc / rtlanal.c
1 /* Analyze RTL for C-Compiler
2    Copyright (C) 1987, 88, 92-99, 2000 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 #include "config.h"
23 #include "system.h"
24 #include "rtl.h"
25
26 static int rtx_addr_can_trap_p  PARAMS ((rtx));
27 static void reg_set_p_1         PARAMS ((rtx, rtx, void *));
28 static void reg_set_last_1      PARAMS ((rtx, rtx, void *));
29
30
31 /* Forward declarations */
32 static int jmp_uses_reg_or_mem          PARAMS ((rtx));
33
34 /* Bit flags that specify the machine subtype we are compiling for.
35    Bits are tested using macros TARGET_... defined in the tm.h file
36    and set by `-m...' switches.  Must be defined in rtlanal.c.  */
37
38 int target_flags;
39 \f
40 /* Return 1 if the value of X is unstable
41    (would be different at a different point in the program).
42    The frame pointer, arg pointer, etc. are considered stable
43    (within one function) and so is anything marked `unchanging'.  */
44
45 int
46 rtx_unstable_p (x)
47      rtx x;
48 {
49   register RTX_CODE code = GET_CODE (x);
50   register int i;
51   register const char *fmt;
52
53   if (code == MEM)
54     return ! RTX_UNCHANGING_P (x);
55
56   if (code == QUEUED)
57     return 1;
58
59   if (code == CONST || code == CONST_INT)
60     return 0;
61
62   if (code == REG)
63     return ! (REGNO (x) == FRAME_POINTER_REGNUM
64               || REGNO (x) == HARD_FRAME_POINTER_REGNUM
65               || REGNO (x) == ARG_POINTER_REGNUM
66               || RTX_UNCHANGING_P (x));
67
68   fmt = GET_RTX_FORMAT (code);
69   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
70     if (fmt[i] == 'e')
71       if (rtx_unstable_p (XEXP (x, i)))
72         return 1;
73   return 0;
74 }
75
76 /* Return 1 if X has a value that can vary even between two
77    executions of the program.  0 means X can be compared reliably
78    against certain constants or near-constants.
79    The frame pointer and the arg pointer are considered constant.  */
80
81 int
82 rtx_varies_p (x)
83      rtx x;
84 {
85   register RTX_CODE code = GET_CODE (x);
86   register int i;
87   register const char *fmt;
88
89   switch (code)
90     {
91     case MEM:
92     case QUEUED:
93       return 1;
94
95     case CONST:
96     case CONST_INT:
97     case CONST_DOUBLE:
98     case SYMBOL_REF:
99     case LABEL_REF:
100       return 0;
101
102     case REG:
103       /* Note that we have to test for the actual rtx used for the frame
104          and arg pointers and not just the register number in case we have
105          eliminated the frame and/or arg pointer and are using it
106          for pseudos.  */
107       return ! (x == frame_pointer_rtx || x == hard_frame_pointer_rtx
108                 || x == arg_pointer_rtx || x == pic_offset_table_rtx);
109
110     case LO_SUM:
111       /* The operand 0 of a LO_SUM is considered constant
112          (in fact is it related specifically to operand 1).  */
113       return rtx_varies_p (XEXP (x, 1));
114       
115     default:
116       break;
117     }
118
119   fmt = GET_RTX_FORMAT (code);
120   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
121     if (fmt[i] == 'e')
122       if (rtx_varies_p (XEXP (x, i)))
123         return 1;
124   return 0;
125 }
126
127 /* Return 0 if the use of X as an address in a MEM can cause a trap.  */
128
129 static int
130 rtx_addr_can_trap_p (x)
131      register rtx x;
132 {
133   register enum rtx_code code = GET_CODE (x);
134
135   switch (code)
136     {
137     case SYMBOL_REF:
138     case LABEL_REF:
139       /* SYMBOL_REF is problematic due to the possible presence of
140          a #pragma weak, but to say that loads from symbols can trap is
141          *very* costly.  It's not at all clear what's best here.  For
142          now, we ignore the impact of #pragma weak.  */
143       return 0;
144
145     case REG:
146       /* As in rtx_varies_p, we have to use the actual rtx, not reg number.  */
147       return ! (x == frame_pointer_rtx || x == hard_frame_pointer_rtx
148                 || x == stack_pointer_rtx || x == arg_pointer_rtx);
149
150     case CONST:
151       return rtx_addr_can_trap_p (XEXP (x, 0));
152
153     case PLUS:
154       /* An address is assumed not to trap if it is an address that can't
155          trap plus a constant integer.  */
156       return (rtx_addr_can_trap_p (XEXP (x, 0))
157               || GET_CODE (XEXP (x, 1)) != CONST_INT);
158
159     case LO_SUM:
160       return rtx_addr_can_trap_p (XEXP (x, 1));
161       
162     default:
163       break;
164     }
165
166   /* If it isn't one of the case above, it can cause a trap.  */
167   return 1;
168 }
169
170 /* Return 1 if X refers to a memory location whose address 
171    cannot be compared reliably with constant addresses,
172    or if X refers to a BLKmode memory object.  */
173
174 int
175 rtx_addr_varies_p (x)
176      rtx x;
177 {
178   register enum rtx_code code;
179   register int i;
180   register const char *fmt;
181
182   if (x == 0)
183     return 0;
184
185   code = GET_CODE (x);
186   if (code == MEM)
187     return GET_MODE (x) == BLKmode || rtx_varies_p (XEXP (x, 0));
188
189   fmt = GET_RTX_FORMAT (code);
190   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
191     if (fmt[i] == 'e')
192       {
193         if (rtx_addr_varies_p (XEXP (x, i)))
194           return 1;
195       }
196     else if (fmt[i] == 'E')
197       {
198         int j;
199         for (j = 0; j < XVECLEN (x, i); j++)
200           if (rtx_addr_varies_p (XVECEXP (x, i, j)))
201             return 1;
202       }
203   return 0;
204 }
205 \f
206 /* Return the value of the integer term in X, if one is apparent;
207    otherwise return 0.
208    Only obvious integer terms are detected.
209    This is used in cse.c with the `related_value' field.*/
210
211 HOST_WIDE_INT
212 get_integer_term (x)
213      rtx x;
214 {
215   if (GET_CODE (x) == CONST)
216     x = XEXP (x, 0);
217
218   if (GET_CODE (x) == MINUS
219       && GET_CODE (XEXP (x, 1)) == CONST_INT)
220     return - INTVAL (XEXP (x, 1));
221   if (GET_CODE (x) == PLUS
222       && GET_CODE (XEXP (x, 1)) == CONST_INT)
223     return INTVAL (XEXP (x, 1));
224   return 0;
225 }
226
227 /* If X is a constant, return the value sans apparent integer term;
228    otherwise return 0.
229    Only obvious integer terms are detected.  */
230
231 rtx
232 get_related_value (x)
233      rtx x;
234 {
235   if (GET_CODE (x) != CONST)
236     return 0;
237   x = XEXP (x, 0);
238   if (GET_CODE (x) == PLUS
239       && GET_CODE (XEXP (x, 1)) == CONST_INT)
240     return XEXP (x, 0);
241   else if (GET_CODE (x) == MINUS
242            && GET_CODE (XEXP (x, 1)) == CONST_INT)
243     return XEXP (x, 0);
244   return 0;
245 }
246 \f
247 /* Nonzero if register REG appears somewhere within IN.
248    Also works if REG is not a register; in this case it checks
249    for a subexpression of IN that is Lisp "equal" to REG.  */
250
251 int
252 reg_mentioned_p (reg, in)
253      register rtx reg, in;
254 {
255   register const char *fmt;
256   register int i;
257   register enum rtx_code code;
258
259   if (in == 0)
260     return 0;
261
262   if (reg == in)
263     return 1;
264
265   if (GET_CODE (in) == LABEL_REF)
266     return reg == XEXP (in, 0);
267
268   code = GET_CODE (in);
269
270   switch (code)
271     {
272       /* Compare registers by number.  */
273     case REG:
274       return GET_CODE (reg) == REG && REGNO (in) == REGNO (reg);
275
276       /* These codes have no constituent expressions
277          and are unique.  */
278     case SCRATCH:
279     case CC0:
280     case PC:
281       return 0;
282
283     case CONST_INT:
284       return GET_CODE (reg) == CONST_INT && INTVAL (in) == INTVAL (reg);
285       
286     case CONST_DOUBLE:
287       /* These are kept unique for a given value.  */
288       return 0;
289       
290     default:
291       break;
292     }
293
294   if (GET_CODE (reg) == code && rtx_equal_p (reg, in))
295     return 1;
296
297   fmt = GET_RTX_FORMAT (code);
298
299   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
300     {
301       if (fmt[i] == 'E')
302         {
303           register int j;
304           for (j = XVECLEN (in, i) - 1; j >= 0; j--)
305             if (reg_mentioned_p (reg, XVECEXP (in, i, j)))
306               return 1;
307         }
308       else if (fmt[i] == 'e'
309                && reg_mentioned_p (reg, XEXP (in, i)))
310         return 1;
311     }
312   return 0;
313 }
314 \f
315 /* Return 1 if in between BEG and END, exclusive of BEG and END, there is
316    no CODE_LABEL insn.  */
317
318 int
319 no_labels_between_p (beg, end)
320      rtx beg, end;
321 {
322   register rtx p;
323   for (p = NEXT_INSN (beg); p != end; p = NEXT_INSN (p))
324     if (GET_CODE (p) == CODE_LABEL)
325       return 0;
326   return 1;
327 }
328
329 /* Return 1 if in between BEG and END, exclusive of BEG and END, there is
330    no JUMP_INSN insn.  */
331
332 int
333 no_jumps_between_p (beg, end)
334      rtx beg, end;
335 {
336   register rtx p;
337   for (p = NEXT_INSN (beg); p != end; p = NEXT_INSN (p))
338     if (GET_CODE (p) == JUMP_INSN)
339       return 0;
340   return 1;
341 }
342
343 /* Nonzero if register REG is used in an insn between
344    FROM_INSN and TO_INSN (exclusive of those two).  */
345
346 int
347 reg_used_between_p (reg, from_insn, to_insn)
348      rtx reg, from_insn, to_insn;
349 {
350   register rtx insn;
351
352   if (from_insn == to_insn)
353     return 0;
354
355   for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn))
356     if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
357         && (reg_overlap_mentioned_p (reg, PATTERN (insn))
358            || (GET_CODE (insn) == CALL_INSN
359               && (find_reg_fusage (insn, USE, reg)
360                   || find_reg_fusage (insn, CLOBBER, reg)))))
361       return 1;
362   return 0;
363 }
364 \f
365 /* Nonzero if the old value of X, a register, is referenced in BODY.  If X
366    is entirely replaced by a new value and the only use is as a SET_DEST,
367    we do not consider it a reference.  */
368
369 int
370 reg_referenced_p (x, body)
371      rtx x;
372      rtx body;
373 {
374   int i;
375
376   switch (GET_CODE (body))
377     {
378     case SET:
379       if (reg_overlap_mentioned_p (x, SET_SRC (body)))
380         return 1;
381
382       /* If the destination is anything other than CC0, PC, a REG or a SUBREG
383          of a REG that occupies all of the REG, the insn references X if
384          it is mentioned in the destination.  */
385       if (GET_CODE (SET_DEST (body)) != CC0
386           && GET_CODE (SET_DEST (body)) != PC
387           && GET_CODE (SET_DEST (body)) != REG
388           && ! (GET_CODE (SET_DEST (body)) == SUBREG
389                 && GET_CODE (SUBREG_REG (SET_DEST (body))) == REG
390                 && (((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (body))))
391                       + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
392                     == ((GET_MODE_SIZE (GET_MODE (SET_DEST (body)))
393                          + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)))
394           && reg_overlap_mentioned_p (x, SET_DEST (body)))
395         return 1;
396       return 0;
397
398     case ASM_OPERANDS:
399       for (i = ASM_OPERANDS_INPUT_LENGTH (body) - 1; i >= 0; i--)
400         if (reg_overlap_mentioned_p (x, ASM_OPERANDS_INPUT (body, i)))
401           return 1;
402       return 0;
403
404     case CALL:
405     case USE:
406     case IF_THEN_ELSE:
407       return reg_overlap_mentioned_p (x, body);
408
409     case TRAP_IF:
410       return reg_overlap_mentioned_p (x, TRAP_CONDITION (body));
411
412     case UNSPEC:
413     case UNSPEC_VOLATILE:
414       for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
415         if (reg_overlap_mentioned_p (x, XVECEXP (body, 0, i)))
416           return 1;
417       return 0;
418
419     case PARALLEL:
420       for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
421         if (reg_referenced_p (x, XVECEXP (body, 0, i)))
422           return 1;
423       return 0;
424       
425     case CLOBBER:
426       if (GET_CODE (XEXP (body, 0)) == MEM)
427         if (reg_overlap_mentioned_p (x, XEXP (XEXP (body, 0), 0)))
428           return 1;
429       return 0;
430
431     default:
432       return 0;
433     }
434 }
435
436 /* Nonzero if register REG is referenced in an insn between
437    FROM_INSN and TO_INSN (exclusive of those two).  Sets of REG do
438    not count.  */
439
440 int
441 reg_referenced_between_p (reg, from_insn, to_insn)
442      rtx reg, from_insn, to_insn;
443 {
444   register rtx insn;
445
446   if (from_insn == to_insn)
447     return 0;
448
449   for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn))
450     if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
451         && (reg_referenced_p (reg, PATTERN (insn))
452            || (GET_CODE (insn) == CALL_INSN
453               && find_reg_fusage (insn, USE, reg))))
454       return 1;
455   return 0;
456 }
457 \f
458 /* Nonzero if register REG is set or clobbered in an insn between
459    FROM_INSN and TO_INSN (exclusive of those two).  */
460
461 int
462 reg_set_between_p (reg, from_insn, to_insn)
463      rtx reg, from_insn, to_insn;
464 {
465   register rtx insn;
466
467   if (from_insn == to_insn)
468     return 0;
469
470   for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn))
471     if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
472         && reg_set_p (reg, insn))
473       return 1;
474   return 0;
475 }
476
477 /* Internals of reg_set_between_p.  */
478
479 static rtx reg_set_reg;
480 static int reg_set_flag;
481
482 static void
483 reg_set_p_1 (x, pat, data)
484      rtx x;
485      rtx pat ATTRIBUTE_UNUSED;
486      void *data ATTRIBUTE_UNUSED;
487 {
488   /* We don't want to return 1 if X is a MEM that contains a register
489      within REG_SET_REG.  */
490
491   if ((GET_CODE (x) != MEM)
492       && reg_overlap_mentioned_p (reg_set_reg, x))
493     reg_set_flag = 1;
494 }
495
496 int
497 reg_set_p (reg, insn)
498      rtx reg, insn;
499 {
500   rtx body = insn;
501
502   /* We can be passed an insn or part of one.  If we are passed an insn,
503      check if a side-effect of the insn clobbers REG.  */
504   if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
505     {
506       if (FIND_REG_INC_NOTE (insn, reg)
507           || (GET_CODE (insn) == CALL_INSN
508               /* We'd like to test call_used_regs here, but rtlanal.c can't
509                  reference that variable due to its use in genattrtab.  So
510                  we'll just be more conservative.
511
512                  ??? Unless we could ensure that the CALL_INSN_FUNCTION_USAGE
513                  information holds all clobbered registers.  */
514               && ((GET_CODE (reg) == REG
515                    && REGNO (reg) < FIRST_PSEUDO_REGISTER)
516                   || GET_CODE (reg) == MEM
517                   || find_reg_fusage (insn, CLOBBER, reg))))
518         return 1;
519
520       body = PATTERN (insn);
521     }
522
523   reg_set_reg = reg;
524   reg_set_flag = 0;
525   note_stores (body, reg_set_p_1, NULL);
526   return reg_set_flag;
527 }
528
529 /* Similar to reg_set_between_p, but check all registers in X.  Return 0
530    only if none of them are modified between START and END.  Do not
531    consider non-registers one way or the other.  */
532
533 int
534 regs_set_between_p (x, start, end)
535      rtx x;
536      rtx start, end;
537 {
538   enum rtx_code code = GET_CODE (x);
539   const char *fmt;
540   int i, j;
541
542   switch (code)
543     {
544     case CONST_INT:
545     case CONST_DOUBLE:
546     case CONST:
547     case SYMBOL_REF:
548     case LABEL_REF:
549     case PC:
550     case CC0:
551       return 0;
552
553     case REG:
554       return reg_set_between_p (x, start, end);
555       
556     default:
557       break;
558     }
559
560   fmt = GET_RTX_FORMAT (code);
561   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
562     {
563       if (fmt[i] == 'e' && regs_set_between_p (XEXP (x, i), start, end))
564         return 1;
565
566       else if (fmt[i] == 'E')
567         for (j = XVECLEN (x, i) - 1; j >= 0; j--)
568           if (regs_set_between_p (XVECEXP (x, i, j), start, end))
569             return 1;
570     }
571
572   return 0;
573 }
574
575 /* Similar to reg_set_between_p, but check all registers in X.  Return 0
576    only if none of them are modified between START and END.  Return 1 if
577    X contains a MEM; this routine does not perform any memory aliasing.  */
578
579 int
580 modified_between_p (x, start, end)
581      rtx x;
582      rtx start, end;
583 {
584   enum rtx_code code = GET_CODE (x);
585   const char *fmt;
586   int i, j;
587
588   switch (code)
589     {
590     case CONST_INT:
591     case CONST_DOUBLE:
592     case CONST:
593     case SYMBOL_REF:
594     case LABEL_REF:
595       return 0;
596
597     case PC:
598     case CC0:
599       return 1;
600
601     case MEM:
602       /* If the memory is not constant, assume it is modified.  If it is
603          constant, we still have to check the address.  */
604       if (! RTX_UNCHANGING_P (x))
605         return 1;
606       break;
607
608     case REG:
609       return reg_set_between_p (x, start, end);
610       
611     default:
612       break;
613     }
614
615   fmt = GET_RTX_FORMAT (code);
616   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
617     {
618       if (fmt[i] == 'e' && modified_between_p (XEXP (x, i), start, end))
619         return 1;
620
621       else if (fmt[i] == 'E')
622         for (j = XVECLEN (x, i) - 1; j >= 0; j--)
623           if (modified_between_p (XVECEXP (x, i, j), start, end))
624             return 1;
625     }
626
627   return 0;
628 }
629
630 /* Similar to reg_set_p, but check all registers in X.  Return 0 only if none
631    of them are modified in INSN.  Return 1 if X contains a MEM; this routine
632    does not perform any memory aliasing.  */
633
634 int
635 modified_in_p (x, insn)
636      rtx x;
637      rtx insn;
638 {
639   enum rtx_code code = GET_CODE (x);
640   const char *fmt;
641   int i, j;
642
643   switch (code)
644     {
645     case CONST_INT:
646     case CONST_DOUBLE:
647     case CONST:
648     case SYMBOL_REF:
649     case LABEL_REF:
650       return 0;
651
652     case PC:
653     case CC0:
654       return 1;
655
656     case MEM:
657       /* If the memory is not constant, assume it is modified.  If it is
658          constant, we still have to check the address.  */
659       if (! RTX_UNCHANGING_P (x))
660         return 1;
661       break;
662
663     case REG:
664       return reg_set_p (x, insn);
665
666     default:
667       break;
668     }
669
670   fmt = GET_RTX_FORMAT (code);
671   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
672     {
673       if (fmt[i] == 'e' && modified_in_p (XEXP (x, i), insn))
674         return 1;
675
676       else if (fmt[i] == 'E')
677         for (j = XVECLEN (x, i) - 1; j >= 0; j--)
678           if (modified_in_p (XVECEXP (x, i, j), insn))
679             return 1;
680     }
681
682   return 0;
683 }
684 \f
685 /* Given an INSN, return a SET expression if this insn has only a single SET.
686    It may also have CLOBBERs, USEs, or SET whose output
687    will not be used, which we ignore.  */
688
689 rtx
690 single_set (insn)
691      rtx insn;
692 {
693   rtx set;
694   int i;
695   
696   if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
697     return 0;
698
699   if (GET_CODE (PATTERN (insn)) == SET)
700     return PATTERN (insn);
701   
702   else if (GET_CODE (PATTERN (insn)) == PARALLEL)
703     {
704       for (i = 0, set = 0; i < XVECLEN (PATTERN (insn), 0); i++)
705         if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET
706             && (! find_reg_note (insn, REG_UNUSED,
707                                  SET_DEST (XVECEXP (PATTERN (insn), 0, i)))
708                 || side_effects_p (XVECEXP (PATTERN (insn), 0, i))))
709           {
710             if (set)
711               return 0;
712             else
713               set = XVECEXP (PATTERN (insn), 0, i);
714           }
715       return set;
716     }
717   
718   return 0;
719 }
720
721 /* Given an INSN, return nonzero if it has more than one SET, else return
722    zero.  */
723
724 int
725 multiple_sets (insn)
726      rtx insn;
727 {
728   int found;
729   int i;
730   
731   /* INSN must be an insn.  */
732   if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
733     return 0;
734
735   /* Only a PARALLEL can have multiple SETs.  */
736   if (GET_CODE (PATTERN (insn)) == PARALLEL)
737     {
738       for (i = 0, found = 0; i < XVECLEN (PATTERN (insn), 0); i++)
739         if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
740           {
741             /* If we have already found a SET, then return now.  */
742             if (found)
743               return 1;
744             else
745               found = 1;
746           }
747     }
748   
749   /* Either zero or one SET.  */
750   return 0;
751 }
752 \f
753 /* Return the last thing that X was assigned from before *PINSN.  Verify that
754    the object is not modified up to VALID_TO.  If it was, if we hit
755    a partial assignment to X, or hit a CODE_LABEL first, return X.  If we
756    found an assignment, update *PINSN to point to it.  
757    ALLOW_HWREG is set to 1 if hardware registers are allowed to be the src.  */
758
759 rtx
760 find_last_value (x, pinsn, valid_to, allow_hwreg)
761      rtx x;
762      rtx *pinsn;
763      rtx valid_to;
764      int allow_hwreg;
765 {
766   rtx p;
767
768   for (p = PREV_INSN (*pinsn); p && GET_CODE (p) != CODE_LABEL;
769        p = PREV_INSN (p))
770     if (GET_RTX_CLASS (GET_CODE (p)) == 'i')
771       {
772         rtx set = single_set (p);
773         rtx note = find_reg_note (p, REG_EQUAL, NULL_RTX);
774
775         if (set && rtx_equal_p (x, SET_DEST (set)))
776           {
777             rtx src = SET_SRC (set);
778
779             if (note && GET_CODE (XEXP (note, 0)) != EXPR_LIST)
780               src = XEXP (note, 0);
781
782             if (! modified_between_p (src, PREV_INSN (p), valid_to)
783                 /* Reject hard registers because we don't usually want
784                    to use them; we'd rather use a pseudo.  */
785                 && (! (GET_CODE (src) == REG
786                       && REGNO (src) < FIRST_PSEUDO_REGISTER) || allow_hwreg))
787               {
788                 *pinsn = p;
789                 return src;
790               }
791           }
792           
793         /* If set in non-simple way, we don't have a value.  */
794         if (reg_set_p (x, p))
795           break;
796       }
797
798   return x;
799 }     
800 \f
801 /* Return nonzero if register in range [REGNO, ENDREGNO)
802    appears either explicitly or implicitly in X
803    other than being stored into.
804
805    References contained within the substructure at LOC do not count.
806    LOC may be zero, meaning don't ignore anything.  */
807
808 int
809 refers_to_regno_p (regno, endregno, x, loc)
810      int regno, endregno;
811      rtx x;
812      rtx *loc;
813 {
814   register int i;
815   register RTX_CODE code;
816   register const char *fmt;
817
818  repeat:
819   /* The contents of a REG_NONNEG note is always zero, so we must come here
820      upon repeat in case the last REG_NOTE is a REG_NONNEG note.  */
821   if (x == 0)
822     return 0;
823
824   code = GET_CODE (x);
825
826   switch (code)
827     {
828     case REG:
829       i = REGNO (x);
830
831       /* If we modifying the stack, frame, or argument pointer, it will
832          clobber a virtual register.  In fact, we could be more precise,
833          but it isn't worth it.  */
834       if ((i == STACK_POINTER_REGNUM
835 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
836            || i == ARG_POINTER_REGNUM
837 #endif
838            || i == FRAME_POINTER_REGNUM)
839           && regno >= FIRST_VIRTUAL_REGISTER && regno <= LAST_VIRTUAL_REGISTER)
840         return 1;
841
842       return (endregno > i
843               && regno < i + (i < FIRST_PSEUDO_REGISTER 
844                               ? HARD_REGNO_NREGS (i, GET_MODE (x))
845                               : 1));
846
847     case SUBREG:
848       /* If this is a SUBREG of a hard reg, we can see exactly which
849          registers are being modified.  Otherwise, handle normally.  */
850       if (GET_CODE (SUBREG_REG (x)) == REG
851           && REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER)
852         {
853           int inner_regno = REGNO (SUBREG_REG (x)) + SUBREG_WORD (x);
854           int inner_endregno
855             = inner_regno + (inner_regno < FIRST_PSEUDO_REGISTER
856                              ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
857
858           return endregno > inner_regno && regno < inner_endregno;
859         }
860       break;
861
862     case CLOBBER:
863     case SET:
864       if (&SET_DEST (x) != loc
865           /* Note setting a SUBREG counts as referring to the REG it is in for
866              a pseudo but not for hard registers since we can
867              treat each word individually.  */
868           && ((GET_CODE (SET_DEST (x)) == SUBREG
869                && loc != &SUBREG_REG (SET_DEST (x))
870                && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG
871                && REGNO (SUBREG_REG (SET_DEST (x))) >= FIRST_PSEUDO_REGISTER
872                && refers_to_regno_p (regno, endregno,
873                                      SUBREG_REG (SET_DEST (x)), loc))
874               || (GET_CODE (SET_DEST (x)) != REG
875                   && refers_to_regno_p (regno, endregno, SET_DEST (x), loc))))
876         return 1;
877
878       if (code == CLOBBER || loc == &SET_SRC (x))
879         return 0;
880       x = SET_SRC (x);
881       goto repeat;
882
883     default:
884       break;
885     }
886
887   /* X does not match, so try its subexpressions.  */
888
889   fmt = GET_RTX_FORMAT (code);
890   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
891     {
892       if (fmt[i] == 'e' && loc != &XEXP (x, i))
893         {
894           if (i == 0)
895             {
896               x = XEXP (x, 0);
897               goto repeat;
898             }
899           else
900             if (refers_to_regno_p (regno, endregno, XEXP (x, i), loc))
901               return 1;
902         }
903       else if (fmt[i] == 'E')
904         {
905           register int j;
906           for (j = XVECLEN (x, i) - 1; j >=0; j--)
907             if (loc != &XVECEXP (x, i, j)
908                 && refers_to_regno_p (regno, endregno, XVECEXP (x, i, j), loc))
909               return 1;
910         }
911     }
912   return 0;
913 }
914
915 /* Nonzero if modifying X will affect IN.  If X is a register or a SUBREG,
916    we check if any register number in X conflicts with the relevant register
917    numbers.  If X is a constant, return 0.  If X is a MEM, return 1 iff IN
918    contains a MEM (we don't bother checking for memory addresses that can't
919    conflict because we expect this to be a rare case.  */
920
921 int
922 reg_overlap_mentioned_p (x, in)
923      rtx x, in;
924 {
925   int regno, endregno;
926
927   /* Overly conservative.  */
928   if (GET_CODE (x) == STRICT_LOW_PART)
929     x = XEXP (x, 0);
930
931   /* If either argument is a constant, then modifying X can not affect IN.  */
932   if (CONSTANT_P (x) || CONSTANT_P (in))
933     return 0;
934   else if (GET_CODE (x) == SUBREG)
935     {
936       regno = REGNO (SUBREG_REG (x));
937       if (regno < FIRST_PSEUDO_REGISTER)
938         regno += SUBREG_WORD (x);
939     }
940   else if (GET_CODE (x) == REG)
941     regno = REGNO (x);
942   else if (GET_CODE (x) == MEM)
943     {
944       const char *fmt;
945       int i;
946
947       if (GET_CODE (in) == MEM)
948         return 1;
949
950       fmt = GET_RTX_FORMAT (GET_CODE (in));
951
952       for (i = GET_RTX_LENGTH (GET_CODE (in)) - 1; i >= 0; i--)
953         if (fmt[i] == 'e' && reg_overlap_mentioned_p (x, XEXP (in, i)))
954           return 1;
955
956       return 0;
957     }
958   else if (GET_CODE (x) == SCRATCH || GET_CODE (x) == PC
959            || GET_CODE (x) == CC0)
960     return reg_mentioned_p (x, in);
961   else if (GET_CODE (x) == PARALLEL
962            && GET_MODE (x) == BLKmode)
963     {
964       register int i;
965
966       /* If any register in here refers to it
967          we return true.  */
968       for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
969         if (reg_overlap_mentioned_p (SET_DEST (XVECEXP (x, 0, i)), in))
970           return 1;
971       return 0;
972     }
973   else
974     abort ();
975
976   endregno = regno + (regno < FIRST_PSEUDO_REGISTER
977                       ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
978
979   return refers_to_regno_p (regno, endregno, in, NULL_PTR);
980 }
981 \f
982 /* Used for communications between the next few functions.  */
983
984 static int reg_set_last_unknown;
985 static rtx reg_set_last_value;
986 static int reg_set_last_first_regno, reg_set_last_last_regno;
987
988 /* Called via note_stores from reg_set_last.  */
989
990 static void
991 reg_set_last_1 (x, pat, data)
992      rtx x;
993      rtx pat;
994      void *data ATTRIBUTE_UNUSED;
995 {
996   int first, last;
997
998   /* If X is not a register, or is not one in the range we care
999      about, ignore.  */
1000   if (GET_CODE (x) != REG)
1001     return;
1002
1003   first = REGNO (x);
1004   last = first + (first < FIRST_PSEUDO_REGISTER
1005                   ? HARD_REGNO_NREGS (first, GET_MODE (x)) : 1);
1006
1007   if (first >= reg_set_last_last_regno
1008       || last <= reg_set_last_first_regno)
1009     return;
1010
1011   /* If this is a CLOBBER or is some complex LHS, or doesn't modify
1012      exactly the registers we care about, show we don't know the value.  */
1013   if (GET_CODE (pat) == CLOBBER || SET_DEST (pat) != x
1014       || first != reg_set_last_first_regno
1015       || last != reg_set_last_last_regno)
1016     reg_set_last_unknown = 1;
1017   else
1018     reg_set_last_value = SET_SRC (pat);
1019 }
1020
1021 /* Return the last value to which REG was set prior to INSN.  If we can't
1022    find it easily, return 0.
1023
1024    We only return a REG, SUBREG, or constant because it is too hard to
1025    check if a MEM remains unchanged.  */
1026
1027 rtx
1028 reg_set_last (x, insn)
1029      rtx x;
1030      rtx insn;
1031 {
1032   rtx orig_insn = insn;
1033
1034   reg_set_last_first_regno = REGNO (x);
1035
1036   reg_set_last_last_regno
1037     = reg_set_last_first_regno
1038       + (reg_set_last_first_regno < FIRST_PSEUDO_REGISTER
1039          ? HARD_REGNO_NREGS (reg_set_last_first_regno, GET_MODE (x)) : 1);
1040
1041   reg_set_last_unknown = 0;
1042   reg_set_last_value = 0;
1043
1044   /* Scan backwards until reg_set_last_1 changed one of the above flags.
1045      Stop when we reach a label or X is a hard reg and we reach a
1046      CALL_INSN (if reg_set_last_last_regno is a hard reg).
1047
1048      If we find a set of X, ensure that its SET_SRC remains unchanged.  */
1049
1050   /* We compare with <= here, because reg_set_last_last_regno
1051      is actually the number of the first reg *not* in X.  */
1052   for (;
1053        insn && GET_CODE (insn) != CODE_LABEL
1054        && ! (GET_CODE (insn) == CALL_INSN
1055              && reg_set_last_last_regno <= FIRST_PSEUDO_REGISTER);
1056        insn = PREV_INSN (insn))
1057     if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
1058       {
1059         note_stores (PATTERN (insn), reg_set_last_1, NULL);
1060         if (reg_set_last_unknown)
1061           return 0;
1062         else if (reg_set_last_value)
1063           {
1064             if (CONSTANT_P (reg_set_last_value)
1065                 || ((GET_CODE (reg_set_last_value) == REG
1066                      || GET_CODE (reg_set_last_value) == SUBREG)
1067                     && ! reg_set_between_p (reg_set_last_value,
1068                                             insn, orig_insn)))
1069               return reg_set_last_value;
1070             else
1071               return 0;
1072           }
1073       }
1074
1075   return 0;
1076 }
1077 \f
1078 /* Call FUN on each register or MEM that is stored into or clobbered by X.
1079    (X would be the pattern of an insn).
1080    FUN receives two arguments:
1081      the REG, MEM, CC0 or PC being stored in or clobbered,
1082      the SET or CLOBBER rtx that does the store.
1083
1084   If the item being stored in or clobbered is a SUBREG of a hard register,
1085   the SUBREG will be passed.  */
1086      
1087 void
1088 note_stores (x, fun, data)
1089      register rtx x;
1090      void (*fun) PARAMS ((rtx, rtx, void *));
1091      void *data;
1092 {
1093   if ((GET_CODE (x) == SET || GET_CODE (x) == CLOBBER))
1094     {
1095       register rtx dest = SET_DEST (x);
1096       while ((GET_CODE (dest) == SUBREG
1097               && (GET_CODE (SUBREG_REG (dest)) != REG
1098                   || REGNO (SUBREG_REG (dest)) >= FIRST_PSEUDO_REGISTER))
1099              || GET_CODE (dest) == ZERO_EXTRACT
1100              || GET_CODE (dest) == SIGN_EXTRACT
1101              || GET_CODE (dest) == STRICT_LOW_PART)
1102         dest = XEXP (dest, 0);
1103
1104       if (GET_CODE (dest) == PARALLEL
1105           && GET_MODE (dest) == BLKmode)
1106         {
1107           register int i;
1108           for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
1109             (*fun) (SET_DEST (XVECEXP (dest, 0, i)), x, data);
1110         }
1111       else
1112         (*fun) (dest, x, data);
1113     }
1114   else if (GET_CODE (x) == PARALLEL)
1115     {
1116       register int i;
1117       for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
1118         {
1119           register rtx y = XVECEXP (x, 0, i);
1120           if (GET_CODE (y) == SET || GET_CODE (y) == CLOBBER)
1121             {
1122               register rtx dest = SET_DEST (y);
1123               while ((GET_CODE (dest) == SUBREG
1124                       && (GET_CODE (SUBREG_REG (dest)) != REG
1125                           || (REGNO (SUBREG_REG (dest))
1126                               >= FIRST_PSEUDO_REGISTER)))
1127                      || GET_CODE (dest) == ZERO_EXTRACT
1128                      || GET_CODE (dest) == SIGN_EXTRACT
1129                      || GET_CODE (dest) == STRICT_LOW_PART)
1130                 dest = XEXP (dest, 0);
1131               if (GET_CODE (dest) == PARALLEL
1132                   && GET_MODE (dest) == BLKmode)
1133                 {
1134                   register int i;
1135                   for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
1136                     (*fun) (SET_DEST (XVECEXP (dest, 0, i)), y, data);
1137                 }
1138               else
1139                 (*fun) (dest, y, data);
1140             }
1141         }
1142     }
1143 }
1144 \f
1145 /* Return nonzero if X's old contents don't survive after INSN.
1146    This will be true if X is (cc0) or if X is a register and
1147    X dies in INSN or because INSN entirely sets X.
1148
1149    "Entirely set" means set directly and not through a SUBREG,
1150    ZERO_EXTRACT or SIGN_EXTRACT, so no trace of the old contents remains.
1151    Likewise, REG_INC does not count.
1152
1153    REG may be a hard or pseudo reg.  Renumbering is not taken into account,
1154    but for this use that makes no difference, since regs don't overlap
1155    during their lifetimes.  Therefore, this function may be used
1156    at any time after deaths have been computed (in flow.c).
1157
1158    If REG is a hard reg that occupies multiple machine registers, this
1159    function will only return 1 if each of those registers will be replaced
1160    by INSN.  */
1161
1162 int
1163 dead_or_set_p (insn, x)
1164      rtx insn;
1165      rtx x;
1166 {
1167   register int regno, last_regno;
1168   register int i;
1169
1170   /* Can't use cc0_rtx below since this file is used by genattrtab.c.  */
1171   if (GET_CODE (x) == CC0)
1172     return 1;
1173
1174   if (GET_CODE (x) != REG)
1175     abort ();
1176
1177   regno = REGNO (x);
1178   last_regno = (regno >= FIRST_PSEUDO_REGISTER ? regno
1179                 : regno + HARD_REGNO_NREGS (regno, GET_MODE (x)) - 1);
1180
1181   for (i = regno; i <= last_regno; i++)
1182     if (! dead_or_set_regno_p (insn, i))
1183       return 0;
1184
1185   return 1;
1186 }
1187
1188 /* Utility function for dead_or_set_p to check an individual register.  Also
1189    called from flow.c.  */
1190
1191 int
1192 dead_or_set_regno_p (insn, test_regno)
1193      rtx insn;
1194      int test_regno;
1195 {
1196   int regno, endregno;
1197   rtx link;
1198
1199   /* See if there is a death note for something that includes
1200      TEST_REGNO.  */
1201   for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
1202     {
1203       if (REG_NOTE_KIND (link) != REG_DEAD
1204           || GET_CODE (XEXP (link, 0)) != REG)
1205         continue;
1206
1207       regno = REGNO (XEXP (link, 0));
1208       endregno = (regno >= FIRST_PSEUDO_REGISTER ? regno + 1
1209                   : regno + HARD_REGNO_NREGS (regno,
1210                                               GET_MODE (XEXP (link, 0))));
1211
1212       if (test_regno >= regno && test_regno < endregno)
1213         return 1;
1214     }
1215
1216   if (GET_CODE (insn) == CALL_INSN
1217       && find_regno_fusage (insn, CLOBBER, test_regno))
1218     return 1;
1219
1220   if (GET_CODE (PATTERN (insn)) == SET)
1221     {
1222       rtx dest = SET_DEST (PATTERN (insn));
1223  
1224       /* A value is totally replaced if it is the destination or the
1225          destination is a SUBREG of REGNO that does not change the number of
1226          words in it.  */
1227       if (GET_CODE (dest) == SUBREG
1228           && (((GET_MODE_SIZE (GET_MODE (dest))
1229                 + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
1230               == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
1231                    + UNITS_PER_WORD - 1) / UNITS_PER_WORD)))
1232         dest = SUBREG_REG (dest);
1233
1234       if (GET_CODE (dest) != REG)
1235         return 0;
1236
1237       regno = REGNO (dest);
1238       endregno = (regno >= FIRST_PSEUDO_REGISTER ? regno + 1
1239                   : regno + HARD_REGNO_NREGS (regno, GET_MODE (dest)));
1240
1241       return (test_regno >= regno && test_regno < endregno);
1242     }
1243   else if (GET_CODE (PATTERN (insn)) == PARALLEL)
1244     {
1245       register int i;
1246
1247       for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
1248         {
1249           rtx body = XVECEXP (PATTERN (insn), 0, i);
1250
1251           if (GET_CODE (body) == SET || GET_CODE (body) == CLOBBER)
1252             {
1253               rtx dest = SET_DEST (body);
1254
1255               if (GET_CODE (dest) == SUBREG
1256                   && (((GET_MODE_SIZE (GET_MODE (dest))
1257                         + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
1258                       == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
1259                            + UNITS_PER_WORD - 1) / UNITS_PER_WORD)))
1260                 dest = SUBREG_REG (dest);
1261
1262               if (GET_CODE (dest) != REG)
1263                 continue;
1264
1265               regno = REGNO (dest);
1266               endregno = (regno >= FIRST_PSEUDO_REGISTER ? regno + 1
1267                           : regno + HARD_REGNO_NREGS (regno, GET_MODE (dest)));
1268
1269               if (test_regno >= regno && test_regno < endregno)
1270                 return 1;
1271             }
1272         }
1273     }
1274
1275   return 0;
1276 }
1277
1278 /* Return the reg-note of kind KIND in insn INSN, if there is one.
1279    If DATUM is nonzero, look for one whose datum is DATUM.  */
1280
1281 rtx
1282 find_reg_note (insn, kind, datum)
1283      rtx insn;
1284      enum reg_note kind;
1285      rtx datum;
1286 {
1287   register rtx link;
1288
1289   /* Ignore anything that is not an INSN, JUMP_INSN or CALL_INSN.  */
1290   if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
1291     return 0;
1292
1293   for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
1294     if (REG_NOTE_KIND (link) == kind
1295         && (datum == 0 || datum == XEXP (link, 0)))
1296       return link;
1297   return 0;
1298 }
1299
1300 /* Return the reg-note of kind KIND in insn INSN which applies to register
1301    number REGNO, if any.  Return 0 if there is no such reg-note.  Note that
1302    the REGNO of this NOTE need not be REGNO if REGNO is a hard register;
1303    it might be the case that the note overlaps REGNO.  */
1304
1305 rtx
1306 find_regno_note (insn, kind, regno)
1307      rtx insn;
1308      enum reg_note kind;
1309      int regno;
1310 {
1311   register rtx link;
1312
1313   /* Ignore anything that is not an INSN, JUMP_INSN or CALL_INSN.  */
1314   if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
1315     return 0;
1316
1317   for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
1318     if (REG_NOTE_KIND (link) == kind
1319         /* Verify that it is a register, so that scratch and MEM won't cause a
1320            problem here.  */
1321         && GET_CODE (XEXP (link, 0)) == REG
1322         && REGNO (XEXP (link, 0)) <= regno
1323         && ((REGNO (XEXP (link, 0))
1324              + (REGNO (XEXP (link, 0)) >= FIRST_PSEUDO_REGISTER ? 1
1325                 : HARD_REGNO_NREGS (REGNO (XEXP (link, 0)),
1326                                     GET_MODE (XEXP (link, 0)))))
1327             > regno))
1328       return link;
1329   return 0;
1330 }
1331
1332 /* Return true if DATUM, or any overlap of DATUM, of kind CODE is found
1333    in the CALL_INSN_FUNCTION_USAGE information of INSN.  */
1334
1335 int
1336 find_reg_fusage (insn, code, datum)
1337      rtx insn;
1338      enum rtx_code code;
1339      rtx datum;
1340 {
1341   /* If it's not a CALL_INSN, it can't possibly have a
1342      CALL_INSN_FUNCTION_USAGE field, so don't bother checking.  */
1343   if (GET_CODE (insn) != CALL_INSN)
1344     return 0;
1345
1346   if (! datum)
1347     abort();
1348
1349   if (GET_CODE (datum) != REG)
1350     {
1351       register rtx link;
1352
1353       for (link = CALL_INSN_FUNCTION_USAGE (insn);
1354            link;
1355            link = XEXP (link, 1))
1356         if (GET_CODE (XEXP (link, 0)) == code
1357             && rtx_equal_p (datum, SET_DEST (XEXP (link, 0))))
1358           return 1;
1359     }
1360   else
1361     {
1362       register int regno = REGNO (datum);
1363
1364       /* CALL_INSN_FUNCTION_USAGE information cannot contain references
1365          to pseudo registers, so don't bother checking.  */
1366
1367       if (regno < FIRST_PSEUDO_REGISTER)
1368         {
1369           int end_regno = regno + HARD_REGNO_NREGS (regno, GET_MODE (datum));
1370           int i;
1371
1372           for (i = regno; i < end_regno; i++)
1373             if (find_regno_fusage (insn, code, i))
1374               return 1;
1375         }
1376     }
1377
1378   return 0;
1379 }
1380
1381 /* Return true if REGNO, or any overlap of REGNO, of kind CODE is found
1382    in the CALL_INSN_FUNCTION_USAGE information of INSN.  */
1383
1384 int
1385 find_regno_fusage (insn, code, regno)
1386      rtx insn;
1387      enum rtx_code code;
1388      int regno;
1389 {
1390   register rtx link;
1391
1392   /* CALL_INSN_FUNCTION_USAGE information cannot contain references
1393      to pseudo registers, so don't bother checking.  */
1394
1395   if (regno >= FIRST_PSEUDO_REGISTER
1396       || GET_CODE (insn) != CALL_INSN )
1397     return 0;
1398
1399   for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
1400     {
1401       register int regnote;
1402       register rtx op, reg;
1403
1404       if (GET_CODE (op = XEXP (link, 0)) == code
1405           && GET_CODE (reg = XEXP (op, 0)) == REG
1406           && (regnote = REGNO (reg)) <= regno
1407           && regnote + HARD_REGNO_NREGS (regnote, GET_MODE (reg)) > regno)
1408         return 1;
1409     }
1410
1411   return 0;
1412 }
1413 \f
1414 /* Remove register note NOTE from the REG_NOTES of INSN.  */
1415
1416 void
1417 remove_note (insn, note)
1418      register rtx insn;
1419      register rtx note;
1420 {
1421   register rtx link;
1422
1423   if (note == NULL_RTX)
1424     return;
1425
1426   if (REG_NOTES (insn) == note)
1427     {
1428       REG_NOTES (insn) = XEXP (note, 1);
1429       return;
1430     }
1431
1432   for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
1433     if (XEXP (link, 1) == note)
1434       {
1435         XEXP (link, 1) = XEXP (note, 1);
1436         return;
1437       }
1438
1439   abort ();
1440 }
1441
1442 /* Search LISTP (an EXPR_LIST) for NODE and remove NODE from the list
1443    if it is found.
1444
1445    A simple equality test is used to determine if NODE is on the
1446    EXPR_LIST.  */
1447
1448 void
1449 remove_node_from_expr_list (node, listp)
1450      rtx node;
1451      rtx *listp;
1452 {
1453   rtx temp = *listp;
1454   rtx prev = NULL_RTX;
1455
1456   while (temp)
1457     {
1458       if (node == XEXP (temp, 0))
1459         {
1460           /* Splice the node out of the list.  */
1461           if (prev)
1462             XEXP (prev, 1) = XEXP (temp, 1);
1463           else
1464             *listp = XEXP (temp, 1);
1465
1466           return;
1467         }
1468       temp = XEXP (temp, 1);
1469     }
1470 }
1471 \f
1472 /* Nonzero if X contains any volatile instructions.  These are instructions
1473    which may cause unpredictable machine state instructions, and thus no
1474    instructions should be moved or combined across them.  This includes
1475    only volatile asms and UNSPEC_VOLATILE instructions.  */
1476
1477 int
1478 volatile_insn_p (x)
1479      rtx x;
1480 {
1481   register RTX_CODE code;
1482
1483   code = GET_CODE (x);
1484   switch (code)
1485     {
1486     case LABEL_REF:
1487     case SYMBOL_REF:
1488     case CONST_INT:
1489     case CONST:
1490     case CONST_DOUBLE:
1491     case CC0:
1492     case PC:
1493     case REG:
1494     case SCRATCH:
1495     case CLOBBER:
1496     case ASM_INPUT:
1497     case ADDR_VEC:
1498     case ADDR_DIFF_VEC:
1499     case CALL:
1500     case MEM:
1501       return 0;
1502
1503     case UNSPEC_VOLATILE:
1504  /* case TRAP_IF: This isn't clear yet.  */
1505       return 1;
1506
1507     case ASM_OPERANDS:
1508       if (MEM_VOLATILE_P (x))
1509         return 1;
1510
1511     default:
1512       break;
1513     }
1514
1515   /* Recursively scan the operands of this expression.  */
1516
1517   {
1518     register const char *fmt = GET_RTX_FORMAT (code);
1519     register int i;
1520     
1521     for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1522       {
1523         if (fmt[i] == 'e')
1524           {
1525             if (volatile_insn_p (XEXP (x, i)))
1526               return 1;
1527           }
1528         else if (fmt[i] == 'E')
1529           {
1530             register int j;
1531             for (j = 0; j < XVECLEN (x, i); j++)
1532               if (volatile_insn_p (XVECEXP (x, i, j)))
1533                 return 1;
1534           }
1535       }
1536   }
1537   return 0;
1538 }
1539
1540 /* Nonzero if X contains any volatile memory references
1541    UNSPEC_VOLATILE operations or volatile ASM_OPERANDS expressions.  */
1542
1543 int
1544 volatile_refs_p (x)
1545      rtx x;
1546 {
1547   register RTX_CODE code;
1548
1549   code = GET_CODE (x);
1550   switch (code)
1551     {
1552     case LABEL_REF:
1553     case SYMBOL_REF:
1554     case CONST_INT:
1555     case CONST:
1556     case CONST_DOUBLE:
1557     case CC0:
1558     case PC:
1559     case REG:
1560     case SCRATCH:
1561     case CLOBBER:
1562     case ASM_INPUT:
1563     case ADDR_VEC:
1564     case ADDR_DIFF_VEC:
1565       return 0;
1566
1567     case CALL:
1568     case UNSPEC_VOLATILE:
1569  /* case TRAP_IF: This isn't clear yet.  */
1570       return 1;
1571
1572     case MEM:
1573     case ASM_OPERANDS:
1574       if (MEM_VOLATILE_P (x))
1575         return 1;
1576
1577     default:
1578       break;
1579     }
1580
1581   /* Recursively scan the operands of this expression.  */
1582
1583   {
1584     register const char *fmt = GET_RTX_FORMAT (code);
1585     register int i;
1586     
1587     for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1588       {
1589         if (fmt[i] == 'e')
1590           {
1591             if (volatile_refs_p (XEXP (x, i)))
1592               return 1;
1593           }
1594         else if (fmt[i] == 'E')
1595           {
1596             register int j;
1597             for (j = 0; j < XVECLEN (x, i); j++)
1598               if (volatile_refs_p (XVECEXP (x, i, j)))
1599                 return 1;
1600           }
1601       }
1602   }
1603   return 0;
1604 }
1605
1606 /* Similar to above, except that it also rejects register pre- and post-
1607    incrementing.  */
1608
1609 int
1610 side_effects_p (x)
1611      rtx x;
1612 {
1613   register RTX_CODE code;
1614
1615   code = GET_CODE (x);
1616   switch (code)
1617     {
1618     case LABEL_REF:
1619     case SYMBOL_REF:
1620     case CONST_INT:
1621     case CONST:
1622     case CONST_DOUBLE:
1623     case CC0:
1624     case PC:
1625     case REG:
1626     case SCRATCH:
1627     case ASM_INPUT:
1628     case ADDR_VEC:
1629     case ADDR_DIFF_VEC:
1630       return 0;
1631
1632     case CLOBBER:
1633       /* Reject CLOBBER with a non-VOID mode.  These are made by combine.c
1634          when some combination can't be done.  If we see one, don't think
1635          that we can simplify the expression.  */
1636       return (GET_MODE (x) != VOIDmode);
1637
1638     case PRE_INC:
1639     case PRE_DEC:
1640     case POST_INC:
1641     case POST_DEC:
1642     case CALL:
1643     case UNSPEC_VOLATILE:
1644  /* case TRAP_IF: This isn't clear yet.  */
1645       return 1;
1646
1647     case MEM:
1648     case ASM_OPERANDS:
1649       if (MEM_VOLATILE_P (x))
1650         return 1;
1651
1652     default:
1653       break;
1654     }
1655
1656   /* Recursively scan the operands of this expression.  */
1657
1658   {
1659     register const char *fmt = GET_RTX_FORMAT (code);
1660     register int i;
1661     
1662     for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1663       {
1664         if (fmt[i] == 'e')
1665           {
1666             if (side_effects_p (XEXP (x, i)))
1667               return 1;
1668           }
1669         else if (fmt[i] == 'E')
1670           {
1671             register int j;
1672             for (j = 0; j < XVECLEN (x, i); j++)
1673               if (side_effects_p (XVECEXP (x, i, j)))
1674                 return 1;
1675           }
1676       }
1677   }
1678   return 0;
1679 }
1680 \f
1681 /* Return nonzero if evaluating rtx X might cause a trap.  */
1682
1683 int
1684 may_trap_p (x)
1685      rtx x;
1686 {
1687   int i;
1688   enum rtx_code code;
1689   const char *fmt;
1690
1691   if (x == 0)
1692     return 0;
1693   code = GET_CODE (x);
1694   switch (code)
1695     {
1696       /* Handle these cases quickly.  */
1697     case CONST_INT:
1698     case CONST_DOUBLE:
1699     case SYMBOL_REF:
1700     case LABEL_REF:
1701     case CONST:
1702     case PC:
1703     case CC0:
1704     case REG:
1705     case SCRATCH:
1706       return 0;
1707
1708       /* Conditional trap can trap!  */
1709     case UNSPEC_VOLATILE:
1710     case TRAP_IF:
1711       return 1;
1712
1713       /* Memory ref can trap unless it's a static var or a stack slot.  */
1714     case MEM:
1715       return rtx_addr_can_trap_p (XEXP (x, 0));
1716
1717       /* Division by a non-constant might trap.  */
1718     case DIV:
1719     case MOD:
1720     case UDIV:
1721     case UMOD:
1722       if (! CONSTANT_P (XEXP (x, 1))
1723           || GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
1724         return 1;
1725       /* This was const0_rtx, but by not using that,
1726          we can link this file into other programs.  */
1727       if (GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) == 0)
1728         return 1;
1729       break;
1730
1731     case EXPR_LIST:
1732       /* An EXPR_LIST is used to represent a function call.  This
1733          certainly may trap.  */
1734       return 1;
1735
1736     default:
1737       /* Any floating arithmetic may trap.  */
1738       if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
1739         return 1;
1740     }
1741
1742   fmt = GET_RTX_FORMAT (code);
1743   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1744     {
1745       if (fmt[i] == 'e')
1746         {
1747           if (may_trap_p (XEXP (x, i)))
1748             return 1;
1749         }
1750       else if (fmt[i] == 'E')
1751         {
1752           register int j;
1753           for (j = 0; j < XVECLEN (x, i); j++)
1754             if (may_trap_p (XVECEXP (x, i, j)))
1755               return 1;
1756         }
1757     }
1758   return 0;
1759 }
1760 \f
1761 /* Return nonzero if X contains a comparison that is not either EQ or NE,
1762    i.e., an inequality.  */
1763
1764 int
1765 inequality_comparisons_p (x)
1766      rtx x;
1767 {
1768   register const char *fmt;
1769   register int len, i;
1770   register enum rtx_code code = GET_CODE (x);
1771
1772   switch (code)
1773     {
1774     case REG:
1775     case SCRATCH:
1776     case PC:
1777     case CC0:
1778     case CONST_INT:
1779     case CONST_DOUBLE:
1780     case CONST:
1781     case LABEL_REF:
1782     case SYMBOL_REF:
1783       return 0;
1784
1785     case LT:
1786     case LTU:
1787     case GT:
1788     case GTU:
1789     case LE:
1790     case LEU:
1791     case GE:
1792     case GEU:
1793       return 1;
1794       
1795     default:
1796       break;
1797     }
1798
1799   len = GET_RTX_LENGTH (code);
1800   fmt = GET_RTX_FORMAT (code);
1801
1802   for (i = 0; i < len; i++)
1803     {
1804       if (fmt[i] == 'e')
1805         {
1806           if (inequality_comparisons_p (XEXP (x, i)))
1807             return 1;
1808         }
1809       else if (fmt[i] == 'E')
1810         {
1811           register int j;
1812           for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1813             if (inequality_comparisons_p (XVECEXP (x, i, j)))
1814               return 1;
1815         }
1816     }
1817             
1818   return 0;
1819 }
1820 \f
1821 /* Replace any occurrence of FROM in X with TO.  The function does
1822    not enter into CONST_DOUBLE for the replace.
1823
1824    Note that copying is not done so X must not be shared unless all copies
1825    are to be modified.  */
1826
1827 rtx
1828 replace_rtx (x, from, to)
1829      rtx x, from, to;
1830 {
1831   register int i, j;
1832   register const char *fmt;
1833
1834   /* The following prevents loops occurrence when we change MEM in
1835      CONST_DOUBLE onto the same CONST_DOUBLE. */
1836   if (x != 0 && GET_CODE (x) == CONST_DOUBLE)
1837     return x;
1838
1839   if (x == from)
1840     return to;
1841
1842   /* Allow this function to make replacements in EXPR_LISTs.  */
1843   if (x == 0)
1844     return 0;
1845
1846   fmt = GET_RTX_FORMAT (GET_CODE (x));
1847   for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
1848     {
1849       if (fmt[i] == 'e')
1850         XEXP (x, i) = replace_rtx (XEXP (x, i), from, to);
1851       else if (fmt[i] == 'E')
1852         for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1853           XVECEXP (x, i, j) = replace_rtx (XVECEXP (x, i, j), from, to);
1854     }
1855
1856   return x;
1857 }  
1858 \f
1859 /* Throughout the rtx X, replace many registers according to REG_MAP.
1860    Return the replacement for X (which may be X with altered contents).
1861    REG_MAP[R] is the replacement for register R, or 0 for don't replace.
1862    NREGS is the length of REG_MAP; regs >= NREGS are not mapped.  
1863
1864    We only support REG_MAP entries of REG or SUBREG.  Also, hard registers
1865    should not be mapped to pseudos or vice versa since validate_change
1866    is not called.
1867
1868    If REPLACE_DEST is 1, replacements are also done in destinations;
1869    otherwise, only sources are replaced.  */
1870
1871 rtx
1872 replace_regs (x, reg_map, nregs, replace_dest)
1873      rtx x;
1874      rtx *reg_map;
1875      int nregs;
1876      int replace_dest;
1877 {
1878   register enum rtx_code code;
1879   register int i;
1880   register const char *fmt;
1881
1882   if (x == 0)
1883     return x;
1884
1885   code = GET_CODE (x);
1886   switch (code)
1887     {
1888     case SCRATCH:
1889     case PC:
1890     case CC0:
1891     case CONST_INT:
1892     case CONST_DOUBLE:
1893     case CONST:
1894     case SYMBOL_REF:
1895     case LABEL_REF:
1896       return x;
1897
1898     case REG:
1899       /* Verify that the register has an entry before trying to access it.  */
1900       if (REGNO (x) < nregs && reg_map[REGNO (x)] != 0)
1901         {
1902           /* SUBREGs can't be shared.  Always return a copy to ensure that if
1903              this replacement occurs more than once then each instance will
1904              get distinct rtx.  */
1905           if (GET_CODE (reg_map[REGNO (x)]) == SUBREG)
1906             return copy_rtx (reg_map[REGNO (x)]);
1907           return reg_map[REGNO (x)];
1908         }
1909       return x;
1910
1911     case SUBREG:
1912       /* Prevent making nested SUBREGs.  */
1913       if (GET_CODE (SUBREG_REG (x)) == REG && REGNO (SUBREG_REG (x)) < nregs
1914           && reg_map[REGNO (SUBREG_REG (x))] != 0
1915           && GET_CODE (reg_map[REGNO (SUBREG_REG (x))]) == SUBREG)
1916         {
1917           rtx map_val = reg_map[REGNO (SUBREG_REG (x))];
1918           rtx map_inner = SUBREG_REG (map_val);
1919
1920           if (GET_MODE (x) == GET_MODE (map_inner))
1921             return map_inner;
1922           else
1923             {
1924               /* We cannot call gen_rtx here since we may be linked with
1925                  genattrtab.c.  */
1926               /* Let's try clobbering the incoming SUBREG and see
1927                  if this is really safe.  */
1928               SUBREG_REG (x) = map_inner;
1929               SUBREG_WORD (x) += SUBREG_WORD (map_val);
1930               return x;
1931 #if 0
1932               rtx new = rtx_alloc (SUBREG);
1933               PUT_MODE (new, GET_MODE (x));
1934               SUBREG_REG (new) = map_inner;
1935               SUBREG_WORD (new) = SUBREG_WORD (x) + SUBREG_WORD (map_val);
1936 #endif
1937             }
1938         }
1939       break;
1940
1941     case SET:
1942       if (replace_dest)
1943         SET_DEST (x) = replace_regs (SET_DEST (x), reg_map, nregs, 0);
1944
1945       else if (GET_CODE (SET_DEST (x)) == MEM
1946                || GET_CODE (SET_DEST (x)) == STRICT_LOW_PART)
1947         /* Even if we are not to replace destinations, replace register if it
1948            is CONTAINED in destination (destination is memory or
1949            STRICT_LOW_PART).  */
1950         XEXP (SET_DEST (x), 0) = replace_regs (XEXP (SET_DEST (x), 0),
1951                                                reg_map, nregs, 0);
1952       else if (GET_CODE (SET_DEST (x)) == ZERO_EXTRACT)
1953         /* Similarly, for ZERO_EXTRACT we replace all operands.  */
1954         break;
1955
1956       SET_SRC (x) = replace_regs (SET_SRC (x), reg_map, nregs, 0);
1957       return x;
1958       
1959     default:
1960       break;
1961     }
1962
1963   fmt = GET_RTX_FORMAT (code);
1964   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1965     {
1966       if (fmt[i] == 'e')
1967         XEXP (x, i) = replace_regs (XEXP (x, i), reg_map, nregs, replace_dest);
1968       else if (fmt[i] == 'E')
1969         {
1970           register int j;
1971           for (j = 0; j < XVECLEN (x, i); j++)
1972             XVECEXP (x, i, j) = replace_regs (XVECEXP (x, i, j), reg_map,
1973                                               nregs, replace_dest);
1974         }
1975     }
1976   return x;
1977 }
1978
1979 /* Return 1 if X, the SRC_SRC of  SET of (pc) contain a REG or MEM that is
1980    not in the constant pool and not in the condition of an IF_THEN_ELSE.  */
1981
1982 static int
1983 jmp_uses_reg_or_mem (x)
1984      rtx x;
1985 {
1986   enum rtx_code code = GET_CODE (x);
1987   int i, j;
1988   const char *fmt;
1989
1990   switch (code)
1991     {
1992     case CONST:
1993     case LABEL_REF:
1994     case PC:
1995       return 0;
1996
1997     case REG:
1998       return 1;
1999
2000     case MEM:
2001       return ! (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
2002                 && CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)));
2003
2004     case IF_THEN_ELSE:
2005       return (jmp_uses_reg_or_mem (XEXP (x, 1))
2006               || jmp_uses_reg_or_mem (XEXP (x, 2)));
2007
2008     case PLUS:  case MINUS:  case MULT:
2009       return (jmp_uses_reg_or_mem (XEXP (x, 0))
2010               || jmp_uses_reg_or_mem (XEXP (x, 1)));
2011
2012     default:
2013       break;
2014     }
2015
2016   fmt = GET_RTX_FORMAT (code);
2017   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2018     {
2019       if (fmt[i] == 'e'
2020           && jmp_uses_reg_or_mem (XEXP (x, i)))
2021         return 1;
2022
2023       else if (fmt[i] == 'E')
2024         for (j = 0; j < XVECLEN (x, i); j++)
2025           if (jmp_uses_reg_or_mem (XVECEXP (x, i, j)))
2026             return 1;
2027     }
2028
2029   return 0;
2030 }
2031
2032 /* Return nonzero if INSN is an indirect jump (aka computed jump).
2033
2034    Tablejumps and casesi insns are not considered indirect jumps;
2035    we can recognize them by a (use (lael_ref)).  */
2036
2037 int
2038 computed_jump_p (insn)
2039      rtx insn;
2040 {
2041   int i;
2042   if (GET_CODE (insn) == JUMP_INSN)
2043     {
2044       rtx pat = PATTERN (insn);
2045
2046       if (GET_CODE (pat) == PARALLEL)
2047         {
2048           int len = XVECLEN (pat, 0);
2049           int has_use_labelref = 0;
2050
2051           for (i = len - 1; i >= 0; i--)
2052             if (GET_CODE (XVECEXP (pat, 0, i)) == USE
2053                 && (GET_CODE (XEXP (XVECEXP (pat, 0, i), 0))
2054                     == LABEL_REF))
2055               has_use_labelref = 1;
2056
2057           if (! has_use_labelref)
2058             for (i = len - 1; i >= 0; i--)
2059               if (GET_CODE (XVECEXP (pat, 0, i)) == SET
2060                   && SET_DEST (XVECEXP (pat, 0, i)) == pc_rtx
2061                   && jmp_uses_reg_or_mem (SET_SRC (XVECEXP (pat, 0, i))))
2062                 return 1;
2063         }
2064       else if (GET_CODE (pat) == SET
2065                && SET_DEST (pat) == pc_rtx
2066                && jmp_uses_reg_or_mem (SET_SRC (pat)))
2067         return 1;
2068     }
2069   return 0;
2070 }
2071
2072 /* Traverse X via depth-first search, calling F for each
2073    sub-expression (including X itself).  F is also passed the DATA.
2074    If F returns -1, do not traverse sub-expressions, but continue
2075    traversing the rest of the tree.  If F ever returns any other
2076    non-zero value, stop the traversal, and return the value returned
2077    by F.  Otherwise, return 0.  This function does not traverse inside
2078    tree structure that contains RTX_EXPRs, or into sub-expressions
2079    whose format code is `0' since it is not known whether or not those
2080    codes are actually RTL.
2081
2082    This routine is very general, and could (should?) be used to
2083    implement many of the other routines in this file.  */
2084
2085 int
2086 for_each_rtx (x, f, data)
2087      rtx *x;
2088      rtx_function f;
2089      void *data;
2090 {
2091   int result;
2092   int length;
2093   const char* format;
2094   int i;
2095
2096   /* Call F on X.  */
2097   result = (*f)(x, data);
2098   if (result == -1)
2099     /* Do not traverse sub-expressions.  */
2100     return 0;
2101   else if (result != 0)
2102     /* Stop the traversal.  */
2103     return result;
2104
2105   if (*x == NULL_RTX)
2106     /* There are no sub-expressions.  */
2107     return 0;
2108
2109   length = GET_RTX_LENGTH (GET_CODE (*x));
2110   format = GET_RTX_FORMAT (GET_CODE (*x));
2111
2112   for (i = 0; i < length; ++i) 
2113     {
2114       switch (format[i]) 
2115         {
2116         case 'e':
2117           result = for_each_rtx (&XEXP (*x, i), f, data);
2118           if (result != 0)
2119             return result;
2120           break;
2121
2122         case 'V':
2123         case 'E':
2124           if (XVEC (*x, i) != 0) 
2125             {
2126               int j;
2127               for (j = 0; j < XVECLEN (*x, i); ++j)
2128                 {
2129                   result = for_each_rtx (&XVECEXP (*x, i, j), f, data);
2130                   if (result != 0)
2131                     return result;
2132                 }
2133             }
2134           break; 
2135
2136         default:
2137           /* Nothing to do.  */
2138           break;
2139         }
2140
2141     }
2142
2143   return 0;
2144 }
2145
2146 /* Searches X for any reference to REGNO, returning the rtx of the
2147    reference found if any.  Otherwise, returns NULL_RTX.  */
2148
2149 rtx
2150 regno_use_in (regno, x)
2151      int regno;
2152      rtx x;
2153 {
2154   register const char *fmt;
2155   int i, j;
2156   rtx tem;
2157
2158   if (GET_CODE (x) == REG && REGNO (x) == regno)
2159     return x;
2160
2161   fmt = GET_RTX_FORMAT (GET_CODE (x));
2162   for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
2163     {
2164       if (fmt[i] == 'e')
2165         {
2166           if ((tem = regno_use_in (regno, XEXP (x, i))))
2167             return tem;
2168         }
2169       else if (fmt[i] == 'E')
2170         for (j = XVECLEN (x, i) - 1; j >= 0; j--)
2171           if ((tem = regno_use_in (regno , XVECEXP (x, i, j))))
2172             return tem;
2173     }
2174
2175   return NULL_RTX;
2176 }
2177
2178
2179 /* Return 1 if X is an autoincrement side effect and the register is
2180    not the stack pointer.  */
2181 int
2182 auto_inc_p (x)
2183      rtx x;
2184 {
2185   switch (GET_CODE (x))
2186     {
2187     case PRE_INC:
2188     case POST_INC:
2189     case PRE_DEC:
2190     case POST_DEC:
2191     case PRE_MODIFY:
2192     case POST_MODIFY:
2193       /* There are no REG_INC notes for SP.  */
2194       if (XEXP (x, 0) != stack_pointer_rtx)
2195         return 1;
2196     default:
2197       break;
2198     }
2199   return 0;
2200 }
2201
2202 /* Return 1 if the sequence of instructions beginning with FROM and up
2203    to and including TO is safe to move.  If NEW_TO is non-NULL, and
2204    the sequence is not already safe to move, but can be easily
2205    extended to a sequence which is safe, then NEW_TO will point to the
2206    end of the extended sequence.  
2207  
2208    For now, this function only checks that the region contains whole
2209    exception regiongs, but it could be extended to check additional
2210    conditions as well.  */
2211
2212 int
2213 insns_safe_to_move_p (from, to, new_to)
2214      rtx from;
2215      rtx to;
2216      rtx *new_to;
2217 {
2218   int eh_region_count = 0;
2219   int past_to_p = 0;
2220   rtx r = from;
2221
2222   /* By default, assume the end of the region will be what was
2223      suggested.  */
2224   if (new_to)
2225     *new_to = to;
2226
2227   while (r)
2228     {
2229       if (GET_CODE (r) == NOTE)
2230         {
2231           switch (NOTE_LINE_NUMBER (r))
2232             {
2233             case NOTE_INSN_EH_REGION_BEG:
2234               ++eh_region_count;
2235               break;
2236
2237             case NOTE_INSN_EH_REGION_END:
2238               if (eh_region_count == 0)
2239                 /* This sequence of instructions contains the end of
2240                    an exception region, but not he beginning.  Moving
2241                    it will cause chaos.  */
2242                 return 0;
2243
2244               --eh_region_count;
2245               break;
2246
2247             default:
2248               break;
2249             }
2250         }
2251       else if (past_to_p)
2252         /* If we've passed TO, and we see a non-note instruction, we
2253            can't extend the sequence to a movable sequence.  */
2254         return 0;
2255
2256       if (r == to)
2257         {
2258           if (!new_to)
2259             /* It's OK to move the sequence if there were matched sets of
2260                exception region notes.  */
2261             return eh_region_count == 0;
2262           
2263           past_to_p = 1;
2264         }
2265
2266       /* It's OK to move the sequence if there were matched sets of
2267          exception region notes.  */
2268       if (past_to_p && eh_region_count == 0)
2269         {
2270           *new_to = r;
2271           return 1;
2272         }
2273
2274       /* Go to the next instruction.  */
2275       r = NEXT_INSN (r);
2276     }
2277   
2278   return 0;
2279 }