*参照元 [#sb70ac68]
#backlinks

*説明 [#o5eaa716]
-パス: [[gcc-8.3/gcc/function.c]]

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


**引数 [#m8f34270]
-rtx_insn *insn
--
--[[gcc-8.3/gcc/rtx_insn]]


**返り値 [#dcf3ce13]
-なし


**参考 [#if684389]


*実装 [#s03f4a77]
 /* A subroutine of instantiate_virtual_regs.  Instantiate any virtual
    registers present inside of insn.  The result will be a valid insn.  */
 
 static void
 instantiate_virtual_regs_in_insn (rtx_insn *insn)
 {
   poly_int64 offset;
   int insn_code, i;
   bool any_change = false;
   rtx set, new_rtx, x;
   rtx_insn *seq;
 
-
--[[gcc-8.3/gcc/poly_int64]]
--[[gcc-8.3/gcc/insn_code]]
--[[gcc-8.3/gcc/rtx]]
--[[gcc-8.3/gcc/rtx_insn]]

   /* There are some special cases to be handled first.  */
   set = single_set (insn);
-
--[[gcc-8.3/gcc/single_set()]]

   if (set)
     {
       /* We're allowed to assign to a virtual register.  This is interpreted
 	 to mean that the underlying register gets assigned the inverse
 	 transformation.  This is used, for example, in the handling of
 	 non-local gotos.  */
       new_rtx = instantiate_new_reg (SET_DEST (set), &offset);

-
--[[gcc-8.3/gcc/instantiate_new_reg()]]
--[[gcc-8.3/gcc/SET_DEST()]]

       if (new_rtx)
 	{
 	  start_sequence ();

 	  instantiate_virtual_regs_in_rtx (&SET_SRC (set));
 	  x = simplify_gen_binary (PLUS, GET_MODE (new_rtx), SET_SRC (set),
 				   gen_int_mode (-offset, GET_MODE (new_rtx)));
 	  x = force_operand (x, new_rtx);
 	  if (x != new_rtx)
 	    emit_move_insn (new_rtx, x);
 
 	  seq = get_insns ();
 	  end_sequence ();
 
-
--[[gcc-8.3/gcc/start_sequence()]]
--[[gcc-8.3/gcc/instantiate_virtual_regs_in_rtx()]]
--[[gcc-8.3/gcc/SET_SRC()]]
--[[gcc-8.3/gcc/simplify_gen_binary()]]
--[[gcc-8.3/gcc/GET_MODE()]]
--[[gcc-8.3/gcc/SET_SRC()]]
--[[gcc-8.3/gcc/gen_int_mode()]]
--[[gcc-8.3/gcc/force_operand()]]
--[[gcc-8.3/gcc/emit_move_insn()]]
--[[gcc-8.3/gcc/get_insns()]]
--[[gcc-8.3/gcc/end_sequence()]]

 	  emit_insn_before (seq, insn);
 	  delete_insn (insn);
 	  return;
 	}
 
-
--[[gcc-8.3/gcc/emit_insn_before()]]
--[[gcc-8.3/gcc/delete_insn()]]

       /* Handle a straight copy from a virtual register by generating a
 	 new add insn.  The difference between this and falling through
 	 to the generic case is avoiding a new pseudo and eliminating a
 	 move insn in the initial rtl stream.  */
       new_rtx = instantiate_new_reg (SET_SRC (set), &offset);
       if (new_rtx
 	  && maybe_ne (offset, 0)
 	  && REG_P (SET_DEST (set))
 	  && REGNO (SET_DEST (set)) > LAST_VIRTUAL_REGISTER)
 	{
-
--[[gcc-8.3/gcc/instantiate_new_reg()]]
--[[gcc-8.3/gcc/SET_SRC()]]
--[[gcc-8.3/gcc/maybe_ne()]]
--[[gcc-8.3/gcc/REG_P()]]
--[[gcc-8.3/gcc/REGNO()]]
--[[gcc-8.3/gcc/SET_DEST()]]

 	  start_sequence ();
 
 	  x = expand_simple_binop (GET_MODE (SET_DEST (set)), PLUS, new_rtx,
 				   gen_int_mode (offset,
 						 GET_MODE (SET_DEST (set))),
 				   SET_DEST (set), 1, OPTAB_LIB_WIDEN);
 	  if (x != SET_DEST (set))
 	    emit_move_insn (SET_DEST (set), x);
 

 	  seq = get_insns ();
 	  end_sequence ();
 
-
--[[gcc-8.3/gcc/start_sequence()]]
--[[gcc-8.3/gcc/expand_simple_binop()]]
--[[gcc-8.3/gcc/GET_MODE()]]
--[[gcc-8.3/gcc/SET_DEST()]]
--[[gcc-8.3/gcc/gen_int_mode()]]
--[[gcc-8.3/gcc/emit_move_insn()]]
--[[gcc-8.3/gcc/get_insns()]]
--[[gcc-8.3/gcc/end_sequence()]]

 	  emit_insn_before (seq, insn);
 	  delete_insn (insn);
 	  return;
 	}
 
-
--[[gcc-8.3/gcc/emit_insn_before()]]
--[[gcc-8.3/gcc/delete_insn()]]

       extract_insn (insn);
       insn_code = INSN_CODE (insn);
 
-
--[[gcc-8.3/gcc/extract_insn()]]
--[[gcc-8.3/gcc/INSN_CODE()]]

       /* Handle a plus involving a virtual register by determining if the
 	 operands remain valid if they're modified in place.  */
       poly_int64 delta;
       if (GET_CODE (SET_SRC (set)) == PLUS
 	  && recog_data.n_operands >= 3
 	  && recog_data.operand_loc[1] == &XEXP (SET_SRC (set), 0)
 	  && recog_data.operand_loc[2] == &XEXP (SET_SRC (set), 1)
 	  && poly_int_rtx_p (recog_data.operand[2], &delta)
 	  && (new_rtx = instantiate_new_reg (recog_data.operand[1], &offset)))
 	{
-
--[[gcc-8.3/gcc/poly_int64]]
--[[gcc-8.3/gcc/XEXP()]]
--[[gcc-8.3/gcc/SET_SERC()]]
--[[gcc-8.3/gcc/poly_int_rtx_p()]]
--[[gcc-8.3/gcc/instantiate_new_reg()]]

 	  offset += delta;
 
 	  /* If the sum is zero, then replace with a plain move.  */
 	  if (known_eq (offset, 0)
 	      && REG_P (SET_DEST (set))
 	      && REGNO (SET_DEST (set)) > LAST_VIRTUAL_REGISTER)
 	    {
-
--[[gcc-8.3/gcc/known_eq()]]
--[[gcc-8.3/gcc/REG_P()]]
--[[gcc-8.3/gcc/REGNO()]]
--[[gcc-8.3/gcc/SET_DEST()]]

 	      start_sequence ();
 	      emit_move_insn (SET_DEST (set), new_rtx);
 	      seq = get_insns ();
 	      end_sequence ();
 
-
--[[gcc-8.3/gcc/start_sequence()]]
--[[gcc-8.3/gcc/expand_move_insn()]]
--[[gcc-8.3/gcc/SET_DEST()]]
--[[gcc-8.3/gcc/get_insns()]]
--[[gcc-8.3/gcc/emit_move_insn()]]
--[[gcc-8.3/gcc/end_sequence()]]

 	      emit_insn_before (seq, insn);
 	      delete_insn (insn);
 	      return;
 	    }
 
-
--[[gcc-8.3/gcc/emit_insn_before()]]
--[[gcc-8.3/gcc/delete_insn()]]

 	  x = gen_int_mode (offset, recog_data.operand_mode[2]);
 
-
--[[gcc-8.3/gcc/gen_int_mode()]]

 	  /* Using validate_change and apply_change_group here leaves
 	     recog_data in an invalid state.  Since we know exactly what
 	     we want to check, do those two by hand.  */
 	  if (safe_insn_predicate (insn_code, 1, new_rtx)
 	      && safe_insn_predicate (insn_code, 2, x))
 	    {
-
--[[gcc-8.3/gcc/safe_insn_predicate()]]

 	      *recog_data.operand_loc[1] = recog_data.operand[1] = new_rtx;
 	      *recog_data.operand_loc[2] = recog_data.operand[2] = x;
 	      any_change = true;
 
 	      /* Fall through into the regular operand fixup loop in
 		 order to take care of operands other than 1 and 2.  */
 	    }
 	}
     }
   else
     {
       extract_insn (insn);
       insn_code = INSN_CODE (insn);
     }
 
-
--[[gcc-8.3/gcc/extract_insn()]]
--[[gcc-8.3/gcc/INSN_CODE()]]

   /* In the general case, we expect virtual registers to appear only in
      operands, and then only as either bare registers or inside memories.  */
   for (i = 0; i < recog_data.n_operands; ++i)
     {
       x = recog_data.operand[i];
       switch (GET_CODE (x))
 	{
-
--[[gcc-8.3/gcc/GET_CODE()]]

 	case MEM:
 	  {
 	    rtx addr = XEXP (x, 0);
 
 	    if (!instantiate_virtual_regs_in_rtx (&addr))
 	      continue;
 
 	    start_sequence ();
 	    x = replace_equiv_address (x, addr, true);
 	    /* It may happen that the address with the virtual reg
 	       was valid (e.g. based on the virtual stack reg, which might
 	       be acceptable to the predicates with all offsets), whereas
 	       the address now isn't anymore, for instance when the address
 	       is still offsetted, but the base reg isn't virtual-stack-reg
 	       anymore.  Below we would do a force_reg on the whole operand,
 	       but this insn might actually only accept memory.  Hence,
 	       before doing that last resort, try to reload the address into
 	       a register, so this operand stays a MEM.  */
 	    if (!safe_insn_predicate (insn_code, i, x))
 	      {
 		addr = force_reg (GET_MODE (addr), addr);
 		x = replace_equiv_address (x, addr, true);
 	      }
 	    seq = get_insns ();
 	    end_sequence ();
 	    if (seq)
 	      emit_insn_before (seq, insn);
-
--[[gcc-8.3/gcc/rtx]]
--[[gcc-8.3/gcc/XEXP()]]
--[[gcc-8.3/gcc/instantiate_virtual_regs_in_rtx()]]
--[[gcc-8.3/gcc/start_sequence()]]
--[[gcc-8.3/gcc/safe_insn_predicate()]]
--[[gcc-8.3/gcc/force_reg()]]
--[[gcc-8.3/gcc/replace_equiv_address()]]
--[[gcc-8.3/gcc/get_insns()]]
--[[gcc-8.3/gcc/end_sequence()]]
--[[gcc-8.3/gcc/emit_insn_before()]]

 	  }
 	  break;
 
 	case REG:
 	  new_rtx = instantiate_new_reg (x, &offset);
 	  if (new_rtx == NULL)
 	    continue;
 	  if (known_eq (offset, 0))
 	    x = new_rtx;
-
--[[gcc-8.3/gcc/instantiate_new_reg()]]
--[[gcc-8.3/gcc/known_eq()]]

 	  else
 	    {
 	      start_sequence ();
 
 	      /* Careful, special mode predicates may have stuff in
 		 insn_data[insn_code].operand[i].mode that isn't useful
 		 to us for computing a new value.  */
 	      /* ??? Recognize address_operand and/or "p" constraints
 		 to see if (plus new offset) is a valid before we put
 		 this through expand_simple_binop.  */
 	      x = expand_simple_binop (GET_MODE (x), PLUS, new_rtx,
 				       gen_int_mode (offset, GET_MODE (x)),
 				       NULL_RTX, 1, OPTAB_LIB_WIDEN);
 	      seq = get_insns ();
 	      end_sequence ();
 	      emit_insn_before (seq, insn);
-
--[[gcc-8.3/gcc/start_sequence()]]
--[[gcc-8.3/gcc/get_insns()]]
--[[gcc-8.3/gcc/end_sequence()]]
--[[gcc-8.3/gcc/emit_insn_before()]]

 	    }
 	  break;
 
 	case SUBREG:
 	  new_rtx = instantiate_new_reg (SUBREG_REG (x), &offset);
 	  if (new_rtx == NULL)
 	    continue;
 	  if (maybe_ne (offset, 0))
-
--[[gcc-8.3/gcc/instantiate_new_reg()]]
--[[gcc-8.3/gcc/maybe_ne()]]

 	    {
 	      start_sequence ();
 	      new_rtx = expand_simple_binop
 		(GET_MODE (new_rtx), PLUS, new_rtx,
 		 gen_int_mode (offset, GET_MODE (new_rtx)),
 		 NULL_RTX, 1, OPTAB_LIB_WIDEN);
 	      seq = get_insns ();
 	      end_sequence ();
 	      emit_insn_before (seq, insn);
 	    }
 	  x = simplify_gen_subreg (recog_data.operand_mode[i], new_rtx,
 				   GET_MODE (new_rtx), SUBREG_BYTE (x));
 	  gcc_assert (x);
 	  break;
 
-
--[[gcc-8.3/gcc/start_sequence()]]
--[[gcc-8.3/gcc/expand_simple_binop()]]
--[[gcc-8.3/gcc/GET_MODE()]]
--[[gcc-8.3/gcc/gen_int_mode()]]
--[[gcc-8.3/gcc/get_insns()]]
--[[gcc-8.3/gcc/end_sequence()]]
--[[gcc-8.3/gcc/emit_insn_before()]]
--[[gcc-8.3/gcc/simplify_gen_subreg()]]
--[[gcc-8.3/gcc/SUBREG_BYTE()]]
--[[gcc-8.3/gcc/gcc_assert()]]

 	default:
 	  continue;
 	}
 
       /* At this point, X contains the new value for the operand.
 	 Validate the new value vs the insn predicate.  Note that
 	 asm insns will have insn_code -1 here.  */
       if (!safe_insn_predicate (insn_code, i, x))
 	{
 	  start_sequence ();
 	  if (REG_P (x))
 	    {
 	      gcc_assert (REGNO (x) <= LAST_VIRTUAL_REGISTER);
 	      x = copy_to_reg (x);
 	    }
 	  else
 	    x = force_reg (insn_data[insn_code].operand[i].mode, x);
 	  seq = get_insns ();
 	  end_sequence ();
 	  if (seq)
 	    emit_insn_before (seq, insn);
 	}
 
-
--[[gcc-8.3/gcc/safe_insn_predicate()]]
--[[gcc-8.3/gcc/start_sequence()]]
--[[gcc-8.3/gcc/REG_P()]]
--[[gcc-8.3/gcc/gcc_assert()]]
--[[gcc-8.3/gcc/REGNO()]]
--[[gcc-8.3/gcc/copy_to_reg()]]
--[[gcc-8.3/gcc/force_reg()]]
--[[gcc-8.3/gcc/get_insns()]]
--[[gcc-8.3/gcc/end_sequence()]]
--[[gcc-8.3/gcc/emit_insn_before()]]

       *recog_data.operand_loc[i] = recog_data.operand[i] = x;
       any_change = true;
     }
 
   if (any_change)
     {
       /* Propagate operand changes into the duplicates.  */
       for (i = 0; i < recog_data.n_dups; ++i)
 	*recog_data.dup_loc[i]
 	  = copy_rtx (recog_data.operand[(unsigned)recog_data.dup_num[i]]);
 
       /* Force re-recognition of the instruction for validation.  */
       INSN_CODE (insn) = -1;
     }
 
-
--[[gcc-8.3/gcc/copy_rtx()]]
--[[gcc-8.3/gcc/INSN_CODE()]]

   if (asm_noperands (PATTERN (insn)) >= 0)
     {
       if (!check_asm_operands (PATTERN (insn)))
 	{
 	  error_for_asm (insn, "impossible constraint in %<asm%>");
 	  /* For asm goto, instead of fixing up all the edges
 	     just clear the template and clear input operands
 	     (asm goto doesn't have any output operands).  */
 	  if (JUMP_P (insn))
 	    {
 	      rtx asm_op = extract_asm_operands (PATTERN (insn));
 	      ASM_OPERANDS_TEMPLATE (asm_op) = ggc_strdup ("");
 	      ASM_OPERANDS_INPUT_VEC (asm_op) = rtvec_alloc (0);
 	      ASM_OPERANDS_INPUT_CONSTRAINT_VEC (asm_op) = rtvec_alloc (0);
 	    }
 	  else
 	    delete_insn (insn);
 	}
     }
-
--[[gcc-8.3/gcc/PATTERN()]]
--[[gcc-8.3/gcc/error_for_asm()]]
--[[gcc-8.3/gcc/JUMP_P()]]
--[[gcc-8.3/gcc/extract_asm_operands()]]
--[[gcc-8.3/gcc/ASM_OPERANDS_TEMPLATE()]]
--[[gcc-8.3/gcc/ggc_strdup()]]
--[[gcc-8.3/gcc/ASM_OPERANDS_INPUT_VEC()]]
--[[gcc-8.3/gcc/rtvec_alloc()]]
--[[gcc-8.3/gcc/ASM_OPERANDS_INPUT_CONSTRAINT_VEC()]]
--[[gcc-8.3/gcc/rtvec_alloc()]]

   else
     {
       if (recog_memoized (insn) < 0)
 	fatal_insn_not_found (insn);
     }
-
--[[gcc-8.3/gcc/recog_memoized()]]
--[[gcc-8.3/gcc/fatal_insn_not_found()]]

 }


*コメント [#yd59f977]

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