can_reach_end = calculate_can_reach_end (last_insn, 0, 1);
if (calculate_can_reach_end (last_insn, 0, 1)) can_reach_end = 1;
jump_optimize_1 (f, cross_jump, noop_moves, after_regscan, mark_labels_only)     rtx f;     int cross_jump;     int noop_moves;     int after_regscan;     int mark_labels_only;{  register rtx insn, next;  int changed;  int old_max_reg;  int first = 1;  int max_uid = 0;  rtx last_insn;  cross_jump_death_matters = (cross_jump == 2);  max_uid = init_label_info (f) + 1;  /* If we are performing cross jump optimizations, then initialize     tables mapping UIDs to EH regions to avoid incorrect movement     of insns from one EH region to another.  */  if (flag_exceptions && cross_jump)    init_insn_eh_region (f, max_uid);  delete_barrier_successors (f);  /* Leave some extra room for labels and duplicate exit test insns     we make.  */  max_jump_chain = max_uid * 14 / 10;  jump_chain = (rtx *) alloca (max_jump_chain * sizeof (rtx));  bzero ((char *) jump_chain, max_jump_chain * sizeof (rtx));  mark_all_labels (f, cross_jump);  /* Keep track of labels used from static data;     they cannot ever be deleted.  */  for (insn = forced_labels; insn; insn = XEXP (insn, 1))    LABEL_NUSES (XEXP (insn, 0))++;  check_exception_handler_labels ();  /* Keep track of labels used for marking handlers for exception     regions; they cannot usually be deleted.  */  for (insn = exception_handler_labels; insn; insn = XEXP (insn, 1))    LABEL_NUSES (XEXP (insn, 0))++;  /* Quit now if we just wanted to rebuild the JUMP_LABEL and REG_LABEL     notes and recompute LABEL_NUSES.  */  if (mark_labels_only)    return;  exception_optimize ();  last_insn = delete_unreferenced_labels (f);  if (!optimize)    {      can_reach_end = calculate_can_reach_end (last_insn, 1, 0);      /* Zero the "deleted" flag of all the "deleted" insns.  */      for (insn = f; insn; insn = NEXT_INSN (insn))	INSN_DELETED_P (insn) = 0;      /* Show that the jump chain is not valid.  */      jump_chain = 0;      return;    }#ifdef HAVE_return  if (HAVE_return)    {      /* If we fall through to the epilogue, see if we can insert a RETURN insn	 in front of it.  If the machine allows it at this point (we might be	 after reload for a leaf routine), it will improve optimization for it	 to be there.  */      insn = get_last_insn ();      while (insn && GET_CODE (insn) == NOTE)	insn = PREV_INSN (insn);      if (insn && GET_CODE (insn) != BARRIER)	{	  emit_jump_insn (gen_return ());	  emit_barrier ();	}    }#endif  if (noop_moves)    delete_noop_moves (f);  /* If we haven't yet gotten to reload and we have just run regscan,     delete any insn that sets a register that isn't used elsewhere.     This helps some of the optimizations below by having less insns     being jumped around.  */  if (! reload_completed && after_regscan)    for (insn = f; insn; insn = next)      {	rtx set = single_set (insn);	next = NEXT_INSN (insn);	if (set && GET_CODE (SET_DEST (set)) == REG	    && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER	    && REGNO_FIRST_UID (REGNO (SET_DEST (set))) == INSN_UID (insn)	    /* We use regno_last_note_uid so as not to delete the setting	       of a reg that's used in notes.  A subsequent optimization	       might arrange to use that reg for real.  */	       	    && REGNO_LAST_NOTE_UID (REGNO (SET_DEST (set))) == INSN_UID (insn)	    && ! side_effects_p (SET_SRC (set))	    && ! find_reg_note (insn, REG_RETVAL, 0))	  delete_insn (insn);      }  /* Now iterate optimizing jumps until nothing changes over one pass.  */  changed = 1;  old_max_reg = max_reg_num ();  while (changed)    {      changed = 0;      for (insn = f; insn; insn = next)	{	  rtx reallabelprev;	  rtx temp, temp1, temp2, temp3, temp4, temp5, temp6;	  rtx nlabel;	  int this_is_simplejump, this_is_condjump, reversep = 0;	  int this_is_condjump_in_parallel;#if 0	  /* If NOT the first iteration, if this is the last jump pass	     (just before final), do the special peephole optimizations.	     Avoiding the first iteration gives ordinary jump opts	     a chance to work before peephole opts.  */	  if (reload_completed && !first && !flag_no_peephole)	    if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN)	      peephole (insn);#endif	  /* That could have deleted some insns after INSN, so check now	     what the following insn is.  */	  next = NEXT_INSN (insn);	  /* See if this is a NOTE_INSN_LOOP_BEG followed by an unconditional	     jump.  Try to optimize by duplicating the loop exit test if so.	     This is only safe immediately after regscan, because it uses	     the values of regno_first_uid and regno_last_uid.  */	  if (after_regscan && GET_CODE (insn) == NOTE	      && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG	      && (temp1 = next_nonnote_insn (insn)) != 0	      && simplejump_p (temp1))	    {	      temp = PREV_INSN (insn);	      if (duplicate_loop_exit_test (insn))		{		  changed = 1;		  next = NEXT_INSN (temp);		  continue;		}	    }	  if (GET_CODE (insn) != JUMP_INSN)	    continue;	  this_is_simplejump = simplejump_p (insn);	  this_is_condjump = condjump_p (insn);	  this_is_condjump_in_parallel = condjump_in_parallel_p (insn);	  /* Tension the labels in dispatch tables.  */	  if (GET_CODE (PATTERN (insn)) == ADDR_VEC)	    changed |= tension_vector_labels (PATTERN (insn), 0);	  if (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)	    changed |= tension_vector_labels (PATTERN (insn), 1);	  /* If a dispatch table always goes to the same place,	     get rid of it and replace the insn that uses it.  */	  if (GET_CODE (PATTERN (insn)) == ADDR_VEC	      || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)	    {	      int i;	      rtx pat = PATTERN (insn);	      int diff_vec_p = GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC;	      int len = XVECLEN (pat, diff_vec_p);	      rtx dispatch = prev_real_insn (insn);	      for (i = 0; i < len; i++)		if (XEXP (XVECEXP (pat, diff_vec_p, i), 0)		    != XEXP (XVECEXP (pat, diff_vec_p, 0), 0))		  break;	      if (i == len		  && dispatch != 0		  && GET_CODE (dispatch) == JUMP_INSN		  && JUMP_LABEL (dispatch) != 0		  /* Don't mess with a casesi insn.  */		  && !(GET_CODE (PATTERN (dispatch)) == SET		       && (GET_CODE (SET_SRC (PATTERN (dispatch)))			   == IF_THEN_ELSE))		  && next_real_insn (JUMP_LABEL (dispatch)) == insn)		{		  redirect_tablejump (dispatch,				      XEXP (XVECEXP (pat, diff_vec_p, 0), 0));		  changed = 1;		}	    }	  reallabelprev = prev_active_insn (JUMP_LABEL (insn));	  /* If a jump references the end of the function, try to turn	     it into a RETURN insn, possibly a conditional one.  */	  if (JUMP_LABEL (insn)	      && (next_active_insn (JUMP_LABEL (insn)) == 0		  || GET_CODE (PATTERN (next_active_insn (JUMP_LABEL (insn))))		      == RETURN))	    changed |= redirect_jump (insn, NULL_RTX);	  /* Detect jump to following insn.  */	  if (reallabelprev == insn && condjump_p (insn))	    {	      next = next_real_insn (JUMP_LABEL (insn));	      delete_jump (insn);	      changed = 1;	      continue;	    }	  /* If we have an unconditional jump preceded by a USE, try to put	     the USE before the target and jump there.  This simplifies many	     of the optimizations below since we don't have to worry about	     dealing with these USE insns.  We only do this if the label	     being branch to already has the identical USE or if code	     never falls through to that label.  */	  if (this_is_simplejump	      && (temp = prev_nonnote_insn (insn)) != 0	      && GET_CODE (temp) == INSN && GET_CODE (PATTERN (temp)) == USE	      && (temp1 = prev_nonnote_insn (JUMP_LABEL (insn))) != 0	      && (GET_CODE (temp1) == BARRIER		  || (GET_CODE (temp1) == INSN		      && rtx_equal_p (PATTERN (temp), PATTERN (temp1))))	      /* Don't do this optimization if we have a loop containing only		 the USE instruction, and the loop start label has a usage		 count of 1.  This is because we will redo this optimization		 everytime through the outer loop, and jump opt will never		 exit.  */	      && ! ((temp2 = prev_nonnote_insn (temp)) != 0		    && temp2 == JUMP_LABEL (insn)		    && LABEL_NUSES (temp2) == 1))	    {	      if (GET_CODE (temp1) == BARRIER)		{		  emit_insn_after (PATTERN (temp), temp1);		  temp1 = NEXT_INSN (temp1);		}	      delete_insn (temp);	      redirect_jump (insn, get_label_before (temp1));	      reallabelprev = prev_real_insn (temp1);	      changed = 1;	    }	  /* Simplify   if (...) x = a; else x = b; by converting it	     to         x = b; if (...) x = a;	     if B is sufficiently simple, the test doesn't involve X,	     and nothing in the test modifies B or X.	     If we have small register classes, we also can't do this if X	     is a hard register.	     If the "x = b;" insn has any REG_NOTES, we don't do this because	     of the possibility that we are running after CSE and there is a	     REG_EQUAL note that is only valid if the branch has already been	     taken.  If we move the insn with the REG_EQUAL note, we may	     fold the comparison to always be false in a later CSE pass.	     (We could also delete the REG_NOTES when moving the insn, but it	     seems simpler to not move it.)  An exception is that we can move	     the insn if the only note is a REG_EQUAL or REG_EQUIV whose	     value is the same as "b".	     INSN is the branch over the `else' part. 	     We set:	     TEMP to the jump insn preceding "x = a;"	     TEMP1 to X	     TEMP2 to the insn that sets "x = b;"	     TEMP3 to the insn that sets "x = a;"	     TEMP4 to the set of "x = b";  */	  if (this_is_simplejump	      && (temp3 = prev_active_insn (insn)) != 0	      && GET_CODE (temp3) == INSN	      && (temp4 = single_set (temp3)) != 0	      && GET_CODE (temp1 = SET_DEST (temp4)) == REG	      && (! SMALL_REGISTER_CLASSES		  || REGNO (temp1) >= FIRST_PSEUDO_REGISTER)	      && (temp2 = next_active_insn (insn)) != 0	      && GET_CODE (temp2) == INSN	      && (temp4 = single_set (temp2)) != 0	      && rtx_equal_p (SET_DEST (temp4), temp1)	      && ! side_effects_p (SET_SRC (temp4))	      && ! may_trap_p (SET_SRC (temp4))	      && (REG_NOTES (temp2) == 0		  || ((REG_NOTE_KIND (REG_NOTES (temp2)) == REG_EQUAL		       || REG_NOTE_KIND (REG_NOTES (temp2)) == REG_EQUIV)		      && XEXP (REG_NOTES (temp2), 1) == 0		      && rtx_equal_p (XEXP (REG_NOTES (temp2), 0),				      SET_SRC (temp4))))	      && (temp = prev_active_insn (temp3)) != 0	      && condjump_p (temp) && ! simplejump_p (temp)	      /* TEMP must skip over the "x = a;" insn */	      && prev_real_insn (JUMP_LABEL (temp)) == insn	      && no_labels_between_p (insn, JUMP_LABEL (temp))	      /* There must be no other entries to the "x = b;" insn.  */	      && no_labels_between_p (JUMP_LABEL (temp), temp2)	      /* INSN must either branch to the insn after TEMP2 or the insn		 after TEMP2 must branch to the same place as INSN.  */	      && (reallabelprev == temp2		  || ((temp5 = next_active_insn (temp2)) != 0		      && simplejump_p (temp5)		      && JUMP_LABEL (temp5) == JUMP_LABEL (insn))))	    {	      /* The test expression, X, may be a complicated test with		 multiple branches.  See if we can find all the uses of		 the label that TEMP branches to without hitting a CALL_INSN		 or a jump to somewhere else.  */	      rtx target = JUMP_LABEL (temp);	      int nuses = LABEL_NUSES (target);	      rtx p;#ifdef HAVE_cc0	      rtx q;#endif	      /* Set P to the first jump insn that goes around "x = a;".  */	      for (p = temp; nuses && p; p = prev_nonnote_insn (p))		{		  if (GET_CODE (p) == JUMP_INSN)		    {		      if (condjump_p (p) && ! simplejump_p (p)			  && JUMP_LABEL (p) == target)			{			  nuses--;			  if (nuses == 0)			    break;			}		      else			break;		    }		  else if (GET_CODE (p) == CALL_INSN)		    break;		}#ifdef HAVE_cc0	      /* We cannot insert anything between a set of cc and its use		 so if P uses cc0, we must back up to the previous insn.  */	      q = prev_nonnote_insn (p);	      if (q && GET_RTX_CLASS (GET_CODE (q)) == 'i'		  && sets_cc0_p (PATTERN (q)))		p = q;#endif	      if (p)		p = PREV_INSN (p);	      /* If we found all the uses and there was no data conflict, we		 can move the assignment unless we can branch into the middle		 from somewhere.  */	      if (nuses == 0 && p		  && no_labels_between_p (p, insn)		  && ! reg_referenced_between_p (temp1, p, NEXT_INSN (temp3))		  && ! reg_set_between_p (temp1, p, temp3)		  && (GET_CODE (SET_SRC (temp4)) == CONST_INT		      || ! modified_between_p (SET_SRC (temp4), p, temp2))		  /* Verify that registers used by the jump are not clobbered		     by the instruction being moved.  */		  && ! regs_set_between_p (PATTERN (temp),					   PREV_INSN (temp2),					   NEXT_INSN (temp2)))		{		  emit_insn_after_with_line_notes (PATTERN (temp2), p, temp2);		  delete_insn (temp2);		  /* Set NEXT to an insn that we know won't go away.  */		  next = next_active_insn (insn);		  /* Delete the jump around the set.  Note that we must do		     this before we redirect the test jumps so that it won't		     delete the code immediately following the assignment		     we moved (which might be a jump).  */		  delete_insn (insn);		  /* We either have two consecutive labels or a jump to		     a jump, so adjust all the JUMP_INSNs to branch to where		     INSN branches to.  */		  for (p = NEXT_INSN (p); p != next; p = NEXT_INSN (p))		    if (GET_CODE (p) == JUMP_INSN)		      redirect_jump (p, target);		  changed = 1;		  continue;		}	    }	  /* Simplify   if (...) { x = a; goto l; } x = b; by converting it	     to         x = a; if (...) goto l; x = b;	     if A is sufficiently simple, the test doesn't involve X,	     and nothing in the test modifies A or X.	     If we have small register classes, we also can't do this if X	     is a hard register.	     If the "x = a;" insn has any REG_NOTES, we don't do this because	     of the possibility that we are running after CSE and there is a	     REG_EQUAL note that is only valid if the branch has already been	     taken.  If we move the insn with the REG_EQUAL note, we may	     fold the comparison to always be false in a later CSE pass.	     (We could also delete the REG_NOTES when moving the insn, but it	     seems simpler to not move it.)  An exception is that we can move	     the insn if the only note is a REG_EQUAL or REG_EQUIV whose	     value is the same as "a".	     INSN is the goto.	     We set:	     TEMP to the jump insn preceding "x = a;"	     TEMP1 to X	     TEMP2 to the insn that sets "x = b;"	     TEMP3 to the insn that sets "x = a;"	     TEMP4 to the set of "x = a";  */	  if (this_is_simplejump	      && (temp2 = next_active_insn (insn)) != 0	      && GET_CODE (temp2) == INSN	      && (temp4 = single_set (temp2)) != 0	      && GET_CODE (temp1 = SET_DEST (temp4)) == REG	      && (! SMALL_REGISTER_CLASSES		  || REGNO (temp1) >= FIRST_PSEUDO_REGISTER)	      && (temp3 = prev_active_insn (insn)) != 0	      && GET_CODE (temp3) == INSN	      && (temp4 = single_set (temp3)) != 0	      && rtx_equal_p (SET_DEST (temp4), temp1)	      && ! side_effects_p (SET_SRC (temp4))	      && ! may_trap_p (SET_SRC (temp4))	      && (REG_NOTES (temp3) == 0		  || ((REG_NOTE_KIND (REG_NOTES (temp3)) == REG_EQUAL		       || REG_NOTE_KIND (REG_NOTES (temp3)) == REG_EQUIV)		      && XEXP (REG_NOTES (temp3), 1) == 0		      && rtx_equal_p (XEXP (REG_NOTES (temp3), 0),				      SET_SRC (temp4))))	      && (temp = prev_active_insn (temp3)) != 0	      && condjump_p (temp) && ! simplejump_p (temp)	      /* TEMP must skip over the "x = a;" insn */	      && prev_real_insn (JUMP_LABEL (temp)) == insn	      && no_labels_between_p (temp, insn))	    {	      rtx prev_label = JUMP_LABEL (temp);	      rtx insert_after = prev_nonnote_insn (temp);#ifdef HAVE_cc0	      /* We cannot insert anything between a set of cc and its use.  */	      if (insert_after && GET_RTX_CLASS (GET_CODE (insert_after)) == 'i'		  && sets_cc0_p (PATTERN (insert_after)))		insert_after = prev_nonnote_insn (insert_after);#endif	      ++LABEL_NUSES (prev_label);	      if (insert_after		  && no_labels_between_p (insert_after, temp)		  && ! reg_referenced_between_p (temp1, insert_after, temp3)		  && ! reg_referenced_between_p (temp1, temp3,						 NEXT_INSN (temp2))		  && ! reg_set_between_p (temp1, insert_after, temp)		  && ! modified_between_p (SET_SRC (temp4), insert_after, temp)		  /* Verify that registers used by the jump are not clobbered		     by the instruction being moved.  */		  && ! regs_set_between_p (PATTERN (temp),					   PREV_INSN (temp3),					   NEXT_INSN (temp3))		  && invert_jump (temp, JUMP_LABEL (insn)))		{		  emit_insn_after_with_line_notes (PATTERN (temp3),						   insert_after, temp3);		  delete_insn (temp3);		  delete_insn (insn);		  /* Set NEXT to an insn that we know won't go away.  */		  next = temp2;		  changed = 1;		}	      if (prev_label && --LABEL_NUSES (prev_label) == 0)		delete_insn (prev_label);	      if (changed)		continue;	    }#ifndef HAVE_cc0	  /* If we have if (...) x = exp;  and branches are expensive,	     EXP is a single insn, does not have any side effects, cannot	     trap, and is not too costly, convert this to	     t = exp; if (...) x = t;	     Don't do this when we have CC0 because it is unlikely to help	     and we'd need to worry about where to place the new insn and	     the potential for conflicts.  We also can't do this when we have	     notes on the insn for the same reason as above.	     We set:	     TEMP to the "x = exp;" insn.	     TEMP1 to the single set in the "x = exp;" insn.	     TEMP2 to "x".  */	  if (! reload_completed	      && this_is_condjump && ! this_is_simplejump	      && BRANCH_COST >= 3	      && (temp = next_nonnote_insn (insn)) != 0	      && GET_CODE (temp) == INSN	      && REG_NOTES (temp) == 0	      && (reallabelprev == temp		  || ((temp2 = next_active_insn (temp)) != 0		      && simplejump_p (temp2)		      && JUMP_LABEL (temp2) == JUMP_LABEL (insn)))	      && (temp1 = single_set (temp)) != 0	      && (temp2 = SET_DEST (temp1), GET_CODE (temp2) == REG)	      && (! SMALL_REGISTER_CLASSES		  || REGNO (temp2) >= FIRST_PSEUDO_REGISTER)	      && GET_CODE (SET_SRC (temp1)) != REG	      && GET_CODE (SET_SRC (temp1)) != SUBREG	      && GET_CODE (SET_SRC (temp1)) != CONST_INT	      && ! side_effects_p (SET_SRC (temp1))	      && ! may_trap_p (SET_SRC (temp1))	      && rtx_cost (SET_SRC (temp1), SET) < 10)	    {	      rtx new = gen_reg_rtx (GET_MODE (temp2));	      if ((temp3 = find_insert_position (insn, temp))		  && validate_change (temp, &SET_DEST (temp1), new, 0))		{		  next = emit_insn_after (gen_move_insn (temp2, new), insn);		  emit_insn_after_with_line_notes (PATTERN (temp), 						   PREV_INSN (temp3), temp);		  delete_insn (temp);		  reallabelprev = prev_active_insn (JUMP_LABEL (insn));		  if (after_regscan)		    {		      reg_scan_update (temp3, NEXT_INSN (next), old_max_reg);		      old_max_reg = max_reg_num ();		    }		}	    }	  /* Similarly, if it takes two insns to compute EXP but they	     have the same destination.  Here TEMP3 will be the second	     insn and TEMP4 the SET from that insn.  */	  if (! reload_completed	      && this_is_condjump && ! this_is_simplejump	      && BRANCH_COST >= 4	      && (temp = next_nonnote_insn (insn)) != 0	      && GET_CODE (temp) == INSN	      && REG_NOTES (temp) == 0	      && (temp3 = next_nonnote_insn (temp)) != 0	      && GET_CODE (temp3) == INSN	      && REG_NOTES (temp3) == 0	      && (reallabelprev == temp3		  || ((temp2 = next_active_insn (temp3)) != 0		      && simplejump_p (temp2)		      && JUMP_LABEL (temp2) == JUMP_LABEL (insn)))	      && (temp1 = single_set (temp)) != 0	      && (temp2 = SET_DEST (temp1), GET_CODE (temp2) == REG)	      && GET_MODE_CLASS (GET_MODE (temp2)) == MODE_INT	      && (! SMALL_REGISTER_CLASSES		  || REGNO (temp2) >= FIRST_PSEUDO_REGISTER)	      && ! side_effects_p (SET_SRC (temp1))	      && ! may_trap_p (SET_SRC (temp1))	      && rtx_cost (SET_SRC (temp1), SET) < 10	      && (temp4 = single_set (temp3)) != 0	      && rtx_equal_p (SET_DEST (temp4), temp2)	      && ! side_effects_p (SET_SRC (temp4))	      && ! may_trap_p (SET_SRC (temp4))	      && rtx_cost (SET_SRC (temp4), SET) < 10)	    {	      rtx new = gen_reg_rtx (GET_MODE (temp2));	      if ((temp5 = find_insert_position (insn, temp))		  && (temp6 = find_insert_position (insn, temp3))		  && validate_change (temp, &SET_DEST (temp1), new, 0))		{		  /* Use the earliest of temp5 and temp6. */		  if (temp5 != insn)		    temp6 = temp5;		  next = emit_insn_after (gen_move_insn (temp2, new), insn);		  emit_insn_after_with_line_notes (PATTERN (temp),						   PREV_INSN (temp6), temp);		  emit_insn_after_with_line_notes		    (replace_rtx (PATTERN (temp3), temp2, new),		     PREV_INSN (temp6), temp3);		  delete_insn (temp);		  delete_insn (temp3);		  reallabelprev = prev_active_insn (JUMP_LABEL (insn));		  if (after_regscan)		    {		      reg_scan_update (temp6, NEXT_INSN (next), old_max_reg);		      old_max_reg = max_reg_num ();		    }		}	    }	  /* Finally, handle the case where two insns are used to 	     compute EXP but a temporary register is used.  Here we must	     ensure that the temporary register is not used anywhere else.  */	  if (! reload_completed	      && after_regscan	      && this_is_condjump && ! this_is_simplejump	      && BRANCH_COST >= 4	      && (temp = next_nonnote_insn (insn)) != 0	      && GET_CODE (temp) == INSN	      && REG_NOTES (temp) == 0	      && (temp3 = next_nonnote_insn (temp)) != 0	      && GET_CODE (temp3) == INSN	      && REG_NOTES (temp3) == 0	      && (reallabelprev == temp3		  || ((temp2 = next_active_insn (temp3)) != 0		      && simplejump_p (temp2)		      && JUMP_LABEL (temp2) == JUMP_LABEL (insn)))	      && (temp1 = single_set (temp)) != 0	      && (temp5 = SET_DEST (temp1),		  (GET_CODE (temp5) == REG		   || (GET_CODE (temp5) == SUBREG		       && (temp5 = SUBREG_REG (temp5),			   GET_CODE (temp5) == REG))))	      && REGNO (temp5) >= FIRST_PSEUDO_REGISTER	      && REGNO_FIRST_UID (REGNO (temp5)) == INSN_UID (temp)	      && REGNO_LAST_UID (REGNO (temp5)) == INSN_UID (temp3)	      && ! side_effects_p (SET_SRC (temp1))	      && ! may_trap_p (SET_SRC (temp1))	      && rtx_cost (SET_SRC (temp1), SET) < 10	      && (temp4 = single_set (temp3)) != 0	      && (temp2 = SET_DEST (temp4), GET_CODE (temp2) == REG)	      && GET_MODE_CLASS (GET_MODE (temp2)) == MODE_INT	      && (! SMALL_REGISTER_CLASSES		  || REGNO (temp2) >= FIRST_PSEUDO_REGISTER)	      && rtx_equal_p (SET_DEST (temp4), temp2)	      && ! side_effects_p (SET_SRC (temp4))	      && ! may_trap_p (SET_SRC (temp4))	      && rtx_cost (SET_SRC (temp4), SET) < 10)	    {	      rtx new = gen_reg_rtx (GET_MODE (temp2));	      if ((temp5 = find_insert_position (insn, temp))		  && (temp6 = find_insert_position (insn, temp3))		  && validate_change (temp3, &SET_DEST (temp4), new, 0))		{		  /* Use the earliest of temp5 and temp6. */		  if (temp5 != insn)		    temp6 = temp5;		  next = emit_insn_after (gen_move_insn (temp2, new), insn);		  emit_insn_after_with_line_notes (PATTERN (temp),						   PREV_INSN (temp6), temp);		  emit_insn_after_with_line_notes (PATTERN (temp3),						   PREV_INSN (temp6), temp3);		  delete_insn (temp);		  delete_insn (temp3);		  reallabelprev = prev_active_insn (JUMP_LABEL (insn));		  if (after_regscan)		    {		      reg_scan_update (temp6, NEXT_INSN (next), old_max_reg);		      old_max_reg = max_reg_num ();		    }		}	    }#endif /* HAVE_cc0 */	  /* Try to use a conditional move (if the target has them), or a	     store-flag insn.  The general case is:	     1) x = a; if (...) x = b; and	     2) if (...) x = b;	     If the jump would be faster, the machine should not have defined	     the movcc or scc insns!.  These cases are often made by the	     previous optimization.	     The second case is treated as  x = x; if (...) x = b;.	     INSN here is the jump around the store.  We set:	     TEMP to the "x = b;" insn.	     TEMP1 to X.	     TEMP2 to B.	     TEMP3 to A (X in the second case).	     TEMP4 to the condition being tested.	     TEMP5 to the earliest insn used to find the condition.  */	  if (/* We can't do this after reload has completed.  */	      ! reload_completed	      && this_is_condjump && ! this_is_simplejump	      /* Set TEMP to the "x = b;" insn.  */	      && (temp = next_nonnote_insn (insn)) != 0	      && GET_CODE (temp) == INSN	      && GET_CODE (PATTERN (temp)) == SET	      && GET_CODE (temp1 = SET_DEST (PATTERN (temp))) == REG	      && (! SMALL_REGISTER_CLASSES		  || REGNO (temp1) >= FIRST_PSEUDO_REGISTER)	      && ! side_effects_p (temp2 = SET_SRC (PATTERN (temp)))	      && ! may_trap_p (temp2)	      /* Allow either form, but prefer the former if both apply. 		 There is no point in using the old value of TEMP1 if		 it is a register, since cse will alias them.  It can		 lose if the old value were a hard register since CSE		 won't replace hard registers.  Avoid using TEMP3 if		 small register classes and it is a hard register.  */	      && (((temp3 = reg_set_last (temp1, insn)) != 0		   && ! (SMALL_REGISTER_CLASSES && GET_CODE (temp3) == REG			 && REGNO (temp3) < FIRST_PSEUDO_REGISTER))		  /* Make the latter case look like  x = x; if (...) x = b;  */		  || (temp3 = temp1, 1))	      /* INSN must either branch to the insn after TEMP or the insn		 after TEMP must branch to the same place as INSN.  */	      && (reallabelprev == temp		  || ((temp4 = next_active_insn (temp)) != 0		      && simplejump_p (temp4)		      && JUMP_LABEL (temp4) == JUMP_LABEL (insn)))	      && (temp4 = get_condition (insn, &temp5)) != 0	      /* We must be comparing objects whose modes imply the size.		 We could handle BLKmode if (1) emit_store_flag could		 and (2) we could find the size reliably.  */	      && GET_MODE (XEXP (temp4, 0)) != BLKmode	      /* Even if branches are cheap, the store_flag optimization		 can win when the operation to be performed can be		 expressed directly.  */#ifdef HAVE_cc0	      /* If the previous insn sets CC0 and something else, we can't		 do this since we are going to delete that insn.  */	      && ! ((temp6 = prev_nonnote_insn (insn)) != 0		    && GET_CODE (temp6) == INSN		    && (sets_cc0_p (PATTERN (temp6)) == -1			|| (sets_cc0_p (PATTERN (temp6)) == 1			    && FIND_REG_INC_NOTE (temp6, NULL_RTX))))#endif	      )	    {#ifdef HAVE_conditional_move	      /* First try a conditional move.  */	      {		enum rtx_code code = GET_CODE (temp4);		rtx var = temp1;		rtx cond0, cond1, aval, bval;		rtx target;		/* Copy the compared variables into cond0 and cond1, so that		   any side effects performed in or after the old comparison,		   will not affect our compare which will come later.  */		/* ??? Is it possible to just use the comparison in the jump		   insn?  After all, we're going to delete it.  We'd have		   to modify emit_conditional_move to take a comparison rtx		   instead or write a new function.  */		cond0 = gen_reg_rtx (GET_MODE (XEXP (temp4, 0)));		/* We want the target to be able to simplify comparisons with		   zero (and maybe other constants as well), so don't create		   pseudos for them.  There's no need to either.  */		if (GET_CODE (XEXP (temp4, 1)) == CONST_INT		    || GET_CODE (XEXP (temp4, 1)) == CONST_DOUBLE)		  cond1 = XEXP (temp4, 1);		else		  cond1 = gen_reg_rtx (GET_MODE (XEXP (temp4, 1)));		aval = temp3;		bval = temp2;		start_sequence ();		target = emit_conditional_move (var, code,						cond0, cond1, VOIDmode,						aval, bval, GET_MODE (var),						(code == LTU || code == GEU						 || code == LEU || code == GTU));		if (target)		  {		    rtx seq1,seq2,last;		    /* Save the conditional move sequence but don't emit it		       yet.  On some machines, like the alpha, it is possible		       that temp5 == insn, so next generate the sequence that		       saves the compared values and then emit both		       sequences ensuring seq1 occurs before seq2.  */		    seq2 = get_insns ();		    end_sequence ();		    /* Now that we can't fail, generate the copy insns that		       preserve the compared values.  */		    start_sequence ();		    emit_move_insn (cond0, XEXP (temp4, 0));		    if (cond1 != XEXP (temp4, 1))		      emit_move_insn (cond1, XEXP (temp4, 1));		    seq1 = get_insns ();		    end_sequence ();		    emit_insns_before (seq1, temp5);		    /* Insert conditional move after insn, to be sure that		       the jump and a possible compare won't be separated */		    last = emit_insns_after (seq2, insn);		    /* ??? We can also delete the insn that sets X to A.		       Flow will do it too though.  */		    delete_insn (temp);		    next = NEXT_INSN (insn);		    delete_jump (insn);		    if (after_regscan)		      {			reg_scan_update (seq1, NEXT_INSN (last), old_max_reg);			old_max_reg = max_reg_num ();		      }		    changed = 1;		    continue;		  }		else		  end_sequence ();	      }#endif	      /* That didn't work, try a store-flag insn.		 We further divide the cases into:		 1) x = a; if (...) x = b; and either A or B is zero,		 2) if (...) x = 0; and jumps are expensive,		 3) x = a; if (...) x = b; and A and B are constants where all		 the set bits in A are also set in B and jumps are expensive,		 4) x = a; if (...) x = b; and A and B non-zero, and jumps are		 more expensive, and		 5) if (...) x = b; if jumps are even more expensive.  */	      if (GET_MODE_CLASS (GET_MODE (temp1)) == MODE_INT		  && ((GET_CODE (temp3) == CONST_INT)		      /* Make the latter case look like			 x = x; if (...) x = 0;  */		      || (temp3 = temp1,			  ((BRANCH_COST >= 2			    && temp2 == const0_rtx)			   || BRANCH_COST >= 3)))		  /* If B is zero, OK; if A is zero, can only do (1) if we		     can reverse the condition.  See if (3) applies possibly		     by reversing the condition.  Prefer reversing to (4) when		     branches are very expensive.  */		  && (((BRANCH_COST >= 2			|| STORE_FLAG_VALUE == -1			|| (STORE_FLAG_VALUE == 1			 /* Check that the mask is a power of two,			    so that it can probably be generated			    with a shift.  */			    && GET_CODE (temp3) == CONST_INT			    && exact_log2 (INTVAL (temp3)) >= 0))		       && (reversep = 0, temp2 == const0_rtx))		      || ((BRANCH_COST >= 2			   || STORE_FLAG_VALUE == -1			   || (STORE_FLAG_VALUE == 1			       && GET_CODE (temp2) == CONST_INT			       && exact_log2 (INTVAL (temp2)) >= 0))			  && temp3 == const0_rtx			  && (reversep = can_reverse_comparison_p (temp4, insn)))		      || (BRANCH_COST >= 2			  && GET_CODE (temp2) == CONST_INT			  && GET_CODE (temp3) == CONST_INT			  && ((INTVAL (temp2) & INTVAL (temp3)) == INTVAL (temp2)			      || ((INTVAL (temp2) & INTVAL (temp3)) == INTVAL (temp3)				  && (reversep = can_reverse_comparison_p (temp4,									   insn)))))		      || BRANCH_COST >= 3)		  )		{		  enum rtx_code code = GET_CODE (temp4);		  rtx uval, cval, var = temp1;		  int normalizep;		  rtx target;		  /* If necessary, reverse the condition.  */		  if (reversep)		    code = reverse_condition (code), uval = temp2, cval = temp3;		  else		    uval = temp3, cval = temp2;		  /* If CVAL is non-zero, normalize to -1.  Otherwise, if UVAL		     is the constant 1, it is best to just compute the result		     directly.  If UVAL is constant and STORE_FLAG_VALUE		     includes all of its bits, it is best to compute the flag		     value unnormalized and `and' it with UVAL.  Otherwise,		     normalize to -1 and `and' with UVAL.  */		  normalizep = (cval != const0_rtx ? -1				: (uval == const1_rtx ? 1				   : (GET_CODE (uval) == CONST_INT				      && (INTVAL (uval) & ~STORE_FLAG_VALUE) == 0)				   ? 0 : -1));		  /* We will be putting the store-flag insn immediately in		     front of the comparison that was originally being done,		     so we know all the variables in TEMP4 will be valid.		     However, this might be in front of the assignment of		     A to VAR.  If it is, it would clobber the store-flag		     we will be emitting.		     Therefore, emit into a temporary which will be copied to		     VAR immediately after TEMP.  */		  start_sequence ();		  target = emit_store_flag (gen_reg_rtx (GET_MODE (var)), code,					    XEXP (temp4, 0), XEXP (temp4, 1),					    VOIDmode,					    (code == LTU || code == LEU 					     || code == GEU || code == GTU),					    normalizep);		  if (target)		    {		      rtx seq;		      rtx before = insn;		      seq = get_insns ();		      end_sequence ();		      /* Put the store-flag insns in front of the first insn			 used to compute the condition to ensure that we			 use the same values of them as the current 			 comparison.  However, the remainder of the insns we			 generate will be placed directly in front of the			 jump insn, in case any of the pseudos we use			 are modified earlier.  */		      emit_insns_before (seq, temp5);		      start_sequence ();		      /* Both CVAL and UVAL are non-zero.  */		      if (cval != const0_rtx && uval != const0_rtx)			{			  rtx tem1, tem2;			  tem1 = expand_and (uval, target, NULL_RTX);			  if (GET_CODE (cval) == CONST_INT			      && GET_CODE (uval) == CONST_INT			      && (INTVAL (cval) & INTVAL (uval)) == INTVAL (cval))			    tem2 = cval;			  else			    {			      tem2 = expand_unop (GET_MODE (var), one_cmpl_optab,						  target, NULL_RTX, 0);			      tem2 = expand_and (cval, tem2,						 (GET_CODE (tem2) == REG						  ? tem2 : 0));			    }			  /* If we usually make new pseudos, do so here.  This			     turns out to help machines that have conditional			     move insns.  */			  /* ??? Conditional moves have already been handled.			     This may be obsolete.  */			  if (flag_expensive_optimizations)			    target = 0;			  target = expand_binop (GET_MODE (var), ior_optab,						 tem1, tem2, target,						 1, OPTAB_WIDEN);			}		      else if (normalizep != 1)			{			  /* We know that either CVAL or UVAL is zero.  If			     UVAL is zero, negate TARGET and `and' with CVAL.			     Otherwise, `and' with UVAL.  */			  if (uval == const0_rtx)			    {			      target = expand_unop (GET_MODE (var), one_cmpl_optab,						    target, NULL_RTX, 0);			      uval = cval;			    }			  target = expand_and (uval, target,					       (GET_CODE (target) == REG						&& ! preserve_subexpressions_p ()						? target : NULL_RTX));			}		  		      emit_move_insn (var, target);		      seq = get_insns ();		      end_sequence ();#ifdef HAVE_cc0		      /* If INSN uses CC0, we must not separate it from the			 insn that sets cc0.  */		      if (reg_mentioned_p (cc0_rtx, PATTERN (before)))			before = prev_nonnote_insn (before);#endif		      emit_insns_before (seq, before);		      delete_insn (temp);		      next = NEXT_INSN (insn);		      delete_jump (insn);		      if (after_regscan)			{			  reg_scan_update (seq, NEXT_INSN (next), old_max_reg);			  old_max_reg = max_reg_num ();			}		      changed = 1;		      continue;		    }		  else		    end_sequence ();		}	    }	  /* If branches are expensive, convert	        if (foo) bar++;    to    bar += (foo != 0);	     and similarly for "bar--;" 	     INSN is the conditional branch around the arithmetic.  We set:	     TEMP is the arithmetic insn.	     TEMP1 is the SET doing the arithmetic.	     TEMP2 is the operand being incremented or decremented.	     TEMP3 to the condition being tested.	     TEMP4 to the earliest insn used to find the condition.  */	  if ((BRANCH_COST >= 2#ifdef HAVE_incscc	       || HAVE_incscc#endif#ifdef HAVE_decscc	       || HAVE_decscc#endif	      )	      && ! reload_completed	      && this_is_condjump && ! this_is_simplejump	      && (temp = next_nonnote_insn (insn)) != 0	      && (temp1 = single_set (temp)) != 0	      && (temp2 = SET_DEST (temp1),		  GET_MODE_CLASS (GET_MODE (temp2)) == MODE_INT)	      && GET_CODE (SET_SRC (temp1)) == PLUS	      && (XEXP (SET_SRC (temp1), 1) == const1_rtx		  || XEXP (SET_SRC (temp1), 1) == constm1_rtx)	      && rtx_equal_p (temp2, XEXP (SET_SRC (temp1), 0))	      && ! side_effects_p (temp2)	      && ! may_trap_p (temp2)	      /* INSN must either branch to the insn after TEMP or the insn		 after TEMP must branch to the same place as INSN.  */	      && (reallabelprev == temp		  || ((temp3 = next_active_insn (temp)) != 0		      && simplejump_p (temp3)		      && JUMP_LABEL (temp3) == JUMP_LABEL (insn)))	      && (temp3 = get_condition (insn, &temp4)) != 0	      /* We must be comparing objects whose modes imply the size.		 We could handle BLKmode if (1) emit_store_flag could		 and (2) we could find the size reliably.  */	      && GET_MODE (XEXP (temp3, 0)) != BLKmode	      && can_reverse_comparison_p (temp3, insn))	    {	      rtx temp6, target = 0, seq, init_insn = 0, init = temp2;	      enum rtx_code code = reverse_condition (GET_CODE (temp3));	      start_sequence ();	      /* It must be the case that TEMP2 is not modified in the range		 [TEMP4, INSN).  The one exception we make is if the insn		 before INSN sets TEMP2 to something which is also unchanged		 in that range.  In that case, we can move the initialization		 into our sequence.  */	      if ((temp5 = prev_active_insn (insn)) != 0		  && no_labels_between_p (temp5, insn)		  && GET_CODE (temp5) == INSN		  && (temp6 = single_set (temp5)) != 0		  && rtx_equal_p (temp2, SET_DEST (temp6))		  && (CONSTANT_P (SET_SRC (temp6))		      || GET_CODE (SET_SRC (temp6)) == REG		      || GET_CODE (SET_SRC (temp6)) == SUBREG))		{		  emit_insn (PATTERN (temp5));		  init_insn = temp5;		  init = SET_SRC (temp6);		}	      if (CONSTANT_P (init)		  || ! reg_set_between_p (init, PREV_INSN (temp4), insn))		target = emit_store_flag (gen_reg_rtx (GET_MODE (temp2)), code,					  XEXP (temp3, 0), XEXP (temp3, 1),					  VOIDmode,					  (code == LTU || code == LEU					   || code == GTU || code == GEU), 1);	      /* If we can do the store-flag, do the addition or		 subtraction.  */	      if (target)		target = expand_binop (GET_MODE (temp2),				       (XEXP (SET_SRC (temp1), 1) == const1_rtx					? add_optab : sub_optab),				       temp2, target, temp2, 0, OPTAB_WIDEN);	      if (target != 0)		{		  /* Put the result back in temp2 in case it isn't already.		     Then replace the jump, possible a CC0-setting insn in		     front of the jump, and TEMP, with the sequence we have		     made.  */		  if (target != temp2)		    emit_move_insn (temp2, target);		  seq = get_insns ();		  end_sequence ();		  emit_insns_before (seq, temp4);		  delete_insn (temp);		  if (init_insn)		    delete_insn (init_insn);		  next = NEXT_INSN (insn);#ifdef HAVE_cc0		  delete_insn (prev_nonnote_insn (insn));#endif		  delete_insn (insn);		  if (after_regscan)		    {		      reg_scan_update (seq, NEXT_INSN (next), old_max_reg);		      old_max_reg = max_reg_num ();		    }		  changed = 1;		  continue;		}	      else		end_sequence ();	    }	  /* Simplify   if (...) x = 1; else {...}  if (x) ...	     We recognize this case scanning backwards as well.	     TEMP is the assignment to x;	     TEMP1 is the label at the head of the second if.  */	  /* ?? This should call get_condition to find the values being	     compared, instead of looking for a COMPARE insn when HAVE_cc0	     is not defined.  This would allow it to work on the m88k.  */	  /* ?? This optimization is only safe before cse is run if HAVE_cc0	     is not defined and the condition is tested by a separate compare	     insn.  This is because the code below assumes that the result	     of the compare dies in the following branch.	     Not only that, but there might be other insns between the	     compare and branch whose results are live.  Those insns need	     to be executed.	     A way to fix this is to move the insns at JUMP_LABEL (insn)	     to before INSN.  If we are running before flow, they will	     be deleted if they aren't needed.   But this doesn't work	     well after flow.	     This is really a special-case of jump threading, anyway.  The	     right thing to do is to replace this and jump threading with	     much simpler code in cse.	     This code has been turned off in the non-cc0 case in the	     meantime.  */#ifdef HAVE_cc0	  else if (this_is_simplejump		   /* Safe to skip USE and CLOBBER insns here		      since they will not be deleted.  */		   && (temp = prev_active_insn (insn))		   && no_labels_between_p (temp, insn)		   && GET_CODE (temp) == INSN		   && GET_CODE (PATTERN (temp)) == SET		   && GET_CODE (SET_DEST (PATTERN (temp))) == REG		   && CONSTANT_P (SET_SRC (PATTERN (temp)))		   && (temp1 = next_active_insn (JUMP_LABEL (insn)))		   /* If we find that the next value tested is `x'		      (TEMP1 is the insn where this happens), win.  */		   && GET_CODE (temp1) == INSN		   && GET_CODE (PATTERN (temp1)) == SET#ifdef HAVE_cc0		   /* Does temp1 `tst' the value of x?  */		   && SET_SRC (PATTERN (temp1)) == SET_DEST (PATTERN (temp))		   && SET_DEST (PATTERN (temp1)) == cc0_rtx		   && (temp1 = next_nonnote_insn (temp1))#else		   /* Does temp1 compare the value of x against zero?  */		   && GET_CODE (SET_SRC (PATTERN (temp1))) == COMPARE		   && XEXP (SET_SRC (PATTERN (temp1)), 1) == const0_rtx		   && (XEXP (SET_SRC (PATTERN (temp1)), 0)		       == SET_DEST (PATTERN (temp)))		   && GET_CODE (SET_DEST (PATTERN (temp1))) == REG		   && (temp1 = find_next_ref (SET_DEST (PATTERN (temp1)), temp1))#endif		   && condjump_p (temp1))	    {	      /* Get the if_then_else from the condjump.  */	      rtx choice = SET_SRC (PATTERN (temp1));	      if (GET_CODE (choice) == IF_THEN_ELSE)		{		  enum rtx_code code = GET_CODE (XEXP (choice, 0));		  rtx val = SET_SRC (PATTERN (temp));		  rtx cond		    = simplify_relational_operation (code, GET_MODE (SET_DEST (PATTERN (temp))),						     val, const0_rtx);		  rtx ultimate;		  if (cond == const_true_rtx)		    ultimate = XEXP (choice, 1);		  else if (cond == const0_rtx)		    ultimate = XEXP (choice, 2);		  else		    ultimate = 0;		  if (ultimate == pc_rtx)		    ultimate = get_label_after (temp1);		  else if (ultimate && GET_CODE (ultimate) != RETURN)		    ultimate = XEXP (ultimate, 0);		  if (ultimate && JUMP_LABEL(insn) != ultimate)		    changed |= redirect_jump (insn, ultimate);		}	    }#endif#if 0	  /* @@ This needs a bit of work before it will be right.	     Any type of comparison can be accepted for the first and	     second compare.  When rewriting the first jump, we must	     compute the what conditions can reach label3, and use the	     appropriate code.  We can not simply reverse/swap the code	     of the first jump.  In some cases, the second jump must be	     rewritten also.	     For example, 	     <  == converts to >  ==	     <  != converts to ==  >	     etc.	     If the code is written to only accept an '==' test for the second	     compare, then all that needs to be done is to swap the condition	     of the first branch.	     It is questionable whether we want this optimization anyways,	     since if the user wrote code like this because he/she knew that	     the jump to label1 is taken most of the time, then rewriting	     this gives slower code.  */	  /* @@ This should call get_condition to find the values being	     compared, instead of looking for a COMPARE insn when HAVE_cc0	     is not defined.  This would allow it to work on the m88k.  */	  /* @@ This optimization is only safe before cse is run if HAVE_cc0	     is not defined and the condition is tested by a separate compare	     insn.  This is because the code below assumes that the result	     of the compare dies in the following branch.  */	  /* Simplify  test a ~= b		       condjump label1;		       test a == b		       condjump label2;		       jump label3;		       label1:	     rewriting as		       test a ~~= b		       condjump label3		       test a == b		       condjump label2		       label1:	     where ~= is an inequality, e.g. >, and ~~= is the swapped	     inequality, e.g. <.	     We recognize this case scanning backwards.	     TEMP is the conditional jump to `label2';	     TEMP1 is the test for `a == b';	     TEMP2 is the conditional jump to `label1';	     TEMP3 is the test for `a ~= b'.  */	  else if (this_is_simplejump		   && (temp = prev_active_insn (insn))		   && no_labels_between_p (temp, insn)		   && condjump_p (temp)		   && (temp1 = prev_active_insn (temp))		   && no_labels_between_p (temp1, temp)		   && GET_CODE (temp1) == INSN		   && GET_CODE (PATTERN (temp1)) == SET#ifdef HAVE_cc0		   && sets_cc0_p (PATTERN (temp1)) == 1#else		   && GET_CODE (SET_SRC (PATTERN (temp1))) == COMPARE		   && GET_CODE (SET_DEST (PATTERN (temp1))) == REG		   && (temp == find_next_ref (SET_DEST (PATTERN (temp1)), temp1))#endif		   && (temp2 = prev_active_insn (temp1))		   && no_labels_between_p (temp2, temp1)		   && condjump_p (temp2)		   && JUMP_LABEL (temp2) == next_nonnote_insn (NEXT_INSN (insn))		   && (temp3 = prev_active_insn (temp2))		   && no_labels_between_p (temp3, temp2)		   && GET_CODE (PATTERN (temp3)) == SET		   && rtx_equal_p (SET_DEST (PATTERN (temp3)),				   SET_DEST (PATTERN (temp1)))		   && rtx_equal_p (SET_SRC (PATTERN (temp1)),				   SET_SRC (PATTERN (temp3)))		   && ! inequality_comparisons_p (PATTERN (temp))		   && inequality_comparisons_p (PATTERN (temp2)))	    {	      rtx fallthrough_label = JUMP_LABEL (temp2);	      ++LABEL_NUSES (fallthrough_label);	      if (swap_jump (temp2, JUMP_LABEL (insn)))		{		  delete_insn (insn);		  changed = 1;		}	      if (--LABEL_NUSES (fallthrough_label) == 0)		delete_insn (fallthrough_label);	    }#endif	  /* Simplify  if (...) {... x = 1;} if (x) ...	     We recognize this case backwards.	     TEMP is the test of `x';	     TEMP1 is the assignment to `x' at the end of the	     previous statement.  */	  /* @@ This should call get_condition to find the values being	     compared, instead of looking for a COMPARE insn when HAVE_cc0	     is not defined.  This would allow it to work on the m88k.  */	  /* @@ This optimization is only safe before cse is run if HAVE_cc0	     is not defined and the condition is tested by a separate compare	     insn.  This is because the code below assumes that the result	     of the compare dies in the following branch.  */	  /* ??? This has to be turned off.  The problem is that the	     unconditional jump might indirectly end up branching to the	     label between TEMP1 and TEMP.  We can't detect this, in general,	     since it may become a jump to there after further optimizations.	     If that jump is done, it will be deleted, so we will retry	     this optimization in the next pass, thus an infinite loop.	     The present code prevents this by putting the jump after the	     label, but this is not logically correct.  */#if 0	  else if (this_is_condjump		   /* Safe to skip USE and CLOBBER insns here		      since they will not be deleted.  */		   && (temp = prev_active_insn (insn))		   && no_labels_between_p (temp, insn)		   && GET_CODE (temp) == INSN		   && GET_CODE (PATTERN (temp)) == SET#ifdef HAVE_cc0		   && sets_cc0_p (PATTERN (temp)) == 1		   && GET_CODE (SET_SRC (PATTERN (temp))) == REG#else		   /* Temp must be a compare insn, we can not accept a register		      to register move here, since it may not be simply a		      tst insn.  */		   && GET_CODE (SET_SRC (PATTERN (temp))) == COMPARE		   && XEXP (SET_SRC (PATTERN (temp)), 1) == const0_rtx		   && GET_CODE (XEXP (SET_SRC (PATTERN (temp)), 0)) == REG		   && GET_CODE (SET_DEST (PATTERN (temp))) == REG		   && insn == find_next_ref (SET_DEST (PATTERN (temp)), temp)#endif		   /* May skip USE or CLOBBER insns here		      for checking for opportunity, since we		      take care of them later.  */		   && (temp1 = prev_active_insn (temp))		   && GET_CODE (temp1) == INSN		   && GET_CODE (PATTERN (temp1)) == SET#ifdef HAVE_cc0		   && SET_SRC (PATTERN (temp)) == SET_DEST (PATTERN (temp1))#else		   && (XEXP (SET_SRC (PATTERN (temp)), 0)		       == SET_DEST (PATTERN (temp1)))#endif		   && CONSTANT_P (SET_SRC (PATTERN (temp1)))		   /* If this isn't true, cse will do the job.  */		   && ! no_labels_between_p (temp1, temp))	    {	      /* Get the if_then_else from the condjump.  */	      rtx choice = SET_SRC (PATTERN (insn));	      if (GET_CODE (choice) == IF_THEN_ELSE		  && (GET_CODE (XEXP (choice, 0)) == EQ		      || GET_CODE (XEXP (choice, 0)) == NE))		{		  int want_nonzero = (GET_CODE (XEXP (choice, 0)) == NE);		  rtx last_insn;		  rtx ultimate;		  rtx p;		  /* Get the place that condjump will jump to		     if it is reached from here.  */		  if ((SET_SRC (PATTERN (temp1)) != const0_rtx)		      == want_nonzero)		    ultimate = XEXP (choice, 1);		  else		    ultimate = XEXP (choice, 2);		  /* Get it as a CODE_LABEL.  */		  if (ultimate == pc_rtx)		    ultimate = get_label_after (insn);		  else		    /* Get the label out of the LABEL_REF.  */		    ultimate = XEXP (ultimate, 0);		  /* Insert the jump immediately before TEMP, specifically		     after the label that is between TEMP1 and TEMP.  */		  last_insn = PREV_INSN (temp);		  /* If we would be branching to the next insn, the jump		     would immediately be deleted and the re-inserted in		     a subsequent pass over the code.  So don't do anything		     in that case.  */		  if (next_active_insn (last_insn)		      != next_active_insn (ultimate))		    {		      emit_barrier_after (last_insn);		      p = emit_jump_insn_after (gen_jump (ultimate),						last_insn);		      JUMP_LABEL (p) = ultimate;		      ++LABEL_NUSES (ultimate);		      if (INSN_UID (ultimate) < max_jump_chain			  && INSN_CODE (p) < max_jump_chain)			{			  jump_chain[INSN_UID (p)]			    = jump_chain[INSN_UID (ultimate)];			  jump_chain[INSN_UID (ultimate)] = p;			}		      changed = 1;		      continue;		    }		}	    }#endif	  /* Detect a conditional jump going to the same place	     as an immediately following unconditional jump.  */	  else if (this_is_condjump		   && (temp = next_active_insn (insn)) != 0		   && simplejump_p (temp)		   && (next_active_insn (JUMP_LABEL (insn))		       == next_active_insn (JUMP_LABEL (temp))))	    {	      rtx tem = temp;	      /* ??? Optional.  Disables some optimizations, but makes		 gcov output more accurate with -O.  */	      if (flag_test_coverage && !reload_completed)		for (tem = insn; tem != temp; tem = NEXT_INSN (tem))		  if (GET_CODE (tem) == NOTE && NOTE_LINE_NUMBER (tem) > 0)		    break;	      if (tem == temp)		{		  delete_jump (insn);		  changed = 1;		  continue;		}	    }#ifdef HAVE_trap	  /* Detect a conditional jump jumping over an unconditional trap.  */	  else if (HAVE_trap		   && this_is_condjump && ! this_is_simplejump		   && reallabelprev != 0		   && GET_CODE (reallabelprev) == INSN		   && GET_CODE (PATTERN (reallabelprev)) == TRAP_IF		   && TRAP_CONDITION (PATTERN (reallabelprev)) == const_true_rtx		   && prev_active_insn (reallabelprev) == insn		   && no_labels_between_p (insn, reallabelprev)		   && (temp2 = get_condition (insn, &temp4))		   && can_reverse_comparison_p (temp2, insn))	    {	      rtx new = gen_cond_trap (reverse_condition (GET_CODE (temp2)),				       XEXP (temp2, 0), XEXP (temp2, 1),				       TRAP_CODE (PATTERN (reallabelprev)));	      if (new)		{		  emit_insn_before (new, temp4);		  delete_insn (reallabelprev);		  delete_jump (insn);		  changed = 1;		  continue;		}	    }	  /* Detect a jump jumping to an unconditional trap.  */	  else if (HAVE_trap && this_is_condjump		   && (temp = next_active_insn (JUMP_LABEL (insn)))		   && GET_CODE (temp) == INSN		   && GET_CODE (PATTERN (temp)) == TRAP_IF		   && (this_is_simplejump		       || (temp2 = get_condition (insn, &temp4))))	    {	      rtx tc = TRAP_CONDITION (PATTERN (temp));	      if (tc == const_true_rtx		  || (! this_is_simplejump && rtx_equal_p (temp2, tc)))		{		  rtx new;		  /* Replace an unconditional jump to a trap with a trap.  */		  if (this_is_simplejump)		    {		      emit_barrier_after (emit_insn_before (gen_trap (), insn));		      delete_jump (insn);		      changed = 1;		      continue;		    }		  new = gen_cond_trap (GET_CODE (temp2), XEXP (temp2, 0),				       XEXP (temp2, 1),				       TRAP_CODE (PATTERN (temp)));		  if (new)		    {		      emit_insn_before (new, temp4);		      delete_jump (insn);		      changed = 1;		      continue;		    }		}	      /* If the trap condition and jump condition are mutually		 exclusive, redirect the jump to the following insn.  */	      else if (GET_RTX_CLASS (GET_CODE (tc)) == '<'		       && ! this_is_simplejump		       && swap_condition (GET_CODE (temp2)) == GET_CODE (tc)		       && rtx_equal_p (XEXP (tc, 0), XEXP (temp2, 0))		       && rtx_equal_p (XEXP (tc, 1), XEXP (temp2, 1))		       && redirect_jump (insn, get_label_after (temp)))		{		  changed = 1;		  continue;		}	    }#endif	  /* Detect a conditional jump jumping over an unconditional jump.  */	  else if ((this_is_condjump || this_is_condjump_in_parallel)		   && ! this_is_simplejump		   && reallabelprev != 0		   && GET_CODE (reallabelprev) == JUMP_INSN		   && prev_active_insn (reallabelprev) == insn		   && no_labels_between_p (insn, reallabelprev)		   && simplejump_p (reallabelprev))	    {	      /* When we invert the unconditional jump, we will be		 decrementing the usage count of its old label.		 Make sure that we don't delete it now because that		 might cause the following code to be deleted.  */	      rtx prev_uses = prev_nonnote_insn (reallabelprev);	      rtx prev_label = JUMP_LABEL (insn);	      if (prev_label)		++LABEL_NUSES (prev_label);	      if (invert_jump (insn, JUMP_LABEL (reallabelprev)))		{		  /* It is very likely that if there are USE insns before		     this jump, they hold REG_DEAD notes.  These REG_DEAD		     notes are no longer valid due to this optimization,		     and will cause the life-analysis that following passes		     (notably delayed-branch scheduling) to think that		     these registers are dead when they are not.		     To prevent this trouble, we just remove the USE insns		     from the insn chain.  */		  while (prev_uses && GET_CODE (prev_uses) == INSN			 && GET_CODE (PATTERN (prev_uses)) == USE)		    {		      rtx useless = prev_uses;		      prev_uses = prev_nonnote_insn (prev_uses);		      delete_insn (useless);		    }		  delete_insn (reallabelprev);		  next = insn;		  changed = 1;		}	      /* We can now safely delete the label if it is unreferenced		 since the delete_insn above has deleted the BARRIER.  */	      if (prev_label && --LABEL_NUSES (prev_label) == 0)		delete_insn (prev_label);	      continue;	    }	  else	    {	      /* Detect a jump to a jump.  */	      nlabel = follow_jumps (JUMP_LABEL (insn));	      if (nlabel != JUMP_LABEL (insn)		  && redirect_jump (insn, nlabel))		{		  changed = 1;		  next = insn;		}	      /* Look for   if (foo) bar; else break;  */	      /* The insns look like this:		 insn = condjump label1;		 ...range1 (some insns)...		 jump label2;		 label1:		 ...range2 (some insns)...		 jump somewhere unconditionally		 label2:  */	      {		rtx label1 = next_label (insn);		rtx range1end = label1 ? prev_active_insn (label1) : 0;		/* Don't do this optimization on the first round, so that		   jump-around-a-jump gets simplified before we ask here		   whether a jump is unconditional.		   Also don't do it when we are called after reload since		   it will confuse reorg.  */		if (! first		    && (reload_completed ? ! flag_delayed_branch : 1)		    /* Make sure INSN is something we can invert.  */		    && condjump_p (insn)		    && label1 != 0		    && JUMP_LABEL (insn) == label1		    && LABEL_NUSES (label1) == 1		    && GET_CODE (range1end) == JUMP_INSN		    && simplejump_p (range1end))		  {		    rtx label2 = next_label (label1);		    rtx range2end = label2 ? prev_active_insn (label2) : 0;		    if (range1end != range2end			&& JUMP_LABEL (range1end) == label2			&& GET_CODE (range2end) == JUMP_INSN			&& GET_CODE (NEXT_INSN (range2end)) == BARRIER			/* Invert the jump condition, so we			   still execute the same insns in each case.  */			&& invert_jump (insn, label1))		      {			rtx range1beg = next_active_insn (insn);			rtx range2beg = next_active_insn (label1);			rtx range1after, range2after;			rtx range1before, range2before;			rtx rangenext;			/* Include in each range any notes before it, to be			   sure that we get the line number note if any, even			   if there are other notes here.  */			while (PREV_INSN (range1beg)			       && GET_CODE (PREV_INSN (range1beg)) == NOTE)			  range1beg = PREV_INSN (range1beg);			while (PREV_INSN (range2beg)			       && GET_CODE (PREV_INSN (range2beg)) == NOTE)			  range2beg = PREV_INSN (range2beg);			/* Don't move NOTEs for blocks or loops; shift them			   outside the ranges, where they'll stay put.  */			range1beg = squeeze_notes (range1beg, range1end);			range2beg = squeeze_notes (range2beg, range2end);			/* Get current surrounds of the 2 ranges.  */			range1before = PREV_INSN (range1beg);			range2before = PREV_INSN (range2beg);			range1after = NEXT_INSN (range1end);			range2after = NEXT_INSN (range2end);			/* Splice range2 where range1 was.  */			NEXT_INSN (range1before) = range2beg;			PREV_INSN (range2beg) = range1before;			NEXT_INSN (range2end) = range1after;			PREV_INSN (range1after) = range2end;			/* Splice range1 where range2 was.  */			NEXT_INSN (range2before) = range1beg;			PREV_INSN (range1beg) = range2before;			NEXT_INSN (range1end) = range2after;			PREV_INSN (range2after) = range1end;			/* Check for a loop end note between the end of			   range2, and the next code label.  If there is one,			   then what we have really seen is			   if (foo) break; end_of_loop;			   and moved the break sequence outside the loop.			   We must move the LOOP_END note to where the			   loop really ends now, or we will confuse loop			   optimization.  Stop if we find a LOOP_BEG note			   first, since we don't want to move the LOOP_END			   note in that case.  */			for (;range2after != label2; range2after = rangenext)			  {			    rangenext = NEXT_INSN (range2after);			    if (GET_CODE (range2after) == NOTE)			      {				if (NOTE_LINE_NUMBER (range2after)				    == NOTE_INSN_LOOP_END)				  {				    NEXT_INSN (PREV_INSN (range2after))				      = rangenext;				    PREV_INSN (rangenext)				      = PREV_INSN (range2after);				    PREV_INSN (range2after) 				      = PREV_INSN (range1beg);				    NEXT_INSN (range2after) = range1beg;				    NEXT_INSN (PREV_INSN (range1beg))				      = range2after;				    PREV_INSN (range1beg) = range2after;				  }				else if (NOTE_LINE_NUMBER (range2after)					 == NOTE_INSN_LOOP_BEG)				  break;			      }			  }			changed = 1;			continue;		      }		  }	      }	      /* Now that the jump has been tensioned,		 try cross jumping: check for identical code		 before the jump and before its target label.  */	      /* First, cross jumping of conditional jumps:  */	      if (cross_jump && condjump_p (insn))		{		  rtx newjpos, newlpos;		  rtx x = prev_real_insn (JUMP_LABEL (insn));		  /* A conditional jump may be crossjumped		     only if the place it jumps to follows		     an opposing jump that comes back here.  */		  if (x != 0 && ! jump_back_p (x, insn))		    /* We have no opposing jump;		       cannot cross jump this insn.  */		    x = 0;		  newjpos = 0;		  /* TARGET is nonzero if it is ok to cross jump		     to code before TARGET.  If so, see if matches.  */		  if (x != 0)		    find_cross_jump (insn, x, 2,				     &newjpos, &newlpos);		  if (newjpos != 0)		    {		      do_cross_jump (insn, newjpos, newlpos);		      /* Make the old conditional jump			 into an unconditional one.  */		      SET_SRC (PATTERN (insn))			= gen_rtx_LABEL_REF (VOIDmode, JUMP_LABEL (insn));		      INSN_CODE (insn) = -1;		      emit_barrier_after (insn);		      /* Add to jump_chain unless this is a new label			 whose UID is too large.  */		      if (INSN_UID (JUMP_LABEL (insn)) < max_jump_chain)			{			  jump_chain[INSN_UID (insn)]			    = jump_chain[INSN_UID (JUMP_LABEL (insn))];			  jump_chain[INSN_UID (JUMP_LABEL (insn))] = insn;			}		      changed = 1;		      next = insn;		    }		}	      /* Cross jumping of unconditional jumps:		 a few differences.  */	      if (cross_jump && simplejump_p (insn))		{		  rtx newjpos, newlpos;		  rtx target;		  newjpos = 0;		  /* TARGET is nonzero if it is ok to cross jump		     to code before TARGET.  If so, see if matches.  */		  find_cross_jump (insn, JUMP_LABEL (insn), 1,				   &newjpos, &newlpos);		  /* If cannot cross jump to code before the label,		     see if we can cross jump to another jump to		     the same label.  */		  /* Try each other jump to this label.  */		  if (INSN_UID (JUMP_LABEL (insn)) < max_uid)		    for (target = jump_chain[INSN_UID (JUMP_LABEL (insn))];			 target != 0 && newjpos == 0;			 target = jump_chain[INSN_UID (target)])		      if (target != insn			  && JUMP_LABEL (target) == JUMP_LABEL (insn)			  /* Ignore TARGET if it's deleted.  */			  && ! INSN_DELETED_P (target))			find_cross_jump (insn, target, 2,					 &newjpos, &newlpos);		  if (newjpos != 0)		    {		      do_cross_jump (insn, newjpos, newlpos);		      changed = 1;		      next = insn;		    }		}	      /* This code was dead in the previous jump.c!  */	      if (cross_jump && GET_CODE (PATTERN (insn)) == RETURN)		{		  /* Return insns all "jump to the same place"		     so we can cross-jump between any two of them.  */		  rtx newjpos, newlpos, target;		  newjpos = 0;		  /* If cannot cross jump to code before the label,		     see if we can cross jump to another jump to		     the same label.  */		  /* Try each other jump to this label.  */		  for (target = jump_chain[0];		       target != 0 && newjpos == 0;		       target = jump_chain[INSN_UID (target)])		    if (target != insn			&& ! INSN_DELETED_P (target)			&& GET_CODE (PATTERN (target)) == RETURN)		      find_cross_jump (insn, target, 2,				       &newjpos, &newlpos);		  if (newjpos != 0)		    {		      do_cross_jump (insn, newjpos, newlpos);		      changed = 1;		      next = insn;		    }		}	    }	}      first = 0;    }  /* Delete extraneous line number notes.     Note that two consecutive notes for different lines are not really     extraneous.  There should be some indication where that line belonged,     even if it became empty.  */  {    rtx last_note = 0;    for (insn = f; insn; insn = NEXT_INSN (insn))      if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) >= 0)	{	  /* Delete this note if it is identical to previous note.  */	  if (last_note	      && NOTE_SOURCE_FILE (insn) == NOTE_SOURCE_FILE (last_note)	      && NOTE_LINE_NUMBER (insn) == NOTE_LINE_NUMBER (last_note))	    {	      delete_insn (insn);	      continue;	    }	  last_note = insn;	}  }#ifdef HAVE_return  if (HAVE_return)    {      /* If we fall through to the epilogue, see if we can insert a RETURN insn	 in front of it.  If the machine allows it at this point (we might be	 after reload for a leaf routine), it will improve optimization for it	 to be there.  We do this both here and at the start of this pass since	 the RETURN might have been deleted by some of our optimizations.  */      insn = get_last_insn ();      while (insn && GET_CODE (insn) == NOTE)	insn = PREV_INSN (insn);      if (insn && GET_CODE (insn) != BARRIER)	{	  emit_jump_insn (gen_return ());	  emit_barrier ();	}    }#endif  can_reach_end = calculate_can_reach_end (last_insn, 0, 1);  /* Show JUMP_CHAIN no longer valid.  */  jump_chain = 0;}