OSDN Git Service

2009-08-14 Paolo Bonzini <bonzini@gnu.org>
[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   if (!JUMP_P (insn))
897     return 0;
898   return for_each_rtx (&PATTERN (insn), returnjump_p_1, NULL);
899 }
900
901 /* Return true if INSN is a (possibly conditional) return insn.  */
902
903 static int
904 eh_returnjump_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
905 {
906   return *loc && GET_CODE (*loc) == EH_RETURN;
907 }
908
909 int
910 eh_returnjump_p (rtx insn)
911 {
912   if (!JUMP_P (insn))
913     return 0;
914   return for_each_rtx (&PATTERN (insn), eh_returnjump_p_1, NULL);
915 }
916
917 /* Return true if INSN is a jump that only transfers control and
918    nothing more.  */
919
920 int
921 onlyjump_p (const_rtx insn)
922 {
923   rtx set;
924
925   if (!JUMP_P (insn))
926     return 0;
927
928   set = single_set (insn);
929   if (set == NULL)
930     return 0;
931   if (GET_CODE (SET_DEST (set)) != PC)
932     return 0;
933   if (side_effects_p (SET_SRC (set)))
934     return 0;
935
936   return 1;
937 }
938
939 #ifdef HAVE_cc0
940
941 /* Return nonzero if X is an RTX that only sets the condition codes
942    and has no side effects.  */
943
944 int
945 only_sets_cc0_p (const_rtx x)
946 {
947   if (! x)
948     return 0;
949
950   if (INSN_P (x))
951     x = PATTERN (x);
952
953   return sets_cc0_p (x) == 1 && ! side_effects_p (x);
954 }
955
956 /* Return 1 if X is an RTX that does nothing but set the condition codes
957    and CLOBBER or USE registers.
958    Return -1 if X does explicitly set the condition codes,
959    but also does other things.  */
960
961 int
962 sets_cc0_p (const_rtx x)
963 {
964   if (! x)
965     return 0;
966
967   if (INSN_P (x))
968     x = PATTERN (x);
969
970   if (GET_CODE (x) == SET && SET_DEST (x) == cc0_rtx)
971     return 1;
972   if (GET_CODE (x) == PARALLEL)
973     {
974       int i;
975       int sets_cc0 = 0;
976       int other_things = 0;
977       for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
978         {
979           if (GET_CODE (XVECEXP (x, 0, i)) == SET
980               && SET_DEST (XVECEXP (x, 0, i)) == cc0_rtx)
981             sets_cc0 = 1;
982           else if (GET_CODE (XVECEXP (x, 0, i)) == SET)
983             other_things = 1;
984         }
985       return ! sets_cc0 ? 0 : other_things ? -1 : 1;
986     }
987   return 0;
988 }
989 #endif
990 \f
991 /* Find all CODE_LABELs referred to in X, and increment their use
992    counts.  If INSN is a JUMP_INSN and there is at least one
993    CODE_LABEL referenced in INSN as a jump target, then store the last
994    one in JUMP_LABEL (INSN).  For a tablejump, this must be the label
995    for the ADDR_VEC.  Store any other jump targets as REG_LABEL_TARGET
996    notes.  If INSN is an INSN or a CALL_INSN or non-target operands of
997    a JUMP_INSN, and there is at least one CODE_LABEL referenced in
998    INSN, add a REG_LABEL_OPERAND note containing that label to INSN.
999
1000    Note that two labels separated by a loop-beginning note
1001    must be kept distinct if we have not yet done loop-optimization,
1002    because the gap between them is where loop-optimize
1003    will want to move invariant code to.  CROSS_JUMP tells us
1004    that loop-optimization is done with.  */
1005
1006 void
1007 mark_jump_label (rtx x, rtx insn, int in_mem)
1008 {
1009   mark_jump_label_1 (x, insn, in_mem != 0,
1010                      (insn != NULL && x == PATTERN (insn) && JUMP_P (insn)));
1011 }
1012
1013 /* Worker function for mark_jump_label.  IN_MEM is TRUE when X occurs
1014    within a (MEM ...).  IS_TARGET is TRUE when X is to be treated as a
1015    jump-target; when the JUMP_LABEL field of INSN should be set or a
1016    REG_LABEL_TARGET note should be added, not a REG_LABEL_OPERAND
1017    note.  */
1018
1019 static void
1020 mark_jump_label_1 (rtx x, rtx insn, bool in_mem, bool is_target)
1021 {
1022   RTX_CODE code = GET_CODE (x);
1023   int i;
1024   const char *fmt;
1025
1026   switch (code)
1027     {
1028     case PC:
1029     case CC0:
1030     case REG:
1031     case CONST_INT:
1032     case CONST_DOUBLE:
1033     case CLOBBER:
1034     case CALL:
1035       return;
1036
1037     case MEM:
1038       in_mem = true;
1039       break;
1040
1041     case SEQUENCE:
1042       for (i = 0; i < XVECLEN (x, 0); i++)
1043         mark_jump_label (PATTERN (XVECEXP (x, 0, i)),
1044                          XVECEXP (x, 0, i), 0);
1045       return;
1046
1047     case SYMBOL_REF:
1048       if (!in_mem)
1049         return;
1050
1051       /* If this is a constant-pool reference, see if it is a label.  */
1052       if (CONSTANT_POOL_ADDRESS_P (x))
1053         mark_jump_label_1 (get_pool_constant (x), insn, in_mem, is_target);
1054       break;
1055
1056       /* Handle operands in the condition of an if-then-else as for a
1057          non-jump insn.  */
1058     case IF_THEN_ELSE:
1059       if (!is_target)
1060         break;
1061       mark_jump_label_1 (XEXP (x, 0), insn, in_mem, false);
1062       mark_jump_label_1 (XEXP (x, 1), insn, in_mem, true);
1063       mark_jump_label_1 (XEXP (x, 2), insn, in_mem, true);
1064       return;
1065
1066     case LABEL_REF:
1067       {
1068         rtx label = XEXP (x, 0);
1069
1070         /* Ignore remaining references to unreachable labels that
1071            have been deleted.  */
1072         if (NOTE_P (label)
1073             && NOTE_KIND (label) == NOTE_INSN_DELETED_LABEL)
1074           break;
1075
1076         gcc_assert (LABEL_P (label));
1077
1078         /* Ignore references to labels of containing functions.  */
1079         if (LABEL_REF_NONLOCAL_P (x))
1080           break;
1081
1082         XEXP (x, 0) = label;
1083         if (! insn || ! INSN_DELETED_P (insn))
1084           ++LABEL_NUSES (label);
1085
1086         if (insn)
1087           {
1088             if (is_target
1089                 /* Do not change a previous setting of JUMP_LABEL.  If the
1090                    JUMP_LABEL slot is occupied by a different label,
1091                    create a note for this label.  */
1092                 && (JUMP_LABEL (insn) == NULL || JUMP_LABEL (insn) == label))
1093               JUMP_LABEL (insn) = label;
1094             else
1095               {
1096                 enum reg_note kind
1097                   = is_target ? REG_LABEL_TARGET : REG_LABEL_OPERAND;
1098
1099                 /* Add a REG_LABEL_OPERAND or REG_LABEL_TARGET note
1100                    for LABEL unless there already is one.  All uses of
1101                    a label, except for the primary target of a jump,
1102                    must have such a note.  */
1103                 if (! find_reg_note (insn, kind, label))
1104                   add_reg_note (insn, kind, label);
1105               }
1106           }
1107         return;
1108       }
1109
1110   /* Do walk the labels in a vector, but not the first operand of an
1111      ADDR_DIFF_VEC.  Don't set the JUMP_LABEL of a vector.  */
1112     case ADDR_VEC:
1113     case ADDR_DIFF_VEC:
1114       if (! INSN_DELETED_P (insn))
1115         {
1116           int eltnum = code == ADDR_DIFF_VEC ? 1 : 0;
1117
1118           for (i = 0; i < XVECLEN (x, eltnum); i++)
1119             mark_jump_label_1 (XVECEXP (x, eltnum, i), NULL_RTX, in_mem,
1120                                is_target);
1121         }
1122       return;
1123
1124     default:
1125       break;
1126     }
1127
1128   fmt = GET_RTX_FORMAT (code);
1129
1130   /* The primary target of a tablejump is the label of the ADDR_VEC,
1131      which is canonically mentioned *last* in the insn.  To get it
1132      marked as JUMP_LABEL, we iterate over items in reverse order.  */
1133   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1134     {
1135       if (fmt[i] == 'e')
1136         mark_jump_label_1 (XEXP (x, i), insn, in_mem, is_target);
1137       else if (fmt[i] == 'E')
1138         {
1139           int j;
1140
1141           for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1142             mark_jump_label_1 (XVECEXP (x, i, j), insn, in_mem,
1143                                is_target);
1144         }
1145     }
1146 }
1147
1148 \f
1149 /* Delete insn INSN from the chain of insns and update label ref counts
1150    and delete insns now unreachable.
1151
1152    Returns the first insn after INSN that was not deleted.
1153
1154    Usage of this instruction is deprecated.  Use delete_insn instead and
1155    subsequent cfg_cleanup pass to delete unreachable code if needed.  */
1156
1157 rtx
1158 delete_related_insns (rtx insn)
1159 {
1160   int was_code_label = (LABEL_P (insn));
1161   rtx note;
1162   rtx next = NEXT_INSN (insn), prev = PREV_INSN (insn);
1163
1164   while (next && INSN_DELETED_P (next))
1165     next = NEXT_INSN (next);
1166
1167   /* This insn is already deleted => return first following nondeleted.  */
1168   if (INSN_DELETED_P (insn))
1169     return next;
1170
1171   delete_insn (insn);
1172
1173   /* If instruction is followed by a barrier,
1174      delete the barrier too.  */
1175
1176   if (next != 0 && BARRIER_P (next))
1177     delete_insn (next);
1178
1179   /* If deleting a jump, decrement the count of the label,
1180      and delete the label if it is now unused.  */
1181
1182   if (JUMP_P (insn) && JUMP_LABEL (insn))
1183     {
1184       rtx lab = JUMP_LABEL (insn), lab_next;
1185
1186       if (LABEL_NUSES (lab) == 0)
1187         /* This can delete NEXT or PREV,
1188            either directly if NEXT is JUMP_LABEL (INSN),
1189            or indirectly through more levels of jumps.  */
1190         delete_related_insns (lab);
1191       else if (tablejump_p (insn, NULL, &lab_next))
1192         {
1193           /* If we're deleting the tablejump, delete the dispatch table.
1194              We may not be able to kill the label immediately preceding
1195              just yet, as it might be referenced in code leading up to
1196              the tablejump.  */
1197           delete_related_insns (lab_next);
1198         }
1199     }
1200
1201   /* Likewise if we're deleting a dispatch table.  */
1202
1203   if (JUMP_TABLE_DATA_P (insn))
1204     {
1205       rtx pat = PATTERN (insn);
1206       int i, diff_vec_p = GET_CODE (pat) == ADDR_DIFF_VEC;
1207       int len = XVECLEN (pat, diff_vec_p);
1208
1209       for (i = 0; i < len; i++)
1210         if (LABEL_NUSES (XEXP (XVECEXP (pat, diff_vec_p, i), 0)) == 0)
1211           delete_related_insns (XEXP (XVECEXP (pat, diff_vec_p, i), 0));
1212       while (next && INSN_DELETED_P (next))
1213         next = NEXT_INSN (next);
1214       return next;
1215     }
1216
1217   /* Likewise for any JUMP_P / INSN / CALL_INSN with a
1218      REG_LABEL_OPERAND or REG_LABEL_TARGET note.  */
1219   if (INSN_P (insn))
1220     for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
1221       if ((REG_NOTE_KIND (note) == REG_LABEL_OPERAND
1222            || REG_NOTE_KIND (note) == REG_LABEL_TARGET)
1223           /* This could also be a NOTE_INSN_DELETED_LABEL note.  */
1224           && LABEL_P (XEXP (note, 0)))
1225         if (LABEL_NUSES (XEXP (note, 0)) == 0)
1226           delete_related_insns (XEXP (note, 0));
1227
1228   while (prev && (INSN_DELETED_P (prev) || NOTE_P (prev)))
1229     prev = PREV_INSN (prev);
1230
1231   /* If INSN was a label and a dispatch table follows it,
1232      delete the dispatch table.  The tablejump must have gone already.
1233      It isn't useful to fall through into a table.  */
1234
1235   if (was_code_label
1236       && NEXT_INSN (insn) != 0
1237       && JUMP_TABLE_DATA_P (NEXT_INSN (insn)))
1238     next = delete_related_insns (NEXT_INSN (insn));
1239
1240   /* If INSN was a label, delete insns following it if now unreachable.  */
1241
1242   if (was_code_label && prev && BARRIER_P (prev))
1243     {
1244       enum rtx_code code;
1245       while (next)
1246         {
1247           code = GET_CODE (next);
1248           if (code == NOTE)
1249             next = NEXT_INSN (next);
1250           /* Keep going past other deleted labels to delete what follows.  */
1251           else if (code == CODE_LABEL && INSN_DELETED_P (next))
1252             next = NEXT_INSN (next);
1253           else if (code == BARRIER || INSN_P (next))
1254             /* Note: if this deletes a jump, it can cause more
1255                deletion of unreachable code, after a different label.
1256                As long as the value from this recursive call is correct,
1257                this invocation functions correctly.  */
1258             next = delete_related_insns (next);
1259           else
1260             break;
1261         }
1262     }
1263
1264   /* I feel a little doubtful about this loop,
1265      but I see no clean and sure alternative way
1266      to find the first insn after INSN that is not now deleted.
1267      I hope this works.  */
1268   while (next && INSN_DELETED_P (next))
1269     next = NEXT_INSN (next);
1270   return next;
1271 }
1272 \f
1273 /* Delete a range of insns from FROM to TO, inclusive.
1274    This is for the sake of peephole optimization, so assume
1275    that whatever these insns do will still be done by a new
1276    peephole insn that will replace them.  */
1277
1278 void
1279 delete_for_peephole (rtx from, rtx to)
1280 {
1281   rtx insn = from;
1282
1283   while (1)
1284     {
1285       rtx next = NEXT_INSN (insn);
1286       rtx prev = PREV_INSN (insn);
1287
1288       if (!NOTE_P (insn))
1289         {
1290           INSN_DELETED_P (insn) = 1;
1291
1292           /* Patch this insn out of the chain.  */
1293           /* We don't do this all at once, because we
1294              must preserve all NOTEs.  */
1295           if (prev)
1296             NEXT_INSN (prev) = next;
1297
1298           if (next)
1299             PREV_INSN (next) = prev;
1300         }
1301
1302       if (insn == to)
1303         break;
1304       insn = next;
1305     }
1306
1307   /* Note that if TO is an unconditional jump
1308      we *do not* delete the BARRIER that follows,
1309      since the peephole that replaces this sequence
1310      is also an unconditional jump in that case.  */
1311 }
1312 \f
1313 /* Throughout LOC, redirect OLABEL to NLABEL.  Treat null OLABEL or
1314    NLABEL as a return.  Accrue modifications into the change group.  */
1315
1316 static void
1317 redirect_exp_1 (rtx *loc, rtx olabel, rtx nlabel, rtx insn)
1318 {
1319   rtx x = *loc;
1320   RTX_CODE code = GET_CODE (x);
1321   int i;
1322   const char *fmt;
1323
1324   if (code == LABEL_REF)
1325     {
1326       if (XEXP (x, 0) == olabel)
1327         {
1328           rtx n;
1329           if (nlabel)
1330             n = gen_rtx_LABEL_REF (Pmode, nlabel);
1331           else
1332             n = gen_rtx_RETURN (VOIDmode);
1333
1334           validate_change (insn, loc, n, 1);
1335           return;
1336         }
1337     }
1338   else if (code == RETURN && olabel == 0)
1339     {
1340       if (nlabel)
1341         x = gen_rtx_LABEL_REF (Pmode, nlabel);
1342       else
1343         x = gen_rtx_RETURN (VOIDmode);
1344       if (loc == &PATTERN (insn))
1345         x = gen_rtx_SET (VOIDmode, pc_rtx, x);
1346       validate_change (insn, loc, x, 1);
1347       return;
1348     }
1349
1350   if (code == SET && nlabel == 0 && SET_DEST (x) == pc_rtx
1351       && GET_CODE (SET_SRC (x)) == LABEL_REF
1352       && XEXP (SET_SRC (x), 0) == olabel)
1353     {
1354       validate_change (insn, loc, gen_rtx_RETURN (VOIDmode), 1);
1355       return;
1356     }
1357
1358   if (code == IF_THEN_ELSE)
1359     {
1360       /* Skip the condition of an IF_THEN_ELSE.  We only want to
1361          change jump destinations, not eventual label comparisons.  */
1362       redirect_exp_1 (&XEXP (x, 1), olabel, nlabel, insn);
1363       redirect_exp_1 (&XEXP (x, 2), olabel, nlabel, insn);
1364       return;
1365     }
1366
1367   fmt = GET_RTX_FORMAT (code);
1368   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1369     {
1370       if (fmt[i] == 'e')
1371         redirect_exp_1 (&XEXP (x, i), olabel, nlabel, insn);
1372       else if (fmt[i] == 'E')
1373         {
1374           int j;
1375           for (j = 0; j < XVECLEN (x, i); j++)
1376             redirect_exp_1 (&XVECEXP (x, i, j), olabel, nlabel, insn);
1377         }
1378     }
1379 }
1380
1381 /* Make JUMP go to NLABEL instead of where it jumps now.  Accrue
1382    the modifications into the change group.  Return false if we did
1383    not see how to do that.  */
1384
1385 int
1386 redirect_jump_1 (rtx jump, rtx nlabel)
1387 {
1388   int ochanges = num_validated_changes ();
1389   rtx *loc;
1390
1391   if (GET_CODE (PATTERN (jump)) == PARALLEL)
1392     loc = &XVECEXP (PATTERN (jump), 0, 0);
1393   else
1394     loc = &PATTERN (jump);
1395
1396   redirect_exp_1 (loc, JUMP_LABEL (jump), nlabel, jump);
1397   return num_validated_changes () > ochanges;
1398 }
1399
1400 /* Make JUMP go to NLABEL instead of where it jumps now.  If the old
1401    jump target label is unused as a result, it and the code following
1402    it may be deleted.
1403
1404    If NLABEL is zero, we are to turn the jump into a (possibly conditional)
1405    RETURN insn.
1406
1407    The return value will be 1 if the change was made, 0 if it wasn't
1408    (this can only occur for NLABEL == 0).  */
1409
1410 int
1411 redirect_jump (rtx jump, rtx nlabel, int delete_unused)
1412 {
1413   rtx olabel = JUMP_LABEL (jump);
1414
1415   if (nlabel == olabel)
1416     return 1;
1417
1418   if (! redirect_jump_1 (jump, nlabel) || ! apply_change_group ())
1419     return 0;
1420
1421   redirect_jump_2 (jump, olabel, nlabel, delete_unused, 0);
1422   return 1;
1423 }
1424
1425 /* Fix up JUMP_LABEL and label ref counts after OLABEL has been replaced with
1426    NLABEL in JUMP.  
1427    If DELETE_UNUSED is positive, delete related insn to OLABEL if its ref
1428    count has dropped to zero.  */
1429 void
1430 redirect_jump_2 (rtx jump, rtx olabel, rtx nlabel, int delete_unused,
1431                  int invert)
1432 {
1433   rtx note;
1434
1435   gcc_assert (JUMP_LABEL (jump) == olabel);
1436
1437   /* Negative DELETE_UNUSED used to be used to signalize behavior on
1438      moving FUNCTION_END note.  Just sanity check that no user still worry
1439      about this.  */
1440   gcc_assert (delete_unused >= 0);
1441   JUMP_LABEL (jump) = nlabel;
1442   if (nlabel)
1443     ++LABEL_NUSES (nlabel);
1444
1445   /* Update labels in any REG_EQUAL note.  */
1446   if ((note = find_reg_note (jump, REG_EQUAL, NULL_RTX)) != NULL_RTX)
1447     {
1448       if (!nlabel || (invert && !invert_exp_1 (XEXP (note, 0), jump)))
1449         remove_note (jump, note);
1450       else
1451         {
1452           redirect_exp_1 (&XEXP (note, 0), olabel, nlabel, jump);
1453           confirm_change_group ();
1454         }
1455     }
1456
1457   if (olabel && --LABEL_NUSES (olabel) == 0 && delete_unused > 0
1458       /* Undefined labels will remain outside the insn stream.  */
1459       && INSN_UID (olabel))
1460     delete_related_insns (olabel);
1461   if (invert)
1462     invert_br_probabilities (jump);
1463 }
1464
1465 /* Invert the jump condition X contained in jump insn INSN.  Accrue the
1466    modifications into the change group.  Return nonzero for success.  */
1467 static int
1468 invert_exp_1 (rtx x, rtx insn)
1469 {
1470   RTX_CODE code = GET_CODE (x);
1471
1472   if (code == IF_THEN_ELSE)
1473     {
1474       rtx comp = XEXP (x, 0);
1475       rtx tem;
1476       enum rtx_code reversed_code;
1477
1478       /* We can do this in two ways:  The preferable way, which can only
1479          be done if this is not an integer comparison, is to reverse
1480          the comparison code.  Otherwise, swap the THEN-part and ELSE-part
1481          of the IF_THEN_ELSE.  If we can't do either, fail.  */
1482
1483       reversed_code = reversed_comparison_code (comp, insn);
1484
1485       if (reversed_code != UNKNOWN)
1486         {
1487           validate_change (insn, &XEXP (x, 0),
1488                            gen_rtx_fmt_ee (reversed_code,
1489                                            GET_MODE (comp), XEXP (comp, 0),
1490                                            XEXP (comp, 1)),
1491                            1);
1492           return 1;
1493         }
1494
1495       tem = XEXP (x, 1);
1496       validate_change (insn, &XEXP (x, 1), XEXP (x, 2), 1);
1497       validate_change (insn, &XEXP (x, 2), tem, 1);
1498       return 1;
1499     }
1500   else
1501     return 0;
1502 }
1503
1504 /* Invert the condition of the jump JUMP, and make it jump to label
1505    NLABEL instead of where it jumps now.  Accrue changes into the
1506    change group.  Return false if we didn't see how to perform the
1507    inversion and redirection.  */
1508
1509 int
1510 invert_jump_1 (rtx jump, rtx nlabel)
1511 {
1512   rtx x = pc_set (jump);
1513   int ochanges;
1514   int ok;
1515
1516   ochanges = num_validated_changes ();
1517   gcc_assert (x);
1518   ok = invert_exp_1 (SET_SRC (x), jump);
1519   gcc_assert (ok);
1520   
1521   if (num_validated_changes () == ochanges)
1522     return 0;
1523
1524   /* redirect_jump_1 will fail of nlabel == olabel, and the current use is
1525      in Pmode, so checking this is not merely an optimization.  */
1526   return nlabel == JUMP_LABEL (jump) || redirect_jump_1 (jump, nlabel);
1527 }
1528
1529 /* Invert the condition of the jump JUMP, and make it jump to label
1530    NLABEL instead of where it jumps now.  Return true if successful.  */
1531
1532 int
1533 invert_jump (rtx jump, rtx nlabel, int delete_unused)
1534 {
1535   rtx olabel = JUMP_LABEL (jump);
1536
1537   if (invert_jump_1 (jump, nlabel) && apply_change_group ())
1538     {
1539       redirect_jump_2 (jump, olabel, nlabel, delete_unused, 1);
1540       return 1;
1541     }
1542   cancel_changes (0);
1543   return 0;
1544 }
1545
1546 \f
1547 /* Like rtx_equal_p except that it considers two REGs as equal
1548    if they renumber to the same value and considers two commutative
1549    operations to be the same if the order of the operands has been
1550    reversed.  */
1551
1552 int
1553 rtx_renumbered_equal_p (const_rtx x, const_rtx y)
1554 {
1555   int i;
1556   const enum rtx_code code = GET_CODE (x);
1557   const char *fmt;
1558
1559   if (x == y)
1560     return 1;
1561
1562   if ((code == REG || (code == SUBREG && REG_P (SUBREG_REG (x))))
1563       && (REG_P (y) || (GET_CODE (y) == SUBREG
1564                                   && REG_P (SUBREG_REG (y)))))
1565     {
1566       int reg_x = -1, reg_y = -1;
1567       int byte_x = 0, byte_y = 0;
1568       struct subreg_info info;
1569
1570       if (GET_MODE (x) != GET_MODE (y))
1571         return 0;
1572
1573       /* If we haven't done any renumbering, don't
1574          make any assumptions.  */
1575       if (reg_renumber == 0)
1576         return rtx_equal_p (x, y);
1577
1578       if (code == SUBREG)
1579         {
1580           reg_x = REGNO (SUBREG_REG (x));
1581           byte_x = SUBREG_BYTE (x);
1582
1583           if (reg_renumber[reg_x] >= 0)
1584             {
1585               subreg_get_info (reg_renumber[reg_x],
1586                                GET_MODE (SUBREG_REG (x)), byte_x,
1587                                GET_MODE (x), &info);
1588               if (!info.representable_p)
1589                 return 0;
1590               reg_x = info.offset;
1591               byte_x = 0;
1592             }
1593         }
1594       else
1595         {
1596           reg_x = REGNO (x);
1597           if (reg_renumber[reg_x] >= 0)
1598             reg_x = reg_renumber[reg_x];
1599         }
1600
1601       if (GET_CODE (y) == SUBREG)
1602         {
1603           reg_y = REGNO (SUBREG_REG (y));
1604           byte_y = SUBREG_BYTE (y);
1605
1606           if (reg_renumber[reg_y] >= 0)
1607             {
1608               subreg_get_info (reg_renumber[reg_y],
1609                                GET_MODE (SUBREG_REG (y)), byte_y,
1610                                GET_MODE (y), &info);
1611               if (!info.representable_p)
1612                 return 0;
1613               reg_y = info.offset;
1614               byte_y = 0;
1615             }
1616         }
1617       else
1618         {
1619           reg_y = REGNO (y);
1620           if (reg_renumber[reg_y] >= 0)
1621             reg_y = reg_renumber[reg_y];
1622         }
1623
1624       return reg_x >= 0 && reg_x == reg_y && byte_x == byte_y;
1625     }
1626
1627   /* Now we have disposed of all the cases
1628      in which different rtx codes can match.  */
1629   if (code != GET_CODE (y))
1630     return 0;
1631
1632   switch (code)
1633     {
1634     case PC:
1635     case CC0:
1636     case ADDR_VEC:
1637     case ADDR_DIFF_VEC:
1638     case CONST_INT:
1639     case CONST_DOUBLE:
1640       return 0;
1641
1642     case LABEL_REF:
1643       /* We can't assume nonlocal labels have their following insns yet.  */
1644       if (LABEL_REF_NONLOCAL_P (x) || LABEL_REF_NONLOCAL_P (y))
1645         return XEXP (x, 0) == XEXP (y, 0);
1646
1647       /* Two label-refs are equivalent if they point at labels
1648          in the same position in the instruction stream.  */
1649       return (next_real_insn (XEXP (x, 0))
1650               == next_real_insn (XEXP (y, 0)));
1651
1652     case SYMBOL_REF:
1653       return XSTR (x, 0) == XSTR (y, 0);
1654
1655     case CODE_LABEL:
1656       /* If we didn't match EQ equality above, they aren't the same.  */
1657       return 0;
1658
1659     default:
1660       break;
1661     }
1662
1663   /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.  */
1664
1665   if (GET_MODE (x) != GET_MODE (y))
1666     return 0;
1667
1668   /* For commutative operations, the RTX match if the operand match in any
1669      order.  Also handle the simple binary and unary cases without a loop.  */
1670   if (targetm.commutative_p (x, UNKNOWN))
1671     return ((rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0))
1672              && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 1)))
1673             || (rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 1))
1674                 && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 0))));
1675   else if (NON_COMMUTATIVE_P (x))
1676     return (rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0))
1677             && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 1)));
1678   else if (UNARY_P (x))
1679     return rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0));
1680
1681   /* Compare the elements.  If any pair of corresponding elements
1682      fail to match, return 0 for the whole things.  */
1683
1684   fmt = GET_RTX_FORMAT (code);
1685   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1686     {
1687       int j;
1688       switch (fmt[i])
1689         {
1690         case 'w':
1691           if (XWINT (x, i) != XWINT (y, i))
1692             return 0;
1693           break;
1694
1695         case 'i':
1696           if (XINT (x, i) != XINT (y, i))
1697             return 0;
1698           break;
1699
1700         case 't':
1701           if (XTREE (x, i) != XTREE (y, i))
1702             return 0;
1703           break;
1704
1705         case 's':
1706           if (strcmp (XSTR (x, i), XSTR (y, i)))
1707             return 0;
1708           break;
1709
1710         case 'e':
1711           if (! rtx_renumbered_equal_p (XEXP (x, i), XEXP (y, i)))
1712             return 0;
1713           break;
1714
1715         case 'u':
1716           if (XEXP (x, i) != XEXP (y, i))
1717             return 0;
1718           /* Fall through.  */
1719         case '0':
1720           break;
1721
1722         case 'E':
1723           if (XVECLEN (x, i) != XVECLEN (y, i))
1724             return 0;
1725           for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1726             if (!rtx_renumbered_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j)))
1727               return 0;
1728           break;
1729
1730         default:
1731           gcc_unreachable ();
1732         }
1733     }
1734   return 1;
1735 }
1736 \f
1737 /* If X is a hard register or equivalent to one or a subregister of one,
1738    return the hard register number.  If X is a pseudo register that was not
1739    assigned a hard register, return the pseudo register number.  Otherwise,
1740    return -1.  Any rtx is valid for X.  */
1741
1742 int
1743 true_regnum (const_rtx x)
1744 {
1745   if (REG_P (x))
1746     {
1747       if (REGNO (x) >= FIRST_PSEUDO_REGISTER && reg_renumber[REGNO (x)] >= 0)
1748         return reg_renumber[REGNO (x)];
1749       return REGNO (x);
1750     }
1751   if (GET_CODE (x) == SUBREG)
1752     {
1753       int base = true_regnum (SUBREG_REG (x));
1754       if (base >= 0
1755           && base < FIRST_PSEUDO_REGISTER)
1756         {
1757           struct subreg_info info;
1758
1759           subreg_get_info (REGNO (SUBREG_REG (x)),
1760                            GET_MODE (SUBREG_REG (x)),
1761                            SUBREG_BYTE (x), GET_MODE (x), &info);
1762
1763           if (info.representable_p)
1764             return base + info.offset;
1765         }
1766     }
1767   return -1;
1768 }
1769
1770 /* Return regno of the register REG and handle subregs too.  */
1771 unsigned int
1772 reg_or_subregno (const_rtx reg)
1773 {
1774   if (GET_CODE (reg) == SUBREG)
1775     reg = SUBREG_REG (reg);
1776   gcc_assert (REG_P (reg));
1777   return REGNO (reg);
1778 }