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