map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j]));
{ map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j])); record_base_value (REGNO (map->reg_map[j]), regno_reg_rtx[j]); }
unroll_loop (loop_end, insn_count, loop_start, end_insert_before,	     strength_reduce_p)     rtx loop_end;     int insn_count;     rtx loop_start;     rtx end_insert_before;     int strength_reduce_p;{  int i, j, temp;  int unroll_number = 1;  rtx copy_start, copy_end;  rtx insn, copy, sequence, pattern, tem;  int max_labelno, max_insnno;  rtx insert_before;  struct inline_remap *map;  char *local_label;  char *local_regno;  int maxregnum;  int new_maxregnum;  rtx exit_label = 0;  rtx start_label;  struct iv_class *bl;  int splitting_not_safe = 0;  enum unroll_types unroll_type;  int loop_preconditioned = 0;  rtx safety_label;  /* This points to the last real insn in the loop, which should be either     a JUMP_INSN (for conditional jumps) or a BARRIER (for unconditional     jumps).  */  rtx last_loop_insn;  /* Don't bother unrolling huge loops.  Since the minimum factor is     two, loops greater than one half of MAX_UNROLLED_INSNS will never     be unrolled.  */  if (insn_count > MAX_UNROLLED_INSNS / 2)    {      if (loop_dump_stream)	fprintf (loop_dump_stream, "Unrolling failure: Loop too big.\n");      return;    }  /* When emitting debugger info, we can't unroll loops with unequal numbers     of block_beg and block_end notes, because that would unbalance the block     structure of the function.  This can happen as a result of the     "if (foo) bar; else break;" optimization in jump.c.  */  if (write_symbols != NO_DEBUG)    {      int block_begins = 0;      int block_ends = 0;      for (insn = loop_start; insn != loop_end; insn = NEXT_INSN (insn))	{	  if (GET_CODE (insn) == NOTE)	    {	      if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG)		block_begins++;	      else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)		block_ends++;	    }	}      if (block_begins != block_ends)	{	  if (loop_dump_stream)	    fprintf (loop_dump_stream,		     "Unrolling failure: Unbalanced block notes.\n");	  return;	}    }  /* Determine type of unroll to perform.  Depends on the number of iterations     and the size of the loop.  */  /* If there is no strength reduce info, then set loop_n_iterations to zero.     This can happen if strength_reduce can't find any bivs in the loop.     A value of zero indicates that the number of iterations could not be     calculated.  */  if (! strength_reduce_p)    loop_n_iterations = 0;  if (loop_dump_stream && loop_n_iterations > 0)    fprintf (loop_dump_stream,	     "Loop unrolling: %d iterations.\n", loop_n_iterations);  /* Find and save a pointer to the last nonnote insn in the loop.  */  last_loop_insn = prev_nonnote_insn (loop_end);  /* Calculate how many times to unroll the loop.  Indicate whether or     not the loop is being completely unrolled.  */  if (loop_n_iterations == 1)    {      /* If number of iterations is exactly 1, then eliminate the compare and	 branch at the end of the loop since they will never be taken.	 Then return, since no other action is needed here.  */      /* If the last instruction is not a BARRIER or a JUMP_INSN, then	 don't do anything.  */      if (GET_CODE (last_loop_insn) == BARRIER)	{	  /* Delete the jump insn.  This will delete the barrier also.  */	  delete_insn (PREV_INSN (last_loop_insn));	}      else if (GET_CODE (last_loop_insn) == JUMP_INSN)	{#ifdef HAVE_cc0	  /* The immediately preceding insn is a compare which must be	     deleted.  */	  delete_insn (last_loop_insn);	  delete_insn (PREV_INSN (last_loop_insn));#else	  /* The immediately preceding insn may not be the compare, so don't	     delete it.  */	  delete_insn (last_loop_insn);#endif	}      return;    }  else if (loop_n_iterations > 0      && loop_n_iterations * insn_count < MAX_UNROLLED_INSNS)    {      unroll_number = loop_n_iterations;      unroll_type = UNROLL_COMPLETELY;    }  else if (loop_n_iterations > 0)    {      /* Try to factor the number of iterations.  Don't bother with the	 general case, only using 2, 3, 5, and 7 will get 75% of all	 numbers theoretically, and almost all in practice.  */      for (i = 0; i < NUM_FACTORS; i++)	factors[i].count = 0;      temp = loop_n_iterations;      for (i = NUM_FACTORS - 1; i >= 0; i--)	while (temp % factors[i].factor == 0)	  {	    factors[i].count++;	    temp = temp / factors[i].factor;	  }      /* Start with the larger factors first so that we generally	 get lots of unrolling.  */      unroll_number = 1;      temp = insn_count;      for (i = 3; i >= 0; i--)	while (factors[i].count--)	  {	    if (temp * factors[i].factor < MAX_UNROLLED_INSNS)	      {		unroll_number *= factors[i].factor;		temp *= factors[i].factor;	      }	    else	      break;	  }      /* If we couldn't find any factors, then unroll as in the normal	 case.  */      if (unroll_number == 1)	{	  if (loop_dump_stream)	    fprintf (loop_dump_stream,		     "Loop unrolling: No factors found.\n");	}      else	unroll_type = UNROLL_MODULO;    }  /* Default case, calculate number of times to unroll loop based on its     size.  */  if (unroll_number == 1)    {      if (8 * insn_count < MAX_UNROLLED_INSNS)	unroll_number = 8;      else if (4 * insn_count < MAX_UNROLLED_INSNS)	unroll_number = 4;      else	unroll_number = 2;      unroll_type = UNROLL_NAIVE;    }  /* Now we know how many times to unroll the loop.  */  if (loop_dump_stream)    fprintf (loop_dump_stream,	     "Unrolling loop %d times.\n", unroll_number);  if (unroll_type == UNROLL_COMPLETELY || unroll_type == UNROLL_MODULO)    {      /* Loops of these types should never start with a jump down to	 the exit condition test.  For now, check for this case just to	 be sure.  UNROLL_NAIVE loops can be of this form, this case is	 handled below.  */      insn = loop_start;      while (GET_CODE (insn) != CODE_LABEL && GET_CODE (insn) != JUMP_INSN)	insn = NEXT_INSN (insn);      if (GET_CODE (insn) == JUMP_INSN)	abort ();    }  if (unroll_type == UNROLL_COMPLETELY)    {      /* Completely unrolling the loop:  Delete the compare and branch at	 the end (the last two instructions).   This delete must done at the	 very end of loop unrolling, to avoid problems with calls to	 back_branch_in_range_p, which is called by find_splittable_regs.	 All increments of splittable bivs/givs are changed to load constant	 instructions.  */      copy_start = loop_start;      /* Set insert_before to the instruction immediately after the JUMP_INSN	 (or BARRIER), so that any NOTEs between the JUMP_INSN and the end of	 the loop will be correctly handled by copy_loop_body.  */      insert_before = NEXT_INSN (last_loop_insn);      /* Set copy_end to the insn before the jump at the end of the loop.  */      if (GET_CODE (last_loop_insn) == BARRIER)	copy_end = PREV_INSN (PREV_INSN (last_loop_insn));      else if (GET_CODE (last_loop_insn) == JUMP_INSN)	{#ifdef HAVE_cc0	  /* The instruction immediately before the JUMP_INSN is a compare	     instruction which we do not want to copy.  */	  copy_end = PREV_INSN (PREV_INSN (last_loop_insn));#else	  /* The instruction immediately before the JUMP_INSN may not be the	     compare, so we must copy it.  */	  copy_end = PREV_INSN (last_loop_insn);#endif	}      else	{	  /* We currently can't unroll a loop if it doesn't end with a	     JUMP_INSN.  There would need to be a mechanism that recognizes	     this case, and then inserts a jump after each loop body, which	     jumps to after the last loop body.  */	  if (loop_dump_stream)	    fprintf (loop_dump_stream,		     "Unrolling failure: loop does not end with a JUMP_INSN.\n");	  return;	}    }  else if (unroll_type == UNROLL_MODULO)    {      /* Partially unrolling the loop:  The compare and branch at the end	 (the last two instructions) must remain.  Don't copy the compare	 and branch instructions at the end of the loop.  Insert the unrolled	 code immediately before the compare/branch at the end so that the	 code will fall through to them as before.  */      copy_start = loop_start;      /* Set insert_before to the jump insn at the end of the loop.	 Set copy_end to before the jump insn at the end of the loop.  */      if (GET_CODE (last_loop_insn) == BARRIER)	{	  insert_before = PREV_INSN (last_loop_insn);	  copy_end = PREV_INSN (insert_before);	}      else if (GET_CODE (last_loop_insn) == JUMP_INSN)	{#ifdef HAVE_cc0	  /* The instruction immediately before the JUMP_INSN is a compare	     instruction which we do not want to copy or delete.  */	  insert_before = PREV_INSN (last_loop_insn);	  copy_end = PREV_INSN (insert_before);#else	  /* The instruction immediately before the JUMP_INSN may not be the	     compare, so we must copy it.  */	  insert_before = last_loop_insn;	  copy_end = PREV_INSN (last_loop_insn);#endif	}      else	{	  /* We currently can't unroll a loop if it doesn't end with a	     JUMP_INSN.  There would need to be a mechanism that recognizes	     this case, and then inserts a jump after each loop body, which	     jumps to after the last loop body.  */	  if (loop_dump_stream)	    fprintf (loop_dump_stream,		     "Unrolling failure: loop does not end with a JUMP_INSN.\n");	  return;	}    }  else    {      /* Normal case: Must copy the compare and branch instructions at the	 end of the loop.  */      if (GET_CODE (last_loop_insn) == BARRIER)	{	  /* Loop ends with an unconditional jump and a barrier.	     Handle this like above, don't copy jump and barrier.	     This is not strictly necessary, but doing so prevents generating	     unconditional jumps to an immediately following label.	     This will be corrected below if the target of this jump is	     not the start_label.  */	  insert_before = PREV_INSN (last_loop_insn);	  copy_end = PREV_INSN (insert_before);	}      else if (GET_CODE (last_loop_insn) == JUMP_INSN)	{	  /* Set insert_before to immediately after the JUMP_INSN, so that	     NOTEs at the end of the loop will be correctly handled by	     copy_loop_body.  */	  insert_before = NEXT_INSN (last_loop_insn);	  copy_end = last_loop_insn;	}      else	{	  /* We currently can't unroll a loop if it doesn't end with a	     JUMP_INSN.  There would need to be a mechanism that recognizes	     this case, and then inserts a jump after each loop body, which	     jumps to after the last loop body.  */	  if (loop_dump_stream)	    fprintf (loop_dump_stream,		     "Unrolling failure: loop does not end with a JUMP_INSN.\n");	  return;	}      /* If copying exit test branches because they can not be eliminated,	 then must convert the fall through case of the branch to a jump past	 the end of the loop.  Create a label to emit after the loop and save	 it for later use.  Do not use the label after the loop, if any, since	 it might be used by insns outside the loop, or there might be insns	 added before it later by final_[bg]iv_value which must be after	 the real exit label.  */      exit_label = gen_label_rtx ();      insn = loop_start;      while (GET_CODE (insn) != CODE_LABEL && GET_CODE (insn) != JUMP_INSN)	insn = NEXT_INSN (insn);      if (GET_CODE (insn) == JUMP_INSN)	{	  /* The loop starts with a jump down to the exit condition test.	     Start copying the loop after the barrier following this	     jump insn.  */	  copy_start = NEXT_INSN (insn);	  /* Splitting induction variables doesn't work when the loop is	     entered via a jump to the bottom, because then we end up doing	     a comparison against a new register for a split variable, but	     we did not execute the set insn for the new register because	     it was skipped over.  */	  splitting_not_safe = 1;	  if (loop_dump_stream)	    fprintf (loop_dump_stream,		     "Splitting not safe, because loop not entered at top.\n");	}      else	copy_start = loop_start;    }  /* This should always be the first label in the loop.  */  start_label = NEXT_INSN (copy_start);  /* There may be a line number note and/or a loop continue note here.  */  while (GET_CODE (start_label) == NOTE)    start_label = NEXT_INSN (start_label);  if (GET_CODE (start_label) != CODE_LABEL)    {      /* This can happen as a result of jump threading.  If the first insns in	 the loop test the same condition as the loop's backward jump, or the	 opposite condition, then the backward jump will be modified to point	 to elsewhere, and the loop's start label is deleted.	 This case currently can not be handled by the loop unrolling code.  */      if (loop_dump_stream)	fprintf (loop_dump_stream,		 "Unrolling failure: unknown insns between BEG note and loop label.\n");      return;    }  if (LABEL_NAME (start_label))    {      /* The jump optimization pass must have combined the original start label	 with a named label for a goto.  We can't unroll this case because	 jumps which go to the named label must be handled differently than	 jumps to the loop start, and it is impossible to differentiate them	 in this case.  */      if (loop_dump_stream)	fprintf (loop_dump_stream,		 "Unrolling failure: loop start label is gone\n");      return;    }  if (unroll_type == UNROLL_NAIVE      && GET_CODE (last_loop_insn) == BARRIER      && start_label != JUMP_LABEL (PREV_INSN (last_loop_insn)))    {      /* In this case, we must copy the jump and barrier, because they will	 not be converted to jumps to an immediately following label.  */      insert_before = NEXT_INSN (last_loop_insn);      copy_end = last_loop_insn;    }  /* Allocate a translation table for the labels and insn numbers.     They will be filled in as we copy the insns in the loop.  */  max_labelno = max_label_num ();  max_insnno = get_max_uid ();  map = (struct inline_remap *) alloca (sizeof (struct inline_remap));  map->integrating = 0;  /* Allocate the label map.  */  if (max_labelno > 0)    {      map->label_map = (rtx *) alloca (max_labelno * sizeof (rtx));      local_label = (char *) alloca (max_labelno);      bzero (local_label, max_labelno);    }  else    map->label_map = 0;  /* Search the loop and mark all local labels, i.e. the ones which have to     be distinct labels when copied.  For all labels which might be     non-local, set their label_map entries to point to themselves.     If they happen to be local their label_map entries will be overwritten     before the loop body is copied.  The label_map entries for local labels     will be set to a different value each time the loop body is copied.  */  for (insn = copy_start; insn != loop_end; insn = NEXT_INSN (insn))    {      if (GET_CODE (insn) == CODE_LABEL)	local_label[CODE_LABEL_NUMBER (insn)] = 1;      else if (GET_CODE (insn) == JUMP_INSN)	{	  if (JUMP_LABEL (insn))	    map->label_map[CODE_LABEL_NUMBER (JUMP_LABEL (insn))]	      = JUMP_LABEL (insn);	  else if (GET_CODE (PATTERN (insn)) == ADDR_VEC		   || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)	    {	      rtx pat = PATTERN (insn);	      int diff_vec_p = GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC;	      int len = XVECLEN (pat, diff_vec_p);	      rtx label;	      for (i = 0; i < len; i++)		{		  label = XEXP (XVECEXP (pat, diff_vec_p, i), 0);		  map->label_map[CODE_LABEL_NUMBER (label)] = label;		}	    }	}    }  /* Allocate space for the insn map.  */  map->insn_map = (rtx *) alloca (max_insnno * sizeof (rtx));  /* Set this to zero, to indicate that we are doing loop unrolling,     not function inlining.  */  map->inline_target = 0;  /* The register and constant maps depend on the number of registers     present, so the final maps can't be created until after     find_splittable_regs is called.  However, they are needed for     preconditioning, so we create temporary maps when preconditioning     is performed.  */  /* The preconditioning code may allocate two new pseudo registers.  */  maxregnum = max_reg_num ();  /* Allocate and zero out the splittable_regs and addr_combined_regs     arrays.  These must be zeroed here because they will be used if     loop preconditioning is performed, and must be zero for that case.     It is safe to do this here, since the extra registers created by the     preconditioning code and find_splittable_regs will never be used     to access the splittable_regs[] and addr_combined_regs[] arrays.  */  splittable_regs = (rtx *) alloca (maxregnum * sizeof (rtx));  bzero ((char *) splittable_regs, maxregnum * sizeof (rtx));  splittable_regs_updates = (int *) alloca (maxregnum * sizeof (int));  bzero ((char *) splittable_regs_updates, maxregnum * sizeof (int));  addr_combined_regs    = (struct induction **) alloca (maxregnum * sizeof (struct induction *));  bzero ((char *) addr_combined_regs, maxregnum * sizeof (struct induction *));  /* We must limit it to max_reg_before_loop, because only these pseudo     registers have valid regno_first_uid info.  Any register created after     that is unlikely to be local to the loop anyways.  */  local_regno = (char *) alloca (max_reg_before_loop);  bzero (local_regno, max_reg_before_loop);  /* Mark all local registers, i.e. the ones which are referenced only     inside the loop.  */  if (INSN_UID (copy_end) < max_uid_for_loop)  {    int copy_start_luid = INSN_LUID (copy_start);    int copy_end_luid = INSN_LUID (copy_end);    /* If a register is used in the jump insn, we must not duplicate it       since it will also be used outside the loop.  */    if (GET_CODE (copy_end) == JUMP_INSN)      copy_end_luid--;    /* If copy_start points to the NOTE that starts the loop, then we must       use the next luid, because invariant pseudo-regs moved out of the loop       have their lifetimes modified to start here, but they are not safe       to duplicate.  */    if (copy_start == loop_start)      copy_start_luid++;    for (j = FIRST_PSEUDO_REGISTER; j < max_reg_before_loop; ++j)      if (regno_first_uid[j] > 0 && regno_first_uid[j] <= max_uid_for_loop	  && uid_luid[regno_first_uid[j]] >= copy_start_luid	  && regno_last_uid[j] > 0 && regno_last_uid[j] <= max_uid_for_loop	  && uid_luid[regno_last_uid[j]] <= copy_end_luid)	local_regno[j] = 1;  }  /* If this loop requires exit tests when unrolled, check to see if we     can precondition the loop so as to make the exit tests unnecessary.     Just like variable splitting, this is not safe if the loop is entered     via a jump to the bottom.  Also, can not do this if no strength     reduce info, because precondition_loop_p uses this info.  */  /* Must copy the loop body for preconditioning before the following     find_splittable_regs call since that will emit insns which need to     be after the preconditioned loop copies, but immediately before the     unrolled loop copies.  */  /* Also, it is not safe to split induction variables for the preconditioned     copies of the loop body.  If we split induction variables, then the code     assumes that each induction variable can be represented as a function     of its initial value and the loop iteration number.  This is not true     in this case, because the last preconditioned copy of the loop body     could be any iteration from the first up to the `unroll_number-1'th,     depending on the initial value of the iteration variable.  Therefore     we can not split induction variables here, because we can not calculate     their value.  Hence, this code must occur before find_splittable_regs     is called.  */  if (unroll_type == UNROLL_NAIVE && ! splitting_not_safe && strength_reduce_p)    {      rtx initial_value, final_value, increment;      if (precondition_loop_p (&initial_value, &final_value, &increment,			       loop_start, loop_end))	{	  register rtx diff, temp;	  enum machine_mode mode;	  rtx *labels;	  int abs_inc, neg_inc;	  map->reg_map = (rtx *) alloca (maxregnum * sizeof (rtx));	  map->const_equiv_map = (rtx *) alloca (maxregnum * sizeof (rtx));	  map->const_age_map = (unsigned *) alloca (maxregnum						    * sizeof (unsigned));	  map->const_equiv_map_size = maxregnum;	  global_const_equiv_map = map->const_equiv_map;	  global_const_equiv_map_size = maxregnum;	  init_reg_map (map, maxregnum);	  /* Limit loop unrolling to 4, since this will make 7 copies of	     the loop body.  */	  if (unroll_number > 4)	    unroll_number = 4;	  /* Save the absolute value of the increment, and also whether or	     not it is negative.  */	  neg_inc = 0;	  abs_inc = INTVAL (increment);	  if (abs_inc < 0)	    {	      abs_inc = - abs_inc;	      neg_inc = 1;	    }	  start_sequence ();	  /* Decide what mode to do these calculations in.  Choose the larger	     of final_value's mode and initial_value's mode, or a full-word if	     both are constants.  */	  mode = GET_MODE (final_value);	  if (mode == VOIDmode)	    {	      mode = GET_MODE (initial_value);	      if (mode == VOIDmode)		mode = word_mode;	    }	  else if (mode != GET_MODE (initial_value)		   && (GET_MODE_SIZE (mode)		       < GET_MODE_SIZE (GET_MODE (initial_value))))	    mode = GET_MODE (initial_value);	  /* Calculate the difference between the final and initial values.	     Final value may be a (plus (reg x) (const_int 1)) rtx.	     Let the following cse pass simplify this if initial value is	     a constant. 	     We must copy the final and initial values here to avoid	     improperly shared rtl.  */	  diff = expand_binop (mode, sub_optab, copy_rtx (final_value),			       copy_rtx (initial_value), NULL_RTX, 0,			       OPTAB_LIB_WIDEN);	  /* Now calculate (diff % (unroll * abs (increment))) by using an	     and instruction.  */	  diff = expand_binop (GET_MODE (diff), and_optab, diff,			       GEN_INT (unroll_number * abs_inc - 1),			       NULL_RTX, 0, OPTAB_LIB_WIDEN);	  /* Now emit a sequence of branches to jump to the proper precond	     loop entry point.  */	  labels = (rtx *) alloca (sizeof (rtx) * unroll_number);	  for (i = 0; i < unroll_number; i++)	    labels[i] = gen_label_rtx ();	  /* Check for the case where the initial value is greater than or equal	     to the final value.  In that case, we want to execute exactly	     one loop iteration.  The code below will fail for this case.  */	  emit_cmp_insn (initial_value, final_value, neg_inc ? LE : GE,			 NULL_RTX, mode, 0, 0);	  if (neg_inc)	    emit_jump_insn (gen_ble (labels[1]));	  else	    emit_jump_insn (gen_bge (labels[1]));	  JUMP_LABEL (get_last_insn ()) = labels[1];	  LABEL_NUSES (labels[1])++;	  /* Assuming the unroll_number is 4, and the increment is 2, then	     for a negative increment:	for a positive increment:	     diff = 0,1   precond 0	diff = 0,7   precond 0	     diff = 2,3   precond 3     diff = 1,2   precond 1	     diff = 4,5   precond 2     diff = 3,4   precond 2	     diff = 6,7   precond 1     diff = 5,6   precond 3  */	  /* We only need to emit (unroll_number - 1) branches here, the	     last case just falls through to the following code.  */	  /* ??? This would give better code if we emitted a tree of branches	     instead of the current linear list of branches.  */	  for (i = 0; i < unroll_number - 1; i++)	    {	      int cmp_const;	      enum rtx_code cmp_code;	      /* For negative increments, must invert the constant compared		 against, except when comparing against zero.  */	      if (i == 0)		{		  cmp_const = 0;		  cmp_code = EQ;		}	      else if (neg_inc)		{		  cmp_const = unroll_number - i;		  cmp_code = GE;		}	      else		{		  cmp_const = i;		  cmp_code = LE;		}	      emit_cmp_insn (diff, GEN_INT (abs_inc * cmp_const),			     cmp_code, NULL_RTX, mode, 0, 0);	      if (i == 0)		emit_jump_insn (gen_beq (labels[i]));	      else if (neg_inc)		emit_jump_insn (gen_bge (labels[i]));	      else		emit_jump_insn (gen_ble (labels[i]));	      JUMP_LABEL (get_last_insn ()) = labels[i];	      LABEL_NUSES (labels[i])++;	    }	  /* If the increment is greater than one, then we need another branch,	     to handle other cases equivalent to 0.  */	  /* ??? This should be merged into the code above somehow to help	     simplify the code here, and reduce the number of branches emitted.	     For the negative increment case, the branch here could easily	     be merged with the `0' case branch above.  For the positive	     increment case, it is not clear how this can be simplified.  */	     	  if (abs_inc != 1)	    {	      int cmp_const;	      enum rtx_code cmp_code;	      if (neg_inc)		{		  cmp_const = abs_inc - 1;		  cmp_code = LE;		}	      else		{		  cmp_const = abs_inc * (unroll_number - 1) + 1;		  cmp_code = GE;		}	      emit_cmp_insn (diff, GEN_INT (cmp_const), cmp_code, NULL_RTX,			     mode, 0, 0);	      if (neg_inc)		emit_jump_insn (gen_ble (labels[0]));	      else		emit_jump_insn (gen_bge (labels[0]));	      JUMP_LABEL (get_last_insn ()) = labels[0];	      LABEL_NUSES (labels[0])++;	    }	  sequence = gen_sequence ();	  end_sequence ();	  emit_insn_before (sequence, loop_start);	  	  /* Only the last copy of the loop body here needs the exit	     test, so set copy_end to exclude the compare/branch here,	     and then reset it inside the loop when get to the last	     copy.  */	  if (GET_CODE (last_loop_insn) == BARRIER)	    copy_end = PREV_INSN (PREV_INSN (last_loop_insn));	  else if (GET_CODE (last_loop_insn) == JUMP_INSN)	    {#ifdef HAVE_cc0	      /* The immediately preceding insn is a compare which we do not		 want to copy.  */	      copy_end = PREV_INSN (PREV_INSN (last_loop_insn));#else	      /* The immediately preceding insn may not be a compare, so we		 must copy it.  */	      copy_end = PREV_INSN (last_loop_insn);#endif	    }	  else	    abort ();	  for (i = 1; i < unroll_number; i++)	    {	      emit_label_after (labels[unroll_number - i],				PREV_INSN (loop_start));	      bzero ((char *) map->insn_map, max_insnno * sizeof (rtx));	      bzero ((char *) map->const_equiv_map, maxregnum * sizeof (rtx));	      bzero ((char *) map->const_age_map,		     maxregnum * sizeof (unsigned));	      map->const_age = 0;	      for (j = 0; j < max_labelno; j++)		if (local_label[j])		  map->label_map[j] = gen_label_rtx ();	      for (j = FIRST_PSEUDO_REGISTER; j < max_reg_before_loop; j++)		if (local_regno[j])		  map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j]));	      /* The last copy needs the compare/branch insns at the end,		 so reset copy_end here if the loop ends with a conditional		 branch.  */	      if (i == unroll_number - 1)		{		  if (GET_CODE (last_loop_insn) == BARRIER)		    copy_end = PREV_INSN (PREV_INSN (last_loop_insn));		  else		    copy_end = last_loop_insn;		}	      /* None of the copies are the `last_iteration', so just		 pass zero for that parameter.  */	      copy_loop_body (copy_start, copy_end, map, exit_label, 0,			      unroll_type, start_label, loop_end,			      loop_start, copy_end);	    }	  emit_label_after (labels[0], PREV_INSN (loop_start));	  if (GET_CODE (last_loop_insn) == BARRIER)	    {	      insert_before = PREV_INSN (last_loop_insn);	      copy_end = PREV_INSN (insert_before);	    }	  else	    {#ifdef HAVE_cc0	      /* The immediately preceding insn is a compare which we do not		 want to copy.  */	      insert_before = PREV_INSN (last_loop_insn);	      copy_end = PREV_INSN (insert_before);#else	      /* The immediately preceding insn may not be a compare, so we		 must copy it.  */	      insert_before = last_loop_insn;	      copy_end = PREV_INSN (last_loop_insn);#endif	    }	  /* Set unroll type to MODULO now.  */	  unroll_type = UNROLL_MODULO;	  loop_preconditioned = 1;	}    }  /* If reach here, and the loop type is UNROLL_NAIVE, then don't unroll     the loop unless all loops are being unrolled.  */  if (unroll_type == UNROLL_NAIVE && ! flag_unroll_all_loops)    {      if (loop_dump_stream)	fprintf (loop_dump_stream, "Unrolling failure: Naive unrolling not being done.\n");      return;    }  /* At this point, we are guaranteed to unroll the loop.  */  /* For each biv and giv, determine whether it can be safely split into     a different variable for each unrolled copy of the loop body.     We precalculate and save this info here, since computing it is     expensive.     Do this before deleting any instructions from the loop, so that     back_branch_in_range_p will work correctly.  */  if (splitting_not_safe)    temp = 0;  else    temp = find_splittable_regs (unroll_type, loop_start, loop_end,				end_insert_before, unroll_number);  /* find_splittable_regs may have created some new registers, so must     reallocate the reg_map with the new larger size, and must realloc     the constant maps also.  */  maxregnum = max_reg_num ();  map->reg_map = (rtx *) alloca (maxregnum * sizeof (rtx));  init_reg_map (map, maxregnum);  /* Space is needed in some of the map for new registers, so new_maxregnum     is an (over)estimate of how many registers will exist at the end.  */  new_maxregnum = maxregnum + (temp * unroll_number * 2);  /* Must realloc space for the constant maps, because the number of registers     may have changed.  */  map->const_equiv_map = (rtx *) alloca (new_maxregnum * sizeof (rtx));  map->const_age_map = (unsigned *) alloca (new_maxregnum * sizeof (unsigned));  map->const_equiv_map_size = new_maxregnum;  global_const_equiv_map = map->const_equiv_map;  global_const_equiv_map_size = new_maxregnum;  /* Search the list of bivs and givs to find ones which need to be remapped     when split, and set their reg_map entry appropriately.  */  for (bl = loop_iv_list; bl; bl = bl->next)    {      if (REGNO (bl->biv->src_reg) != bl->regno)	map->reg_map[bl->regno] = bl->biv->src_reg;#if 0      /* Currently, non-reduced/final-value givs are never split.  */      for (v = bl->giv; v; v = v->next_iv)	if (REGNO (v->src_reg) != bl->regno)	  map->reg_map[REGNO (v->dest_reg)] = v->src_reg;#endif    }  /* If the loop is being partially unrolled, and the iteration variables     are being split, and are being renamed for the split, then must fix up     the compare/jump instruction at the end of the loop to refer to the new     registers.  This compare isn't copied, so the registers used in it     will never be replaced if it isn't done here.  */  if (unroll_type == UNROLL_MODULO)    {      insn = NEXT_INSN (copy_end);      if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN)	PATTERN (insn) = remap_split_bivs (PATTERN (insn));    }  /* For unroll_number - 1 times, make a copy of each instruction     between copy_start and copy_end, and insert these new instructions     before the end of the loop.  */  for (i = 0; i < unroll_number; i++)    {      bzero ((char *) map->insn_map, max_insnno * sizeof (rtx));      bzero ((char *) map->const_equiv_map, new_maxregnum * sizeof (rtx));      bzero ((char *) map->const_age_map, new_maxregnum * sizeof (unsigned));      map->const_age = 0;      for (j = 0; j < max_labelno; j++)	if (local_label[j])	  map->label_map[j] = gen_label_rtx ();      for (j = FIRST_PSEUDO_REGISTER; j < max_reg_before_loop; j++)	if (local_regno[j])	  map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j]));      /* If loop starts with a branch to the test, then fix it so that	 it points to the test of the first unrolled copy of the loop.  */      if (i == 0 && loop_start != copy_start)	{	  insn = PREV_INSN (copy_start);	  pattern = PATTERN (insn);	  	  tem = map->label_map[CODE_LABEL_NUMBER			       (XEXP (SET_SRC (pattern), 0))];	  SET_SRC (pattern) = gen_rtx (LABEL_REF, VOIDmode, tem);	  /* Set the jump label so that it can be used by later loop unrolling	     passes.  */	  JUMP_LABEL (insn) = tem;	  LABEL_NUSES (tem)++;	}      copy_loop_body (copy_start, copy_end, map, exit_label,		      i == unroll_number - 1, unroll_type, start_label,		      loop_end, insert_before, insert_before);    }  /* Before deleting any insns, emit a CODE_LABEL immediately after the last     insn to be deleted.  This prevents any runaway delete_insn call from     more insns that it should, as it always stops at a CODE_LABEL.  */  /* Delete the compare and branch at the end of the loop if completely     unrolling the loop.  Deleting the backward branch at the end also     deletes the code label at the start of the loop.  This is done at     the very end to avoid problems with back_branch_in_range_p.  */  if (unroll_type == UNROLL_COMPLETELY)    safety_label = emit_label_after (gen_label_rtx (), last_loop_insn);  else    safety_label = emit_label_after (gen_label_rtx (), copy_end);  /* Delete all of the original loop instructions.  Don't delete the      LOOP_BEG note, or the first code label in the loop.  */  insn = NEXT_INSN (copy_start);  while (insn != safety_label)    {      if (insn != start_label)	insn = delete_insn (insn);      else	insn = NEXT_INSN (insn);    }  /* Can now delete the 'safety' label emitted to protect us from runaway     delete_insn calls.  */  if (INSN_DELETED_P (safety_label))    abort ();  delete_insn (safety_label);  /* If exit_label exists, emit it after the loop.  Doing the emit here     forces it to have a higher INSN_UID than any insn in the unrolled loop.     This is needed so that mostly_true_jump in reorg.c will treat jumps     to this loop end label correctly, i.e. predict that they are usually     not taken.  */  if (exit_label)    emit_label_after (exit_label, loop_end);}