This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
schedule-ebbs and trapping insns
- From: "David S. Miller" <davem at redhat dot com>
- To: gcc at gcc dot gnu dot org, bernds at redhat dot com
- Cc: rth at redhat dot com, jakub at redhat dot com
- Date: Thu, 27 Jun 2002 00:52:17 -0700 (PDT)
- Subject: schedule-ebbs and trapping insns
How can the init_ready_list used by sched-ebb.c legally not
take into consideration trapping instructions like the
sched-rgn.c version does? You can't move trapping instructions
between basic blocks.
I hit this because I tried to start using sched-ebb on Sparc
and things blew up when schedule_ebbs swapped the order of
these two tests in expmed.c:extract_bit_field
&& GET_MODE_SIZE (mode1) != 0
&& byte_offset % GET_MODE_SIZE (mode1) == 0)
Such a transformation is obviously illegal and this results
in a divide by zero while building libobjc.
I guess this doesn't get hit on IA64 (which is the only current port
in the tree using schedule_ebbs) because of predication. If that is
true then it shouldn't hurt code generated on that platform if we put
the necessary checks in.
I guess there are properties we can depend upon for extended basic
blocks that would allow the "exception free" test to be more leanient
than the one in sched-rgn.c, particularly for loads/stores.
For reference here is the patch I am using to make Sparc use
schedule_ebbs.
2002-06-26 David S. Miller <davem@redhat.com>
* config/sparc/sparc.h (MASK_NORMAL_SCHED2, TARGET_NORMAL_SCHED2):
Define.
(TARGET_SWITCHED): Add -mnormal-sched2.
(MACHINE_DEPENDENT_REORG): Define.
* config/sparc/sparc-protos.h (sparc_reorg): Declare.
* config/sparc/sparc.c: Include basic-block.h, timevar.h
(sparc_flag_schedule_insns2): New.
(sparc_override_options): If not TARGET_NORMAL_SCHED2, propagate
flag_schedule_insns_after_reload setting to
sparc_flag_schedule_insn2 and then clear the former.
(sparc_reorg): New, run schedule_ebbs pass if
sparc_flag_schedule_insns2 is set.
--- ./config/sparc/sparc.c.~1~ Tue Jun 4 14:08:55 2002
+++ ./config/sparc/sparc.c Wed Jun 26 21:22:03 2002
@@ -41,6 +41,8 @@ Boston, MA 02111-1307, USA. */
#include "recog.h"
#include "toplev.h"
#include "ggc.h"
+#include "basic-block.h"
+#include "timevar.h"
#include "tm_p.h"
#include "debug.h"
#include "target.h"
@@ -125,6 +127,12 @@ char sparc_leaf_regs[] =
static const char *frame_base_name;
static int frame_base_offset;
+/* Determines whether we run our own second scheduling pass or not.
+ The user can choose the normal sched2 pass if he wants by specifying
+ -mnormal-sched2 on the command line. */
+
+static int sparc_flag_schedule_insns2;
+
static void sparc_init_modes PARAMS ((void));
static int save_regs PARAMS ((FILE *, int, int, const char *,
int, int, int));
@@ -435,6 +443,12 @@ sparc_override_options ()
if (!TARGET_ARCH64)
targetm.asm_out.unaligned_op.di = NULL;
+ if (!TARGET_NORMAL_SCHED2)
+ {
+ sparc_flag_schedule_insns2 = flag_schedule_insns_after_reload;
+ flag_schedule_insns_after_reload = 0;
+ }
+
/* Do various machine dependent initializations. */
sparc_init_modes ();
}
@@ -8511,6 +8525,35 @@ sparc_output_mi_thunk (file, thunk_fndec
reload_completed = 0;
no_new_pseudos = 0;
+}
+
+/* Perform machine dependent operations on the rtl chain INSNS. */
+
+void
+sparc_reorg (insns)
+ rtx insns ATTRIBUTE_UNUSED;
+{
+ if (TARGET_NORMAL_SCHED2)
+ return;
+
+ /* We are freeing block_for_insn in the toplev to keep compatibility
+ with old MDEP_REORGS that are not CFG based. Recompute it now. */
+ compute_bb_for_insn ();
+
+ /* If optimizing, we'll have split before scheduling. */
+ if (optimize == 0)
+ split_all_insns (0);
+
+ /* ??? update_life_info_in_dirty_blocks fails to terminate during
+ non-optimizing bootstrap. */
+ update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES, PROP_DEATH_NOTES);
+
+ if (sparc_flag_schedule_insns2)
+ {
+ timevar_push (TV_SCHED2);
+ schedule_ebbs (rtl_dump_file);
+ timevar_pop (TV_SCHED2);
+ }
}
#include "gt-sparc.h"
--- ./config/sparc/sparc.h.~1~ Mon Jun 24 01:20:25 2002
+++ ./config/sparc/sparc.h Wed Jun 26 01:08:37 2002
@@ -496,6 +496,10 @@ extern int target_flags;
#define MASK_LONG_DOUBLE_128 0x8000000
#define TARGET_LONG_DOUBLE_128 (target_flags & MASK_LONG_DOUBLE_128)
+/* Use normal second scheduling pass instead of schedule_ebbs. */
+#define MASK_NORMAL_SCHED2 0x10000000
+#define TARGET_NORMAL_SCHED2 (target_flags & MASK_NORMAL_SCHED2)
+
/* TARGET_HARD_MUL: Use hardware multiply instructions but not %y.
TARGET_HARD_MUL32: Use hardware multiply instructions with rd %y
to get high 32 bits. False in V8+ or V9 because multiply stores
@@ -590,6 +594,8 @@ extern int target_flags;
N_("Optimize tail call instructions in assembler and linker") }, \
{"no-relax", 0, \
N_("Do not optimize tail call instructions in assembler or linker") }, \
+ {"normal-sched2", MASK_NORMAL_SCHED2, \
+ N_("Do not use extended basic block scheduling") }, \
SUBTARGET_SWITCHES \
{ "", TARGET_DEFAULT, ""}}
@@ -2667,6 +2673,12 @@ case LABEL_REF: case SYMBOL_REF: case CO
? 2 \
: (sparc_cpu == PROCESSOR_ULTRASPARC3 \
? 8 : 3))
+
+/* Run schedule_ebbs instead of the normal second scheduling pass
+ if the second scheduling pass was enabled. */
+
+#define MACHINE_DEPENDENT_REORG(INSN) sparc_reorg (INSN)
+
/* Control the assembler format that we output. */
--- ./config/sparc/sparc-protos.h.~1~ Mon May 27 03:54:36 2002
+++ ./config/sparc/sparc-protos.h Wed Jun 26 01:01:16 2002
@@ -121,6 +121,7 @@ extern int sparc_check_64 PARAMS ((rtx,
extern rtx gen_df_reg PARAMS ((rtx, int));
extern int sparc_extra_constraint_check PARAMS ((rtx, int, int));
extern int sparc_rtx_costs PARAMS ((rtx, enum rtx_code, enum rtx_code));
+extern void sparc_reorg PARAMS((rtx));
#endif /* RTX_CODE */
extern void sparc_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT, tree));