/* Code for RTL transformations to satisfy insn constraints.
- Copyright (C) 2010-2014 Free Software Foundation, Inc.
+ Copyright (C) 2010-2015 Free Software Foundation, Inc.
Contributed by Vladimir Makarov <vmakarov@redhat.com>.
This file is part of GCC.
#include "addresses.h"
#include "target.h"
#include "function.h"
+#include "symtab.h"
+#include "flags.h"
+#include "alias.h"
+#include "tree.h"
+#include "expmed.h"
+#include "dojump.h"
+#include "explow.h"
+#include "calls.h"
+#include "emit-rtl.h"
+#include "varasm.h"
+#include "stmt.h"
#include "expr.h"
+#include "predict.h"
+#include "dominance.h"
+#include "cfg.h"
+#include "cfgrtl.h"
#include "basic-block.h"
#include "except.h"
#include "optabs.h"
#include "df.h"
#include "ira.h"
#include "rtl-error.h"
+#include "params.h"
#include "lra-int.h"
/* Value of LRA_CURR_RELOAD_NUM at the beginning of BB of the current
static basic_block curr_bb;
static lra_insn_recog_data_t curr_id;
static struct lra_static_insn_data *curr_static_id;
-static enum machine_mode curr_operand_mode[MAX_RECOG_OPERANDS];
+static machine_mode curr_operand_mode[MAX_RECOG_OPERANDS];
+/* Mode of the register substituted by its equivalence with VOIDmode
+ (e.g. constant) and whose subreg is given operand of the current
+ insn. VOIDmode in all other cases. */
+static machine_mode original_subreg_reg_mode[MAX_RECOG_OPERANDS];
\f
in_class_p (rtx reg, enum reg_class cl, enum reg_class *new_class)
{
enum reg_class rclass, common_class;
- enum machine_mode reg_mode;
+ machine_mode reg_mode;
int class_size, hard_regno, nregs, i, j;
int regno = REGNO (reg);
space AS, and check that each pseudo has the proper kind of hard
reg. */
static int
-valid_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
+valid_address_p (machine_mode mode ATTRIBUTE_UNUSED,
rtx addr, addr_space_t as)
{
#ifdef GO_IF_LEGITIMATE_ADDRESS
|| lra_get_regno_hard_regno (regno) >= 0)
return x;
if ((res = ira_reg_equiv[regno].memory) != NULL_RTX)
- return res;
+ {
+ if (targetm.cannot_substitute_mem_equiv_p (res))
+ return x;
+ return res;
+ }
if ((res = ira_reg_equiv[regno].constant) != NULL_RTX)
return res;
if ((res = ira_reg_equiv[regno].invariant) != NULL_RTX)
if (x == res || CONSTANT_P (res))
return res;
- return lra_eliminate_regs_1 (insn, res, GET_MODE (res), false, false, true);
+ return lra_eliminate_regs_1 (insn, res, GET_MODE (res),
+ false, false, 0, true);
}
/* Set up curr_operand_mode. */
int nop = curr_static_id->n_operands;
for (int i = 0; i < nop; i++)
{
- enum machine_mode mode = GET_MODE (*curr_id->operand_loc[i]);
+ machine_mode mode = GET_MODE (*curr_id->operand_loc[i]);
if (mode == VOIDmode)
{
/* The .md mode for address operands is the mode of the
reused the already created input reload pseudo. Use TITLE to
describe new registers for debug purposes. */
static bool
-get_reload_reg (enum op_type type, enum machine_mode mode, rtx original,
+get_reload_reg (enum op_type type, machine_mode mode, rtx original,
enum reg_class rclass, bool in_subreg_p,
const char *title, rtx *result_reg)
{
/* A version of regno_ok_for_base_p for use here, when all pseudos
should count as OK. Arguments as for regno_ok_for_base_p. */
static inline bool
-ok_for_base_p_nonstrict (rtx reg, enum machine_mode mode, addr_space_t as,
+ok_for_base_p_nonstrict (rtx reg, machine_mode mode, addr_space_t as,
enum rtx_code outer_code, enum rtx_code index_code)
{
unsigned regno = REGNO (reg);
REGNO1 + lra_constraint_offset (REGNO1, MODE1)
== REGNO2 + lra_constraint_offset (REGNO2, MODE2) */
int
-lra_constraint_offset (int regno, enum machine_mode mode)
+lra_constraint_offset (int regno, machine_mode mode)
{
lra_assert (regno < FIRST_PSEUDO_REGISTER);
if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (mode) > UNITS_PER_WORD
slow:
+ if (code == REG && REG_P (y))
+ return REGNO (x) == REGNO (y);
+
if (code == REG && GET_CODE (y) == SUBREG && REG_P (SUBREG_REG (y))
&& x == SUBREG_REG (y))
return true;
return false;
case LABEL_REF:
- return XEXP (x, 0) == XEXP (y, 0);
+ return LABEL_REF_LABEL (x) == LABEL_REF_LABEL (y);
case SYMBOL_REF:
return XSTR (x, 0) == XSTR (y, 0);
rtx_insn **before, rtx_insn **after)
{
int i, in;
- rtx new_in_reg, new_out_reg, reg, clobber;
- enum machine_mode inmode, outmode;
+ rtx new_in_reg, new_out_reg, reg;
+ machine_mode inmode, outmode;
rtx in_rtx = *curr_id->operand_loc[ins[0]];
rtx out_rtx = out < 0 ? in_rtx : *curr_id->operand_loc[out];
NEW_OUT_REG living above. We add clobber clause for
this. This is just a temporary clobber. We can remove
it at the end of LRA work. */
- clobber = emit_clobber (new_out_reg);
+ rtx_insn *clobber = emit_clobber (new_out_reg);
LRA_TEMP_CLOBBER_P (PATTERN (clobber)) = 1;
LRA_SUBREG_P (new_in_reg) = 1;
if (GET_CODE (in_rtx) == SUBREG)
LRA_SUBREG_P (mem_pseudo) = 1;
}
}
- return as_a <rtx_insn *> (to_p
- ? gen_move_insn (mem_pseudo, val)
- : gen_move_insn (val, mem_pseudo));
+ return to_p ? gen_move_insn (mem_pseudo, val)
+ : gen_move_insn (val, mem_pseudo);
}
/* Process a special case insn (register move), return true if we
check_and_process_move (bool *change_p, bool *sec_mem_p ATTRIBUTE_UNUSED)
{
int sregno, dregno;
- rtx dest, src, dreg, sreg, old_sreg, new_reg, scratch_reg;
+ rtx dest, src, dreg, sreg, new_reg, scratch_reg;
rtx_insn *before;
enum reg_class dclass, sclass, secondary_class;
- enum machine_mode sreg_mode;
secondary_reload_info sri;
lra_assert (curr_insn_set != NULL_RTX);
were a right class for the pseudo, secondary_... hooks usually
are not define for ALL_REGS. */
return false;
- sreg_mode = GET_MODE (sreg);
- old_sreg = sreg;
if (REG_P (sreg))
sclass = get_reg_class (REGNO (sreg));
if (sclass == ALL_REGS)
sri.icode = CODE_FOR_nothing;
sri.extra_cost = 0;
secondary_class
- = (enum reg_class) targetm.secondary_reload (true, sreg,
+ = (enum reg_class) targetm.secondary_reload (true, src,
(reg_class_t) dclass,
- sreg_mode, &sri);
+ GET_MODE (src), &sri);
/* Check the target hook consistency. */
lra_assert
((secondary_class == NO_REGS && sri.icode == CODE_FOR_nothing)
*change_p = true;
new_reg = NULL_RTX;
if (secondary_class != NO_REGS)
- new_reg = lra_create_new_reg_with_unique_value (sreg_mode, NULL_RTX,
+ new_reg = lra_create_new_reg_with_unique_value (GET_MODE (src), NULL_RTX,
secondary_class,
"secondary");
start_sequence ();
- if (old_sreg != sreg)
- sreg = copy_rtx (sreg);
if (sri.icode == CODE_FOR_nothing)
- lra_emit_move (new_reg, sreg);
+ lra_emit_move (new_reg, src);
else
{
enum reg_class scratch_class;
(insn_data[sri.icode].operand[2].mode, NULL_RTX,
scratch_class, "scratch"));
emit_insn (GEN_FCN (sri.icode) (new_reg != NULL_RTX ? new_reg : dest,
- sreg, scratch_reg));
+ src, scratch_reg));
}
before = get_insns ();
end_sequence ();
lra_process_new_insns (curr_insn, before, NULL, "Inserting the move");
if (new_reg != NULL_RTX)
- {
- if (GET_CODE (src) == SUBREG)
- SUBREG_REG (src) = new_reg;
- else
- SET_SRC (curr_insn_set) = new_reg;
- }
+ SET_SRC (curr_insn_set) = new_reg;
else
{
if (lra_dump_file != NULL)
insn. */
static int curr_swapped;
-/* Arrange for address element *LOC to be a register of class CL.
- Add any input reloads to list BEFORE. AFTER is nonnull if *LOC is an
- automodified value; handle that case by adding the required output
- reloads to list AFTER. Return true if the RTL was changed. */
+/* if CHECK_ONLY_P is false, arrange for address element *LOC to be a
+ register of class CL. Add any input reloads to list BEFORE. AFTER
+ is nonnull if *LOC is an automodified value; handle that case by
+ adding the required output reloads to list AFTER. Return true if
+ the RTL was changed.
+
+ if CHECK_ONLY_P is true, check that the *LOC is a correct address
+ register. Return false if the address register is correct. */
static bool
-process_addr_reg (rtx *loc, rtx_insn **before, rtx_insn **after,
+process_addr_reg (rtx *loc, bool check_only_p, rtx_insn **before, rtx_insn **after,
enum reg_class cl)
{
int regno;
enum reg_class rclass, new_class;
rtx reg;
rtx new_reg;
- enum machine_mode mode;
+ machine_mode mode;
bool subreg_p, before_p = false;
subreg_p = GET_CODE (*loc) == SUBREG;
mode = GET_MODE (reg);
if (! REG_P (reg))
{
+ if (check_only_p)
+ return true;
/* Always reload memory in an address even if the target supports
such addresses. */
new_reg = lra_create_new_reg_with_unique_value (mode, reg, cl, "address");
{
regno = REGNO (reg);
rclass = get_reg_class (regno);
- if ((*loc = get_equiv_with_elimination (reg, curr_insn)) != reg)
+ if (! check_only_p
+ && (*loc = get_equiv_with_elimination (reg, curr_insn)) != reg)
{
if (lra_dump_file != NULL)
{
}
if (*loc != reg || ! in_class_p (reg, cl, &new_class))
{
+ if (check_only_p)
+ return true;
reg = *loc;
if (get_reload_reg (after == NULL ? OP_IN : OP_INOUT,
mode, reg, cl, subreg_p, "address", &new_reg))
}
else if (new_class != NO_REGS && rclass != new_class)
{
+ if (check_only_p)
+ return true;
lra_change_class (regno, new_class, " Change to", true);
return false;
}
}
}
-static int valid_address_p (enum machine_mode mode, rtx addr, addr_space_t as);
+static int valid_address_p (machine_mode mode, rtx addr, addr_space_t as);
/* Make reloads for subreg in operand NOP with internal subreg mode
REG_MODE, add new reloads for further processing. Return true if
- any reload was generated. */
+ any change was done. */
static bool
-simplify_operand_subreg (int nop, enum machine_mode reg_mode)
+simplify_operand_subreg (int nop, machine_mode reg_mode)
{
int hard_regno;
rtx_insn *before, *after;
- enum machine_mode mode;
+ machine_mode mode, innermode;
rtx reg, new_reg;
rtx operand = *curr_id->operand_loc[nop];
enum reg_class regclass;
mode = GET_MODE (operand);
reg = SUBREG_REG (operand);
+ innermode = GET_MODE (reg);
type = curr_static_id->operand[nop].type;
/* If we change address for paradoxical subreg of memory, the
address might violate the necessary alignment or the access might
alter_subreg (curr_id->operand_loc[nop], false);
subst = *curr_id->operand_loc[nop];
lra_assert (MEM_P (subst));
- if (! valid_address_p (GET_MODE (reg), XEXP (reg, 0),
+ if (! valid_address_p (innermode, XEXP (reg, 0),
MEM_ADDR_SPACE (reg))
|| valid_address_p (GET_MODE (subst), XEXP (subst, 0),
MEM_ADDR_SPACE (subst)))
alter_subreg (curr_id->operand_loc[nop], false);
return true;
}
+ else if (CONSTANT_P (reg))
+ {
+ /* Try to simplify subreg of constant. It is usually result of
+ equivalence substitution. */
+ if (innermode == VOIDmode
+ && (innermode = original_subreg_reg_mode[nop]) == VOIDmode)
+ innermode = curr_static_id->operand[nop].mode;
+ if ((new_reg = simplify_subreg (mode, reg, innermode,
+ SUBREG_BYTE (operand))) != NULL_RTX)
+ {
+ *curr_id->operand_loc[nop] = new_reg;
+ return true;
+ }
+ }
/* Put constant into memory when we have mixed modes. It generates
a better code in most cases as it does not need a secondary
reload memory. It also prevents LRA looping when LRA is using
&& (hard_regno = lra_get_regno_hard_regno (REGNO (reg))) >= 0
/* Don't reload paradoxical subregs because we could be looping
having repeatedly final regno out of hard regs range. */
- && (hard_regno_nregs[hard_regno][GET_MODE (reg)]
+ && (hard_regno_nregs[hard_regno][innermode]
>= hard_regno_nregs[hard_regno][mode])
- && simplify_subreg_regno (hard_regno, GET_MODE (reg),
+ && simplify_subreg_regno (hard_regno, innermode,
SUBREG_BYTE (operand), mode) < 0
/* Don't reload subreg for matching reload. It is actually
valid subreg in LRA. */
bitmap_set_bit (&lra_subreg_reload_pseudos, REGNO (new_reg));
insert_before = (type != OP_OUT
- || GET_MODE_SIZE (GET_MODE (reg)) > GET_MODE_SIZE (mode));
+ || GET_MODE_SIZE (innermode) > GET_MODE_SIZE (mode));
insert_after = (type != OP_IN);
insert_move_for_subreg (insert_before ? &before : NULL,
insert_after ? &after : NULL,
else if (REG_P (reg)
&& REGNO (reg) >= FIRST_PSEUDO_REGISTER
&& (hard_regno = lra_get_regno_hard_regno (REGNO (reg))) >= 0
- && (hard_regno_nregs[hard_regno][GET_MODE (reg)]
+ && (hard_regno_nregs[hard_regno][innermode]
< hard_regno_nregs[hard_regno][mode])
&& (regclass = lra_get_allocno_class (REGNO (reg)))
&& (type != OP_IN
bool insert_before, insert_after;
PUT_MODE (new_reg, mode);
- subreg = simplify_gen_subreg (GET_MODE (reg), new_reg, mode, 0);
+ subreg = simplify_gen_subreg (innermode, new_reg, mode, 0);
bitmap_set_bit (&lra_subreg_reload_pseudos, REGNO (new_reg));
insert_before = (type != OP_OUT);
uses_hard_regs_p (rtx x, HARD_REG_SET set)
{
int i, j, x_hard_regno;
- enum machine_mode mode;
+ machine_mode mode;
const char *fmt;
enum rtx_code code;
return in_class_p (reg, cl, NULL);
}
+/* Return true if SET of RCLASS contains no hard regs which can be
+ used in MODE. */
+static bool
+prohibited_class_reg_set_mode_p (enum reg_class rclass,
+ HARD_REG_SET &set,
+ enum machine_mode mode)
+{
+ HARD_REG_SET temp;
+
+ lra_assert (hard_reg_set_subset_p (reg_class_contents[rclass], set));
+ COPY_HARD_REG_SET (temp, set);
+ AND_COMPL_HARD_REG_SET (temp, lra_no_alloc_regs);
+ return (hard_reg_set_subset_p
+ (temp, ira_prohibited_class_mode_regs[rclass][mode]));
+}
+
/* Major function to choose the current insn alternative and what
operands should be reloaded and how. If ONLY_ALTERNATIVE is not
negative we should consider only this alternative. Return false if
then REJECT is ignored, but otherwise it gets this much counted
against it in addition to the reloading needed. */
int reject;
+ int op_reject;
/* The number of elements in the following array. */
int early_clobbered_regs_num;
/* Numbers of operands which are early clobber registers. */
otherwise NULL. */
rtx operand_reg[MAX_RECOG_OPERANDS];
int hard_regno[MAX_RECOG_OPERANDS];
- enum machine_mode biggest_mode[MAX_RECOG_OPERANDS];
+ machine_mode biggest_mode[MAX_RECOG_OPERANDS];
int reload_nregs, reload_sum;
bool costly_p;
enum reg_class cl;
together, the second alternatives go together, etc.
First loop over alternatives. */
- alternative_mask enabled = curr_id->enabled_alternatives;
+ alternative_mask preferred = curr_id->preferred_alternatives;
if (only_alternative >= 0)
- enabled &= ALTERNATIVE_BIT (only_alternative);
+ preferred &= ALTERNATIVE_BIT (only_alternative);
for (nalt = 0; nalt < n_alternatives; nalt++)
{
/* Loop over operands for one constraint alternative. */
- if (!TEST_BIT (enabled, nalt))
+ if (!TEST_BIT (preferred, nalt))
continue;
overall = losers = reject = reload_nregs = reload_sum = 0;
bool this_alternative_match_win, this_alternative_win;
bool this_alternative_offmemok;
bool scratch_p;
- enum machine_mode mode;
+ machine_mode mode;
enum constraint_num cn;
opalt_num = nalt * n_operands + nop;
track. */
lra_assert (*p != 0 && *p != ',');
+ op_reject = 0;
/* Scan this alternative's specs for this operand; set WIN
if the operand fits any letter in this alternative.
Otherwise, clear BADOP if this operand could fit some
early_clobber_p = true;
break;
+ case '$':
+ op_reject += LRA_MAX_REJECT;
+ break;
+ case '^':
+ op_reject += LRA_LOSER_COST_FACTOR;
+ break;
+
case '#':
/* Ignore rest of this alternative. */
c = '\0';
int const_to_mem = 0;
bool no_regs_p;
+ reject += op_reject;
/* Never do output reload of stack pointer. It makes
impossible to do elimination when SP is changed in
RTL. */
goto fail;
}
+ /* Alternative loses if it required class pseudo can not
+ hold value of required mode. Such insns can be
+ described by insn definitions with mode iterators. */
+ if (GET_MODE (*curr_id->operand_loc[nop]) != VOIDmode
+ && ! hard_reg_set_empty_p (this_alternative_set)
+ /* It is common practice for constraints to use a
+ class which does not have actually enough regs to
+ hold the value (e.g. x86 AREG for mode requiring
+ more one general reg). Therefore we have 2
+ conditions to check that the reload pseudo can
+ not hold the mode value. */
+ && ! HARD_REGNO_MODE_OK (ira_class_hard_regs
+ [this_alternative][0],
+ GET_MODE (*curr_id->operand_loc[nop]))
+ /* The above condition is not enough as the first
+ reg in ira_class_hard_regs can be not aligned for
+ multi-words mode values. */
+ && (prohibited_class_reg_set_mode_p
+ (this_alternative, this_alternative_set,
+ GET_MODE (*curr_id->operand_loc[nop]))))
+ {
+ if (lra_dump_file != NULL)
+ fprintf (lra_dump_file,
+ " alt=%d: reload pseudo for op %d "
+ " can not hold the mode value -- refuse\n",
+ nalt, nop);
+ goto fail;
+ }
+
/* Check strong discouragement of reload of non-constant
into class THIS_ALTERNATIVE. */
if (! CONSTANT_P (op) && ! no_regs_p
: *ad->disp_term);
if (!valid_address_p (ad->mode, new_inner, ad->as))
return NULL_RTX;
- insn = emit_insn (gen_rtx_SET (ad->mode, new_reg, *ad->base_term));
+ insn = emit_insn (gen_rtx_SET (new_reg, *ad->base_term));
code = recog_memoized (insn);
if (code < 0)
{
return change_p;
}
-/* Major function to make reloads for an address in operand NOP.
- The supported cases are:
+/* Major function to make reloads for an address in operand NOP or
+ check its correctness (If CHECK_ONLY_P is true). The supported
+ cases are:
1) an address that existed before LRA started, at which point it
must have been valid. These addresses are subject to elimination
address. Return true for any RTL change.
The function is a helper function which does not produce all
- transformations which can be necessary. It does just basic steps.
- To do all necessary transformations use function
- process_address. */
+ transformations (when CHECK_ONLY_P is false) which can be
+ necessary. It does just basic steps. To do all necessary
+ transformations use function process_address. */
static bool
-process_address_1 (int nop, rtx_insn **before, rtx_insn **after)
+process_address_1 (int nop, bool check_only_p,
+ rtx_insn **before, rtx_insn **after)
{
struct address_info ad;
rtx new_reg;
rtx op = *curr_id->operand_loc[nop];
const char *constraint = curr_static_id->operand[nop].constraint;
enum constraint_num cn = lookup_constraint (constraint);
- bool change_p;
+ bool change_p = false;
if (insn_extra_address_constraint (cn))
decompose_lea_address (&ad, curr_id->operand_loc[nop]);
decompose_mem_address (&ad, SUBREG_REG (op));
else
return false;
- change_p = equiv_address_substitution (&ad);
+ /* If INDEX_REG_CLASS is assigned to base_term already and isn't to
+ index_term, swap them so to avoid assigning INDEX_REG_CLASS to both
+ when INDEX_REG_CLASS is a single register class. */
+ if (ad.base_term != NULL
+ && ad.index_term != NULL
+ && ira_class_hard_regs_num[INDEX_REG_CLASS] == 1
+ && REG_P (*ad.base_term)
+ && REG_P (*ad.index_term)
+ && in_class_p (*ad.base_term, INDEX_REG_CLASS, NULL)
+ && ! in_class_p (*ad.index_term, INDEX_REG_CLASS, NULL))
+ {
+ std::swap (ad.base, ad.index);
+ std::swap (ad.base_term, ad.index_term);
+ }
+ if (! check_only_p)
+ change_p = equiv_address_substitution (&ad);
if (ad.base_term != NULL
&& (process_addr_reg
- (ad.base_term, before,
+ (ad.base_term, check_only_p, before,
(ad.autoinc_p
&& !(REG_P (*ad.base_term)
&& find_regno_note (curr_insn, REG_DEAD,
*ad.base_term2 = *ad.base_term;
}
if (ad.index_term != NULL
- && process_addr_reg (ad.index_term, before, NULL, INDEX_REG_CLASS))
+ && process_addr_reg (ad.index_term, check_only_p,
+ before, NULL, INDEX_REG_CLASS))
change_p = true;
/* Target hooks sometimes don't treat extra-constraint addresses as
&& satisfies_address_constraint_p (&ad, cn))
return change_p;
+ if (check_only_p)
+ return change_p;
+
/* There are three cases where the shape of *AD.INNER may now be invalid:
1) the original address was valid, but either elimination or
rtx addr = *ad.inner;
new_reg = lra_create_new_reg (Pmode, NULL_RTX, cl, "addr");
-#ifdef HAVE_lo_sum
- {
- rtx_insn *insn;
- rtx_insn *last = get_last_insn ();
-
- /* addr => lo_sum (new_base, addr), case (2) above. */
- insn = emit_insn (gen_rtx_SET
- (VOIDmode, new_reg,
- gen_rtx_HIGH (Pmode, copy_rtx (addr))));
- code = recog_memoized (insn);
- if (code >= 0)
- {
- *ad.inner = gen_rtx_LO_SUM (Pmode, new_reg, addr);
- if (! valid_address_p (ad.mode, *ad.outer, ad.as))
- {
- /* Try to put lo_sum into register. */
- insn = emit_insn (gen_rtx_SET
- (VOIDmode, new_reg,
- gen_rtx_LO_SUM (Pmode, new_reg, addr)));
- code = recog_memoized (insn);
- if (code >= 0)
- {
- *ad.inner = new_reg;
- if (! valid_address_p (ad.mode, *ad.outer, ad.as))
- {
- *ad.inner = addr;
- code = -1;
- }
- }
-
- }
- }
- if (code < 0)
- delete_insns_since (last);
- }
-#endif
+ if (HAVE_lo_sum)
+ {
+ rtx_insn *insn;
+ rtx_insn *last = get_last_insn ();
+
+ /* addr => lo_sum (new_base, addr), case (2) above. */
+ insn = emit_insn (gen_rtx_SET
+ (new_reg,
+ gen_rtx_HIGH (Pmode, copy_rtx (addr))));
+ code = recog_memoized (insn);
+ if (code >= 0)
+ {
+ *ad.inner = gen_rtx_LO_SUM (Pmode, new_reg, addr);
+ if (! valid_address_p (ad.mode, *ad.outer, ad.as))
+ {
+ /* Try to put lo_sum into register. */
+ insn = emit_insn (gen_rtx_SET
+ (new_reg,
+ gen_rtx_LO_SUM (Pmode, new_reg, addr)));
+ code = recog_memoized (insn);
+ if (code >= 0)
+ {
+ *ad.inner = new_reg;
+ if (! valid_address_p (ad.mode, *ad.outer, ad.as))
+ {
+ *ad.inner = addr;
+ code = -1;
+ }
+ }
+
+ }
+ }
+ if (code < 0)
+ delete_insns_since (last);
+ }
+
if (code < 0)
{
/* addr => new_base, case (2) above. */
delete_insns_since (PREV_INSN (last_insn));
}
}
+ /* Try if target can split displacement into legitimite new disp
+ and offset. If it's the case, we replace the last insn with
+ insns for base + offset => new_reg and set new_reg + new disp
+ to *ad.inner. */
+ last_insn = get_last_insn ();
+ if ((set = single_set (last_insn)) != NULL_RTX
+ && GET_CODE (SET_SRC (set)) == PLUS
+ && REG_P (XEXP (SET_SRC (set), 0))
+ && REGNO (XEXP (SET_SRC (set), 0)) < FIRST_PSEUDO_REGISTER
+ && CONST_INT_P (XEXP (SET_SRC (set), 1)))
+ {
+ rtx addend, disp = XEXP (SET_SRC (set), 1);
+ if (targetm.legitimize_address_displacement (&disp, &addend,
+ ad.mode))
+ {
+ rtx_insn *new_insns;
+ start_sequence ();
+ lra_emit_add (new_reg, XEXP (SET_SRC (set), 0), addend);
+ new_insns = get_insns ();
+ end_sequence ();
+ new_reg = gen_rtx_PLUS (Pmode, new_reg, disp);
+ delete_insns_since (PREV_INSN (last_insn));
+ add_insn (new_insns);
+ insns = get_insns ();
+ }
+ }
end_sequence ();
emit_insn (insns);
*ad.inner = new_reg;
return true;
}
-/* Do address reloads until it is necessary. Use process_address_1 as
- a helper function. Return true for any RTL changes. */
+/* If CHECK_ONLY_P is false, do address reloads until it is necessary.
+ Use process_address_1 as a helper function. Return true for any
+ RTL changes.
+
+ If CHECK_ONLY_P is true, just check address correctness. Return
+ false if the address correct. */
static bool
-process_address (int nop, rtx_insn **before, rtx_insn **after)
+process_address (int nop, bool check_only_p,
+ rtx_insn **before, rtx_insn **after)
{
bool res = false;
- while (process_address_1 (nop, before, after))
- res = true;
+ while (process_address_1 (nop, check_only_p, before, after))
+ {
+ if (check_only_p)
+ return true;
+ res = true;
+ }
return res;
}
&& (sclass = get_op_class (src)) != NO_REGS
/* The backend guarantees that register moves of cost 2
never need reloads. */
- && targetm.register_move_cost (GET_MODE (src), dclass, sclass) == 2);
+ && targetm.register_move_cost (GET_MODE (src), sclass, dclass) == 2);
}
/* Swap operands NOP and NOP + 1. */
static inline void
swap_operands (int nop)
{
- enum machine_mode mode = curr_operand_mode[nop];
- curr_operand_mode[nop] = curr_operand_mode[nop + 1];
- curr_operand_mode[nop + 1] = mode;
- rtx x = *curr_id->operand_loc[nop];
- *curr_id->operand_loc[nop] = *curr_id->operand_loc[nop + 1];
- *curr_id->operand_loc[nop + 1] = x;
+ std::swap (curr_operand_mode[nop], curr_operand_mode[nop + 1]);
+ std::swap (original_subreg_reg_mode[nop], original_subreg_reg_mode[nop + 1]);
+ std::swap (*curr_id->operand_loc[nop], *curr_id->operand_loc[nop + 1]);
/* Swap the duplicates too. */
lra_update_dup (curr_id, nop);
lra_update_dup (curr_id, nop + 1);
model can be changed in future. Make commutative operand exchange
if it is chosen.
- Return true if some RTL changes happened during function call. */
+ 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 (void)
+curr_insn_transform (bool check_only_p)
{
int i, j, k;
int n_operands;
if (JUMP_P (curr_insn) || CALL_P (curr_insn))
no_output_reloads_p = true;
-#ifdef HAVE_cc0
- if (reg_referenced_p (cc0_rtx, PATTERN (curr_insn)))
+ if (HAVE_cc0 && reg_referenced_p (cc0_rtx, PATTERN (curr_insn)))
no_input_reloads_p = true;
- if (reg_set_p (cc0_rtx, PATTERN (curr_insn)))
+ if (HAVE_cc0 && reg_set_p (cc0_rtx, PATTERN (curr_insn)))
no_output_reloads_p = true;
-#endif
n_operands = curr_static_id->n_operands;
n_alternatives = curr_static_id->n_alternatives;
curr_swapped = false;
goal_alt_swapped = false;
- /* 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 = *curr_id->operand_loc[i];
- rtx subst, old = op;
- bool op_change_p = false;
-
- if (GET_CODE (old) == SUBREG)
- old = SUBREG_REG (old);
- subst = get_equiv_with_elimination (old, curr_insn);
- if (subst != old)
- {
- subst = copy_rtx (subst);
- lra_assert (REG_P (old));
- if (GET_CODE (op) == SUBREG)
- SUBREG_REG (op) = subst;
- else
- *curr_id->operand_loc[i] = subst;
- 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);
- }
- }
+ 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 = *curr_id->operand_loc[i];
+ rtx subst, old = op;
+ bool op_change_p = false;
+
+ if (GET_CODE (old) == SUBREG)
+ old = SUBREG_REG (old);
+ subst = get_equiv_with_elimination (old, curr_insn);
+ original_subreg_reg_mode[i] = VOIDmode;
+ if (subst != old)
+ {
+ 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);
+ }
+ }
/* 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, &before, &after))
+ && process_address (i, check_only_p, &before, &after))
{
+ if (check_only_p)
+ return true;
change_p = true;
lra_update_dup (curr_id, i);
}
we chose previously may no longer be valid. */
lra_set_used_insn_alternative (curr_insn, -1);
- if (curr_insn_set != NULL_RTX
+ if (! check_only_p && curr_insn_set != NULL_RTX
&& check_and_process_move (&change_p, &sec_mem_p))
return change_p;
try_swapped:
- reused_alternative_num = curr_id->used_insn_alternative;
+ reused_alternative_num = check_only_p ? -1 : 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;
+
/* 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
if (use_sec_mem_p)
{
rtx new_reg, src, dest, rld;
- enum machine_mode sec_mode, rld_mode;
+ machine_mode sec_mode, rld_mode;
lra_assert (sec_mem_p);
lra_assert (curr_static_id->operand[0].type == OP_OUT
char c;
rtx op = *curr_id->operand_loc[i];
rtx subreg = NULL_RTX;
- enum machine_mode mode = curr_operand_mode[i];
+ machine_mode mode = curr_operand_mode[i];
if (GET_CODE (op) == SUBREG)
{
*curr_id->operand_loc[i] = tem;
lra_update_dup (curr_id, i);
- process_address (i, &before, &after);
+ process_address (i, false, &before, &after);
/* If the alternative accepts constant pool refs directly
there will be no reload needed at all. */
&& 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))
}
else if (goal_alt_matched[i][0] == -1)
{
- enum machine_mode mode;
+ machine_mode mode;
rtx reg, *loc;
int hard_regno, byte;
enum op_type type = curr_static_id->operand[i].type;
(ira_class_hard_regs[goal_alt[i]][0],
GET_MODE (reg), byte, mode) >= 0)))))
{
+ if (type == OP_OUT)
+ type = OP_INOUT;
loc = &SUBREG_REG (*loc);
mode = GET_MODE (*loc);
}
return change_p;
}
+/* Return true if INSN satisfies all constraints. In other words, no
+ reload insns are needed. */
+bool
+lra_constrain_insn (rtx_insn *insn)
+{
+ int saved_new_regno_start = new_regno_start;
+ int saved_new_insn_uid_start = new_insn_uid_start;
+ bool change_p;
+
+ curr_insn = insn;
+ curr_id = lra_get_insn_recog_data (curr_insn);
+ curr_static_id = curr_id->insn_static_data;
+ new_insn_uid_start = get_max_uid ();
+ new_regno_start = max_reg_num ();
+ change_p = curr_insn_transform (true);
+ new_regno_start = saved_new_regno_start;
+ new_insn_uid_start = saved_new_insn_uid_start;
+ return ! change_p;
+}
+
/* Return true if X is in LIST. */
static bool
in_list_p (rtx x, rtx list)
return false;
}
+/* Return true if X contains a symbol reg. */
+static bool
+contains_symbol_ref_p (rtx x)
+{
+ int i, j;
+ const char *fmt;
+ enum rtx_code code;
+
+ code = GET_CODE (x);
+ if (code == SYMBOL_REF)
+ return true;
+ fmt = GET_RTX_FORMAT (code);
+ for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ {
+ if (fmt[i] == 'e')
+ {
+ if (contains_symbol_ref_p (XEXP (x, i)))
+ return true;
+ }
+ else if (fmt[i] == 'E')
+ {
+ for (j = XVECLEN (x, i) - 1; j >= 0; j--)
+ if (contains_symbol_ref_p (XVECEXP (x, i, j)))
+ return true;
+ }
+ }
+ return false;
+}
+
/* Process all regs in location *LOC and change them on equivalent
substitution. Return true if any change was done. */
static bool
/* The current iteration number of this LRA pass. */
int lra_constraint_iter;
-/* The current iteration number of this LRA pass after the last spill
- pass. */
-int lra_constraint_iter_after_spill;
-
/* True if we substituted equiv which needs checking register
allocation correctness because the equivalent value contains
allocatable hard registers or when we restore multi-register
/* Return true if X contains a pseudo dying in INSN. */
static bool
-dead_pseudo_p (rtx x, rtx insn)
+dead_pseudo_p (rtx x, rtx_insn *insn)
{
int i, j;
const char *fmt;
if (lra_dump_file != NULL)
fprintf (lra_dump_file, "\n********** Local #%d: **********\n\n",
lra_constraint_iter);
- lra_constraint_iter_after_spill++;
- if (lra_constraint_iter_after_spill > LRA_MAX_CONSTRAINT_ITERATION_NUMBER)
- internal_error
- ("Maximum number of LRA constraint passes is achieved (%d)\n",
- LRA_MAX_CONSTRAINT_ITERATION_NUMBER);
changed_p = false;
- lra_risky_transformations_p = false;
+ if (pic_offset_table_rtx
+ && REGNO (pic_offset_table_rtx) >= FIRST_PSEUDO_REGISTER)
+ lra_risky_transformations_p = true;
+ else
+ lra_risky_transformations_p = false;
new_insn_uid_start = get_max_uid ();
new_regno_start = first_p ? lra_constraint_new_regno_start : max_reg_num ();
/* Mark used hard regs for target stack size calulations. */
paradoxical subregs. */
|| (MEM_P (x)
&& (GET_MODE_SIZE (lra_reg_info[i].biggest_mode)
- > GET_MODE_SIZE (GET_MODE (x)))))
+ > GET_MODE_SIZE (GET_MODE (x))))
+ || (pic_offset_table_rtx
+ && ((CONST_POOL_OK_P (PSEUDO_REGNO_MODE (i), x)
+ && (targetm.preferred_reload_class
+ (x, lra_get_allocno_class (i)) == NO_REGS))
+ || contains_symbol_ref_p (x))))
ira_reg_equiv[i].defined_p = false;
if (contains_reg_p (x, false, true))
ira_reg_equiv[i].profitable_p = false;
curr_static_id = curr_id->insn_static_data;
init_curr_insn_input_reloads ();
init_curr_operand_mode ();
- if (curr_insn_transform ())
+ if (curr_insn_transform (false))
changed_p = true;
/* Check non-transformed insns too for equiv change as USE
or CLOBBER don't need reloads but can contain pseudos
usage_insns[regno].check = 0;
}
-/* Replace all references to register OLD_REGNO in *LOC with pseudo
- register NEW_REG. Return true if any change was made. */
-static bool
-substitute_pseudo (rtx *loc, int old_regno, rtx new_reg)
-{
- rtx x = *loc;
- bool result = false;
- enum rtx_code code;
- const char *fmt;
- int i, j;
-
- if (x == NULL_RTX)
- return false;
-
- code = GET_CODE (x);
- if (code == REG && (int) REGNO (x) == old_regno)
- {
- enum machine_mode mode = GET_MODE (*loc);
- enum machine_mode inner_mode = GET_MODE (new_reg);
-
- if (mode != inner_mode)
- {
- if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (inner_mode)
- || ! SCALAR_INT_MODE_P (inner_mode))
- new_reg = gen_rtx_SUBREG (mode, new_reg, 0);
- else
- new_reg = gen_lowpart_SUBREG (mode, new_reg);
- }
- *loc = new_reg;
- return true;
- }
-
- /* Scan all the operand sub-expressions. */
- fmt = GET_RTX_FORMAT (code);
- for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
- {
- if (fmt[i] == 'e')
- {
- if (substitute_pseudo (&XEXP (x, i), old_regno, new_reg))
- result = true;
- }
- else if (fmt[i] == 'E')
- {
- for (j = XVECLEN (x, i) - 1; j >= 0; j--)
- if (substitute_pseudo (&XVECEXP (x, i, j), old_regno, new_reg))
- result = true;
- }
- }
- return result;
-}
-
-/* Call substitute_pseudo within an insn. This won't update the insn ptr,
- just the contents of the insn. */
-
-static bool
-substitute_pseudo_within_insn (rtx_insn *insn, int old_regno, rtx new_reg)
-{
- rtx loc = insn;
- return substitute_pseudo (&loc, old_regno, new_reg);
-}
-
/* Return first non-debug insn in list USAGE_INSNS. */
static rtx_insn *
skip_usage_debug_insns (rtx usage_insns)
}
return false;
}
- substitute_pseudo_within_insn (insn, original_regno, new_reg);
+ lra_substitute_pseudo_within_insn (insn, original_regno, new_reg);
lra_update_insn_regno_info (insn);
if (! def_p)
/* We now have a new usage insn for original regno. */
lra_assert (DEBUG_INSN_P (usage_insn));
next_usage_insns = XEXP (next_usage_insns, 1);
}
- substitute_pseudo (&usage_insn, original_regno, new_reg);
+ lra_substitute_pseudo (&usage_insn, original_regno, new_reg);
lra_update_insn_regno_info (as_a <rtx_insn *> (usage_insn));
if (lra_dump_file != NULL)
{
" Inheritance reuse change %d->%d (bb%d):\n",
original_regno, REGNO (new_reg),
BLOCK_FOR_INSN (usage_insn)->index);
- dump_insn_slim (lra_dump_file, usage_insn);
+ dump_insn_slim (lra_dump_file, as_a <rtx_insn *> (usage_insn));
}
}
if (lra_dump_file != NULL)
lra_assert (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] >= 0);
return (usage_insns[regno].calls_num < calls_num
&& (overlaps_hard_reg_set_p
- ((flag_use_caller_save &&
+ ((flag_ipa_ra &&
! hard_reg_set_empty_p (lra_reg_info[regno].actual_call_used_reg_set))
? lra_reg_info[regno].actual_call_used_reg_set
: call_used_reg_set,
static enum reg_class
choose_split_class (enum reg_class allocno_class,
int hard_regno ATTRIBUTE_UNUSED,
- enum machine_mode mode ATTRIBUTE_UNUSED)
+ machine_mode mode ATTRIBUTE_UNUSED)
{
#ifndef SECONDARY_MEMORY_NEEDED
return allocno_class;
" ((((((((((((((((((((((((((((((((((((((((((((((((\n");
if (call_save_p)
{
- enum machine_mode mode = GET_MODE (original_reg);
+ machine_mode mode = GET_MODE (original_reg);
mode = HARD_REGNO_CALLER_SAVE_MODE (hard_regno,
hard_regno_nregs[hard_regno][mode],
reg_renumber[REGNO (new_reg)] = hard_regno;
}
save = emit_spill_move (true, new_reg, original_reg);
- if (NEXT_INSN (save) != NULL_RTX)
+ if (NEXT_INSN (save) != NULL_RTX && !call_save_p)
{
- lra_assert (! call_save_p);
if (lra_dump_file != NULL)
{
fprintf
(lra_dump_file,
- " Rejecting split %d->%d resulting in > 2 %s save insns:\n",
- original_regno, REGNO (new_reg), call_save_p ? "call" : "");
+ " Rejecting split %d->%d resulting in > 2 save insns:\n",
+ original_regno, REGNO (new_reg));
dump_rtl_slim (lra_dump_file, save, NULL, -1, 0);
fprintf (lra_dump_file,
" ))))))))))))))))))))))))))))))))))))))))))))))))\n");
return false;
}
restore = emit_spill_move (false, new_reg, original_reg);
- if (NEXT_INSN (restore) != NULL_RTX)
+ if (NEXT_INSN (restore) != NULL_RTX && !call_save_p)
{
- lra_assert (! call_save_p);
if (lra_dump_file != NULL)
{
fprintf (lra_dump_file,
" Rejecting split %d->%d "
- "resulting in > 2 %s restore insns:\n",
- original_regno, REGNO (new_reg), call_save_p ? "call" : "");
+ "resulting in > 2 restore insns:\n",
+ original_regno, REGNO (new_reg));
dump_rtl_slim (lra_dump_file, restore, NULL, -1, 0);
fprintf (lra_dump_file,
" ))))))))))))))))))))))))))))))))))))))))))))))))\n");
usage_insn = XEXP (next_usage_insns, 0);
lra_assert (DEBUG_INSN_P (usage_insn));
next_usage_insns = XEXP (next_usage_insns, 1);
- substitute_pseudo (&usage_insn, original_regno, new_reg);
+ lra_substitute_pseudo (&usage_insn, original_regno, new_reg);
lra_update_insn_regno_info (as_a <rtx_insn *> (usage_insn));
if (lra_dump_file != NULL)
{
fprintf (lra_dump_file, " Split reuse change %d->%d:\n",
original_regno, REGNO (new_reg));
- dump_insn_slim (lra_dump_file, usage_insn);
+ dump_insn_slim (lra_dump_file, as_a <rtx_insn *> (usage_insn));
}
}
lra_assert (NOTE_P (usage_insn) || NONDEBUG_INSN_P (usage_insn));
uid before starting INSN processing. Return true if we succeed in
such transformation. */
static bool
-split_if_necessary (int regno, enum machine_mode mode,
+split_if_necessary (int regno, machine_mode mode,
HARD_REG_SET potential_reload_hard_regs,
bool before_p, rtx_insn *insn, int max_uid)
{
if (GET_CODE (pat) == PARALLEL)
pat = XVECEXP (pat, 0, 0);
dest = SET_DEST (pat);
- start_sequence ();
- emit_move_insn (cheap, copy_rtx (dest));
- restore = get_insns ();
- end_sequence ();
- lra_process_new_insns (curr_insn, NULL, restore,
- "Inserting call parameter restore");
- /* We don't need to save/restore of the pseudo from
- this call. */
- usage_insns[regno].calls_num = calls_num;
- bitmap_set_bit (&check_only_regs, regno);
+ /* For multiple return values dest is PARALLEL.
+ Currently we handle only single return value case. */
+ if (REG_P (dest))
+ {
+ start_sequence ();
+ emit_move_insn (cheap, copy_rtx (dest));
+ restore = get_insns ();
+ end_sequence ();
+ lra_process_new_insns (curr_insn, NULL, restore,
+ "Inserting call parameter restore");
+ /* We don't need to save/restore of the pseudo from
+ this call. */
+ usage_insns[regno].calls_num = calls_num;
+ bitmap_set_bit (&check_only_regs, regno);
+ }
}
}
to_inherit_num = 0;
|| reg_renumber[src_regno] >= 0)
{
bool before_p;
- rtx use_insn = curr_insn;
+ rtx_insn *use_insn = curr_insn;
before_p = (JUMP_P (curr_insn)
|| (CALL_P (curr_insn) && reg->type == OP_IN));
/* This value affects EBB forming. If probability of edge from EBB to
a BB is not greater than the following value, we don't add the BB
to EBB. */
-#define EBB_PROBABILITY_CUTOFF ((REG_BR_PROB_BASE * 50) / 100)
+#define EBB_PROBABILITY_CUTOFF \
+ ((REG_BR_PROB_BASE * LRA_INHERITANCE_EBB_PROBABILITY_CUTOFF) / 100)
/* Current number of inheritance/split iteration. */
int lra_inheritance_iter;
e = find_fallthru_edge (bb->succs);
if (! e)
break;
- if (e->probability <= EBB_PROBABILITY_CUTOFF)
+ if (e->probability < EBB_PROBABILITY_CUTOFF)
break;
bb = bb->next_bb;
}
{
if (change_p && bitmap_bit_p (remove_pseudos, regno))
{
- substitute_pseudo_within_insn (
+ lra_substitute_pseudo_within_insn (
curr_insn, regno, regno_reg_rtx[restore_regno]);
restored_regs_p = true;
}
we remove the inheritance pseudo and the optional
reload. */
}
- substitute_pseudo_within_insn (
+ lra_substitute_pseudo_within_insn (
insn, regno,
regno_reg_rtx[lra_reg_info[regno].restore_regno]);
lra_update_insn_regno_info (insn);