Daniel Jacobowitz wrote: ...
Not even a single comment - shame on you both! :-) If this is the solution we choose, can we make sure that there's at least a comment explaining what's going on?
Totally agree. That was an *example patch*. Here is a bit updated, but still an example of how we can arrange instructions on ARM or some other platform with not much execution units.
-- Maxim
--- config/arm/arm.c (/gcc-local/trunk/gcc) (revision 19935) +++ config/arm/arm.c (/gcc-local/arm-bug/gcc) (revision 19935) @@ -52,6 +52,7 @@ #include "target-def.h" #include "debug.h" #include "langhooks.h" +#include "sched-int.h" /* Forward definitions of types. */ typedef struct minipool_node Mnode; @@ -118,6 +119,9 @@ static void thumb_output_function_prolog static int arm_comp_type_attributes (tree, tree); static void arm_set_default_type_attributes (tree); static int arm_adjust_cost (rtx, rtx, rtx, int); +static void arm_reorder (rtx *, int); +static int arm_reorder1 (FILE *, int, rtx *, int *, int); +static int arm_reorder2 (FILE *, int, rtx *, int *, int); static int count_insns_for_constant (HOST_WIDE_INT, int); static int arm_get_strip_length (int); static bool arm_function_ok_for_sibcall (tree, tree); @@ -245,6 +249,12 @@ static bool arm_tls_symbol_p (rtx x); #undef TARGET_SCHED_ADJUST_COST #define TARGET_SCHED_ADJUST_COST arm_adjust_cost +#undef TARGET_SCHED_REORDER +#define TARGET_SCHED_REORDER arm_reorder1 + +#undef TARGET_SCHED_REORDER2 +#define TARGET_SCHED_REORDER2 arm_reorder2 + #undef TARGET_ENCODE_SECTION_INFO #ifdef ARM_PE #define TARGET_ENCODE_SECTION_INFO arm_pe_encode_section_info @@ -5229,6 +5239,68 @@ arm_adjust_cost (rtx insn, rtx link, rtx return cost; } +/* Reorder insns in the ready list, so that instructions from the target block + will be scheduled ahead of instructions from the source blocks. */ +static void +arm_reorder (rtx *ready, int n_ready) +{ + if (n_ready > 1) + { + /* Find out what target block is. + + !!! It is better to use TARGET_BB itself from the + haifa-sched.c: schedule_block (), but it is unavailable due to its + local scope. */ + basic_block target_bb = BLOCK_FOR_INSN (current_sched_info->prev_head); + + if (/* If insn, that will be scheduled next don't belong to + TARGET_BB. + + !!! Actually, we want here another condition: + 'if (IS_SPECULATIVE_INSN (ready[n_ready - 1]))', but it is + unavailable due to local scope in sched-rgn.c . */ + BLOCK_FOR_INSN (ready[n_ready - 1]) != target_bb) + /* Search the ready list for the most prioritized insn from the + TARGET_BB, and, if found, move it to the head of the list. */ + { + int i; + + for (i = n_ready - 1; i >= 0; i--) + { + rtx insn = ready[i]; + + if (BLOCK_FOR_INSN (insn) != target_bb) + continue; + + memcpy (ready + i, ready + i + 1, + (n_ready - i - 1) * sizeof (*ready)); + ready[n_ready - 1] = insn; + break; + } + } + } +} + +/* Override default sorting algorithm to reduce number of interblock + motions. */ +static int +arm_reorder1 (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose ATTRIBUTE_UNUSED, + rtx *ready, int *pn_ready, int clock_var ATTRIBUTE_UNUSED) +{ + arm_reorder (ready, *pn_ready); + return 1; +} + +/* Override default sorting algorithm to reduce number of interblock + motions. */ +static int +arm_reorder2 (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose ATTRIBUTE_UNUSED, + rtx *ready, int *pn_ready, int clock_var ATTRIBUTE_UNUSED) +{ + arm_reorder (ready, *pn_ready); + return 0; +} + static int fp_consts_inited = 0; /* Only zero is valid for VFP. Other values are also valid for FPA. */