diff options
49 files changed, 782 insertions, 664 deletions
diff --git a/gcc/Makefile.in b/gcc/Makefile.in index aa9f7ad..a5253e5 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -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) diff --git a/gcc/config/a29k/a29k.c b/gcc/config/a29k/a29k.c index 420e2f5..730ff55 100644 --- a/gcc/config/a29k/a29k.c +++ b/gcc/config/a29k/a29k.c @@ -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; +} diff --git a/gcc/config/a29k/a29k.h b/gcc/config/a29k/a29k.h index 8568d5e..4a63731 100644 --- a/gcc/config/a29k/a29k.h +++ b/gcc/config/a29k/a29k.h @@ -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. */ diff --git a/gcc/config/alpha/alpha-protos.h b/gcc/config/alpha/alpha-protos.h index 9e3ae7d..511bfb6 100644 --- a/gcc/config/alpha/alpha-protos.h +++ b/gcc/config/alpha/alpha-protos.h @@ -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)); diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index 731f6a6..999d050 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -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. */ diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h index 9a724ed..c1ffe4a 100644 --- a/gcc/config/alpha/alpha.h +++ b/gcc/config/alpha/alpha.h @@ -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, diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index 1a603f2..2c3f831 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -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)); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 13669b7..825a465 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -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; diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 28f49ea..784f28f 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -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 diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h index 5467fa4..3fd1e56 100644 --- a/gcc/config/avr/avr.h +++ b/gcc/config/avr/avr.h @@ -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 diff --git a/gcc/config/c4x/c4x-protos.h b/gcc/config/c4x/c4x-protos.h index 99ce1cc..1a3ebcf 100644 --- a/gcc/config/c4x/c4x-protos.h +++ b/gcc/config/c4x/c4x-protos.h @@ -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)); diff --git a/gcc/config/c4x/c4x.c b/gcc/config/c4x/c4x.c index 71d4c5c..2e79177 100644 --- a/gcc/config/c4x/c4x.c +++ b/gcc/config/c4x/c4x.c @@ -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; diff --git a/gcc/config/c4x/c4x.h b/gcc/config/c4x/c4x.h index e2c483d..cdc39db 100644 --- a/gcc/config/c4x/c4x.h +++ b/gcc/config/c4x/c4x.h @@ -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. */ diff --git a/gcc/config/convex/convex.c b/gcc/config/convex/convex.c index dcf3669..6f965a2 100644 --- a/gcc/config/convex/convex.c +++ b/gcc/config/convex/convex.c @@ -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 diff --git a/gcc/config/convex/convex.h b/gcc/config/convex/convex.h index c0615e4..8d11c63 100644 --- a/gcc/config/convex/convex.h +++ b/gcc/config/convex/convex.h @@ -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 diff --git a/gcc/config/d30v/d30v-protos.h b/gcc/config/d30v/d30v-protos.h index f681a40..0dfa8f1 100644 --- a/gcc/config/d30v/d30v-protos.h +++ b/gcc/config/d30v/d30v-protos.h @@ -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)); diff --git a/gcc/config/d30v/d30v.c b/gcc/config/d30v/d30v.c index cf5918f..2af7b26 100644 --- a/gcc/config/d30v/d30v.c +++ b/gcc/config/d30v/d30v.c @@ -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. */ diff --git a/gcc/config/d30v/d30v.h b/gcc/config/d30v/d30v.h index e39f37c..82598fd 100644 --- a/gcc/config/d30v/d30v.h +++ b/gcc/config/d30v/d30v.h @@ -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 */ diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index e263116..b97d82f 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.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)); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index e952e61..51d32f6 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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; diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index a0d23f6..bc5fd08 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -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. diff --git a/gcc/config/ia64/ia64-protos.h b/gcc/config/ia64/ia64-protos.h index 80f7479..e9c2c5c 100644 --- a/gcc/config/ia64/ia64-protos.h +++ b/gcc/config/ia64/ia64-protos.h @@ -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 diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index d7474ac..360e2b3 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -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 diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h index f6b4693..d1a1fed 100644 --- a/gcc/config/ia64/ia64.h +++ b/gcc/config/ia64/ia64.h @@ -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 diff --git a/gcc/config/m32r/m32r-protos.h b/gcc/config/m32r/m32r-protos.h index f0a1a5b..fd93040 100644 --- a/gcc/config/m32r/m32r-protos.h +++ b/gcc/config/m32r/m32r-protos.h @@ -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 diff --git a/gcc/config/m32r/m32r.c b/gcc/config/m32r/m32r.c index a37ed65..a9ca24f 100644 --- a/gcc/config/m32r/m32r.c +++ b/gcc/config/m32r/m32r.c @@ -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; diff --git a/gcc/config/m32r/m32r.h b/gcc/config/m32r/m32r.h index 692249b..5ef9951 100644 --- a/gcc/config/m32r/m32r.h +++ b/gcc/config/m32r/m32r.h @@ -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. */ diff --git a/gcc/config/m88k/m88k.c b/gcc/config/m88k/m88k.c index 1c0bd15..34ca914 100644 --- a/gcc/config/m88k/m88k.c +++ b/gcc/config/m88k/m88k.c @@ -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; +} diff --git a/gcc/config/m88k/m88k.h b/gcc/config/m88k/m88k.h index 1f7304c..c30c818 100644 --- a/gcc/config/m88k/m88k.h +++ b/gcc/config/m88k/m88k.h @@ -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 diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index d9cdcf5..268c7f4 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -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. */ diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index a3500ee..e09fb12 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -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 diff --git a/gcc/config/pa/pa-protos.h b/gcc/config/pa/pa-protos.h index d8430a7..03d4ee2 100644 --- a/gcc/config/pa/pa-protos.h +++ b/gcc/config/pa/pa-protos.h @@ -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)); diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 5517f99..85183ff 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -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. diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h index fcceaa1..a6580b8 100644 --- a/gcc/config/pa/pa.h +++ b/gcc/config/pa/pa.h @@ -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) \ diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index a6c2b01..13a2f3d 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -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)); diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index f8a168d..4bfb673 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -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: /* ? */ diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index f87c1eb..bc3f788 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -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; diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h index 5027e74..7f16843 100644 --- a/gcc/config/s390/s390-protos.h +++ b/gcc/config/s390/s390-protos.h @@ -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 *)); diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 5ce9a19..425c98e 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -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; diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h index 2e52dd2..ba737f2 100644 --- a/gcc/config/s390/s390.h +++ b/gcc/config/s390/s390.h @@ -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). */ diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index f8d77d4..b07979d 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -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; +} diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h index 9a2c347..b22684c3 100644 --- a/gcc/config/sh/sh.h +++ b/gcc/config/sh/sh.h @@ -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) diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h index 78117f7..fe65829 100644 --- a/gcc/config/sparc/sparc-protos.h +++ b/gcc/config/sparc/sparc-protos.h @@ -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 diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index b0d9ade..216fc60 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -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) diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index e24b0f9..0e9e515 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -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 { \ diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 7a64bcd..8f567db 100644 --- a/gcc/doc/tm.texi +++ b/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}) diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c index 46993fb..9e32034 100644 --- a/gcc/haifa-sched.c +++ b/gcc/haifa-sched.c @@ -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. */ diff --git a/gcc/target-def.h b/gcc/target-def.h index 94f8d10..3282b3c 100644 --- a/gcc/target-def.h +++ b/gcc/target-def.h @@ -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, \ diff --git a/gcc/target.h b/gcc/target.h index bc839c5..8d73f49 100644 --- a/gcc/target.h +++ b/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. */ |