OSDN Git Service

gcc/testsuite/
[pf3gnuchains/gcc-fork.git] / gcc / jump.c
1 /* Optimize jump instructions, for GNU compiler.
2    Copyright (C) 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997
3    1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
4    Free Software Foundation, Inc.
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21
22 /* This is the pathetic reminder of old fame of the jump-optimization pass
23    of the compiler.  Now it contains basically a set of utility functions to
24    operate with jumps.
25
26    Each CODE_LABEL has a count of the times it is used
27    stored in the LABEL_NUSES internal field, and each JUMP_INSN
28    has one label that it refers to stored in the
29    JUMP_LABEL internal field.  With this we can detect labels that
30    become unused because of the deletion of all the jumps that
31    formerly used them.  The JUMP_LABEL info is sometimes looked
32    at by later passes.
33
34    The subroutines redirect_jump and invert_jump are used
35    from other passes as well.  */
36
37 #include "config.h"
38 #include "system.h"
39 #include "coretypes.h"
40 #include "tm.h"
41 #include "rtl.h"
42 #include "tm_p.h"
43 #include "flags.h"
44 #include "hard-reg-set.h"
45 #include "regs.h"
46 #include "insn-config.h"
47 #include "insn-attr.h"
48 #include "recog.h"
49 #include "function.h"
50 #include "expr.h"
51 #include "real.h"
52 #include "except.h"
53 #include "diagnostic.h"
54 #include "toplev.h"
55 #include "reload.h"
56 #include "predict.h"
57 #include "timevar.h"
58 #include "tree-pass.h"
59 #include "target.h"
60
61 /* Optimize jump y; x: ... y: jumpif... x?
62    Don't know if it is worth bothering with.  */
63 /* Optimize two cases of conditional jump to conditional jump?
64    This can never delete any instruction or make anything dead,
65    or even change what is live at any point.
66    So perhaps let combiner do it.  */
67
68 static void init_label_info (rtx);
69 static void mark_all_labels (rtx);
70 static void mark_jump_label_1 (rtx, rtx, bool, bool);
71 static void redirect_exp_1 (rtx *, rtx, rtx, rtx);
72 static int invert_exp_1 (rtx, rtx);
73 static int returnjump_p_1 (rtx *, void *);
74 \f
75 /* This function rebuilds the JUMP_LABEL field and REG_LABEL_TARGET
76    notes in jumping insns and REG_LABEL_OPERAND notes in non-jumping
77    instructions and jumping insns that have labels as operands
78    (e.g. cbranchsi4).  */
79 void
80 rebuild_jump_labels (rtx f)
81 {
82   rtx insn;
83
84   timevar_push (TV_REBUILD_JUMP);
85   init_label_info (f);
86   mark_all_labels (f);
87
88   /* Keep track of labels used from static data; we don't track them
89      closely enough to delete them here, so make sure their reference
90      count doesn't drop to zero.  */
91
92   for (insn = forced_labels; insn; insn = XEXP (insn, 1))
93     if (LABEL_P (XEXP (insn, 0)))
94       LABEL_NUSES (XEXP (insn, 0))++;
95   timevar_pop (TV_REBUILD_JUMP);
96 }
97 \f
98 /* Some old code expects exactly one BARRIER as the NEXT_INSN of a
99    non-fallthru insn.  This is not generally true, as multiple barriers
100    may have crept in, or the BARRIER may be separated from the last
101    real insn by one or more NOTEs.
102
103    This simple pass moves barriers and removes duplicates so that the
104    old code is happy.
105  */
106 unsigned int
107 cleanup_barriers (void)
108 {
109   rtx insn, next, prev;
110   for (insn = get_insns (); insn; insn = next)
111     {
112       next = NEXT_INSN (insn);
113       if (BARRIER_P (insn))
114         {
115           prev = prev_nonnote_insn (insn);
116           if (!prev)
117             continue;
118           if (BARRIER_P (prev))
119             delete_insn (insn);
120           else if (prev != PREV_INSN (insn))
121             reorder_insns (insn, insn, prev);
122         }
123     }
124   return 0;
125 }
126
127 struct rtl_opt_pass pass_cleanup_barriers =
128 {
129  {
130   RTL_PASS,
131   "barriers",                           /* name */
132   NULL,                                 /* gate */
133   cleanup_barriers,                     /* execute */
134   NULL,                                 /* sub */
135   NULL,                                 /* next */
136   0,                                    /* static_pass_number */
137   TV_NONE,                              /* tv_id */
138   0,                                    /* properties_required */
139   0,                                    /* properties_provided */
140   0,                                    /* properties_destroyed */
141   0,                                    /* todo_flags_start */
142   TODO_dump_func                        /* todo_flags_finish */
143  }
144 };
145
146 \f
147 /* Initialize LABEL_NUSES and JUMP_LABEL fields, add REG_LABEL_TARGET
148    for remaining targets for JUMP_P.  Delete any REG_LABEL_OPERAND
149    notes whose labels don't occur in the insn any more.  */
150
151 static void
152 init_label_info (rtx f)
153 {
154   rtx insn;
155
156   for (insn = f; insn; insn = NEXT_INSN (insn))
157     {
158       if (LABEL_P (insn))
159         LABEL_NUSES (insn) = (LABEL_PRESERVE_P (insn) != 0);
160
161       /* REG_LABEL_TARGET notes (including the JUMP_LABEL field) are
162          sticky and not reset here; that way we won't lose association
163          with a label when e.g. the source for a target register
164          disappears out of reach for targets that may use jump-target
165          registers.  Jump transformations are supposed to transform
166          any REG_LABEL_TARGET notes.  The target label reference in a
167          branch may disappear from the branch (and from the
168          instruction before it) for other reasons, like register
169          allocation.  */
170
171       if (INSN_P (insn))
172         {
173           rtx note, next;
174
175           for (note = REG_NOTES (insn); note; note = next)
176             {
177               next = XEXP (note, 1);
178               if (REG_NOTE_KIND (note) == REG_LABEL_OPERAND
179                   && ! reg_mentioned_p (XEXP (note, 0), PATTERN (insn)))
180                 remove_note (insn, note);
181             }
182         }
183     }
184 }
185
186 /* Mark the label each jump jumps to.
187    Combine consecutive labels, and count uses of labels.  */
188
189 static void
190 mark_all_labels (rtx f)
191 {
192   rtx insn;
193   rtx prev_nonjump_insn = NULL;
194
195   for (insn = f; insn; insn = NEXT_INSN (insn))
196     if (INSN_P (insn))
197       {
198         mark_jump_label (PATTERN (insn), insn, 0);
199
200         /* If the previous non-jump insn sets something to a label,
201            something that this jump insn uses, make that label the primary
202            target of this insn if we don't yet have any.  That previous
203            insn must be a single_set and not refer to more than one label.
204            The jump insn must not refer to other labels as jump targets
205            and must be a plain (set (pc) ...), maybe in a parallel, and
206            may refer to the item being set only directly or as one of the
207            arms in an IF_THEN_ELSE.  */
208         if (! INSN_DELETED_P (insn)
209             && JUMP_P (insn)
210             && JUMP_LABEL (insn) == NULL)
211           {
212             rtx label_note = NULL;
213             rtx pc = pc_set (insn);
214             rtx pc_src = pc != NULL ? SET_SRC (pc) : NULL;
215
216             if (prev_nonjump_insn != NULL)
217               label_note
218                 = find_reg_note (prev_nonjump_insn, REG_LABEL_OPERAND, NULL);
219
220             if (label_note != NULL && pc_src != NULL)
221               {
222                 rtx label_set = single_set (prev_nonjump_insn);
223                 rtx label_dest
224                   = label_set != NULL ? SET_DEST (label_set) : NULL;
225
226                 if (label_set != NULL
227                     /* The source must be the direct LABEL_REF, not a
228                        PLUS, UNSPEC, IF_THEN_ELSE etc.  */
229                     && GET_CODE (SET_SRC (label_set)) == LABEL_REF
230                     && (rtx_equal_p (label_dest, pc_src)
231                         || (GET_CODE (pc_src) == IF_THEN_ELSE
232                             && (rtx_equal_p (label_dest, XEXP (pc_src, 1))
233                                 || rtx_equal_p (label_dest,
234                                                 XEXP (pc_src, 2))))))
235                                 
236                   {
237                     /* The CODE_LABEL referred to in the note must be the
238                        CODE_LABEL in the LABEL_REF of the "set".  We can
239                        conveniently use it for the marker function, which
240                        requires a LABEL_REF wrapping.  */
241                     gcc_assert (XEXP (label_note, 0)
242                                 == XEXP (SET_SRC (label_set), 0));
243
244                     mark_jump_label_1 (label_set, insn, false, true);
245                     gcc_assert (JUMP_LABEL (insn)
246                                 == XEXP (SET_SRC (label_set), 0));
247                   }
248               }
249           }
250         else if (! INSN_DELETED_P (insn))
251           prev_nonjump_insn = insn;
252       }
253     else if (LABEL_P (insn))
254       prev_nonjump_insn = NULL;
255
256   /* If we are in cfglayout mode, there may be non-insns between the
257      basic blocks.  If those non-insns represent tablejump data, they
258      contain label references that we must record.  */
259   if (current_ir_type () == IR_RTL_CFGLAYOUT)
260     {
261       basic_block bb;
262       rtx insn;
263       FOR_EACH_BB (bb)
264         {
265           for (insn = bb->il.rtl->header; insn; insn = NEXT_INSN (insn))
266             if (INSN_P (insn))
267               {
268                 gcc_assert (JUMP_TABLE_DATA_P (insn));
269                 mark_jump_label (PATTERN (insn), insn, 0);
270               }
271
272           for (insn = bb->il.rtl->footer; insn; insn = NEXT_INSN (insn))
273             if (INSN_P (insn))
274               {
275                 gcc_assert (JUMP_TABLE_DATA_P (insn));
276                 mark_jump_label (PATTERN (insn), insn, 0);
277               }
278         }
279     }
280 }
281 \f
282 /* Given a comparison (CODE ARG0 ARG1), inside an insn, INSN, return a code
283    of reversed comparison if it is possible to do so.  Otherwise return UNKNOWN.
284    UNKNOWN may be returned in case we are having CC_MODE compare and we don't
285    know whether it's source is floating point or integer comparison.  Machine
286    description should define REVERSIBLE_CC_MODE and REVERSE_CONDITION macros
287    to help this function avoid overhead in these cases.  */
288 enum rtx_code
289 reversed_comparison_code_parts (enum rtx_code code, const_rtx arg0,
290                                 const_rtx arg1, const_rtx insn)
291 {
292   enum machine_mode mode;
293
294   /* If this is not actually a comparison, we can't reverse it.  */
295   if (GET_RTX_CLASS (code) != RTX_COMPARE
296       && GET_RTX_CLASS (code) != RTX_COMM_COMPARE)
297     return UNKNOWN;
298
299   mode = GET_MODE (arg0);
300   if (mode == VOIDmode)
301     mode = GET_MODE (arg1);
302
303   /* First see if machine description supplies us way to reverse the
304      comparison.  Give it priority over everything else to allow
305      machine description to do tricks.  */
306   if (GET_MODE_CLASS (mode) == MODE_CC
307       && REVERSIBLE_CC_MODE (mode))
308     {
309 #ifdef REVERSE_CONDITION
310       return REVERSE_CONDITION (code, mode);
311 #endif
312       return reverse_condition (code);
313     }
314
315   /* Try a few special cases based on the comparison code.  */
316   switch (code)
317     {
318     case GEU:
319     case GTU:
320     case LEU:
321     case LTU:
322     case NE:
323     case EQ:
324       /* It is always safe to reverse EQ and NE, even for the floating
325          point.  Similarly the unsigned comparisons are never used for
326          floating point so we can reverse them in the default way.  */
327       return reverse_condition (code);
328     case ORDERED:
329     case UNORDERED:
330     case LTGT:
331     case UNEQ:
332       /* In case we already see unordered comparison, we can be sure to
333          be dealing with floating point so we don't need any more tests.  */
334       return reverse_condition_maybe_unordered (code);
335     case UNLT:
336     case UNLE:
337     case UNGT:
338     case UNGE:
339       /* We don't have safe way to reverse these yet.  */
340       return UNKNOWN;
341     default:
342       break;
343     }
344
345   if (GET_MODE_CLASS (mode) == MODE_CC || CC0_P (arg0))
346     {
347       const_rtx prev;
348       /* Try to search for the comparison to determine the real mode.
349          This code is expensive, but with sane machine description it
350          will be never used, since REVERSIBLE_CC_MODE will return true
351          in all cases.  */
352       if (! insn)
353         return UNKNOWN;
354
355       /* These CONST_CAST's are okay because prev_nonnote_insn just
356          returns its argument and we assign it to a const_rtx
357          variable.  */
358       for (prev = prev_nonnote_insn (CONST_CAST_RTX(insn));
359            prev != 0 && !LABEL_P (prev);
360            prev = prev_nonnote_insn (CONST_CAST_RTX(prev)))
361         {
362           const_rtx set = set_of (arg0, prev);
363           if (set && GET_CODE (set) == SET
364               && rtx_equal_p (SET_DEST (set), arg0))
365             {
366               rtx src = SET_SRC (set);
367
368               if (GET_CODE (src) == COMPARE)
369                 {
370                   rtx comparison = src;
371                   arg0 = XEXP (src, 0);
372                   mode = GET_MODE (arg0);
373                   if (mode == VOIDmode)
374                     mode = GET_MODE (XEXP (comparison, 1));
375                   break;
376                 }
377               /* We can get past reg-reg moves.  This may be useful for model
378                  of i387 comparisons that first move flag registers around.  */
379               if (REG_P (src))
380                 {
381                   arg0 = src;
382                   continue;
383                 }
384             }
385           /* If register is clobbered in some ununderstandable way,
386              give up.  */
387           if (set)
388             return UNKNOWN;
389         }
390     }
391
392   /* Test for an integer condition, or a floating-point comparison
393      in which NaNs can be ignored.  */
394   if (CONST_INT_P (arg0)
395       || (GET_MODE (arg0) != VOIDmode
396           && GET_MODE_CLASS (mode) != MODE_CC
397           && !HONOR_NANS (mode)))
398     return reverse_condition (code);
399
400   return UNKNOWN;
401 }
402
403 /* A wrapper around the previous function to take COMPARISON as rtx
404    expression.  This simplifies many callers.  */
405 enum rtx_code
406 reversed_comparison_code (const_rtx comparison, const_rtx insn)
407 {
408   if (!COMPARISON_P (comparison))
409     return UNKNOWN;
410   return reversed_comparison_code_parts (GET_CODE (comparison),
411                                          XEXP (comparison, 0),
412                                          XEXP (comparison, 1), insn);
413 }
414
415 /* Return comparison with reversed code of EXP.
416    Return NULL_RTX in case we fail to do the reversal.  */
417 rtx
418 reversed_comparison (const_rtx exp, enum machine_mode mode)
419 {
420   enum rtx_code reversed_code = reversed_comparison_code (exp, NULL_RTX);
421   if (reversed_code == UNKNOWN)
422     return NULL_RTX;
423   else
424     return simplify_gen_relational (reversed_code, mode, VOIDmode,
425                                     XEXP (exp, 0), XEXP (exp, 1));
426 }
427
428 \f
429 /* Given an rtx-code for a comparison, return the code for the negated
430    comparison.  If no such code exists, return UNKNOWN.
431
432    WATCH OUT!  reverse_condition is not safe to use on a jump that might
433    be acting on the results of an IEEE floating point comparison, because
434    of the special treatment of non-signaling nans in comparisons.
435    Use reversed_comparison_code instead.  */
436
437 enum rtx_code
438 reverse_condition (enum rtx_code code)
439 {
440   switch (code)
441     {
442     case EQ:
443       return NE;
444     case NE:
445       return EQ;
446     case GT:
447       return LE;
448     case GE:
449       return LT;
450     case LT:
451       return GE;
452     case LE:
453       return GT;
454     case GTU:
455       return LEU;
456     case GEU:
457       return LTU;
458     case LTU:
459       return GEU;
460     case LEU:
461       return GTU;
462     case UNORDERED:
463       return ORDERED;
464     case ORDERED:
465       return UNORDERED;
466
467     case UNLT:
468     case UNLE:
469     case UNGT:
470     case UNGE:
471     case UNEQ:
472     case LTGT:
473       return UNKNOWN;
474
475     default:
476       gcc_unreachable ();
477     }
478 }
479
480 /* Similar, but we're allowed to generate unordered comparisons, which
481    makes it safe for IEEE floating-point.  Of course, we have to recognize
482    that the target will support them too...  */
483
484 enum rtx_code
485 reverse_condition_maybe_unordered (enum rtx_code code)
486 {
487   switch (code)
488     {
489     case EQ:
490       return NE;
491     case NE:
492       return EQ;
493     case GT:
494       return UNLE;
495     case GE:
496       return UNLT;
497     case LT:
498       return UNGE;
499     case LE:
500       return UNGT;
501     case LTGT:
502       return UNEQ;
503     case UNORDERED:
504       return ORDERED;
505     case ORDERED:
506       return UNORDERED;
507     case UNLT:
508       return GE;
509     case UNLE:
510       return GT;
511     case UNGT:
512       return LE;
513     case UNGE:
514       return LT;
515     case UNEQ:
516       return LTGT;
517
518     default:
519       gcc_unreachable ();
520     }
521 }
522
523 /* Similar, but return the code when two operands of a comparison are swapped.
524    This IS safe for IEEE floating-point.  */
525
526 enum rtx_code
527 swap_condition (enum rtx_code code)
528 {
529   switch (code)
530     {
531     case EQ:
532     case NE:
533     case UNORDERED:
534     case ORDERED:
535     case UNEQ:
536     case LTGT:
537       return code;
538
539     case GT:
540       return LT;
541     case GE:
542       return LE;
543     case LT:
544       return GT;
545     case LE:
546       return GE;
547     case GTU:
548       return LTU;
549     case GEU:
550       return LEU;
551     case LTU:
552       return GTU;
553     case LEU:
554       return GEU;
555     case UNLT:
556       return UNGT;
557     case UNLE:
558       return UNGE;
559     case UNGT:
560       return UNLT;
561     case UNGE:
562       return UNLE;
563
564     default:
565       gcc_unreachable ();
566     }
567 }
568
569 /* Given a comparison CODE, return the corresponding unsigned comparison.
570    If CODE is an equality comparison or already an unsigned comparison,
571    CODE is returned.  */
572
573 enum rtx_code
574 unsigned_condition (enum rtx_code code)
575 {
576   switch (code)
577     {
578     case EQ:
579     case NE:
580     case GTU:
581     case GEU:
582     case LTU:
583     case LEU:
584       return code;
585
586     case GT:
587       return GTU;
588     case GE:
589       return GEU;
590     case LT:
591       return LTU;
592     case LE:
593       return LEU;
594
595     default:
596       gcc_unreachable ();
597     }
598 }
599
600 /* Similarly, return the signed version of a comparison.  */
601
602 enum rtx_code
603 signed_condition (enum rtx_code code)
604 {
605   switch (code)
606     {
607     case EQ:
608     case NE:
609     case GT:
610     case GE:
611     case LT:
612     case LE:
613       return code;
614
615     case GTU:
616       return GT;
617     case GEU:
618       return GE;
619     case LTU:
620       return LT;
621     case LEU:
622       return LE;
623
624     default:
625       gcc_unreachable ();
626     }
627 }
628 \f
629 /* Return nonzero if CODE1 is more strict than CODE2, i.e., if the
630    truth of CODE1 implies the truth of CODE2.  */
631
632 int
633 comparison_dominates_p (enum rtx_code code1, enum rtx_code code2)
634 {
635   /* UNKNOWN comparison codes can happen as a result of trying to revert
636      comparison codes.
637      They can't match anything, so we have to reject them here.  */
638   if (code1 == UNKNOWN || code2 == UNKNOWN)
639     return 0;
640
641   if (code1 == code2)
642     return 1;
643
644   switch (code1)
645     {
646     case UNEQ:
647       if (code2 == UNLE || code2 == UNGE)
648         return 1;
649       break;
650
651     case EQ:
652       if (code2 == LE || code2 == LEU || code2 == GE || code2 == GEU
653           || code2 == ORDERED)
654         return 1;
655       break;
656
657     case UNLT:
658       if (code2 == UNLE || code2 == NE)
659         return 1;
660       break;
661
662     case LT:
663       if (code2 == LE || code2 == NE || code2 == ORDERED || code2 == LTGT)
664         return 1;
665       break;
666
667     case UNGT:
668       if (code2 == UNGE || code2 == NE)
669         return 1;
670       break;
671
672     case GT:
673       if (code2 == GE || code2 == NE || code2 == ORDERED || code2 == LTGT)
674         return 1;
675       break;
676
677     case GE:
678     case LE:
679       if (code2 == ORDERED)
680         return 1;
681       break;
682
683     case LTGT:
684       if (code2 == NE || code2 == ORDERED)
685         return 1;
686       break;
687
688     case LTU:
689       if (code2 == LEU || code2 == NE)
690         return 1;
691       break;
692
693     case GTU:
694       if (code2 == GEU || code2 == NE)
695         return 1;
696       break;
697
698     case UNORDERED:
699       if (code2 == NE || code2 == UNEQ || code2 == UNLE || code2 == UNLT
700           || code2 == UNGE || code2 == UNGT)
701         return 1;
702       break;
703
704     default:
705       break;
706     }
707
708   return 0;
709 }
710 \f
711 /* Return 1 if INSN is an unconditional jump and nothing else.  */
712
713 int
714 simplejump_p (const_rtx insn)
715 {
716   return (JUMP_P (insn)
717           && GET_CODE (PATTERN (insn)) == SET
718           && GET_CODE (SET_DEST (PATTERN (insn))) == PC
719           && GET_CODE (SET_SRC (PATTERN (insn))) == LABEL_REF);
720 }
721
722 /* Return nonzero if INSN is a (possibly) conditional jump
723    and nothing more.
724
725    Use of this function is deprecated, since we need to support combined
726    branch and compare insns.  Use any_condjump_p instead whenever possible.  */
727
728 int
729 condjump_p (const_rtx insn)
730 {
731   const_rtx x = PATTERN (insn);
732
733   if (GET_CODE (x) != SET
734       || GET_CODE (SET_DEST (x)) != PC)
735     return 0;
736
737   x = SET_SRC (x);
738   if (GET_CODE (x) == LABEL_REF)
739     return 1;
740   else
741     return (GET_CODE (x) == IF_THEN_ELSE
742             && ((GET_CODE (XEXP (x, 2)) == PC
743                  && (GET_CODE (XEXP (x, 1)) == LABEL_REF
744                      || GET_CODE (XEXP (x, 1)) == RETURN))
745                 || (GET_CODE (XEXP (x, 1)) == PC
746                     && (GET_CODE (XEXP (x, 2)) == LABEL_REF
747                         || GET_CODE (XEXP (x, 2)) == RETURN))));
748 }
749
750 /* Return nonzero if INSN is a (possibly) conditional jump inside a
751    PARALLEL.
752
753    Use this function is deprecated, since we need to support combined
754    branch and compare insns.  Use any_condjump_p instead whenever possible.  */
755
756 int
757 condjump_in_parallel_p (const_rtx insn)
758 {
759   const_rtx x = PATTERN (insn);
760
761   if (GET_CODE (x) != PARALLEL)
762     return 0;
763   else
764     x = XVECEXP (x, 0, 0);
765
766   if (GET_CODE (x) != SET)
767     return 0;
768   if (GET_CODE (SET_DEST (x)) != PC)
769     return 0;
770   if (GET_CODE (SET_SRC (x)) == LABEL_REF)
771     return 1;
772   if (GET_CODE (SET_SRC (x)) != IF_THEN_ELSE)
773     return 0;
774   if (XEXP (SET_SRC (x), 2) == pc_rtx
775       && (GET_CODE (XEXP (SET_SRC (x), 1)) == LABEL_REF
776           || GET_CODE (XEXP (SET_SRC (x), 1)) == RETURN))
777     return 1;
778   if (XEXP (SET_SRC (x), 1) == pc_rtx
779       && (GET_CODE (XEXP (SET_SRC (x), 2)) == LABEL_REF
780           || GET_CODE (XEXP (SET_SRC (x), 2)) == RETURN))
781     return 1;
782   return 0;
783 }
784
785 /* Return set of PC, otherwise NULL.  */
786
787 rtx
788 pc_set (const_rtx insn)
789 {
790   rtx pat;
791   if (!JUMP_P (insn))
792     return NULL_RTX;
793   pat = PATTERN (insn);
794
795   /* The set is allowed to appear either as the insn pattern or
796      the first set in a PARALLEL.  */
797   if (GET_CODE (pat) == PARALLEL)
798     pat = XVECEXP (pat, 0, 0);
799   if (GET_CODE (pat) == SET && GET_CODE (SET_DEST (pat)) == PC)
800     return pat;
801
802   return NULL_RTX;
803 }
804
805 /* Return true when insn is an unconditional direct jump,
806    possibly bundled inside a PARALLEL.  */
807
808 int
809 any_uncondjump_p (const_rtx insn)
810 {
811   const_rtx x = pc_set (insn);
812   if (!x)
813     return 0;
814   if (GET_CODE (SET_SRC (x)) != LABEL_REF)
815     return 0;
816   if (find_reg_note (insn, REG_NON_LOCAL_GOTO, NULL_RTX))
817     return 0;
818   return 1;
819 }
820
821 /* Return true when insn is a conditional jump.  This function works for
822    instructions containing PC sets in PARALLELs.  The instruction may have
823    various other effects so before removing the jump you must verify
824    onlyjump_p.
825
826    Note that unlike condjump_p it returns false for unconditional jumps.  */
827
828 int
829 any_condjump_p (const_rtx insn)
830 {
831   const_rtx x = pc_set (insn);
832   enum rtx_code a, b;
833
834   if (!x)
835     return 0;
836   if (GET_CODE (SET_SRC (x)) != IF_THEN_ELSE)
837     return 0;
838
839   a = GET_CODE (XEXP (SET_SRC (x), 1));
840   b = GET_CODE (XEXP (SET_SRC (x), 2));
841
842   return ((b == PC && (a == LABEL_REF || a == RETURN))
843           || (a == PC && (b == LABEL_REF || b == RETURN)));
844 }
845
846 /* Return the label of a conditional jump.  */
847
848 rtx
849 condjump_label (const_rtx insn)
850 {
851   rtx x = pc_set (insn);
852
853   if (!x)
854     return NULL_RTX;
855   x = SET_SRC (x);
856   if (GET_CODE (x) == LABEL_REF)
857     return x;
858   if (GET_CODE (x) != IF_THEN_ELSE)
859     return NULL_RTX;
860   if (XEXP (x, 2) == pc_rtx && GET_CODE (XEXP (x, 1)) == LABEL_REF)
861     return XEXP (x, 1);
862   if (XEXP (x, 1) == pc_rtx && GET_CODE (XEXP (x, 2)) == LABEL_REF)
863     return XEXP (x, 2);
864   return NULL_RTX;
865 }
866
867 /* Return true if INSN is a (possibly conditional) return insn.  */
868
869 static int
870 returnjump_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
871 {
872   rtx x = *loc;
873
874   if (x == NULL)
875     return false;
876
877   switch (GET_CODE (x))
878     {
879     case RETURN:
880     case EH_RETURN:
881       return true;
882
883     case SET:
884       return SET_IS_RETURN_P (x);
885
886     default:
887       return false;
888     }
889 }
890
891 /* Return TRUE if INSN is a return jump.  */
892
893 int
894 returnjump_p (rtx insn)
895 {
896   /* Handle delayed branches.  */
897   if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE)
898     insn = XVECEXP (PATTERN (insn), 0, 0);
899
900   if (!JUMP_P (insn))
901     return 0;
902
903   return for_each_rtx (&PATTERN (insn), returnjump_p_1, NULL);
904 }
905
906 /* Return true if INSN is a (possibly conditional) return insn.  */
907
908 static int
909 eh_returnjump_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
910 {
911   return *loc && GET_CODE (*loc) == EH_RETURN;
912 }
913
914 int
915 eh_returnjump_p (rtx insn)
916 {
917   if (!JUMP_P (insn))
918     return 0;
919   return for_each_rtx (&PATTERN (insn), eh_returnjump_p_1, NULL);
920 }
921
922 /* Return true if INSN is a jump that only transfers control and
923    nothing more.  */
924
925 int
926 onlyjump_p (const_rtx insn)
927 {
928   rtx set;
929
930   if (!JUMP_P (insn))
931     return 0;
932
933   set = single_set (insn);
934   if (set == NULL)
935     return 0;
936   if (GET_CODE (SET_DEST (set)) != PC)
937     return 0;
938   if (side_effects_p (SET_SRC (set)))
939     return 0;
940
941   return 1;
942 }
943
944 #ifdef HAVE_cc0
945
946 /* Return nonzero if X is an RTX that only sets the condition codes
947    and has no side effects.  */
948
949 int
950 only_sets_cc0_p (const_rtx x)
951 {
952   if (! x)
953     return 0;
954
955   if (INSN_P (x))
956     x = PATTERN (x);
957
958   return sets_cc0_p (x) == 1 && ! side_effects_p (x);
959 }
960
961 /* Return 1 if X is an RTX that does nothing but set the condition codes
962    and CLOBBER or USE registers.
963    Return -1 if X does explicitly set the condition codes,
964    but also does other things.  */
965
966 int
967 sets_cc0_p (const_rtx x)
968 {
969   if (! x)
970     return 0;
971
972   if (INSN_P (x))
973     x = PATTERN (x);
974
975   if (GET_CODE (x) == SET && SET_DEST (x) == cc0_rtx)
976     return 1;
977   if (GET_CODE (x) == PARALLEL)
978     {
979       int i;
980       int sets_cc0 = 0;
981       int other_things = 0;
982       for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
983         {
984           if (GET_CODE (XVECEXP (x, 0, i)) == SET
985               && SET_DEST (XVECEXP (x, 0, i)) == cc0_rtx)
986             sets_cc0 = 1;
987           else if (GET_CODE (XVECEXP (x, 0, i)) == SET)
988             other_things = 1;
989         }
990       return ! sets_cc0 ? 0 : other_things ? -1 : 1;
991     }
992   return 0;
993 }
994 #endif
995 \f
996 /* Find all CODE_LABELs referred to in X, and increment their use
997    counts.  If INSN is a JUMP_INSN and there is at least one
998    CODE_LABEL referenced in INSN as a jump target, then store the last
999    one in JUMP_LABEL (INSN).  For a tablejump, this must be the label
1000    for the ADDR_VEC.  Store any other jump targets as REG_LABEL_TARGET
1001    notes.  If INSN is an INSN or a CALL_INSN or non-target operands of
1002    a JUMP_INSN, and there is at least one CODE_LABEL referenced in
1003    INSN, add a REG_LABEL_OPERAND note containing that label to INSN.
1004
1005    Note that two labels separated by a loop-beginning note
1006    must be kept distinct if we have not yet done loop-optimization,
1007    because the gap between them is where loop-optimize
1008    will want to move invariant code to.  CROSS_JUMP tells us
1009    that loop-optimization is done with.  */
1010
1011 void
1012 mark_jump_label (rtx x, rtx insn, int in_mem)
1013 {
1014   mark_jump_label_1 (x, insn, in_mem != 0,
1015                      (insn != NULL && x == PATTERN (insn) && JUMP_P (insn)));
1016 }
1017
1018 /* Worker function for mark_jump_label.  IN_MEM is TRUE when X occurs
1019    within a (MEM ...).  IS_TARGET is TRUE when X is to be treated as a
1020    jump-target; when the JUMP_LABEL field of INSN should be set or a
1021    REG_LABEL_TARGET note should be added, not a REG_LABEL_OPERAND
1022    note.  */
1023
1024 static void
1025 mark_jump_label_1 (rtx x, rtx insn, bool in_mem, bool is_target)
1026 {
1027   RTX_CODE code = GET_CODE (x);
1028   int i;
1029   const char *fmt;
1030
1031   switch (code)
1032     {
1033     case PC:
1034     case CC0:
1035     case REG:
1036     case CONST_INT:
1037     case CONST_DOUBLE:
1038     case CLOBBER:
1039     case CALL:
1040       return;
1041
1042     case MEM:
1043       in_mem = true;
1044       break;
1045
1046     case SEQUENCE:
1047       for (i = 0; i < XVECLEN (x, 0); i++)
1048         mark_jump_label (PATTERN (XVECEXP (x, 0, i)),
1049                          XVECEXP (x, 0, i), 0);
1050       return;
1051
1052     case SYMBOL_REF:
1053       if (!in_mem)
1054         return;
1055
1056       /* If this is a constant-pool reference, see if it is a label.  */
1057       if (CONSTANT_POOL_ADDRESS_P (x))
1058         mark_jump_label_1 (get_pool_constant (x), insn, in_mem, is_target);
1059       break;
1060
1061       /* Handle operands in the condition of an if-then-else as for a
1062          non-jump insn.  */
1063     case IF_THEN_ELSE:
1064       if (!is_target)
1065         break;
1066       mark_jump_label_1 (XEXP (x, 0), insn, in_mem, false);
1067       mark_jump_label_1 (XEXP (x, 1), insn, in_mem, true);
1068       mark_jump_label_1 (XEXP (x, 2), insn, in_mem, true);
1069       return;
1070
1071     case LABEL_REF:
1072       {
1073         rtx label = XEXP (x, 0);
1074
1075         /* Ignore remaining references to unreachable labels that
1076            have been deleted.  */
1077         if (NOTE_P (label)
1078             && NOTE_KIND (label) == NOTE_INSN_DELETED_LABEL)
1079           break;
1080
1081         gcc_assert (LABEL_P (label));
1082
1083         /* Ignore references to labels of containing functions.  */
1084         if (LABEL_REF_NONLOCAL_P (x))
1085           break;
1086
1087         XEXP (x, 0) = label;
1088         if (! insn || ! INSN_DELETED_P (insn))
1089           ++LABEL_NUSES (label);
1090
1091         if (insn)
1092           {
1093             if (is_target
1094                 /* Do not change a previous setting of JUMP_LABEL.  If the
1095                    JUMP_LABEL slot is occupied by a different label,
1096                    create a note for this label.  */
1097                 && (JUMP_LABEL (insn) == NULL || JUMP_LABEL (insn) == label))
1098               JUMP_LABEL (insn) = label;
1099             else
1100               {
1101                 enum reg_note kind
1102                   = is_target ? REG_LABEL_TARGET : REG_LABEL_OPERAND;
1103
1104                 /* Add a REG_LABEL_OPERAND or REG_LABEL_TARGET note
1105                    for LABEL unless there already is one.  All uses of
1106                    a label, except for the primary target of a jump,
1107                    must have such a note.  */
1108                 if (! find_reg_note (insn, kind, label))
1109                   add_reg_note (insn, kind, label);
1110               }
1111           }
1112         return;
1113       }
1114
1115   /* Do walk the labels in a vector, but not the first operand of an
1116      ADDR_DIFF_VEC.  Don't set the JUMP_LABEL of a vector.  */
1117     case ADDR_VEC:
1118     case ADDR_DIFF_VEC:
1119       if (! INSN_DELETED_P (insn))
1120         {
1121           int eltnum = code == ADDR_DIFF_VEC ? 1 : 0;
1122
1123           for (i = 0; i < XVECLEN (x, eltnum); i++)
1124             mark_jump_label_1 (XVECEXP (x, eltnum, i), NULL_RTX, in_mem,
1125                                is_target);
1126         }
1127       return;
1128
1129     default:
1130       break;
1131     }
1132
1133   fmt = GET_RTX_FORMAT (code);
1134
1135   /* The primary target of a tablejump is the label of the ADDR_VEC,
1136      which is canonically mentioned *last* in the insn.  To get it
1137      marked as JUMP_LABEL, we iterate over items in reverse order.  */
1138   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1139     {
1140       if (fmt[i] == 'e')
1141         mark_jump_label_1 (XEXP (x, i), insn, in_mem, is_target);
1142       else if (fmt[i] == 'E')
1143         {
1144           int j;
1145
1146           for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1147             mark_jump_label_1 (XVECEXP (x, i, j), insn, in_mem,
1148                                is_target);
1149         }
1150     }
1151 }
1152
1153 \f
1154 /* Delete insn INSN from the chain of insns and update label ref counts
1155    and delete insns now unreachable.
1156
1157    Returns the first insn after INSN that was not deleted.
1158
1159    Usage of this instruction is deprecated.  Use delete_insn instead and
1160    subsequent cfg_cleanup pass to delete unreachable code if needed.  */
1161
1162 rtx
1163 delete_related_insns (rtx insn)
1164 {
1165   int was_code_label = (LABEL_P (insn));
1166   rtx note;
1167   rtx next = NEXT_INSN (insn), prev = PREV_INSN (insn);
1168
1169   while (next && INSN_DELETED_P (next))
1170     next = NEXT_INSN (next);
1171
1172   /* This insn is already deleted => return first following nondeleted.  */
1173   if (INSN_DELETED_P (insn))
1174     return next;
1175
1176   delete_insn (insn);
1177
1178   /* If instruction is followed by a barrier,
1179      delete the barrier too.  */
1180
1181   if (next != 0 && BARRIER_P (next))
1182     delete_insn (next);
1183
1184   /* If deleting a jump, decrement the count of the label,
1185      and delete the label if it is now unused.  */
1186
1187   if (JUMP_P (insn) && JUMP_LABEL (insn))
1188     {
1189       rtx lab = JUMP_LABEL (insn), lab_next;
1190
1191       if (LABEL_NUSES (lab) == 0)
1192         /* This can delete NEXT or PREV,
1193            either directly if NEXT is JUMP_LABEL (INSN),
1194            or indirectly through more levels of jumps.  */
1195         delete_related_insns (lab);
1196       else if (tablejump_p (insn, NULL, &lab_next))
1197         {
1198           /* If we're deleting the tablejump, delete the dispatch table.
1199              We may not be able to kill the label immediately preceding
1200              just yet, as it might be referenced in code leading up to
1201              the tablejump.  */
1202           delete_related_insns (lab_next);
1203         }
1204     }
1205
1206   /* Likewise if we're deleting a dispatch table.  */
1207
1208   if (JUMP_TABLE_DATA_P (insn))
1209     {
1210       rtx pat = PATTERN (insn);
1211       int i, diff_vec_p = GET_CODE (pat) == ADDR_DIFF_VEC;
1212       int len = XVECLEN (pat, diff_vec_p);
1213
1214       for (i = 0; i < len; i++)
1215         if (LABEL_NUSES (XEXP (XVECEXP (pat, diff_vec_p, i), 0)) == 0)
1216           delete_related_insns (XEXP (XVECEXP (pat, diff_vec_p, i), 0));
1217       while (next && INSN_DELETED_P (next))
1218         next = NEXT_INSN (next);
1219       return next;
1220     }
1221
1222   /* Likewise for any JUMP_P / INSN / CALL_INSN with a
1223      REG_LABEL_OPERAND or REG_LABEL_TARGET note.  */
1224   if (INSN_P (insn))
1225     for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
1226       if ((REG_NOTE_KIND (note) == REG_LABEL_OPERAND
1227            || REG_NOTE_KIND (note) == REG_LABEL_TARGET)
1228           /* This could also be a NOTE_INSN_DELETED_LABEL note.  */
1229           && LABEL_P (XEXP (note, 0)))
1230         if (LABEL_NUSES (XEXP (note, 0)) == 0)
1231           delete_related_insns (XEXP (note, 0));
1232
1233   while (prev && (INSN_DELETED_P (prev) || NOTE_P (prev)))
1234     prev = PREV_INSN (prev);
1235
1236   /* If INSN was a label and a dispatch table follows it,
1237      delete the dispatch table.  The tablejump must have gone already.
1238      It isn't useful to fall through into a table.  */
1239
1240   if (was_code_label
1241       && NEXT_INSN (insn) != 0
1242       && JUMP_TABLE_DATA_P (NEXT_INSN (insn)))
1243     next = delete_related_insns (NEXT_INSN (insn));
1244
1245   /* If INSN was a label, delete insns following it if now unreachable.  */
1246
1247   if (was_code_label && prev && BARRIER_P (prev))
1248     {
1249       enum rtx_code code;
1250       while (next)
1251         {
1252           code = GET_CODE (next);
1253           if (code == NOTE)
1254             next = NEXT_INSN (next);
1255           /* Keep going past other deleted labels to delete what follows.  */
1256           else if (code == CODE_LABEL && INSN_DELETED_P (next))
1257             next = NEXT_INSN (next);
1258           else if (code == BARRIER || INSN_P (next))
1259             /* Note: if this deletes a jump, it can cause more
1260                deletion of unreachable code, after a different label.
1261                As long as the value from this recursive call is correct,
1262                this invocation functions correctly.  */
1263             next = delete_related_insns (next);
1264           else
1265             break;
1266         }
1267     }
1268
1269   /* I feel a little doubtful about this loop,
1270      but I see no clean and sure alternative way
1271      to find the first insn after INSN that is not now deleted.
1272      I hope this works.  */
1273   while (next && INSN_DELETED_P (next))
1274     next = NEXT_INSN (next);
1275   return next;
1276 }
1277 \f
1278 /* Delete a range of insns from FROM to TO, inclusive.
1279    This is for the sake of peephole optimization, so assume
1280    that whatever these insns do will still be done by a new
1281    peephole insn that will replace them.  */
1282
1283 void
1284 delete_for_peephole (rtx from, rtx to)
1285 {
1286   rtx insn = from;
1287
1288   while (1)
1289     {
1290       rtx next = NEXT_INSN (insn);
1291       rtx prev = PREV_INSN (insn);
1292
1293       if (!NOTE_P (insn))
1294         {
1295           INSN_DELETED_P (insn) = 1;
1296
1297           /* Patch this insn out of the chain.  */
1298           /* We don't do this all at once, because we
1299              must preserve all NOTEs.  */
1300           if (prev)
1301             NEXT_INSN (prev) = next;
1302
1303           if (next)
1304             PREV_INSN (next) = prev;
1305         }
1306
1307       if (insn == to)
1308         break;
1309       insn = next;
1310     }
1311
1312   /* Note that if TO is an unconditional jump
1313      we *do not* delete the BARRIER that follows,
1314      since the peephole that replaces this sequence
1315      is also an unconditional jump in that case.  */
1316 }
1317 \f
1318 /* Throughout LOC, redirect OLABEL to NLABEL.  Treat null OLABEL or
1319    NLABEL as a return.  Accrue modifications into the change group.  */
1320
1321 static void
1322 redirect_exp_1 (rtx *loc, rtx olabel, rtx nlabel, rtx insn)
1323 {
1324   rtx x = *loc;
1325   RTX_CODE code = GET_CODE (x);
1326   int i;
1327   const char *fmt;
1328
1329   if (code == LABEL_REF)
1330     {
1331       if (XEXP (x, 0) == olabel)
1332         {
1333           rtx n;
1334           if (nlabel)
1335             n = gen_rtx_LABEL_REF (Pmode, nlabel);
1336           else
1337             n = gen_rtx_RETURN (VOIDmode);
1338
1339           validate_change (insn, loc, n, 1);
1340           return;
1341         }
1342     }
1343   else if (code == RETURN && olabel == 0)
1344     {
1345       if (nlabel)
1346         x = gen_rtx_LABEL_REF (Pmode, nlabel);
1347       else
1348         x = gen_rtx_RETURN (VOIDmode);
1349       if (loc == &PATTERN (insn))
1350         x = gen_rtx_SET (VOIDmode, pc_rtx, x);
1351       validate_change (insn, loc, x, 1);
1352       return;
1353     }
1354
1355   if (code == SET && nlabel == 0 && SET_DEST (x) == pc_rtx
1356       && GET_CODE (SET_SRC (x)) == LABEL_REF
1357       && XEXP (SET_SRC (x), 0) == olabel)
1358     {
1359       validate_change (insn, loc, gen_rtx_RETURN (VOIDmode), 1);
1360       return;
1361     }
1362
1363   if (code == IF_THEN_ELSE)
1364     {
1365       /* Skip the condition of an IF_THEN_ELSE.  We only want to
1366          change jump destinations, not eventual label comparisons.  */
1367       redirect_exp_1 (&XEXP (x, 1), olabel, nlabel, insn);
1368       redirect_exp_1 (&XEXP (x, 2), olabel, nlabel, insn);
1369       return;
1370     }
1371
1372   fmt = GET_RTX_FORMAT (code);
1373   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1374     {
1375       if (fmt[i] == 'e')
1376         redirect_exp_1 (&XEXP (x, i), olabel, nlabel, insn);
1377       else if (fmt[i] == 'E')
1378         {
1379           int j;
1380           for (j = 0; j < XVECLEN (x, i); j++)
1381             redirect_exp_1 (&XVECEXP (x, i, j), olabel, nlabel, insn);
1382         }
1383     }
1384 }
1385
1386 /* Make JUMP go to NLABEL instead of where it jumps now.  Accrue
1387    the modifications into the change group.  Return false if we did
1388    not see how to do that.  */
1389
1390 int
1391 redirect_jump_1 (rtx jump, rtx nlabel)
1392 {
1393   int ochanges = num_validated_changes ();
1394   rtx *loc;
1395
1396   if (GET_CODE (PATTERN (jump)) == PARALLEL)
1397     loc = &XVECEXP (PATTERN (jump), 0, 0);
1398   else
1399     loc = &PATTERN (jump);
1400
1401   redirect_exp_1 (loc, JUMP_LABEL (jump), nlabel, jump);
1402   return num_validated_changes () > ochanges;
1403 }
1404
1405 /* Make JUMP go to NLABEL instead of where it jumps now.  If the old
1406    jump target label is unused as a result, it and the code following
1407    it may be deleted.
1408
1409    If NLABEL is zero, we are to turn the jump into a (possibly conditional)
1410    RETURN insn.
1411
1412    The return value will be 1 if the change was made, 0 if it wasn't
1413    (this can only occur for NLABEL == 0).  */
1414
1415 int
1416 redirect_jump (rtx jump, rtx nlabel, int delete_unused)
1417 {
1418   rtx olabel = JUMP_LABEL (jump);
1419
1420   if (nlabel == olabel)
1421     return 1;
1422
1423   if (! redirect_jump_1 (jump, nlabel) || ! apply_change_group ())
1424     return 0;
1425
1426   redirect_jump_2 (jump, olabel, nlabel, delete_unused, 0);
1427   return 1;
1428 }
1429
1430 /* Fix up JUMP_LABEL and label ref counts after OLABEL has been replaced with
1431    NLABEL in JUMP.  
1432    If DELETE_UNUSED is positive, delete related insn to OLABEL if its ref
1433    count has dropped to zero.  */
1434 void
1435 redirect_jump_2 (rtx jump, rtx olabel, rtx nlabel, int delete_unused,
1436                  int invert)
1437 {
1438   rtx note;
1439
1440   gcc_assert (JUMP_LABEL (jump) == olabel);
1441
1442   /* Negative DELETE_UNUSED used to be used to signalize behavior on
1443      moving FUNCTION_END note.  Just sanity check that no user still worry
1444      about this.  */
1445   gcc_assert (delete_unused >= 0);
1446   JUMP_LABEL (jump) = nlabel;
1447   if (nlabel)
1448     ++LABEL_NUSES (nlabel);
1449
1450   /* Update labels in any REG_EQUAL note.  */
1451   if ((note = find_reg_note (jump, REG_EQUAL, NULL_RTX)) != NULL_RTX)
1452     {
1453       if (!nlabel || (invert && !invert_exp_1 (XEXP (note, 0), jump)))
1454         remove_note (jump, note);
1455       else
1456         {
1457           redirect_exp_1 (&XEXP (note, 0), olabel, nlabel, jump);
1458           confirm_change_group ();
1459         }
1460     }
1461
1462   if (olabel && --LABEL_NUSES (olabel) == 0 && delete_unused > 0
1463       /* Undefined labels will remain outside the insn stream.  */
1464       && INSN_UID (olabel))
1465     delete_related_insns (olabel);
1466   if (invert)
1467     invert_br_probabilities (jump);
1468 }
1469
1470 /* Invert the jump condition X contained in jump insn INSN.  Accrue the
1471    modifications into the change group.  Return nonzero for success.  */
1472 static int
1473 invert_exp_1 (rtx x, rtx insn)
1474 {
1475   RTX_CODE code = GET_CODE (x);
1476
1477   if (code == IF_THEN_ELSE)
1478     {
1479       rtx comp = XEXP (x, 0);
1480       rtx tem;
1481       enum rtx_code reversed_code;
1482
1483       /* We can do this in two ways:  The preferable way, which can only
1484          be done if this is not an integer comparison, is to reverse
1485          the comparison code.  Otherwise, swap the THEN-part and ELSE-part
1486          of the IF_THEN_ELSE.  If we can't do either, fail.  */
1487
1488       reversed_code = reversed_comparison_code (comp, insn);
1489
1490       if (reversed_code != UNKNOWN)
1491         {
1492           validate_change (insn, &XEXP (x, 0),
1493                            gen_rtx_fmt_ee (reversed_code,
1494                                            GET_MODE (comp), XEXP (comp, 0),
1495                                            XEXP (comp, 1)),
1496                            1);
1497           return 1;
1498         }
1499
1500       tem = XEXP (x, 1);
1501       validate_change (insn, &XEXP (x, 1), XEXP (x, 2), 1);
1502       validate_change (insn, &XEXP (x, 2), tem, 1);
1503       return 1;
1504     }
1505   else
1506     return 0;
1507 }
1508
1509 /* Invert the condition of the jump JUMP, and make it jump to label
1510    NLABEL instead of where it jumps now.  Accrue changes into the
1511    change group.  Return false if we didn't see how to perform the
1512    inversion and redirection.  */
1513
1514 int
1515 invert_jump_1 (rtx jump, rtx nlabel)
1516 {
1517   rtx x = pc_set (jump);
1518   int ochanges;
1519   int ok;
1520
1521   ochanges = num_validated_changes ();
1522   gcc_assert (x);
1523   ok = invert_exp_1 (SET_SRC (x), jump);
1524   gcc_assert (ok);
1525   
1526   if (num_validated_changes () == ochanges)
1527     return 0;
1528
1529   /* redirect_jump_1 will fail of nlabel == olabel, and the current use is
1530      in Pmode, so checking this is not merely an optimization.  */
1531   return nlabel == JUMP_LABEL (jump) || redirect_jump_1 (jump, nlabel);
1532 }
1533
1534 /* Invert the condition of the jump JUMP, and make it jump to label
1535    NLABEL instead of where it jumps now.  Return true if successful.  */
1536
1537 int
1538 invert_jump (rtx jump, rtx nlabel, int delete_unused)
1539 {
1540   rtx olabel = JUMP_LABEL (jump);
1541
1542   if (invert_jump_1 (jump, nlabel) && apply_change_group ())
1543     {
1544       redirect_jump_2 (jump, olabel, nlabel, delete_unused, 1);
1545       return 1;
1546     }
1547   cancel_changes (0);
1548   return 0;
1549 }
1550
1551 \f
1552 /* Like rtx_equal_p except that it considers two REGs as equal
1553    if they renumber to the same value and considers two commutative
1554    operations to be the same if the order of the operands has been
1555    reversed.  */
1556
1557 int
1558 rtx_renumbered_equal_p (const_rtx x, const_rtx y)
1559 {
1560   int i;
1561   const enum rtx_code code = GET_CODE (x);
1562   const char *fmt;
1563
1564   if (x == y)
1565     return 1;
1566
1567   if ((code == REG || (code == SUBREG && REG_P (SUBREG_REG (x))))
1568       && (REG_P (y) || (GET_CODE (y) == SUBREG
1569                                   && REG_P (SUBREG_REG (y)))))
1570     {
1571       int reg_x = -1, reg_y = -1;
1572       int byte_x = 0, byte_y = 0;
1573       struct subreg_info info;
1574
1575       if (GET_MODE (x) != GET_MODE (y))
1576         return 0;
1577
1578       /* If we haven't done any renumbering, don't
1579          make any assumptions.  */
1580       if (reg_renumber == 0)
1581         return rtx_equal_p (x, y);
1582
1583       if (code == SUBREG)
1584         {
1585           reg_x = REGNO (SUBREG_REG (x));
1586           byte_x = SUBREG_BYTE (x);
1587
1588           if (reg_renumber[reg_x] >= 0)
1589             {
1590               subreg_get_info (reg_renumber[reg_x],
1591                                GET_MODE (SUBREG_REG (x)), byte_x,
1592                                GET_MODE (x), &info);
1593               if (!info.representable_p)
1594                 return 0;
1595               reg_x = info.offset;
1596               byte_x = 0;
1597             }
1598         }
1599       else
1600         {
1601           reg_x = REGNO (x);
1602           if (reg_renumber[reg_x] >= 0)
1603             reg_x = reg_renumber[reg_x];
1604         }
1605
1606       if (GET_CODE (y) == SUBREG)
1607         {
1608           reg_y = REGNO (SUBREG_REG (y));
1609           byte_y = SUBREG_BYTE (y);
1610
1611           if (reg_renumber[reg_y] >= 0)
1612             {
1613               subreg_get_info (reg_renumber[reg_y],
1614                                GET_MODE (SUBREG_REG (y)), byte_y,
1615                                GET_MODE (y), &info);
1616               if (!info.representable_p)
1617                 return 0;
1618               reg_y = info.offset;
1619               byte_y = 0;
1620             }
1621         }
1622       else
1623         {
1624           reg_y = REGNO (y);
1625           if (reg_renumber[reg_y] >= 0)
1626             reg_y = reg_renumber[reg_y];
1627         }
1628
1629       return reg_x >= 0 && reg_x == reg_y && byte_x == byte_y;
1630     }
1631
1632   /* Now we have disposed of all the cases
1633      in which different rtx codes can match.  */
1634   if (code != GET_CODE (y))
1635     return 0;
1636
1637   switch (code)
1638     {
1639     case PC:
1640     case CC0:
1641     case ADDR_VEC:
1642     case ADDR_DIFF_VEC:
1643     case CONST_INT:
1644     case CONST_DOUBLE:
1645       return 0;
1646
1647     case LABEL_REF:
1648       /* We can't assume nonlocal labels have their following insns yet.  */
1649       if (LABEL_REF_NONLOCAL_P (x) || LABEL_REF_NONLOCAL_P (y))
1650         return XEXP (x, 0) == XEXP (y, 0);
1651
1652       /* Two label-refs are equivalent if they point at labels
1653          in the same position in the instruction stream.  */
1654       return (next_real_insn (XEXP (x, 0))
1655               == next_real_insn (XEXP (y, 0)));
1656
1657     case SYMBOL_REF:
1658       return XSTR (x, 0) == XSTR (y, 0);
1659
1660     case CODE_LABEL:
1661       /* If we didn't match EQ equality above, they aren't the same.  */
1662       return 0;
1663
1664     default:
1665       break;
1666     }
1667
1668   /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.  */
1669
1670   if (GET_MODE (x) != GET_MODE (y))
1671     return 0;
1672
1673   /* For commutative operations, the RTX match if the operand match in any
1674      order.  Also handle the simple binary and unary cases without a loop.  */
1675   if (targetm.commutative_p (x, UNKNOWN))
1676     return ((rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0))
1677              && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 1)))
1678             || (rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 1))
1679                 && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 0))));
1680   else if (NON_COMMUTATIVE_P (x))
1681     return (rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0))
1682             && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 1)));
1683   else if (UNARY_P (x))
1684     return rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0));
1685
1686   /* Compare the elements.  If any pair of corresponding elements
1687      fail to match, return 0 for the whole things.  */
1688
1689   fmt = GET_RTX_FORMAT (code);
1690   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1691     {
1692       int j;
1693       switch (fmt[i])
1694         {
1695         case 'w':
1696           if (XWINT (x, i) != XWINT (y, i))
1697             return 0;
1698           break;
1699
1700         case 'i':
1701           if (XINT (x, i) != XINT (y, i))
1702             return 0;
1703           break;
1704
1705         case 't':
1706           if (XTREE (x, i) != XTREE (y, i))
1707             return 0;
1708           break;
1709
1710         case 's':
1711           if (strcmp (XSTR (x, i), XSTR (y, i)))
1712             return 0;
1713           break;
1714
1715         case 'e':
1716           if (! rtx_renumbered_equal_p (XEXP (x, i), XEXP (y, i)))
1717             return 0;
1718           break;
1719
1720         case 'u':
1721           if (XEXP (x, i) != XEXP (y, i))
1722             return 0;
1723           /* Fall through.  */
1724         case '0':
1725           break;
1726
1727         case 'E':
1728           if (XVECLEN (x, i) != XVECLEN (y, i))
1729             return 0;
1730           for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1731             if (!rtx_renumbered_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j)))
1732               return 0;
1733           break;
1734
1735         default:
1736           gcc_unreachable ();
1737         }
1738     }
1739   return 1;
1740 }
1741 \f
1742 /* If X is a hard register or equivalent to one or a subregister of one,
1743    return the hard register number.  If X is a pseudo register that was not
1744    assigned a hard register, return the pseudo register number.  Otherwise,
1745    return -1.  Any rtx is valid for X.  */
1746
1747 int
1748 true_regnum (const_rtx x)
1749 {
1750   if (REG_P (x))
1751     {
1752       if (REGNO (x) >= FIRST_PSEUDO_REGISTER && reg_renumber[REGNO (x)] >= 0)
1753         return reg_renumber[REGNO (x)];
1754       return REGNO (x);
1755     }
1756   if (GET_CODE (x) == SUBREG)
1757     {
1758       int base = true_regnum (SUBREG_REG (x));
1759       if (base >= 0
1760           && base < FIRST_PSEUDO_REGISTER)
1761         {
1762           struct subreg_info info;
1763
1764           subreg_get_info (REGNO (SUBREG_REG (x)),
1765                            GET_MODE (SUBREG_REG (x)),
1766                            SUBREG_BYTE (x), GET_MODE (x), &info);
1767
1768           if (info.representable_p)
1769             return base + info.offset;
1770         }
1771     }
1772   return -1;
1773 }
1774
1775 /* Return regno of the register REG and handle subregs too.  */
1776 unsigned int
1777 reg_or_subregno (const_rtx reg)
1778 {
1779   if (GET_CODE (reg) == SUBREG)
1780     reg = SUBREG_REG (reg);
1781   gcc_assert (REG_P (reg));
1782   return REGNO (reg);
1783 }