OSDN Git Service

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