*参照元 [#k21ff7b9]
#backlinks

*説明 [#t244dfe8]
-パス: [[gcc-8.3/gcc/lra-constraints.c]]

-FIXME: これは何?
--説明


**引数 [#ka780a09]
-bool check_only_p
--


**返り値 [#ib4ccb9e]
-bool
--


**参考 [#q805b13b]


*実装 [#g63a1382]
 /* Main entry point of the constraint code: search the body of the
    current insn to choose the best alternative.  It is mimicking insn
    alternative cost calculation model of former reload pass.  That is
    because machine descriptions were written to use this model.  This
    model can be changed in future.  Make commutative operand exchange
    if it is chosen.
 
    if CHECK_ONLY_P is false, do RTL changes to satisfy the
    constraints.  Return true if any change happened during function
    call.
 
    If CHECK_ONLY_P is true then don't do any transformation.  Just
    check that the insn satisfies all constraints.  If the insn does
    not satisfy any constraint, return true.  */
 static bool
 curr_insn_transform (bool check_only_p)
 {
   int i, j, k;
   int n_operands;
   int n_alternatives;
   int n_outputs;
   int commutative;
   signed char goal_alt_matched[MAX_RECOG_OPERANDS][MAX_RECOG_OPERANDS];
   signed char match_inputs[MAX_RECOG_OPERANDS + 1];
   signed char outputs[MAX_RECOG_OPERANDS + 1];
   rtx_insn *before, *after;
   bool alt_p = false;
   /* Flag that the insn has been changed through a transformation.  */
   bool change_p;
   bool sec_mem_p;
   bool use_sec_mem_p;
   int max_regno_before;
   int reused_alternative_num;
 
-
--[[gcc-8.3/gcc/rtx_insn]]

   curr_insn_set = single_set (curr_insn);
   if (curr_insn_set != NULL_RTX && simple_move_p ())
     {
       /* We assume that the corresponding insn alternative has no
 	 earlier clobbers.  If it is not the case, don't define move
 	 cost equal to 2 for the corresponding register classes.  */
       lra_set_used_insn_alternative (curr_insn, LRA_NON_CLOBBERED_ALT);
       return false;
     }
 
-
--[[gcc-8.3/gcc/curr_insn_set(global)]]
---[[gcc-8.3/gcc/rtx]]
--[[gcc-8.3/gcc/single_set()]]
--[[gcc-8.3/gcc/simple_move_p()]]
--[[gcc-8.3/gcc/lra_set_used_insn_alternative()]]

   no_input_reloads_p = no_output_reloads_p = false;
   goal_alt_number = -1;
   change_p = sec_mem_p = false;
   /* JUMP_INSNs and CALL_INSNs are not allowed to have any output
      reloads; neither are insns that SET cc0.  Insns that use CC0 are
      not allowed to have any input reloads.  */
   if (JUMP_P (curr_insn) || CALL_P (curr_insn))
     no_output_reloads_p = true;
 
   if (HAVE_cc0 && reg_referenced_p (cc0_rtx, PATTERN (curr_insn)))
     no_input_reloads_p = true;
   if (HAVE_cc0 && reg_set_p (cc0_rtx, PATTERN (curr_insn)))
     no_output_reloads_p = true;
 
-
--[[gcc-8.3/gcc/no_input_reloads_p(global)]]
---bool 型
--[[gcc-8.3/gcc/no_output_reloads_p(global)]]
---bool 型
--[[gcc-8.3/gcc/goal_alt_number(global)]]
---int 型
--[[gcc-8.3/gcc/JUMP_P()]]
--[[gcc-8.3/gcc/CALL_P()]]
--[[gcc-8.3/gcc/reg_referenced_p()]]
--[[gcc-8.3/gcc/PATTERN()]]
--[[gcc-8.3/gcc/reg_set_p()]]

   n_operands = curr_static_id->n_operands;
   n_alternatives = curr_static_id->n_alternatives;
 
   /* Just return "no reloads" if insn has no operands with
      constraints.  */
   if (n_operands == 0 || n_alternatives == 0)
     return false;
 
   max_regno_before = max_reg_num ();
 
   for (i = 0; i < n_operands; i++)
     {
       goal_alt_matched[i][0] = -1;
       goal_alt_matches[i] = -1;
     }
 
   commutative = curr_static_id->commutative;
 
-
--[[gcc-8.3/gcc/curr_static_id(global)]]
---lra_static_insn_data * 型
---[[gcc-8.3/gcc/lra_static_insn_data]]
--[[gcc-8.3/gcc/max_reg_num()]]

   /* Now see what we need for pseudos that didn't get hard regs or got
      the wrong kind of hard reg.  For this, we must consider all the
      operands together against the register constraints.  */
 
   best_losers = best_overall = INT_MAX;
   best_reload_sum = 0;
 
   curr_swapped = false;
   goal_alt_swapped = false;
 
-
--[[gcc-8.3/gcc/best_losers(global)]]
--[[gcc-8.3/gcc/best_overall(global)]]
---int 型
--[[gcc-8.3/gcc/best_reload_sum(global)]]
---int 型
--[[gcc-8.3/gcc/curr_swapped(global)]]
--- int

   if (! check_only_p)
     /* Make equivalence substitution and memory subreg elimination
        before address processing because an address legitimacy can
        depend on memory mode.  */
     for (i = 0; i < n_operands; i++)
       {
 	rtx op, subst, old;
 	bool op_change_p = false;
 
 	if (curr_static_id->operand[i].is_operator)
 	  continue;
 	
 	old = op = *curr_id->operand_loc[i];
 	if (GET_CODE (old) == SUBREG)
 	  old = SUBREG_REG (old);
 	subst = get_equiv_with_elimination (old, curr_insn);
 	original_subreg_reg_mode[i] = VOIDmode;
 	equiv_substition_p[i] = false;
 	if (subst != old)
 	  {
 	    equiv_substition_p[i] = true;
 	    subst = copy_rtx (subst);
 	    lra_assert (REG_P (old));
 	    if (GET_CODE (op) != SUBREG)
 	      *curr_id->operand_loc[i] = subst;
 	    else
 	      {
 		SUBREG_REG (op) = subst;
 		if (GET_MODE (subst) == VOIDmode)
 		  original_subreg_reg_mode[i] = GET_MODE (old);
 	      }
 	    if (lra_dump_file != NULL)
 	      {
 		fprintf (lra_dump_file,
 			 "Changing pseudo %d in operand %i of insn %u on equiv ",
 			 REGNO (old), i, INSN_UID (curr_insn));
 		dump_value_slim (lra_dump_file, subst, 1);
 		fprintf (lra_dump_file, "\n");
 	      }
 	    op_change_p = change_p = true;
 	  }
 	if (simplify_operand_subreg (i, GET_MODE (old)) || op_change_p)
 	  {
 	    change_p = true;
 	    lra_update_dup (curr_id, i);
 	  }
       }
 
-
--[[gcc-8.3/gcc/GET_CODE()]]
--[[gcc-8.3/gcc/SUBREG_REG()]]
--[[gcc-8.3/gcc/get_equiv_with_elimination()]]
--[[gcc-8.3/gcc/original_subreg_reg_mode(global)]]
---machine_mode 型
---[[gcc-8.3/gcc/machine_mode]]
--[[gcc-8.3/gcc/equiv_substiotion_p(global)]]
---bool 型
--[[gcc-8.3/gcc/copy_rtx()]]
--[[gcc-8.3/gcc/lra_assert()]]
--[[gcc-8.3/gcc/REG_P()]]
--[[gcc-8.3/gcc/GET_MODE()]]
--[[gcc-8.3/gcc/REGNO()]]
--[[gcc-8.3/gcc/INSN_UID()]]
--[[gcc-8.3/gcc/dump_value_slim()]]
--[[gcc-8.3/gcc/simplify_operand_subreg()]]
--[[gcc-8.3/gcc/lra_update_dup()]]

   /* Reload address registers and displacements.  We do it before
      finding an alternative because of memory constraints.  */
   before = after = NULL;
   for (i = 0; i < n_operands; i++)
     if (! curr_static_id->operand[i].is_operator
 	&& process_address (i, check_only_p, &before, &after))
       {
 	if (check_only_p)
 	  return true;
 	change_p = true;
 	lra_update_dup (curr_id, i);
       }
   
-
--[[gcc-8.3/gcc/process_address()]]

   if (change_p)
     /* If we've changed the instruction then any alternative that
        we chose previously may no longer be valid.  */
     lra_set_used_insn_alternative (curr_insn, LRA_UNKNOWN_ALT);
 
   if (! check_only_p && curr_insn_set != NULL_RTX
       && check_and_process_move (&change_p, &sec_mem_p))
     return change_p;
 
-
--[[gcc-8.3/gcc/lra_set_used_insn_alternative()]]
--[[gcc-8.3/gcc/check_and_process_move()]]

  try_swapped:
 
   reused_alternative_num = check_only_p ? LRA_UNKNOWN_ALT : curr_id->used_insn_alternative;
   if (lra_dump_file != NULL && reused_alternative_num >= 0)
     fprintf (lra_dump_file, "Reusing alternative %d for insn #%u\n",
 	     reused_alternative_num, INSN_UID (curr_insn));
 
   if (process_alt_operands (reused_alternative_num))
     alt_p = true;
 
   if (check_only_p)
     return ! alt_p || best_losers != 0;
 
-
--[[gcc-8.3/gcc/INSN_UID()]]
--[[gcc-8.3/gcc/process_alt_operands()]]

   /* If insn is commutative (it's safe to exchange a certain pair of
      operands) then we need to try each alternative twice, the second
      time matching those two operands as if we had exchanged them.  To
      do this, really exchange them in operands.
 
      If we have just tried the alternatives the second time, return
      operands to normal and drop through.  */
 
   if (reused_alternative_num < 0 && commutative >= 0)
     {
       curr_swapped = !curr_swapped;
       if (curr_swapped)
 	{
 	  swap_operands (commutative);
 	  goto try_swapped;
 	}
       else
 	swap_operands (commutative);
     }
 
-
--[[gcc-8.3/gcc/curr_swapped(global)]]
--[[gcc-8.3/gcc/swap_operands()]]

   if (! alt_p && ! sec_mem_p)
     {
       /* No alternative works with reloads??  */
       if (INSN_CODE (curr_insn) >= 0)
 	fatal_insn ("unable to generate reloads for:", curr_insn);
       error_for_asm (curr_insn,
 		     "inconsistent operand constraints in an %<asm%>");
       /* Avoid further trouble with this insn.  Don't generate use
 	 pattern here as we could use the insn SP offset.  */
       lra_set_insn_deleted (curr_insn);
       return true;
     }
 
-
--[[gcc-8.3/gcc/fatal_insn()]]
--[[gcc-8.3/gcc/error_for_asm()]]
--[[gcc-8.3/gcc/lra_set_insn_deleted()]]

   /* If the best alternative is with operands 1 and 2 swapped, swap
      them.  Update the operand numbers of any reloads already
      pushed.  */
 
   if (goal_alt_swapped)
     {
       if (lra_dump_file != NULL)
 	fprintf (lra_dump_file, "  Commutative operand exchange in insn %u\n",
 		 INSN_UID (curr_insn));
 
       /* Swap the duplicates too.  */
       swap_operands (commutative);
       change_p = true;
     }
 
   /* Some targets' TARGET_SECONDARY_MEMORY_NEEDED (e.g. x86) are defined
      too conservatively.  So we use the secondary memory only if there
      is no any alternative without reloads.  */
   use_sec_mem_p = false;
   if (! alt_p)
     use_sec_mem_p = true;
   else if (sec_mem_p)
     {
       for (i = 0; i < n_operands; i++)
 	if (! goal_alt_win[i] && ! goal_alt_match_win[i])
 	  break;
       use_sec_mem_p = i < n_operands;
     }
 
   if (use_sec_mem_p)
     {
       int in = -1, out = -1;
       rtx new_reg, src, dest, rld;
       machine_mode sec_mode, rld_mode;
 
       lra_assert (curr_insn_set != NULL_RTX && sec_mem_p);
       dest = SET_DEST (curr_insn_set);
       src = SET_SRC (curr_insn_set);
       for (i = 0; i < n_operands; i++)
 	if (*curr_id->operand_loc[i] == dest)
 	  out = i;
 	else if (*curr_id->operand_loc[i] == src)
 	  in = i;
       for (i = 0; i < curr_static_id->n_dups; i++)
 	if (out < 0 && *curr_id->dup_loc[i] == dest)
 	  out = curr_static_id->dup_num[i];
 	else if (in < 0 && *curr_id->dup_loc[i] == src)
 	  in = curr_static_id->dup_num[i];
-
--[[gcc-8.3/gcc/rtx]]
--[[gcc-8.3/gcc/machine_mode]]
--[[gcc-8.3/gcc/lra_assert()]]
--[[gcc-8.3/gcc/SET_DEST()]]
--[[gcc-8.3/gcc/SET_SRC()]]

       lra_assert (out >= 0 && in >= 0
 		  && curr_static_id->operand[out].type == OP_OUT
 		  && curr_static_id->operand[in].type == OP_IN);
       rld = partial_subreg_p (GET_MODE (src), GET_MODE (dest)) ? src : dest;
       rld_mode = GET_MODE (rld);
       sec_mode = targetm.secondary_memory_needed_mode (rld_mode);
       new_reg = lra_create_new_reg (sec_mode, NULL_RTX,
 				    NO_REGS, "secondary");
-
--[[gcc-8.3/gcc/partial_subreg_p()]]
--[[gcc-8.3/gcc/GET_MODE()]]
--[[gcc-8.3/gcc/targetm(global)]]
--[[gcc-8.3/gcc/lra_create_new_reg()]]

       /* If the mode is changed, it should be wider.  */
       lra_assert (!partial_subreg_p (sec_mode, rld_mode));
       if (sec_mode != rld_mode)
         {
 	  /* If the target says specifically to use another mode for
 	     secondary memory moves we can not reuse the original
 	     insn.  */
 	  after = emit_spill_move (false, new_reg, dest);
 	  lra_process_new_insns (curr_insn, NULL, after,
 				 "Inserting the sec. move");
 	  /* We may have non null BEFORE here (e.g. after address
 	     processing.  */
 	  push_to_sequence (before);
 	  before = emit_spill_move (true, new_reg, src);
 	  emit_insn (before);
 	  before = get_insns ();
 	  end_sequence ();
 	  lra_process_new_insns (curr_insn, before, NULL, "Changing on");
 	  lra_set_insn_deleted (curr_insn);
-
--[[gcc-8.3/gcc/lra_assert()]]
--[[gcc-8.3/gcc/partial_subreg_p()]]
--[[gcc-8.3/gcc/emit_spill_move()]]
--[[gcc-8.3/gcc/lra_process_new_insns()]]
--[[gcc-8.3/gcc/push_to_sequence()]]
--[[gcc-8.3/gcc/get_insns()]]
--[[gcc-8.3/gcc/end_sequence()]]
--[[gcc-8.3/gcc/lra_set_insn_deleted()]]

 	}
       else if (dest == rld)
         {
 	  *curr_id->operand_loc[out] = new_reg;
 	  lra_update_dup (curr_id, out);
 	  after = emit_spill_move (false, new_reg, dest);
 	  lra_process_new_insns (curr_insn, NULL, after,
 				 "Inserting the sec. move");
-
--[[gcc-8.3/gcc/lra_update_dup()]]
--[[gcc-8.3/gcc/emit_spill_move()]]
--[[gcc-8.3/gcc/lra_process_new_insns()]]

 	}
       else
 	{
 	  *curr_id->operand_loc[in] = new_reg;
 	  lra_update_dup (curr_id, in);
 	  /* See comments above.  */
 	  push_to_sequence (before);
 	  before = emit_spill_move (true, new_reg, src);
 	  emit_insn (before);
 	  before = get_insns ();
 	  end_sequence ();
 	  lra_process_new_insns (curr_insn, before, NULL,
 				 "Inserting the sec. move");
 	}
       lra_update_insn_regno_info (curr_insn);
       return true;
-
--[[gcc-8.3/gcc/lra_update_dup()]]
--[[gcc-8.3/gcc/push_to_sequence()]]
--[[gcc-8.3/gcc/emit_spill_move()]]
--[[gcc-8.3/gcc/emit_insn()]]
--[[gcc-8.3/gcc/get_insns()]]
--[[gcc-8.3/gcc/end_sequence()]]
--[[gcc-8.3/gcc/lra_process_new_insns()]]
--[[gcc-8.3/gcc/lra_update_insn_regno_info()]]

     }
 
   lra_assert (goal_alt_number >= 0);
   lra_set_used_insn_alternative (curr_insn, goal_alt_number);
 
-
--[[gcc-8.3/gcc/lra_assert()]]
--[[gcc-8.3/gcc/lra_set_used_insn_alternative()]]

   if (lra_dump_file != NULL)
     {
       const char *p;
 
       fprintf (lra_dump_file, "	 Choosing alt %d in insn %u:",
 	       goal_alt_number, INSN_UID (curr_insn));
       for (i = 0; i < n_operands; i++)
 	{
 	  p = (curr_static_id->operand_alternative
 	       [goal_alt_number * n_operands + i].constraint);
 	  if (*p == '\0')
 	    continue;
 	  fprintf (lra_dump_file, "  (%d) ", i);
 	  for (; *p != '\0' && *p != ',' && *p != '#'; p++)
 	    fputc (*p, lra_dump_file);
 	}
       if (INSN_CODE (curr_insn) >= 0
           && (p = get_insn_name (INSN_CODE (curr_insn))) != NULL)
         fprintf (lra_dump_file, " {%s}", p);
       if (maybe_ne (curr_id->sp_offset, 0))
 	{
 	  fprintf (lra_dump_file, " (sp_off=");
 	  print_dec (curr_id->sp_offset, lra_dump_file);
 	  fprintf (lra_dump_file, ")");
 	}
       fprintf (lra_dump_file, "\n");
     }
 
-
--[[gcc-8.3/gcc/INSN_UID()]]
--[[gcc-8.3/gcc/INSN_CODE()]]
--[[gcc-8.3/gcc/maybe_ne()]]
--[[gcc-8.3/gcc/print_dec()]]

   /* Right now, for any pair of operands I and J that are required to
      match, with J < I, goal_alt_matches[I] is J.  Add I to
      goal_alt_matched[J].  */
 
   for (i = 0; i < n_operands; i++)
     if ((j = goal_alt_matches[i]) >= 0)
       {
 	for (k = 0; goal_alt_matched[j][k] >= 0; k++)
 	  ;
 	/* We allow matching one output operand and several input
 	   operands.  */
 	lra_assert (k == 0
 		    || (curr_static_id->operand[j].type == OP_OUT
 			&& curr_static_id->operand[i].type == OP_IN
 			&& (curr_static_id->operand
 			    [goal_alt_matched[j][0]].type == OP_IN)));
 	goal_alt_matched[j][k] = i;
 	goal_alt_matched[j][k + 1] = -1;
       }
 
   for (i = 0; i < n_operands; i++)
     goal_alt_win[i] |= goal_alt_match_win[i];
 
   /* Any constants that aren't allowed and can't be reloaded into
      registers are here changed into memory references.	 */
   for (i = 0; i < n_operands; i++)
     if (goal_alt_win[i])
       {
 	int regno;
 	enum reg_class new_class;
 	rtx reg = *curr_id->operand_loc[i];
 
 	if (GET_CODE (reg) == SUBREG)
 	  reg = SUBREG_REG (reg);
 
 	if (REG_P (reg) && (regno = REGNO (reg)) >= FIRST_PSEUDO_REGISTER)
 	  {
 	    bool ok_p = in_class_p (reg, goal_alt[i], &new_class);
 
 	    if (new_class != NO_REGS && get_reg_class (regno) != new_class)
 	      {
 		lra_assert (ok_p);
 		lra_change_class (regno, new_class, "      Change to", true);
 	      }
 	  }
-
--[[gcc-8.3/gcc/reg_class]]
--[[gcc-8.3/gcc/rtx]]
--[[gcc-8.3/gcc/GET_CODE()]]
--[[gcc-8.3/gcc/SUBREG_REG()]]
--[[gcc-8.3/gcc/REG_P()]]
--[[gcc-8.3/gcc/REGNO()]]
--[[gcc-8.3/gcc/in_class_p()]]
--[[gcc-8.3/gcc/get_reg_class()]]
--[[gcc-8.3/gcc/lra_assert()]]
--[[gcc-8.3/gcc/lra_change_class()]]

       }
     else
       {
 	const char *constraint;
 	char c;
 	rtx op = *curr_id->operand_loc[i];
 	rtx subreg = NULL_RTX;
 	machine_mode mode = curr_operand_mode[i];
 
 	if (GET_CODE (op) == SUBREG)
 	  {
 	    subreg = op;
 	    op = SUBREG_REG (op);
 	    mode = GET_MODE (op);
 	  }
 
-
--[[gcc-8.3/gcc/rtx]]
--[[gcc-8.3/gcc/machine_mode]]
--[[gcc-8.3/gcc/GET_CODE()]]
--[[gcc-8.3/gcc/SUBREG_REG()]]
--[[gcc-8.3/gcc/GET_MODE()]]

 	if (CONST_POOL_OK_P (mode, op)
 	    && ((targetm.preferred_reload_class
 		 (op, (enum reg_class) goal_alt[i]) == NO_REGS)
 		|| no_input_reloads_p))
 	  {
 	    rtx tem = force_const_mem (mode, op);
 
 	    change_p = true;
 	    if (subreg != NULL_RTX)
 	      tem = gen_rtx_SUBREG (mode, tem, SUBREG_BYTE (subreg));
 
 	    *curr_id->operand_loc[i] = tem;
 	    lra_update_dup (curr_id, i);
 	    process_address (i, false, &before, &after);
 
-
--[[gcc-8.3/gcc/CONST_POOL_OK_P()]]
--[[gcc-8.3/gcc/targetm(global)]]
--[[gcc-8.3/gcc/force_const_mem()]]
--[[gcc-8.3/gcc/gen_rtx_SUBREG()]]
--[[gcc-8.3/gcc/SUBREG_BYTE()]]
--[[gcc-8.3/gcc/lra_update_dup()]]
--[[gcc-8.3/gcc/process_address()]]

 	    /* If the alternative accepts constant pool refs directly
 	       there will be no reload needed at all.  */
 	    if (subreg != NULL_RTX)
 	      continue;
 	    /* Skip alternatives before the one requested.  */
 	    constraint = (curr_static_id->operand_alternative
 			  [goal_alt_number * n_operands + i].constraint);
 	    for (;
 		 (c = *constraint) && c != ',' && c != '#';
 		 constraint += CONSTRAINT_LEN (c, constraint))
 	      {
 		enum constraint_num cn = lookup_constraint (constraint);
 		if ((insn_extra_memory_constraint (cn)
 		     || insn_extra_special_memory_constraint (cn))
 		    && satisfies_memory_constraint_p (tem, cn))
 		  break;
 	      }
 	    if (c == '\0' || c == ',' || c == '#')
 	      continue;
 
 	    goal_alt_win[i] = true;
 	  }
       }
 
-
--[[gcc-8.3/gcc/CONSTRAINT_LEN()]]
--[[gcc-8.3/gcc/lookup_constraint()]]
--[[gcc-8.3/gcc/insn_extra_memory_constraint()]]
--[[gcc-8.3/gcc/insn_extra_special_memory_constraint()]]
--[[gcc-8.3/gcc/satisfies_memory_constraint_p()]]

   n_outputs = 0;
   outputs[0] = -1;
   for (i = 0; i < n_operands; i++)
     {
       int regno;
       bool optional_p = false;
       rtx old, new_reg;
       rtx op = *curr_id->operand_loc[i];
 
       if (goal_alt_win[i])
 	{
 	  if (goal_alt[i] == NO_REGS
 	      && REG_P (op)
 	      /* When we assign NO_REGS it means that we will not
 		 assign a hard register to the scratch pseudo by
 		 assigment pass and the scratch pseudo will be
 		 spilled.  Spilled scratch pseudos are transformed
 		 back to scratches at the LRA end.  */
 	      && lra_former_scratch_operand_p (curr_insn, i)
 	      && lra_former_scratch_p (REGNO (op)))
 	    {
 	      int regno = REGNO (op);
 	      lra_change_class (regno, NO_REGS, "      Change to", true);
 	      if (lra_get_regno_hard_regno (regno) >= 0)
 		/* We don't have to mark all insn affected by the
 		   spilled pseudo as there is only one such insn, the
 		   current one.  */
 		reg_renumber[regno] = -1;
 	      lra_assert (bitmap_single_bit_set_p
 			  (&lra_reg_info[REGNO (op)].insn_bitmap));
 	    }
-
--[[gcc-8.3/gcc/rtx]]
--[[gcc-8.3/gcc/REG_P()]]
--[[gcc-8.3/gcc/lra_former_scratch_operand_p()]]
--[[gcc-8.3/gcc/lra_former_scratch_p()]]
--[[gcc-8.3/gcc/REGNO()]]
--[[gcc-8.3/gcc/lra_change_class()]]
--[[gcc-8.3/gcc/lra_get_regno_hard_regno()]]
--[[gcc-8.3/gcc/lra_assert()]]
--[[gcc-8.3/gcc/bitmap_single_bit_set_p()]]

 	  /* We can do an optional reload.  If the pseudo got a hard
 	     reg, we might improve the code through inheritance.  If
 	     it does not get a hard register we coalesce memory/memory
 	     moves later.  Ignore move insns to avoid cycling.  */
 	  if (! lra_simple_p
 	      && lra_undo_inheritance_iter < LRA_MAX_INHERITANCE_PASSES
 	      && goal_alt[i] != NO_REGS && REG_P (op)
 	      && (regno = REGNO (op)) >= FIRST_PSEUDO_REGISTER
 	      && regno < new_regno_start
 	      && ! lra_former_scratch_p (regno)
 	      && reg_renumber[regno] < 0
 	      /* Check that the optional reload pseudo will be able to
 		 hold given mode value.  */
 	      && ! (prohibited_class_reg_set_mode_p
 		    (goal_alt[i], reg_class_contents[goal_alt[i]],
 		     PSEUDO_REGNO_MODE (regno)))
 	      && (curr_insn_set == NULL_RTX
 		  || !((REG_P (SET_SRC (curr_insn_set))
 			|| MEM_P (SET_SRC (curr_insn_set))
 			|| GET_CODE (SET_SRC (curr_insn_set)) == SUBREG)
 		       && (REG_P (SET_DEST (curr_insn_set))
 			   || MEM_P (SET_DEST (curr_insn_set))
 			   || GET_CODE (SET_DEST (curr_insn_set)) == SUBREG))))
 	    optional_p = true;
 	  else
 	    continue;
 	}
 
-
--[[gcc-8.3/gcc/REG_P()]]
--[[gcc-8.3/gcc/REGNO()]]
--[[gcc-8.3/gcc/lra_former_scratch_p()]]
--[[gcc-8.3/gcc/reg_renumber(global)]]
--[[gcc-8.3/gcc/prohibited_class_reg_set_mode_p()]]
--[[gcc-8.3/gcc/PSEUDO_REGNO_MODE()]]
--[[gcc-8.3/gcc/REG_P()]]
--[[gcc-8.3/gcc/MEM_P()]]
--[[gcc-8.3/gcc/SET_SRC()]]
--[[gcc-8.3/gcc/SET_DEST()]]
--[[gcc-8.3/gcc/GET_CODE()]]

       /* Operands that match previous ones have already been handled.  */
       if (goal_alt_matches[i] >= 0)
 	continue;
 
       /* We should not have an operand with a non-offsettable address
 	 appearing where an offsettable address will do.  It also may
 	 be a case when the address should be special in other words
 	 not a general one (e.g. it needs no index reg).  */
       if (goal_alt_matched[i][0] == -1 && goal_alt_offmemok[i] && MEM_P (op))
 	{
 	  enum reg_class rclass;
 	  rtx *loc = &XEXP (op, 0);
 	  enum rtx_code code = GET_CODE (*loc);
 
 	  push_to_sequence (before);
 	  rclass = base_reg_class (GET_MODE (op), MEM_ADDR_SPACE (op),
 				   MEM, SCRATCH);
-
--[[gcc-8.3/gcc/reg_class]]
--[[gcc-8.3/gcc/rtx]]
--[[gcc-8.3/gcc/XEXP()]]
--[[gcc-8.3/gcc/rtx_code]]
--[[gcc-8.3/gcc/GET_CODE()]]
--[[gcc-8.3/gcc/push_to_sequence()]]
--[[gcc-8.3/gcc/base_reg_class()]]
--[[gcc-8.3/gcc/GET_MODE()]]
--[[gcc-8.3/gcc/MEM_ADDR_SPACE()]]

 	  if (GET_RTX_CLASS (code) == RTX_AUTOINC)
 	    new_reg = emit_inc (rclass, *loc, *loc,
 				/* This value does not matter for MODIFY.  */
 				GET_MODE_SIZE (GET_MODE (op)));
 	  else if (get_reload_reg (OP_IN, Pmode, *loc, rclass, FALSE,
 				   "offsetable address", &new_reg))
 	    {
 	      rtx addr = *loc;
 	      enum rtx_code code = GET_CODE (addr);
 	      
 	      if (code == AND && CONST_INT_P (XEXP (addr, 1)))
 		/* (and ... (const_int -X)) is used to align to X bytes.  */
 		addr = XEXP (*loc, 0);
 	      lra_emit_move (new_reg, addr);
 	      if (addr != *loc)
 		emit_move_insn (new_reg, gen_rtx_AND (GET_MODE (new_reg), new_reg, XEXP (*loc, 1)));
 	    }
 	  before = get_insns ();
 	  end_sequence ();
 	  *loc = new_reg;
 	  lra_update_dup (curr_id, i);
 	}
-
--[[gcc-8.3/gcc/GET_RTX_CLASS()]]
--[[gcc-8.3/gcc/emit_inc()]]
--[[gcc-8.3/gcc/GET_MODE_SIZE()]]
--[[gcc-8.3/gcc/GET_MODE()]]
--[[gcc-8.3/gcc/get_reload_reg()]]
--[[gcc-8.3/gcc/rtx]]
--[[gcc-8.3/gcc/rtx_code]]
--[[gcc-8.3/gcc/GET_CODE()]]
--[[gcc-8.3/gcc/CONST_INT_P()]]
--[[gcc-8.3/gcc/XEXP()]]
--[[gcc-8.3/gcc/lra_emit_move()]]
--[[gcc-8.3/gcc/emit_move_insn()]]
--[[gcc-8.3/gcc/gen_rtx_AND()]]
--[[gcc-8.3/gcc/get_insns()]]
--[[gcc-8.3/gcc/end_sequence()]]
--[[gcc-8.3/gcc/lra_update_dup()]]

       else if (goal_alt_matched[i][0] == -1)
 	{
 	  machine_mode mode;
 	  rtx reg, *loc;
 	  int hard_regno;
 	  enum op_type type = curr_static_id->operand[i].type;
 
 	  loc = curr_id->operand_loc[i];
 	  mode = curr_operand_mode[i];
 	  if (GET_CODE (*loc) == SUBREG)
 	    {
 	      reg = SUBREG_REG (*loc);
 	      poly_int64 byte = SUBREG_BYTE (*loc);
 	      if (REG_P (reg)
 		  /* Strict_low_part requires reloading the register and not
 		     just the subreg.  Likewise for a strict subreg no wider
 		     than a word for WORD_REGISTER_OPERATIONS targets.  */
 		  && (curr_static_id->operand[i].strict_low
 		      || (!paradoxical_subreg_p (mode, GET_MODE (reg))
 			  && (hard_regno
 			      = get_try_hard_regno (REGNO (reg))) >= 0
 			  && (simplify_subreg_regno
 			      (hard_regno,
 			       GET_MODE (reg), byte, mode) < 0)
 			  && (goal_alt[i] == NO_REGS
 			      || (simplify_subreg_regno
 				  (ira_class_hard_regs[goal_alt[i]][0],
 				   GET_MODE (reg), byte, mode) >= 0)))
 		      || (partial_subreg_p (mode, GET_MODE (reg))
 			  && known_le (GET_MODE_SIZE (GET_MODE (reg)),
 				       UNITS_PER_WORD)
 			  && WORD_REGISTER_OPERATIONS)))
 		{
 		  /* An OP_INOUT is required when reloading a subreg of a
 		     mode wider than a word to ensure that data beyond the
 		     word being reloaded is preserved.  Also automatically
 		     ensure that strict_low_part reloads are made into
 		     OP_INOUT which should already be true from the backend
 		     constraints.  */
 		  if (type == OP_OUT
 		      && (curr_static_id->operand[i].strict_low
 			  || read_modify_subreg_p (*loc)))
 		    type = OP_INOUT;
 		  loc = &SUBREG_REG (*loc);
 		  mode = GET_MODE (*loc);
 		}
 	    }
-
--[[gcc-8.3/gcc/machine_mode]]
--[[gcc-8.3/gcc/rtx]]
--[[gcc-8.3/gcc/op_type]]
--[[gcc-8.3/gcc/GET_CODE()]]
--[[gcc-8.3/gcc/SUBREG_REG()]]
--[[gcc-8.3/gcc/poly_int64]]
--[[gcc-8.3/gcc/SUBREG_BYTE()]]
--[[gcc-8.3/gcc/REG_P()]]
--[[gcc-8.3/gcc/paradoxical_subreg_p()]]
--[[gcc-8.3/gcc/get_try_hard_regno()]]
--[[gcc-8.3/gcc/GET_MODE()]]
--[[gcc-8.3/gcc/REGNO()]]
--[[gcc-8.3/gcc/simplify_subreg_regno()]]
--[[gcc-8.3/gcc/partial_subreg_p()]]
--[[gcc-8.3/gcc/known_le()]]
--[[gcc-8.3/gcc/GET_MODE_SIZE()]]
--[[gcc-8.3/gcc/read_modify_subreg_p()]]

 	  old = *loc;
 	  if (get_reload_reg (type, mode, old, goal_alt[i],
 			      loc != curr_id->operand_loc[i], "", &new_reg)
 	      && type != OP_OUT)
 	    {
 	      push_to_sequence (before);
 	      lra_emit_move (new_reg, old);
 	      before = get_insns ();
 	      end_sequence ();
 	    }
-
--[[gcc-8.3/gcc/get_reload_reg()]]
--[[gcc-8.3/gcc/push_to_sequence()]]
--[[gcc-8.3/gcc/lra_emit_move()]]
--[[gcc-8.3/gcc/get_insns()]]
--[[gcc-8.3/gcc/end_sequence()]]

 	  *loc = new_reg;
 	  if (type != OP_IN
 	      && find_reg_note (curr_insn, REG_UNUSED, old) == NULL_RTX)
 	    {
 	      start_sequence ();
 	      lra_emit_move (type == OP_INOUT ? copy_rtx (old) : old, new_reg);
 	      emit_insn (after);
 	      after = get_insns ();
 	      end_sequence ();
 	      *loc = new_reg;
 	    }
 	  for (j = 0; j < goal_alt_dont_inherit_ops_num; j++)
 	    if (goal_alt_dont_inherit_ops[j] == i)
 	      {
 		lra_set_regno_unique_value (REGNO (new_reg));
 		break;
 	      }
 	  lra_update_dup (curr_id, i);
 	}
-
--[[gcc-8.3/gcc/find_reg_note()]]
--[[gcc-8.3/gcc/start_sequence()]]
--[[gcc-8.3/gcc/lra_emit_move()]]
--[[gcc-8.3/gcc/copy_rtx()]]
--[[gcc-8.3/gcc/emit_insn()]]
--[[gcc-8.3/gcc/get_insns()]]
--[[gcc-8.3/gcc/end_sequence()]]
--[[gcc-8.3/gcc/lra_set_regno_unique_value()]]
--[[gcc-8.3/gcc/REGNO()]]
--[[gcc-8.3/gcc/lra_update_dup()]]

       else if (curr_static_id->operand[i].type == OP_IN
 	       && (curr_static_id->operand[goal_alt_matched[i][0]].type
 		   == OP_OUT
 		   || (curr_static_id->operand[goal_alt_matched[i][0]].type
 		       == OP_INOUT
 		       && (operands_match_p
 			   (*curr_id->operand_loc[i],
 			    *curr_id->operand_loc[goal_alt_matched[i][0]],
 			    -1)))))
 	{
 	  /* generate reloads for input and matched outputs.  */
 	  match_inputs[0] = i;
 	  match_inputs[1] = -1;
 	  match_reload (goal_alt_matched[i][0], match_inputs, outputs,
 			goal_alt[i], &before, &after,
 			curr_static_id->operand_alternative
 			[goal_alt_number * n_operands + goal_alt_matched[i][0]]
 			.earlyclobber);
 	}
-
--[[gcc-8.3/gcc/operands_match_p()]]
--[[gcc-8.3/gcc/match_reload()]]

       else if ((curr_static_id->operand[i].type == OP_OUT
 		|| (curr_static_id->operand[i].type == OP_INOUT
 		    && (operands_match_p
 			(*curr_id->operand_loc[i],
 			 *curr_id->operand_loc[goal_alt_matched[i][0]],
 			 -1))))
 	       && (curr_static_id->operand[goal_alt_matched[i][0]].type
 		    == OP_IN))
 	/* Generate reloads for output and matched inputs.  */
 	match_reload (i, goal_alt_matched[i], outputs, goal_alt[i], &before,
 		      &after, curr_static_id->operand_alternative
 			      [goal_alt_number * n_operands + i].earlyclobber);

-
--[[gcc-8.3/gcc/operands_match_p()]]
--[[gcc-8.3/gcc/match_reload()]]

       else if (curr_static_id->operand[i].type == OP_IN
 	       && (curr_static_id->operand[goal_alt_matched[i][0]].type
 		   == OP_IN))
 	{
 	  /* Generate reloads for matched inputs.  */
 	  match_inputs[0] = i;
 	  for (j = 0; (k = goal_alt_matched[i][j]) >= 0; j++)
 	    match_inputs[j + 1] = k;
 	  match_inputs[j + 1] = -1;
 	  match_reload (-1, match_inputs, outputs, goal_alt[i], &before,
 			&after, false);
 	}
       else
 	/* We must generate code in any case when function
 	   process_alt_operands decides that it is possible.  */
 	gcc_unreachable ();
 
-
--[[gcc-8.3/gcc/match_reload()]]
--[[gcc-8.3/gcc/gcc_unreachable()]]

       /* Memorise processed outputs so that output remaining to be processed
 	 can avoid using the same register value (see match_reload).  */
       if (curr_static_id->operand[i].type == OP_OUT)
 	{
 	  outputs[n_outputs++] = i;
 	  outputs[n_outputs] = -1;
 	}
 
       if (optional_p)
 	{
 	  rtx reg = op;
 
 	  lra_assert (REG_P (reg));
 	  regno = REGNO (reg);
 	  op = *curr_id->operand_loc[i]; /* Substitution.  */
 	  if (GET_CODE (op) == SUBREG)
 	    op = SUBREG_REG (op);
 	  gcc_assert (REG_P (op) && (int) REGNO (op) >= new_regno_start);
 	  bitmap_set_bit (&lra_optional_reload_pseudos, REGNO (op));
 	  lra_reg_info[REGNO (op)].restore_rtx = reg;
 	  if (lra_dump_file != NULL)
 	    fprintf (lra_dump_file,
 		     "      Making reload reg %d for reg %d optional\n",
 		     REGNO (op), regno);
 	}
     }
-
--[[gcc-8.3/gcc/rtx]]
--[[gcc-8.3/gcc/lra_assert()]]
--[[gcc-8.3/gcc/REG_P()]]
--[[gcc-8.3/gcc/REGNO()]]
--[[gcc-8.3/gcc/GET_CODE()]]
--[[gcc-8.3/gcc/SUBREG_REG()]]
--[[gcc-8.3/gcc/gcc_assert()]]
--[[gcc-8.3/gcc/bitmap_set_bit()]]

   if (before != NULL_RTX || after != NULL_RTX
       || max_regno_before != max_reg_num ())
     change_p = true;
   if (change_p)
     {
       lra_update_operator_dups (curr_id);
       /* Something changes -- process the insn.	 */
       lra_update_insn_regno_info (curr_insn);
     }
   lra_process_new_insns (curr_insn, before, after, "Inserting insn reload");
   return change_p;
 }
-
--[[gcc-8.3/gcc/max_reg_num()]]
--[[gcc-8.3/gcc/lra_update_operator_dups()]]
--[[gcc-8.3/gcc/lra_update_insn_regno_info()]]
--[[gcc-8.3/gcc/lra_process_new_insns()]]


*コメント [#ze913074]

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS