/* Register Transfer Language (RTL) definitions for GCC
Copyright (C) 1987, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+ 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
This file is part of GCC.
#include "vecir.h"
#include "fixed-value.h"
#include "alias.h"
+#include "hashtab.h"
#undef FFS /* Some systems predefine this symbol; don't let it interfere. */
#undef FLOAT /* Likewise. */
/* Structure used to describe the attributes of a MEM. These are hashed
so MEMs that the same attributes share a data structure. This means
- they cannot be modified in place. If any element is nonzero, it means
- the value of the corresponding attribute is unknown. */
-/* ALIGN and SIZE are the alignment and size of the MEM itself,
- while EXPR can describe a larger underlying object, which might have a
- stricter alignment; OFFSET is the offset of the MEM within that object. */
+ they cannot be modified in place. */
typedef struct GTY(()) mem_attrs
{
- tree expr; /* expr corresponding to MEM. */
- rtx offset; /* Offset from start of DECL, as CONST_INT. */
- rtx size; /* Size in bytes, as a CONST_INT. */
- alias_set_type alias; /* Memory alias set. */
- unsigned int align; /* Alignment of MEM in bits. */
- unsigned char addrspace; /* Address space (0 for generic). */
+ /* The expression that the MEM accesses, or null if not known.
+ This expression might be larger than the memory reference itself.
+ (In other words, the MEM might access only part of the object.) */
+ tree expr;
+
+ /* The offset of the memory reference from the start of EXPR.
+ Only valid if OFFSET_KNOWN_P. */
+ HOST_WIDE_INT offset;
+
+ /* The size of the memory reference in bytes. Only valid if
+ SIZE_KNOWN_P. */
+ HOST_WIDE_INT size;
+
+ /* The alias set of the memory reference. */
+ alias_set_type alias;
+
+ /* The alignment of the reference in bits. Always a multiple of
+ BITS_PER_UNIT. Note that EXPR may have a stricter alignment
+ than the memory reference itself. */
+ unsigned int align;
+
+ /* The address space that the memory reference uses. */
+ unsigned char addrspace;
+
+ /* True if OFFSET is known. */
+ bool offset_known_p;
+
+ /* True if SIZE is known. */
+ bool size_known_p;
} mem_attrs;
/* Structure used to describe the attributes of a REG in similar way as
mem_attrs *rt_mem;
reg_attrs *rt_reg;
struct constant_descriptor_rtx *rt_constant;
+ struct dw_cfi_struct *rt_cfi;
};
typedef union rtunion_def rtunion;
constants pool.
1 in a CALL_INSN logically equivalent to ECF_CONST and TREE_READONLY.
1 in a NOTE, or EXPR_LIST for a const call.
- 1 in a JUMP_INSN, CALL_INSN, or INSN of an annulling branch. */
+ 1 in a JUMP_INSN of an annulling branch. */
unsigned int unchanging : 1;
/* 1 in a MEM or ASM_OPERANDS expression if the memory reference is volatile.
1 in an INSN, CALL_INSN, JUMP_INSN, CODE_LABEL, BARRIER, or NOTE
(JUMP_P (INSN) && (GET_CODE (PATTERN (INSN)) == ADDR_VEC || \
GET_CODE (PATTERN (INSN)) == ADDR_DIFF_VEC))
+/* Predicate yielding nonzero iff X is a return or simple_return. */
+#define ANY_RETURN_P(X) \
+ (GET_CODE (X) == RETURN || GET_CODE (X) == SIMPLE_RETURN)
+
/* 1 if X is a unary operator. */
#define UNARY_P(X) \
#define XTREE(RTX, N) (RTL_CHECK1 (RTX, N, 't').rt_tree)
#define XBBDEF(RTX, N) (RTL_CHECK1 (RTX, N, 'B').rt_bb)
#define XTMPL(RTX, N) (RTL_CHECK1 (RTX, N, 'T').rt_str)
+#define XCFI(RTX, N) (RTL_CHECK1 (RTX, N, 'C').rt_cfi)
#define XVECEXP(RTX, N, M) RTVEC_ELT (XVEC (RTX, N), M)
#define XVECLEN(RTX, N) GET_NUM_ELEM (XVEC (RTX, N))
#define XCMODE(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_type)
#define XCTREE(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_tree)
#define XCBBDEF(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_bb)
+#define XCCFI(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_cfi)
#define XCCSELIB(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_cselib)
#define XCVECEXP(RTX, N, M, C) RTVEC_ELT (XCVEC (RTX, N, C), M)
/* 1 if RTX is a jump_insn, call_insn, or insn that is an annulling branch. */
#define INSN_ANNULLED_BRANCH_P(RTX) \
- (RTL_FLAG_CHECK3("INSN_ANNULLED_BRANCH_P", (RTX), JUMP_INSN, CALL_INSN, INSN)->unchanging)
+ (RTL_FLAG_CHECK1("INSN_ANNULLED_BRANCH_P", (RTX), JUMP_INSN)->unchanging)
/* 1 if RTX is an insn in a delay slot and is from the target of the branch.
If the branch insn has INSN_ANNULLED_BRANCH_P set, this insn should only be
but a value from enum reg_note. */
#define REG_NOTES(INSN) XEXP(INSN, 7)
+/* In an ENTRY_VALUE this is the DECL_INCOMING_RTL of the argument in
+ question. */
+#define ENTRY_VALUE_EXP(RTX) (RTL_CHECKC1 (RTX, 0, ENTRY_VALUE).rt_rtx)
+
enum reg_note
{
#define DEF_REG_NOTE(NAME) NAME,
#define NOTE_EH_HANDLER(INSN) XCINT (INSN, 4, NOTE)
#define NOTE_BASIC_BLOCK(INSN) XCBBDEF (INSN, 4, NOTE)
#define NOTE_VAR_LOCATION(INSN) XCEXP (INSN, 4, NOTE)
+#define NOTE_CFI(INSN) XCCFI (INSN, 4, NOTE)
+#define NOTE_LABEL_NUMBER(INSN) XCINT (INSN, 4, NOTE)
/* In a NOTE that is a line number, this is the line number.
Other kinds of NOTEs are identified by negative numbers here. */
/* 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. */
-enum var_init_status
-{
- VAR_INIT_STATUS_UNKNOWN,
- VAR_INIT_STATUS_UNINITIALIZED,
- VAR_INIT_STATUS_INITIALIZED
-};
+/* PARM_DECL DEBUG_PARAMETER_REF references. */
+#define DEBUG_PARAMETER_REF_DECL(RTX) XCTREE (RTX, 0, DEBUG_PARAMETER_REF)
/* Codes that appear in the NOTE_KIND field for kinds of notes
that are not line numbers. These codes are all negative.
}
extern void init_rtlanal (void);
-extern int rtx_cost (rtx, enum rtx_code, bool);
+extern int rtx_cost (rtx, enum rtx_code, int, bool);
extern int address_cost (rtx, enum machine_mode, addr_space_t, bool);
-extern void get_full_rtx_cost (rtx, enum rtx_code, struct full_rtx_costs *);
+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,
unsigned int);
extern bool truncated_to_mode (enum machine_mode, const_rtx);
extern int low_bitmask_len (enum machine_mode, unsigned HOST_WIDE_INT);
+#ifndef GENERATOR_FILE
+/* Return the cost of SET X. SPEED_P is true if optimizing for speed
+ rather than size. */
+
+static inline int
+set_rtx_cost (rtx x, bool speed_p)
+{
+ return rtx_cost (x, INSN, 4, speed_p);
+}
+
+/* Like set_rtx_cost, but return both the speed and size costs in C. */
+
+static inline void
+get_full_set_rtx_cost (rtx x, struct full_rtx_costs *c)
+{
+ get_full_rtx_cost (x, INSN, 4, c);
+}
+
+/* Return the cost of moving X into a register, relative to the cost
+ of a register move. SPEED_P is true if optimizing for speed rather
+ than size. */
+
+static inline int
+set_src_cost (rtx x, bool speed_p)
+{
+ return rtx_cost (x, SET, 1, speed_p);
+}
+
+/* Like set_src_cost, but return both the speed and size costs in C. */
+
+static inline void
+get_full_set_src_cost (rtx x, struct full_rtx_costs *c)
+{
+ get_full_rtx_cost (x, SET, 1, c);
+}
+#endif
/* 1 if RTX is a subreg containing a reg that is already known to be
sign- or zero-extended from the mode of the subreg to the mode of
#define MEM_NOTRAP_P(RTX) \
(RTL_FLAG_CHECK1("MEM_NOTRAP_P", (RTX), MEM)->call)
-/* If VAL is nonzero, set MEM_IN_STRUCT_P and clear MEM_SCALAR_P in
- RTX. Otherwise, vice versa. Use this macro only when you are
- *sure* that you know that the MEM is in a structure, or is a
- scalar. VAL is evaluated only once. */
-#define MEM_SET_IN_STRUCT_P(RTX, VAL) \
-do { \
- if (VAL) \
- { \
- MEM_IN_STRUCT_P (RTX) = 1; \
- MEM_SCALAR_P (RTX) = 0; \
- } \
- else \
- { \
- MEM_IN_STRUCT_P (RTX) = 0; \
- MEM_SCALAR_P (RTX) = 1; \
- } \
-} while (0)
-
/* The memory attribute block. We provide access macros for each value
in the block and provide defaults if none specified. */
#define MEM_ATTRS(RTX) X0MEMATTR (RTX, 1)
in the block and provide defaults if none specified. */
#define REG_ATTRS(RTX) X0REGATTR (RTX, 2)
+#ifndef GENERATOR_FILE
/* For a MEM rtx, the alias set. If 0, this MEM is not in any alias
set, and may alias anything. Otherwise, the MEM can only alias
MEMs in a conflicting alias set. This value is set in a
language-dependent manner in the front-end, and should not be
altered in the back-end. These set numbers are tested with
alias_sets_conflict_p. */
-#define MEM_ALIAS_SET(RTX) (MEM_ATTRS (RTX) == 0 ? 0 : MEM_ATTRS (RTX)->alias)
+#define MEM_ALIAS_SET(RTX) (get_mem_attrs (RTX)->alias)
/* For a MEM rtx, the decl it is known to refer to, if it is known to
refer to part of a DECL. It may also be a COMPONENT_REF. */
-#define MEM_EXPR(RTX) (MEM_ATTRS (RTX) == 0 ? 0 : MEM_ATTRS (RTX)->expr)
+#define MEM_EXPR(RTX) (get_mem_attrs (RTX)->expr)
+
+/* For a MEM rtx, true if its MEM_OFFSET is known. */
+#define MEM_OFFSET_KNOWN_P(RTX) (get_mem_attrs (RTX)->offset_known_p)
-/* For a MEM rtx, the offset from the start of MEM_EXPR, if known, as a
- RTX that is always a CONST_INT. */
-#define MEM_OFFSET(RTX) (MEM_ATTRS (RTX) == 0 ? 0 : MEM_ATTRS (RTX)->offset)
+/* For a MEM rtx, the offset from the start of MEM_EXPR. */
+#define MEM_OFFSET(RTX) (get_mem_attrs (RTX)->offset)
/* For a MEM rtx, the address space. */
-#define MEM_ADDR_SPACE(RTX) (MEM_ATTRS (RTX) == 0 ? ADDR_SPACE_GENERIC \
- : MEM_ATTRS (RTX)->addrspace)
+#define MEM_ADDR_SPACE(RTX) (get_mem_attrs (RTX)->addrspace)
+
+/* For a MEM rtx, true if its MEM_SIZE is known. */
+#define MEM_SIZE_KNOWN_P(RTX) (get_mem_attrs (RTX)->size_known_p)
-/* For a MEM rtx, the size in bytes of the MEM, if known, as an RTX that
- is always a CONST_INT. */
-#define MEM_SIZE(RTX) \
-(MEM_ATTRS (RTX) != 0 ? MEM_ATTRS (RTX)->size \
- : GET_MODE (RTX) != BLKmode ? GEN_INT (GET_MODE_SIZE (GET_MODE (RTX))) \
- : 0)
+/* For a MEM rtx, the size in bytes of the MEM. */
+#define MEM_SIZE(RTX) (get_mem_attrs (RTX)->size)
/* For a MEM rtx, the alignment in bits. We can use the alignment of the
mode as a default when STRICT_ALIGNMENT, but not if not. */
-#define MEM_ALIGN(RTX) \
-(MEM_ATTRS (RTX) != 0 ? MEM_ATTRS (RTX)->align \
- : (STRICT_ALIGNMENT && GET_MODE (RTX) != BLKmode \
- ? GET_MODE_ALIGNMENT (GET_MODE (RTX)) : BITS_PER_UNIT))
+#define MEM_ALIGN(RTX) (get_mem_attrs (RTX)->align)
+#else
+#define MEM_ADDR_SPACE(RTX) ADDR_SPACE_GENERIC
+#endif
/* For a REG rtx, the decl it is known to refer to, if it is known to
refer to part of a DECL. */
extern rtx shallow_copy_rtx_stat (const_rtx MEM_STAT_DECL);
#define shallow_copy_rtx(a) shallow_copy_rtx_stat (a MEM_STAT_INFO)
extern int rtx_equal_p (const_rtx, const_rtx);
+extern hashval_t iterative_hash_rtx (const_rtx, hashval_t);
/* In emit-rtl.c */
extern rtvec gen_rtvec_v (int, rtx *);
/* In emit-rtl.c */
extern rtx operand_subword_force (rtx, unsigned int, enum 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 rtx get_pool_constant_mark (rtx, bool *);
extern enum 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);
-extern rtx assign_stack_local_1 (enum machine_mode, HOST_WIDE_INT, int, bool);
+#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, int);
extern rtx assign_stack_temp_for_type (enum machine_mode,
HOST_WIDE_INT, int, tree);
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,
+ unsigned HOST_WIDE_INT);
+extern bool val_signbit_known_clear_p (enum machine_mode,
+ unsigned HOST_WIDE_INT);
/* In reginfo.c */
extern enum machine_mode choose_hard_reg_mode (unsigned int, unsigned int,
extern void add_reg_note (rtx, enum reg_note, rtx);
extern void remove_note (rtx, const_rtx);
extern void remove_reg_equal_equiv_notes (rtx);
+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 int volatile_insn_p (const_rtx);
typedef int (*rtx_function) (rtx *, void *);
extern int for_each_rtx (rtx *, rtx_function, void *);
+/* 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. */
+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 *, 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,
extern enum reg_class reg_preferred_class (int);
extern enum reg_class reg_alternate_class (int);
-extern enum reg_class reg_cover_class (int);
+extern enum reg_class reg_allocno_class (int);
extern void setup_reg_classes (int, enum reg_class, enum reg_class,
enum reg_class);
{
GR_PC,
GR_CC0,
+ GR_RETURN,
+ GR_SIMPLE_RETURN,
GR_STACK_POINTER,
GR_FRAME_POINTER,
/* For register elimination to work properly these hard_frame_pointer_rtx,
/* 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];
+
+ /* The default memory attributes for each mode. */
+ struct mem_attrs *x_mode_mem_attrs[(int) MAX_MACHINE_MODE];
};
extern GTY(()) struct target_rtl default_target_rtl;
(this_target_rtl->x_return_address_pointer_rtx)
#define top_of_stack \
(this_target_rtl->x_top_of_stack)
+#define mode_mem_attrs \
+ (this_target_rtl->x_mode_mem_attrs)
/* Standard pieces of rtx, to be substituted directly into things. */
#define pc_rtx (global_rtl[GR_PC])
+#define ret_rtx (global_rtl[GR_RETURN])
+#define simple_return_rtx (global_rtl[GR_SIMPLE_RETURN])
#define cc0_rtx (global_rtl[GR_CC0])
/* All references to certain hard regs, except those created
#define hard_frame_pointer_rtx (global_rtl[GR_HARD_FRAME_POINTER])
#define arg_pointer_rtx (global_rtl[GR_ARG_POINTER])
+#ifndef GENERATOR_FILE
+/* Return the attributes of a MEM rtx. */
+static inline struct mem_attrs *
+get_mem_attrs (const_rtx x)
+{
+ struct mem_attrs *attrs;
+
+ attrs = MEM_ATTRS (x);
+ if (!attrs)
+ attrs = mode_mem_attrs[(int) GET_MODE (x)];
+ return attrs;
+}
+#endif
+
/* Include the RTL generation functions. */
#ifndef GENERATOR_FILE
extern int exp_equiv_p (const_rtx, const_rtx, int, bool);
extern unsigned hash_rtx (const_rtx x, enum machine_mode, int *, int *, bool);
+/* In dse.c */
+extern void check_for_inc_dec (rtx 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 void redirect_jump_2 (rtx, rtx, rtx, int, int);
extern int redirect_jump (rtx, rtx, int);
extern void rebuild_jump_labels (rtx);
+extern void rebuild_jump_labels_chain (rtx);
extern rtx reversed_comparison (const_rtx, enum 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,
/* In sched-ebb.c. */
extern void schedule_ebbs (void);
-/* In haifa-sched.c. */
-extern void fix_sched_param (const char *, const char *);
-
/* In sel-sched-dump.c. */
extern void sel_sched_fix_param (const char *param, const char *val);
extern int sibcall_epilogue_contains (const_rtx);
extern void mark_temp_addr_taken (rtx);
extern void update_temp_slot_address (rtx, rtx);
-extern void maybe_copy_epilogue_insn (rtx, rtx);
+extern void maybe_copy_prologue_epilogue_insn (rtx, rtx);
/* In stmt.c */
extern void expand_null_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);
/* In reginfo.c */
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 globalize_reg (tree, int);
extern void init_reg_modes_target (void);
extern void init_regs (void);
extern void reinit_regs (void);
extern void regclass (rtx, int);
extern void reg_scan (rtx, unsigned int);
extern void fix_register (const char *, int, int);
-extern bool invalid_mode_change_p (unsigned int, enum reg_class,
- enum machine_mode);
+extern bool invalid_mode_change_p (unsigned int, enum reg_class);
/* In reorg.c */
extern void dbr_schedule (rtx);
extern void init_alias_target (void);
extern void init_alias_analysis (void);
extern void end_alias_analysis (void);
+extern void vt_equate_reg_base_value (const_rtx, const_rtx);
extern bool memory_modified_in_insn_p (const_rtx, const_rtx);
extern rtx find_base_term (rtx);
extern rtx gen_hard_reg_clobber (enum 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);
#ifdef STACK_REGS
extern int stack_regs_mentioned (const_rtx insn);