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. */