OSDN Git Service

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