gcc-8.3/gcc/curr_insn_transform()
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
*参照元 [#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 b...
current insn to choose the best alternative. It is m...
alternative cost calculation model of former reload p...
because machine descriptions were written to use this...
model can be changed in future. Make commutative ope...
if it is chosen.
if CHECK_ONLY_P is false, do RTL changes to satisfy the
constraints. Return true if any change happened duri...
call.
If CHECK_ONLY_P is true then don't do any transformat...
check that the insn satisfies all constraints. If th...
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_R...
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 trans...
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 alternati...
earlier clobbers. If it is not the case, don't define...
cost equal to 2 for the corresponding register classes...
lra_set_used_insn_alternative (curr_insn, LRA_NON_...
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 a...
reloads; neither are insns that SET cc0. Insns tha...
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 (cu...
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 ha...
the wrong kind of hard reg. For this, we must cons...
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 e...
before address processing because an address legi...
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 equi...
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_c...
{
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 ...
finding an alternative because of memory constraint...
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 alterna...
we chose previously may no longer be valid. */
lra_set_used_insn_alternative (curr_insn, LRA_UNKNOW...
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_AL...
if (lra_dump_file != NULL && reused_alternative_num >=...
fprintf (lra_dump_file, "Reusing alternative %d for ...
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 cer...
operands) then we need to try each alternative twic...
time matching those two operands as if we had excha...
do this, really exchange them in operands.
If we have just tried the alternatives the second t...
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_ins...
error_for_asm (curr_insn,
"inconsistent operand constraints in an %<asm%>");
/* Avoid further trouble with this insn. Don't ge...
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 sw...
them. Update the operand numbers of any reloads al...
pushed. */
if (goal_alt_swapped)
{
if (lra_dump_file != NULL)
fprintf (lra_dump_file, " Commutative operand exchange...
INSN_UID (curr_insn));
/* Swap the duplicates too. */
swap_operands (commutative);
change_p = true;
}
/* Some targets' TARGET_SECONDARY_MEMORY_NEEDED (e.g. ...
too conservatively. So we use the secondary memory...
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 (...
rld_mode = GET_MODE (rld);
sec_mode = targetm.secondary_memory_needed_mode (r...
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 mod...
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, "Chan...
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_num...
-
--[[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...
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)))...
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 ar...
match, with J < I, goal_alt_matches[I] is J. Add I...
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 relo...
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_PSEUD...
{
bool ok_p = in_class_p (reg, goal_alt[i], &new_clas...
if (new_class != NO_REGS && get_reg_class (regno) !...
{
lra_assert (ok_p);
lra_change_class (regno, new_class, " Change to",...
}
}
-
--[[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 (sub...
*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 di...
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 t...
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...
reg, we might improve the code through inheritance...
it does not get a hard register we coalesce memory...
moves later. Ignore move insns to avoid cycling. ...
if (! lra_simple_p
&& lra_undo_inheritance_iter < LRA_MAX_INHERITANC...
&& 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 ...
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 ...
if (goal_alt_matches[i] >= 0)
continue;
/* We should not have an operand with a non-offset...
appearing where an offsettable address will do. It al...
be a case when the address should be special in other ...
not a general one (e.g. it needs no index reg). */
if (goal_alt_matched[i][0] == -1 && goal_alt_offme...
{
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_SPAC...
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, ...
"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 byte...
addr = XEXP (*loc, 0);
lra_emit_move (new_reg, addr);
if (addr != *loc)
emit_move_insn (new_reg, gen_rtx_AND (GET_MODE (new_re...
}
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 a...
just the subreg. Likewise for a strict subreg no...
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 o...
mode wider than a word to ensure that data beyond...
word being reloaded is preserved. Also automatic...
ensure that strict_low_part reloads are made into
OP_INOUT which should already be true from the ba...
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) == ...
{
start_sequence ();
lra_emit_move (type == OP_INOUT ? copy_rtx (old) ...
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][...
== OP_OUT
|| (curr_static_id->operand[goal_alt_matched[i][0]]...
== 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, o...
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][...
== OP_IN))
/* Generate reloads for output and matched inputs. */
match_reload (i, goal_alt_matched[i], outputs, goal_alt...
&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][...
== 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],...
&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 remai...
can avoid using the same register value (see match_rel...
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_reg...
bitmap_set_bit (&lra_optional_reload_pseudos, REGNO (...
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, "Inse...
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]
終了行:
*参照元 [#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 b...
current insn to choose the best alternative. It is m...
alternative cost calculation model of former reload p...
because machine descriptions were written to use this...
model can be changed in future. Make commutative ope...
if it is chosen.
if CHECK_ONLY_P is false, do RTL changes to satisfy the
constraints. Return true if any change happened duri...
call.
If CHECK_ONLY_P is true then don't do any transformat...
check that the insn satisfies all constraints. If th...
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_R...
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 trans...
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 alternati...
earlier clobbers. If it is not the case, don't define...
cost equal to 2 for the corresponding register classes...
lra_set_used_insn_alternative (curr_insn, LRA_NON_...
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 a...
reloads; neither are insns that SET cc0. Insns tha...
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 (cu...
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 ha...
the wrong kind of hard reg. For this, we must cons...
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 e...
before address processing because an address legi...
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 equi...
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_c...
{
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 ...
finding an alternative because of memory constraint...
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 alterna...
we chose previously may no longer be valid. */
lra_set_used_insn_alternative (curr_insn, LRA_UNKNOW...
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_AL...
if (lra_dump_file != NULL && reused_alternative_num >=...
fprintf (lra_dump_file, "Reusing alternative %d for ...
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 cer...
operands) then we need to try each alternative twic...
time matching those two operands as if we had excha...
do this, really exchange them in operands.
If we have just tried the alternatives the second t...
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_ins...
error_for_asm (curr_insn,
"inconsistent operand constraints in an %<asm%>");
/* Avoid further trouble with this insn. Don't ge...
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 sw...
them. Update the operand numbers of any reloads al...
pushed. */
if (goal_alt_swapped)
{
if (lra_dump_file != NULL)
fprintf (lra_dump_file, " Commutative operand exchange...
INSN_UID (curr_insn));
/* Swap the duplicates too. */
swap_operands (commutative);
change_p = true;
}
/* Some targets' TARGET_SECONDARY_MEMORY_NEEDED (e.g. ...
too conservatively. So we use the secondary memory...
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 (...
rld_mode = GET_MODE (rld);
sec_mode = targetm.secondary_memory_needed_mode (r...
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 mod...
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, "Chan...
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_num...
-
--[[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...
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)))...
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 ar...
match, with J < I, goal_alt_matches[I] is J. Add I...
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 relo...
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_PSEUD...
{
bool ok_p = in_class_p (reg, goal_alt[i], &new_clas...
if (new_class != NO_REGS && get_reg_class (regno) !...
{
lra_assert (ok_p);
lra_change_class (regno, new_class, " Change to",...
}
}
-
--[[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 (sub...
*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 di...
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 t...
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...
reg, we might improve the code through inheritance...
it does not get a hard register we coalesce memory...
moves later. Ignore move insns to avoid cycling. ...
if (! lra_simple_p
&& lra_undo_inheritance_iter < LRA_MAX_INHERITANC...
&& 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 ...
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 ...
if (goal_alt_matches[i] >= 0)
continue;
/* We should not have an operand with a non-offset...
appearing where an offsettable address will do. It al...
be a case when the address should be special in other ...
not a general one (e.g. it needs no index reg). */
if (goal_alt_matched[i][0] == -1 && goal_alt_offme...
{
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_SPAC...
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, ...
"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 byte...
addr = XEXP (*loc, 0);
lra_emit_move (new_reg, addr);
if (addr != *loc)
emit_move_insn (new_reg, gen_rtx_AND (GET_MODE (new_re...
}
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 a...
just the subreg. Likewise for a strict subreg no...
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 o...
mode wider than a word to ensure that data beyond...
word being reloaded is preserved. Also automatic...
ensure that strict_low_part reloads are made into
OP_INOUT which should already be true from the ba...
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) == ...
{
start_sequence ();
lra_emit_move (type == OP_INOUT ? copy_rtx (old) ...
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][...
== OP_OUT
|| (curr_static_id->operand[goal_alt_matched[i][0]]...
== 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, o...
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][...
== OP_IN))
/* Generate reloads for output and matched inputs. */
match_reload (i, goal_alt_matched[i], outputs, goal_alt...
&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][...
== 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],...
&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 remai...
can avoid using the same register value (see match_rel...
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_reg...
bitmap_set_bit (&lra_optional_reload_pseudos, REGNO (...
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, "Inse...
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]
ページ名: