/* 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
when we access a component.
1 in a CALL_INSN if it is a sibling call.
1 in a SET that is for a return.
- In a CODE_LABEL, part of the two-bit alternate entry field. */
+ 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. */
unsigned int jump : 1;
/* In a CODE_LABEL, part of the two-bit alternate entry field.
1 in a MEM if it cannot trap.
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.
+ 1 in a CONCAT is VAL_EXPR_IS_CLOBBERED in var-tracking.c.
+ 1 in a preserved VALUE is PRESERVED_VALUE_P in cselib.c. */
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
non-local label.
In a SYMBOL_REF, this flag is used for machine-specific purposes.
In a PREFETCH, this flag indicates that it should be considered a scheduling
- barrier. */
+ barrier.
+ 1 in a CONCAT is VAL_NEEDS_RESOLUTION in var-tracking.c. */
unsigned int volatil : 1;
/* 1 in a MEM referring to a field of an aggregate.
0 if the MEM was a variable or the result of a * operator in C;
In a REG, this is not needed for that purpose, and used instead
in `leaf_renumber_regs_insn'.
1 in a SYMBOL_REF, means that emit_library_call
- has used it as the function. */
+ has used it as the function.
+ 1 in a CONCAT is VAL_HOLDS_TRACK_EXPR in var-tracking.c.
+ 1 in a VALUE or DEBUG_EXPR is VALUE_RECURSED_INTO in var-tracking.c. */
unsigned int used : 1;
/* 1 in an INSN or a SET if this rtx is related to the call frame,
either changing how we compute the frame address or saving and
restoring registers in the prologue and epilogue.
1 in a REG or MEM if it is a pointer.
1 in a SYMBOL_REF if it addresses something in the per-function
- constant string pool. */
+ constant string pool.
+ 1 in a VALUE is VALUE_CHANGED in var-tracking.c. */
unsigned frame_related : 1;
/* 1 in a REG or PARALLEL that is the current function's return value.
1 in a MEM if it refers to a scalar.
1 in a SYMBOL_REF for a weak symbol.
- 1 in a CALL_INSN logically equivalent to ECF_PURE and DECL_PURE_P. */
+ 1 in a CALL_INSN logically equivalent to ECF_PURE and DECL_PURE_P.
+ 1 in a CONCAT is VAL_EXPR_HAS_REVERSE in var-tracking.c.
+ 1 in a VALUE or DEBUG_EXPR is NO_LOC_P in var-tracking.c. */
unsigned return_val : 1;
/* The first element of the operands of this rtx.
(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) \
/* 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
}
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
refer to part of a DECL. It may also be a COMPONENT_REF. */
#define MEM_EXPR(RTX) (get_mem_attrs (RTX)->expr)
-/* For a MEM rtx, the offset from the start of MEM_EXPR, if known, as a
- RTX that is always a CONST_INT. */
+/* 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. */
#define MEM_OFFSET(RTX) (get_mem_attrs (RTX)->offset)
/* For a MEM rtx, the address space. */
#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 != NULL_RTX)
+#define MEM_SIZE_KNOWN_P(RTX) (get_mem_attrs (RTX)->size_known_p)
/* For a MEM rtx, the size in bytes of the MEM. */
-#define MEM_SIZE(RTX) INTVAL (get_mem_attrs (RTX)->size)
+#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. */
extern rtx prev_active_insn (rtx);
extern rtx next_active_insn (rtx);
extern int active_insn_p (const_rtx);
-extern rtx prev_label (rtx);
extern rtx next_label (rtx);
extern rtx skip_consecutive_labels (rtx);
extern rtx next_cc0_user (rtx);
/* In emit-rtl.c */
extern rtx set_unique_reg_note (rtx, enum reg_note, rtx);
+extern rtx set_dst_reg_note (rtx, enum reg_note, rtx, rtx);
extern void set_insn_deleted (rtx);
/* Functions in rtlanal.c */
extern int 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 *);
+#endif
extern void note_stores (const_rtx, void (*) (rtx, const_rtx, void *), void *);
extern void note_uses (rtx *, void (*) (rtx *, void *), void *);
extern int dead_or_set_p (const_rtx, const_rtx);
/* lists.c */
-extern void free_EXPR_LIST_list (rtx *);
-extern void free_INSN_LIST_list (rtx *);
-extern void free_EXPR_LIST_node (rtx);
-extern void free_INSN_LIST_node (rtx);
-extern rtx alloc_INSN_LIST (rtx, rtx);
-extern rtx alloc_EXPR_LIST (int, rtx, rtx);
+extern void free_EXPR_LIST_list (rtx *);
+extern void free_INSN_LIST_list (rtx *);
+extern void free_EXPR_LIST_node (rtx);
+extern void free_INSN_LIST_node (rtx);
+extern rtx alloc_INSN_LIST (rtx, rtx);
+extern rtx copy_INSN_LIST (rtx);
+extern rtx concat_INSN_LIST (rtx, rtx);
+extern rtx alloc_EXPR_LIST (int, rtx, rtx);
extern void remove_free_INSN_LIST_elem (rtx, rtx *);
extern rtx remove_list_elem (rtx, rtx *);
extern rtx remove_free_INSN_LIST_node (rtx *);
#define constm1_rtx (const_int_rtx[MAX_SAVED_CONST_INT-1])
extern GTY(()) rtx const_true_rtx;
-extern GTY(()) rtx const_tiny_rtx[3][(int) MAX_MACHINE_MODE];
+extern GTY(()) rtx const_tiny_rtx[4][(int) MAX_MACHINE_MODE];
/* Returns a constant 0 rtx in mode MODE. Integer modes are treated the
same as VOIDmode. */
#define CONST0_RTX(MODE) (const_tiny_rtx[0][(int) (MODE)])
-/* Likewise, for the constants 1 and 2. */
+/* Likewise, for the constants 1 and 2 and -1. */
#define CONST1_RTX(MODE) (const_tiny_rtx[1][(int) (MODE)])
#define CONST2_RTX(MODE) (const_tiny_rtx[2][(int) (MODE)])
+#define CONSTM1_RTX(MODE) (const_tiny_rtx[3][(int) (MODE)])
/* If HARD_FRAME_POINTER_REGNUM is defined, then a special dummy reg
is used to represent the frame pointer. This is because the
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,
/* 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
extern unsigned hash_rtx (const_rtx x, enum machine_mode, int *, int *, bool);
/* In dse.c */
-extern void check_for_inc_dec (rtx insn);
+extern bool 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 mark_temp_addr_taken (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);
/* 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);