2003-01-09 Vladimir Makarov <vmakarov@redhat.com>
Merging changes from itanium-sched-branch: From-SVN: r61132
This commit is contained in:
parent
6ff2fe3933
commit
30028c8515
441
gcc/ChangeLog
441
gcc/ChangeLog
|
@ -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.
|
||||
|
|
|
@ -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
|
@ -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 */
|
||||
|
|
|
@ -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)]
|
||||
""
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||
|
|
112
gcc/doc/md.texi
112
gcc/doc/md.texi
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
1565
gcc/genautomata.c
1565
gcc/genautomata.c
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
89
gcc/rtl.def
89
gcc/rtl.def
|
@ -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.
|
||||
|
|
136
gcc/sched-deps.c
136
gcc/sched-deps.c
|
@ -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, ®_last->uses,
|
||||
REG_DEP_ANTI);
|
||||
add_dependence_list_and_free (insn, ®_last->sets, 0);
|
||||
add_dependence_list_and_free (insn, ®_last->clobbers, 0);
|
||||
add_dependence_list_and_free (insn, ®_last->sets,
|
||||
REG_DEP_ANTI);
|
||||
add_dependence_list_and_free (insn, ®_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))
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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}
|
||||
|
||||
|
|
24
gcc/target.h
24
gcc/target.h
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue