Commit 8c660648 by Jeffrey A Law Committed by Jeff Law

* Integrate Haifa instruction scheduler.

        * Integrate regmove pass.
See ChangeLog for deatils.

From-SVN: r14770
parent aa32d841
Mon Aug 11 14:50:55 1997 Jeffrey A Law (law@cygnus.com)
* Integrate Haifa instruction scheduler.
* Makefile.in (ALL_CFLAGS): Add SCHED_CFLAGS. Prefix all references
to sched with $(SCHED_CFLAGS.
* configure.in: Handle --enable-haifa.
* configure: Rebuilt.
* flags.h: Add new flags for haifa instruction scheduler.
* genattrtab.c (expand_units): For haifa, don't subtract one
when computing blockage.
* toplev.h (flag_schedule_interblock): Haifa scheduler flag.
(flag_schedule_speculative): Ditto.
(flag_schedule_speculative_load): Ditto.
(flag_schedule_speculative_load_dangerous): Ditto.
(flag_schedule_reverse_before_reload): Ditto.
(flag_schedule_reverse_after_reload): Ditto.
(flag_branch_on_count_reg): Ditto.
(f_options): Add Haifa switches.
(main): Turn off some Haifa options if appropriate macro is
defined. Process Haifa switches.
* unroll.c (iteration_info): No longer static, since Haifa
scheduler uses it.
(unroll_loop): Inform HAIFA scheduler about loop unrolling factor.
* unroll.c (unroll_loop): Set loop_unroll_iter, loop_start_value.
* loop.h (loop_unroll_factor, loop_number): Add HAIFA decls.
* loop.h (loop_initial_value,loop_unroll_iter): New globals.
* loop.c (loop_optimize): If HAIFA is defined, allocate additional
storage for the Haifa scheduler.
(mark_loop_jump): If HAIFA defined, set LABEL_OUTSIDE_LOOP_P and
LABEL_NEXTREF.
(strength_reduce): If HAIFA and HAVE_decrement_and_branch_on_count
are defined, call analyze_loop_iterations and insert_bct to use
countdown loops.
(record_giv): Refine test for jumps out of loops if HAIFA is
defined.
(analyze_loop_iterations): New function to identify if we can use
a countdown loop.
(insert_bct): Insert countdown loop.
(instrument_loop_bct): Low level code to insert countdown loop.
(loop_number): Calculate UID of loop.
(indirect_jump_in_function_p): Return true if an indirect jump is
in the function.
(is_power_of_2): Return true if value is a power of 2.
(is_conditional_branch): Return true if insn is a conditional
jump.
(fix_bct_param): Process -fbct-{min,max}-N switches.
(check_bct_param): Return true if loop should be instrumented.
* loop.c (loop_initial_value,loop_unroll_iter): New globals.
(loop_optimize): Initialize.
(get_condition_for_loop): Ditto.
* loop.c (strength_reduce): Inside of code that uses #ifdef
HAVE_decrement_and_branch_on_count code, test it to make sure the
condition is true.
(instrument_loop_bct): Ditto.
* haifa-sched.c: New file.
* Integrate regmove pass.
* Makefile.in (OBJS): Add regmove.o
(regmove.o): Add dependencies.
* flow.c (find_use_as_address): No longer static.
* rtl.h (find_use_as_address): Declare.
* toplev.c (regmove_dump, flag_regmove): Define.
(f_options): Add -fregmove.
(regmove_dump_file, regmove_time): Define.
(fatal_insn): Close the regmove dump file.
(compile_file): Initialize regmove_time; open/close the regmove dump
file as needed. Print regmove time as needed.
(rest_of_compilation): Run regmove pass if requested, dump
RTL after regmove if requested.
(main): If -O2 or more, turn on regmove. Handle dump switches.
* regmove.c: New file.
Mon Aug 11 14:15:02 1997 Jeffrey A Law (law@cygnus.com)
* Integrate tlink patch from jason@cygnus.com
......
......@@ -444,7 +444,7 @@ INTERNAL_CFLAGS = $(CROSS) -DIN_GCC @extra_c_flags@
# This is the variable actually used when we compile.
ALL_CFLAGS = $(INTERNAL_CFLAGS) $(X_CFLAGS) $(T_CFLAGS) $(CFLAGS) $(XCFLAGS) \
@DEFS@
@DEFS@ $(SCHED_CFLAGS)
# Likewise.
ALL_CPPFLAGS = $(CPPFLAGS) $(X_CPPFLAGS) $(T_CPPFLAGS)
......@@ -548,14 +548,17 @@ BC_OBJS = bc-emit.o bc-optab.o
# Bytecode header files constructed at build time; vmsconfig.com wants this.
BC_ALL = bc-arity.h bc-opcode.h bc-opname.h
SCHED_PREFIX = @sched_prefix@
SCHED_CFLAGS = @sched_cflags@
# Language-independent object files.
OBJS = toplev.o version.o tree.o print-tree.o stor-layout.o fold-const.o \
function.o stmt.o except.o expr.o calls.o expmed.o explow.o optabs.o \
varasm.o rtl.o print-rtl.o rtlanal.o emit-rtl.o real.o \
dbxout.o sdbout.o dwarfout.o dwarf2out.o xcoffout.o bitmap.o \
varasm.o rtl.o print-rtl.o rtlanal.o emit-rtl.o real.o regmove.o \
dbxout.o sdbout.o dwarfout.o dwarf2out.o xcoffout.o bitmap.o alias.o \
integrate.o jump.o cse.o loop.o unroll.o flow.o stupid.o combine.o \
regclass.o local-alloc.o global.o reload.o reload1.o caller-save.o \
insn-peep.o reorg.o alias.o sched.o final.o recog.o reg-stack.o \
insn-peep.o reorg.o $(SCHED_PREFIX)sched.o final.o recog.o reg-stack.o \
insn-opinit.o insn-recog.o insn-extract.o insn-output.o insn-emit.o \
profile.o insn-attrtab.o $(out_object_file) getpwd.o convert.o $(EXTRA_OBJS)
......@@ -1326,7 +1329,9 @@ reorg.o : reorg.c $(CONFIG_H) $(RTL_H) conditions.h hard-reg-set.h \
flags.h output.h
alias.o : alias.c $(CONFIG_H) $(RTL_H) flags.h hard-reg-set.h regs.h \
insn-codes.h
sched.o : $(SCHED_PREFIX)sched.c $(CONFIG_H) $(RTL_H) $(BASIC_BLOCK_H) regs.h hard-reg-set.h \
regmove.o : regmove.c $(CONFIG_H) $(RTL_H) insn-config.h recog.h output.h \
reload.h regs.h hard-reg-set.h flags.h expr.h insn-flags.h
$(SCHED_PREFIX)sched.o : $(SCHED_PREFIX)sched.c $(CONFIG_H) $(RTL_H) $(BASIC_BLOCK_H) regs.h hard-reg-set.h \
flags.h insn-config.h insn-attr.h
final.o : final.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h regs.h \
recog.h conditions.h insn-config.h insn-attr.h except.h real.h output.h \
......
......@@ -4361,6 +4361,26 @@ if [ ! -f Makefile.in ]; then
echo "source ${srcdir}/.gdbinit" >> .gdbinit
fi
# Override SCHED_OBJ and SCHED_CFLAGS to enable the Haifa scheduler.
sched_prefix=
sched_cflags=
if [[ x$enable_haifa = xyes ]]; then
echo "Using the Haifa scheduler."
sched_prefix=haifa-
sched_cflags=-DHAIFA
fi
if [[ x$enable_haifa != x ]]; then
# Explicitly remove files that need to be recompiled for the Haifa scheduler.
for x in genattrtab.o toplev.o loop.o unroll.o *sched.o; do
if [ -f $x ]; then
echo "Removing $x"
rm -f $x
fi
done
fi
# Process the language and host/target makefile fragments.
${CONFIG_SHELL-/bin/sh} $srcdir/configure.frag $srcdir "$subdirs" "$dep_host_xmake_file" "$dep_tmake_file"
......@@ -4602,6 +4622,8 @@ s%@CC@%$CC%g
s%@SET_MAKE@%$SET_MAKE%g
s%@CPP@%$CPP%g
s%@manext@%$manext%g
s%@sched_prefix@%$sched_prefix%g
s%@sched_cflags@%$sched_cflags%g
s%@objext@%$objext%g
s%@subdirs@%$subdirs%g
s%@all_languages@%$all_languages%g
......
......@@ -3027,6 +3027,26 @@ if [[ ! -f Makefile.in ]]; then
echo "source ${srcdir}/.gdbinit" >> .gdbinit
fi
# Override SCHED_OBJ and SCHED_CFLAGS to enable the Haifa scheduler.
sched_prefix=
sched_cflags=
if [[ x$enable_haifa = xyes ]]; then
echo "Using the Haifa scheduler."
sched_prefix=haifa-
sched_cflags=-DHAIFA
fi
AC_SUBST(sched_prefix)
AC_SUBST(sched_cflags)
if [[ x$enable_haifa != x ]]; then
# Explicitly remove files that need to be recompiled for the Haifa scheduler.
for x in genattrtab.o toplev.o loop.o unroll.o *sched.o; do
if [ -f $x ]; then
echo "Removing $x"
rm -f $x
fi
done
fi
# Process the language and host/target makefile fragments.
${CONFIG_SHELL-/bin/sh} $srcdir/configure.frag $srcdir "$subdirs" "$dep_host_xmake_file" "$dep_tmake_file"
......
......@@ -304,6 +304,34 @@ extern int flag_shared_data;
extern int flag_schedule_insns;
extern int flag_schedule_insns_after_reload;
#ifdef HAIFA
/* The following flags have effect only for scheduling before register
allocation:
flag_schedule_interblock means schedule insns accross basic blocks.
flag_schedule_speculative means allow speculative motion of non-load insns.
flag_schedule_speculative_load means allow speculative motion of some
load insns.
flag_schedule_speculative_load_dangerous allows speculative motion of more
load insns.
flag_schedule_reverse_before_reload means try to reverse original order
of insns (S).
flag_schedule_reverse_after_reload means try to reverse original order
of insns (R). */
extern int flag_schedule_interblock;
extern int flag_schedule_speculative;
extern int flag_schedule_speculative_load;
extern int flag_schedule_speculative_load_dangerous;
extern int flag_schedule_reverse_before_reload;
extern int flag_schedule_reverse_after_reload;
/* flag_on_branch_count_reg means try to replace add-1,compare,branch tupple
by a cheaper branch, on a count register. */
extern int flag_branch_on_count_reg;
#endif /* HAIFA */
/* Nonzero means put things in delayed-branch slots if supported. */
extern int flag_delayed_branch;
......
......@@ -268,7 +268,6 @@ static void find_auto_inc PROTO((regset, rtx, rtx));
static void mark_used_regs PROTO((regset, regset, rtx, int, rtx));
static int try_pre_increment_1 PROTO((rtx));
static int try_pre_increment PROTO((rtx, rtx, HOST_WIDE_INT));
static rtx find_use_as_address PROTO((rtx, rtx, HOST_WIDE_INT));
void dump_flow_info PROTO((FILE *));
/* Find basic blocks of the current function and perform data flow analysis.
......@@ -2795,7 +2794,7 @@ try_pre_increment (insn, reg, amount)
If REG appears more than once, or is used other than in such an address,
return (rtx)1. */
static rtx
rtx
find_use_as_address (x, reg, plusconst)
register rtx x;
rtx reg;
......
......@@ -2003,6 +2003,9 @@ expand_units ()
for (op = unit->ops; op; op = op->next)
{
#ifdef HAIFA
rtx blockage = op->issue_exp;
#else
rtx blockage = operate_exp (POS_MINUS_OP, readycost,
make_numeric_value (1));
......@@ -2018,6 +2021,7 @@ expand_units ()
blockage);
blockage = operate_exp (MAX_OP, blockage, op->issue_exp);
#endif
blockage = simplify_knowing (blockage, unit->condexp);
/* Add this op's contribution to MAX (BLOCKAGE (E,*)) and
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -147,7 +147,7 @@ in the following sections.
-ffunction-sections -finline-functions
-fkeep-inline-functions -fno-default-inline
-fno-defer-pop -fno-function-cse
-fno-inline -fno-peephole -fomit-frame-pointer
-fno-inline -fno-peephole -fomit-frame-pointer -fregmove
-frerun-cse-after-loop -fschedule-insns
-fschedule-insns2 -fstrength-reduce -fthread-jumps
-funroll-all-loops -funroll-loops
......@@ -2195,6 +2195,12 @@ used in one place: in @file{reorg.c}, instead of guessing which path a
branch is mostly to take, the @samp{REG_BR_PROB} values are used to
exactly determine which path is taken more often.
@end ifset
@item -fregmove
Some machines only support 2 operands per instruction. On such
machines, GNU CC might have to do extra copies. The @samp{-fregmove}
option overrides the default for the machine to do the copy before
register allocation.
@end table
@node Preprocessor Options
......
......@@ -181,3 +181,13 @@ rtx final_biv_value PROTO((struct iv_class *, rtx, rtx));
rtx final_giv_value PROTO((struct induction *, rtx, rtx));
void emit_unrolled_add PROTO((rtx, rtx, rtx));
int back_branch_in_range_p PROTO((rtx, rtx, rtx));
#ifdef HAIFA
/* variables for interaction between unroll.c and loop.c, for
the insertion of branch-on-count instruction. */
extern int *loop_unroll_factor;
extern rtx *loop_start_value;
extern int *loop_unroll_iter;
extern int loop_number();
#endif /* HAIFA */
This diff is collapsed. Click to expand it.
......@@ -812,6 +812,7 @@ extern void remove_note PROTO((rtx, rtx));
extern void note_stores PROTO((rtx, void (*)()));
extern int refers_to_regno_p PROTO((int, int, rtx, rtx *));
extern int reg_overlap_mentioned_p PROTO((rtx, rtx));
extern rtx find_use_as_address PROTO((rtx, rtx, HOST_WIDE_INT));
/* Maximum number of parallel sets and clobbers in any insn in this fn.
......
......@@ -245,6 +245,7 @@ int cse2_dump = 0;
int branch_prob_dump = 0;
int flow_dump = 0;
int combine_dump = 0;
int regmove_dump = 0;
int sched_dump = 0;
int local_reg_dump = 0;
int global_reg_dump = 0;
......@@ -566,6 +567,35 @@ int flag_pedantic_errors = 0;
int flag_schedule_insns = 0;
int flag_schedule_insns_after_reload = 0;
#ifdef HAIFA
/* The following flags have effect only for scheduling before register
allocation:
flag_schedule_interblock means schedule insns accross basic blocks.
flag_schedule_speculative means allow speculative motion of non-load insns.
flag_schedule_speculative_load means allow speculative motion of some
load insns.
flag_schedule_speculative_load_dangerous allows speculative motion of more
load insns.
flag_schedule_reverse_before_reload means try to reverse original order
of insns (S).
flag_schedule_reverse_after_reload means try to reverse original order
of insns (R). */
int flag_schedule_interblock = 1;
int flag_schedule_speculative = 1;
int flag_schedule_speculative_load = 0;
int flag_schedule_speculative_load_dangerous = 0;
int flag_schedule_reverse_before_reload = 0;
int flag_schedule_reverse_after_reload = 0;
/* flag_on_branch_count_reg means try to replace add-1,compare,branch tupple
by a cheaper branch, on a count register. */
int flag_branch_on_count_reg;
#endif /* HAIFA */
/* -finhibit-size-directive inhibits output of .size for ELF.
This is used only for compiling crtstuff.c,
and it may be extended to other effects
......@@ -616,6 +646,8 @@ int flag_check_memory_usage = 0;
-fcheck-memory-usage. */
int flag_prefix_function_name = 0;
int flag_regmove = 0;
/* 1 if alias checking is on (by default, when -O). */
int flag_alias_check = 0;
......@@ -666,6 +698,15 @@ struct { char *string; int *variable; int on_value;} f_options[] =
{"pretend-float", &flag_pretend_float, 1},
{"schedule-insns", &flag_schedule_insns, 1},
{"schedule-insns2", &flag_schedule_insns_after_reload, 1},
#ifdef HAIFA
{"sched-interblock",&flag_schedule_interblock, 1},
{"sched-spec",&flag_schedule_speculative, 1},
{"sched-spec-load",&flag_schedule_speculative_load, 1},
{"sched-spec-load-dangerous",&flag_schedule_speculative_load_dangerous, 1},
{"sched-reverse-S",&flag_schedule_reverse_before_reload, 1},
{"sched-reverse-R",&flag_schedule_reverse_after_reload, 1},
{"branch-count-reg",&flag_branch_on_count_reg, 1},
#endif /* HAIFA */
{"pic", &flag_pic, 1},
{"PIC", &flag_pic, 2},
{"exceptions", &flag_exceptions, 1},
......@@ -680,6 +721,7 @@ struct { char *string; int *variable; int on_value;} f_options[] =
{"function-sections", &flag_function_sections, 1},
{"verbose-asm", &flag_verbose_asm, 1},
{"gnu-linker", &flag_gnu_linker, 1},
{"regmove", &flag_regmove, 1},
{"pack-struct", &flag_pack_struct, 1},
{"stack-check", &flag_stack_check, 1},
{"bytecode", &output_bytecode, 1},
......@@ -885,6 +927,7 @@ FILE *cse2_dump_file;
FILE *branch_prob_dump_file;
FILE *flow_dump_file;
FILE *combine_dump_file;
FILE *regmove_dump_file;
FILE *sched_dump_file;
FILE *local_reg_dump_file;
FILE *global_reg_dump_file;
......@@ -905,6 +948,7 @@ int cse2_time;
int branch_prob_time;
int flow_time;
int combine_time;
int regmove_time;
int sched_time;
int local_alloc_time;
int global_alloc_time;
......@@ -1053,6 +1097,8 @@ fatal_insn (message, insn)
fflush (flow_dump_file);
if (combine_dump_file)
fflush (combine_dump_file);
if (regmove_dump_file)
fflush (regmove_dump_file);
if (sched_dump_file)
fflush (sched_dump_file);
if (local_reg_dump_file)
......@@ -2131,6 +2177,7 @@ compile_file (name)
branch_prob_time = 0;
flow_time = 0;
combine_time = 0;
regmove_time = 0;
sched_time = 0;
local_alloc_time = 0;
global_alloc_time = 0;
......@@ -2229,6 +2276,10 @@ compile_file (name)
if (combine_dump)
combine_dump_file = open_dump_file (dump_base_name, ".combine");
/* If regmove dump desired, open the output file. */
if (regmove_dump)
regmove_dump_file = open_dump_file (dump_base_name, ".regmove");
/* If scheduling dump desired, open the output file. */
if (sched_dump)
sched_dump_file = open_dump_file (dump_base_name, ".sched");
......@@ -2713,6 +2764,9 @@ compile_file (name)
fclose (combine_dump_file);
}
if (regmove_dump)
fclose (regmove_dump_file);
if (sched_dump)
fclose (sched_dump_file);
......@@ -2765,6 +2819,7 @@ compile_file (name)
print_time ("branch-prob", branch_prob_time);
print_time ("flow", flow_time);
print_time ("combine", combine_time);
print_time ("regmove", regmove_time);
print_time ("sched", sched_time);
print_time ("local-alloc", local_alloc_time);
print_time ("global-alloc", global_alloc_time);
......@@ -3304,6 +3359,26 @@ rest_of_compilation (decl)
fflush (combine_dump_file);
});
if (regmove_dump)
TIMEVAR (dump_time,
{
fprintf (regmove_dump_file, "\n;; Function %s\n\n",
(*decl_printable_name) (decl, 2));
});
/* Register allocation pre-pass, to reduce number of moves
necessary for two-address machines. */
if (optimize > 0 && flag_regmove)
TIMEVAR (regmove_time, regmove_optimize (insns, max_reg_num (),
regmove_dump_file));
if (regmove_dump)
TIMEVAR (dump_time,
{
print_rtl (regmove_dump_file, insns);
fflush (regmove_dump_file);
});
/* Print function header into sched dump now
because doing the sched analysis makes some of the dump. */
......@@ -3703,6 +3778,7 @@ main (argc, argv, envp)
flag_schedule_insns = 1;
flag_schedule_insns_after_reload = 1;
#endif
flag_regmove = 1;
}
if (optimize >= 3)
......@@ -3764,6 +3840,7 @@ main (argc, argv, envp)
jump2_opt_dump = 1;
local_reg_dump = 1;
loop_dump = 1;
regmove_dump = 1;
rtl_dump = 1;
cse_dump = 1, cse2_dump = 1;
sched_dump = 1;
......@@ -3815,6 +3892,9 @@ main (argc, argv, envp)
case 't':
cse2_dump = 1;
break;
case 'N':
regmove_dump = 1;
break;
case 'S':
sched_dump = 1;
break;
......@@ -3862,6 +3942,18 @@ main (argc, argv, envp)
if (found)
;
#ifdef HAIFA
#ifdef INSN_SCHEDULING
else if (!strncmp (p, "sched-verbose-",14))
fix_sched_param("verbose",&p[14]);
else if (!strncmp (p, "sched-max-",10))
fix_sched_param("max",&p[10]);
else if (!strncmp (p, "sched-inter-max-b-",18))
fix_sched_param("interblock-max-blocks",&p[18]);
else if (!strncmp (p, "sched-inter-max-i-",18))
fix_sched_param("interblock-max-insns",&p[18]);
#endif
#endif /* HAIFA */
else if (!strncmp (p, "fixed-", 6))
fix_register (&p[6], 1, 1);
else if (!strncmp (p, "call-used-", 10))
......
......@@ -202,7 +202,7 @@ static rtx initial_reg_note_copy PROTO((rtx, struct inline_remap *));
static void final_reg_note_copy PROTO((rtx, struct inline_remap *));
static void copy_loop_body PROTO((rtx, rtx, struct inline_remap *, rtx, int,
enum unroll_types, rtx, rtx, rtx, rtx));
static void iteration_info PROTO((rtx, rtx *, rtx *, rtx, rtx));
void iteration_info PROTO((rtx, rtx *, rtx *, rtx, rtx));
static rtx approx_final_value PROTO((enum rtx_code, rtx, int *, int *));
static int find_splittable_regs PROTO((enum unroll_types, rtx, rtx, rtx, int));
static int find_splittable_givs PROTO((struct iv_class *,enum unroll_types,
......@@ -1094,6 +1094,16 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
/* Set unroll type to MODULO now. */
unroll_type = UNROLL_MODULO;
loop_preconditioned = 1;
#ifdef HAIFA
if (loop_n_iterations > 0)
loop_unroll_iter[ loop_number(loop_start, loop_end) ]
= (loop_n_iterations
- loop_n_iterations % (abs_inc * unroll_number));
else
/* inform loop.c about the new initial value */
loop_start_value[loop_number(loop_start, loop_end)] = initial_value;
#endif
}
}
......@@ -1108,6 +1118,15 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
/* At this point, we are guaranteed to unroll the loop. */
#ifdef HAIFA
/* inform loop.c about the factor of unrolling */
if (unroll_type == UNROLL_COMPLETELY)
loop_unroll_factor[ loop_number(loop_start, loop_end) ] = -1;
else
loop_unroll_factor[ loop_number(loop_start, loop_end) ] = unroll_number;
#endif /* HAIFA */
/* For each biv and giv, determine whether it can be safely split into
a different variable for each unrolled copy of the loop body.
We precalculate and save this info here, since computing it is
......@@ -2263,7 +2282,7 @@ biv_total_increment (bl, loop_start, loop_end)
Initial_value and/or increment are set to zero if their values could not
be calculated. */
static void
void
iteration_info (iteration_var, initial_value, increment, loop_start, loop_end)
rtx iteration_var, *initial_value, *increment;
rtx loop_start, loop_end;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment