struct rtvec_def *rtvec;
enum machine_mode rttype;
addr_diff_vec_flags rt_addr_diff_vec_flags;
+ struct bitmap_head_def *rtbit;
+ union tree_node *rttree;
} rtunion;
/* RTL expression ("rtx"). */
In a SYMBOL_REF, this flag is used for machine-specific purposes.
In a LABEL_REF or in a REG_LABEL note, this is LABEL_REF_NONLOCAL_P. */
unsigned int volatil : 1;
- /* 1 in a MEM referring to a field of a structure (not a union!).
+ /* 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;
1 if it was the result of a . or -> operator (on a struct) in C.
1 in a REG if the register is used only in exit code a loop.
#define CONSTANT_P(X) \
(GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
|| GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE \
- || GET_CODE (X) == CONST || GET_CODE (X) == HIGH)
+ || GET_CODE (X) == CONST || GET_CODE (X) == HIGH \
+ || GET_CODE (X) == CONSTANT_P_RTX)
/* General accessor macros for accessing the fields of an rtx. */
#define XVEC(RTX, N) ((RTX)->fld[N].rtvec)
#define XVECLEN(RTX, N) ((RTX)->fld[N].rtvec->num_elem)
#define XVECEXP(RTX,N,M)((RTX)->fld[N].rtvec->elem[M].rtx)
+#define XBITMAP(RTX, N) ((RTX)->fld[N].rtbit)
+#define XTREE(RTX, N) ((RTX)->fld[N].rttree)
+
\f
/* ACCESS MACROS for particular fields of insns. */
#define LINE_NUMBER NOTE
-/* In a NOTE that is a line number, this is a string for the file name
- that the line is in. We use the same field to record block numbers
- temporarily in NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes.
- (We avoid lots of casts between ints and pointers if we use a
- different macro for the bock number.) */
+/* In a NOTE that is a line number, this is a string for the file name that the
+ line is in. We use the same field to record block numbers temporarily in
+ NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes. (We avoid lots of casts
+ between ints and pointers if we use a different macro for the block number.)
+ The NOTE_INSN_RANGE_{START,END} and NOTE_INSN_LIVE notes record their
+ information as a rtx in the field. */
#define NOTE_SOURCE_FILE(INSN) ((INSN)->fld[3].rtstr)
#define NOTE_BLOCK_NUMBER(INSN) ((INSN)->fld[3].rtint)
+#define NOTE_RANGE_INFO(INSN) ((INSN)->fld[3].rtx)
+#define NOTE_LIVE_INFO(INSN) ((INSN)->fld[3].rtx)
+
+/* If the NOTE_BLOCK_NUMBER field gets a -1, it means create a new
+ block node for a live range block. */
+#define NOTE_BLOCK_LIVE_RANGE_BLOCK -1
/* In a NOTE that is a line number, this is the line number.
Other kinds of NOTEs are identified by negative numbers here. */
the line containing the inline call from being counted twice in gcov. */
#define NOTE_REPEATED_LINE_NUMBER -16
+/* Start/end of a live range region, where pseudos allocated on the stack can
+ be allocated to temporary registers. */
+#define NOTE_INSN_RANGE_START -17
+#define NOTE_INSN_RANGE_END -18
+/* Record which registers are currently live. */
+#define NOTE_INSN_LIVE -19
#if 0 /* These are not used, and I don't know what they were for. --rms. */
#define NOTE_DECL_NAME(INSN) ((INSN)->fld[3].rtstr)
Also in an ASM_OPERANDS rtx. */
#define MEM_VOLATILE_P(RTX) ((RTX)->volatil)
-/* For a MEM rtx, 1 if it refers to a structure or union component. */
+/* For a MEM rtx, 1 if it refers to a field of an aggregate. */
#define MEM_IN_STRUCT_P(RTX) ((RTX)->in_struct)
+/* 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 the same 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 for zero,
+ and compared for equality; they have no other significance. In
+ some front-ends, these numbers may correspond in some way to types,
+ or other language-level entities, but they need not, and the
+ back-end makes no such assumptions. */
+#define MEM_ALIAS_SET(RTX) (XINT (RTX, 1))
+
/* For a LABEL_REF, 1 means that this reference is to a label outside the
loop containing the reference. */
#define LABEL_OUTSIDE_LOOP_P(RTX) ((RTX)->in_struct)
/* For a TRAP_IF rtx, TRAP_CONDITION is an expression. */
#define TRAP_CONDITION(RTX) ((RTX)->fld[0].rtx)
+#define TRAP_CODE(RTX) (RTX)->fld[1].rtx
/* 1 in a SYMBOL_REF if it addresses this function's constants pool. */
#define CONSTANT_POOL_ADDRESS_P(RTX) ((RTX)->unchanging)
#if (defined (HAVE_PRE_INCREMENT) || defined (HAVE_PRE_DECREMENT) || defined (HAVE_POST_INCREMENT) || defined (HAVE_POST_DECREMENT))
#define AUTO_INC_DEC
#endif
+
+/* Accessors for RANGE_INFO. */
+/* For RANGE_{START,END} notes return the RANGE_START note. */
+#define RANGE_INFO_NOTE_START(INSN) (XEXP (INSN, 0))
+
+/* For RANGE_{START,END} notes return the RANGE_START note. */
+#define RANGE_INFO_NOTE_END(INSN) (XEXP (INSN, 1))
+
+/* For RANGE_{START,END} notes, return the vector containing the registers used
+ in the range. */
+#define RANGE_INFO_REGS(INSN) (XVEC (INSN, 2))
+#define RANGE_INFO_REGS_REG(INSN, N) (XVECEXP (INSN, 2, N))
+#define RANGE_INFO_NUM_REGS(INSN) (XVECLEN (INSN, 2))
+
+/* For RANGE_{START,END} notes, the number of calls within the range. */
+#define RANGE_INFO_NCALLS(INSN) (XINT (INSN, 3))
+
+/* For RANGE_{START,END} notes, the number of insns within the range. */
+#define RANGE_INFO_NINSNS(INSN) (XINT (INSN, 4))
+
+/* For RANGE_{START,END} notes, a unique # to identify this range. */
+#define RANGE_INFO_UNIQUE(INSN) (XINT (INSN, 5))
+
+/* For RANGE_{START,END} notes, the basic block # the range starts with. */
+#define RANGE_INFO_BB_START(INSN) (XINT (INSN, 6))
+
+/* For RANGE_{START,END} notes, the basic block # the range ends with. */
+#define RANGE_INFO_BB_END(INSN) (XINT (INSN, 7))
+
+/* For RANGE_{START,END} notes, the loop depth the range is in. */
+#define RANGE_INFO_LOOP_DEPTH(INSN) (XINT (INSN, 8))
+
+/* For RANGE_{START,END} notes, the bitmap of live registers at the start
+ of the range. */
+#define RANGE_INFO_LIVE_START(INSN) (XBITMAP (INSN, 9))
+
+/* For RANGE_{START,END} notes, the bitmap of live registers at the end
+ of the range. */
+#define RANGE_INFO_LIVE_END(INSN) (XBITMAP (INSN, 10))
+
+/* For RANGE_START notes, the marker # of the start of the range. */
+#define RANGE_INFO_MARKER_START(INSN) (XINT (INSN, 11))
+
+/* For RANGE_START notes, the marker # of the end of the range. */
+#define RANGE_INFO_MARKER_END(INSN) (XINT (INSN, 12))
+
+/* Original pseudo register # for a live range note. */
+#define RANGE_REG_PSEUDO(INSN,N) (XINT (XVECEXP (INSN, 2, N), 0))
+
+/* Pseudo register # original register is copied into or -1. */
+#define RANGE_REG_COPY(INSN,N) (XINT (XVECEXP (INSN, 2, N), 1))
+
+/* How many times a register in a live range note was referenced. */
+#define RANGE_REG_REFS(INSN,N) (XINT (XVECEXP (INSN, 2, N), 2))
+
+/* How many times a register in a live range note was set. */
+#define RANGE_REG_SETS(INSN,N) (XINT (XVECEXP (INSN, 2, N), 3))
+
+/* How many times a register in a live range note died. */
+#define RANGE_REG_DEATHS(INSN,N) (XINT (XVECEXP (INSN, 2, N), 4))
+
+/* Whether the original value is needed to be copied into the range register at
+ the start of the range. */
+#define RANGE_REG_COPY_FLAGS(INSN,N) (XINT (XVECEXP (INSN, 2, N), 5))
+
+/* # of insns the register copy is live over. */
+#define RANGE_REG_LIVE_LENGTH(INSN,N) (XINT (XVECEXP (INSN, 2, N), 6))
+
+/* # of calls the register copy is live over. */
+#define RANGE_REG_N_CALLS(INSN,N) (XINT (XVECEXP (INSN, 2, N), 7))
+
+/* DECL_NODE pointer of the declaration if the register is a user defined
+ variable. */
+#define RANGE_REG_SYMBOL_NODE(INSN,N) (XTREE (XVECEXP (INSN, 2, N), 8))
+
+/* BLOCK_NODE pointer to the block the variable is declared in if the
+ register is a user defined variable. */
+#define RANGE_REG_BLOCK_NODE(INSN,N) (XTREE (XVECEXP (INSN, 2, N), 9))
+
+/* EXPR_LIST of the distinct ranges a variable is in. */
+#define RANGE_VAR_LIST(INSN) (XEXP (INSN, 0))
+
+/* Block a variable is declared in. */
+#define RANGE_VAR_BLOCK(INSN) (XTREE (INSN, 1))
+
+/* # of distinct ranges a variable is in. */
+#define RANGE_VAR_NUM(INSN) (XINT (INSN, 2))
+
+/* For a NOTE_INSN_LIVE note, the registers which are currently live. */
+#define RANGE_LIVE_BITMAP(INSN) (XBITMAP (INSN, 0))
+
+/* For a NOTE_INSN_LIVE note, the original basic block number. */
+#define RANGE_LIVE_ORIG_BLOCK(INSN) (XINT (INSN, 1))
\f
/* Generally useful functions. */
#define plus_constant_for_output(X,C) \
plus_constant_for_output_wide (X, (HOST_WIDE_INT) (C))
+/* In explow.c */
extern rtx plus_constant_wide PROTO((rtx, HOST_WIDE_INT));
extern rtx plus_constant_for_output_wide PROTO((rtx, HOST_WIDE_INT));
+extern void optimize_save_area_alloca PROTO((rtx));
extern rtx gen_rtx PVPROTO((enum rtx_code,
enum machine_mode, ...));
cast their pointers to char *, and all of the xrealloc's don't use
void * yet. */
extern char *xmalloc PROTO((size_t));
+extern char *xcalloc PROTO((size_t, size_t));
extern char *xrealloc PROTO((void *, size_t));
#else
extern char *xmalloc ();
+extern char *xcalloc ();
extern char *xrealloc ();
#endif
extern char *oballoc PROTO((int));
extern char *permalloc PROTO((int));
-#ifdef NEED_DECLARATION_FREE
-extern void free PROTO((void *));
-#endif
extern rtx rtx_alloc PROTO((RTX_CODE));
extern rtvec rtvec_alloc PROTO((int));
extern rtx copy_rtx PROTO((rtx));
extern int volatile_refs_p PROTO((rtx));
extern int volatile_insn_p PROTO((rtx));
extern void remove_note PROTO((rtx, rtx));
-extern void note_stores PROTO((rtx, void (*) (rtx, rtx)));
extern int refers_to_regno_p PROTO((int, int, rtx, rtx *));
extern int reg_overlap_mentioned_p PROTO((rtx, rtx));
-extern rtx find_use_as_address PROTO((rtx, rtx, HOST_WIDE_INT));
/* Functions in rtlanal.c */
extern rtx find_last_value PROTO((rtx, rtx *, rtx));
extern int refers_to_regno_p PROTO((int, int, rtx, rtx *));
extern int reg_overlap_mentioned_p PROTO((rtx, rtx));
+extern rtx find_use_as_address PROTO((rtx, rtx, HOST_WIDE_INT));
+extern void note_stores PROTO((rtx, void (*)()));
extern rtx reg_set_last PROTO((rtx, rtx));
extern int rtx_equal_p PROTO((rtx, rtx));
extern int dead_or_set_p PROTO((rtx, rtx));
#include "genrtl.h"
#endif
-/* There are two RTL codes that require special attention; the generation
- functions included above do the raw handling. */
+/* There are some RTL codes that require special attention; the
+ generation functions included above do the raw handling. If you
+ add to this list, modify special_rtx in gengenrtl.c as well. You
+ should also modify gen_rtx to use the special function. */
extern rtx gen_rtx_CONST_INT PROTO((enum machine_mode, HOST_WIDE_INT));
extern rtx gen_rtx_REG PROTO((enum machine_mode, int));
+extern rtx gen_rtx_MEM PROTO((enum machine_mode, rtx));
/* We need the cast here to ensure that we get the same result both with
and without prototypes. */
extern rtx find_next_ref PROTO((rtx, rtx));
extern rtx *find_single_use PROTO((rtx, rtx, rtx *));
-/* It is hard to write the prototype for expand_expr, since it needs
- expr.h to be included for the enumeration. */
-
-extern rtx expand_expr ();
-
extern rtx output_constant_def PROTO((union tree_node *));
extern rtx immed_real_const PROTO((union tree_node *));
extern union tree_node *make_tree PROTO((union tree_node *, rtx));
#ifdef BUFSIZ
extern void schedule_insns PROTO ((FILE *));
#endif
+#ifdef HAIFA
+extern void fix_sched_param PROTO ((char *, char *));
+#endif
/* In print-rtl.c */
extern void debug_rtx PROTO ((rtx));
extern rtx debug_rtx_find PROTO ((rtx, int));
#ifdef BUFSIZ
extern void print_rtl PROTO ((FILE *, rtx));
+extern void print_rtl_single PROTO ((FILE *, rtx));
extern void print_inline_rtx PROTO ((FILE *, rtx, int));
#endif
extern void mark_temp_addr_taken PROTO ((rtx));
extern void update_temp_slot_address PROTO ((rtx, rtx));
extern void use_variable_after PROTO ((rtx, rtx));
+extern void purge_addressof PROTO ((rtx));
/* In reload.c */
extern int operands_match_p PROTO ((rtx, rtx));
extern int recog PROTO ((rtx, rtx, int *));
/* In stmt.c */
+extern void expand_null_return PROTO((void));
extern void emit_jump PROTO ((rtx));
extern int preserve_subexpressions_p PROTO ((void));
/* In flow.c */
extern void allocate_for_life_analysis PROTO ((void));
+extern void recompute_reg_usage PROTO ((rtx));
#ifdef BUFSIZ
extern void dump_flow_info PROTO ((FILE *));
#endif
unsigned HOST_WIDE_INT, rtx,
int, int));
+/* In gcse.c */
+#ifdef BUFSIZ
+extern void gcse_main PROTO ((rtx, FILE *));
+#endif
+
/* In global.c */
+extern void mark_elimination PROTO ((int, int));
#ifdef BUFSIZ
extern int global_alloc PROTO ((FILE *));
extern void dump_global_regs PROTO ((FILE *));
#endif
+#ifdef HARD_CONST
+extern void retry_global_alloc PROTO ((int, HARD_REG_SET));
+#endif
/* In regclass.c */
+extern int reg_classes_intersect_p PROTO ((enum reg_class, enum reg_class));
+extern int reg_class_subset_p PROTO ((enum reg_class, enum reg_class));
extern void globalize_reg PROTO ((int));
extern void init_regs PROTO ((void));
extern void init_reg_sets PROTO ((void));
extern void regclass_init PROTO ((void));
extern void regclass PROTO ((rtx, int));
extern void reg_scan PROTO ((rtx, int, int));
+extern void reg_scan_update PROTO ((rtx, rtx, int));
extern void fix_register PROTO ((char *, int, int));
+/* In regmove.c */
+#ifdef BUFSIZ
+extern void regmove_optimize PROTO ((rtx, int, FILE *));
+#endif
+
+/* In reorg.c */
+#ifdef BUFSIZ
+extern void dbr_schedule PROTO ((rtx, FILE *));
+#endif
+
/* In optabs.c */
extern void init_optabs PROTO ((void));
/* In profile.c */
extern void init_branch_prob PROTO ((char *));
+#ifdef BUFSIZ
+extern void branch_prob PROTO ((rtx, FILE *));
+extern void end_branch_prob PROTO ((FILE *));
+#endif
+extern void output_func_start_profiler PROTO ((void));
/* In reg-stack.c */
#ifdef BUFSIZ