2003-01-09 Vladimir Makarov <vmakarov@redhat.com>

Merging changes from itanium-sched-branch:

From-SVN: r61132
This commit is contained in:
Vladimir Makarov 2003-01-09 23:15:34 +00:00 committed by Vladimir Makarov
parent 6ff2fe3933
commit 30028c8515
21 changed files with 6868 additions and 2347 deletions

View File

@ -1,3 +1,444 @@
2003-01-09 Vladimir Makarov <vmakarov@redhat.com>
The following changes are merged from itanium-sched-branch:
2003-01-08 David Edelsohn <edelsohn@gnu.org>
* doc/md.texi: Clarify assignment of units to automata description.
2003-01-08 Vladimir Makarov <vmakarov@redhat.com>
* genautomata.c (unit_decl): Remove members
`the_same_automaton_unit' and
`the_same_automaton_message_reported_p'.
(process_unit_to_form_the_same_automaton_unit_lists,
form_the_same_automaton_unit_lists_from_regexp,
form_the_same_automaton_unit_lists, the_same_automaton_lists):
Remove them.
(annotation_message_reported_p): New global variable.
(check_unit_distribution_in_reserv,
check_regexp_units_distribution): New functions.
(check_unit_distributions_to_automata): Rewrite it.
2003-01-04 Vladimir Makarov <vmakarov@redhat.com>
* genautomata.c (form_the_same_automaton_unit_lists_from_regexp):
Use continue instead of break if cycle is too big.
2002-12-20 Vladimir Makarov <vmakarov@redhat.com>
* genautomata.c (check_unit_distributions_to_automata): Output at
most one message for a unit.
(process_unit_to_form_the_same_automaton_unit_lists): Check
automaton of units instead of units themself.
* doc/md.texi: Describe the constraint about assigning unit to
automata.
2002-12-20 Jan Hubicka <jH@suse.cz>
Vladimir Makarov <vmakarov@redhat.com>
* genautomata.c (unit_decl): Add new members `min_occ_cycle_num'
and `in_set_p'.
(gen_cpu_unit): Initialize the new members.
(process_regexp_cycles): Calculate minimal finish cycle too. Set
up `min_occ_cycle_num'.
(evaluate_max_reserv_cycles): Change the function call.
(CLEAR_BIT): New macro.
(states_union, state_shift): Use the mask.
(initiate_excl_sets, form_reserv_sets_list): Set up `in_set_p'.
(form_reservs_matter): New function.
(make_automaton): Call the function and use the mask.
(estimate_one_automaton_bound): Take `min_occ_cycle_num' into
account.
2002-12-17 Vladimir Makarov <vmakarov@redhat.com>
* config/ia64/itanium2.md (lfetch): Change the insn reservation.
2002-12-17 Vladimir Makarov <vmakarov@redhat.com>
* config/ia64/ia64.c (bundling): Try to insert 2 nops for M insn
for Itanium.
2002-12-17 Vladimir Makarov <vmakarov@redhat.com>
* config/ia64/ia64.c (ia64_override_options): Make itanium2 as
default cpu.
2002-12-17 Vladimir Makarov <vmakarov@redhat.com>
2002-10-31 Dale Johannesen <dalej@apple.com>
* haifa-sched.c (find_set_reg_weight): New function.
(find_insn_reg_weight): Use the new function.
(schedule_block): Do sorting ready queue always
after insn issue.
2002-11-27 Vladimir Makarov <vmakarov@redhat.com>
* config/ia64/ia64.c (bundling): Use MFI template instead of MLX.
2002-11-19 Vladimir Makarov <vmakarov@redhat.com>
* haifa-sched.c (choice_entry): New structure.
(choice_stack, cycle_issued_insns): New variables.
(max_issue): Rewrite it.
(choose_ready): Set up ready_try for unknown insns too.
(schedule_block): Allocate and free choice_stack. Set up
and modify cycle_issued_insns.
* config/ia64/ia64.c (issue_nops_and_insn): Combine insn issue
with and without filling the bundle.
(bundling): Combine calls of issue_nops_and_insn.
2002-10-17 Vladimir Makarov <vmakarov@redhat.com>
* config/ia64/itanium1.md: New file.
* config/ia64/itanium2.md: New file.
* config/ia64/ia64.md: Move DFA descriptions into the new files.
Remove the old pipeline description.
* config/ia64/ia64.c (ia64_override_options): Add aliases of
itanium processor names.
2002-10-16 Vladimir Makarov <vmakarov@redhat.com>
* config/ia64/ia64.c (bundling): Print states for Itanium2 too.
(ia64_reorg): Set up queried unit codes for Itanium2 too.
* config/ia64/ia64.md: Add descriptions for Itanium2.
2002-10-08 Vladimir Makarov <vmakarov@redhat.com>
* config/ia64/ia64.h (processor_type): New enumeration.
(ia64_tune, ia64_tune_string): New external declarations.
(TARGET_OPTIONS): Add option `tune='.
* config/ia64/ia64.c (ia64_tune, ia64_tune_string): New global
variables.
(ia64_override_options): Set up `ia64_tune'.
(ia64_sched_reorder2): Set up `clocks' only for Itanium.
(ia64_dfa_new_cycle): Set up `add_cycles' only for Itanium.
(bundling): Add nops for MM-insns only for Itanium.
(ia64_reorg): Allocate and free `clocks' and `add_cycles' only for
Itanium.
* config/ia64/ia64.md (cpu): New attribute.
(DFA description): Enable it only for Itanium.
2002-10-08 Vladimir Makarov <vmakarov@redhat.com>
Richard Henderson <rth@redhat.com>
* config/ia64/ia64.h (MASK_TUNE_STOP_BITS): Rename it to
MASK_EARLY_STOP_BITS.
(TARGET_TUNE_STOP_BITS): Rename it to TARGET_EARLY_STOP_BITS.
(TARGET_SWITCHES): Rename option `tune-stop-bits' to
`early-stop-bits'.
* config/ia64/ia64.c (ia64_dfa_new_cycle,
final_emit_insn_group_barriers): Use TARGET_EARLY_STOP_BITS
instead of TARGET_TUNE_STOP_BITS.
* doc/invoke.texi: Rename option `-mtune-stop-bits' to
`-mearly-stop-bits'.
* config/ia64/ia64.c (automata_option "v"): Comment it.
2002-10-07 Vladimir Makarov <vmakarov@redhat.com>
* config/ia64/ia64.h (MASK_TUNE_STOP_BITS, TARGET_TUNE_STOP_BITS):
New macros.
(TARGET_SWITCHES): Add entries for the new option.
* config/ia64/ia64.c (dfa_stop_insn, last_scheduled_insn, rtx
dfa_pre_cycle_insn, ia64_nop): Don't make them as roots for GC.
(stops_p, stop_before_p, clocks_length, clocks, add_cycles): New
global variables.
(ia64_sched_reorder2): Set up `clocks'.
(ia64_variable_issue): Set up `stops_p' and reset `stop_before_p'.
(ia64_dfa_new_cycle): Set up add_cycle. Permit sorting ready
queue when TARGET_TUNE_STOP_BITS.
(bundling): Insert additional nops for MM-insns.
(final_emit_insn_group_barriers): Add insertion of stop bits
according `stops_p'.
(ia64_reorg): Initiate the new varibales.
* doc/invoke.texi: Add description of option `-mtune-stop-bits'.
2002-10-02 Vladimir Makarov <vmakarov@redhat.com>
* haifa-sched.c (schedule_block): Modify INSN_TICK of depended
insns at the end of block insn scheduling.
2002-09-30 Vladimir Makarov <vmakarov@redhat.com>
* sched-deps.c (remove_dependence, group_leader): Remove it.
(add_dependence): Add dependence to group leader to.
(set_sched_group_p): Add dependence to the first insn of the
schedule group too.
(sched_analyze_insn): Make dependence to jump as anti-dependence.
Change true dependence by anti-dependence when
`reg_pending_barrier'.
* sched-rgn.c (init_ready_list, can_schedule_ready_p,
add_branch_dependences): Ignore schedule groups.
* sched-ebb.c (init_ready_list): Ditto.
* (move_insn, set_priorities): Ditto.
* config/ia64/ia64.c (ia64_sched_init): Check that schedule group
flag is clear after reload.
(adjust_cost): Change cost only for output dependencies.
* config/ia64/ia64.md: Add more insns into bypass for MM-insns.
2002-09-26 Vladimir Makarov <vmakarov@redhat.com>
* Makefile.in (sched-ebb.o): Add `$(TARGET_H)' to the entry.
* target.h (gcc_target): Add member
`dependencies_evaluation_hook'.
* target-def.h (TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK): New
macro.
(TARGET_SCHED): Add initiatialization of the new member.
* sched-ebb.c: Include `target.h'.
(schedule_ebb): Call `dependencies_evaluation_hook'.
* sched-rgn.c (schedule_region): Call
`dependencies_evaluation_hook'.
* config/ia64/ia64.c (TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK):
New macro.
(ia64_dependencies_evaluation_hook): New function.
* doc/tm.texi (TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK):
Describe the new hook.
2002-09-25 Vladimir Makarov <vmakarov@redhat.com>
* target.h (gcc_target): Add members
`first_cycle_multipass_dfa_lookahead_guard' and `dfa_new_cycle'.
* target-def.h (TARGET_SCHED_DFA_NEW_CYCLE,
TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD): New
macros.
(TARGET_SCHED): Add initiatialization of the new members.
* haifa-sched.c (schedule_insn): Update last_clock_var for the 1st
insn scheduling too.
(choose_ready): Use `first_cycle_multipass_dfa_lookahead_guard' to
initialize `ready_try'.
(schedule_block): Use `dfa_new_cycle'. Sort `ready' only unless
`dfa_new_cycle' says not to do it.
* config/ia64/ia64.md: Add DFA Itanium 1 description for insn
bundling.
* config/ia64/ia64.h (CPU_UNITS_QUERY): New macro.
* config/ia64/ia64.c: Include `hashtab.h'.
(ia64_first_cycle_multipass_dfa_lookahead_guard,
ia64_dfa_new_cycle, final_emit_insn_group_barriers,
ia64_dfa_sched_reorder, get_free_bundle_state, free_bundle_state,
initiate_bundle_states, finish_bundle_states, bundle_state_hash,
bundle_state_eq_p, insert_bundle_state,
initiate_bundle_state_table, finish_bundle_state_table,
try_issue_nops, try_issue_insn, issue_nops_and_insn, get_max_pos,
get_template, get_next_important_insn, bundling): New functions.
(ia64_internal_sched_reorder): Remove it.
(TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD,
TARGET_SCHED_DFA_NEW_CYCLE): New macros.
(ia64_safe_itanium_requires_unit0): Remove it.
(group_barrier_needed_p): Place group barrier right before a real
insn.
(bundle, ia64_packet, NR_PACKETS, type_names, packets, packets):
Remove them.
(bundle_name): New variable.
(_0mii_, _0mmi_, _0mfi_, _0mmf_, _0bbb_, _0mbb_, _0mib_, _0mmb_,
_0mfb_, _0mlx_, _1mii_, _1mmi_, _1mfi_, _1mmf_, _1bbb_, _1mbb_,
_1mib_, _1mmb_, _1mfb_, _1mlx_, pos_1, pos_2, pos_3, pos_4, pos_5,
pos_6, dfa_stop_insn, last_scheduled_insn, dfa_state_size,
temp_dfa_state, prev_cycle_state): New global variables.
(insn_matches_slot, maybe_rotate, finish_last_head,
rotate_one_bundle, rotate_one_bundles, nop_cycles_until,
cycle_end_fill_slots, packet_matches_p, get_split, find_best_insn,
find_best_packet, itanium_reorder, dump_current_packet,
schedule_stop, gen_nop_type, ia64_emit_nops): Remove them.
(sched_data, sched_ready, sched_types): Remove them.
(ia64_sched_init): Initiate only `last_scheduled_insn' and call
`init_insn_group_barriers'.
(ia64_sched_reorder, ia64_sched_reorder2): Call
ia64_dfa_sched_reorder.
(ia64_variable_issue): Rewrite it.
(bundle_state): New structure.
(index_to_bundle_states, bundle_states_num,
allocated_bundle_states_chain, free_bundle_state_chain): New
global variables.
(ia64_sched_finish): Add stop bits and call `bundling' after the
2nd insn scheduling.
(ia64_use_dfa_pipeline_interface): Return zero always.
(ia64_first_cycle_multipass_dfa_lookahead): Return 6 for the 2nd
insn scheduling.
(ia64_init_dfa_pre_cycle_insn): Initialize `dfa_state_size',
`temp_dfa_state', `prev_cycle_state', and `dfa_stop_insn'.
(ia64_reorg): Add bundling insns.
* doc/tm.texi
(TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD,
TARGET_SCHED_DFA_NEW_CYCLE): Describe the new hooks.
2002-09-23 Vladimir Makarov <vmakarov@redhat.com>
* config/ia64/ia64.md: Add Itanium1 DFA description.
(itanium_class): Add `nop' and `pre_cycle'. Add
define_function_unit for `nop'.
(nop): Change attribute `itanium_class'.
(pre_cycle): New define_insn.
* config/ia64/ia64-protos.h (bundling_p): New external variable.
(ia64_st_address_bypass_p, ia64_ld_address_bypass_p,
ia64_produce_address_p): New function prototypes.
* config/ia64/ia64.c (bundling_p): New global variable.
(ia64_use_dfa_pipeline_interface,
ia64_first_cycle_multipass_dfa_lookahead,
ia64_init_dfa_pre_cycle_insn, ia64_dfa_pre_cycle_insn): New
functions.
(TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE,
TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD,
TARGET_SCHED_INIT_DFA_PRE_CYCLE_INSN,
TARGET_SCHED_DFA_PRE_CYCLE_INSN): New macros.
(ia64_sched_init, ia64_sched_reorder, ia64_sched_reorder2,
ia64_variable_issue, ia64_sched_finish): Do nothing before reload.
(dfa_pre_cycle_insn): New variable.
2002-09-20 Vladimir Makarov <vmakarov@redhat.com>
* rtl.def (FINAL_PRESENCE_SET, FINAL_ABSENCE_SET): New
constructions.
* genattrtab.h (gen_final_presence_set, gen_final_absence_set):
New function prototypes.
* genattrtab.c (main): Process the new constructions.
* genautomata.c (gen_presence_absence_set,
process_presence_absence_names, process_presence_absence_patterns,
add_presence_absence, check_absence_pattern_sets): Add parameter
`final_p'.
(unit_decl): Add new members `final_presence_list' and
`final_absence_list'.
(unit_pattern_rel_decl): Add new member `final_p'.
(gen_final_presence_set, gen_final_absence_set): New functions.
(process_decls): Use member `final_p'.
(temp_reserv): New global variable.
(reserv_sets_are_intersected): Add processing `final_presence_set'
and `final_absence_set'.
(initiate_states): Allocate `temp_reserv'.
(unit_final_presence_set_table, unit_final_absence_set_table): New
gloabal variables.
(initiate_presence_absence_pattern_sets): Initiate them.
(NDFA_to_DFA): Fix typo.
(output_description): Output `final_presence_set' and
`final_absence_set'.
* doc/md.texi (final_presence_set, final_absence_set): Describe
them.
2002-09-20 Vladimir Makarov <vmakarov@redhat.com>
* genautomata.c (transform_3): Process a missing case (nothing on
unit place).
2002-09-20 Vladimir Makarov <vmakarov@redhat.com>
* rtl.def (DEFINE_QUERY_CPU_UNIT, AUTOMATA_OPTION): Change
comments about queried units and the minimization.
* doc/md.texi: Ditto.
* genautomata.c (create_composed_state): Return nonzero if the new
state has been created.
(first_cycle_unit_presence): New function.
(state_is_differed): Add new parameter. Use the new function.
Take queried units into account.
(partition_equiv_class): Pass additional parameter to
`state_is_differed'.
(merge_states): Process composed states too.
(build_automaton, create_automata, output_min_issue_delay_table,
output_tables, output_statistics): Output more information.
(output_reserved_units_table): Use function
`first_cycle_unit_presence'.
(output_tables): Output table of queried units even if the
minimization is switched on.
(write_automata): Output code for querying units even if the
minimization is switched on.
2002-09-19 Vladimir Makarov <vmakarov@redhat.com>
* rtl.def (PRESENCE_SET, ABSENCE_SET): Add comments about extended
syntax of the constructions.
* doc/md.texi (PRESENCE_SET, ABSENCE_SET): Add description of
extended syntax of the constructions.
* genautomata.c (unit_rel_decl): Rename it to
`unit_pattern_rel_decl'.
(pattern_set_el, pattern_reserv): New structures.
(pattern_set_el_t, pattern_reserv_t): New types.
(gen_presence_absence_set): New function.
(process_presence_absence): Remove it.
(process_presence_absence_names,
process_presence_absence_patterns): New functions.
(get_presence_absence_set): Remove it.
(initiate_presence_absence_sets): Rename it on
`initiate_presence_absence_pattern_sets'. Use new function
`form_reserv_sets_list'.
(form_reserv_sets_list, check_presence_pattern_sets,
check_absence_pattern_sets, output_pattern_set_el_list): New
functions.
(unit_decl): Change types of members `presence_list' and
`absence_list'.
(unit_rel_decl): Rename member `names_num' to `all_names_num'.
(decl): Change types of members `excl', `presence', and `absence'.
(get_str_vect): Rename `par_flag' to `paren_p'. Add null element
at the end of the vector.
(gen_cpu_unit, gen_query_cpu_unit, gen_bypass, gen_excl_set,
gen_automaton, gen_regexp_repeat, gen_regexp_allof,
gen_regexp_oneof, gen_regexp_sequence): Use boolean values.
(gen_presence_set, gen_absence_set): Use new function
`gen_presence_absence_set'.
(add_presence_absence): Process `pattern_list' instead of
`source_list'.
(process_decls): USe new functions
`process_presence_absence_names' and
`process_presence_absence_patterns'.
(reserv_sets_are_intersected): Use new function
`check_presence_pattern_sets'.
(presence_set, absence_set): Remove them.
(unit_presence_set_table, unit_absence_set_table): New global
variables.
(output_description): Use new function
`output_pattern_set_el_list'.
(generate): Use `initiate_presence_absence_pattern_sets'.
2002-09-18 Vladimir Makarov <vmakarov@redhat.com>
* genattr.c (main): Add output of prototype of new interface
function `dfa_clean_insn_cache'.
* genautomata.c (output_dfa_clean_insn_cache_func): New function.
(DFA_CLEAN_INSN_CACHE_FUNC_NAME): New macro.
(output_dfa_start_func): Use function `dfa_clean_insn_cache' in
the generated code.
(write_automata): Call the new function.
Thu Jan 9 22:47:38 CET 2003 Jan Hubicka <jh@suse.cz>
* i386.md (unit, prefix_0f, memory attributes): Hanlde sseicvt correctly.

View File

@ -27,7 +27,11 @@ extern GTY(()) rtx ia64_compare_op1;
/* Functions defined in ia64.c */
extern int bundling_p;
#ifdef RTX_CODE
extern int ia64_st_address_bypass_p PARAMS((rtx, rtx));
extern int ia64_ld_address_bypass_p PARAMS((rtx, rtx));
extern int ia64_produce_address_p PARAMS((rtx));
extern int call_operand PARAMS((rtx, enum machine_mode));
extern int sdata_symbolic_operand PARAMS((rtx, enum machine_mode));
extern int got_symbolic_operand PARAMS((rtx, enum machine_mode));

File diff suppressed because it is too large Load Diff

View File

@ -95,6 +95,8 @@ extern int target_flags;
#define MASK_DWARF2_ASM 0x40000000 /* test dwarf2 line info via gas. */
#define MASK_EARLY_STOP_BITS 0x00002000 /* tune stop bits for the model. */
#define TARGET_BIG_ENDIAN (target_flags & MASK_BIG_ENDIAN)
#define TARGET_GNU_AS (target_flags & MASK_GNU_AS)
@ -137,6 +139,7 @@ extern int ia64_tls_size;
#define TARGET_TLS14 (ia64_tls_size == 14)
#define TARGET_TLS22 (ia64_tls_size == 22)
#define TARGET_TLS64 (ia64_tls_size == 64)
#define TARGET_EARLY_STOP_BITS (target_flags & MASK_EARLY_STOP_BITS)
#define TARGET_HPUX_LD 0
@ -188,6 +191,10 @@ extern int ia64_tls_size;
N_("Enable Dwarf 2 line debug info via GNU as")}, \
{ "no-dwarf2-asm", -MASK_DWARF2_ASM, \
N_("Disable Dwarf 2 line debug info via GNU as")}, \
{ "early-stop-bits", MASK_EARLY_STOP_BITS, \
N_("Enable earlier placing stop bits for better scheduling")}, \
{ "no-early-stop-bits", -MASK_EARLY_STOP_BITS, \
N_("Disable earlier placing stop bits")}, \
SUBTARGET_SWITCHES \
{ "", TARGET_DEFAULT | TARGET_CPU_DEFAULT, \
NULL } \
@ -213,12 +220,30 @@ extern int ia64_tls_size;
extern const char *ia64_fixed_range_string;
extern const char *ia64_tls_size_string;
/* Which processor to schedule for. The cpu attribute defines a list
that mirrors this list, so changes to i64.md must be made at the
same time. */
enum processor_type
{
PROCESSOR_ITANIUM, /* Original Itanium. */
PROCESSOR_ITANIUM2,
PROCESSOR_max
};
extern enum processor_type ia64_tune;
extern const char *ia64_tune_string;
#define TARGET_OPTIONS \
{ \
{ "fixed-range=", &ia64_fixed_range_string, \
N_("Specify range of registers to make fixed")}, \
{ "tls-size=", &ia64_tls_size_string, \
N_("Specify bit size of immediate TLS offsets")}, \
{ "tune=", &ia64_tune_string, \
N_("Schedule code for given CPU")}, \
}
/* Sometimes certain combinations of command options do not make sense on a
@ -2485,4 +2510,9 @@ enum fetchop_code {
#undef PROFILE_BEFORE_PROLOGUE
#define PROFILE_BEFORE_PROLOGUE 1
/* Switch on code for querying unit reservations. */
#define CPU_UNITS_QUERY 1
/* End of ia64.h */

