/* Search an insn for pseudo regs that must be in hard regs and are not.
- Copyright (C) 1987-2014 Free Software Foundation, Inc.
+ Copyright (C) 1987-2015 Free Software Foundation, Inc.
This file is part of GCC.
#include "rtl-error.h"
#include "tm_p.h"
#include "insn-config.h"
+#include "symtab.h"
+#include "hard-reg-set.h"
+#include "function.h"
+#include "rtl.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 "insn-codes.h"
#include "optabs.h"
#include "recog.h"
+#include "dominance.h"
+#include "cfg.h"
+#include "predict.h"
+#include "basic-block.h"
#include "df.h"
#include "reload.h"
#include "regs.h"
#include "addresses.h"
-#include "hard-reg-set.h"
-#include "flags.h"
-#include "hashtab.h"
-#include "hash-set.h"
-#include "vec.h"
-#include "machmode.h"
-#include "input.h"
-#include "function.h"
#include "params.h"
#include "target.h"
#include "ira.h"
{
rtx *where; /* Location to store in */
int what; /* which reload this is for */
- enum machine_mode mode; /* mode it must have */
+ machine_mode mode; /* mode it must have */
};
static struct replacement replacements[MAX_RECOG_OPERANDS * ((MAX_REGS_PER_ADDRESS * 2) + 1)];
: (type)))
static int push_secondary_reload (int, rtx, int, int, enum reg_class,
- enum machine_mode, enum reload_type,
+ machine_mode, enum reload_type,
enum insn_code *, secondary_reload_info *);
-static enum reg_class find_valid_class (enum machine_mode, enum machine_mode,
+static enum reg_class find_valid_class (machine_mode, machine_mode,
int, unsigned int);
-static void push_replacement (rtx *, int, enum machine_mode);
+static void push_replacement (rtx *, int, machine_mode);
static void dup_replacements (rtx *, rtx *);
static void combine_reloads (void);
static int find_reusable_reload (rtx *, rtx, enum reg_class,
enum reload_type, int, int);
-static rtx find_dummy_reload (rtx, rtx, rtx *, rtx *, enum machine_mode,
- enum machine_mode, reg_class_t, int, int);
+static rtx find_dummy_reload (rtx, rtx, rtx *, rtx *, machine_mode,
+ machine_mode, reg_class_t, int, int);
static int hard_reg_set_here_p (unsigned int, unsigned int, rtx);
static struct decomposition decompose (rtx);
static int immune_p (rtx, rtx, struct decomposition);
static rtx find_reloads_toplev (rtx, int, enum reload_type, int, int,
rtx_insn *, int *);
static rtx make_memloc (rtx, int);
-static int maybe_memory_address_addr_space_p (enum machine_mode, rtx,
+static int maybe_memory_address_addr_space_p (machine_mode, rtx,
addr_space_t, rtx *);
-static int find_reloads_address (enum machine_mode, rtx *, rtx, rtx *,
+static int find_reloads_address (machine_mode, rtx *, rtx, rtx *,
int, enum reload_type, int, rtx_insn *);
static rtx subst_reg_equivs (rtx, rtx_insn *);
static rtx subst_indexed_address (rtx);
static void update_auto_inc_notes (rtx_insn *, int, int);
-static int find_reloads_address_1 (enum machine_mode, addr_space_t, rtx, int,
+static int find_reloads_address_1 (machine_mode, addr_space_t, rtx, int,
enum rtx_code, enum rtx_code, rtx *,
int, enum reload_type,int, rtx_insn *);
static void find_reloads_address_part (rtx, rtx *, enum reg_class,
- enum machine_mode, int,
+ machine_mode, int,
enum reload_type, int);
static rtx find_reloads_subreg_address (rtx, int, enum reload_type,
int, rtx_insn *, int *);
static int
push_secondary_reload (int in_p, rtx x, int opnum, int optional,
enum reg_class reload_class,
- enum machine_mode reload_mode, enum reload_type type,
+ machine_mode reload_mode, enum reload_type type,
enum insn_code *picode, secondary_reload_info *prev_sri)
{
enum reg_class rclass = NO_REGS;
enum reg_class scratch_class;
- enum machine_mode mode = reload_mode;
+ machine_mode mode = reload_mode;
enum insn_code icode = CODE_FOR_nothing;
enum insn_code t_icode = CODE_FOR_nothing;
enum reload_type secondary_type;
register and a scratch register is needed, we return the class of the
intermediate register. */
reg_class_t
-secondary_reload_class (bool in_p, reg_class_t rclass, enum machine_mode mode,
+secondary_reload_class (bool in_p, reg_class_t rclass, machine_mode mode,
rtx x)
{
enum insn_code icode;
call find_reloads_address on the location being returned. */
rtx
-get_secondary_mem (rtx x ATTRIBUTE_UNUSED, enum machine_mode mode,
+get_secondary_mem (rtx x ATTRIBUTE_UNUSED, machine_mode mode,
int opnum, enum reload_type type)
{
rtx loc;
into REGNO. Such a class must exist. */
static enum reg_class
-find_valid_class (enum machine_mode outer ATTRIBUTE_UNUSED,
- enum machine_mode inner ATTRIBUTE_UNUSED, int n,
+find_valid_class (machine_mode outer ATTRIBUTE_UNUSED,
+ machine_mode inner ATTRIBUTE_UNUSED, int n,
unsigned int dest_regno ATTRIBUTE_UNUSED)
{
int best_cost = -1;
which we would eventually like to obtain the object. */
static enum reg_class
-find_valid_class_1 (enum machine_mode outer ATTRIBUTE_UNUSED,
- enum machine_mode mode ATTRIBUTE_UNUSED,
+find_valid_class_1 (machine_mode outer ATTRIBUTE_UNUSED,
+ machine_mode mode ATTRIBUTE_UNUSED,
enum reg_class dest_class ATTRIBUTE_UNUSED)
{
int best_cost = -1;
the function is invoked for the output part of an enclosing reload. */
static bool
-reload_inner_reg_of_subreg (rtx x, enum machine_mode mode, bool output)
+reload_inner_reg_of_subreg (rtx x, machine_mode mode, bool output)
{
rtx inner;
patterns by register elimination and substituting pseudos without a home
by their function-invariant equivalences. */
static int
-can_reload_into (rtx in, int regno, enum machine_mode mode)
+can_reload_into (rtx in, int regno, machine_mode mode)
{
rtx dst;
rtx_insn *test_insn;
/* If we can make a simple SET insn that does the job, everything should
be fine. */
dst = gen_rtx_REG (mode, regno);
- test_insn = make_insn_raw (gen_rtx_SET (VOIDmode, dst, in));
+ test_insn = make_insn_raw (gen_rtx_SET (dst, in));
save_recog_data = recog_data;
if (recog_memoized (test_insn) >= 0)
{
extract_insn (test_insn);
- r = constrain_operands (1);
+ r = constrain_operands (1, get_enabled_alternatives (test_insn));
}
recog_data = save_recog_data;
return r;
int
push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
- enum reg_class rclass, enum machine_mode inmode,
- enum machine_mode outmode, int strict_low, int optional,
+ enum reg_class rclass, machine_mode inmode,
+ machine_mode outmode, int strict_low, int optional,
int opnum, enum reload_type type)
{
int i;
is specified. */
if (this_insn_is_asm)
{
- enum machine_mode mode;
+ machine_mode mode;
if (GET_MODE_SIZE (inmode) > GET_MODE_SIZE (outmode))
mode = inmode;
else
{
rtx note;
int regno;
- enum machine_mode rel_mode = inmode;
+ machine_mode rel_mode = inmode;
if (out && GET_MODE_SIZE (outmode) > GET_MODE_SIZE (inmode))
rel_mode = outmode;
end_hard_regno (rel_mode,
regno),
PATTERN (this_insn), inloc)
+ && ! find_reg_fusage (this_insn, USE, XEXP (note, 0))
/* If this is also an output reload, IN cannot be used as
the reload register if it is set in this insn unless IN
is also OUT. */
This is used in insn patterns that use match_dup. */
static void
-push_replacement (rtx *loc, int reloadnum, enum machine_mode mode)
+push_replacement (rtx *loc, int reloadnum, machine_mode mode)
{
if (replace_reloads)
{
static rtx
find_dummy_reload (rtx real_in, rtx real_out, rtx *inloc, rtx *outloc,
- enum machine_mode inmode, enum machine_mode outmode,
+ machine_mode inmode, machine_mode outmode,
reg_class_t rclass, int for_real, int earlyclobber)
{
rtx in = real_in;
proper kind of hard reg. */
int
-strict_memory_address_addr_space_p (enum machine_mode mode ATTRIBUTE_UNUSED,
+strict_memory_address_addr_space_p (machine_mode mode ATTRIBUTE_UNUSED,
rtx addr, addr_space_t as)
{
#ifdef GO_IF_LEGITIMATE_ADDRESS
rtx body = PATTERN (insn);
rtx set = single_set (insn);
int goal_earlyclobber = 0, this_earlyclobber;
- enum machine_mode operand_mode[MAX_RECOG_OPERANDS];
+ machine_mode operand_mode[MAX_RECOG_OPERANDS];
int retval = 0;
this_insn = insn;
if (JUMP_P (insn) || CALL_P (insn))
no_output_reloads = 1;
-#ifdef HAVE_cc0
- if (reg_referenced_p (cc0_rtx, PATTERN (insn)))
+ if (HAVE_cc0 && reg_referenced_p (cc0_rtx, PATTERN (insn)))
no_input_reloads = 1;
- if (reg_set_p (cc0_rtx, PATTERN (insn)))
+ if (HAVE_cc0 && reg_set_p (cc0_rtx, PATTERN (insn)))
no_output_reloads = 1;
-#endif
#ifdef SECONDARY_MEMORY_NEEDED
/* The eliminated forms of any secondary memory locations are per-insn, so
this_insn_is_asm = insn_code_number < 0;
memcpy (operand_mode, recog_data.operand_mode,
- noperands * sizeof (enum machine_mode));
+ noperands * sizeof (machine_mode));
memcpy (constraints, recog_data.constraints,
noperands * sizeof (const char *));
First loop over alternatives. */
+ alternative_mask enabled = get_enabled_alternatives (insn);
for (this_alternative_number = 0;
this_alternative_number < n_alternatives;
this_alternative_number++)
{
int swapped;
- if (!TEST_BIT (recog_data.enabled_alternatives, this_alternative_number))
+ if (!TEST_BIT (enabled, this_alternative_number))
{
int i;
if (swapped)
{
- enum reg_class tclass;
- int t;
-
recog_data.operand[commutative] = substed_operand[commutative + 1];
recog_data.operand[commutative + 1] = substed_operand[commutative];
/* Swap the duplicates too. */
*recog_data.dup_loc[i]
= recog_data.operand[(int) recog_data.dup_num[i]];
- tclass = preferred_class[commutative];
- preferred_class[commutative] = preferred_class[commutative + 1];
- preferred_class[commutative + 1] = tclass;
-
- t = pref_or_nothing[commutative];
- pref_or_nothing[commutative] = pref_or_nothing[commutative + 1];
- pref_or_nothing[commutative + 1] = t;
-
- t = address_reloaded[commutative];
- address_reloaded[commutative] = address_reloaded[commutative + 1];
- address_reloaded[commutative + 1] = t;
+ std::swap (preferred_class[commutative],
+ preferred_class[commutative + 1]);
+ std::swap (pref_or_nothing[commutative],
+ pref_or_nothing[commutative + 1]);
+ std::swap (address_reloaded[commutative],
+ address_reloaded[commutative + 1]);
}
this_earlyclobber = 0;
if (swapped)
{
- enum reg_class tclass;
- int t;
-
/* If the commutative operands have been swapped, swap
them back in order to check the next alternative. */
recog_data.operand[commutative] = substed_operand[commutative];
= recog_data.operand[(int) recog_data.dup_num[i]];
/* Unswap the operand related information as well. */
- tclass = preferred_class[commutative];
- preferred_class[commutative] = preferred_class[commutative + 1];
- preferred_class[commutative + 1] = tclass;
-
- t = pref_or_nothing[commutative];
- pref_or_nothing[commutative] = pref_or_nothing[commutative + 1];
- pref_or_nothing[commutative + 1] = t;
-
- t = address_reloaded[commutative];
- address_reloaded[commutative] = address_reloaded[commutative + 1];
- address_reloaded[commutative + 1] = t;
+ std::swap (preferred_class[commutative],
+ preferred_class[commutative + 1]);
+ std::swap (pref_or_nothing[commutative],
+ pref_or_nothing[commutative + 1]);
+ std::swap (address_reloaded[commutative],
+ address_reloaded[commutative + 1]);
}
}
}
if (goal_alternative_swapped)
{
- rtx tem;
-
- tem = substed_operand[commutative];
- substed_operand[commutative] = substed_operand[commutative + 1];
- substed_operand[commutative + 1] = tem;
- tem = recog_data.operand[commutative];
- recog_data.operand[commutative] = recog_data.operand[commutative + 1];
- recog_data.operand[commutative + 1] = tem;
- tem = *recog_data.operand_loc[commutative];
- *recog_data.operand_loc[commutative]
- = *recog_data.operand_loc[commutative + 1];
- *recog_data.operand_loc[commutative + 1] = tem;
+ std::swap (substed_operand[commutative],
+ substed_operand[commutative + 1]);
+ std::swap (recog_data.operand[commutative],
+ recog_data.operand[commutative + 1]);
+ std::swap (*recog_data.operand_loc[commutative],
+ *recog_data.operand_loc[commutative + 1]);
+
+ for (i = 0; i < recog_data.n_dups; i++)
+ if (recog_data.dup_num[i] == commutative
+ || recog_data.dup_num[i] == commutative + 1)
+ *recog_data.dup_loc[i]
+ = recog_data.operand[(int) recog_data.dup_num[i]];
for (i = 0; i < n_reloads; i++)
{
rtx op = recog_data.operand[i];
rtx subreg = NULL_RTX;
rtx plus = NULL_RTX;
- enum machine_mode mode = operand_mode[i];
+ machine_mode mode = operand_mode[i];
/* Reloads of SUBREGs of CONSTANT RTXs are handled later in
push_reload so we have to let them pass here. */
use the default address mode as mode of the reload register,
as would have been done by find_reloads_address. */
addr_space_t as = MEM_ADDR_SPACE (recog_data.operand[i]);
- enum machine_mode address_mode;
+ machine_mode address_mode;
address_mode = get_address_mode (recog_data.operand[i]);
operand_reloadnum[i]
rld[j].in = 0;
}
-#ifdef HAVE_cc0
/* If we made any reloads for addresses, see if they violate a
"no input reloads" requirement for this insn. But loads that we
do after the insn (such as for output addresses) are fine. */
- if (no_input_reloads)
+ if (HAVE_cc0 && no_input_reloads)
for (i = 0; i < n_reloads; i++)
gcc_assert (rld[i].in == 0
|| rld[i].when_needed == RELOAD_FOR_OUTADDR_ADDRESS
|| rld[i].when_needed == RELOAD_FOR_OUTPUT_ADDRESS);
-#endif
/* Compute reload_mode and reload_nregs. */
for (i = 0; i < n_reloads; i++)
by PART into a register. */
static int
-maybe_memory_address_addr_space_p (enum machine_mode mode, rtx ad,
+maybe_memory_address_addr_space_p (machine_mode mode, rtx ad,
addr_space_t as, rtx *part)
{
int retv;
to a hard register, and frame pointer elimination. */
static int
-find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
+find_reloads_address (machine_mode mode, rtx *memrefloc, rtx ad,
rtx *loc, int opnum, enum reload_type type,
int ind_levels, rtx_insn *insn)
{
#if !HARD_FRAME_POINTER_IS_FRAME_POINTER
|| operand == hard_frame_pointer_rtx
#endif
-#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
- || operand == arg_pointer_rtx
-#endif
+ || (FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
+ && operand == arg_pointer_rtx)
|| operand == stack_pointer_rtx)
&& ! maybe_memory_address_addr_space_p
(mode, ad, as, &XEXP (XEXP (ad, 0), 1 - op_index)))
into a register. */
if (CONSTANT_P (ad) && ! strict_memory_address_addr_space_p (mode, ad, as))
{
- enum machine_mode address_mode = GET_MODE (ad);
+ machine_mode address_mode = GET_MODE (ad);
if (address_mode == VOIDmode)
address_mode = targetm.addr_space.address_mode (as);
This routine assumes both inputs are already in canonical form. */
rtx
-form_sum (enum machine_mode mode, rtx x, rtx y)
+form_sum (machine_mode mode, rtx x, rtx y)
{
rtx tem;
handles those cases gracefully. */
static int
-find_reloads_address_1 (enum machine_mode mode, addr_space_t as,
+find_reloads_address_1 (machine_mode mode, addr_space_t as,
rtx x, int context,
enum rtx_code outer_code, enum rtx_code index_code,
rtx *loc, int opnum, enum reload_type type,
enum insn_code icode = optab_handler (add_optab, GET_MODE (x));
if (insn && NONJUMP_INSN_P (insn) && equiv
&& memory_operand (equiv, GET_MODE (equiv))
-#ifdef HAVE_cc0
+#if HAVE_cc0
&& ! sets_cc0_p (PATTERN (insn))
#endif
&& ! (icode != CODE_FOR_nothing
static void
find_reloads_address_part (rtx x, rtx *loc, enum reg_class rclass,
- enum machine_mode mode, int opnum,
+ machine_mode mode, int opnum,
enum reload_type type, int ind_levels)
{
if (CONSTANT_P (x)
int ind_levels, rtx_insn *insn,
int *address_reloaded)
{
- enum machine_mode outer_mode = GET_MODE (x);
- enum machine_mode inner_mode = GET_MODE (SUBREG_REG (x));
+ machine_mode outer_mode = GET_MODE (x);
+ machine_mode inner_mode = GET_MODE (SUBREG_REG (x));
int regno = REGNO (SUBREG_REG (x));
int reloaded = 0;
rtx tem, orig;
return 0;
}
- endregno = END_HARD_REGNO (x);
+ endregno = END_REGNO (x);
return refers_to_regno_for_reload_p (regno, endregno, in, (rtx*) 0);
}
rtx
find_equiv_reg (rtx goal, rtx_insn *insn, enum reg_class rclass, int other,
- short *reload_reg_p, int goalreg, enum machine_mode mode)
+ short *reload_reg_p, int goalreg, machine_mode mode)
{
rtx_insn *p = insn;
rtx goaltry, valtry, value;
REG_INC. REGNO must refer to a hard register. */
int
-regno_clobbered_p (unsigned int regno, rtx_insn *insn, enum machine_mode mode,
+regno_clobbered_p (unsigned int regno, rtx_insn *insn, machine_mode mode,
int sets)
{
unsigned int nregs, endregno;
/* Find the low part, with mode MODE, of a hard regno RELOADREG. */
rtx
-reload_adjust_reg_for_mode (rtx reloadreg, enum machine_mode mode)
+reload_adjust_reg_for_mode (rtx reloadreg, machine_mode mode)
{
int regno;