haifa-sched.c: Convert to target hooks.
* haifa-sched.c: Convert to target hooks. Macros replaced are ISSUE_RATE, ADJUST_COST, ADJUST_PRIORITY, MD_SCHED_INIT, MD_SCHED_REORDER, MD_SCHED_REORDER2, MD_SCHED_VARIABLE_ISSUE, MD_SCHED_FINISH, and HAVE_cycle_display. * target-def.h (TARGET_SCHED_ADJUST_COST, TARGET_SCHED_ADJUST_PRIORITY, TARGET_SCHED_ISSUE_RATE, TARGET_SCHED_VARIABLE_ISSUE, TARGET_SCHED_INIT, TARGET_SCHED_FINISH, TARGET_SCHED_REORDER, TARGET_SCHED_REORDER2, TARGET_SCHED_CYCLE_DISPLAY): New hook #defines to be overridden. (TARGET_SCHED): Bring them all together. (TARGET_INITIALIZER): Update. * target.h: Don't forward declare struct rtx_def. Use 'rtx' instead of 'struct rtx_def *' throughout. (struct sched): New set of hooks for the scheduler. * Makefile.in (haifa-sched.o): Depend on target.h. * doc/tm.texi: Document the new scheduler hooks, together in their own section, instead of scattered around. Fix a bunch of underfull/overfull hboxes. * a29k.h, alpha.h, arm.h, c4x.h, convex.h, d30v.h, i386.h, ia64.h, m32r.h, m88k.h, mips.h, pa.h, rs6000.h, s390.h, sh.h, sparc.h: Don't define any of the old scheduler macros. * a29k.c, alpha.c, arm.c, c4x.c, convex.c, d30v.c, i386.c, ia64.c, m32r.c, m88k.c, mips.c, pa.c, rs6000.c, s390.c, sh.c, sparc.c: Create hook functions from code extracted from corresponding target header, or make existing hooks static, as appropriate. Set the appropriate entries in targetm. * alpha-protos.h, arm-protos.h, c4x-protos.h, d30v-protos.h, i386-protos.h, ia64-protos.h, m32r-protos.h, pa-protos.h, rs6000-protos.h, s390-protos.h, sparc-protos.h: Remove prototypes for functions which are now static. * d30v.h, d30v.c, m32r.h, m32r.c: Remove #ifdef HAIFA and related gunk; the Haifa scheduler is now the only choice. From-SVN: r45009
This commit is contained in:
parent
ef89d648b8
commit
c237e94a5f
|
@ -1527,7 +1527,7 @@ regmove.o : regmove.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) insn-config.h \
|
|||
$(EXPR_H) $(BASIC_BLOCK_H) toplev.h $(TM_P_H) except.h reload.h
|
||||
haifa-sched.o : haifa-sched.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) sched-int.h \
|
||||
$(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h flags.h insn-config.h function.h \
|
||||
$(INSN_ATTR_H) toplev.h $(RECOG_H) except.h $(TM_P_H)
|
||||
$(INSN_ATTR_H) toplev.h $(RECOG_H) except.h $(TM_P_H) $(TARGET_H)
|
||||
sched-deps.o : sched-deps.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) sched-int.h \
|
||||
$(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h flags.h insn-config.h function.h \
|
||||
$(INSN_ATTR_H) toplev.h $(RECOG_H) except.h cselib.h $(PARAMS_H) $(TM_P_H)
|
||||
|
|
|
@ -49,6 +49,7 @@ static void check_epilogue_internal_label PARAMS ((FILE *));
|
|||
static void output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
|
||||
static void output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
|
||||
static void a29k_asm_named_section PARAMS ((const char *, unsigned int));
|
||||
static int a29k_adjust_cost PARAMS ((rtx, rtx, rtx, int));
|
||||
|
||||
#define min(A,B) ((A) < (B) ? (A) : (B))
|
||||
|
||||
|
@ -100,6 +101,8 @@ int a29k_compare_fp_p;
|
|||
#define TARGET_ASM_FUNCTION_PROLOGUE output_function_prologue
|
||||
#undef TARGET_ASM_FUNCTION_EPILOGUE
|
||||
#define TARGET_ASM_FUNCTION_EPILOGUE output_function_epilogue
|
||||
#undef TARGET_SCHED_ADJUST_COST
|
||||
#define TARGET_SCHED_ADJUST_COST a29k_adjust_cost
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
|
@ -1578,3 +1581,21 @@ a29k_asm_named_section (name, flags)
|
|||
/* ??? Is it really correct to mark all sections as "bss"? */
|
||||
fprintf (asm_out_file, "\t.sect %s, bss\n\t.use %s\n", name, name);
|
||||
}
|
||||
|
||||
/* Return a new value for COST based on the relationship between INSN
|
||||
that is dependent on DEP_INSN through the dependence LINK. The
|
||||
default is to make no adjustment to COST.
|
||||
|
||||
On the a29k, ignore the cost of anti- and output-dependencies. */
|
||||
static int
|
||||
a29k_adjust_cost (insn, link, dep_insn, cost)
|
||||
rtx insn ATTRIBUTE_UNUSED;
|
||||
rtx link;
|
||||
rtx dep_insn ATTRIBUTE_UNUSED;
|
||||
int cost;
|
||||
{
|
||||
if (REG_NOTE_KIND (link) != 0)
|
||||
return 0; /* Anti or output dependence. */
|
||||
|
||||
return cost;
|
||||
}
|
||||
|
|
|
@ -679,15 +679,6 @@ enum reg_class { NO_REGS, LR0_REGS, GENERAL_REGS, BP_REGS, FC_REGS, CR_REGS,
|
|||
most expensive register-register copy. */
|
||||
|
||||
#define MEMORY_MOVE_COST(MODE,CLASS,IN) 6
|
||||
|
||||
/* A C statement (sans semicolon) to update the integer variable COST
|
||||
based on the relationship between INSN that is dependent on
|
||||
DEP_INSN through the dependence LINK. The default is to make no
|
||||
adjustment to COST. On the a29k, ignore the cost of anti- and
|
||||
output-dependencies. */
|
||||
#define ADJUST_COST(INSN,LINK,DEP_INSN,COST) \
|
||||
if (REG_NOTE_KIND (LINK) != 0) \
|
||||
(COST) = 0; /* Anti or output dependence. */
|
||||
|
||||
/* Stack layout; function entry, exit and calling. */
|
||||
|
||||
|
|
|
@ -99,7 +99,6 @@ extern void alpha_expand_unaligned_store PARAMS ((rtx, rtx, HOST_WIDE_INT,
|
|||
HOST_WIDE_INT));
|
||||
extern int alpha_expand_block_move PARAMS ((rtx []));
|
||||
extern int alpha_expand_block_clear PARAMS ((rtx []));
|
||||
extern int alpha_adjust_cost PARAMS ((rtx, rtx, rtx, int));
|
||||
extern rtx alpha_return_addr PARAMS ((int, rtx));
|
||||
extern rtx alpha_gp_save_rtx PARAMS ((void));
|
||||
extern void print_operand PARAMS ((FILE *, rtx, int));
|
||||
|
|
|
@ -136,6 +136,12 @@ static rtx alpha_emit_xfloating_compare
|
|||
PARAMS ((enum rtx_code, rtx, rtx));
|
||||
static void alpha_output_function_end_prologue
|
||||
PARAMS ((FILE *));
|
||||
static int alpha_adjust_cost
|
||||
PARAMS ((rtx, rtx, rtx, int));
|
||||
static int alpha_issue_rate
|
||||
PARAMS ((void));
|
||||
static int alpha_variable_issue
|
||||
PARAMS ((FILE *, int, rtx, int));
|
||||
|
||||
/* Get the number of args of a function in one of two ways. */
|
||||
#if TARGET_ABI_OPEN_VMS
|
||||
|
@ -163,6 +169,13 @@ static void vms_asm_out_destructor PARAMS ((rtx, int));
|
|||
#undef TARGET_ASM_FUNCTION_END_PROLOGUE
|
||||
#define TARGET_ASM_FUNCTION_END_PROLOGUE alpha_output_function_end_prologue
|
||||
|
||||
#undef TARGET_SCHED_ADJUST_COST
|
||||
#define TARGET_SCHED_ADJUST_COST alpha_adjust_cost
|
||||
#undef TARGET_SCHED_ISSUE_RATE
|
||||
#define TARGET_SCHED_ISSUE_RATE alpha_issue_rate
|
||||
#undef TARGET_SCHED_VARIABLE_ISSUE
|
||||
#define TARGET_SCHED_VARIABLE_ISSUE alpha_variable_issue
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
/* Parse target option strings. */
|
||||
|
@ -3542,7 +3555,7 @@ alpha_expand_block_clear (operands)
|
|||
/* Adjust the cost of a scheduling dependency. Return the new cost of
|
||||
a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
|
||||
|
||||
int
|
||||
static int
|
||||
alpha_adjust_cost (insn, link, dep_insn, cost)
|
||||
rtx insn;
|
||||
rtx link;
|
||||
|
@ -3686,6 +3699,27 @@ alpha_adjust_cost (insn, link, dep_insn, cost)
|
|||
/* Otherwise, return the default cost. */
|
||||
return cost;
|
||||
}
|
||||
|
||||
/* Function to initialize the issue rate used by the scheduler. */
|
||||
static int
|
||||
alpha_issue_rate ()
|
||||
{
|
||||
return (alpha_cpu == PROCESSOR_EV4 ? 2 : 4);
|
||||
}
|
||||
|
||||
static int
|
||||
alpha_variable_issue (dump, verbose, insn, cim)
|
||||
FILE *dump ATTRIBUTE_UNUSED;
|
||||
int verbose ATTRIBUTE_UNUSED;
|
||||
rtx insn;
|
||||
int cim;
|
||||
{
|
||||
if (recog_memoized (insn) < 0 || get_attr_type (insn) == TYPE_MULTI)
|
||||
return 0;
|
||||
|
||||
return cim - 1;
|
||||
}
|
||||
|
||||
|
||||
/* Functions to save and restore alpha_return_addr_rtx. */
|
||||
|
||||
|
|
|
@ -870,11 +870,6 @@ extern int alpha_memory_latency;
|
|||
|
||||
/* Provide the cost of a branch. Exact meaning under development. */
|
||||
#define BRANCH_COST 5
|
||||
|
||||
/* Adjust the cost of dependencies. */
|
||||
|
||||
#define ADJUST_COST(INSN,LINK,DEP,COST) \
|
||||
(COST) = alpha_adjust_cost (INSN, LINK, DEP, COST)
|
||||
|
||||
/* Stack layout; function entry, exit and calling. */
|
||||
|
||||
|
@ -1724,15 +1719,6 @@ do { \
|
|||
few bits. */
|
||||
#define SHIFT_COUNT_TRUNCATED 1
|
||||
|
||||
/* The EV4 is dual issue; EV5/EV6 are quad issue. */
|
||||
#define ISSUE_RATE (alpha_cpu == PROCESSOR_EV4 ? 2 : 4)
|
||||
|
||||
/* Describe the fact that MULTI instructions are multiple instructions
|
||||
and so to assume they don't pair with anything. */
|
||||
#define MD_SCHED_VARIABLE_ISSUE(DUMP, SCHED_VERBOSE, INSN, CAN_ISSUE_MORE) \
|
||||
if (recog_memoized (INSN) < 0 || get_attr_type (INSN) == TYPE_MULTI) \
|
||||
(CAN_ISSUE_MORE) = 0
|
||||
|
||||
/* Compute the cost of computing a constant rtl expression RTX
|
||||
whose rtx-code is CODE. The body of this macro is a portion
|
||||
of a switch statement. If the code is computed here,
|
||||
|
|
|
@ -49,7 +49,6 @@ extern RTX_CODE arm_canonicalize_comparison PARAMS ((RTX_CODE, rtx *));
|
|||
extern int legitimate_pic_operand_p PARAMS ((rtx));
|
||||
extern rtx legitimize_pic_address PARAMS ((rtx, enum machine_mode, rtx));
|
||||
extern int arm_rtx_costs PARAMS ((rtx, RTX_CODE, RTX_CODE));
|
||||
extern int arm_adjust_cost PARAMS ((rtx, rtx, rtx, int));
|
||||
extern int const_double_rtx_ok_for_fpu PARAMS ((rtx));
|
||||
extern int neg_const_double_rtx_ok_for_fpu PARAMS ((rtx));
|
||||
|
||||
|
|
|
@ -117,6 +117,8 @@ static int arm_comp_type_attributes PARAMS ((tree, tree));
|
|||
static void arm_set_default_type_attributes PARAMS ((tree));
|
||||
static void arm_elf_asm_named_section PARAMS ((const char *,
|
||||
unsigned int));
|
||||
static int arm_adjust_cost PARAMS ((rtx, rtx, rtx, int));
|
||||
|
||||
#undef Hint
|
||||
#undef Mmode
|
||||
#undef Ulong
|
||||
|
@ -157,6 +159,9 @@ static void arm_elf_asm_named_section PARAMS ((const char *,
|
|||
#undef TARGET_EXPAND_BUILTIN
|
||||
#define TARGET_EXPAND_BUILTIN arm_expand_builtin
|
||||
|
||||
#undef TARGET_SCHED_ADJUST_COST
|
||||
#define TARGET_SCHED_ADJUST_COST arm_adjust_cost
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
/* Obstack for minipool constant handling. */
|
||||
|
@ -2744,7 +2749,7 @@ arm_rtx_costs (x, code, outer)
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
arm_adjust_cost (insn, link, dep, cost)
|
||||
rtx insn;
|
||||
rtx link;
|
||||
|
|
|
@ -2446,11 +2446,6 @@ typedef struct
|
|||
conditional instructions */
|
||||
#define BRANCH_COST \
|
||||
(TARGET_ARM ? 4 : (optimize > 1 ? 1 : 0))
|
||||
|
||||
/* A C statement to update the variable COST based on the relationship
|
||||
between INSN that is dependent on DEP through dependence LINK. */
|
||||
#define ADJUST_COST(INSN, LINK, DEP, COST) \
|
||||
(COST) = arm_adjust_cost (INSN, LINK, DEP, COST)
|
||||
|
||||
/* Position Independent Code. */
|
||||
/* We decide which register to use based on the compilation options and
|
||||
|
|
|
@ -1842,23 +1842,7 @@ do { \
|
|||
#define NO_RECURSIVE_FUNCTION_CSE
|
||||
/* Define this macro if it is as good or better for a function to call
|
||||
itself with an explicit address than to call an address kept in a
|
||||
register.
|
||||
|
||||
`ADJUST_COST (INSN, LINK, DEP_INSN, COST)'
|
||||
A C statement (sans semicolon) to update the integer variable COST
|
||||
based on the relationship between INSN that is dependent on
|
||||
DEP_INSN through the dependence LINK. The default is to make no
|
||||
adjustment to COST. This can be used for example to specify to
|
||||
the scheduler that an output- or anti-dependence does not incur
|
||||
the same cost as a data-dependence.
|
||||
|
||||
`ADJUST_PRIORITY (INSN)'
|
||||
A C statement (sans semicolon) to update the integer scheduling
|
||||
priority `INSN_PRIORITY(INSN)'. Reduce the priority to execute
|
||||
the INSN earlier, increase the priority to execute INSN later.
|
||||
Do not define this macro if you do not need to adjust the
|
||||
scheduling priorities of insns. */
|
||||
|
||||
register. */
|
||||
|
||||
#define TEXT_SECTION_ASM_OP "\t.text"
|
||||
/* A C expression whose value is a string containing the assembler
|
||||
|
|
|
@ -107,8 +107,6 @@ extern int c4x_label_conflict PARAMS ((rtx, rtx, rtx));
|
|||
|
||||
extern int c4x_address_conflict PARAMS ((rtx, rtx, int, int));
|
||||
|
||||
extern int c4x_adjust_cost PARAMS ((rtx, rtx, rtx, int));
|
||||
|
||||
extern void c4x_process_after_reload PARAMS ((rtx));
|
||||
|
||||
extern void c4x_rptb_insert PARAMS ((rtx insn));
|
||||
|
|
|
@ -194,6 +194,7 @@ static int c4x_label_ref_used_p PARAMS ((rtx, rtx));
|
|||
static int c4x_valid_type_attribute_p PARAMS ((tree, tree, tree, tree));
|
||||
static void c4x_insert_attributes PARAMS ((tree, tree *));
|
||||
static void c4x_asm_named_section PARAMS ((const char *, unsigned int));
|
||||
static int c4x_adjust_cost PARAMS ((rtx, rtx, rtx, int));
|
||||
|
||||
/* Initialize the GCC target structure. */
|
||||
#undef TARGET_VALID_TYPE_ATTRIBUTE
|
||||
|
@ -208,6 +209,9 @@ static void c4x_asm_named_section PARAMS ((const char *, unsigned int));
|
|||
#undef TARGET_EXPAND_BUILTIN
|
||||
#define TARGET_EXPAND_BUILTIN c4x_expand_builtin
|
||||
|
||||
#undef TARGET_SCHED_ADJUST_COST
|
||||
#define TARGET_SCHED_ADJUST_COST c4x_adjust_cost
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
/* Called to register all of our global variables with the garbage
|
||||
|
@ -4907,8 +4911,7 @@ c4x_check_laj_p (insn)
|
|||
#define SETLDA_USE_COST 2
|
||||
#define READ_USE_COST 2
|
||||
|
||||
|
||||
int
|
||||
static int
|
||||
c4x_adjust_cost (insn, link, dep_insn, cost)
|
||||
rtx insn;
|
||||
rtx link;
|
||||
|
|
|
@ -1953,11 +1953,6 @@ if (REG_P (OP1) && ! REG_P (OP0)) \
|
|||
|
||||
#define BRANCH_COST 8
|
||||
|
||||
/* Adjust the cost of dependencies. */
|
||||
|
||||
#define ADJUST_COST(INSN,LINK,DEP,COST) \
|
||||
(COST) = c4x_adjust_cost (INSN, LINK, DEP, COST)
|
||||
|
||||
#define WORD_REGISTER_OPERATIONS
|
||||
|
||||
/* Dividing the Output into Sections. */
|
||||
|
|
|
@ -66,12 +66,15 @@ static rtx convert_arg_pushes ();
|
|||
static void expand_movstr_call PARAMS ((rtx *));
|
||||
static void convex_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
|
||||
static void convex_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
|
||||
static int convex_adjust_cost PARAMS ((rtx, rtx, rtx, int));
|
||||
|
||||
/* Initialize the GCC target structure. */
|
||||
#undef TARGET_ASM_FUNCTION_PROLOGUE
|
||||
#define TARGET_ASM_FUNCTION_PROLOGUE convex_output_function_prologue
|
||||
#undef TARGET_ASM_FUNCTION_EPILOGUE
|
||||
#define TARGET_ASM_FUNCTION_EPILOGUE convex_output_function_epilogue
|
||||
#undef TARGET_SCHED_ADJUST_COST
|
||||
#define TARGET_SCHED_ADJUST_COST convex_adjust_cost
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
|
@ -111,6 +114,43 @@ convex_output_function_epilogue (file, size)
|
|||
fprintf (file, "\tds.h 0\n");
|
||||
}
|
||||
|
||||
/* Adjust the cost of dependences. */
|
||||
static int
|
||||
convex_adjust_cost (insn, link, dep, cost)
|
||||
rtx insn;
|
||||
rtx link;
|
||||
rtx dep;
|
||||
int cost;
|
||||
{
|
||||
/* Antidependencies don't block issue. */
|
||||
if (REG_NOTE_KIND (link) != 0)
|
||||
cost = 0;
|
||||
/* C38 situations where delay depends on context */
|
||||
else if (TARGET_C38
|
||||
&& GET_CODE (PATTERN (insn)) == SET
|
||||
&& GET_CODE (PATTERN (dep)) == SET)
|
||||
{
|
||||
enum attr_type insn_type = get_attr_type (insn);
|
||||
enum attr_type dep_type = get_attr_type (dep);
|
||||
/* index register must be ready one cycle early */
|
||||
if (insn_type == TYPE_MLDW || insn_type == TYPE_MLDL
|
||||
|| (insn_type == TYPE_MST
|
||||
&& reg_mentioned_p (SET_DEST (PATTERN (dep)),
|
||||
SET_SRC (PATTERN (insn)))))
|
||||
cost += 1;
|
||||
/* alu forwarding off alu takes two */
|
||||
if (dep_type == TYPE_ALU
|
||||
&& insn_type != TYPE_ALU
|
||||
&& ! (insn_type == TYPE_MST
|
||||
&& SET_DEST (PATTERN (dep)) == SET_SRC (PATTERN (insn))))
|
||||
cost += 1;
|
||||
}
|
||||
|
||||
return cost;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Here from OVERRIDE_OPTIONS at startup. Initialize constant tables. */
|
||||
|
||||
void
|
||||
|
|
|
@ -1115,35 +1115,6 @@ enum reg_class {
|
|||
|
||||
#define BRANCH_COST 0
|
||||
|
||||
/* Adjust the cost of dependences. */
|
||||
|
||||
#define ADJUST_COST(INSN,LINK,DEP,COST) \
|
||||
{ \
|
||||
/* Antidependencies don't block issue. */ \
|
||||
if (REG_NOTE_KIND (LINK) != 0) \
|
||||
(COST) = 0; \
|
||||
/* C38 situations where delay depends on context */ \
|
||||
else if (TARGET_C38 \
|
||||
&& GET_CODE (PATTERN (INSN)) == SET \
|
||||
&& GET_CODE (PATTERN (DEP)) == SET) \
|
||||
{ \
|
||||
enum attr_type insn_type = get_attr_type (INSN); \
|
||||
enum attr_type dep_type = get_attr_type (DEP); \
|
||||
/* index register must be ready one cycle early */ \
|
||||
if (insn_type == TYPE_MLDW || insn_type == TYPE_MLDL \
|
||||
|| (insn_type == TYPE_MST \
|
||||
&& reg_mentioned_p (SET_DEST (PATTERN (DEP)), \
|
||||
SET_SRC (PATTERN (INSN))))) \
|
||||
(COST) += 1; \
|
||||
/* alu forwarding off alu takes two */ \
|
||||
if (dep_type == TYPE_ALU \
|
||||
&& insn_type != TYPE_ALU \
|
||||
&& ! (insn_type == TYPE_MST \
|
||||
&& SET_DEST (PATTERN (DEP)) == SET_SRC (PATTERN (INSN)))) \
|
||||
(COST) += 1; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Convex uses VAX or IEEE floats.
|
||||
Follow the host format. */
|
||||
#define TARGET_FLOAT_FORMAT HOST_FLOAT_FORMAT
|
||||
|
|
|
@ -129,7 +129,6 @@ extern rtx d30v_emit_comparison PARAMS ((int, rtx, rtx, rtx));
|
|||
extern char *d30v_move_2words PARAMS ((rtx *, rtx));
|
||||
extern int d30v_emit_cond_move PARAMS ((rtx, rtx, rtx, rtx));
|
||||
extern void d30v_machine_dependent_reorg PARAMS ((rtx));
|
||||
extern int d30v_adjust_cost PARAMS ((rtx, rtx, rtx, int));
|
||||
extern rtx d30v_return_addr PARAMS ((void));
|
||||
#endif
|
||||
extern void d30v_init_expanders PARAMS ((void));
|
||||
|
|
|
@ -51,6 +51,8 @@ static void d30v_mark_machine_status PARAMS ((struct function *));
|
|||
static void d30v_free_machine_status PARAMS ((struct function *));
|
||||
static void d30v_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
|
||||
static void d30v_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
|
||||
static int d30v_adjust_cost PARAMS ((rtx, rtx, rtx, int));
|
||||
static int d30v_issue_rate PARAMS ((void));
|
||||
|
||||
/* Define the information needed to generate branch and scc insns. This is
|
||||
stored from the compare operation. */
|
||||
|
@ -86,6 +88,10 @@ enum reg_class reg_class_from_letter[256];
|
|||
#define TARGET_ASM_FUNCTION_PROLOGUE d30v_output_function_prologue
|
||||
#undef TARGET_ASM_FUNCTION_EPILOGUE
|
||||
#define TARGET_ASM_FUNCTION_EPILOGUE d30v_output_function_epilogue
|
||||
#undef TARGET_SCHED_ADJUST_COST
|
||||
#define TARGET_SCHED_ADJUST_COST d30v_adjust_cost
|
||||
#undef TARGET_SCHED_ISSUE_RATE
|
||||
#define TARGET_SCHED_ISSUE_RATE d30v_issue_rate
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
|
@ -3490,7 +3496,7 @@ d30v_machine_dependent_reorg (insn)
|
|||
/* For the d30v, try to insure that the source operands for a load/store are
|
||||
set 2 cycles before the memory reference. */
|
||||
|
||||
int
|
||||
static int
|
||||
d30v_adjust_cost (insn, link, dep_insn, cost)
|
||||
rtx insn;
|
||||
rtx link ATTRIBUTE_UNUSED;
|
||||
|
@ -3511,13 +3517,22 @@ d30v_adjust_cost (insn, link, dep_insn, cost)
|
|||
|| (GET_CODE (mem = SET_DEST (set_insn)) == MEM
|
||||
&& reg_mentioned_p (reg, XEXP (mem, 0))))
|
||||
{
|
||||
return cost + ((HAIFA_P) ? 2 : 4);
|
||||
return cost + 2;
|
||||
}
|
||||
}
|
||||
|
||||
return cost;
|
||||
}
|
||||
|
||||
/* Function which returns the number of insns that can be
|
||||
scheduled in the same machine cycle. This must be constant
|
||||
over an entire compilation. The default is 1. */
|
||||
static int
|
||||
d30v_issue_rate ()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
/* Routine to allocate, mark and free a per-function,
|
||||
machine specific structure. */
|
||||
|
|
|
@ -3630,29 +3630,6 @@ extern const char *d30v_branch_cost_string;
|
|||
with an explicit address than to call an address kept in a register. */
|
||||
/* #define NO_RECURSIVE_FUNCTION_CSE */
|
||||
|
||||
/* A C statement (sans semicolon) to update the integer variable COST based on
|
||||
the relationship between INSN that is dependent on DEP_INSN through the
|
||||
dependence LINK. The default is to make no adjustment to COST. This can be
|
||||
used for example to specify to the scheduler that an output- or
|
||||
anti-dependence does not incur the same cost as a data-dependence. */
|
||||
|
||||
#define ADJUST_COST(INSN,LINK,DEP_INSN,COST) \
|
||||
(COST) = d30v_adjust_cost (INSN, LINK, DEP_INSN, COST)
|
||||
|
||||
/* A C statement (sans semicolon) to update the integer scheduling
|
||||
priority `INSN_PRIORITY(INSN)'. Reduce the priority to execute
|
||||
the INSN earlier, increase the priority to execute INSN later.
|
||||
Do not define this macro if you do not need to adjust the
|
||||
scheduling priorities of insns. */
|
||||
/* #define ADJUST_PRIORITY (INSN) */
|
||||
|
||||
/* Macro to determine whether the Haifa scheduler is used. */
|
||||
#ifdef HAIFA
|
||||
#define HAIFA_P 1
|
||||
#else
|
||||
#define HAIFA_P 0
|
||||
#endif
|
||||
|
||||
|
||||
/* Dividing the output into sections. */
|
||||
|
||||
|
@ -5764,7 +5741,4 @@ fprintf (STREAM, "\t.word .L%d\n", VALUE)
|
|||
extern int d30v_cond_exec;
|
||||
extern const char *d30v_cond_exec_string;
|
||||
|
||||
/* Indicate how many instructions can be issued at the same time. */
|
||||
#define ISSUE_RATE 2
|
||||
|
||||
#endif /* GCC_D30V_H */
|
||||
|
|
|
@ -131,11 +131,6 @@ extern rtx assign_386_stack_local PARAMS ((enum machine_mode, int));
|
|||
extern int ix86_attr_length_immediate_default PARAMS ((rtx, int));
|
||||
extern int ix86_attr_length_address_default PARAMS ((rtx));
|
||||
|
||||
extern int ix86_issue_rate PARAMS ((void));
|
||||
extern int ix86_adjust_cost PARAMS ((rtx, rtx, rtx, int));
|
||||
extern void ix86_sched_init PARAMS ((FILE *, int));
|
||||
extern int ix86_sched_reorder PARAMS ((FILE *, int, rtx *, int, int));
|
||||
extern int ix86_variable_issue PARAMS ((FILE *, int, rtx, int));
|
||||
extern enum machine_mode ix86_fp_compare_mode PARAMS ((enum rtx_code));
|
||||
|
||||
extern int x86_64_sign_extended_value PARAMS ((rtx));
|
||||
|
|
|
@ -574,6 +574,11 @@ static HOST_WIDE_INT ix86_GOT_alias_set PARAMS ((void));
|
|||
static void ix86_adjust_counter PARAMS ((rtx, HOST_WIDE_INT));
|
||||
static rtx ix86_expand_aligntest PARAMS ((rtx, int));
|
||||
static void ix86_expand_strlensi_unroll_1 PARAMS ((rtx, rtx));
|
||||
static int ix86_issue_rate PARAMS ((void));
|
||||
static int ix86_adjust_cost PARAMS ((rtx, rtx, rtx, int));
|
||||
static void ix86_sched_init PARAMS ((FILE *, int, int));
|
||||
static int ix86_sched_reorder PARAMS ((FILE *, int, rtx *, int *, int));
|
||||
static int ix86_variable_issue PARAMS ((FILE *, int, rtx, int));
|
||||
|
||||
struct ix86_address
|
||||
{
|
||||
|
@ -649,6 +654,17 @@ static void sco_asm_out_constructor PARAMS ((rtx, int));
|
|||
#undef TARGET_ASM_CLOSE_PAREN
|
||||
#define TARGET_ASM_CLOSE_PAREN ""
|
||||
|
||||
#undef TARGET_SCHED_ADJUST_COST
|
||||
#define TARGET_SCHED_ADJUST_COST ix86_adjust_cost
|
||||
#undef TARGET_SCHED_ISSUE_RATE
|
||||
#define TARGET_SCHED_ISSUE_RATE ix86_issue_rate
|
||||
#undef TARGET_SCHED_VARIABLE_ISSUE
|
||||
#define TARGET_SCHED_VARIABLE_ISSUE ix86_variable_issue
|
||||
#undef TARGET_SCHED_INIT
|
||||
#define TARGET_SCHED_INIT ix86_sched_init
|
||||
#undef TARGET_SCHED_REORDER
|
||||
#define TARGET_SCHED_REORDER ix86_sched_reorder
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
/* Sometimes certain combinations of command options do not make
|
||||
|
@ -8373,7 +8389,7 @@ ix86_attr_length_address_default (insn)
|
|||
|
||||
/* Return the maximum number of instructions a cpu can issue. */
|
||||
|
||||
int
|
||||
static int
|
||||
ix86_issue_rate ()
|
||||
{
|
||||
switch (ix86_cpu)
|
||||
|
@ -8479,7 +8495,7 @@ ix86_agi_dependant (insn, dep_insn, insn_type)
|
|||
return modified_in_p (addr, dep_insn);
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
ix86_adjust_cost (insn, link, dep_insn, cost)
|
||||
rtx insn, link, dep_insn;
|
||||
int cost;
|
||||
|
@ -8707,10 +8723,11 @@ ix86_dump_ppro_packet (dump)
|
|||
|
||||
/* We're beginning a new block. Initialize data structures as necessary. */
|
||||
|
||||
void
|
||||
ix86_sched_init (dump, sched_verbose)
|
||||
static void
|
||||
ix86_sched_init (dump, sched_verbose, veclen)
|
||||
FILE *dump ATTRIBUTE_UNUSED;
|
||||
int sched_verbose ATTRIBUTE_UNUSED;
|
||||
int veclen ATTRIBUTE_UNUSED;
|
||||
{
|
||||
memset (&ix86_sched_data, 0, sizeof (ix86_sched_data));
|
||||
}
|
||||
|
@ -8941,14 +8958,15 @@ ix86_sched_reorder_ppro (ready, e_ready)
|
|||
|
||||
/* We are about to being issuing insns for this clock cycle.
|
||||
Override the default sort algorithm to better slot instructions. */
|
||||
int
|
||||
ix86_sched_reorder (dump, sched_verbose, ready, n_ready, clock_var)
|
||||
static int
|
||||
ix86_sched_reorder (dump, sched_verbose, ready, n_readyp, clock_var)
|
||||
FILE *dump ATTRIBUTE_UNUSED;
|
||||
int sched_verbose ATTRIBUTE_UNUSED;
|
||||
rtx *ready;
|
||||
int n_ready;
|
||||
int *n_readyp;
|
||||
int clock_var ATTRIBUTE_UNUSED;
|
||||
{
|
||||
int n_ready = *n_readyp;
|
||||
rtx *e_ready = ready + n_ready - 1;
|
||||
|
||||
if (n_ready < 2)
|
||||
|
@ -8975,7 +8993,7 @@ out:
|
|||
/* We are about to issue INSN. Return the number of insns left on the
|
||||
ready queue that can be issued this cycle. */
|
||||
|
||||
int
|
||||
static int
|
||||
ix86_variable_issue (dump, sched_verbose, insn, can_issue_more)
|
||||
FILE *dump;
|
||||
int sched_verbose;
|
||||
|
|
|
@ -2638,29 +2638,6 @@ while (0)
|
|||
register. */
|
||||
|
||||
#define NO_RECURSIVE_FUNCTION_CSE
|
||||
|
||||
/* A C statement (sans semicolon) to update the integer variable COST
|
||||
based on the relationship between INSN that is dependent on
|
||||
DEP_INSN through the dependence LINK. The default is to make no
|
||||
adjustment to COST. This can be used for example to specify to
|
||||
the scheduler that an output- or anti-dependence does not incur
|
||||
the same cost as a data-dependence. */
|
||||
|
||||
#define ADJUST_COST(insn,link,dep_insn,cost) \
|
||||
(cost) = ix86_adjust_cost(insn, link, dep_insn, cost)
|
||||
|
||||
#define ISSUE_RATE \
|
||||
ix86_issue_rate ()
|
||||
|
||||
#define MD_SCHED_INIT(DUMP, SCHED_VERBOSE, MAX_READY) \
|
||||
ix86_sched_init (DUMP, SCHED_VERBOSE)
|
||||
|
||||
#define MD_SCHED_REORDER(DUMP, SCHED_VERBOSE, READY, N_READY, CLOCK, CIM) \
|
||||
(CIM) = ix86_sched_reorder (DUMP, SCHED_VERBOSE, READY, N_READY, CLOCK)
|
||||
|
||||
#define MD_SCHED_VARIABLE_ISSUE(DUMP, SCHED_VERBOSE, INSN, CAN_ISSUE_MORE) \
|
||||
((CAN_ISSUE_MORE) = \
|
||||
ix86_variable_issue (DUMP, SCHED_VERBOSE, INSN, CAN_ISSUE_MORE))
|
||||
|
||||
/* Add any extra modes needed to represent the condition code.
|
||||
|
||||
|
|
|
@ -91,13 +91,6 @@ extern enum reg_class ia64_secondary_reload_class PARAMS((enum reg_class,
|
|||
extern void ia64_reorg PARAMS((rtx));
|
||||
extern void process_for_unwind_directive PARAMS ((FILE *, rtx));
|
||||
extern const char *get_bundle_name PARAMS ((int));
|
||||
extern int ia64_issue_rate PARAMS ((void));
|
||||
extern int ia64_adjust_cost PARAMS ((rtx, rtx, rtx, int));
|
||||
extern void ia64_sched_init PARAMS ((FILE *, int, int));
|
||||
extern void ia64_sched_finish PARAMS ((FILE *, int));
|
||||
extern int ia64_sched_reorder PARAMS ((FILE *, int, rtx *, int *, int, int));
|
||||
extern int ia64_sched_reorder2 PARAMS ((FILE *, int, rtx *, int *, int));
|
||||
extern int ia64_variable_issue PARAMS ((FILE *, int, rtx, int));
|
||||
#endif /* RTX_CODE */
|
||||
|
||||
#ifdef TREE_CODE
|
||||
|
|
|
@ -141,6 +141,18 @@ static int ia64_valid_type_attribute PARAMS((tree, tree, tree, tree));
|
|||
static void ia64_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
|
||||
static void ia64_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
|
||||
static void ia64_output_function_end_prologue PARAMS ((FILE *));
|
||||
|
||||
static int ia64_issue_rate PARAMS ((void));
|
||||
static int ia64_adjust_cost PARAMS ((rtx, rtx, rtx, int));
|
||||
static void ia64_sched_init PARAMS ((FILE *, int, int));
|
||||
static void ia64_sched_finish PARAMS ((FILE *, int));
|
||||
static int ia64_internal_sched_reorder PARAMS ((FILE *, int, rtx *,
|
||||
int *, int, int));
|
||||
static int ia64_sched_reorder PARAMS ((FILE *, int, rtx *, int *, int));
|
||||
static int ia64_sched_reorder2 PARAMS ((FILE *, int, rtx *, int *, int));
|
||||
static int ia64_variable_issue PARAMS ((FILE *, int, rtx, int));
|
||||
static rtx ia64_cycle_display PARAMS ((int, rtx));
|
||||
|
||||
|
||||
/* Initialize the GCC target structure. */
|
||||
#undef TARGET_VALID_TYPE_ATTRIBUTE
|
||||
|
@ -159,6 +171,23 @@ static void ia64_output_function_end_prologue PARAMS ((FILE *));
|
|||
#undef TARGET_ASM_FUNCTION_EPILOGUE
|
||||
#define TARGET_ASM_FUNCTION_EPILOGUE ia64_output_function_epilogue
|
||||
|
||||
#undef TARGET_SCHED_ADJUST_COST
|
||||
#define TARGET_SCHED_ADJUST_COST ia64_adjust_cost
|
||||
#undef TARGET_SCHED_ISSUE_RATE
|
||||
#define TARGET_SCHED_ISSUE_RATE ia64_issue_rate
|
||||
#undef TARGET_SCHED_VARIABLE_ISSUE
|
||||
#define TARGET_SCHED_VARIABLE_ISSUE ia64_variable_issue
|
||||
#undef TARGET_SCHED_INIT
|
||||
#define TARGET_SCHED_INIT ia64_sched_init
|
||||
#undef TARGET_SCHED_FINISH
|
||||
#define TARGET_SCHED_FINISH ia64_sched_finish
|
||||
#undef TARGET_SCHED_REORDER
|
||||
#define TARGET_SCHED_REORDER ia64_sched_reorder
|
||||
#undef TARGET_SCHED_REORDER2
|
||||
#define TARGET_SCHED_REORDER2 ia64_sched_reorder2
|
||||
#undef TARGET_SCHED_CYCLE_DISPLAY
|
||||
#define TARGET_SCHED_CYCLE_DISPLAY ia64_cycle_display
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
/* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
|
||||
|
@ -5064,7 +5093,7 @@ itanium_split_issue (p, begin)
|
|||
|
||||
/* Return the maximum number of instructions a cpu can issue. */
|
||||
|
||||
int
|
||||
static int
|
||||
ia64_issue_rate ()
|
||||
{
|
||||
return 6;
|
||||
|
@ -5087,7 +5116,7 @@ ia64_single_set (insn)
|
|||
/* Adjust the cost of a scheduling dependency. Return the new cost of
|
||||
a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
|
||||
|
||||
int
|
||||
static int
|
||||
ia64_adjust_cost (insn, link, dep_insn, cost)
|
||||
rtx insn, link, dep_insn;
|
||||
int cost;
|
||||
|
@ -5465,7 +5494,7 @@ rotate_two_bundles (dump)
|
|||
|
||||
/* We're beginning a new block. Initialize data structures as necessary. */
|
||||
|
||||
void
|
||||
static void
|
||||
ia64_sched_init (dump, sched_verbose, max_ready)
|
||||
FILE *dump ATTRIBUTE_UNUSED;
|
||||
int sched_verbose ATTRIBUTE_UNUSED;
|
||||
|
@ -5987,8 +6016,8 @@ nop_cycles_until (clock_var, dump)
|
|||
/* We are about to being issuing insns for this clock cycle.
|
||||
Override the default sort algorithm to better slot instructions. */
|
||||
|
||||
int
|
||||
ia64_sched_reorder (dump, sched_verbose, ready, pn_ready,
|
||||
static int
|
||||
ia64_internal_sched_reorder (dump, sched_verbose, ready, pn_ready,
|
||||
reorder_type, clock_var)
|
||||
FILE *dump ATTRIBUTE_UNUSED;
|
||||
int sched_verbose ATTRIBUTE_UNUSED;
|
||||
|
@ -6139,10 +6168,22 @@ ia64_sched_reorder (dump, sched_verbose, ready, pn_ready,
|
|||
ready, e_ready, reorder_type == 1);
|
||||
}
|
||||
|
||||
static int
|
||||
ia64_sched_reorder (dump, sched_verbose, ready, pn_ready, clock_var)
|
||||
FILE *dump;
|
||||
int sched_verbose;
|
||||
rtx *ready;
|
||||
int *pn_ready;
|
||||
int clock_var;
|
||||
{
|
||||
return ia64_internal_sched_reorder (dump, sched_verbose, ready,
|
||||
pn_ready, 0, clock_var);
|
||||
}
|
||||
|
||||
/* Like ia64_sched_reorder, but called after issuing each insn.
|
||||
Override the default sort algorithm to better slot instructions. */
|
||||
|
||||
int
|
||||
static int
|
||||
ia64_sched_reorder2 (dump, sched_verbose, ready, pn_ready, clock_var)
|
||||
FILE *dump ATTRIBUTE_UNUSED;
|
||||
int sched_verbose ATTRIBUTE_UNUSED;
|
||||
|
@ -6232,8 +6273,9 @@ ia64_sched_reorder2 (dump, sched_verbose, ready, pn_ready, clock_var)
|
|||
|
||||
if (*pn_ready > 0)
|
||||
{
|
||||
int more = ia64_sched_reorder (dump, sched_verbose, ready, pn_ready, 1,
|
||||
clock_var);
|
||||
int more = ia64_internal_sched_reorder (dump, sched_verbose,
|
||||
ready, pn_ready, 1,
|
||||
clock_var);
|
||||
if (more)
|
||||
return more;
|
||||
/* Did we schedule a stop? If so, finish this cycle. */
|
||||
|
@ -6253,7 +6295,7 @@ ia64_sched_reorder2 (dump, sched_verbose, ready, pn_ready, clock_var)
|
|||
/* We are about to issue INSN. Return the number of insns left on the
|
||||
ready queue that can be issued this cycle. */
|
||||
|
||||
int
|
||||
static int
|
||||
ia64_variable_issue (dump, sched_verbose, insn, can_issue_more)
|
||||
FILE *dump;
|
||||
int sched_verbose;
|
||||
|
@ -6315,7 +6357,7 @@ ia64_variable_issue (dump, sched_verbose, insn, can_issue_more)
|
|||
|
||||
/* Free data allocated by ia64_sched_init. */
|
||||
|
||||
void
|
||||
static void
|
||||
ia64_sched_finish (dump, sched_verbose)
|
||||
FILE *dump;
|
||||
int sched_verbose;
|
||||
|
@ -6326,6 +6368,14 @@ ia64_sched_finish (dump, sched_verbose)
|
|||
free (sched_types);
|
||||
free (sched_ready);
|
||||
}
|
||||
|
||||
static rtx
|
||||
ia64_cycle_display (clock, last)
|
||||
int clock;
|
||||
rtx last;
|
||||
{
|
||||
return emit_insn_after (gen_cycle_display (GEN_INT (clock)), last);
|
||||
}
|
||||
|
||||
/* Emit pseudo-ops for the assembler to describe predicate relations.
|
||||
At present this assumes that we only consider predicate pairs to
|
||||
|
|
|
@ -2755,40 +2755,6 @@ do { \
|
|||
/* ??? Investigate. */
|
||||
#define MAX_CONDITIONAL_EXECUTE 12
|
||||
|
||||
/* A C statement (sans semicolon) to update the integer scheduling
|
||||
priority `INSN_PRIORITY(INSN)'. */
|
||||
|
||||
/* ??? Investigate. */
|
||||
/* #define ADJUST_PRIORITY (INSN) */
|
||||
|
||||
/* A C statement (sans semicolon) to update the integer variable COST
|
||||
based on the relationship between INSN that is dependent on
|
||||
DEP_INSN through the dependence LINK. The default is to make no
|
||||
adjustment to COST. This can be used for example to specify to
|
||||
the scheduler that an output- or anti-dependence does not incur
|
||||
the same cost as a data-dependence. */
|
||||
|
||||
#define ADJUST_COST(insn,link,dep_insn,cost) \
|
||||
(cost) = ia64_adjust_cost(insn, link, dep_insn, cost)
|
||||
|
||||
#define ISSUE_RATE ia64_issue_rate ()
|
||||
|
||||
#define MD_SCHED_INIT(DUMP, SCHED_VERBOSE, MAX_READY) \
|
||||
ia64_sched_init (DUMP, SCHED_VERBOSE, MAX_READY)
|
||||
|
||||
#define MD_SCHED_REORDER(DUMP, SCHED_VERBOSE, READY, N_READY, CLOCK, CIM) \
|
||||
(CIM) = ia64_sched_reorder (DUMP, SCHED_VERBOSE, READY, &N_READY, 0, CLOCK)
|
||||
|
||||
#define MD_SCHED_REORDER2(DUMP, SCHED_VERBOSE, READY, N_READY, CLOCK, CIM) \
|
||||
(CIM) = ia64_sched_reorder2 (DUMP, SCHED_VERBOSE, READY, &N_READY, CLOCK)
|
||||
|
||||
#define MD_SCHED_FINISH(DUMP, SCHED_VERBOSE) \
|
||||
ia64_sched_finish (DUMP, SCHED_VERBOSE)
|
||||
|
||||
#define MD_SCHED_VARIABLE_ISSUE(DUMP, SCHED_VERBOSE, INSN, CAN_ISSUE_MORE) \
|
||||
((CAN_ISSUE_MORE) \
|
||||
= ia64_variable_issue (DUMP, SCHED_VERBOSE, INSN, CAN_ISSUE_MORE))
|
||||
|
||||
extern int ia64_final_schedule;
|
||||
|
||||
#define IA64_UNWIND_INFO 1
|
||||
|
|
|
@ -31,7 +31,6 @@ extern int m32r_first_insn_address PARAMS ((void));
|
|||
extern void m32r_expand_prologue PARAMS ((void));
|
||||
extern void m32r_finalize_pic PARAMS ((void));
|
||||
extern void m32r_asm_file_start PARAMS ((FILE *));
|
||||
extern void m32r_sched_init PARAMS ((FILE *, int));
|
||||
extern int direct_return PARAMS ((void));
|
||||
#ifdef TREE_CODE
|
||||
extern void m32r_select_section PARAMS ((tree, int));
|
||||
|
@ -60,10 +59,6 @@ extern void m32r_expand_block_move PARAMS ((rtx *));
|
|||
extern void m32r_print_operand PARAMS ((FILE *, rtx, int));
|
||||
extern void m32r_print_operand_address PARAMS ((FILE *, rtx));
|
||||
extern int m32r_address_cost PARAMS ((rtx));
|
||||
extern int m32r_adjust_cost PARAMS ((rtx, rtx, rtx, int));
|
||||
extern int m32r_adjust_priority PARAMS ((rtx, int));
|
||||
extern void m32r_sched_reorder PARAMS ((FILE *, int, rtx *, int));
|
||||
extern int m32r_sched_variable_issue PARAMS ((FILE *, int, rtx, int));
|
||||
extern int m32r_not_same_reg PARAMS ((rtx, rtx));
|
||||
|
||||
#ifdef HAVE_MACHINE_MODES
|
||||
|
|
|
@ -56,7 +56,7 @@ const char * m32r_sdata_string = M32R_SDATA_DEFAULT;
|
|||
enum m32r_sdata m32r_sdata;
|
||||
|
||||
/* Scheduler support */
|
||||
int m32r_sched_odd_word_p;
|
||||
static int m32r_sched_odd_word_p;
|
||||
|
||||
/* Forward declaration. */
|
||||
static void init_reg_tables PARAMS ((void));
|
||||
|
@ -66,6 +66,14 @@ static int m32r_valid_decl_attribute PARAMS ((tree, tree,
|
|||
tree, tree));
|
||||
static void m32r_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
|
||||
static void m32r_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
|
||||
|
||||
static int m32r_adjust_cost PARAMS ((rtx, rtx, rtx, int));
|
||||
static int m32r_adjust_priority PARAMS ((rtx, int));
|
||||
static void m32r_sched_init PARAMS ((FILE *, int));
|
||||
static int m32r_sched_reorder PARAMS ((FILE *, int, rtx *, int *, int));
|
||||
static int m32r_variable_issue PARAMS ((FILE *, int, rtx, int));
|
||||
static int m32r_issue_rate PARAMS ((void));
|
||||
|
||||
|
||||
/* Initialize the GCC target structure. */
|
||||
#undef TARGET_VALID_DECL_ATTRIBUTE
|
||||
|
@ -76,6 +84,19 @@ static void m32r_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
|
|||
#undef TARGET_ASM_FUNCTION_EPILOGUE
|
||||
#define TARGET_ASM_FUNCTION_EPILOGUE m32r_output_function_epilogue
|
||||
|
||||
#undef TARGET_SCHED_ADJUST_COST
|
||||
#define TARGET_SCHED_ADJUST_COST m32r_adjust_cost
|
||||
#undef TARGET_SCHED_ADJUST_PRIORITY
|
||||
#define TARGET_SCHED_ADJUST_PRIORITY m32r_adjust_priority
|
||||
#undef TARGET_SCHED_ISSUE_RATE
|
||||
#define TARGET_SCHED_ISSUE_RATE m32r_issue_rate
|
||||
#undef TARGET_SCHED_VARIABLE_ISSUE
|
||||
#define TARGET_SCHED_VARIABLE_ISSUE m32r_variable_issue
|
||||
#undef TARGET_SCHED_INIT
|
||||
#define TARGET_SCHED_INIT m32r_sched_init
|
||||
#undef TARGET_SCHED_REORDER
|
||||
#define TARGET_SCHED_REORDER m32r_sched_reorder
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
/* Called by OVERRIDE_OPTIONS to initialize various things. */
|
||||
|
@ -1471,7 +1492,7 @@ m32r_va_arg (valist, type)
|
|||
return addr_rtx;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
m32r_adjust_cost (insn, link, dep_insn, cost)
|
||||
rtx insn ATTRIBUTE_UNUSED;
|
||||
rtx link ATTRIBUTE_UNUSED;
|
||||
|
@ -1497,7 +1518,7 @@ m32r_is_insn (insn)
|
|||
/* Increase the priority of long instructions so that the
|
||||
short instructions are scheduled ahead of the long ones. */
|
||||
|
||||
int
|
||||
static int
|
||||
m32r_adjust_priority (insn, priority)
|
||||
rtx insn;
|
||||
int priority;
|
||||
|
@ -1512,7 +1533,7 @@ m32r_adjust_priority (insn, priority)
|
|||
|
||||
/* Initialize for scheduling a group of instructions. */
|
||||
|
||||
void
|
||||
static void
|
||||
m32r_sched_init (stream, verbose)
|
||||
FILE * stream ATTRIBUTE_UNUSED;
|
||||
int verbose ATTRIBUTE_UNUSED;
|
||||
|
@ -1523,15 +1544,18 @@ m32r_sched_init (stream, verbose)
|
|||
|
||||
/* Reorder the schedulers priority list if needed */
|
||||
|
||||
void
|
||||
m32r_sched_reorder (stream, verbose, ready, n_ready)
|
||||
static int
|
||||
m32r_sched_reorder (stream, verbose, ready, n_readyp, clock)
|
||||
FILE * stream;
|
||||
int verbose;
|
||||
rtx * ready;
|
||||
int n_ready;
|
||||
int *n_readyp;
|
||||
int clock ATTRIBUTE_UNUSED;
|
||||
{
|
||||
int n_ready = *n_readyp;
|
||||
|
||||
if (TARGET_DEBUG)
|
||||
return;
|
||||
return m32r_issue_rate ();
|
||||
|
||||
if (verbose <= 7)
|
||||
stream = (FILE *)0;
|
||||
|
@ -1605,11 +1629,8 @@ m32r_sched_reorder (stream, verbose, ready, n_ready)
|
|||
memcpy (ready, new_head, sizeof (rtx) * n_ready);
|
||||
if (stream)
|
||||
{
|
||||
#ifdef HAIFA
|
||||
fprintf (stream, ";;\t\t::: New ready list: ");
|
||||
debug_ready_list (ready, n_ready);
|
||||
#else
|
||||
int i;
|
||||
fprintf (stream, ";;\t\t::: New ready list: ");
|
||||
for (i = 0; i < n_ready; i++)
|
||||
{
|
||||
rtx insn = ready[i];
|
||||
|
@ -1627,17 +1648,27 @@ m32r_sched_reorder (stream, verbose, ready, n_ready)
|
|||
}
|
||||
|
||||
fprintf (stream, "\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return m32r_issue_rate ();
|
||||
}
|
||||
|
||||
/* Indicate how many instructions can be issued at the same time.
|
||||
This is sort of a lie. The m32r can issue only 1 long insn at
|
||||
once, but it can issue 2 short insns. The default therefore is
|
||||
set at 2, but this can be overridden by the command line option
|
||||
-missue-rate=1 */
|
||||
static int
|
||||
m32r_issue_rate ()
|
||||
{
|
||||
return ((TARGET_LOW_ISSUE_RATE) ? 1 : 2);
|
||||
}
|
||||
|
||||
|
||||
/* If we have a machine that can issue a variable # of instructions
|
||||
per cycle, indicate how many more instructions can be issued
|
||||
after the current one. */
|
||||
int
|
||||
m32r_sched_variable_issue (stream, verbose, insn, how_many)
|
||||
static int
|
||||
m32r_variable_issue (stream, verbose, insn, how_many)
|
||||
FILE * stream;
|
||||
int verbose;
|
||||
rtx insn;
|
||||
|
|
|
@ -154,8 +154,8 @@ extern int target_flags;
|
|||
#define TARGET_ALIGN_LOOPS (target_flags & TARGET_ALIGN_LOOPS_MASK)
|
||||
|
||||
/* Change issue rate. */
|
||||
#define TARGET_ISSUE_RATE_MASK (1 << 3)
|
||||
#define TARGET_ISSUE_RATE (target_flags & TARGET_ISSUE_RATE_MASK)
|
||||
#define TARGET_LOW_ISSUE_RATE_MASK (1 << 3)
|
||||
#define TARGET_LOW_ISSUE_RATE (target_flags & TARGET_LOW_ISSUE_RATE_MASK)
|
||||
|
||||
/* Change branch cost */
|
||||
#define TARGET_BRANCH_COST_MASK (1 << 4)
|
||||
|
@ -187,9 +187,9 @@ extern int target_flags;
|
|||
{ "align-loops", TARGET_ALIGN_LOOPS_MASK, \
|
||||
N_("Align all loops to 32 byte boundary") }, \
|
||||
{ "no-align-loops", -TARGET_ALIGN_LOOPS_MASK, "" }, \
|
||||
{ "issue-rate=1", TARGET_ISSUE_RATE_MASK, \
|
||||
{ "issue-rate=1", TARGET_LOW_ISSUE_RATE_MASK, \
|
||||
N_("Only issue one instruction per cycle") }, \
|
||||
{ "issue-rate=2", -TARGET_ISSUE_RATE_MASK, "" }, \
|
||||
{ "issue-rate=2", -TARGET_LOW_ISSUE_RATE_MASK, "" }, \
|
||||
{ "branch-cost=1", TARGET_BRANCH_COST_MASK, \
|
||||
N_("Prefer branches over conditional execution") }, \
|
||||
{ "branch-cost=2", -TARGET_BRANCH_COST_MASK, "" }, \
|
||||
|
@ -1473,59 +1473,6 @@ do { \
|
|||
register. */
|
||||
#define NO_RECURSIVE_FUNCTION_CSE
|
||||
|
||||
/* A C statement (sans semicolon) to update the integer variable COST based on
|
||||
the relationship between INSN that is dependent on DEP_INSN through the
|
||||
dependence LINK. The default is to make no adjustment to COST. This can be
|
||||
used for example to specify to the scheduler that an output- or
|
||||
anti-dependence does not incur the same cost as a data-dependence. */
|
||||
|
||||
#define ADJUST_COST(INSN,LINK,DEP_INSN,COST) \
|
||||
(COST) = m32r_adjust_cost (INSN, LINK, DEP_INSN, COST)
|
||||
|
||||
/* A C statement (sans semicolon) to update the integer scheduling
|
||||
priority `INSN_PRIORITY(INSN)'. Reduce the priority to execute
|
||||
the INSN earlier, increase the priority to execute INSN later.
|
||||
Do not define this macro if you do not need to adjust the
|
||||
scheduling priorities of insns. */
|
||||
#define ADJUST_PRIORITY(INSN) \
|
||||
INSN_PRIORITY (INSN) = m32r_adjust_priority (INSN, INSN_PRIORITY (INSN))
|
||||
|
||||
/* Macro to determine whether the Haifa scheduler is used. */
|
||||
#ifdef HAIFA
|
||||
#define HAIFA_P 1
|
||||
#else
|
||||
#define HAIFA_P 0
|
||||
#endif
|
||||
|
||||
/* Indicate how many instructions can be issued at the same time.
|
||||
This is sort of a lie. The m32r can issue only 1 long insn at
|
||||
once, but it can issue 2 short insns. The default therefore is
|
||||
set at 2, but this can be overridden by the command line option
|
||||
-missue-rate=1 */
|
||||
#define ISSUE_RATE ((TARGET_ISSUE_RATE) ? 1 : 2)
|
||||
|
||||
/* If we have a machine that can issue a variable # of instructions
|
||||
per cycle, indicate how many more instructions can be issued
|
||||
after the current one. */
|
||||
#define MD_SCHED_VARIABLE_ISSUE(STREAM, VERBOSE, INSN, HOW_MANY) \
|
||||
(HOW_MANY) = m32r_sched_variable_issue (STREAM, VERBOSE, INSN, HOW_MANY)
|
||||
|
||||
/* Whether we are on an odd word boundary while scheduling. */
|
||||
extern int m32r_sched_odd_word_p;
|
||||
|
||||
/* Hook to run before scheduling a block of insns. */
|
||||
#define MD_SCHED_INIT(STREAM, VERBOSE, MAX_READY) \
|
||||
m32r_sched_init (STREAM, VERBOSE)
|
||||
|
||||
/* Hook to reorder the list of ready instructions. */
|
||||
#define MD_SCHED_REORDER(STREAM, VERBOSE, READY, N_READY, CLOCK, CIM) \
|
||||
do \
|
||||
{ \
|
||||
m32r_sched_reorder (STREAM, VERBOSE, READY, N_READY); \
|
||||
CIM = issue_rate; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* When the `length' insn attribute is used, this macro specifies the
|
||||
value to be assigned to the address of the first insn in a
|
||||
function. If not specified, 0 is used. */
|
||||
|
|
|
@ -72,6 +72,8 @@ static void m88k_output_function_begin_epilogue PARAMS ((FILE *));
|
|||
static void m88k_svr3_asm_out_constructor PARAMS ((rtx, int));
|
||||
static void m88k_svr3_asm_out_destructor PARAMS ((rtx, int));
|
||||
#endif
|
||||
|
||||
static int m88k_adjust_cost PARAMS ((rtx, rtx, rtx, int));
|
||||
|
||||
/* Initialize the GCC target structure. */
|
||||
#undef TARGET_ASM_FUNCTION_PROLOGUE
|
||||
|
@ -83,6 +85,9 @@ static void m88k_svr3_asm_out_destructor PARAMS ((rtx, int));
|
|||
#undef TARGET_ASM_FUNCTION_EPILOGUE
|
||||
#define TARGET_ASM_FUNCTION_EPILOGUE m88k_output_function_epilogue
|
||||
|
||||
#undef TARGET_SCHED_ADJUST_COST
|
||||
#define TARGET_SCHED_ADJUST_COST m88k_adjust_cost
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
/* Determine what instructions are needed to manufacture the integer VALUE
|
||||
|
@ -3316,3 +3321,30 @@ m88k_svr3_asm_out_destructor (symbol, priority)
|
|||
assemble_integer (constm1_rtx, UNITS_PER_WORD, BITS_PER_WORD, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Adjust the cost of INSN based on the relationship between INSN that
|
||||
is dependent on DEP_INSN through the dependence LINK. The default
|
||||
is to make no adjustment to COST.
|
||||
|
||||
On the m88k, ignore the cost of anti- and output-dependencies. On
|
||||
the m88100, a store can issue two cycles before the value (not the
|
||||
address) has finished computing. */
|
||||
|
||||
static int
|
||||
m88k_adjust_cost (insn, link, dep, cost)
|
||||
rtx insn;
|
||||
rtx link;
|
||||
rtx dep;
|
||||
int cost;
|
||||
{
|
||||
if (REG_NOTE_KIND (link) != 0)
|
||||
return 0; /* Anti or output dependence. */
|
||||
|
||||
if (! TARGET_88100
|
||||
&& recog_memoized (insn) >= 0
|
||||
&& get_attr_type (insn) == TYPE_STORE
|
||||
&& SET_SRC (PATTERN (insn)) == SET_DEST (PATTERN (dep)))
|
||||
return cost - 4; /* 88110 store reservation station. */
|
||||
|
||||
return cost;
|
||||
}
|
||||
|
|
|
@ -1638,23 +1638,6 @@ enum reg_class { NO_REGS, AP_REG, XRF_REGS, GENERAL_REGS, AGRF_REGS,
|
|||
/* Provide the cost of a branch. Exact meaning under development. */
|
||||
#define BRANCH_COST (TARGET_88100 ? 1 : 2)
|
||||
|
||||
/* A C statement (sans semicolon) to update the integer variable COST
|
||||
based on the relationship between INSN that is dependent on
|
||||
DEP_INSN through the dependence LINK. The default is to make no
|
||||
adjustment to COST. On the m88k, ignore the cost of anti- and
|
||||
output-dependencies. On the m88100, a store can issue two cycles
|
||||
before the value (not the address) has finished computing. */
|
||||
#define ADJUST_COST(INSN,LINK,DEP_INSN,COST) \
|
||||
do { \
|
||||
if (REG_NOTE_KIND (LINK) != 0) \
|
||||
(COST) = 0; /* Anti or output dependence. */ \
|
||||
else if (! TARGET_88100 \
|
||||
&& recog_memoized (INSN) >= 0 \
|
||||
&& get_attr_type (INSN) == TYPE_STORE \
|
||||
&& SET_SRC (PATTERN (INSN)) == SET_DEST (PATTERN (DEP_INSN))) \
|
||||
(COST) -= 4; /* 88110 store reservation station. */ \
|
||||
} while (0)
|
||||
|
||||
/* Do not break .stabs pseudos into continuations. */
|
||||
#define DBX_CONTIN_LENGTH 0
|
||||
|
||||
|
|
|
@ -126,6 +126,7 @@ static int iris_section_align_entry_eq PARAMS ((const PTR, const PTR));
|
|||
static hashval_t iris_section_align_entry_hash PARAMS ((const PTR));
|
||||
static int iris6_section_align_1 PARAMS ((void **, void *));
|
||||
#endif
|
||||
static int mips_adjust_cost PARAMS ((rtx, rtx, rtx, int));
|
||||
|
||||
/* Global variables for machine-dependent things. */
|
||||
|
||||
|
@ -455,6 +456,9 @@ enum reg_class mips_char_to_class[256] =
|
|||
#undef TARGET_ASM_FUNCTION_EPILOGUE
|
||||
#define TARGET_ASM_FUNCTION_EPILOGUE mips_output_function_epilogue
|
||||
|
||||
#undef TARGET_SCHED_ADJUST_COST
|
||||
#define TARGET_SCHED_ADJUST_COST mips_adjust_cost
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
/* Return truth value of whether OP can be used as an operands
|
||||
|
@ -9743,6 +9747,23 @@ mips_parse_cpu (cpu_string)
|
|||
return cpu;
|
||||
}
|
||||
|
||||
/* Adjust the cost of INSN based on the relationship between INSN that
|
||||
is dependent on DEP_INSN through the dependence LINK. The default
|
||||
is to make no adjustment to COST.
|
||||
|
||||
On the MIPS, ignore the cost of anti- and output-dependencies. */
|
||||
static int
|
||||
mips_adjust_cost (insn, link, dep, cost)
|
||||
rtx insn ATTRIBUTE_UNUSED;
|
||||
rtx link;
|
||||
rtx dep ATTRIBUTE_UNUSED;
|
||||
int cost;
|
||||
{
|
||||
if (REG_NOTE_KIND (link) != 0)
|
||||
return 0; /* Anti or output dependence. */
|
||||
return cost;
|
||||
}
|
||||
|
||||
/* Cover function for UNIQUE_SECTION. */
|
||||
|
||||
void
|
||||
|
@ -9815,6 +9836,7 @@ mips_unique_section (decl, reloc)
|
|||
|
||||
DECL_SECTION_NAME (decl) = build_string (len, string);
|
||||
}
|
||||
|
||||
|
||||
#ifdef TARGET_IRIX6
|
||||
/* Output assembly to switch to section NAME with attribute FLAGS. */
|
||||
|
|
|
@ -3688,16 +3688,6 @@ while (0)
|
|||
&& (TUNE_MIPS4000 || TUNE_MIPS6000)) \
|
||||
? 2 : 1)
|
||||
|
||||
/* A C statement (sans semicolon) to update the integer variable COST
|
||||
based on the relationship between INSN that is dependent on
|
||||
DEP_INSN through the dependence LINK. The default is to make no
|
||||
adjustment to COST. On the MIPS, ignore the cost of anti- and
|
||||
output-dependencies. */
|
||||
|
||||
#define ADJUST_COST(INSN,LINK,DEP_INSN,COST) \
|
||||
if (REG_NOTE_KIND (LINK) != 0) \
|
||||
(COST) = 0; /* Anti or output dependence. */
|
||||
|
||||
/* If defined, modifies the length assigned to instruction INSN as a
|
||||
function of the context in which it is used. LENGTH is an lvalue
|
||||
that contains the initially computed length of the insn and should
|
||||
|
|
|
@ -66,7 +66,6 @@ extern int arith11_operand PARAMS ((rtx, enum machine_mode));
|
|||
extern int symbolic_expression_p PARAMS ((rtx));
|
||||
extern int hppa_address_cost PARAMS ((rtx));
|
||||
extern int symbolic_memory_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int pa_adjust_cost PARAMS ((rtx, rtx, rtx, int));
|
||||
extern int pa_adjust_insn_length PARAMS ((rtx, int));
|
||||
extern int int11_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int reg_or_cint_move_operand PARAMS ((rtx, enum machine_mode));
|
||||
|
|
|
@ -69,6 +69,9 @@ static rtx store_reg PARAMS ((int, int, int));
|
|||
static rtx load_reg PARAMS ((int, int, int));
|
||||
static rtx set_reg_plus_d PARAMS ((int, int, int));
|
||||
static void pa_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
|
||||
static int pa_adjust_cost PARAMS ((rtx, rtx, rtx, int));
|
||||
static int pa_adjust_priority PARAMS ((rtx, int));
|
||||
static int pa_issue_rate PARAMS ((void));
|
||||
|
||||
/* Save the operands last given to a compare for use when we
|
||||
generate a scc or bcc insn. */
|
||||
|
@ -115,6 +118,13 @@ int n_deferred_plabels = 0;
|
|||
#undef TARGET_ASM_FUNCTION_EPILOGUE
|
||||
#define TARGET_ASM_FUNCTION_EPILOGUE pa_output_function_epilogue
|
||||
|
||||
#undef TARGET_SCHED_ADJUST_COST
|
||||
#define TARGET_SCHED_ADJUST_COST pa_adjust_cost
|
||||
#undef TARGET_SCHED_ADJUST_PRIORITY
|
||||
#define TARGET_SCHED_ADJUST_PRIORITY pa_adjust_priority
|
||||
#undef TARGET_SCHED_ISSUE_RATE
|
||||
#define TARGET_SCHED_ISSUE_RATE pa_issue_rate
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
void
|
||||
|
@ -3591,7 +3601,7 @@ gen_cmp_fp (code, operand0, operand1)
|
|||
/* Adjust the cost of a scheduling dependency. Return the new cost of
|
||||
a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
|
||||
|
||||
int
|
||||
static int
|
||||
pa_adjust_cost (insn, link, dep_insn, cost)
|
||||
rtx insn;
|
||||
rtx link;
|
||||
|
@ -3829,6 +3839,60 @@ pa_adjust_cost (insn, link, dep_insn, cost)
|
|||
abort ();
|
||||
}
|
||||
|
||||
/* Adjust scheduling priorities. We use this to try and keep addil
|
||||
and the next use of %r1 close together. */
|
||||
static int
|
||||
pa_adjust_priority (insn, priority)
|
||||
rtx insn;
|
||||
int priority;
|
||||
{
|
||||
rtx set = single_set (insn);
|
||||
rtx src, dest;
|
||||
if (set)
|
||||
{
|
||||
src = SET_SRC (set);
|
||||
dest = SET_DEST (set);
|
||||
if (GET_CODE (src) == LO_SUM
|
||||
&& symbolic_operand (XEXP (src, 1), VOIDmode)
|
||||
&& ! read_only_operand (XEXP (src, 1), VOIDmode))
|
||||
priority >>= 3;
|
||||
|
||||
else if (GET_CODE (src) == MEM
|
||||
&& GET_CODE (XEXP (src, 0)) == LO_SUM
|
||||
&& symbolic_operand (XEXP (XEXP (src, 0), 1), VOIDmode)
|
||||
&& ! read_only_operand (XEXP (XEXP (src, 0), 1), VOIDmode))
|
||||
priority >>= 1;
|
||||
|
||||
else if (GET_CODE (dest) == MEM
|
||||
&& GET_CODE (XEXP (dest, 0)) == LO_SUM
|
||||
&& symbolic_operand (XEXP (XEXP (dest, 0), 1), VOIDmode)
|
||||
&& ! read_only_operand (XEXP (XEXP (dest, 0), 1), VOIDmode))
|
||||
priority >>= 3;
|
||||
}
|
||||
return priority;
|
||||
}
|
||||
|
||||
/* The 700 can only issue a single insn at a time.
|
||||
The 7XXX processors can issue two insns at a time.
|
||||
The 8000 can issue 4 insns at a time. */
|
||||
static int
|
||||
pa_issue_rate ()
|
||||
{
|
||||
switch (pa_cpu)
|
||||
{
|
||||
case PROCESSOR_700: return 1;
|
||||
case PROCESSOR_7100: return 2;
|
||||
case PROCESSOR_7100LC: return 2;
|
||||
case PROCESSOR_7200: return 2;
|
||||
case PROCESSOR_8000: return 4;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Return any length adjustment needed by INSN which already has its length
|
||||
computed as LENGTH. Return zero if no adjustment is necessary.
|
||||
|
||||
|
|
|
@ -50,17 +50,6 @@ extern enum processor_type pa_cpu;
|
|||
|
||||
#define pa_cpu_attr ((enum attr_cpu)pa_cpu)
|
||||
|
||||
/* The 700 can only issue a single insn at a time.
|
||||
The 7XXX processors can issue two insns at a time.
|
||||
The 8000 can issue 4 insns at a time. */
|
||||
#define ISSUE_RATE \
|
||||
(pa_cpu == PROCESSOR_700 ? 1 \
|
||||
: pa_cpu == PROCESSOR_7100 ? 2 \
|
||||
: pa_cpu == PROCESSOR_7100LC ? 2 \
|
||||
: pa_cpu == PROCESSOR_7200 ? 2 \
|
||||
: pa_cpu == PROCESSOR_8000 ? 4 \
|
||||
: 2)
|
||||
|
||||
/* Which architecture to generate code for. */
|
||||
|
||||
enum architecture_type
|
||||
|
@ -1651,38 +1640,6 @@ while (0)
|
|||
/* Adjust the cost of branches. */
|
||||
#define BRANCH_COST (pa_cpu == PROCESSOR_8000 ? 2 : 1)
|
||||
|
||||
/* Adjust the cost of dependencies. */
|
||||
|
||||
#define ADJUST_COST(INSN,LINK,DEP,COST) \
|
||||
(COST) = pa_adjust_cost (INSN, LINK, DEP, COST)
|
||||
|
||||
/* Adjust scheduling priorities. We use this to try and keep addil
|
||||
and the next use of %r1 close together. */
|
||||
#define ADJUST_PRIORITY(PREV) \
|
||||
{ \
|
||||
rtx set = single_set (PREV); \
|
||||
rtx src, dest; \
|
||||
if (set) \
|
||||
{ \
|
||||
src = SET_SRC (set); \
|
||||
dest = SET_DEST (set); \
|
||||
if (GET_CODE (src) == LO_SUM \
|
||||
&& symbolic_operand (XEXP (src, 1), VOIDmode) \
|
||||
&& ! read_only_operand (XEXP (src, 1), VOIDmode)) \
|
||||
INSN_PRIORITY (PREV) >>= 3; \
|
||||
else if (GET_CODE (src) == MEM \
|
||||
&& GET_CODE (XEXP (src, 0)) == LO_SUM \
|
||||
&& symbolic_operand (XEXP (XEXP (src, 0), 1), VOIDmode)\
|
||||
&& ! read_only_operand (XEXP (XEXP (src, 0), 1), VOIDmode))\
|
||||
INSN_PRIORITY (PREV) >>= 1; \
|
||||
else if (GET_CODE (dest) == MEM \
|
||||
&& GET_CODE (XEXP (dest, 0)) == LO_SUM \
|
||||
&& symbolic_operand (XEXP (XEXP (dest, 0), 1), VOIDmode)\
|
||||
&& ! read_only_operand (XEXP (XEXP (dest, 0), 1), VOIDmode))\
|
||||
INSN_PRIORITY (PREV) >>= 3; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Handling the special cases is going to get too complicated for a macro,
|
||||
just call `pa_adjust_insn_length' to do the real work. */
|
||||
#define ADJUST_INSN_LENGTH(INSN, LENGTH) \
|
||||
|
|
|
@ -103,8 +103,6 @@ extern rtx rs6000_emit_set_const PARAMS ((rtx, enum machine_mode, rtx, int));
|
|||
extern int rs6000_emit_cmove PARAMS ((rtx, rtx, rtx, rtx));
|
||||
extern void rs6000_emit_minmax PARAMS ((rtx, enum rtx_code, rtx, rtx));
|
||||
extern void output_toc PARAMS ((FILE *, rtx, int, enum machine_mode));
|
||||
extern int rs6000_adjust_cost PARAMS ((rtx, rtx, rtx, int));
|
||||
extern int rs6000_adjust_priority PARAMS ((rtx, int));
|
||||
extern void rs6000_initialize_trampoline PARAMS ((rtx, rtx, rtx));
|
||||
extern struct rtx_def *rs6000_longcall_ref PARAMS ((rtx));
|
||||
extern void rs6000_fatal_bad_address PARAMS ((rtx));
|
||||
|
@ -157,7 +155,6 @@ extern void rs6000_file_start PARAMS ((FILE *, const char *));
|
|||
extern struct rtx_def *rs6000_float_const PARAMS ((const char *,
|
||||
enum machine_mode));
|
||||
extern int direct_return PARAMS ((void));
|
||||
extern int get_issue_rate PARAMS ((void));
|
||||
extern union tree_node *rs6000_build_va_list PARAMS ((void));
|
||||
extern int first_reg_to_save PARAMS ((void));
|
||||
extern int first_fp_reg_to_save PARAMS ((void));
|
||||
|
|
|
@ -141,6 +141,10 @@ static void rs6000_elf_asm_out_destructor PARAMS ((rtx, int));
|
|||
#ifdef OBJECT_FORMAT_COFF
|
||||
static void xcoff_asm_named_section PARAMS ((const char *, unsigned int));
|
||||
#endif
|
||||
static int rs6000_adjust_cost PARAMS ((rtx, rtx, rtx, int));
|
||||
static int rs6000_adjust_priority PARAMS ((rtx, int));
|
||||
static int rs6000_issue_rate PARAMS ((void));
|
||||
|
||||
|
||||
/* Default register names. */
|
||||
char rs6000_reg_names[][8] =
|
||||
|
@ -193,6 +197,13 @@ static char alt_reg_names[][8] =
|
|||
#define TARGET_SECTION_TYPE_FLAGS rs6000_elf_section_type_flags
|
||||
#endif
|
||||
|
||||
#undef TARGET_SCHED_ISSUE_RATE
|
||||
#define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
|
||||
#undef TARGET_SCHED_ADJUST_COST
|
||||
#define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
|
||||
#undef TARGET_SCHED_ADJUST_PRIORITY
|
||||
#define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
/* Override command line options. Mostly we process the processor
|
||||
|
@ -7874,7 +7885,7 @@ output_function_profiler (file, labelno)
|
|||
/* Adjust the cost of a scheduling dependency. Return the new cost of
|
||||
a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
|
||||
|
||||
int
|
||||
static int
|
||||
rs6000_adjust_cost (insn, link, dep_insn, cost)
|
||||
rtx insn;
|
||||
rtx link;
|
||||
|
@ -7910,7 +7921,7 @@ rs6000_adjust_cost (insn, link, dep_insn, cost)
|
|||
increase the priority to execute INSN later. Do not define this macro if
|
||||
you do not need to adjust the scheduling priorities of insns. */
|
||||
|
||||
int
|
||||
static int
|
||||
rs6000_adjust_priority (insn, priority)
|
||||
rtx insn ATTRIBUTE_UNUSED;
|
||||
int priority;
|
||||
|
@ -7949,7 +7960,8 @@ rs6000_adjust_priority (insn, priority)
|
|||
}
|
||||
|
||||
/* Return how many instructions the machine can issue per cycle */
|
||||
int get_issue_rate()
|
||||
static int
|
||||
rs6000_issue_rate ()
|
||||
{
|
||||
switch (rs6000_cpu_attr) {
|
||||
case CPU_RIOS1: /* ? */
|
||||
|
|
|
@ -812,24 +812,6 @@ extern int rs6000_debug_arg; /* debug argument handling */
|
|||
|
||||
#define BRANCH_COST 3
|
||||
|
||||
/* A C statement (sans semicolon) to update the integer variable COST
|
||||
based on the relationship between INSN that is dependent on
|
||||
DEP_INSN through the dependence LINK. The default is to make no
|
||||
adjustment to COST. On the RS/6000, ignore the cost of anti- and
|
||||
output-dependencies. In fact, output dependencies on the CR do have
|
||||
a cost, but it is probably not worthwhile to track it. */
|
||||
|
||||
#define ADJUST_COST(INSN, LINK, DEP_INSN, COST) \
|
||||
(COST) = rs6000_adjust_cost (INSN,LINK,DEP_INSN,COST)
|
||||
|
||||
/* A C statement (sans semicolon) to update the integer scheduling priority
|
||||
INSN_PRIORITY (INSN). Reduce the priority to execute the INSN earlier,
|
||||
increase the priority to execute INSN later. Do not define this macro if
|
||||
you do not need to adjust the scheduling priorities of insns. */
|
||||
|
||||
#define ADJUST_PRIORITY(INSN) \
|
||||
INSN_PRIORITY (INSN) = rs6000_adjust_priority (INSN, INSN_PRIORITY (INSN))
|
||||
|
||||
/* Define this macro to change register usage conditional on target flags.
|
||||
Set MQ register fixed (already call_used) if not POWER architecture
|
||||
(RIOS1, RIOS2, RSC, and PPC601) so that it will not be allocated.
|
||||
|
@ -2632,10 +2614,6 @@ do { \
|
|||
/* #define MACHINE_no_sched_speculative */
|
||||
/* #define MACHINE_no_sched_speculative_load */
|
||||
|
||||
/* indicate that issue rate is defined for this machine
|
||||
(no need to use the default) */
|
||||
#define ISSUE_RATE get_issue_rate ()
|
||||
|
||||
/* General flags. */
|
||||
extern int flag_pic;
|
||||
extern int optimize;
|
||||
|
|
|
@ -53,7 +53,6 @@ extern void emit_pic_move PARAMS ((rtx *, enum machine_mode));
|
|||
extern void s390_output_symbolic_const PARAMS ((FILE *, rtx));
|
||||
extern void print_operand_address PARAMS ((FILE *, rtx));
|
||||
extern void print_operand PARAMS ((FILE *, rtx, int));
|
||||
extern int s390_adjust_cost PARAMS ((rtx, rtx, rtx, int));
|
||||
extern int s390_stop_dump_lit_p PARAMS ((rtx));
|
||||
extern void s390_dump_literal_pool PARAMS ((rtx, rtx));
|
||||
extern void s390_trampoline_template PARAMS ((FILE *));
|
||||
|
|
|
@ -45,6 +45,7 @@ Boston, MA 02111-1307, USA. */
|
|||
#include "debug.h"
|
||||
|
||||
|
||||
static int s390_adjust_cost PARAMS ((rtx, rtx, rtx, int));
|
||||
|
||||
#undef TARGET_ASM_FUNCTION_PROLOGUE
|
||||
#define TARGET_ASM_FUNCTION_PROLOGUE s390_function_prologue
|
||||
|
@ -58,6 +59,9 @@ Boston, MA 02111-1307, USA. */
|
|||
#undef TARGET_ASM_CLOSE_PAREN
|
||||
#define TARGET_ASM_CLOSE_PAREN ""
|
||||
|
||||
#undef TARGET_SCHED_ADJUST_COST
|
||||
#define TARGET_SCHED_ADJUST_COST s390_adjust_cost
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
extern int reload_completed;
|
||||
|
@ -1585,7 +1589,7 @@ addr_generation_dependency_p (dep_rtx, insn)
|
|||
register of a memory reference, at least 4 cycles need to pass
|
||||
between setting and using the register to avoid pipeline stalls. */
|
||||
|
||||
int
|
||||
static int
|
||||
s390_adjust_cost (insn, link, dep_insn, cost)
|
||||
rtx insn;
|
||||
rtx link;
|
||||
|
|
|
@ -1743,17 +1743,6 @@ extern struct rtx_def *s390_compare_op0, *s390_compare_op1;
|
|||
{"tmxx_operand", { CONST_INT, MEM }},
|
||||
|
||||
|
||||
/* A C statement (sans semicolon) to update the integer variable COST
|
||||
based on the relationship between INSN that is dependent on
|
||||
DEP_INSN through the dependence LINK. The default is to make no
|
||||
adjustment to COST. This can be used for example to specify to
|
||||
the scheduler that an output- or anti-dependence does not incur
|
||||
the same cost as a data-dependence. */
|
||||
|
||||
#define ADJUST_COST(insn, link, dep_insn, cost) \
|
||||
(cost) = s390_adjust_cost (insn, link, dep_insn, cost)
|
||||
|
||||
|
||||
/* Constant Pool for all symbols operands which are changed with
|
||||
force_const_mem during insn generation (expand_insn). */
|
||||
|
||||
|
|
|
@ -158,6 +158,7 @@ static int sh_valid_decl_attribute PARAMS ((tree, tree, tree, tree));
|
|||
static void sh_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
|
||||
static void sh_insert_attributes PARAMS ((tree, tree *));
|
||||
static void sh_asm_named_section PARAMS ((const char *, unsigned int));
|
||||
static int sh_adjust_cost PARAMS ((rtx, rtx, rtx, int));
|
||||
|
||||
/* Initialize the GCC target structure. */
|
||||
#undef TARGET_VALID_DECL_ATTRIBUTE
|
||||
|
@ -169,6 +170,9 @@ static void sh_asm_named_section PARAMS ((const char *, unsigned int));
|
|||
#undef TARGET_INSERT_ATTRIBUTES
|
||||
#define TARGET_INSERT_ATTRIBUTES sh_insert_attributes
|
||||
|
||||
#undef TARGET_SCHED_ADJUST_COST
|
||||
#define TARGET_SCHED_ADJUST_COST sh_adjust_cost
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
/* Print the operand address in x to the stream. */
|
||||
|
@ -5566,3 +5570,61 @@ sh_asm_named_section (name, flags)
|
|||
/* ??? Perhaps we should be using default_coff_asm_named_section. */
|
||||
fprintf (asm_out_file, "\t.section %s\n", name);
|
||||
}
|
||||
|
||||
/* A C statement (sans semicolon) to update the integer variable COST
|
||||
based on the relationship between INSN that is dependent on
|
||||
DEP_INSN through the dependence LINK. The default is to make no
|
||||
adjustment to COST. This can be used for example to specify to
|
||||
the scheduler that an output- or anti-dependence does not incur
|
||||
the same cost as a data-dependence. */
|
||||
static int
|
||||
sh_adjust_cost (insn, link, dep_insn, cost)
|
||||
rtx insn;
|
||||
rtx link;
|
||||
rtx dep_insn;
|
||||
int cost;
|
||||
{
|
||||
rtx reg;
|
||||
|
||||
if (GET_CODE(insn) == CALL_INSN)
|
||||
{
|
||||
/* The only input for a call that is timing-critical is the
|
||||
function's address. */
|
||||
rtx call = PATTERN (insn);
|
||||
|
||||
if (GET_CODE (call) == PARALLEL)
|
||||
call = XVECEXP (call, 0 ,0);
|
||||
if (GET_CODE (call) == SET)
|
||||
call = SET_SRC (call);
|
||||
if (GET_CODE (call) == CALL && GET_CODE (XEXP (call, 0)) == MEM
|
||||
&& ! reg_set_p (XEXP (XEXP (call, 0), 0), dep_insn))
|
||||
cost = 0;
|
||||
}
|
||||
/* All sfunc calls are parallels with at least four components.
|
||||
Exploit this to avoid unnecessary calls to sfunc_uses_reg. */
|
||||
else if (GET_CODE (PATTERN (insn)) == PARALLEL
|
||||
&& XVECLEN (PATTERN (insn), 0) >= 4
|
||||
&& (reg = sfunc_uses_reg (insn)))
|
||||
{
|
||||
/* Likewise, the most timing critical input for an sfuncs call
|
||||
is the function address. However, sfuncs typically start
|
||||
using their arguments pretty quickly.
|
||||
Assume a four cycle delay before they are needed. */
|
||||
if (! reg_set_p (reg, dep_insn))
|
||||
cost -= TARGET_SUPERSCALAR ? 40 : 4;
|
||||
}
|
||||
/* Adjust load_si / pcload_si type insns latency. Use the known
|
||||
nominal latency and form of the insn to speed up the check. */
|
||||
else if (cost == 3
|
||||
&& GET_CODE (PATTERN (dep_insn)) == SET
|
||||
/* Latency for dmpy type insns is also 3, so check the that
|
||||
it's actually a move insn. */
|
||||
&& general_movsrc_operand (SET_SRC (PATTERN (dep_insn)), SImode))
|
||||
cost = 2;
|
||||
else if (cost == 30
|
||||
&& GET_CODE (PATTERN (dep_insn)) == SET
|
||||
&& GET_MODE (SET_SRC (PATTERN (dep_insn))) == SImode)
|
||||
cost = 20;
|
||||
|
||||
return cost;
|
||||
}
|
||||
|
|
|
@ -2321,58 +2321,6 @@ extern struct rtx_def *fpscr_rtx;
|
|||
clear if this would give better code. If implemented, should check for
|
||||
compatibility problems. */
|
||||
|
||||
/* A C statement (sans semicolon) to update the integer variable COST
|
||||
based on the relationship between INSN that is dependent on
|
||||
DEP_INSN through the dependence LINK. The default is to make no
|
||||
adjustment to COST. This can be used for example to specify to
|
||||
the scheduler that an output- or anti-dependence does not incur
|
||||
the same cost as a data-dependence. */
|
||||
|
||||
#define ADJUST_COST(insn,link,dep_insn,cost) \
|
||||
do { \
|
||||
rtx reg; \
|
||||
\
|
||||
if (GET_CODE(insn) == CALL_INSN) \
|
||||
{ \
|
||||
/* The only input for a call that is timing-critical is the \
|
||||
function's address. */ \
|
||||
rtx call = PATTERN (insn); \
|
||||
\
|
||||
if (GET_CODE (call) == PARALLEL) \
|
||||
call = XVECEXP (call, 0 ,0); \
|
||||
if (GET_CODE (call) == SET) \
|
||||
call = SET_SRC (call); \
|
||||
if (GET_CODE (call) == CALL && GET_CODE (XEXP (call, 0)) == MEM \
|
||||
&& ! reg_set_p (XEXP (XEXP (call, 0), 0), dep_insn)) \
|
||||
(cost) = 0; \
|
||||
} \
|
||||
/* All sfunc calls are parallels with at least four components. \
|
||||
Exploit this to avoid unnecessary calls to sfunc_uses_reg. */ \
|
||||
else if (GET_CODE (PATTERN (insn)) == PARALLEL \
|
||||
&& XVECLEN (PATTERN (insn), 0) >= 4 \
|
||||
&& (reg = sfunc_uses_reg (insn))) \
|
||||
{ \
|
||||
/* Likewise, the most timing critical input for an sfuncs call \
|
||||
is the function address. However, sfuncs typically start \
|
||||
using their arguments pretty quickly. \
|
||||
Assume a four cycle delay before they are needed. */ \
|
||||
if (! reg_set_p (reg, dep_insn)) \
|
||||
cost -= TARGET_SUPERSCALAR ? 40 : 4; \
|
||||
} \
|
||||
/* Adjust load_si / pcload_si type insns latency. Use the known \
|
||||
nominal latency and form of the insn to speed up the check. */ \
|
||||
else if (cost == 3 \
|
||||
&& GET_CODE (PATTERN (dep_insn)) == SET \
|
||||
/* Latency for dmpy type insns is also 3, so check the that \
|
||||
it's actually a move insn. */ \
|
||||
&& general_movsrc_operand (SET_SRC (PATTERN (dep_insn)), SImode))\
|
||||
cost = 2; \
|
||||
else if (cost == 30 \
|
||||
&& GET_CODE (PATTERN (dep_insn)) == SET \
|
||||
&& GET_MODE (SET_SRC (PATTERN (dep_insn))) == SImode) \
|
||||
cost = 20; \
|
||||
} while (0) \
|
||||
|
||||
#define SH_DYNAMIC_SHIFT_COST \
|
||||
(TARGET_HARD_SH4 ? 1 : TARGET_SH3 ? (TARGET_SMALLCODE ? 1 : 2) : 20)
|
||||
|
||||
|
|
|
@ -50,14 +50,12 @@ extern enum direction function_arg_padding PARAMS ((enum machine_mode, tree));
|
|||
#endif /* ARGS_SIZE_RTX */
|
||||
#endif /* TREE_CODE */
|
||||
|
||||
extern void ultrasparc_sched_init PARAMS ((FILE *, int));
|
||||
extern void load_pic_register PARAMS ((void));
|
||||
extern void order_regs_for_local_alloc PARAMS ((void));
|
||||
extern int compute_frame_size PARAMS ((int, int));
|
||||
extern int check_pic PARAMS ((int));
|
||||
extern int short_branch PARAMS ((int, int));
|
||||
extern int sparc_flat_epilogue_delay_slots PARAMS ((void));
|
||||
extern int sparc_issue_rate PARAMS ((void));
|
||||
extern unsigned long sparc_flat_compute_frame_size PARAMS ((int));
|
||||
extern void sparc_function_profiler PARAMS ((FILE *, int));
|
||||
extern void sparc_function_block_profiler PARAMS ((FILE *, int));
|
||||
|
@ -81,8 +79,6 @@ extern int gen_v9_scc PARAMS ((enum rtx_code, rtx *));
|
|||
extern void sparc_initialize_trampoline PARAMS ((rtx, rtx, rtx));
|
||||
extern void sparc64_initialize_trampoline PARAMS ((rtx, rtx, rtx));
|
||||
extern rtx legitimize_pic_address PARAMS ((rtx, enum machine_mode, rtx));
|
||||
extern void ultrasparc_sched_reorder PARAMS ((FILE *, int, rtx *, int));
|
||||
extern int ultrasparc_variable_issue PARAMS ((rtx));
|
||||
extern void sparc_defer_case_vector PARAMS ((rtx, rtx, int));
|
||||
extern void sparc_emit_set_const32 PARAMS ((rtx, rtx));
|
||||
extern void sparc_emit_set_const64 PARAMS ((rtx, rtx));
|
||||
|
@ -115,7 +111,6 @@ extern int reg_unused_after PARAMS ((rtx, rtx));
|
|||
extern int register_ok_for_ldd PARAMS ((rtx));
|
||||
extern int registers_ok_for_ldd_peep PARAMS ((rtx, rtx));
|
||||
extern int sparc_flat_eligible_for_epilogue_delay PARAMS ((rtx, int));
|
||||
extern int sparc_adjust_cost PARAMS ((rtx, rtx, rtx, int));
|
||||
extern int v9_regcmp_p PARAMS ((enum rtx_code));
|
||||
extern char *sparc_v8plus_shift PARAMS ((rtx *, rtx, const char *));
|
||||
/* Function used for V8+ code generation. Returns 1 if the high
|
||||
|
|
|
@ -168,6 +168,16 @@ static void sparc_nonflat_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT,
|
|||
static void sparc_nonflat_function_prologue PARAMS ((FILE *, HOST_WIDE_INT,
|
||||
int));
|
||||
static void sparc_elf_asm_named_section PARAMS ((const char *, unsigned int));
|
||||
|
||||
static void ultrasparc_sched_reorder PARAMS ((FILE *, int, rtx *, int));
|
||||
static int ultrasparc_variable_issue PARAMS ((rtx));
|
||||
static void ultrasparc_sched_init PARAMS ((void));
|
||||
|
||||
static int sparc_adjust_cost PARAMS ((rtx, rtx, rtx, int));
|
||||
static int sparc_issue_rate PARAMS ((void));
|
||||
static int sparc_variable_issue PARAMS ((FILE *, int, rtx, int));
|
||||
static void sparc_sched_init PARAMS ((FILE *, int, int));
|
||||
static int sparc_sched_reorder PARAMS ((FILE *, int, rtx *, int *, int));
|
||||
|
||||
/* Option handling. */
|
||||
|
||||
|
@ -196,6 +206,17 @@ enum processor_type sparc_cpu;
|
|||
#undef TARGET_ASM_FUNCTION_EPILOGUE
|
||||
#define TARGET_ASM_FUNCTION_EPILOGUE sparc_output_function_epilogue
|
||||
|
||||
#undef TARGET_SCHED_ADJUST_COST
|
||||
#define TARGET_SCHED_ADJUST_COST sparc_adjust_cost
|
||||
#undef TARGET_SCHED_ISSUE_RATE
|
||||
#define TARGET_SCHED_ISSUE_RATE sparc_issue_rate
|
||||
#undef TARGET_SCHED_VARIABLE_ISSUE
|
||||
#define TARGET_SCHED_VARIABLE_ISSUE sparc_variable_issue
|
||||
#undef TARGET_SCHED_INIT
|
||||
#define TARGET_SCHED_INIT sparc_sched_init
|
||||
#undef TARGET_SCHED_REORDER
|
||||
#define TARGET_SCHED_REORDER sparc_sched_reorder
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
/* Validate and override various options, and do some machine dependent
|
||||
|
@ -7299,7 +7320,7 @@ ultrasparc_adjust_cost (insn, link, dep_insn, cost)
|
|||
#undef SLOW_FP
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
sparc_adjust_cost(insn, link, dep, cost)
|
||||
rtx insn;
|
||||
rtx link;
|
||||
|
@ -7680,10 +7701,8 @@ ultra_flush_pipeline ()
|
|||
}
|
||||
|
||||
/* Init our data structures for this current block. */
|
||||
void
|
||||
ultrasparc_sched_init (dump, sched_verbose)
|
||||
FILE *dump ATTRIBUTE_UNUSED;
|
||||
int sched_verbose ATTRIBUTE_UNUSED;
|
||||
static void
|
||||
ultrasparc_sched_init ()
|
||||
{
|
||||
memset ((char *) ultra_pipe_hist, 0, sizeof ultra_pipe_hist);
|
||||
ultra_cur_hist = 0;
|
||||
|
@ -7691,10 +7710,20 @@ ultrasparc_sched_init (dump, sched_verbose)
|
|||
ultra_pipe.free_slot_mask = 0xf;
|
||||
}
|
||||
|
||||
static void
|
||||
sparc_sched_init (dump, sched_verbose, max_ready)
|
||||
FILE *dump ATTRIBUTE_UNUSED;
|
||||
int sched_verbose ATTRIBUTE_UNUSED;
|
||||
int max_ready ATTRIBUTE_UNUSED;
|
||||
{
|
||||
if (sparc_cpu == PROCESSOR_ULTRASPARC)
|
||||
ultrasparc_sched_init ();
|
||||
}
|
||||
|
||||
/* INSN has been scheduled, update pipeline commit state
|
||||
and return how many instructions are still to be
|
||||
scheduled in this group. */
|
||||
int
|
||||
static int
|
||||
ultrasparc_variable_issue (insn)
|
||||
rtx insn;
|
||||
{
|
||||
|
@ -7718,6 +7747,19 @@ ultrasparc_variable_issue (insn)
|
|||
return left_to_fire;
|
||||
}
|
||||
|
||||
static int
|
||||
sparc_variable_issue (dump, sched_verbose, insn, cim)
|
||||
FILE *dump ATTRIBUTE_UNUSED;
|
||||
int sched_verbose ATTRIBUTE_UNUSED;
|
||||
rtx insn;
|
||||
int cim;
|
||||
{
|
||||
if (sparc_cpu == PROCESSOR_ULTRASPARC)
|
||||
return ultrasparc_variable_issue (INSN);
|
||||
else
|
||||
return cim - 1;
|
||||
}
|
||||
|
||||
/* In actual_hazard_this_instance, we may have yanked some
|
||||
instructions from the ready list due to conflict cost
|
||||
adjustments. If so, and such an insn was in our pipeline
|
||||
|
@ -7767,7 +7809,7 @@ ultra_rescan_pipeline_state (ready, n_ready)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
ultrasparc_sched_reorder (dump, sched_verbose, ready, n_ready)
|
||||
FILE *dump;
|
||||
int sched_verbose;
|
||||
|
@ -8053,7 +8095,20 @@ ultrasparc_sched_reorder (dump, sched_verbose, ready, n_ready)
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
sparc_sched_reorder (dump, sched_verbose, ready, n_readyp, clock)
|
||||
FILE *dump;
|
||||
int sched_verbose;
|
||||
rtx *ready;
|
||||
int *n_readyp;
|
||||
int clock;
|
||||
{
|
||||
if (sparc_cpu == PROCESSOR_ULTRASPARC)
|
||||
ultrasparc_sched_reorder (dump, sched_verbose, ready, *n_readyp);
|
||||
return sparc_issue_rate ();
|
||||
}
|
||||
|
||||
static int
|
||||
sparc_issue_rate ()
|
||||
{
|
||||
switch (sparc_cpu)
|
||||
|
|
|
@ -2865,31 +2865,6 @@ do { \
|
|||
case FIX: \
|
||||
return 19;
|
||||
|
||||
#define ISSUE_RATE sparc_issue_rate()
|
||||
|
||||
/* Adjust the cost of dependencies. */
|
||||
#define ADJUST_COST(INSN,LINK,DEP,COST) \
|
||||
(COST) = sparc_adjust_cost(INSN, LINK, DEP, COST)
|
||||
|
||||
#define MD_SCHED_INIT(DUMP, SCHED_VERBOSE, MAX_READY) \
|
||||
if (sparc_cpu == PROCESSOR_ULTRASPARC) \
|
||||
ultrasparc_sched_init (DUMP, SCHED_VERBOSE)
|
||||
|
||||
#define MD_SCHED_REORDER(DUMP, SCHED_VERBOSE, READY, N_READY, CLOCK, CIM) \
|
||||
do { \
|
||||
if (sparc_cpu == PROCESSOR_ULTRASPARC) \
|
||||
ultrasparc_sched_reorder (DUMP, SCHED_VERBOSE, READY, N_READY); \
|
||||
CIM = issue_rate; \
|
||||
} while (0)
|
||||
|
||||
#define MD_SCHED_VARIABLE_ISSUE(DUMP, SCHED_VERBOSE, INSN, CAN_ISSUE_MORE) \
|
||||
do { \
|
||||
if (sparc_cpu == PROCESSOR_ULTRASPARC) \
|
||||
(CAN_ISSUE_MORE) = ultrasparc_variable_issue (INSN); \
|
||||
else \
|
||||
(CAN_ISSUE_MORE)--; \
|
||||
} while (0)
|
||||
|
||||
/* Conditional branches with empty delay slots have a length of two. */
|
||||
#define ADJUST_INSN_LENGTH(INSN, LENGTH) \
|
||||
do { \
|
||||
|
|
268
gcc/doc/tm.texi
268
gcc/doc/tm.texi
|
@ -41,6 +41,7 @@ through the macros defined in the @file{.h} file.
|
|||
* Addressing Modes:: Defining addressing modes valid for memory operands.
|
||||
* Condition Code:: Defining how insns update the condition code.
|
||||
* Costs:: Defining relative costs of different operations.
|
||||
* Scheduling:: Adjusting the behavior of the instruction scheduler.
|
||||
* Sections:: Dividing storage into text, data, and other sections.
|
||||
* PIC:: Macros for position independent code.
|
||||
* Assembler Format:: Defining how to write insns and pseudo-ops to output.
|
||||
|
@ -465,8 +466,8 @@ standard choice of @file{/usr/local/include} as the default prefix to
|
|||
try when searching for local header files. @code{LOCAL_INCLUDE_DIR}
|
||||
comes before @code{SYSTEM_INCLUDE_DIR} in the search order.
|
||||
|
||||
Cross compilers do not use this macro and do not search either
|
||||
@file{/usr/local/include} or its replacement.
|
||||
Cross compilers do not search either @file{/usr/local/include} or its
|
||||
replacement.
|
||||
|
||||
@findex MODIFY_TARGET_NAME
|
||||
@item MODIFY_TARGET_NAME
|
||||
|
@ -1735,19 +1736,18 @@ preserve the entire contents of a register across a call.
|
|||
@item CONDITIONAL_REGISTER_USAGE
|
||||
Zero or more C statements that may conditionally modify five variables
|
||||
@code{fixed_regs}, @code{call_used_regs}, @code{global_regs},
|
||||
(these three are of type @code{char []}), @code{reg_names} (of type
|
||||
@code{const char * []}) and @code{reg_class_contents} (of type
|
||||
@code{HARD_REG_SET}).
|
||||
Before the macro is called @code{fixed_regs}, @code{call_used_regs}
|
||||
@code{reg_class_contents} and @code{reg_names} have been initialized
|
||||
@code{reg_names}, and @code{reg_class_contents}, to take into account
|
||||
any dependence of these register sets on target flags. The first three
|
||||
of these are of type @code{char []} (interpreted as Boolean vectors).
|
||||
@code{global_regs} is a @code{const char *[]}, and
|
||||
@code{reg_class_contents} is a @code{HARD_REG_SET}. Before the macro is
|
||||
called, @code{fixed_regs}, @code{call_used_regs},
|
||||
@code{reg_class_contents}, and @code{reg_names} have been initialized
|
||||
from @code{FIXED_REGISTERS}, @code{CALL_USED_REGISTERS},
|
||||
@code{REG_CLASS_CONTENTS} and @code{REGISTER_NAMES}, respectively,
|
||||
@code{REG_CLASS_CONTENTS}, and @code{REGISTER_NAMES}, respectively.
|
||||
@code{global_regs} has been cleared, and any @option{-ffixed-@var{reg}},
|
||||
@option{-fcall-used-@var{reg}} and @option{-fcall-saved-@var{reg}} command
|
||||
options have been applied.
|
||||
|
||||
This is necessary in case the fixed or call-clobbered registers depend
|
||||
on target flags.
|
||||
@option{-fcall-used-@var{reg}} and @option{-fcall-saved-@var{reg}}
|
||||
command options have been applied.
|
||||
|
||||
You need not define this macro if it has no work to do.
|
||||
|
||||
|
@ -2025,11 +2025,11 @@ this.
|
|||
|
||||
@findex current_function_is_leaf
|
||||
@findex current_function_uses_only_leaf_regs
|
||||
Normally, @code{TARGET_ASM_FUNCTION_PROLOGUE} and
|
||||
@code{TARGET_ASM_FUNCTION_EPILOGUE} must treat leaf functions specially.
|
||||
They can test the C variable @code{current_function_is_leaf} which is
|
||||
nonzero for leaf functions. @code{current_function_is_leaf} is set
|
||||
prior to local register allocation and is valid for the remaining
|
||||
@code{TARGET_ASM_FUNCTION_PROLOGUE} and
|
||||
@code{TARGET_ASM_FUNCTION_EPILOGUE} must usually treat leaf functions
|
||||
specially. They can test the C variable @code{current_function_is_leaf}
|
||||
which is nonzero for leaf functions. @code{current_function_is_leaf} is
|
||||
set prior to local register allocation and is valid for the remaining
|
||||
compiler passes. They can also test the C variable
|
||||
@code{current_function_uses_only_leaf_regs} which is nonzero for leaf
|
||||
functions which only use leaf registers.
|
||||
|
@ -2528,8 +2528,7 @@ This describes the stack layout and calling conventions.
|
|||
* Caller Saves::
|
||||
* Function Entry::
|
||||
* Profiling::
|
||||
* Inlining::
|
||||
* Tail Calling::
|
||||
* Inlining and Tail Calls::
|
||||
@end menu
|
||||
|
||||
@node Frame Layout
|
||||
|
@ -4205,27 +4204,22 @@ profiling when the frame pointer is omitted.
|
|||
|
||||
@end table
|
||||
|
||||
@node Inlining
|
||||
@subsection Permitting inlining of functions with attributes
|
||||
@node Inlining and Tail Calls
|
||||
@subsection Permitting inlining and tail calls
|
||||
@cindex inlining
|
||||
|
||||
By default if a function has a target specific attribute attached to it,
|
||||
it will not be inlined. This behaviour can be overridden if the target
|
||||
defines the @samp{FUNCTION_ATTRIBUTE_INLINABLE_P} macro. This macro
|
||||
takes one argument, a @samp{DECL} describing the function. It should
|
||||
return non-zero if the function can be inlined, otherwise it should
|
||||
return 0.
|
||||
|
||||
@node Tail Calling
|
||||
@subsection Permitting tail calls to functions
|
||||
@cindex tail calls
|
||||
@cindex sibling calls
|
||||
|
||||
@table @code
|
||||
@findex FUNCTION_ATTRIBUTE_INLINABLE_P
|
||||
@item FUNCTION_ATTRIBUTE_INLINABLE_P (@var{decl})
|
||||
A C expression that evaluates to true if it is ok to inline @var{decl}
|
||||
into the current function, despite its having target-specific
|
||||
attributes. By default, if a function has a target specific attribute
|
||||
attached to it, it will not be inlined.
|
||||
|
||||
@findex FUNCTION_OK_FOR_SIBCALL
|
||||
@item FUNCTION_OK_FOR_SIBCALL (@var{decl})
|
||||
A C expression that evaluates to true if it is ok to perform a sibling
|
||||
call to @var{decl}.
|
||||
call to @var{decl} from the current function.
|
||||
|
||||
It is not uncommon for limitations of calling conventions to prevent
|
||||
tail calls to functions outside the current unit of translation, or
|
||||
|
@ -5441,25 +5435,108 @@ function address than to call an address kept in a register.
|
|||
Define this macro if it is as good or better for a function to call
|
||||
itself with an explicit address than to call an address kept in a
|
||||
register.
|
||||
|
||||
@findex ADJUST_COST
|
||||
@item ADJUST_COST (@var{insn}, @var{link}, @var{dep_insn}, @var{cost})
|
||||
A C statement (sans semicolon) to update the integer variable @var{cost}
|
||||
based on the relationship between @var{insn} that is dependent on
|
||||
@var{dep_insn} through the dependence @var{link}. The default is to
|
||||
make no adjustment to @var{cost}. This can be used for example to
|
||||
specify to the scheduler that an output- or anti-dependence does not
|
||||
incur the same cost as a data-dependence.
|
||||
|
||||
@findex ADJUST_PRIORITY
|
||||
@item ADJUST_PRIORITY (@var{insn})
|
||||
A C statement (sans semicolon) to update the integer scheduling
|
||||
priority @code{INSN_PRIORITY(@var{insn})}. Reduce the priority
|
||||
to execute the @var{insn} earlier, increase the priority to execute
|
||||
@var{insn} later. Do not define this macro if you do not need to
|
||||
adjust the scheduling priorities of insns.
|
||||
@end table
|
||||
|
||||
@node Scheduling
|
||||
@section Adjusting the Instruction Scheduler
|
||||
|
||||
The instruction scheduler may need a fair amount of machine-specific
|
||||
adjustment in order to produce good code. GCC provides several target
|
||||
hooks for this purpose. It is usually enough to define just a few of
|
||||
them: try the first ones in this list first.
|
||||
|
||||
@deftypefn {Target Hook} int TARGET_SCHED_ISSUE_RATE (void)
|
||||
This hook returns the maximum number of instructions that can ever issue
|
||||
at the same time on the target machine. The default is one. This value
|
||||
must be constant over the entire compilation. If you need it to vary
|
||||
depending on what the instructions are, you must use
|
||||
@samp{TARGET_SCHED_VARIABLE_ISSUE}.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Target Hook} int TARGET_SCHED_VARIABLE_ISSUE (FILE *@var{file}, int @var{verbose}, rtx @var{insn}, int @var{more})
|
||||
This hook is executed by the scheduler after it has scheduled an insn
|
||||
from the ready list. It should return the number of insns which can
|
||||
still be issued in the current cycle. Normally this is
|
||||
@samp{@w{@var{more} - 1}}. You should define this hook if some insns
|
||||
take more machine resources than others, so that fewer insns can follow
|
||||
them in the same cycle. @var{file} is either a null pointer, or a stdio
|
||||
stream to write any debug output to. @var{verbose} is the verbose level
|
||||
provided by @option{-fsched-verbose-@var{n}}. @var{insn} is the
|
||||
instruction that was scheduled.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Target Hook} int TARGET_SCHED_ADJUST_COST (rtx @var{insn}, rtx @var{link}, rtx @var{dep_insn}, int @var{cost})
|
||||
This function corrects the value of @var{cost} based on the relationship
|
||||
between @var{insn} and @var{dep_insn} through the dependence @var{link}.
|
||||
It should return the new value. The default is to make no adjustment to
|
||||
@var{cost}. This can be used for example to specify to the scheduler
|
||||
that an output- or anti-dependence does not incur the same cost as a
|
||||
data-dependence.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Target Hook} int TARGET_SCHED_ADJUST_PRIORITY (rtx @var{insn}, int @var{priority})
|
||||
This hook adjusts the integer scheduling priority @var{priority} of
|
||||
@var{insn}. It should return the new priority. Reduce the priority to
|
||||
execute @var{insn} earlier, increase the priority to execute @var{insn}
|
||||
later. Do not define this hook if you do not need to adjust the
|
||||
scheduling priorities of insns.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Target Hook} int TARGET_SCHED_REORDER (FILE *@var{file}, int @var{verbose}, rtx *@var{ready}, int *@var{n_readyp}, int @var{clock})
|
||||
This hook is executed by the scheduler after it has scheduled the ready
|
||||
list, to allow the machine description to reorder it (for example to
|
||||
combine two small instructions together on @samp{VLIW} machines).
|
||||
@var{file} is either a null pointer, or a stdio stream to write any
|
||||
debug output to. @var{verbose} is the verbose level provided by
|
||||
@option{-fsched-verbose-@var{n}}. @var{ready} is a pointer to the ready
|
||||
list of instructions that are ready to be scheduled. @var{n_readyp} is
|
||||
a pointer to the number of elements in the ready list. The scheduler
|
||||
reads the ready list in reverse order, starting with
|
||||
@var{ready}[@var{*n_readyp}-1] and going to @var{ready}[0]. @var{clock}
|
||||
is the timer tick of the scheduler. You may modify the ready list and
|
||||
the number of ready insns. The return value is the number of insns that
|
||||
can issue this cycle; normally this is just @code{issue_rate}. See also
|
||||
@samp{TARGET_SCHED_REORDER2}.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Target Hook} int TARGET_SCHED_REORDER2 (FILE *@var{file}, int @var{verbose}, rtx *@var{ready}, int *@var{n_ready}, @var{clock})
|
||||
Like @samp{TARGET_SCHED_REORDER}, but called at a different time. That
|
||||
function is called whenever the scheduler starts a new cycle. This one
|
||||
is called once per iteration over a cycle, immediately after
|
||||
@samp{TARGET_SCHED_VARIABLE_ISSUE}; it can reorder the ready list and
|
||||
return the number of insns to be scheduled in the same cycle. Defining
|
||||
this hook can be useful if there are frequent situations where
|
||||
scheduling one insn causes other insns to become ready in the same
|
||||
cycle. These other insns can then be taken into account properly.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Target Hook} void TARGET_SCHED_INIT (FILE *@var{file}, int @var{verbose}, int @var{max_ready})
|
||||
This hook is executed by the scheduler at the beginning of each block of
|
||||
instructions that are to be scheduled. @var{file} is either a null
|
||||
pointer, or a stdio stream to write any debug output to. @var{verbose}
|
||||
is the verbose level provided by @option{-fsched-verbose-@var{n}}.
|
||||
@var{max_ready} is the maximum number of insns in the current scheduling
|
||||
region that can be live at the same time. This can be used to allocate
|
||||
scratch space if it is needed, e.g. by @samp{TARGET_SCHED_REORDER}.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Target Hook} void TARGET_SCHED_FINISH (FILE *@var{file}, int @var{verbose})
|
||||
This hook is executed by the scheduler at the end of each block of
|
||||
instructions that are to be scheduled. It can be used to perform
|
||||
cleanup of any actions done by the other scheduling hooks. @var{file}
|
||||
is either a null pointer, or a stdio stream to write any debug output
|
||||
to. @var{verbose} is the verbose level provided by
|
||||
@option{-fsched-verbose-@var{n}}.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Target Hook} rtx TARGET_SCHED_CYCLE_DISPLAY (int @var{clock}, rtx @var{last})
|
||||
This hook is called in verbose mode only, at the beginning of each pass
|
||||
over a basic block. It should insert an insn into the chain after
|
||||
@var{last}, which has no effect, but records the value @var{clock} in
|
||||
RTL dumps and assembly output. Define this hook only if you need this
|
||||
level of detail about what the scheduler is doing.
|
||||
@end deftypefn
|
||||
|
||||
@node Sections
|
||||
@section Dividing the Output into Sections (Texts, Data, @dots{})
|
||||
@c the above section title is WAY too long. maybe cut the part between
|
||||
|
@ -6932,12 +7009,17 @@ numeric index of the assembler language dialect to use, with zero as the
|
|||
first variant.
|
||||
|
||||
If this macro is defined, you may use constructs of the form
|
||||
@samp{@{option0|option1|option2@dots{}@}} in the output
|
||||
templates of patterns (@pxref{Output Template}) or in the first argument
|
||||
of @code{asm_fprintf}. This construct outputs @samp{option0},
|
||||
@samp{option1} or @samp{option2}, etc., if the value of
|
||||
@code{ASSEMBLER_DIALECT} is zero, one or two, etc. Any special
|
||||
characters within these strings retain their usual meaning.
|
||||
@smallexample
|
||||
@samp{@{option0|option1|option2@dots{}@}}
|
||||
@end smallexample
|
||||
@noindent
|
||||
in the output templates of patterns (@pxref{Output Template}) or in the
|
||||
first argument of @code{asm_fprintf}. This construct outputs
|
||||
@samp{option0}, @samp{option1}, @samp{option2}, etc., if the value of
|
||||
@code{ASSEMBLER_DIALECT} is zero, one, two, etc. Any special characters
|
||||
within these strings retain their usual meaning. If there are fewer
|
||||
alternatives within the braces than the value of
|
||||
@code{ASSEMBLER_DIALECT}, the construct outputs nothing.
|
||||
|
||||
If you do not define this macro, the characters @samp{@{}, @samp{|} and
|
||||
@samp{@}} do not have any special meaning when used in templates or
|
||||
|
@ -8312,8 +8394,8 @@ The primary reason to define this macro is to provide compatibility with
|
|||
other compilers for the same target. In general, we discourage
|
||||
definition of target-specific pragmas for GCC@.
|
||||
|
||||
If the pragma can be implemented by attributes then the macro
|
||||
@samp{INSERT_ATTRIBUTES} might be a useful one to define as well.
|
||||
If the pragma can be implemented by attributes then you should consider
|
||||
defining @samp{INSERT_ATTRIBUTES} as well.
|
||||
|
||||
Preprocessor macros that appear on pragma lines are not expanded. All
|
||||
@samp{#pragma} directives that do not match any registered pragma are
|
||||
|
@ -8561,68 +8643,6 @@ symbols must be explicitly imported from shared libraries (DLLs).
|
|||
A C statement that adds to @var{clobbers} @code{STRING_CST} trees for
|
||||
any hard regs the port wishes to automatically clobber for all asms.
|
||||
|
||||
@findex ISSUE_RATE
|
||||
@item ISSUE_RATE
|
||||
A C expression that returns how many instructions can be issued at the
|
||||
same time if the machine is a superscalar machine.
|
||||
|
||||
@findex MD_SCHED_INIT
|
||||
@item MD_SCHED_INIT (@var{file}, @var{verbose}, @var{max_ready})
|
||||
A C statement which is executed by the scheduler at the
|
||||
beginning of each block of instructions that are to be scheduled.
|
||||
@var{file} is either a null pointer, or a stdio stream to write any
|
||||
debug output to. @var{verbose} is the verbose level provided by
|
||||
@option{-fsched-verbose-@var{n}}. @var{max_ready} is the maximum number
|
||||
of insns in the current scheduling region that can be live at the same
|
||||
time. This can be used to allocate scratch space if it is needed.
|
||||
|
||||
@findex MD_SCHED_FINISH
|
||||
@item MD_SCHED_FINISH (@var{file}, @var{verbose})
|
||||
A C statement which is executed by the scheduler at the end of each block
|
||||
of instructions that are to be scheduled. It can be used to perform
|
||||
cleanup of any actions done by the other scheduling macros.
|
||||
@var{file} is either a null pointer, or a stdio stream to write any
|
||||
debug output to. @var{verbose} is the verbose level provided by
|
||||
@option{-fsched-verbose-@var{n}}.
|
||||
|
||||
@findex MD_SCHED_REORDER
|
||||
@item MD_SCHED_REORDER (@var{file}, @var{verbose}, @var{ready}, @var{n_ready}, @var{clock}, @var{can_issue_more})
|
||||
A C statement which is executed by the scheduler after it
|
||||
has scheduled the ready list to allow the machine description to reorder
|
||||
it (for example to combine two small instructions together on
|
||||
@samp{VLIW} machines). @var{file} is either a null pointer, or a stdio
|
||||
stream to write any debug output to. @var{verbose} is the verbose level
|
||||
provided by @option{-fsched-verbose-@var{n}}. @var{ready} is a pointer to
|
||||
the ready list of instructions that are ready to be scheduled.
|
||||
@var{n_ready} is the number of elements in the ready list. The
|
||||
scheduler reads the ready list in reverse order, starting with
|
||||
@var{ready}[@var{n_ready}-1] and going to @var{ready}[0]. @var{clock}
|
||||
is the timer tick of the scheduler. @var{can_issue_more} is an output
|
||||
parameter that is set to the number of insns that can issue this clock;
|
||||
normally this is just @code{issue_rate}. See also @samp{MD_SCHED_REORDER2}.
|
||||
|
||||
@findex MD_SCHED_REORDER2
|
||||
@item MD_SCHED_REORDER2 (@var{file}, @var{verbose}, @var{ready}, @var{n_ready}, @var{clock}, @var{can_issue_more})
|
||||
Like @samp{MD_SCHED_REORDER}, but called at a different time. While the
|
||||
@samp{MD_SCHED_REORDER} macro is called whenever the scheduler starts a
|
||||
new cycle, this macro is used immediately after @samp{MD_SCHED_VARIABLE_ISSUE}
|
||||
is called; it can reorder the ready list and set @var{can_issue_more} to
|
||||
determine whether there are more insns to be scheduled in the same cycle.
|
||||
Defining this macro can be useful if there are frequent situations where
|
||||
scheduling one insn causes other insns to become ready in the same cycle,
|
||||
these other insns can then be taken into account properly.
|
||||
|
||||
@findex MD_SCHED_VARIABLE_ISSUE
|
||||
@item MD_SCHED_VARIABLE_ISSUE (@var{file}, @var{verbose}, @var{insn}, @var{more})
|
||||
A C statement which is executed by the scheduler after it
|
||||
has scheduled an insn from the ready list. @var{file} is either a null
|
||||
pointer, or a stdio stream to write any debug output to. @var{verbose}
|
||||
is the verbose level provided by @option{-fsched-verbose-@var{n}}.
|
||||
@var{insn} is the instruction that was scheduled. @var{more} is the
|
||||
number of instructions that can be issued in the current cycle. The
|
||||
@samp{MD_SCHED_VARIABLE_ISSUE} macro is responsible for updating the
|
||||
value of @var{more} (typically by @samp{@var{more}--}).
|
||||
|
||||
@findex MAX_INTEGER_COMPUTATION_MODE
|
||||
@item MAX_INTEGER_COMPUTATION_MODE
|
||||
Define this to the largest integer machine mode which can be used for
|
||||
|
@ -8688,6 +8708,7 @@ converting code to conditional execution in the basic blocks
|
|||
A C expression to cancel any machine dependent modifications in
|
||||
converting code to conditional execution in the basic blocks
|
||||
@code{TEST_BB}, @code{THEN_BB}, @code{ELSE_BB}, and @code{JOIN_BB}.
|
||||
@end table
|
||||
|
||||
@deftypefn {Target Hook} void TARGET_INIT_BUILTINS ()
|
||||
Define this hook if you have any machine-specific built-in functions
|
||||
|
@ -8702,7 +8723,7 @@ instructions or prefetch instructions).
|
|||
To create a built-in function, call the function @code{builtin_function}
|
||||
which is defined by the language front end. You can use any type nodes set
|
||||
up by @code{build_common_tree_nodes} and @code{build_common_tree_nodes_2};
|
||||
only language front ends that use these two functions will use
|
||||
only language front ends that use those two functions will call
|
||||
@samp{TARGET_INIT_BUILTINS}.
|
||||
@end deftypefn
|
||||
|
||||
|
@ -8718,6 +8739,7 @@ ignored. This function should return the result of the call to the
|
|||
built-in function.
|
||||
@end deftypefn
|
||||
|
||||
@table @code
|
||||
@findex MD_CAN_REDIRECT_BRANCH
|
||||
@item MD_CAN_REDIRECT_BRANCH(@var{branch1}, @var{branch2})
|
||||
|
||||
|
|
|
@ -148,6 +148,7 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
#include "toplev.h"
|
||||
#include "recog.h"
|
||||
#include "sched-int.h"
|
||||
#include "target.h"
|
||||
|
||||
#ifdef INSN_SCHEDULING
|
||||
|
||||
|
@ -157,10 +158,6 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
|
||||
static int issue_rate;
|
||||
|
||||
#ifndef ISSUE_RATE
|
||||
#define ISSUE_RATE 1
|
||||
#endif
|
||||
|
||||
/* sched-verbose controls the amount of debugging output the
|
||||
scheduler prints. It is controlled by -fsched-verbose=N:
|
||||
N>0 and no -DSR : the output is directed to stderr.
|
||||
|
@ -693,12 +690,10 @@ insn_cost (insn, link, used)
|
|||
|
||||
if (LINK_COST_FREE (link))
|
||||
cost = 0;
|
||||
#ifdef ADJUST_COST
|
||||
else if (!LINK_COST_ZERO (link))
|
||||
else if (!LINK_COST_ZERO (link) && targetm.sched.adjust_cost)
|
||||
{
|
||||
int ncost = cost;
|
||||
int ncost = (*targetm.sched.adjust_cost) (used, link, insn, cost);
|
||||
|
||||
ADJUST_COST (used, link, insn, ncost);
|
||||
if (ncost < 1)
|
||||
{
|
||||
LINK_COST_FREE (link) = 1;
|
||||
|
@ -708,7 +703,7 @@ insn_cost (insn, link, used)
|
|||
LINK_COST_ZERO (link) = 1;
|
||||
cost = ncost;
|
||||
}
|
||||
#endif
|
||||
|
||||
return cost;
|
||||
}
|
||||
|
||||
|
@ -952,7 +947,7 @@ ready_sort (ready)
|
|||
|
||||
HAIFA_INLINE static void
|
||||
adjust_priority (prev)
|
||||
rtx prev ATTRIBUTE_UNUSED;
|
||||
rtx prev;
|
||||
{
|
||||
/* ??? There used to be code here to try and estimate how an insn
|
||||
affected register lifetimes, but it did it by looking at REG_DEAD
|
||||
|
@ -961,9 +956,9 @@ adjust_priority (prev)
|
|||
|
||||
Revisit when we have a machine model to work with and not before. */
|
||||
|
||||
#ifdef ADJUST_PRIORITY
|
||||
ADJUST_PRIORITY (prev);
|
||||
#endif
|
||||
if (targetm.sched.adjust_priority)
|
||||
INSN_PRIORITY (prev) =
|
||||
(*targetm.sched.adjust_priority) (prev, INSN_PRIORITY (prev));
|
||||
}
|
||||
|
||||
/* Clock at which the previous instruction was issued. */
|
||||
|
@ -1668,16 +1663,15 @@ schedule_block (b, rgn_n_insns)
|
|||
clear_units ();
|
||||
|
||||
/* Allocate the ready list. */
|
||||
ready.veclen = rgn_n_insns + 1 + ISSUE_RATE;
|
||||
ready.veclen = rgn_n_insns + 1 + issue_rate;
|
||||
ready.first = ready.veclen - 1;
|
||||
ready.vec = (rtx *) xmalloc (ready.veclen * sizeof (rtx));
|
||||
ready.n_ready = 0;
|
||||
|
||||
(*current_sched_info->init_ready_list) (&ready);
|
||||
|
||||
#ifdef MD_SCHED_INIT
|
||||
MD_SCHED_INIT (sched_dump, sched_verbose, ready.veclen);
|
||||
#endif
|
||||
if (targetm.sched.md_init)
|
||||
(*targetm.sched.md_init) (sched_dump, sched_verbose, ready.veclen);
|
||||
|
||||
/* No insns scheduled in this block yet. */
|
||||
last_scheduled_insn = 0;
|
||||
|
@ -1706,10 +1700,8 @@ schedule_block (b, rgn_n_insns)
|
|||
list. */
|
||||
queue_to_ready (&ready);
|
||||
|
||||
#ifdef HAVE_cycle_display
|
||||
if (HAVE_cycle_display)
|
||||
last = emit_insn_after (gen_cycle_display (GEN_INT (clock_var)), last);
|
||||
#endif
|
||||
if (sched_verbose && targetm.sched.cycle_display)
|
||||
last = (*targetm.sched.cycle_display) (clock_var, last);
|
||||
|
||||
if (ready.n_ready == 0)
|
||||
abort ();
|
||||
|
@ -1725,12 +1717,13 @@ schedule_block (b, rgn_n_insns)
|
|||
|
||||
/* Allow the target to reorder the list, typically for
|
||||
better instruction bundling. */
|
||||
#ifdef MD_SCHED_REORDER
|
||||
MD_SCHED_REORDER (sched_dump, sched_verbose, ready_lastpos (&ready),
|
||||
ready.n_ready, clock_var, can_issue_more);
|
||||
#else
|
||||
can_issue_more = issue_rate;
|
||||
#endif
|
||||
if (targetm.sched.reorder)
|
||||
can_issue_more =
|
||||
(*targetm.sched.reorder) (sched_dump, sched_verbose,
|
||||
ready_lastpos (&ready),
|
||||
&ready.n_ready, clock_var);
|
||||
else
|
||||
can_issue_more = issue_rate;
|
||||
|
||||
if (sched_verbose)
|
||||
{
|
||||
|
@ -1759,25 +1752,27 @@ schedule_block (b, rgn_n_insns)
|
|||
last_scheduled_insn = insn;
|
||||
last = move_insn (insn, last);
|
||||
|
||||
#ifdef MD_SCHED_VARIABLE_ISSUE
|
||||
MD_SCHED_VARIABLE_ISSUE (sched_dump, sched_verbose, insn,
|
||||
can_issue_more);
|
||||
#else
|
||||
can_issue_more--;
|
||||
#endif
|
||||
if (targetm.sched.variable_issue)
|
||||
can_issue_more =
|
||||
(*targetm.sched.variable_issue) (sched_dump, sched_verbose,
|
||||
insn, can_issue_more);
|
||||
else
|
||||
can_issue_more--;
|
||||
|
||||
schedule_insn (insn, &ready, clock_var);
|
||||
|
||||
next:
|
||||
;
|
||||
#ifdef MD_SCHED_REORDER2
|
||||
/* Sort the ready list based on priority. */
|
||||
if (ready.n_ready > 0)
|
||||
ready_sort (&ready);
|
||||
MD_SCHED_REORDER2 (sched_dump, sched_verbose,
|
||||
ready.n_ready ? ready_lastpos (&ready) : NULL,
|
||||
ready.n_ready, clock_var, can_issue_more);
|
||||
#endif
|
||||
if (targetm.sched.reorder2)
|
||||
{
|
||||
/* Sort the ready list based on priority. */
|
||||
if (ready.n_ready > 0)
|
||||
ready_sort (&ready);
|
||||
can_issue_more =
|
||||
(*targetm.sched.reorder2) (sched_dump,sched_verbose,
|
||||
ready.n_ready
|
||||
? ready_lastpos (&ready) : NULL,
|
||||
&ready.n_ready, clock_var);
|
||||
}
|
||||
}
|
||||
|
||||
/* Debug info. */
|
||||
|
@ -1785,9 +1780,8 @@ schedule_block (b, rgn_n_insns)
|
|||
visualize_scheduled_insns (clock_var);
|
||||
}
|
||||
|
||||
#ifdef MD_SCHED_FINISH
|
||||
MD_SCHED_FINISH (sched_dump, sched_verbose);
|
||||
#endif
|
||||
if (targetm.sched.md_finish)
|
||||
(*targetm.sched.md_finish) (sched_dump, sched_verbose);
|
||||
|
||||
/* Debug info. */
|
||||
if (sched_verbose)
|
||||
|
@ -1896,7 +1890,10 @@ sched_init (dump_file)
|
|||
? stderr : dump_file);
|
||||
|
||||
/* Initialize issue_rate. */
|
||||
issue_rate = ISSUE_RATE;
|
||||
if (targetm.sched.issue_rate)
|
||||
issue_rate = (*targetm.sched.issue_rate) ();
|
||||
else
|
||||
issue_rate = 1;
|
||||
|
||||
/* We use LUID 0 for the fake insn (UID 0) which holds dependencies for
|
||||
pseudos which do not cross calls. */
|
||||
|
|
|
@ -82,6 +82,28 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
TARGET_ASM_CONSTRUCTOR, \
|
||||
TARGET_ASM_DESTRUCTOR}
|
||||
|
||||
/* Scheduler hooks. All of these default to null pointers, which
|
||||
haifa-sched.c looks for and handles. */
|
||||
#define TARGET_SCHED_ADJUST_COST 0
|
||||
#define TARGET_SCHED_ADJUST_PRIORITY 0
|
||||
#define TARGET_SCHED_ISSUE_RATE 0
|
||||
#define TARGET_SCHED_VARIABLE_ISSUE 0
|
||||
#define TARGET_SCHED_INIT 0
|
||||
#define TARGET_SCHED_FINISH 0
|
||||
#define TARGET_SCHED_REORDER 0
|
||||
#define TARGET_SCHED_REORDER2 0
|
||||
#define TARGET_SCHED_CYCLE_DISPLAY 0
|
||||
|
||||
#define TARGET_SCHED {TARGET_SCHED_ADJUST_COST, \
|
||||
TARGET_SCHED_ADJUST_PRIORITY, \
|
||||
TARGET_SCHED_ISSUE_RATE, \
|
||||
TARGET_SCHED_VARIABLE_ISSUE, \
|
||||
TARGET_SCHED_INIT, \
|
||||
TARGET_SCHED_FINISH, \
|
||||
TARGET_SCHED_REORDER, \
|
||||
TARGET_SCHED_REORDER2, \
|
||||
TARGET_SCHED_CYCLE_DISPLAY}
|
||||
|
||||
/* All in tree.c. */
|
||||
#define TARGET_MERGE_DECL_ATTRIBUTES merge_decl_attributes
|
||||
#define TARGET_MERGE_TYPE_ATTRIBUTES merge_type_attributes
|
||||
|
@ -104,6 +126,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define TARGET_INITIALIZER \
|
||||
{ \
|
||||
TARGET_ASM_OUT, \
|
||||
TARGET_SCHED, \
|
||||
TARGET_MERGE_DECL_ATTRIBUTES, \
|
||||
TARGET_MERGE_TYPE_ATTRIBUTES, \
|
||||
TARGET_VALID_DECL_ATTRIBUTE, \
|
||||
|
|
54
gcc/target.h
54
gcc/target.h
|
@ -44,9 +44,6 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
to gradually reduce the amount of conditional compilation that is
|
||||
scattered throughout GCC. */
|
||||
|
||||
/* Forward declaration for the benefit of prototypes. */
|
||||
struct rtx_def;
|
||||
|
||||
struct gcc_target
|
||||
{
|
||||
/* Functions that output assembler for the target. */
|
||||
|
@ -72,12 +69,52 @@ struct gcc_target
|
|||
void (* named_section) PARAMS ((const char *, unsigned int));
|
||||
|
||||
/* Output a constructor for a symbol with a given priority. */
|
||||
void (* constructor) PARAMS ((struct rtx_def *, int));
|
||||
void (* constructor) PARAMS ((rtx, int));
|
||||
|
||||
/* Output a destructor for a symbol with a given priority. */
|
||||
void (* destructor) PARAMS ((struct rtx_def *, int));
|
||||
void (* destructor) PARAMS ((rtx, int));
|
||||
} asm_out;
|
||||
|
||||
/* Functions relating to instruction scheduling. */
|
||||
struct sched
|
||||
{
|
||||
/* Given the current cost, COST, of an insn, INSN, calculate and
|
||||
return a new cost based on its relationship to DEP_INSN through
|
||||
the dependence LINK. The default is to make no adjustment. */
|
||||
int (* adjust_cost) PARAMS ((rtx insn, rtx link, rtx def_insn, int cost));
|
||||
|
||||
/* Adjust the priority of an insn as you see fit. Returns the new
|
||||
priority. */
|
||||
int (* adjust_priority) PARAMS ((rtx, int));
|
||||
|
||||
/* Function which returns the maximum number of insns that can be
|
||||
scheduled in the same machine cycle. This must be constant
|
||||
over an entire compilation. The default is 1. */
|
||||
int (* issue_rate) PARAMS ((void));
|
||||
|
||||
/* Calculate how much this insn affects how many more insns we
|
||||
can emit this cycle. Default is they all cost the same. */
|
||||
int (* variable_issue) PARAMS ((FILE *, int, rtx, int));
|
||||
|
||||
/* Initialize machine-dependent scheduling code. */
|
||||
void (* md_init) PARAMS ((FILE *, int, int));
|
||||
|
||||
/* Finalize machine-dependent scheduling code. */
|
||||
void (* md_finish) PARAMS ((FILE *, int));
|
||||
|
||||
/* Reorder insns in a machine-dependent fashion, in two different
|
||||
places. Default does nothing. */
|
||||
int (* reorder) PARAMS ((FILE *, int, rtx *, int *, int));
|
||||
int (* reorder2) PARAMS ((FILE *, int, rtx *, int *, int));
|
||||
|
||||
/* cycle_display is a pointer to a function which can emit
|
||||
data into the assembly stream about the current cycle.
|
||||
Arguments are CLOCK, the data to emit, and LAST, the last
|
||||
insn in the new chain we're building. Returns a new LAST.
|
||||
The default is to do nothing. */
|
||||
rtx (* cycle_display) PARAMS ((int clock, rtx last));
|
||||
} sched;
|
||||
|
||||
/* Given two decls, merge their attributes and return the result. */
|
||||
tree (* merge_decl_attributes) PARAMS ((tree, tree));
|
||||
|
||||
|
@ -111,11 +148,8 @@ struct gcc_target
|
|||
void (* init_builtins) PARAMS ((void));
|
||||
|
||||
/* Expand a target-specific builtin. */
|
||||
struct rtx_def * (* expand_builtin) PARAMS ((tree exp,
|
||||
struct rtx_def *target,
|
||||
struct rtx_def *subtarget,
|
||||
enum machine_mode mode,
|
||||
int ignore));
|
||||
rtx (* expand_builtin) PARAMS ((tree exp, rtx target, rtx subtarget,
|
||||
enum machine_mode mode, int ignore));
|
||||
|
||||
/* Given a decl, a section name, and whether the decl initializer
|
||||
has relocs, choose attributes for the section. */
|
||||
|
|
Loading…
Reference in New Issue