View File

@ -91,6 +91,10 @@
;; ::
;; ::::::::::::::::::::
;; Processor type. This attribute must exactly match the processor_type
;; enumeration in ia64.h.
(define_attr "cpu" "itanium,itanium2" (const (symbol_ref "ia64_tune")))
;; Instruction type. This primarily determines how instructions can be
;; packed in bundles, and secondarily affects scheduling to function units.
@ -110,8 +114,8 @@
(define_attr "itanium_class" "unknown,ignore,stop_bit,br,fcmp,fcvtfx,fld,
fmac,fmisc,frar_i,frar_m,frbr,frfr,frpr,ialu,icmp,ilog,ishf,ld,
chk_s,long_i,mmmul,mmshf,mmshfi,rse_m,scall,sem,stf,st,syst_m0,
syst_m,tbit,toar_i,toar_m,tobr,tofr,topr,xmpy,xtd,nop_b,nop_f,
nop_i,nop_m,nop_x,lfetch"
syst_m,tbit,toar_i,toar_m,tobr,tofr,topr,xmpy,xtd,nop,nop_b,nop_f,
nop_i,nop_m,nop_x,lfetch,pre_cycle"
(const_string "unknown"))
;; chk_s has an I and an M form; use type A for convenience.
@ -146,76 +150,23 @@
(define_attr "predicable" "no,yes" (const_string "yes"))
;; ::::::::::::::::::::
;; ::
;; :: Function Units
;; ::
;; ::::::::::::::::::::
;; We define 6 "dummy" functional units. All the real work to decide which
;; insn uses which unit is done by our MD_SCHED_REORDER hooks. We only
;; have to ensure here that there are enough copies of the dummy unit so
;; that the scheduler doesn't get confused by MD_SCHED_REORDER.
;; Other than the 6 dummies for normal insns, we also add a single dummy unit
;; for stop bits.
;; DFA descriptions of ia64 processors used for insn scheduling and
;; bundling.
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "br") 0 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "scall") 0 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fcmp") 2 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fcvtfx") 7 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fld") 9 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fmac") 5 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fmisc") 5 0)
(automata_option "ndfa")
;; There is only one insn `mov = ar.bsp' for frar_i:
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frar_i") 13 0)
;; There is only ony insn `mov = ar.unat' for frar_m:
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frar_m") 6 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frbr") 2 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frfr") 2 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frpr") 2 0)
;; Uncomment the following line to output automata for debugging.
;; (automata_option "v")
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ialu") 1 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "icmp") 1 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ilog") 1 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ishf") 1 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ld") 2 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "long_i") 1 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "mmmul") 2 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "mmshf") 2 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "mmshfi") 2 0)
(automata_option "w")
;; Now we have only one insn (flushrs) of such class. We assume that flushrs
;; is the 1st syllable of the bundle after stop bit.
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "rse_m") 0 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "sem") 11 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "stf") 1 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "st") 1 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "syst_m0") 1 0)
;; Now we use only one insn `mf'. Therfore latency time is set up to 0.
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "syst_m") 0 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "tbit") 1 0)
;;(automata_option "no-minimization")
;; There is only one insn `mov ar.pfs =' for toar_i therefore we use
;; latency time equal to 0:
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "toar_i") 0 0)
;; There are only ony 2 insns `mov ar.ccv =' and `mov ar.unat =' for toar_m:
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "toar_m") 5 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "tobr") 1 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "tofr") 9 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "topr") 1 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "xmpy") 7 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "xtd") 1 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_m") 0 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_i") 0 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_f") 0 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_b") 0 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_x") 0 0)
(include "itanium1.md")
(include "itanium2.md")
(define_function_unit "stop_bit" 1 1 (eq_attr "itanium_class" "stop_bit") 0 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ignore") 0 0)
(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "unknown") 0 0)
;; ::::::::::::::::::::
;; ::
@ -5089,7 +5040,7 @@
[(const_int 0)]
""
"nop 0"
[(set_attr "itanium_class" "unknown")])
[(set_attr "itanium_class" "nop")])
(define_insn "nop_m"
[(const_int 1)]
@ -5121,6 +5072,14 @@
""
[(set_attr "itanium_class" "nop_x")])
;; The following insn will be never generated. It is used only by
;; insn scheduler to change state before advancing cycle.
(define_insn "pre_cycle"
[(const_int 6)]
""
""
[(set_attr "itanium_class" "pre_cycle")])
(define_insn "bundle_selector"
[(unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BUNDLE_SELECTOR)]
""

1616
gcc/config/ia64/itanium1.md Normal file

File diff suppressed because it is too large Load Diff

1762
gcc/config/ia64/itanium2.md Normal file

File diff suppressed because it is too large Load Diff

View File

@ -9519,6 +9519,14 @@ A fixed register is one that the register allocator can not use. This is
useful when compiling kernel code. A register range is specified as
two registers separated by a dash. Multiple register ranges can be
specified separated by a comma.
@item -mearly-stop-bits
@itemx -mno-early-stop-bits
@opindex mearly-stop-bits
@opindex mno-early-stop-bits
Allow stop bits to be placed earlier than immediately preceding the
instruction that triggered the stop bit. This can improve instruction
scheduling, but does not always do so.
@end table
@node D30V Options

View File

@ -5586,16 +5586,23 @@ which the unit is bound. The automaton should be described in
construction @code{define_automaton}. You should give
@dfn{automaton-name}, if there is a defined automaton.
The assignment of units to automata are constrained by the uses of the
units in insn reservations. The most important constraint is: if a
unit reservation is present on a particular cycle of an alternative
for an insn reservation, then some unit from the same automaton must
be present on the same cycle for the other alternatives of the insn
reservation. The rest of the constraints are mentioned in the
description of the subsequent constructions.
@findex define_query_cpu_unit
@cindex querying function unit reservations
The following construction describes CPU functional units analogously
to @code{define_cpu_unit}. If we use automata without their
minimization, the reservation of such units can be queried for an
automaton state. The instruction scheduler never queries reservation
of functional units for given automaton state. So as a rule, you
don't need this construction. This construction could be used for
future code generation goals (e.g. to generate @acronym{VLIW} insn
templates).
to @code{define_cpu_unit}. The reservation of such units can be
queried for an automaton state. The instruction scheduler never
queries reservation of functional units for given automaton state. So
as a rule, you don't need this construction. This construction could
be used for future code generation goals (e.g. to generate
@acronym{VLIW} insn templates).
@smallexample
(define_query_cpu_unit @var{unit-names} [@var{automaton-name}])
@ -5744,7 +5751,9 @@ of insn @samp{store} (not a stored value).
@findex exclusion_set
@findex presence_set
@findex final_presence_set
@findex absence_set
@findex final_absence_set
@cindex VLIW
@cindex RISC
Usually the following three constructions are used to describe
@ -5754,13 +5763,19 @@ used for @acronym{RISC} processors too.
@smallexample
(exclusion_set @var{unit-names} @var{unit-names})
(presence_set @var{unit-names} @var{unit-names})
(absence_set @var{unit-names} @var{unit-names})
(presence_set @var{unit-names} @var{patterns})
(final_presence_set @var{unit-names} @var{patterns})
(absence_set @var{unit-names} @var{patterns})
(final_absence_set @var{unit-names} @var{patterns})
@end smallexample
@var{unit-names} is a string giving names of functional units
separated by commas.
@var{patterns} is a string giving patterns of functional units
separated by comma. Currently pattern is is one unit or units
separated by white-spaces.
The first construction (@samp{exclusion_set}) means that each
functional unit in the first string can not be reserved simultaneously
with a unit whose name is in the second string and vice versa. For
@ -5771,22 +5786,75 @@ point insns or only double floating point insns.
The second construction (@samp{presence_set}) means that each
functional unit in the first string can not be reserved unless at
least one of units whose names are in the second string is reserved.
This is an asymmetric relation. For example, it is useful for
description that @acronym{VLIW} @samp{slot1} is reserved after
@samp{slot0} reservation.
least one of pattern of units whose names are in the second string is
reserved. This is an asymmetric relation. For example, it is useful
for description that @acronym{VLIW} @samp{slot1} is reserved after
@samp{slot0} reservation. We could describe it by the following
construction
The third construction (@samp{absence_set}) means that each functional
unit in the first string can be reserved only if each unit whose name
is in the second string is not reserved. This is an asymmetric
relation (actually @samp{exclusion_set} is analogous to this one but
it is symmetric). For example, it is useful for description that
@acronym{VLIW} @samp{slot0} can not be reserved after @samp{slot1} or
@samp{slot2} reservation.
@smallexample
(presence_set "slot1" "slot0")
@end smallexample
Or @samp{slot1} is reserved only after @samp{slot0} and unit @samp{b0}
reservation. In this case we could write
@smallexample
(presence_set "slot1" "slot0 b0")
@end smallexample
The third construction (@samp{final_presence_set}) is analogous to
@samp{presence_set}. The difference between them is when checking is
done. When an instruction is issued in given automaton state
reflecting all current and planned unit reservations, the automaton
state is changed. The first state is a source state, the second one
is a result state. Checking for @samp{presence_set} is done on the
source state reservation, checking for @samp{final_presence_set} is
done on the result reservation. This construction is useful to
describe a reservation which is actually two subsequent reservations.
For example, if we use
@smallexample
(presence_set "slot1" "slot0")
@end smallexample
the following insn will be never issued (because @samp{slot1} requires
@samp{slot0} which is absent in the source state).
@smallexample
(define_reservation "insn_and_nop" "slot0 + slot1")
@end smallexample
but it can be issued if we use analogous @samp{final_presence_set}.
The forth construction (@samp{absence_set}) means that each functional
unit in the first string can be reserved only if each pattern of units
whose names are in the second string is not reserved. This is an
asymmetric relation (actually @samp{exclusion_set} is analogous to
this one but it is symmetric). For example, it is useful for
description that @acronym{VLIW} @samp{slot0} can not be reserved after
@samp{slot1} or @samp{slot2} reservation. We could describe it by the
following construction
@smallexample
(absence_set "slot2" "slot0, slot1")
@end smallexample
Or @samp{slot2} can not be reserved if @samp{slot0} and unit @samp{b0}
are reserved or @samp{slot1} and unit @samp{b1} are reserved. In
this case we could write
@smallexample
(absence_set "slot2" "slot0 b0, slot1 b1")
@end smallexample
All functional units mentioned in a set should belong to the same
automaton.
The last construction (@samp{final_absence_set}) is analogous to
@samp{absence_set} but checking is done on the result (state)
reservation. See comments for @samp{final_presence_set}.
@findex automata_option
@cindex deterministic finite state automaton
@cindex nondeterministic finite state automaton
@ -5804,8 +5872,8 @@ code. Currently there are the following options:
@itemize @bullet
@item
@dfn{no-minimization} makes no minimization of the automaton. This is
only worth to do when we are going to query CPU functional unit
reservations in an automaton state.
only worth to do when we are debugging the description and need to
look more accurately at reservations of states.
@item
@dfn{time} means printing additional time statistics about

View File

@ -5629,6 +5629,16 @@ 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_DEPENDENCIES_EVALUATION_HOOK (rtx @var{head}, rtx @var{tail})
This hook is called after evaluation forward dependencies of insns in
chain given by two parameter values (@var{head} and @var{tail}
correspondingly) but before insns scheduling of the insn chain. For
example, it can be used for better insn classification if it requires
analysis of dependencies. This hook can use backward and forward
dependencies of the insn scheduler because they are already
calculated.
@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
@ -5715,6 +5725,30 @@ schedules to choose the best one.
The default is no multipass scheduling.
@end deftypefn
@deftypefn {Target Hook} int TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD (rtx)
This hook controls what insns from the ready insn queue will be
considered for the multipass insn scheduling. If the hook returns
zero for insn passed as the parameter, the insn will be not chosen to
be issued.
The default is that any ready insns can be choosen to be issued.
@end deftypefn
@deftypefn {Target Hook} int TARGET_SCHED_DFA_NEW_CYCLE (FILE *, int, rtx, int, int, int *)
This hook is called by the insn scheduler before issuing insn passed
as the third parameter on given cycle. If the hook returns nonzero,
the insn is not issued on given processors cycle. Instead of that,
the processor cycle is advanced. If the value passed through the last
parameter is zero, the insn ready queue is not sorted on the new cycle
start as usually. The first parameter passes file for debugging
output. The second one passes the scheduler verbose level of the
debugging output. The forth and the fifth parameter values are
correspondingly processor cycle on which the previous insn has been
issued and the current processor cycle.
@end deftypefn
@deftypefn {Target Hook} void TARGET_SCHED_INIT_DFA_BUBBLES (void)
The @acronym{DFA}-based scheduler could take the insertion of nop
operations for better insn scheduling into account. It can be done

View File

@ -441,6 +441,11 @@ main (argc, argv)
printf (" unit with given code is currently reserved in given\n");
printf (" DFA state. */\n");
printf ("extern int cpu_unit_reservation_p PARAMS ((state_t, int));\n");
printf ("/* Clean insn code cache. It should be called if there\n");
printf (" is a chance that condition value in a\n");
printf (" define_insn_reservation will be changed after\n");
printf (" last call of dfa_start. */\n");
printf ("extern void dfa_clean_insn_cache PARAMS ((void));\n\n");
printf ("#endif\n\n");
printf ("/* Initiate and finish work with DFA. They should be\n");
printf (" called as the first and the last interface\n");

View File

@ -6115,10 +6115,18 @@ from the machine description file `md'. */\n\n");
gen_presence_set (desc);
break;
case FINAL_PRESENCE_SET:
gen_final_presence_set (desc);
break;
case ABSENCE_SET:
gen_absence_set (desc);
break;
case FINAL_ABSENCE_SET:
gen_final_absence_set (desc);
break;
case DEFINE_AUTOMATON:
gen_automaton (desc);
break;

View File

@ -33,7 +33,9 @@ extern void gen_query_cpu_unit PARAMS ((rtx));
extern void gen_bypass PARAMS ((rtx));
extern void gen_excl_set PARAMS ((rtx));
extern void gen_presence_set PARAMS ((rtx));
extern void gen_final_presence_set PARAMS ((rtx));
extern void gen_absence_set PARAMS ((rtx));
extern void gen_final_absence_set PARAMS ((rtx));
extern void gen_automaton PARAMS ((rtx));
extern void gen_automata_option PARAMS ((rtx));
extern void gen_reserv PARAMS ((rtx));

File diff suppressed because it is too large Load Diff

View File

@ -320,6 +320,7 @@ static int rank_for_schedule PARAMS ((const PTR, const PTR));
static void swap_sort PARAMS ((rtx *, int));
static void queue_insn PARAMS ((rtx, int));
static void schedule_insn PARAMS ((rtx, struct ready_list *, int));
static int find_set_reg_weight PARAMS ((rtx));
static void find_insn_reg_weight PARAMS ((int));
static void adjust_priority PARAMS ((rtx));
static void advance_one_cycle PARAMS ((void));
@ -366,7 +367,7 @@ static rtx move_insn PARAMS ((rtx, rtx));
on the first cycle. It is used only for DFA based scheduler. */
static rtx ready_element PARAMS ((struct ready_list *, int));
static rtx ready_remove PARAMS ((struct ready_list *, int));
static int max_issue PARAMS ((struct ready_list *, state_t, int *));
static int max_issue PARAMS ((struct ready_list *, int *));
static rtx choose_ready PARAMS ((struct ready_list *));
@ -853,6 +854,7 @@ rank_for_schedule (x, y)
/* Prefer insn with higher priority. */
priority_val = INSN_PRIORITY (tmp2) - INSN_PRIORITY (tmp);
if (priority_val)
return priority_val;
@ -1017,8 +1019,10 @@ ready_element (ready, index)
struct ready_list *ready;
int index;
{
#ifdef ENABLE_CHECKING
if (ready->n_ready == 0 || index >= ready->n_ready)
abort ();
#endif
return ready->vec[ready->first - index];
}
@ -1195,11 +1199,12 @@ schedule_insn (insn, ready, clock)
to issue on the same cycle as the previous insn. A machine
may use this information to decide how the instruction should
be aligned. */
if (reload_completed && issue_rate > 1
if (issue_rate > 1
&& GET_CODE (PATTERN (insn)) != USE
&& GET_CODE (PATTERN (insn)) != CLOBBER)
{
PUT_MODE (insn, clock > last_clock_var ? TImode : VOIDmode);
if (reload_completed)
PUT_MODE (insn, clock > last_clock_var ? TImode : VOIDmode);
last_clock_var = clock;
}
}
@ -1536,6 +1541,32 @@ rm_other_notes (head, tail)
/* Functions for computation of registers live/usage info. */
/* This function looks for a new register being defined.
If the destination register is already used by the source,
a new register is not needed. */
static int
find_set_reg_weight (x)
rtx x;
{
if (GET_CODE (x) == CLOBBER
&& register_operand (SET_DEST (x), VOIDmode))
return 1;
if (GET_CODE (x) == SET
&& register_operand (SET_DEST (x), VOIDmode))
{
if (GET_CODE (SET_DEST (x)) == REG)
{
if (!reg_mentioned_p (SET_DEST (x), SET_SRC (x)))
return 1;
else
return 0;
}
return 1;
}
return 0;
}
/* Calculate INSN_REG_WEIGHT for all insns of a block. */
static void
@ -1558,21 +1589,16 @@ find_insn_reg_weight (b)
/* Increment weight for each register born here. */
x = PATTERN (insn);
if ((GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
&& register_operand (SET_DEST (x), VOIDmode))
reg_weight++;
else if (GET_CODE (x) == PARALLEL)
{
int j;
for (j = XVECLEN (x, 0) - 1; j >= 0; j--)
{
x = XVECEXP (PATTERN (insn), 0, j);
if ((GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
&& register_operand (SET_DEST (x), VOIDmode))
reg_weight++;
}
}
reg_weight += find_set_reg_weight (x);
if (GET_CODE (x) == PARALLEL)
{
int j;
for (j = XVECLEN (x, 0) - 1; j >= 0; j--)
{
x = XVECEXP (PATTERN (insn), 0, j);
reg_weight += find_set_reg_weight (x);
}
}
/* Decrement weight for each register that dies here. */
for (x = REG_NOTES (insn); x; x = XEXP (x, 1))
{
@ -1743,25 +1769,6 @@ move_insn (insn, last)
{
rtx retval = NULL;
/* If INSN has SCHED_GROUP_P set, then issue it and any other
insns with SCHED_GROUP_P set first. */
while (SCHED_GROUP_P (insn))
{
rtx prev = PREV_INSN (insn);
/* Move a SCHED_GROUP_P insn. */
move_insn1 (insn, last);
/* If this is the first call to reemit_notes, then record
its return value. */
if (retval == NULL_RTX)
retval = reemit_notes (insn, insn);
else
reemit_notes (insn, insn);
/* Consume SCHED_GROUP_P flag. */
SCHED_GROUP_P (insn) = 0;
insn = prev;
}
/* Now move the first non SCHED_GROUP_P insn. */
move_insn1 (insn, last);
@ -1772,90 +1779,109 @@ move_insn (insn, last)
else
reemit_notes (insn, insn);
SCHED_GROUP_P (insn) = 0;
return retval;
}
/* The following structure describe an entry of the stack of choices. */
struct choice_entry
{
/* Ordinal number of the issued insn in the ready queue. */
int index;
/* The number of the rest insns whose issues we should try. */
int rest;
/* The number of issued essential insns. */
int n;
/* State after issuing the insn. */
state_t state;
};
/* The following array is used to implement a stack of choices used in
function max_issue. */
static struct choice_entry *choice_stack;
/* The following variable value is number of essential insns issued on
the current cycle. An insn is essential one if it changes the
processors state. */
static int cycle_issued_insns;
/* The following function returns maximal (or close to maximal) number
of insns which can be issued on the same cycle and one of which
insns is insns with the best rank (the last insn in READY). To
insns is insns with the best rank (the first insn in READY). To
make this function tries different samples of ready insns. READY
is current queue `ready'. Global array READY_TRY reflects what
insns are already issued in this try. STATE is current processor
state. If the function returns nonzero, INDEX will contain index
insns are already issued in this try. INDEX will contain index
of the best insn in READY. The following function is used only for
first cycle multipass scheduling. */
static int
max_issue (ready, state, index)
struct ready_list *ready;
state_t state;
int *index;
max_issue (ready, index)
struct ready_list *ready;
int *index;
{
int i, best, n, temp_index, delay;
state_t temp_state;
int n, i, all, n_ready, lookahead, best, delay;
struct choice_entry *top;
rtx insn;
int max_lookahead = (*targetm.sched.first_cycle_multipass_dfa_lookahead) ();
if (state_dead_lock_p (state))
return 0;
temp_state = alloca (dfa_state_size);
lookahead = (*targetm.sched.first_cycle_multipass_dfa_lookahead) ();
best = 0;
for (i = 0; i < ready->n_ready; i++)
memcpy (choice_stack->state, curr_state, dfa_state_size);
top = choice_stack;
top->rest = lookahead;
top->n = 0;
n_ready = ready->n_ready;
for (all = i = 0; i < n_ready; i++)
if (!ready_try [i])
{
insn = ready_element (ready, i);
if (INSN_CODE (insn) < 0)
continue;
memcpy (temp_state, state, dfa_state_size);
delay = state_transition (temp_state, insn);
if (delay == 0)
{
if (!targetm.sched.dfa_bubble)
continue;
else
{
int j;
rtx bubble;
for (j = 0;
(bubble = (*targetm.sched.dfa_bubble) (j)) != NULL_RTX;
j++)
if (state_transition (temp_state, bubble) < 0
&& state_transition (temp_state, insn) < 0)
break;
if (bubble == NULL_RTX)
continue;
}
}
else if (delay > 0)
continue;
--max_lookahead;
if (max_lookahead < 0)
break;
ready_try [i] = 1;
n = max_issue (ready, temp_state, &temp_index);
if (n > 0 || ready_try[0])
n += 1;
if (best < n)
{
best = n;
*index = i;
}
ready_try [i] = 0;
}
all++;
i = 0;
for (;;)
{
if (top->rest == 0 || i >= n_ready)
{
if (top == choice_stack)
break;
if (best < top - choice_stack && ready_try [0])
{
best = top - choice_stack;
*index = choice_stack [1].index;
if (top->n == issue_rate - cycle_issued_insns || best == all)
break;
}
i = top->index;
ready_try [i] = 0;
top--;
memcpy (curr_state, top->state, dfa_state_size);
}
else if (!ready_try [i])
{
insn = ready_element (ready, i);
delay = state_transition (curr_state, insn);
if (delay < 0)
{
if (state_dead_lock_p (curr_state))
top->rest = 0;
else
top->rest--;
n = top->n;
if (memcmp (top->state, curr_state, dfa_state_size) != 0)
n++;
top++;
top->rest = lookahead;
top->index = i;
top->n = n;
memcpy (top->state, curr_state, dfa_state_size);
ready_try [i] = 1;
i = -1;
}
}
i++;
}
while (top != choice_stack)
{
ready_try [top->index] = 0;
top--;
}
memcpy (curr_state, choice_stack->state, dfa_state_size);
return best;
}
@ -1873,9 +1899,21 @@ choose_ready (ready)
else
{
/* Try to choose the better insn. */
int index;
int index, i;
rtx insn;
if (max_issue (ready, curr_state, &index) == 0)
insn = ready_element (ready, 0);
if (INSN_CODE (insn) < 0)
return ready_remove_first (ready);
for (i = 1; i < ready->n_ready; i++)
{
insn = ready_element (ready, i);
ready_try [i]
= (INSN_CODE (insn) < 0
|| (targetm.sched.first_cycle_multipass_dfa_lookahead_guard
&& !(*targetm.sched.first_cycle_multipass_dfa_lookahead_guard) (insn)));
}
if (max_issue (ready, &index) == 0)
return ready_remove_first (ready);
else
return ready_remove (ready, index);
@ -1903,9 +1941,10 @@ schedule_block (b, rgn_n_insns)
int rgn_n_insns;
{
struct ready_list ready;
int first_cycle_insn_p;
int i, first_cycle_insn_p;
int can_issue_more;
state_t temp_state = NULL; /* It is used for multipass scheduling. */
int sort_p;
/* Head/tail info for this block. */
rtx prev_head = current_sched_info->prev_head;
@ -1957,6 +1996,11 @@ schedule_block (b, rgn_n_insns)
temp_state = alloca (dfa_state_size);
ready_try = (char *) xmalloc ((rgn_n_insns + 1) * sizeof (char));
memset (ready_try, 0, (rgn_n_insns + 1) * sizeof (char));
choice_stack
= (struct choice_entry *) xmalloc ((rgn_n_insns + 1)
* sizeof (struct choice_entry));
for (i = 0; i <= rgn_n_insns; i++)
choice_stack[i].state = (state_t) xmalloc (dfa_state_size);
}
(*current_sched_info->init_ready_list) (&ready);
@ -1985,6 +2029,7 @@ schedule_block (b, rgn_n_insns)
/* Start just before the beginning of time. */
clock_var = -1;
sort_p = TRUE;
/* Loop until all the insns in BB are scheduled. */
while ((*current_sched_info->schedule_more_p) ())
{
@ -2007,8 +2052,17 @@ schedule_block (b, rgn_n_insns)
debug_ready_list (&ready);
}
/* Sort the ready list based on priority. */
ready_sort (&ready);
if (sort_p)
{
/* Sort the ready list based on priority. */
ready_sort (&ready);
if (sched_verbose >= 2)
{
fprintf (sched_dump, ";;\t\tReady list after ready_sort: ");
debug_ready_list (&ready);
}
}
/* Allow the target to reorder the list, typically for
better instruction bundling. */
@ -2021,6 +2075,7 @@ schedule_block (b, rgn_n_insns)
can_issue_more = issue_rate;
first_cycle_insn_p = 1;
cycle_issued_insns = 0;
for (;;)
{
rtx insn;
@ -2050,8 +2105,21 @@ schedule_block (b, rgn_n_insns)
break;
/* Select and remove the insn from the ready list. */
insn = choose_ready (&ready);
if (sort_p)
insn = choose_ready (&ready);
else
insn = ready_remove_first (&ready);
if (targetm.sched.dfa_new_cycle
&& (*targetm.sched.dfa_new_cycle) (sched_dump, sched_verbose,
insn, last_clock_var,
clock_var, &sort_p))
{
ready_add (&ready, insn);
break;
}
sort_p = TRUE;
memcpy (temp_state, curr_state, dfa_state_size);
if (recog_memoized (insn) < 0)
{
@ -2155,7 +2223,11 @@ schedule_block (b, rgn_n_insns)
if (targetm.sched.use_dfa_pipeline_interface
&& (*targetm.sched.use_dfa_pipeline_interface) ())
memcpy (curr_state, temp_state, dfa_state_size);
{
if (memcmp (curr_state, temp_state, dfa_state_size) != 0)
cycle_issued_insns++;
memcpy (curr_state, temp_state, dfa_state_size);
}
if (targetm.sched.variable_issue)
can_issue_more =
@ -2172,13 +2244,16 @@ schedule_block (b, rgn_n_insns)
next:
first_cycle_insn_p = 0;
/* Sort the ready list based on priority. This must be
redone here, as schedule_insn may have readied additional
insns that will not be sorted correctly. */
if (ready.n_ready > 0)
ready_sort (&ready);
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,
(*targetm.sched.reorder2) (sched_dump, sched_verbose,
ready.n_ready
? ready_lastpos (&ready) : NULL,
&ready.n_ready, clock_var);
@ -2214,6 +2289,27 @@ schedule_block (b, rgn_n_insns)
head = NEXT_INSN (prev_head);
tail = last_scheduled_insn;
if (!reload_completed)
{
rtx insn, link, next;
/* INSN_TICK (minimum clock tick at which the insn becomes
ready) may be not correct for the insn in the subsequent
blocks of the region. We should use a correct value of
`clock_var' or modify INSN_TICK. It is better to keep
clock_var value equal to 0 at the start of a basic block.
Therefore we modify INSN_TICK here. */
for (insn = head; insn != tail; insn = NEXT_INSN (insn))
if (INSN_P (insn))
{
for (link = INSN_DEPEND (insn); link != 0; link = XEXP (link, 1))
{
next = XEXP (link, 0);
INSN_TICK (next) -= clock_var;
}
}
}
/* Restore-other-notes: NOTE_LIST is the end of a chain of notes
previously found among the insns. Insert them at the beginning
of the insns. */
@ -2250,7 +2346,12 @@ schedule_block (b, rgn_n_insns)
if (targetm.sched.use_dfa_pipeline_interface
&& (*targetm.sched.use_dfa_pipeline_interface) ())
free (ready_try);
{
free (ready_try);
for (i = 0; i <= rgn_n_insns; i++)
free (choice_stack [i].state);
free (choice_stack);
}
}
/* Set_priorities: compute priority of each insn in the block. */
@ -2275,8 +2376,7 @@ set_priorities (head, tail)
if (GET_CODE (insn) == NOTE)
continue;
if (!(SCHED_GROUP_P (insn)))
n_insn++;
n_insn++;
(void) priority (insn);
}

View File

@ -358,9 +358,8 @@ DEF_RTL_EXPR(ADDRESS, "address", "e", 'm')
DEF_RTL_EXPR(DEFINE_CPU_UNIT, "define_cpu_unit", "sS", 'x')
/* (define_query_cpu_unit string [string]) describes cpu functional
units analogously to define_cpu_unit. If we use automaton without
minimization, the reservation of such units can be queried for
automaton state. */
units analogously to define_cpu_unit. The reservation of such
units can be queried for automaton state. */
DEF_RTL_EXPR(DEFINE_QUERY_CPU_UNIT, "define_query_cpu_unit", "sS", 'x')
/* (exclusion_set string string) means that each CPU functional unit
@ -370,28 +369,80 @@ DEF_RTL_EXPR(DEFINE_QUERY_CPU_UNIT, "define_query_cpu_unit", "sS", 'x')
for description CPU with fully pipelined floating point functional
unit which can execute simultaneously only single floating point
insns or only double floating point insns. All CPU functional
units in a set should belong the same automaton. */
units in a set should belong to the same automaton. */
DEF_RTL_EXPR(EXCLUSION_SET, "exclusion_set", "ss", 'x')
/* (presence_set string string) means that each CPU functional unit in
the first string can not be reserved unless at least one of units
whose names are in the second string is reserved. This is an
asymmetric relation. CPU units in the string are separated by
commas. For example, it is useful for description that slot1 is
reserved after slot0 reservation for VLIW processor. All CPU
functional units in a set should belong the same automaton. */
the first string can not be reserved unless at least one of pattern
of units whose names are in the second string is reserved. This is
an asymmetric relation. CPU units or unit patterns in the strings
are separated by commas. Pattern is one unit name or unit names
separated by white-spaces.
For example, it is useful for description that slot1 is reserved
after slot0 reservation for a VLIW processor. We could describe it
by the following construction
(presence_set "slot1" "slot0")
Or slot1 is reserved only after slot0 and unit b0 reservation. In
this case we could write
(presence_set "slot1" "slot0 b0")
All CPU functional units in a set should belong to the same
automaton. */
DEF_RTL_EXPR(PRESENCE_SET, "presence_set", "ss", 'x')
/* (final_presence_set string string) is analogous to `presence_set'.
The difference between them is when checking is done. When an
instruction is issued in given automaton state reflecting all
current and planned unit reservations, the automaton state is
changed. The first state is a source state, the second one is a
result state. Checking for `presence_set' is done on the source
state reservation, checking for `final_presence_set' is done on the
result reservation. This construction is useful to describe a
reservation which is actually two subsequent reservations. For
example, if we use
(presence_set "slot1" "slot0")
the following insn will be never issued (because slot1 requires
slot0 which is absent in the source state).
(define_reservation "insn_and_nop" "slot0 + slot1")
but it can be issued if we use analogous `final_presence_set'. */
DEF_RTL_EXPR(FINAL_PRESENCE_SET, "final_presence_set", "ss", 'x')
/* (absence_set string string) means that each CPU functional unit in
the first string can not be reserved only if each unit whose name
is in the second string is not reserved. This is an asymmetric
relation (actually exclusion set is analogous to this one but it is
symmetric). CPU units in the string are separated by commas. For
example, it is useful for description that slot0 can not be
reserved after slot1 or slot2 reservation for VLIW processor. All
CPU functional units in a set should belong the same automaton. */
the first string can be reserved only if each pattern of units
whose names are in the second string is not reserved. This is an
asymmetric relation (actually exclusion set is analogous to this
one but it is symmetric). CPU units or unit patterns in the string
are separated by commas. Pattern is one unit name or unit names
separated by white-spaces.
For example, it is useful for description that slot0 can not be
reserved after slot1 or slot2 reservation for a VLIW processor. We
could describe it by the following construction
(absence_set "slot2" "slot0, slot1")
Or slot2 can not be reserved if slot0 and unit b0 are reserved or
slot1 and unit b1 are reserved . In this case we could write
(absence_set "slot2" "slot0 b0, slot1 b1")
All CPU functional units in a set should to belong the same
automaton. */
DEF_RTL_EXPR(ABSENCE_SET, "absence_set", "ss", 'x')
/* (final_absence_set string string) is analogous to `absence_set' but
checking is done on the result (state) reservation. See comments
for `final_presence_set'. */
DEF_RTL_EXPR(FINAL_ABSENCE_SET, "final_absence_set", "ss", 'x')
/* (define_bypass number out_insn_names in_insn_names) names bypass
with given latency (the first number) from insns given by the first
string (see define_insn_reservation) into insns given by the second
@ -416,8 +467,8 @@ DEF_RTL_EXPR(DEFINE_AUTOMATON, "define_automaton", "s", 'x')
automata. Currently there are the following options:
o "no-minimization" which makes no minimization of automata. This
is only worth to do when we are going to query CPU functional
unit reservations in an automaton state.
is only worth to do when we are debugging the description and
need to look more accurately at reservations of states.
o "time" which means printing additional time statistics about
generation of automata.

View File

@ -83,14 +83,12 @@ static sbitmap *forward_dependency_cache;
static int deps_may_trap_p PARAMS ((rtx));
static void add_dependence_list PARAMS ((rtx, rtx, enum reg_note));
static void add_dependence_list_and_free PARAMS ((rtx, rtx *, enum reg_note));
static void remove_dependence PARAMS ((rtx, rtx));
static void set_sched_group_p PARAMS ((rtx));
static void flush_pending_lists PARAMS ((struct deps *, rtx, int, int));
static void sched_analyze_1 PARAMS ((struct deps *, rtx, rtx));
static void sched_analyze_2 PARAMS ((struct deps *, rtx, rtx));
static void sched_analyze_insn PARAMS ((struct deps *, rtx, rtx, rtx));
static rtx group_leader PARAMS ((rtx));
static rtx get_condition PARAMS ((rtx));
static int conditions_mutex_p PARAMS ((rtx, rtx));
@ -237,18 +235,16 @@ add_dependence (insn, elem, dep_type)
rtx nnext;
while ((nnext = next_nonnote_insn (next)) != NULL
&& INSN_P (nnext)
&& next != insn
&& SCHED_GROUP_P (nnext))
next = nnext;
/* Again, don't depend an insn on itself. */
if (insn == next)
return;
if (insn != next)
add_dependence (insn, next, REG_DEP_ANTI);
/* Make the dependence to NEXT, the last insn of the group, instead
of the original ELEM. */
elem = next;
}
present_p = 1;
#ifdef INSN_SCHEDULING
/* ??? No good way to tell from here whether we're doing interblock
@ -384,76 +380,6 @@ add_dependence_list_and_free (insn, listp, dep_type)
}
}
/* Remove ELEM wrapped in an INSN_LIST from the LOG_LINKS
of INSN. Abort if not found. */
static void
remove_dependence (insn, elem)
rtx insn;
rtx elem;
{
rtx prev, link, next;
int found = 0;
for (prev = 0, link = LOG_LINKS (insn); link; link = next)
{
next = XEXP (link, 1);
if (XEXP (link, 0) == elem)
{
if (prev)
XEXP (prev, 1) = next;
else
LOG_LINKS (insn) = next;
#ifdef INSN_SCHEDULING
/* If we are removing a dependency from the LOG_LINKS list,
make sure to remove it from the cache too. */
if (true_dependency_cache != NULL)
{
if (REG_NOTE_KIND (link) == 0)
RESET_BIT (true_dependency_cache[INSN_LUID (insn)],
INSN_LUID (elem));
else if (REG_NOTE_KIND (link) == REG_DEP_ANTI)
RESET_BIT (anti_dependency_cache[INSN_LUID (insn)],
INSN_LUID (elem));
else if (REG_NOTE_KIND (link) == REG_DEP_OUTPUT)
RESET_BIT (output_dependency_cache[INSN_LUID (insn)],
INSN_LUID (elem));
}
#endif
free_INSN_LIST_node (link);
found = 1;
}
else
prev = link;
}
if (!found)
abort ();
return;
}
/* Return an insn which represents a SCHED_GROUP, which is
the last insn in the group. */
static rtx
group_leader (insn)
rtx insn;
{
rtx prev;
do
{
prev = insn;
insn = next_nonnote_insn (insn);
}
while (insn && INSN_P (insn) && SCHED_GROUP_P (insn));
return prev;
}
/* Set SCHED_GROUP_P and care for the rest of the bookkeeping that
goes along with that. */
@ -465,21 +391,21 @@ set_sched_group_p (insn)
SCHED_GROUP_P (insn) = 1;
/* There may be a note before this insn now, but all notes will
be removed before we actually try to schedule the insns, so
it won't cause a problem later. We must avoid it here though. */
for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
{
prev = insn;
do
{
prev = prev_nonnote_insn (prev);
if (XEXP (link, 0) == prev)
break;
}
while (SCHED_GROUP_P (prev));
if (XEXP (link, 0) != prev)
add_dependence (prev, XEXP (link, 0), REG_DEP_ANTI);
}
prev = prev_nonnote_insn (insn);
/* Make a copy of all dependencies on the immediately previous insn,
and add to this insn. This is so that all the dependencies will
apply to the group. Remove an explicit dependence on this insn
as SCHED_GROUP_P now represents it. */
if (find_insn_list (prev, LOG_LINKS (insn)))
remove_dependence (insn, prev);
for (link = LOG_LINKS (prev); link; link = XEXP (link, 1))
add_dependence (insn, XEXP (link, 0), REG_NOTE_KIND (link));
add_dependence (insn, prev, REG_DEP_ANTI);
}
/* Process an insn's memory dependencies. There are four kinds of
@ -983,7 +909,15 @@ sched_analyze_insn (deps, x, insn, loop_notes)
INIT_REG_SET (&tmp);
(*current_sched_info->compute_jump_reg_dependencies) (insn, &tmp);
IOR_REG_SET (reg_pending_uses, &tmp);
/* Make latency of jump equal to 0 by using anti-dependence. */
EXECUTE_IF_SET_IN_REG_SET (&tmp, 0, i,
{
struct deps_reg *reg_last = &deps->reg_last[i];
add_dependence_list (insn, reg_last->sets, REG_DEP_ANTI);
add_dependence_list (insn, reg_last->clobbers, REG_DEP_ANTI);
reg_last->uses_length++;
reg_last->uses = alloc_INSN_LIST (insn, reg_last->uses);
});
CLEAR_REG_SET (&tmp);
/* All memory writes and volatile reads must happen before the
@ -1049,14 +983,16 @@ sched_analyze_insn (deps, x, insn, loop_notes)
/* Add dependencies if a scheduling barrier was found. */
if (reg_pending_barrier)
{
/* In the case of barrier the most added dependencies are not
real, so we use anti-dependence here. */
if (GET_CODE (PATTERN (insn)) == COND_EXEC)
{
EXECUTE_IF_SET_IN_REG_SET (&deps->reg_last_in_use, 0, i,
{
struct deps_reg *reg_last = &deps->reg_last[i];
add_dependence_list (insn, reg_last->uses, REG_DEP_ANTI);
add_dependence_list (insn, reg_last->sets, 0);
add_dependence_list (insn, reg_last->clobbers, 0);
add_dependence_list (insn, reg_last->sets, REG_DEP_ANTI);
add_dependence_list (insn, reg_last->clobbers, REG_DEP_ANTI);
});
}
else
@ -1066,8 +1002,10 @@ sched_analyze_insn (deps, x, insn, loop_notes)
struct deps_reg *reg_last = &deps->reg_last[i];
add_dependence_list_and_free (insn, &reg_last->uses,
REG_DEP_ANTI);
add_dependence_list_and_free (insn, &reg_last->sets, 0);
add_dependence_list_and_free (insn, &reg_last->clobbers, 0);
add_dependence_list_and_free (insn, &reg_last->sets,
REG_DEP_ANTI);
add_dependence_list_and_free (insn, &reg_last->clobbers,
REG_DEP_ANTI);
reg_last->uses_length = 0;
reg_last->clobbers_length = 0;
});
@ -1432,11 +1370,9 @@ compute_forward_dependences (head, tail)
if (! INSN_P (insn))
continue;
insn = group_leader (insn);
for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
{
rtx x = group_leader (XEXP (link, 0));
rtx x = XEXP (link, 0);
rtx new_link;
if (x != XEXP (link, 0))

View File

@ -40,6 +40,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "recog.h"
#include "cfglayout.h"
#include "sched-int.h"
#include "target.h"
/* The number of insns to be scheduled in total. */
static int target_n_insns;
@ -89,14 +90,7 @@ init_ready_list (ready)
Count number of insns in the target block being scheduled. */
for (insn = NEXT_INSN (prev_head); insn != next_tail; insn = NEXT_INSN (insn))
{
rtx next;
if (! INSN_P (insn))
continue;
next = NEXT_INSN (insn);
if (INSN_DEP_COUNT (insn) == 0
&& (! INSN_P (next) || SCHED_GROUP_P (next) == 0))
if (INSN_DEP_COUNT (insn) == 0)
ready_add (ready, insn);
if (!(SCHED_GROUP_P (insn)))
target_n_insns++;
@ -222,6 +216,9 @@ schedule_ebb (head, tail)
/* Compute INSN_DEPEND. */
compute_forward_dependences (head, tail);
if (targetm.sched.dependencies_evaluation_hook)
targetm.sched.dependencies_evaluation_hook (head, tail);
/* Set priorities. */
n_insns = set_priorities (head, tail);

View File

@ -2023,17 +2023,9 @@ init_ready_list (ready)
Count number of insns in the target block being scheduled. */
for (insn = NEXT_INSN (prev_head); insn != next_tail; insn = NEXT_INSN (insn))
{
rtx next;
if (! INSN_P (insn))
continue;
next = NEXT_INSN (insn);
if (INSN_DEP_COUNT (insn) == 0
&& (! INSN_P (next) || SCHED_GROUP_P (next) == 0))
if (INSN_DEP_COUNT (insn) == 0)
ready_add (ready, insn);
if (!(SCHED_GROUP_P (insn)))
target_n_insns++;
target_n_insns++;
}
/* Add to ready list all 'ready' insns in valid source blocks.
@ -2067,19 +2059,8 @@ init_ready_list (ready)
insn, insn) <= 3)))
&& check_live (insn, bb_src)
&& is_exception_free (insn, bb_src, target_bb))))
{
rtx next;
/* Note that we haven't squirreled away the notes for
blocks other than the current. So if this is a
speculative insn, NEXT might otherwise be a note. */
next = next_nonnote_insn (insn);
if (INSN_DEP_COUNT (insn) == 0
&& (! next
|| ! INSN_P (next)
|| SCHED_GROUP_P (next) == 0))
ready_add (ready, insn);
}
if (INSN_DEP_COUNT (insn) == 0)
ready_add (ready, insn);
}
}
}
@ -2097,7 +2078,6 @@ can_schedule_ready_p (insn)
/* An interblock motion? */
if (INSN_BB (insn) != target_bb)
{
rtx temp;
basic_block b1;
if (IS_SPECULATIVE_INSN (insn))
@ -2114,18 +2094,9 @@ can_schedule_ready_p (insn)
}
nr_inter++;
/* Find the beginning of the scheduling group. */
/* ??? Ought to update basic block here, but later bits of
schedule_block assumes the original insn block is
still intact. */
temp = insn;
while (SCHED_GROUP_P (temp))
temp = PREV_INSN (temp);
/* Update source block boundaries. */
b1 = BLOCK_FOR_INSN (temp);
if (temp == b1->head && insn == b1->end)
b1 = BLOCK_FOR_INSN (insn);
if (insn == b1->head && insn == b1->end)
{
/* We moved all the insns in the basic block.
Emit a note after the last insn and update the
@ -2139,9 +2110,9 @@ can_schedule_ready_p (insn)
/* We took insns from the end of the basic block,
so update the end of block boundary so that it
points to the first insn we did not move. */
b1->end = PREV_INSN (temp);
b1->end = PREV_INSN (insn);
}
else if (temp == b1->head)
else if (insn == b1->head)
{
/* We took insns from the start of the basic block,
so update the start of block boundary so that
@ -2361,17 +2332,6 @@ add_branch_dependences (head, tail)
CANT_MOVE (insn) = 1;
last = insn;
/* Skip over insns that are part of a group.
Make each insn explicitly depend on the previous insn.
This ensures that only the group header will ever enter
the ready queue (and, when scheduled, will automatically
schedule the SCHED_GROUP_P block). */
while (SCHED_GROUP_P (insn))
{
rtx temp = prev_nonnote_insn (insn);
add_dependence (insn, temp, REG_DEP_ANTI);
insn = temp;
}
}
/* Don't overrun the bounds of the basic block. */
@ -2393,10 +2353,6 @@ add_branch_dependences (head, tail)
add_dependence (last, insn, REG_DEP_ANTI);
INSN_REF_COUNT (insn) = 1;
/* Skip over insns that are part of a group. */
while (SCHED_GROUP_P (insn))
insn = prev_nonnote_insn (insn);
}
}
@ -2728,6 +2684,10 @@ schedule_region (rgn)
get_block_head_tail (BB_TO_BLOCK (bb), &head, &tail);
compute_forward_dependences (head, tail);
if (targetm.sched.dependencies_evaluation_hook)
targetm.sched.dependencies_evaluation_hook (head, tail);
}
/* Set priorities. */

