/* Register Transfer Language (RTL) definitions for GCC
- Copyright (C) 1987-2014 Free Software Foundation, Inc.
+ Copyright (C) 1987-2015 Free Software Foundation, Inc.
This file is part of GCC.
#ifndef GCC_RTL_H
#define GCC_RTL_H
-#include <utility>
-#include "statistics.h"
-#include "machmode.h"
-#include "input.h"
+/* This file is occasionally included by generator files which expect
+ machmode.h and other files to exist and would not normally have been
+ included by coretypes.h. */
+#ifdef GENERATOR_FILE
+#include "machmode.h"
+#include "signop.h"
+#include "wide-int.h"
+#include "double-int.h"
#include "real.h"
-#include "vec.h"
#include "fixed-value.h"
-#include "alias.h"
-#include "hashtab.h"
-#include "wide-int.h"
-#include "flags.h"
+#include "statistics.h"
+#include "vec.h"
+#include "hash-table.h"
+#include "hash-set.h"
+#include "input.h"
#include "is-a.h"
+#endif /* GENERATOR_FILE */
+
+#include "flags.h"
/* Value used by some passes to "recognize" noop moves as valid
instructions. */
object in the low part of a 4-byte register, the OFFSET field
will be -3 rather than 0. */
-struct GTY(()) reg_attrs {
+struct GTY((for_user)) reg_attrs {
tree decl; /* decl corresponding to REG. */
HOST_WIDE_INT offset; /* Offset from start of DECL. */
};
const char *rt_str;
rtx rt_rtx;
rtvec rt_rtvec;
- enum machine_mode rt_type;
+ machine_mode rt_type;
addr_diff_vec_flags rt_addr_diff_vec_flags;
struct cselib_val *rt_cselib;
tree rt_tree;
basic_block rt_bb;
mem_attrs *rt_mem;
- reg_attrs *rt_reg;
struct constant_descriptor_rtx *rt_constant;
struct dw_cfi_node *rt_cfi;
};
+/* Describes the properties of a REG. */
+struct GTY(()) reg_info {
+ /* The value of REGNO. */
+ unsigned int regno;
+
+ /* The value of REG_NREGS. */
+ unsigned int nregs : 8;
+ unsigned int unused : 24;
+
+ /* The value of REG_ATTRS. */
+ reg_attrs *attrs;
+};
+
/* This structure remembers the position of a SYMBOL_REF within an
object_block structure. A SYMBOL_REF only provides this information
if SYMBOL_REF_HAS_BLOCK_INFO_P is true. */
/* Describes a group of objects that are to be placed together in such
a way that their relative positions are known. */
-struct GTY(()) object_block {
+struct GTY((for_user)) object_block {
/* The section in which these objects should be placed. */
section *sect;
In a CODE_LABEL, part of the two-bit alternate entry field.
1 in a CONCAT is VAL_EXPR_IS_COPIED in var-tracking.c.
1 in a VALUE is SP_BASED_VALUE_P in cselib.c.
- 1 in a SUBREG generated by LRA for reload insns. */
+ 1 in a SUBREG generated by LRA for reload insns.
+ 1 in a CALL for calls instrumented by Pointer Bounds Checker. */
unsigned int jump : 1;
/* In a CODE_LABEL, part of the two-bit alternate entry field.
1 in a MEM if it cannot trap.
union u {
rtunion fld[1];
HOST_WIDE_INT hwint[1];
+ struct reg_info reg;
struct block_symbol block_sym;
struct real_value rv;
struct fixed_value fv;
class GTY(()) rtx_insn : public rtx_def
{
+public:
/* No extra fields, but adds the invariant:
(INSN_P (X)
i.e. we have an rtx that has an INSN_UID field and can be part of
a linked list of insns.
*/
+
+ /* Returns true if this insn has been deleted. */
+
+ bool deleted () const { return volatil; }
+
+ /* Mark this insn as deleted. */
+
+ void set_deleted () { volatil = true; }
+
+ /* Mark this insn as not deleted. */
+
+ void set_undeleted () { volatil = false; }
};
/* Subclasses of rtx_insn. */
class GTY(()) rtx_jump_insn : public rtx_insn
{
+public:
/* No extra fields, but adds the invariant:
JUMP_P (X) aka (GET_CODE (X) == JUMP_INSN)
i.e. an instruction that can possibly jump.
This is an instance of:
DEF_RTL_EXPR(JUMP_INSN, "jump_insn", "uuBeiie0", RTX_INSN)
from rtl.def. */
+
+ /* Returns jump target of this instruction. The returned value is not
+ necessarily a code label: it may also be a RETURN or SIMPLE_RETURN
+ expression. Also, when the code label is marked "deleted", it is
+ replaced by a NOTE. In some cases the value is NULL_RTX. */
+
+ inline rtx jump_label () const;
+
+ /* Returns jump target cast to rtx_code_label *. */
+
+ inline rtx_code_label *jump_target () const;
+
+ /* Set jump target. */
+
+ inline void set_jump_target (rtx_code_label *);
};
class GTY(()) rtx_call_insn : public rtx_insn
|| JUMP_TABLE_DATA_P (X) \
|| BARRIER_P (X) \
|| LABEL_P (X)) \
- && PREV_INSN (X) != NULL \
- && NEXT_INSN (PREV_INSN (X)) == X \
- ? PREV_INSN (X) : NULL)
+ && PREV_INSN (as_a <rtx_insn *> (X)) != NULL \
+ && NEXT_INSN (PREV_INSN (as_a <rtx_insn *> (X))) == X \
+ ? PREV_INSN (as_a <rtx_insn *> (X)) : NULL)
/* Define macros to access the `code' field of the rtx. */
#define GET_CODE(RTX) ((enum rtx_code) (RTX)->code)
#define PUT_CODE(RTX, CODE) ((RTX)->code = (CODE))
-#define GET_MODE(RTX) ((enum machine_mode) (RTX)->mode)
-#define PUT_MODE(RTX, MODE) ((RTX)->mode = (MODE))
+#define GET_MODE(RTX) ((machine_mode) (RTX)->mode)
+#define PUT_MODE_RAW(RTX, MODE) ((RTX)->mode = (MODE))
/* RTL vector. These appear inside RTX's when there is a need
for a variable number of things. The principle use is inside
/* Predicate yielding nonzero iff X is a data for a jump table. */
#define JUMP_TABLE_DATA_P(INSN) (GET_CODE (INSN) == JUMP_TABLE_DATA)
+/* Predicate yielding nonzero iff RTX is a subreg. */
+#define SUBREG_P(RTX) (GET_CODE (RTX) == SUBREG)
+
template <>
template <>
inline bool
return JUMP_P (rt);
}
+template <>
+template <>
+inline bool
+is_a_helper <rtx_jump_insn *>::test (rtx_insn *insn)
+{
+ return JUMP_P (insn);
+}
+
template <>
template <>
inline bool
__LINE__, __FUNCTION__); \
&_rtx->u.fv; })
+#define REG_CHECK(RTX) __extension__ \
+({ __typeof (RTX) const _rtx = (RTX); \
+ if (GET_CODE (_rtx) != REG) \
+ rtl_check_failed_code1 (_rtx, REG, __FILE__, __LINE__, \
+ __FUNCTION__); \
+ &_rtx->u.reg; })
+
#define BLOCK_SYMBOL_CHECK(RTX) __extension__ \
({ __typeof (RTX) const _symbol = (RTX); \
const unsigned int flags = SYMBOL_REF_FLAGS (_symbol); \
extern void rtl_check_failed_code2 (const_rtx, enum rtx_code, enum rtx_code,
const char *, int, const char *)
ATTRIBUTE_NORETURN;
-extern void rtl_check_failed_code_mode (const_rtx, enum rtx_code, enum machine_mode,
+extern void rtl_check_failed_code_mode (const_rtx, enum rtx_code, machine_mode,
bool, const char *, int, const char *)
ATTRIBUTE_NORETURN;
extern void rtl_check_failed_block_symbol (const char *, int, const char *)
#define XCNMWINT(RTX, N, C, M) ((RTX)->u.hwint[N])
#define XCNMPRV(RTX, C, M) (&(RTX)->u.rv)
#define XCNMPFV(RTX, C, M) (&(RTX)->u.fv)
+#define REG_CHECK(RTX) (&(RTX)->u.reg)
#define BLOCK_SYMBOL_CHECK(RTX) (&(RTX)->u.block_sym)
#define HWIVEC_CHECK(RTX,C) (&(RTX)->u.hwiv)
#define X0ADVFLAGS(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_addr_diff_vec_flags)
#define X0CSELIB(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_cselib)
#define X0MEMATTR(RTX, N) (RTL_CHECKC1 (RTX, N, MEM).rt_mem)
-#define X0REGATTR(RTX, N) (RTL_CHECKC1 (RTX, N, REG).rt_reg)
#define X0CONSTANT(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_constant)
/* Access a '0' field with any type. */
and an lvalue form:
SET_NEXT_INSN/SET_PREV_INSN. */
-inline rtx_insn *PREV_INSN (const_rtx insn)
+inline rtx_insn *PREV_INSN (const rtx_insn *insn)
{
rtx prev = XEXP (insn, 0);
return safe_as_a <rtx_insn *> (prev);
}
-inline rtx& SET_PREV_INSN (rtx insn)
+inline rtx& SET_PREV_INSN (rtx_insn *insn)
{
return XEXP (insn, 0);
}
-inline rtx_insn *NEXT_INSN (const_rtx insn)
+inline rtx_insn *NEXT_INSN (const rtx_insn *insn)
{
rtx next = XEXP (insn, 1);
return safe_as_a <rtx_insn *> (next);
}
-inline rtx& SET_NEXT_INSN (rtx insn)
+inline rtx& SET_NEXT_INSN (rtx_insn *insn)
{
return XEXP (insn, 1);
}
return XBBDEF (insn, 2);
}
+inline void set_block_for_insn (rtx_insn *insn, basic_block bb)
+{
+ BLOCK_FOR_INSN (insn) = bb;
+}
+
/* The body of an insn. */
inline rtx PATTERN (const_rtx insn)
{
return XEXP (insn, 3);
}
-inline unsigned int INSN_LOCATION (const_rtx insn)
+inline unsigned int INSN_LOCATION (const rtx_insn *insn)
{
return XUINT (insn, 4);
}
-inline unsigned int& INSN_LOCATION (rtx insn)
+inline unsigned int& INSN_LOCATION (rtx_insn *insn)
{
return XUINT (insn, 4);
}
-inline bool INSN_HAS_LOCATION (const_rtx insn)
+inline bool INSN_HAS_LOCATION (const rtx_insn *insn)
{
return LOCATION_LOCUS (INSN_LOCATION (insn)) != UNKNOWN_LOCATION;
}
/* LOCATION of an RTX if relevant. */
#define RTL_LOCATION(X) (INSN_P (X) ? \
- INSN_LOCATION (X) : UNKNOWN_LOCATION)
+ INSN_LOCATION (as_a <rtx_insn *> (X)) \
+ : UNKNOWN_LOCATION)
/* Code number of instruction, from when it was recognized.
-1 means this instruction has not been recognized yet. */
(RTL_FLAG_CHECK6 ("RTX_FRAME_RELATED_P", (RTX), DEBUG_INSN, INSN, \
CALL_INSN, JUMP_INSN, BARRIER, SET)->frame_related)
-/* 1 if RTX is an insn that has been deleted. */
-#define INSN_DELETED_P(RTX) \
- (RTL_INSN_CHAIN_FLAG_CHECK ("INSN_DELETED_P", (RTX))->volatil)
-
/* 1 if JUMP RTX is a crossing jump. */
#define CROSSING_JUMP_P(RTX) \
(RTL_FLAG_CHECK1 ("CROSSING_JUMP_P", (RTX), JUMP_INSN)->jump)
/* Define macros to extract and insert the reg-note kind in an EXPR_LIST. */
#define REG_NOTE_KIND(LINK) ((enum reg_note) GET_MODE (LINK))
#define PUT_REG_NOTE_KIND(LINK, KIND) \
- PUT_MODE (LINK, (enum machine_mode) (KIND))
+ PUT_MODE_RAW (LINK, (machine_mode) (KIND))
/* Names for REG_NOTE's in EXPR_LIST insn's. */
be decremented and possibly the label can be deleted. */
#define JUMP_LABEL(INSN) XCEXP (INSN, 7, JUMP_INSN)
+inline rtx_insn *JUMP_LABEL_AS_INSN (const rtx_insn *insn)
+{
+ return safe_as_a <rtx_insn *> (JUMP_LABEL (insn));
+}
+
+/* Methods of rtx_jump_insn. */
+
+inline rtx rtx_jump_insn::jump_label () const
+{
+ return JUMP_LABEL (this);
+}
+
+inline rtx_code_label *rtx_jump_insn::jump_target () const
+{
+ return safe_as_a <rtx_code_label *> (JUMP_LABEL (this));
+}
+
+inline void rtx_jump_insn::set_jump_target (rtx_code_label *target)
+{
+ JUMP_LABEL (this) = target;
+}
+
/* Once basic blocks are found, each CODE_LABEL starts a chain that
goes through all the LABEL_REFs that jump to that label. The chain
eventually winds up at the CODE_LABEL: it is circular. */
#define LABEL_REFS(LABEL) XCEXP (LABEL, 3, CODE_LABEL)
+
+/* Get the label that a LABEL_REF references. */
+#define LABEL_REF_LABEL(LABREF) XCEXP (LABREF, 0, LABEL_REF)
+
\f
/* For a REG rtx, REGNO extracts the register number. REGNO can only
be used on RHS. Use SET_REGNO to change the value. */
#define REGNO(RTX) (rhs_regno(RTX))
-#define SET_REGNO(RTX,N) \
- (df_ref_change_reg_with_loc (REGNO (RTX), N, RTX), XCUINT (RTX, 0, REG) = N)
-#define SET_REGNO_RAW(RTX,N) (XCUINT (RTX, 0, REG) = N)
+#define SET_REGNO(RTX, N) (df_ref_change_reg_with_loc (RTX, N))
+
+/* Return the number of consecutive registers in a REG. This is always
+ 1 for pseudo registers and is determined by HARD_REGNO_NREGS for
+ hard registers. */
+#define REG_NREGS(RTX) (REG_CHECK (RTX)->nregs)
/* ORIGINAL_REGNO holds the number the register originally had; for a
pseudo register turned into a hard reg this will hold the old pseudo
static inline unsigned int
rhs_regno (const_rtx x)
{
- return XCUINT (x, 0, REG);
+ return REG_CHECK (x)->regno;
}
+/* Return the final register in REG X plus one. */
+static inline unsigned int
+END_REGNO (const_rtx x)
+{
+ return REGNO (x) + REG_NREGS (x);
+}
+
+/* Change the REGNO and REG_NREGS of REG X to the specified values,
+ bypassing the df machinery. */
+static inline void
+set_regno_raw (rtx x, unsigned int regno, unsigned int nregs)
+{
+ reg_info *reg = REG_CHECK (x);
+ reg->regno = regno;
+ reg->nregs = nregs;
+}
/* 1 if RTX is a reg or parallel that is the current function's return
value. */
not to use an rtx with this cost under any circumstances. */
#define MAX_COST INT_MAX
+/* Return true if CODE always has VOIDmode. */
+
+static inline bool
+always_void_p (enum rtx_code code)
+{
+ return code == SET;
+}
+
/* A structure to hold all available cost information about an rtl
expression. */
struct full_rtx_costs
c->size += COSTS_N_INSNS (n);
}
+/* Describes the shape of a subreg:
+
+ inner_mode == the mode of the SUBREG_REG
+ offset == the SUBREG_BYTE
+ outer_mode == the mode of the SUBREG itself. */
+struct subreg_shape {
+ subreg_shape (machine_mode, unsigned int, machine_mode);
+ bool operator == (const subreg_shape &) const;
+ bool operator != (const subreg_shape &) const;
+ unsigned int unique_id () const;
+
+ machine_mode inner_mode;
+ unsigned int offset;
+ machine_mode outer_mode;
+};
+
+inline
+subreg_shape::subreg_shape (machine_mode inner_mode_in,
+ unsigned int offset_in,
+ machine_mode outer_mode_in)
+ : inner_mode (inner_mode_in), offset (offset_in), outer_mode (outer_mode_in)
+{}
+
+inline bool
+subreg_shape::operator == (const subreg_shape &other) const
+{
+ return (inner_mode == other.inner_mode
+ && offset == other.offset
+ && outer_mode == other.outer_mode);
+}
+
+inline bool
+subreg_shape::operator != (const subreg_shape &other) const
+{
+ return !operator == (other);
+}
+
+/* Return an integer that uniquely identifies this shape. Structures
+ like rtx_def assume that a mode can fit in an 8-bit bitfield and no
+ current mode is anywhere near being 65536 bytes in size, so the
+ id comfortably fits in an int. */
+
+inline unsigned int
+subreg_shape::unique_id () const
+{
+ STATIC_ASSERT (MAX_MACHINE_MODE <= 256);
+ return (int) inner_mode + ((int) outer_mode << 8) + (offset << 16);
+}
+
+/* Return the shape of a SUBREG rtx. */
+
+static inline subreg_shape
+shape_of_subreg (const_rtx x)
+{
+ return subreg_shape (GET_MODE (SUBREG_REG (x)),
+ SUBREG_BYTE (x), GET_MODE (x));
+}
+
/* Information about an address. This structure is supposed to be able
to represent all supported target addresses. Please extend it if it
is not yet general enough. */
struct address_info {
/* The mode of the value being addressed, or VOIDmode if this is
a load-address operation with no known address mode. */
- enum machine_mode mode;
+ machine_mode mode;
/* The address space. */
addr_space_t as;
/* This is used to bundle an rtx and a mode together so that the pair
can be used with the wi:: routines. If we ever put modes into rtx
integer constants, this should go away and then just pass an rtx in. */
-typedef std::pair <rtx, enum machine_mode> rtx_mode_t;
+typedef std::pair <rtx, machine_mode> rtx_mode_t;
namespace wi
{
namespace wi
{
- hwi_with_prec shwi (HOST_WIDE_INT, enum machine_mode mode);
- wide_int min_value (enum machine_mode, signop);
- wide_int max_value (enum machine_mode, signop);
+ hwi_with_prec shwi (HOST_WIDE_INT, machine_mode mode);
+ wide_int min_value (machine_mode, signop);
+ wide_int max_value (machine_mode, signop);
}
inline wi::hwi_with_prec
-wi::shwi (HOST_WIDE_INT val, enum machine_mode mode)
+wi::shwi (HOST_WIDE_INT val, machine_mode mode)
{
return shwi (val, GET_MODE_PRECISION (mode));
}
/* Produce the smallest number that is represented in MODE. The precision
is taken from MODE and the sign from SGN. */
inline wide_int
-wi::min_value (enum machine_mode mode, signop sgn)
+wi::min_value (machine_mode mode, signop sgn)
{
return min_value (GET_MODE_PRECISION (mode), sgn);
}
/* Produce the largest number that is represented in MODE. The precision
is taken from MODE and the sign from SGN. */
inline wide_int
-wi::max_value (enum machine_mode mode, signop sgn)
+wi::max_value (machine_mode mode, signop sgn)
{
return max_value (GET_MODE_PRECISION (mode), sgn);
}
extern void init_rtlanal (void);
extern int rtx_cost (rtx, enum rtx_code, int, bool);
-extern int address_cost (rtx, enum machine_mode, addr_space_t, bool);
+extern int address_cost (rtx, machine_mode, addr_space_t, bool);
extern void get_full_rtx_cost (rtx, enum rtx_code, int,
struct full_rtx_costs *);
extern unsigned int subreg_lsb (const_rtx);
-extern unsigned int subreg_lsb_1 (enum machine_mode, enum machine_mode,
+extern unsigned int subreg_lsb_1 (machine_mode, machine_mode,
unsigned int);
-extern unsigned int subreg_regno_offset (unsigned int, enum machine_mode,
- unsigned int, enum machine_mode);
-extern bool subreg_offset_representable_p (unsigned int, enum machine_mode,
- unsigned int, enum machine_mode);
+extern unsigned int subreg_regno_offset (unsigned int, machine_mode,
+ unsigned int, machine_mode);
+extern bool subreg_offset_representable_p (unsigned int, machine_mode,
+ unsigned int, machine_mode);
extern unsigned int subreg_regno (const_rtx);
-extern int simplify_subreg_regno (unsigned int, enum machine_mode,
- unsigned int, enum machine_mode);
+extern int simplify_subreg_regno (unsigned int, machine_mode,
+ unsigned int, machine_mode);
extern unsigned int subreg_nregs (const_rtx);
extern unsigned int subreg_nregs_with_regno (unsigned int, const_rtx);
-extern unsigned HOST_WIDE_INT nonzero_bits (const_rtx, enum machine_mode);
-extern unsigned int num_sign_bit_copies (const_rtx, enum machine_mode);
+extern unsigned HOST_WIDE_INT nonzero_bits (const_rtx, machine_mode);
+extern unsigned int num_sign_bit_copies (const_rtx, machine_mode);
extern bool constant_pool_constant_p (rtx);
-extern bool truncated_to_mode (enum machine_mode, const_rtx);
-extern int low_bitmask_len (enum machine_mode, unsigned HOST_WIDE_INT);
+extern bool truncated_to_mode (machine_mode, const_rtx);
+extern int low_bitmask_len (machine_mode, unsigned HOST_WIDE_INT);
extern void split_double (rtx, rtx *, rtx *);
extern rtx *strip_address_mutations (rtx *, enum rtx_code * = 0);
extern void decompose_address (struct address_info *, rtx *,
- enum machine_mode, addr_space_t, enum rtx_code);
+ machine_mode, addr_space_t, enum rtx_code);
extern void decompose_lea_address (struct address_info *, rtx *);
extern void decompose_mem_address (struct address_info *, rtx);
extern void update_address (struct address_info *);
#define LRA_SUBREG_P(RTX) \
(RTL_FLAG_CHECK1 ("LRA_SUBREG_P", (RTX), SUBREG)->jump)
+/* True if call is instrumented by Pointer Bounds Checker. */
+#define CALL_EXPR_WITH_BOUNDS_P(RTX) \
+ (RTL_FLAG_CHECK1 ("CALL_EXPR_WITH_BOUNDS_P", (RTX), CALL)->jump)
+
/* Access various components of an ASM_OPERANDS rtx. */
#define ASM_OPERANDS_TEMPLATE(RTX) XCSTR (RTX, 0, ASM_OPERANDS)
/* The register attribute block. We provide access macros for each value
in the block and provide defaults if none specified. */
-#define REG_ATTRS(RTX) X0REGATTR (RTX, 1)
+#define REG_ATTRS(RTX) (REG_CHECK (RTX)->attrs)
#ifndef GENERATOR_FILE
/* For a MEM rtx, the alias set. If 0, this MEM is not in any alias
/* Generally useful functions. */
/* In explow.c */
-extern HOST_WIDE_INT trunc_int_for_mode (HOST_WIDE_INT, enum machine_mode);
-extern rtx plus_constant (enum machine_mode, rtx, HOST_WIDE_INT, bool = false);
+extern HOST_WIDE_INT trunc_int_for_mode (HOST_WIDE_INT, machine_mode);
+extern rtx plus_constant (machine_mode, rtx, HOST_WIDE_INT, bool = false);
/* In rtl.c */
extern rtx rtx_alloc_stat (RTX_CODE MEM_STAT_DECL);
extern rtvec shallow_copy_rtvec (rtvec);
extern bool shared_const_p (const_rtx);
extern rtx copy_rtx (rtx);
+extern enum rtx_code classify_insn (rtx);
extern void dump_rtx_statistics (void);
/* In emit-rtl.c */
/* In emit-rtl.c */
extern rtvec gen_rtvec_v (int, rtx *);
-extern rtx gen_reg_rtx (enum machine_mode);
-extern rtx gen_rtx_REG_offset (rtx, enum machine_mode, unsigned int, int);
-extern rtx gen_reg_rtx_offset (rtx, enum machine_mode, int);
+extern rtvec gen_rtvec_v (int, rtx_insn **);
+extern rtx gen_reg_rtx (machine_mode);
+extern rtx gen_rtx_REG_offset (rtx, machine_mode, unsigned int, int);
+extern rtx gen_reg_rtx_offset (rtx, machine_mode, int);
extern rtx gen_reg_rtx_and_attrs (rtx);
extern rtx_code_label *gen_label_rtx (void);
-extern rtx gen_lowpart_common (enum machine_mode, rtx);
+extern rtx gen_lowpart_common (machine_mode, rtx);
/* In cse.c */
-extern rtx gen_lowpart_if_possible (enum machine_mode, rtx);
+extern rtx gen_lowpart_if_possible (machine_mode, rtx);
/* In emit-rtl.c */
-extern rtx gen_highpart (enum machine_mode, rtx);
-extern rtx gen_highpart_mode (enum machine_mode, enum machine_mode, rtx);
-extern rtx operand_subword (rtx, unsigned int, int, enum machine_mode);
+extern rtx gen_highpart (machine_mode, rtx);
+extern rtx gen_highpart_mode (machine_mode, machine_mode, rtx);
+extern rtx operand_subword (rtx, unsigned int, int, machine_mode);
/* In emit-rtl.c */
-extern rtx operand_subword_force (rtx, unsigned int, enum machine_mode);
+extern rtx operand_subword_force (rtx, unsigned int, machine_mode);
extern bool paradoxical_subreg_p (const_rtx);
extern int subreg_lowpart_p (const_rtx);
-extern unsigned int subreg_lowpart_offset (enum machine_mode,
- enum machine_mode);
-extern unsigned int subreg_highpart_offset (enum machine_mode,
- enum machine_mode);
-extern int byte_lowpart_offset (enum machine_mode, enum machine_mode);
+extern unsigned int subreg_lowpart_offset (machine_mode,
+ machine_mode);
+extern unsigned int subreg_highpart_offset (machine_mode,
+ machine_mode);
+extern int byte_lowpart_offset (machine_mode, machine_mode);
extern rtx make_safe_from (rtx, rtx);
-extern rtx convert_memory_address_addr_space (enum machine_mode, rtx,
+extern rtx convert_memory_address_addr_space (machine_mode, rtx,
addr_space_t);
#define convert_memory_address(to_mode,x) \
convert_memory_address_addr_space ((to_mode), (x), ADDR_SPACE_GENERIC)
extern const char *get_insn_name (int);
extern rtx_insn *get_last_insn_anywhere (void);
-extern rtx get_first_nonnote_insn (void);
-extern rtx get_last_nonnote_insn (void);
+extern rtx_insn *get_first_nonnote_insn (void);
+extern rtx_insn *get_last_nonnote_insn (void);
extern void start_sequence (void);
extern void push_to_sequence (rtx_insn *);
extern void push_to_sequence2 (rtx_insn *, rtx_insn *);
#endif
extern void cwi_output_hex (FILE *, const_rtx);
#ifndef GENERATOR_FILE
-extern rtx immed_wide_int_const (const wide_int_ref &, enum machine_mode);
+extern rtx immed_wide_int_const (const wide_int_ref &, machine_mode);
#endif
#if TARGET_SUPPORTS_WIDE_INT == 0
extern rtx immed_double_const (HOST_WIDE_INT, HOST_WIDE_INT,
- enum machine_mode);
+ machine_mode);
#endif
/* In loop-iv.c */
-extern rtx lowpart_subreg (enum machine_mode, rtx, enum machine_mode);
+extern rtx lowpart_subreg (machine_mode, rtx, machine_mode);
/* In varasm.c */
-extern rtx force_const_mem (enum machine_mode, rtx);
+extern rtx force_const_mem (machine_mode, rtx);
/* In varasm.c */
struct function;
-extern rtx get_pool_constant (rtx);
+extern rtx get_pool_constant (const_rtx);
extern rtx get_pool_constant_mark (rtx, bool *);
-extern enum machine_mode get_pool_mode (const_rtx);
+extern machine_mode get_pool_mode (const_rtx);
extern rtx simplify_subtraction (rtx);
extern void decide_function_section (tree);
-/* In function.c */
-extern rtx assign_stack_local (enum machine_mode, HOST_WIDE_INT, int);
-#define ASLK_REDUCE_ALIGN 1
-#define ASLK_RECORD_PAD 2
-extern rtx assign_stack_local_1 (enum machine_mode, HOST_WIDE_INT, int, int);
-extern rtx assign_stack_temp (enum machine_mode, HOST_WIDE_INT);
-extern rtx assign_stack_temp_for_type (enum machine_mode, HOST_WIDE_INT, tree);
-extern rtx assign_temp (tree, int, int);
-
/* In emit-rtl.c */
extern rtx_insn *emit_insn_before (rtx, rtx);
-extern rtx_insn *emit_insn_before_noloc (rtx, rtx, basic_block);
-extern rtx_insn *emit_insn_before_setloc (rtx, rtx, int);
-extern rtx_insn *emit_jump_insn_before (rtx, rtx);
-extern rtx_insn *emit_jump_insn_before_noloc (rtx, rtx);
-extern rtx_insn *emit_jump_insn_before_setloc (rtx, rtx, int);
-extern rtx_insn *emit_call_insn_before (rtx, rtx);
-extern rtx_insn *emit_call_insn_before_noloc (rtx, rtx);
-extern rtx_insn *emit_call_insn_before_setloc (rtx, rtx, int);
-extern rtx_insn *emit_debug_insn_before (rtx, rtx);
+extern rtx_insn *emit_insn_before_noloc (rtx, rtx_insn *, basic_block);
+extern rtx_insn *emit_insn_before_setloc (rtx, rtx_insn *, int);
+extern rtx_jump_insn *emit_jump_insn_before (rtx, rtx);
+extern rtx_jump_insn *emit_jump_insn_before_noloc (rtx, rtx_insn *);
+extern rtx_jump_insn *emit_jump_insn_before_setloc (rtx, rtx_insn *, int);
+extern rtx_insn *emit_call_insn_before (rtx, rtx_insn *);
+extern rtx_insn *emit_call_insn_before_noloc (rtx, rtx_insn *);
+extern rtx_insn *emit_call_insn_before_setloc (rtx, rtx_insn *, int);
+extern rtx_insn *emit_debug_insn_before (rtx, rtx_insn *);
extern rtx_insn *emit_debug_insn_before_noloc (rtx, rtx);
extern rtx_insn *emit_debug_insn_before_setloc (rtx, rtx, int);
extern rtx_barrier *emit_barrier_before (rtx);
-extern rtx_insn *emit_label_before (rtx, rtx);
-extern rtx_note *emit_note_before (enum insn_note, rtx);
+extern rtx_code_label *emit_label_before (rtx, rtx_insn *);
+extern rtx_note *emit_note_before (enum insn_note, rtx_insn *);
extern rtx_insn *emit_insn_after (rtx, rtx);
extern rtx_insn *emit_insn_after_noloc (rtx, rtx, basic_block);
extern rtx_insn *emit_insn_after_setloc (rtx, rtx, int);
-extern rtx_insn *emit_jump_insn_after (rtx, rtx);
-extern rtx_insn *emit_jump_insn_after_noloc (rtx, rtx);
-extern rtx_insn *emit_jump_insn_after_setloc (rtx, rtx, int);
+extern rtx_jump_insn *emit_jump_insn_after (rtx, rtx);
+extern rtx_jump_insn *emit_jump_insn_after_noloc (rtx, rtx);
+extern rtx_jump_insn *emit_jump_insn_after_setloc (rtx, rtx, int);
extern rtx_insn *emit_call_insn_after (rtx, rtx);
extern rtx_insn *emit_call_insn_after_noloc (rtx, rtx);
extern rtx_insn *emit_call_insn_after_setloc (rtx, rtx, int);
extern rtx_insn *emit_debug_insn_after_noloc (rtx, rtx);
extern rtx_insn *emit_debug_insn_after_setloc (rtx, rtx, int);
extern rtx_barrier *emit_barrier_after (rtx);
-extern rtx_insn *emit_label_after (rtx, rtx);
-extern rtx_note *emit_note_after (enum insn_note, rtx);
+extern rtx_insn *emit_label_after (rtx, rtx_insn *);
+extern rtx_note *emit_note_after (enum insn_note, rtx_insn *);
extern rtx_insn *emit_insn (rtx);
extern rtx_insn *emit_debug_insn (rtx);
extern rtx_insn *emit_jump_insn (rtx);
extern rtx_insn *emit_call_insn (rtx);
-extern rtx_insn *emit_label (rtx);
+extern rtx_code_label *emit_label (rtx);
extern rtx_jump_table_data *emit_jump_table_data (rtx);
extern rtx_barrier *emit_barrier (void);
extern rtx_note *emit_note (enum insn_note);
extern rtx_insn *make_insn_raw (rtx);
extern void add_function_usage_to (rtx, rtx);
extern rtx_call_insn *last_call_insn (void);
-extern rtx_insn *previous_insn (rtx);
-extern rtx_insn *next_insn (rtx);
+extern rtx_insn *previous_insn (rtx_insn *);
+extern rtx_insn *next_insn (rtx_insn *);
extern rtx_insn *prev_nonnote_insn (rtx);
extern rtx_insn *prev_nonnote_insn_bb (rtx);
extern rtx_insn *next_nonnote_insn (rtx);
-extern rtx_insn *next_nonnote_insn_bb (rtx);
+extern rtx_insn *next_nonnote_insn_bb (rtx_insn *);
extern rtx_insn *prev_nondebug_insn (rtx);
extern rtx_insn *next_nondebug_insn (rtx);
extern rtx_insn *prev_nonnote_nondebug_insn (rtx);
extern rtx_insn *next_active_insn (rtx);
extern int active_insn_p (const_rtx);
extern rtx_insn *next_cc0_user (rtx);
-extern rtx_insn *prev_cc0_setter (rtx);
+extern rtx_insn *prev_cc0_setter (rtx_insn *);
/* In emit-rtl.c */
-extern int insn_line (const_rtx);
-extern const char * insn_file (const_rtx);
-extern tree insn_scope (const_rtx);
-extern expanded_location insn_location (const_rtx);
+extern int insn_line (const rtx_insn *);
+extern const char * insn_file (const rtx_insn *);
+extern tree insn_scope (const rtx_insn *);
+extern expanded_location insn_location (const rtx_insn *);
extern location_t prologue_location, epilogue_location;
/* In jump.c */
extern enum rtx_code swap_condition (enum rtx_code);
extern enum rtx_code unsigned_condition (enum rtx_code);
extern enum rtx_code signed_condition (enum rtx_code);
-extern void mark_jump_label (rtx, rtx, int);
+extern void mark_jump_label (rtx, rtx_insn *, int);
/* In jump.c */
extern rtx_insn *delete_related_insns (rtx);
extern rtx *find_constant_term_loc (rtx *);
/* In emit-rtl.c */
-extern rtx_insn *try_split (rtx, rtx, int);
+extern rtx_insn *try_split (rtx, rtx_insn *, int);
extern int split_branch_probability;
-/* In unknown file */
-extern rtx split_insns (rtx, rtx);
+/* In insn-recog.c (generated by genrecog). */
+extern rtx_insn *split_insns (rtx, rtx_insn *);
/* In simplify-rtx.c */
-extern rtx simplify_const_unary_operation (enum rtx_code, enum machine_mode,
- rtx, enum machine_mode);
-extern rtx simplify_unary_operation (enum rtx_code, enum machine_mode, rtx,
- enum machine_mode);
-extern rtx simplify_const_binary_operation (enum rtx_code, enum machine_mode,
+extern rtx simplify_const_unary_operation (enum rtx_code, machine_mode,
+ rtx, machine_mode);
+extern rtx simplify_unary_operation (enum rtx_code, machine_mode, rtx,
+ machine_mode);
+extern rtx simplify_const_binary_operation (enum rtx_code, machine_mode,
rtx, rtx);
-extern rtx simplify_binary_operation (enum rtx_code, enum machine_mode, rtx,
+extern rtx simplify_binary_operation (enum rtx_code, machine_mode, rtx,
rtx);
-extern rtx simplify_ternary_operation (enum rtx_code, enum machine_mode,
- enum machine_mode, rtx, rtx, rtx);
+extern rtx simplify_ternary_operation (enum rtx_code, machine_mode,
+ machine_mode, rtx, rtx, rtx);
extern rtx simplify_const_relational_operation (enum rtx_code,
- enum machine_mode, rtx, rtx);
-extern rtx simplify_relational_operation (enum rtx_code, enum machine_mode,
- enum machine_mode, rtx, rtx);
-extern rtx simplify_gen_binary (enum rtx_code, enum machine_mode, rtx, rtx);
-extern rtx simplify_gen_unary (enum rtx_code, enum machine_mode, rtx,
- enum machine_mode);
-extern rtx simplify_gen_ternary (enum rtx_code, enum machine_mode,
- enum machine_mode, rtx, rtx, rtx);
-extern rtx simplify_gen_relational (enum rtx_code, enum machine_mode,
- enum machine_mode, rtx, rtx);
-extern rtx simplify_subreg (enum machine_mode, rtx, enum machine_mode,
+ machine_mode, rtx, rtx);
+extern rtx simplify_relational_operation (enum rtx_code, machine_mode,
+ machine_mode, rtx, rtx);
+extern rtx simplify_gen_binary (enum rtx_code, machine_mode, rtx, rtx);
+extern rtx simplify_gen_unary (enum rtx_code, machine_mode, rtx,
+ machine_mode);
+extern rtx simplify_gen_ternary (enum rtx_code, machine_mode,
+ machine_mode, rtx, rtx, rtx);
+extern rtx simplify_gen_relational (enum rtx_code, machine_mode,
+ machine_mode, rtx, rtx);
+extern rtx simplify_subreg (machine_mode, rtx, machine_mode,
unsigned int);
-extern rtx simplify_gen_subreg (enum machine_mode, rtx, enum machine_mode,
+extern rtx simplify_gen_subreg (machine_mode, rtx, machine_mode,
unsigned int);
extern rtx simplify_replace_fn_rtx (rtx, const_rtx,
rtx (*fn) (rtx, const_rtx, void *), void *);
extern rtx simplify_rtx (const_rtx);
extern rtx avoid_constant_pool_reference (rtx);
extern rtx delegitimize_mem_from_attrs (rtx);
-extern bool mode_signbit_p (enum machine_mode, const_rtx);
-extern bool val_signbit_p (enum machine_mode, unsigned HOST_WIDE_INT);
-extern bool val_signbit_known_set_p (enum machine_mode,
+extern bool mode_signbit_p (machine_mode, const_rtx);
+extern bool val_signbit_p (machine_mode, unsigned HOST_WIDE_INT);
+extern bool val_signbit_known_set_p (machine_mode,
unsigned HOST_WIDE_INT);
-extern bool val_signbit_known_clear_p (enum machine_mode,
+extern bool val_signbit_known_clear_p (machine_mode,
unsigned HOST_WIDE_INT);
/* In reginfo.c */
-extern enum machine_mode choose_hard_reg_mode (unsigned int, unsigned int,
+extern machine_mode choose_hard_reg_mode (unsigned int, unsigned int,
bool);
+#ifdef HARD_CONST
+extern const HARD_REG_SET &simplifiable_subregs (const subreg_shape &);
+#endif
/* In emit-rtl.c */
extern rtx set_for_reg_notes (rtx);
/* Functions in rtlanal.c */
-/* Single set is implemented as macro for performance reasons. */
-#define single_set(I) (INSN_P (I) \
- ? (GET_CODE (PATTERN (I)) == SET \
- ? PATTERN (I) : single_set_1 (I)) \
- : NULL_RTX)
-#define single_set_1(I) single_set_2 (I, PATTERN (I))
+extern rtx single_set_2 (const rtx_insn *, const_rtx);
-/* Structure used for passing data to REPLACE_LABEL. */
-struct replace_label_data
+/* Handle the cheap and common cases inline for performance. */
+
+inline rtx single_set (const rtx_insn *insn)
{
- rtx r1;
- rtx r2;
- bool update_label_nuses;
-};
+ if (!INSN_P (insn))
+ return NULL_RTX;
+
+ if (GET_CODE (PATTERN (insn)) == SET)
+ return PATTERN (insn);
+
+ /* Defer to the more expensive case. */
+ return single_set_2 (insn, PATTERN (insn));
+}
-extern enum machine_mode get_address_mode (rtx mem);
+extern machine_mode get_address_mode (rtx mem);
extern int rtx_addr_can_trap_p (const_rtx);
extern bool nonzero_address_p (const_rtx);
extern int rtx_unstable_p (const_rtx);
extern int reg_mentioned_p (const_rtx, const_rtx);
extern int count_occurrences (const_rtx, const_rtx, int);
extern int reg_referenced_p (const_rtx, const_rtx);
-extern int reg_used_between_p (const_rtx, const_rtx, const_rtx);
-extern int reg_set_between_p (const_rtx, const_rtx, const_rtx);
+extern int reg_used_between_p (const_rtx, const rtx_insn *, const rtx_insn *);
+extern int reg_set_between_p (const_rtx, const rtx_insn *, const rtx_insn *);
extern int commutative_operand_precedence (rtx);
extern bool swap_commutative_operands_p (rtx, rtx);
-extern int modified_between_p (const_rtx, const_rtx, const_rtx);
-extern int no_labels_between_p (const_rtx, const_rtx);
+extern int modified_between_p (const_rtx, const rtx_insn *, const rtx_insn *);
+extern int no_labels_between_p (const rtx_insn *, const rtx_insn *);
extern int modified_in_p (const_rtx, const_rtx);
extern int reg_set_p (const_rtx, const_rtx);
-extern rtx single_set_2 (const_rtx, const_rtx);
extern int multiple_sets (const_rtx);
extern int set_noop_p (const_rtx);
-extern int noop_move_p (const_rtx);
-extern rtx find_last_value (rtx, rtx *, rtx, int);
-extern int refers_to_regno_p (unsigned int, unsigned int, const_rtx, rtx *);
+extern int noop_move_p (const rtx_insn *);
+extern bool refers_to_regno_p (unsigned int, unsigned int, const_rtx, rtx *);
extern int reg_overlap_mentioned_p (const_rtx, const_rtx);
extern const_rtx set_of (const_rtx, const_rtx);
extern void record_hard_reg_sets (rtx, const_rtx, void *);
extern void record_hard_reg_uses (rtx *, void *);
#ifdef HARD_CONST
-extern void find_all_hard_reg_sets (const_rtx, HARD_REG_SET *, bool);
+extern void find_all_hard_regs (const_rtx, HARD_REG_SET *);
+extern void find_all_hard_reg_sets (const rtx_insn *, HARD_REG_SET *, bool);
#endif
extern void note_stores (const_rtx, void (*) (rtx, const_rtx, void *), void *);
extern void note_uses (rtx *, void (*) (rtx *, void *), void *);
extern rtx find_reg_note (const_rtx, enum reg_note, const_rtx);
extern rtx find_regno_note (const_rtx, enum reg_note, unsigned int);
extern rtx find_reg_equal_equiv_note (const_rtx);
-extern rtx find_constant_src (const_rtx);
+extern rtx find_constant_src (const rtx_insn *);
extern int find_reg_fusage (const_rtx, enum rtx_code, const_rtx);
extern int find_regno_fusage (const_rtx, enum rtx_code, unsigned int);
extern rtx alloc_reg_note (enum reg_note, rtx, rtx);
extern void add_reg_note (rtx, enum reg_note, rtx);
extern void add_int_reg_note (rtx, enum reg_note, int);
-extern void add_shallow_copy_of_reg_note (rtx, rtx);
+extern void add_shallow_copy_of_reg_note (rtx_insn *, rtx);
extern void remove_note (rtx, const_rtx);
-extern void remove_reg_equal_equiv_notes (rtx);
+extern void remove_reg_equal_equiv_notes (rtx_insn *);
extern void remove_reg_equal_equiv_notes_for_regno (unsigned int);
extern int side_effects_p (const_rtx);
extern int volatile_refs_p (const_rtx);
extern bool can_throw_external (const_rtx);
extern bool insn_could_throw_p (const_rtx);
extern bool insn_nothrow_p (const_rtx);
-extern bool can_nonlocal_goto (const_rtx);
-extern void copy_reg_eh_region_note_forward (rtx, rtx, rtx);
-extern void copy_reg_eh_region_note_backward (rtx, rtx, rtx);
+extern bool can_nonlocal_goto (const rtx_insn *);
+extern void copy_reg_eh_region_note_forward (rtx, rtx_insn *, rtx);
+extern void copy_reg_eh_region_note_backward (rtx, rtx_insn *, rtx);
extern int inequality_comparisons_p (const_rtx);
extern rtx replace_rtx (rtx, rtx, rtx);
-extern int replace_label (rtx *, void *);
-extern int rtx_referenced_p (rtx, rtx);
-extern bool tablejump_p (const_rtx, rtx *, rtx_jump_table_data **);
-extern int computed_jump_p (const_rtx);
-extern bool tls_referenced_p (rtx);
-
-typedef int (*rtx_function) (rtx *, void *);
-extern int for_each_rtx (rtx *, rtx_function, void *);
-extern int for_each_rtx_in_insn (rtx_insn **, rtx_function, void *);
+extern void replace_label (rtx *, rtx, rtx, bool);
+extern void replace_label_in_insn (rtx_insn *, rtx, rtx, bool);
+extern bool rtx_referenced_p (const_rtx, const_rtx);
+extern bool tablejump_p (const rtx_insn *, rtx *, rtx_jump_table_data **);
+extern int computed_jump_p (const rtx_insn *);
+extern bool tls_referenced_p (const_rtx);
+
+/* Overload for refers_to_regno_p for checking a single register. */
+inline bool
+refers_to_regno_p (unsigned int regnum, const_rtx x, rtx* loc = NULL)
+{
+ return refers_to_regno_p (regnum, regnum + 1, x, loc);
+}
/* Callback for for_each_inc_dec, to process the autoinc operation OP
within MEM that sets DEST to SRC + SRCOFF, or SRC if SRCOFF is
NULL. The callback is passed the same opaque ARG passed to
for_each_inc_dec. Return zero to continue looking for other
- autoinc operations, -1 to skip OP's operands, and any other value
- to interrupt the traversal and return that value to the caller of
- for_each_inc_dec. */
+ autoinc operations or any other value to interrupt the traversal and
+ return that value to the caller of for_each_inc_dec. */
typedef int (*for_each_inc_dec_fn) (rtx mem, rtx op, rtx dest, rtx src,
rtx srcoff, void *arg);
-extern int for_each_inc_dec (rtx_insn **, for_each_inc_dec_fn, void *arg);
+extern int for_each_inc_dec (rtx, for_each_inc_dec_fn, void *arg);
typedef int (*rtx_equal_p_callback_function) (const_rtx *, const_rtx *,
rtx *, rtx *);
extern int rtx_equal_p_cb (const_rtx, const_rtx,
rtx_equal_p_callback_function);
-typedef int (*hash_rtx_callback_function) (const_rtx, enum machine_mode, rtx *,
- enum machine_mode *);
-extern unsigned hash_rtx_cb (const_rtx, enum machine_mode, int *, int *,
+typedef int (*hash_rtx_callback_function) (const_rtx, machine_mode, rtx *,
+ machine_mode *);
+extern unsigned hash_rtx_cb (const_rtx, machine_mode, int *, int *,
bool, hash_rtx_callback_function);
extern rtx regno_use_in (unsigned int, rtx);
extern int auto_inc_p (const_rtx);
-extern int in_expr_list_p (const_rtx, const_rtx);
-extern void remove_node_from_expr_list (const_rtx, rtx *);
+extern bool in_insn_list_p (const rtx_insn_list *, const rtx_insn *);
+extern void remove_node_from_expr_list (const_rtx, rtx_expr_list **);
+extern void remove_node_from_insn_list (const rtx_insn *, rtx_insn_list **);
extern int loc_mentioned_in_p (rtx *, const_rtx);
-extern rtx_insn *find_first_parameter_load (rtx, rtx);
-extern bool keep_with_call_p (const_rtx);
-extern bool label_is_jump_target_p (const_rtx, const_rtx);
+extern rtx_insn *find_first_parameter_load (rtx_insn *, rtx_insn *);
+extern bool keep_with_call_p (const rtx_insn *);
+extern bool label_is_jump_target_p (const_rtx, const rtx_insn *);
extern int insn_rtx_cost (rtx, bool);
+extern unsigned seq_cost (const rtx_insn *, bool);
/* Given an insn and condition, return a canonical description of
the test being made. */
{
/* Offset of first hard register involved in the subreg. */
int offset;
- /* Number of hard registers involved in the subreg. */
+ /* Number of hard registers involved in the subreg. In the case of
+ a paradoxical subreg, this is the number of registers that would
+ be modified by writing to the subreg; some of them may be don't-care
+ when reading from the subreg. */
int nregs;
/* Whether this subreg can be represented as a hard reg with the new
- mode. */
+ mode (by adding OFFSET to the original hard register). */
bool representable_p;
};
-extern void subreg_get_info (unsigned int, enum machine_mode,
- unsigned int, enum machine_mode,
+extern void subreg_get_info (unsigned int, machine_mode,
+ unsigned int, machine_mode,
struct subreg_info *);
/* lists.c */
-extern void free_EXPR_LIST_list (rtx *);
+extern void free_EXPR_LIST_list (rtx_expr_list **);
extern void free_INSN_LIST_list (rtx_insn_list **);
extern void free_EXPR_LIST_node (rtx);
extern void free_INSN_LIST_node (rtx);
extern rtx_insn_list *alloc_INSN_LIST (rtx, rtx);
extern rtx_insn_list *copy_INSN_LIST (rtx_insn_list *);
extern rtx_insn_list *concat_INSN_LIST (rtx_insn_list *, rtx_insn_list *);
-extern rtx alloc_EXPR_LIST (int, rtx, rtx);
+extern rtx_expr_list *alloc_EXPR_LIST (int, rtx, rtx);
extern void remove_free_INSN_LIST_elem (rtx_insn *, rtx_insn_list **);
extern rtx remove_list_elem (rtx, rtx *);
extern rtx_insn *remove_free_INSN_LIST_node (rtx_insn_list **);
-extern rtx remove_free_EXPR_LIST_node (rtx *);
+extern rtx remove_free_EXPR_LIST_node (rtx_expr_list **);
/* reginfo.c */
extern rtx extract_asm_operands (rtx);
extern int asm_noperands (const_rtx);
extern const char *decode_asm_operands (rtx, rtx *, rtx **, const char **,
- enum machine_mode *, location_t *);
+ machine_mode *, location_t *);
extern void get_referenced_operands (const char *, bool *, unsigned int);
extern enum reg_class reg_preferred_class (int);
extern GTY(()) rtx cc0_rtx;
extern GTY(()) rtx ret_rtx;
extern GTY(()) rtx simple_return_rtx;
+extern GTY(()) rtx_insn *invalid_insn_rtx;
/* If HARD_FRAME_POINTER_REGNUM is defined, then a special dummy reg
is used to represent the frame pointer. This is because the
generation functions included above do the raw handling. If you
add to this list, modify special_rtx in gengenrtl.c as well. */
-extern rtx_expr_list *gen_rtx_EXPR_LIST (enum machine_mode, rtx, rtx);
-extern rtx_insn_list *gen_rtx_INSN_LIST (enum machine_mode, rtx, rtx);
-extern rtx gen_rtx_CONST_INT (enum machine_mode, HOST_WIDE_INT);
-extern rtx gen_rtx_CONST_VECTOR (enum machine_mode, rtvec);
-extern rtx gen_raw_REG (enum machine_mode, int);
-extern rtx gen_rtx_REG (enum machine_mode, unsigned);
-extern rtx gen_rtx_SUBREG (enum machine_mode, rtx, int);
-extern rtx gen_rtx_MEM (enum machine_mode, rtx);
-extern rtx gen_rtx_VAR_LOCATION (enum machine_mode, tree, rtx,
+extern rtx_expr_list *gen_rtx_EXPR_LIST (machine_mode, rtx, rtx);
+extern rtx_insn_list *gen_rtx_INSN_LIST (machine_mode, rtx, rtx);
+extern rtx_insn *
+gen_rtx_INSN (machine_mode mode, rtx_insn *prev_insn, rtx_insn *next_insn,
+ basic_block bb, rtx pattern, int location, int code,
+ rtx reg_notes);
+extern rtx gen_rtx_CONST_INT (machine_mode, HOST_WIDE_INT);
+extern rtx gen_rtx_CONST_VECTOR (machine_mode, rtvec);
+extern void set_mode_and_regno (rtx, machine_mode, unsigned int);
+extern rtx gen_raw_REG (machine_mode, unsigned int);
+extern rtx gen_rtx_REG (machine_mode, unsigned int);
+extern rtx gen_rtx_SUBREG (machine_mode, rtx, int);
+extern rtx gen_rtx_MEM (machine_mode, rtx);
+extern rtx gen_rtx_VAR_LOCATION (machine_mode, tree, rtx,
enum var_init_status);
+#ifdef GENERATOR_FILE
+#define PUT_MODE(RTX, MODE) PUT_MODE_RAW (RTX, MODE)
+#else
+static inline void
+PUT_MODE (rtx x, machine_mode mode)
+{
+ if (REG_P (x))
+ set_mode_and_regno (x, mode, REGNO (x));
+ else
+ PUT_MODE_RAW (x, mode);
+}
+#endif
+
#define GEN_INT(N) gen_rtx_CONST_INT (VOIDmode, (N))
/* Virtual registers are used during RTL generation to refer to locations into
/* In cse.c */
extern int delete_trivially_dead_insns (rtx_insn *, int);
extern int exp_equiv_p (const_rtx, const_rtx, int, bool);
-extern unsigned hash_rtx (const_rtx x, enum machine_mode, int *, int *, bool);
+extern unsigned hash_rtx (const_rtx x, machine_mode, int *, int *, bool);
/* In dse.c */
extern bool check_for_inc_dec (rtx_insn *insn);
/* In jump.c */
extern int comparison_dominates_p (enum rtx_code, enum rtx_code);
-extern bool jump_to_label_p (rtx);
-extern int condjump_p (const_rtx);
-extern int any_condjump_p (const_rtx);
-extern int any_uncondjump_p (const_rtx);
-extern rtx pc_set (const_rtx);
-extern rtx condjump_label (const_rtx);
-extern int simplejump_p (const_rtx);
-extern int returnjump_p (rtx);
-extern int eh_returnjump_p (rtx);
-extern int onlyjump_p (const_rtx);
+extern bool jump_to_label_p (const rtx_insn *);
+extern int condjump_p (const rtx_insn *);
+extern int any_condjump_p (const rtx_insn *);
+extern int any_uncondjump_p (const rtx_insn *);
+extern rtx pc_set (const rtx_insn *);
+extern rtx condjump_label (const rtx_insn *);
+extern int simplejump_p (const rtx_insn *);
+extern int returnjump_p (const rtx_insn *);
+extern int eh_returnjump_p (rtx_insn *);
+extern int onlyjump_p (const rtx_insn *);
extern int only_sets_cc0_p (const_rtx);
extern int sets_cc0_p (const_rtx);
-extern int invert_jump_1 (rtx, rtx);
-extern int invert_jump (rtx, rtx, int);
+extern int invert_jump_1 (rtx_jump_insn *, rtx);
+extern int invert_jump (rtx_jump_insn *, rtx, int);
extern int rtx_renumbered_equal_p (const_rtx, const_rtx);
extern int true_regnum (const_rtx);
extern unsigned int reg_or_subregno (const_rtx);
-extern int redirect_jump_1 (rtx, rtx);
-extern void redirect_jump_2 (rtx, rtx, rtx, int, int);
-extern int redirect_jump (rtx, rtx, int);
+extern int redirect_jump_1 (rtx_insn *, rtx);
+extern void redirect_jump_2 (rtx_jump_insn *, rtx, rtx, int, int);
+extern int redirect_jump (rtx_jump_insn *, rtx, int);
extern void rebuild_jump_labels (rtx_insn *);
extern void rebuild_jump_labels_chain (rtx_insn *);
-extern rtx reversed_comparison (const_rtx, enum machine_mode);
+extern rtx reversed_comparison (const_rtx, machine_mode);
extern enum rtx_code reversed_comparison_code (const_rtx, const_rtx);
extern enum rtx_code reversed_comparison_code_parts (enum rtx_code, const_rtx,
const_rtx, const_rtx);
extern void delete_for_peephole (rtx_insn *, rtx_insn *);
-extern int condjump_in_parallel_p (const_rtx);
+extern int condjump_in_parallel_p (const rtx_insn *);
/* In emit-rtl.c. */
extern int max_reg_num (void);
extern void set_new_first_and_last_insn (rtx_insn *, rtx_insn *);
extern unsigned int unshare_all_rtl (void);
extern void unshare_all_rtl_again (rtx_insn *);
-extern void unshare_all_rtl_in_chain (rtx);
+extern void unshare_all_rtl_in_chain (rtx_insn *);
extern void verify_rtl_sharing (void);
extern void add_insn (rtx_insn *);
extern void add_insn_before (rtx, rtx, basic_block);
extern void add_insn_after (rtx, rtx, basic_block);
extern void remove_insn (rtx);
-extern rtx_insn *emit (rtx);
-extern void delete_insn (rtx);
-extern rtx_insn *entry_of_function (void);
+extern rtx_insn *emit (rtx, bool = true);
extern void emit_insn_at_entry (rtx);
-extern void delete_insn_chain (rtx, rtx, bool);
-extern rtx_insn *unlink_insn_chain (rtx_insn *, rtx_insn *);
-extern void delete_insn_and_edges (rtx_insn *);
-extern rtx gen_lowpart_SUBREG (enum machine_mode, rtx);
-extern rtx gen_const_mem (enum machine_mode, rtx);
-extern rtx gen_frame_mem (enum machine_mode, rtx);
-extern rtx gen_tmp_stack_mem (enum machine_mode, rtx);
-extern bool validate_subreg (enum machine_mode, enum machine_mode,
+extern rtx gen_lowpart_SUBREG (machine_mode, rtx);
+extern rtx gen_const_mem (machine_mode, rtx);
+extern rtx gen_frame_mem (machine_mode, rtx);
+extern rtx gen_tmp_stack_mem (machine_mode, rtx);
+extern bool validate_subreg (machine_mode, machine_mode,
const_rtx, unsigned int);
/* In combine.c */
-extern unsigned int extended_count (const_rtx, enum machine_mode, int);
+extern unsigned int extended_count (const_rtx, machine_mode, int);
extern rtx remove_death (unsigned int, rtx_insn *);
extern void dump_combine_stats (FILE *);
extern void dump_combine_total_stats (FILE *);
extern rtx make_compound_operation (rtx, enum rtx_code);
-/* In cfgcleanup.c */
-extern void delete_dead_jumptables (void);
-
/* In sched-rgn.c. */
extern void schedule_insns (void);
extern void debug_rtx (const_rtx);
extern void debug_rtx_list (const rtx_insn *, int);
extern void debug_rtx_range (const rtx_insn *, const rtx_insn *);
-extern const_rtx debug_rtx_find (const rtx_insn *, int);
+extern const rtx_insn *debug_rtx_find (const rtx_insn *, int);
extern void print_mem_expr (FILE *, const_tree);
extern void print_rtl (FILE *, const_rtx);
extern void print_simple_rtl (FILE *, const_rtx);
not be in sched-vis.c but in rtl.c, because they are not only used
by the scheduler anymore but for all "slim" RTL dumping. */
extern void dump_value_slim (FILE *, const_rtx, int);
-extern void dump_insn_slim (FILE *, const_rtx);
-extern void dump_rtl_slim (FILE *, const_rtx, const_rtx, int, int);
+extern void dump_insn_slim (FILE *, const rtx_insn *);
+extern void dump_rtl_slim (FILE *, const rtx_insn *, const rtx_insn *,
+ int, int);
extern void print_value (pretty_printer *, const_rtx, int);
extern void print_pattern (pretty_printer *, const_rtx, int);
extern void print_insn (pretty_printer *, const_rtx, int);
extern void rtl_dump_bb_for_graph (pretty_printer *, basic_block);
extern const char *str_pattern_slim (const_rtx);
-/* In function.c */
-extern void reposition_prologue_and_epilogue_notes (void);
-extern int prologue_epilogue_contains (const_rtx);
-extern int sibcall_epilogue_contains (const_rtx);
-extern void update_temp_slot_address (rtx, rtx);
-extern void maybe_copy_prologue_epilogue_insn (rtx, rtx);
-extern void set_return_jump_label (rtx);
-
/* In stmt.c */
extern void expand_null_return (void);
extern void expand_naked_return (void);
/* In expr.c */
extern rtx move_by_pieces (rtx, rtx, unsigned HOST_WIDE_INT,
unsigned int, int);
-extern HOST_WIDE_INT find_args_size_adjust (rtx);
-extern int fixup_args_size_notes (rtx, rtx, int);
-
-/* In cfgrtl.c */
-extern void print_rtl_with_bb (FILE *, const rtx_insn *, int);
-extern rtx_insn *duplicate_insn_chain (rtx_insn *, rtx_insn *);
+extern HOST_WIDE_INT find_args_size_adjust (rtx_insn *);
+extern int fixup_args_size_notes (rtx_insn *, rtx_insn *, int);
/* In expmed.c */
extern void init_expmed (void);
extern void init_lower_subreg (void);
/* In gcse.c */
-extern bool can_copy_p (enum machine_mode);
+extern bool can_copy_p (machine_mode);
extern bool can_assign_to_reg_without_clobbers_p (rtx);
extern rtx fis_get_condition (rtx_insn *);
extern void regclass (rtx, int);
extern void reg_scan (rtx_insn *, unsigned int);
extern void fix_register (const char *, int, int);
-extern bool invalid_mode_change_p (unsigned int, enum reg_class);
+#ifdef HARD_CONST
+extern const HARD_REG_SET *valid_mode_changes_for_regno (unsigned int);
+#endif
/* In reload1.c */
extern int function_invariant_p (const_rtx);
LCT_RETURNS_TWICE = 5
};
-extern void emit_library_call (rtx, enum libcall_type, enum machine_mode, int,
+extern void emit_library_call (rtx, enum libcall_type, machine_mode, int,
...);
extern rtx emit_library_call_value (rtx, rtx, enum libcall_type,
- enum machine_mode, int, ...);
+ machine_mode, int, ...);
/* In varasm.c */
extern void init_varasm_once (void);
/* In alias.c */
extern rtx canon_rtx (rtx);
-extern int true_dependence (const_rtx, enum machine_mode, const_rtx);
+extern int true_dependence (const_rtx, machine_mode, const_rtx);
extern rtx get_addr (rtx);
-extern int canon_true_dependence (const_rtx, enum machine_mode, rtx,
+extern int canon_true_dependence (const_rtx, machine_mode, rtx,
const_rtx, rtx);
extern int read_dependence (const_rtx, const_rtx);
extern int anti_dependence (const_rtx, const_rtx);
extern int canon_anti_dependence (const_rtx, bool,
- const_rtx, enum machine_mode, rtx);
+ const_rtx, machine_mode, rtx);
extern int output_dependence (const_rtx, const_rtx);
extern int may_alias_p (const_rtx, const_rtx);
extern void init_alias_target (void);
extern bool memory_modified_in_insn_p (const_rtx, const_rtx);
extern bool memory_must_be_modified_in_insn_p (const_rtx, const_rtx);
extern bool may_be_sp_based_p (rtx);
-extern rtx gen_hard_reg_clobber (enum machine_mode, unsigned int);
+extern rtx gen_hard_reg_clobber (machine_mode, unsigned int);
extern rtx get_reg_known_value (unsigned int);
extern bool get_reg_known_equiv_p (unsigned int);
extern rtx get_reg_base_value (unsigned int);
/* In toplev.c */
extern GTY(()) rtx stack_limit_rtx;
-/* In predict.c */
-extern void invert_br_probabilities (rtx);
-extern bool expensive_function_p (int);
-
/* In var-tracking.c */
extern unsigned int variable_tracking_main (void);
/* In stor-layout.c. */
-extern void get_mode_bounds (enum machine_mode, int, enum machine_mode,
+extern void get_mode_bounds (machine_mode, int, machine_mode,
rtx *, rtx *);
/* In loop-iv.c */
\f
struct rtl_hooks
{
- rtx (*gen_lowpart) (enum machine_mode, rtx);
- rtx (*gen_lowpart_no_emit) (enum machine_mode, rtx);
- rtx (*reg_nonzero_bits) (const_rtx, enum machine_mode, const_rtx, enum machine_mode,
+ rtx (*gen_lowpart) (machine_mode, rtx);
+ rtx (*gen_lowpart_no_emit) (machine_mode, rtx);
+ rtx (*reg_nonzero_bits) (const_rtx, machine_mode, const_rtx, machine_mode,
unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT *);
- rtx (*reg_num_sign_bit_copies) (const_rtx, enum machine_mode, const_rtx, enum machine_mode,
+ rtx (*reg_num_sign_bit_copies) (const_rtx, machine_mode, const_rtx, machine_mode,
unsigned int, unsigned int *);
- bool (*reg_truncated_to_mode) (enum machine_mode, const_rtx);
+ bool (*reg_truncated_to_mode) (machine_mode, const_rtx);
/* Whenever you add entries here, make sure you adjust rtlhooks-def.h. */
};
extern void insn_locations_finalize (void);
extern void set_curr_insn_location (location_t);
extern location_t curr_insn_location (void);
-extern bool optimize_insn_for_size_p (void);
-extern bool optimize_insn_for_speed_p (void);
/* rtl-error.c */
extern void _fatal_insn_not_found (const_rtx, const char *, int, const char *)
/* reginfo.c */
extern tree GTY(()) global_regs_decl[FIRST_PSEUDO_REGISTER];
+#ifdef HARD_CONST
+/* Information about the function that is propagated by the RTL backend.
+ Available only for functions that has been already assembled. */
+
+struct GTY(()) cgraph_rtl_info {
+ unsigned int preferred_incoming_stack_boundary;
+
+ /* Call unsaved hard registers really used by the corresponding
+ function (including ones used by functions called by the
+ function). */
+ HARD_REG_SET function_used_regs;
+ /* Set if function_used_regs is valid. */
+ unsigned function_used_regs_valid: 1;
+};
+#endif
+
#endif /* ! GCC_RTL_H */