#include "tm_p.h"
#include "flags.h"
#include "regs.h"
-#include "hashtab.h"
-#include "hash-set.h"
-#include "vec.h"
-#include "machmode.h"
-#include "input.h"
#include "function.h"
#include "predict.h"
#include "basic-block.h"
#include "df.h"
#include "symtab.h"
-#include "wide-int.h"
-#include "inchash.h"
#include "tree.h"
#include "emit-rtl.h" /* FIXME: Can go away once crtl is moved to rtl.h. */
#include "addresses.h"
return base;
}
gcc_checking_assert (i == LOCAL_ELEMS);
- vec_safe_grow (array.heap, i + 1);
+ /* A previous iteration might also have moved from the stack to the
+ heap, in which case the heap array will already be big enough. */
+ if (vec_safe_length (array.heap) <= i)
+ vec_safe_grow (array.heap, i + 1);
base = array.heap->address ();
memcpy (base, array.stack, sizeof (array.stack));
base[LOCAL_ELEMS] = x;
/* Examine INSN, and compute the set of hard registers written by it.
Store it in *PSET. Should only be called after reload. */
void
-find_all_hard_reg_sets (const_rtx insn, HARD_REG_SET *pset, bool implicit)
+find_all_hard_reg_sets (const rtx_insn *insn, HARD_REG_SET *pset, bool implicit)
{
rtx link;
value to itself. */
int
-noop_move_p (const_rtx insn)
+noop_move_p (const rtx_insn *insn)
{
rtx pat = PATTERN (insn);
clobber a virtual register. In fact, we could be more precise,
but it isn't worth it. */
if ((x_regno == STACK_POINTER_REGNUM
-#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
- || x_regno == ARG_POINTER_REGNUM
-#endif
+ || (FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
+ && x_regno == ARG_POINTER_REGNUM)
|| x_regno == FRAME_POINTER_REGNUM)
&& regno >= FIRST_VIRTUAL_REGISTER && regno <= LAST_VIRTUAL_REGISTER)
return true;
if (regno < FIRST_PSEUDO_REGISTER)
{
- unsigned int end_regno = END_HARD_REGNO (datum);
+ unsigned int end_regno = END_REGNO (datum);
unsigned int i;
for (i = regno; i < end_regno; i++)
if (GET_CODE (op = XEXP (link, 0)) == code
&& REG_P (reg = XEXP (op, 0))
&& REGNO (reg) <= regno
- && END_HARD_REGNO (reg) > regno)
+ && END_REGNO (reg) > regno)
return 1;
}
/* Add a register note like NOTE to INSN. */
void
-add_shallow_copy_of_reg_note (rtx insn, rtx note)
+add_shallow_copy_of_reg_note (rtx_insn *insn, rtx note)
{
if (GET_CODE (note) == INT_LIST)
add_int_reg_note (insn, REG_NOTE_KIND (note), XINT (note, 0));
/* Remove REG_EQUAL and/or REG_EQUIV notes if INSN has such notes. */
void
-remove_reg_equal_equiv_notes (rtx insn)
+remove_reg_equal_equiv_notes (rtx_insn *insn)
{
rtx *loc;
return 1 if it is found. A simple equality test is used to determine if
NODE matches. */
-int
-in_expr_list_p (const_rtx listp, const_rtx node)
+bool
+in_insn_list_p (const rtx_insn_list *listp, const rtx_insn *node)
{
const_rtx x;
for (x = listp; x; x = XEXP (x, 1))
if (node == XEXP (x, 0))
- return 1;
+ return true;
- return 0;
+ return false;
}
/* Search LISTP (an EXPR_LIST) for an entry whose first operand is NODE and
remove_node_from_expr_list (const_rtx node, rtx_expr_list **listp)
{
rtx_expr_list *temp = *listp;
- rtx prev = NULL_RTX;
+ rtx_expr_list *prev = NULL;
while (temp)
{
remove_node_from_insn_list (const rtx_insn *node, rtx_insn_list **listp)
{
rtx_insn_list *temp = *listp;
- rtx prev = NULL;
+ rtx_insn_list *prev = NULL;
while (temp)
{
bool
tablejump_p (const rtx_insn *insn, rtx *labelp, rtx_jump_table_data **tablep)
{
- rtx label, table;
+ rtx label;
+ rtx_insn *table;
if (!JUMP_P (insn))
return false;
we can recognize them by a (use (label_ref)). */
int
-computed_jump_p (const_rtx insn)
+computed_jump_p (const rtx_insn *insn)
{
int i;
if (JUMP_P (insn))
}
/* Return a value indicating whether OP, an operand of a commutative
- operation, is preferred as the first or second operand. The higher
- the value, the stronger the preference for being the first operand.
- We use negative values to indicate a preference for the first operand
- and positive values for the second operand. */
+ operation, is preferred as the first or second operand. The more
+ positive the value, the stronger the preference for being the first
+ operand. */
int
commutative_operand_precedence (rtx op)
{
enum rtx_code code = GET_CODE (op);
- /* Constants always come the second operand. Prefer "nice" constants. */
+ /* Constants always become the second operand. Prefer "nice" constants. */
if (code == CONST_INT)
return -8;
if (code == CONST_WIDE_INT)
info->offset = offset / regsize_xmode;
return;
}
+ /* Quick exit for the simple and common case of extracting whole
+ subregisters from a multiregister value. */
+ /* ??? It would be better to integrate this into the code below,
+ if we can generalize the concept enough and figure out how
+ odd-sized modes can coexist with the other weird cases we support. */
+ if (!rknown
+ && WORDS_BIG_ENDIAN == REG_WORDS_BIG_ENDIAN
+ && regsize_xmode == regsize_ymode
+ && (offset % regsize_ymode) == 0)
+ {
+ info->representable_p = true;
+ info->nregs = nregs_ymode;
+ info->offset = offset / regsize_ymode;
+ gcc_assert (info->offset + info->nregs <= nregs_xmode);
+ return;
+ }
}
/* Lowpart subregs are otherwise valid. */
/* Set nonzero when we find something of interest. */
rtx x = 0;
-#ifdef HAVE_cc0
/* If comparison with cc0, import actual comparison from compare
insn. */
if (op0 == cc0_rtx)
if (earliest)
*earliest = prev;
}
-#endif
/* If this is a COMPARE, pick up the two things being compared. */
if (GET_CODE (op0) == COMPARE)
inner = strip_address_mutations (&XEXP (*inner, 0));
if (REG_P (*inner)
|| MEM_P (*inner)
- || GET_CODE (*inner) == SUBREG)
+ || GET_CODE (*inner) == SUBREG
+ || GET_CODE (*inner) == SCRATCH)
return inner;
return 0;
}