/* RTL expression ("rtx"). */
struct GTY((chain_next ("RTX_NEXT (&%h)"),
- chain_prev ("RTX_PREV (&%h)"))) rtx_def {
+ chain_prev ("RTX_PREV (&%h)"), variable_size)) rtx_def {
/* The kind of expression this is. */
ENUM_BITFIELD(rtx_code) code: 16;
for a variable number of things. The principle use is inside
PARALLEL expressions. */
-struct GTY(()) rtvec_def {
+struct GTY((variable_size)) rtvec_def {
int num_elem; /* number of elements */
rtx GTY ((length ("%h.num_elem"))) elem[1];
};
#define NEXT_INSN(INSN) XEXP (INSN, 2)
#define BLOCK_FOR_INSN(INSN) XBBDEF (INSN, 3)
-#define INSN_LOCATOR(INSN) XINT (INSN, 4)
+
+/* The body of an insn. */
+#define PATTERN(INSN) XEXP (INSN, 4)
+
+#define INSN_LOCATOR(INSN) XINT (INSN, 5)
/* LOCATION of an RTX if relevant. */
#define RTL_LOCATION(X) (INSN_P (X) ? \
locator_location (INSN_LOCATOR (X)) \
: UNKNOWN_LOCATION)
/* LOCATION of current INSN. */
#define CURR_INSN_LOCATION (locator_location (curr_insn_locator ()))
-/* The body of an insn. */
-#define PATTERN(INSN) XEXP (INSN, 5)
/* Code number of instruction, from when it was recognized.
-1 means this instruction has not been recognized yet. */
/* DEBUG_EXPR_DECL corresponding to a DEBUG_EXPR RTX. */
#define DEBUG_EXPR_TREE_DECL(RTX) XCTREE (RTX, 0, DEBUG_EXPR)
+/* VAR_DECL/PARM_DECL DEBUG_IMPLICIT_PTR takes address of. */
+#define DEBUG_IMPLICIT_PTR_DECL(RTX) XCTREE (RTX, 0, DEBUG_IMPLICIT_PTR)
+
/* Possible initialization status of a variable. When requested
by the user, this information is tracked and recorded in the DWARF
debug information, along with the variable's location. */
/* In jump.c, each label contains a count of the number
of LABEL_REFs that point at it, so unused labels can be deleted. */
-#define LABEL_NUSES(RTX) XCINT (RTX, 4, CODE_LABEL)
+#define LABEL_NUSES(RTX) XCINT (RTX, 5, CODE_LABEL)
/* Labels carry a two-bit field composed of the ->jump and ->call
bits. This field indicates whether the label is an alternate
/* 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, 5, CODE_LABEL)
+#define LABEL_REFS(LABEL) XCEXP (LABEL, 4, CODE_LABEL)
\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)
/* ORIGINAL_REGNO holds the number the register originally had; for a
pseudo register turned into a hard reg this will hold the old pseudo
}
-
/* 1 if RTX is a reg or parallel that is the current function's return
value. */
#define REG_FUNCTION_VALUE_P(RTX) \
extern int ceil_log2 (unsigned HOST_WIDE_INT);
/* In explow.c */
-extern void set_stack_check_libfunc (rtx);
extern HOST_WIDE_INT trunc_int_for_mode (HOST_WIDE_INT, enum machine_mode);
extern rtx plus_constant (rtx, HOST_WIDE_INT);
-/* In emit-rtl.c */
-extern rtx gen_blockage (void);
-extern rtvec gen_rtvec (int, ...);
-extern rtx copy_insn_1 (rtx);
-extern rtx copy_insn (rtx);
-extern rtx gen_int_mode (HOST_WIDE_INT, enum machine_mode);
-extern rtx emit_copy_of_insn_after (rtx, rtx);
-extern void set_reg_attrs_from_value (rtx, rtx);
-extern void set_reg_attrs_for_parm (rtx, rtx);
-extern void set_reg_attrs_for_decl_rtl (tree t, rtx x);
-extern void adjust_reg_mode (rtx, enum machine_mode);
-extern int mem_expr_equal_p (const_tree, const_tree);
-
/* In rtl.c */
extern rtx rtx_alloc_stat (RTX_CODE MEM_STAT_DECL);
#define rtx_alloc(c) rtx_alloc_stat (c MEM_STAT_INFO)
addr_space_t);
#define convert_memory_address(to_mode,x) \
convert_memory_address_addr_space ((to_mode), (x), ADDR_SPACE_GENERIC)
-extern rtx get_insns (void);
extern const char *get_insn_name (int);
-extern rtx get_last_insn (void);
extern rtx get_last_insn_anywhere (void);
extern rtx get_first_nonnote_insn (void);
extern rtx get_last_nonnote_insn (void);
extern rtx next_nonnote_insn_bb (rtx);
extern rtx prev_nondebug_insn (rtx);
extern rtx next_nondebug_insn (rtx);
+extern rtx prev_nonnote_nondebug_insn (rtx);
+extern rtx next_nonnote_nondebug_insn (rtx);
extern rtx prev_real_insn (rtx);
extern rtx next_real_insn (rtx);
extern rtx prev_active_insn (rtx);
#define HARD_FRAME_POINTER_REGNUM FRAME_POINTER_REGNUM
#endif
+#ifndef HARD_FRAME_POINTER_IS_FRAME_POINTER
+#define HARD_FRAME_POINTER_IS_FRAME_POINTER \
+ (HARD_FRAME_POINTER_REGNUM == FRAME_POINTER_REGNUM)
+#endif
+
+#ifndef HARD_FRAME_POINTER_IS_ARG_POINTER
+#define HARD_FRAME_POINTER_IS_ARG_POINTER \
+ (HARD_FRAME_POINTER_REGNUM == ARG_POINTER_REGNUM)
+#endif
+
/* Index labels for global_rtl. */
enum global_rtl_index
{
#if FRAME_POINTER_REGNUM == ARG_POINTER_REGNUM
GR_ARG_POINTER = GR_FRAME_POINTER,
#endif
-#if HARD_FRAME_POINTER_REGNUM == FRAME_POINTER_REGNUM
+#if HARD_FRAME_POINTER_IS_FRAME_POINTER
GR_HARD_FRAME_POINTER = GR_FRAME_POINTER,
#else
GR_HARD_FRAME_POINTER,
#endif
#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
-#if HARD_FRAME_POINTER_REGNUM == ARG_POINTER_REGNUM
+#if HARD_FRAME_POINTER_IS_ARG_POINTER
GR_ARG_POINTER = GR_HARD_FRAME_POINTER,
#else
GR_ARG_POINTER,
GR_VIRTUAL_STACK_DYNAMIC,
GR_VIRTUAL_OUTGOING_ARGS,
GR_VIRTUAL_CFA,
+ GR_VIRTUAL_PREFERRED_STACK_BOUNDARY,
GR_MAX
};
-/* Pointers to standard pieces of rtx are stored here. */
-extern GTY(()) rtx global_rtl[GR_MAX];
+/* Target-dependent globals. */
+struct GTY(()) target_rtl {
+ /* All references to the hard registers in global_rtl_index go through
+ these unique rtl objects. On machines where the frame-pointer and
+ arg-pointer are the same register, they use the same unique object.
+
+ After register allocation, other rtl objects which used to be pseudo-regs
+ may be clobbered to refer to the frame-pointer register.
+ But references that were originally to the frame-pointer can be
+ distinguished from the others because they contain frame_pointer_rtx.
+
+ When to use frame_pointer_rtx and hard_frame_pointer_rtx is a little
+ tricky: until register elimination has taken place hard_frame_pointer_rtx
+ should be used if it is being set, and frame_pointer_rtx otherwise. After
+ register elimination hard_frame_pointer_rtx should always be used.
+ On machines where the two registers are same (most) then these are the
+ same. */
+ rtx x_global_rtl[GR_MAX];
+
+ /* A unique representation of (REG:Pmode PIC_OFFSET_TABLE_REGNUM). */
+ rtx x_pic_offset_table_rtx;
+
+ /* A unique representation of (REG:Pmode RETURN_ADDRESS_POINTER_REGNUM).
+ This is used to implement __builtin_return_address for some machines;
+ see for instance the MIPS port. */
+ rtx x_return_address_pointer_rtx;
+
+ /* Commonly used RTL for hard registers. These objects are not
+ necessarily unique, so we allocate them separately from global_rtl.
+ They are initialized once per compilation unit, then copied into
+ regno_reg_rtx at the beginning of each function. */
+ rtx x_initial_regno_reg_rtx[FIRST_PSEUDO_REGISTER];
+
+ /* A sample (mem:M stack_pointer_rtx) rtx for each mode M. */
+ rtx x_top_of_stack[MAX_MACHINE_MODE];
+
+ /* Static hunks of RTL used by the aliasing code; these are treated
+ as persistent to avoid unnecessary RTL allocations. */
+ rtx x_static_reg_base_value[FIRST_PSEUDO_REGISTER];
+};
+
+extern GTY(()) struct target_rtl default_target_rtl;
+#if SWITCHABLE_TARGET
+extern struct target_rtl *this_target_rtl;
+#else
+#define this_target_rtl (&default_target_rtl)
+#endif
+
+#define global_rtl \
+ (this_target_rtl->x_global_rtl)
+#define pic_offset_table_rtx \
+ (this_target_rtl->x_pic_offset_table_rtx)
+#define return_address_pointer_rtx \
+ (this_target_rtl->x_return_address_pointer_rtx)
+#define top_of_stack \
+ (this_target_rtl->x_top_of_stack)
/* Standard pieces of rtx, to be substituted directly into things. */
#define pc_rtx (global_rtl[GR_PC])
#define hard_frame_pointer_rtx (global_rtl[GR_HARD_FRAME_POINTER])
#define arg_pointer_rtx (global_rtl[GR_ARG_POINTER])
-extern GTY(()) rtx pic_offset_table_rtx;
-extern GTY(()) rtx return_address_pointer_rtx;
-
/* Include the RTL generation functions. */
#ifndef GENERATOR_FILE
#define VIRTUAL_CFA_REGNUM ((FIRST_VIRTUAL_REGISTER) + 4)
-#define LAST_VIRTUAL_REGISTER ((FIRST_VIRTUAL_REGISTER) + 4)
+#define LAST_VIRTUAL_POINTER_REGISTER ((FIRST_VIRTUAL_REGISTER) + 4)
+
+/* This is replaced by crtl->preferred_stack_boundary / BITS_PER_UNIT
+ when finalized. */
+
+#define virtual_preferred_stack_boundary_rtx \
+ (global_rtl[GR_VIRTUAL_PREFERRED_STACK_BOUNDARY])
+
+#define VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM \
+ ((FIRST_VIRTUAL_REGISTER) + 5)
+
+#define LAST_VIRTUAL_REGISTER ((FIRST_VIRTUAL_REGISTER) + 5)
/* Nonzero if REGNUM is a pointer into the stack frame. */
#define REGNO_PTR_FRAME_P(REGNUM) \
|| (REGNUM) == HARD_FRAME_POINTER_REGNUM \
|| (REGNUM) == ARG_POINTER_REGNUM \
|| ((REGNUM) >= FIRST_VIRTUAL_REGISTER \
- && (REGNUM) <= LAST_VIRTUAL_REGISTER))
+ && (REGNUM) <= LAST_VIRTUAL_POINTER_REGISTER))
/* REGNUM never really appearing in the INSN stream. */
#define INVALID_REGNUM (~(unsigned int) 0)
extern void set_used_flags (rtx);
extern void reorder_insns (rtx, rtx, rtx);
extern void reorder_insns_nobb (rtx, rtx, rtx);
-extern int get_max_uid (void);
extern int get_max_insn_count (void);
extern int in_sequence_p (void);
extern void force_next_line_note (void);
extern void unshare_all_rtl_again (rtx);
extern void unshare_all_rtl_in_chain (rtx);
extern void verify_rtl_sharing (void);
-extern void set_first_insn (rtx);
-extern void set_last_insn (rtx);
extern void link_cc0_insns (rtx);
extern void add_insn (rtx);
extern void add_insn_before (rtx, rtx, struct basic_block_def *);
extern void mark_elimination (int, int);
/* In reginfo.c */
-extern int reg_classes_intersect_p (enum reg_class, enum reg_class);
-extern int reg_class_subset_p (enum reg_class, enum reg_class);
+extern int reg_classes_intersect_p (reg_class_t, reg_class_t);
+extern int reg_class_subset_p (reg_class_t, reg_class_t);
extern void globalize_reg (int);
extern void init_reg_modes_target (void);
extern void init_regs (void);
extern rtx make_debug_expr_from_rtl (const_rtx);
-/* In rtl.c */
-extern void traverse_md_constants (int (*) (void **, void *), void *);
-struct md_constant { char *name, *value; };
-
/* In read-rtl.c */
-extern int read_skip_spaces (FILE *);
-extern bool read_rtx (FILE *, rtx *, int *);
-extern void copy_rtx_ptr_loc (const void *, const void *);
-extern void print_rtx_ptr_loc (const void *);
-extern const char *join_c_conditions (const char *, const char *);
-extern void print_c_condition (const char *);
-extern const char *read_rtx_filename;
-extern int read_rtx_lineno;
+extern bool read_rtx (const char *, rtx *);
/* In alias.c */
extern rtx canon_rtx (rtx);
extern int read_dependence (const_rtx, const_rtx);
extern int anti_dependence (const_rtx, const_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 void init_alias_analysis (void);
extern void end_alias_analysis (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 *)
+ ATTRIBUTE_NORETURN;
+extern void _fatal_insn (const char *, const_rtx, const char *, int, const char *)
+ ATTRIBUTE_NORETURN;
+
+#define fatal_insn(msgid, insn) \
+ _fatal_insn (msgid, insn, __FILE__, __LINE__, __FUNCTION__)
+#define fatal_insn_not_found(insn) \
+ _fatal_insn_not_found (insn, __FILE__, __LINE__, __FUNCTION__)
+
+
+
#endif /* ! GCC_RTL_H */