View File

@ -194,12 +194,15 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define TARGET_SCHED_FINISH 0
#define TARGET_SCHED_REORDER 0
#define TARGET_SCHED_REORDER2 0
#define TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK 0
#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE 0
#define TARGET_SCHED_INIT_DFA_PRE_CYCLE_INSN 0
#define TARGET_SCHED_DFA_PRE_CYCLE_INSN 0
#define TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN 0
#define TARGET_SCHED_DFA_POST_CYCLE_INSN 0
#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD 0
#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD 0
#define TARGET_SCHED_DFA_NEW_CYCLE 0
#define TARGET_SCHED_INIT_DFA_BUBBLES 0
#define TARGET_SCHED_DFA_BUBBLE 0
@ -212,12 +215,15 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
TARGET_SCHED_FINISH, \
TARGET_SCHED_REORDER, \
TARGET_SCHED_REORDER2, \
TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK, \
TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE, \
TARGET_SCHED_INIT_DFA_PRE_CYCLE_INSN, \
TARGET_SCHED_DFA_PRE_CYCLE_INSN, \
TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN, \
TARGET_SCHED_DFA_POST_CYCLE_INSN, \
TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD, \
TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD, \
TARGET_SCHED_DFA_NEW_CYCLE, \
TARGET_SCHED_INIT_DFA_BUBBLES, \
TARGET_SCHED_DFA_BUBBLE}

View File

@ -177,6 +177,11 @@ struct gcc_target
int (* reorder) PARAMS ((FILE *, int, rtx *, int *, int));
int (* reorder2) PARAMS ((FILE *, int, rtx *, int *, int));
/* The following member value is a pointer to a function called
after evaluation forward dependencies of insns in chain given
by two parameter values (head and tail correspondingly). */
void (* dependencies_evaluation_hook) PARAMS ((rtx, rtx));
/* The following member value is a pointer to a function returning
nonzero if we should use DFA based scheduling. The default is
to use the old pipeline scheduler. */
@ -206,6 +211,25 @@ struct gcc_target
try to choose ready insn which permits to start maximum number of
insns on the same cycle. */
int (* first_cycle_multipass_dfa_lookahead) PARAMS ((void));
/* The following member value is pointer to a function controlling
what insns from the ready insn queue will be considered for the
multipass insn scheduling. If the hook returns zero for insn
passed as the parameter, the insn will be not chosen to be
issued. */
int (* first_cycle_multipass_dfa_lookahead_guard) PARAMS ((rtx));
/* The following member value is pointer to a function called by
the insn scheduler before issuing insn passed as the third
parameter on given cycle. If the hook returns nonzero, the
insn is not issued on given processors cycle. Instead of that,
the processor cycle is advanced. If the value passed through
the last parameter is zero, the insn ready queue is not sorted
on the new cycle start as usually. The first parameter passes
file for debugging output. The second one passes the scheduler
verbose level of the debugging output. The forth and the fifth
parameter values are correspondingly processor cycle on which
the previous insn has been issued and the current processor
cycle. */
int (* dfa_new_cycle) PARAMS ((FILE *, int, rtx, int, int, int *));
/* The values of the following members are pointers to functions
used to improve the first cycle multipass scheduling by
inserting nop insns. dfa_scheduler_bubble gives a function