Commit ce18efcb by Vladimir Makarov Committed by Vladimir Makarov

invoke.texi (-fsched-pressure): Document it.

2009-09-02  Vladimir Makarov  <vmakarov@redhat.com>

	* doc/invoke.texi (-fsched-pressure): Document it.
	(-fsched-reg-pressure-heuristic): Remove it.
	
	* reload.c (ira.h): Include.
	(find_reloads): Add choosing reload on number of small spilled
	classes.
	
	* haifa-sched.c (ira.h): Include.
	(sched_pressure_p, sched_regno_cover_class, curr_reg_pressure,
	saved_reg_pressure, curr_reg_live, saved_reg_live,
	region_ref_regs): New variables.
	(sched_init_region_reg_pressure_info, mark_regno_birth_or_death,
	initiate_reg_pressure_info, setup_ref_regs,
	initiate_bb_reg_pressure_info, save_reg_pressure,
	restore_reg_pressure, dying_use_p, print_curr_reg_pressure): New
	functions.
	(setup_insn_reg_pressure_info): New function.
	(rank_for_schedule): Add pressure checking and insn issue time.
	Remove comparison of insn reg weights.
	(ready_sort): Set insn reg pressure info.
	(update_register_pressure, setup_insn_max_reg_pressure,
	update_reg_and_insn_max_reg_pressure,
	sched_setup_bb_reg_pressure_info): New functions.
	(schedule_insn): Add code for printing and updating reg pressure
	info.
	(find_set_reg_weight, find_insn_reg_weight): Remove.
	(ok_for_early_queue_removal): Do nothing if pressure_only_p.
	(debug_ready_list): Print reg pressure info.
	(schedule_block): Ditto.  Check insn issue time.
	(sched_init): Set up sched_pressure_p.  Allocate and set up some
	reg pressure related info.
	(sched_finish): Free some reg pressure related info.
	(fix_tick_ready): Make insn always ready if pressure_p.
	(init_h_i_d): Don't call find_insn_reg_weight.
	(haifa_finish_h_i_d): Free insn reg pressure info.
	
	* ira-int.h (ira_hard_regno_cover_class, ira_reg_class_nregs,
	ira_memory_move_cost, ira_class_hard_regs,
	ira_class_hard_regs_num, ira_no_alloc_regs,
	ira_available_class_regs, ira_reg_class_cover_size,
	ira_reg_class_cover, ira_class_translate): Move to ira.h.

	* ira-lives.c (single_reg_class): Check mode to find how many
	registers are necessary for operand.
	(ira_implicitly_set_insn_hard_regs): New.

	* common.opt (fsched-pressure): New options.
	(fsched-reg-pressure-heuristic): Remove.

	* ira.c (setup_eliminable_regset): Rename to
	ira_setup_eliminable_regset.  Make it external.
	(expand_reg_info): Pass cover class to setup_reg_classes.
	(ira): Call resize_reg_info instead of allocate_reg_info.

	* sched-deps.c: Include ira.h.
	(implicit_reg_pending_clobbers, implicit_reg_pending_uses): New.
	(create_insn_reg_use, create_insn_reg_set, setup_insn_reg_uses,
	reg_pressure_info, insn_use_p, mark_insn_pseudo_birth,
	mark_insn_hard_regno_birth, mark_insn_reg_birth,
	mark_pseudo_death, mark_hard_regno_death, mark_reg_death,
	mark_insn_reg_store, mark_insn_reg_clobber,
	setup_insn_reg_pressure_info): New.
	(sched_analyze_1): Update implicit_reg_pending_uses.
	(sched_analyze_insn): Find implicit sets, uses, clobbers of regs.
	Use them to create dependencies.  Set insn reg uses and pressure
	info.  Process reg_pending_uses in one place.
	(free_deps): Free implicit sets.
	(remove_from_deps): Remove implicit sets if necessary.  Check
	implicit sets when clearing reg_last_in_use.
	(init_deps_global): Clear implicit_reg_pending_clobbers and
	implicit_reg_pending_uses.
	
	* ira.h (ira_hard_regno_cover_class, ira_reg_class_nregs,
	ira_memory_move_cost, ira_class_hard_regs,
	ira_class_hard_regs_num, ira_no_alloc_regs,
	ira_available_class_regs, ira_reg_class_cover_size,
	ira_reg_class_cover, ira_class_translate): Move from ira-int.h.
	(ira_setup_eliminable_regset, ira_set_pseudo_classes,
	ira_implicitly_set_insn_hard_regs): New prototypes.
	
	* ira-costs.c (pseudo_classes_defined_p, allocno_p,
	cost_elements_num): New variables.
	(allocno_costs, total_costs): Rename to costs and
	total_allocno_costs.
	(COSTS_OF_ALLOCNO): Rename to COSTS.
	(allocno_pref): Rename to pref.
	(allocno_pref_buffer): Rename to pref_buffer.
	(common_classes): Rename to regno_cover_class.
	(COST_INDEX): New.
	(record_reg_classes): Set allocno attributes only if allocno_p.
	(record_address_regs): Ditto.  Use COST_INDEX instead of
	ALLOCNO_NUM.
	(scan_one_insn): Use COST_INDEX and COSTS instead of ALLOCNO_NUM
	and COSTS_OF_ALLOCNO.
	(print_costs): Rename to print_allocno_costs.
	(print_pseudo_costs): New.
	(process_bb_node_for_costs): Split into 2 functions with new
	function process_bb_for_costs.  Pass BB to process_bb_for_costs.
	(find_allocno_class_costs): Rename to find_costs_and_classes.  Add
	new parameter dump_file.  Use cost_elements_num instead of
	ira_allocnos_num.  Make one iteration if preferred classes were
	already calculated for scheduler.  Make 2 versions of code
	depending on allocno_p.
	(setup_allocno_cover_class_and_costs): Check allocno_p.  Use
	regno_cover_class and COSTS instead of common_classes and
	COSTS_OF_ALLOCNO.
	(init_costs, finish_costs): New.
	(ira_costs): Set up allocno_p and cost_elements_num.  Call
	init_costs and finish_costs.
	(ira_set_pseudo_classes): New.

	* rtl.h (allocate_reg_info): Remove.
	(resize_reg_info): Change return type.
	(reg_cover_class): New.
	(setup_reg_classes): Add new parameter.
	
	* sched-int.h (struct deps_reg): New member implicit_sets.
	(sched_pressure_p, sched_regno_cover_class): New external
	definitions.
	(INCREASE_BITS): New macro.
	(struct reg_pressure_data, struct reg_use_data): New.
	(struct _haifa_insn_data): Remove reg_weight.  Add members
	reg_pressure, reg_use_list, reg_set_list, and
	reg_pressure_excess_cost_change.
	(struct deps): New member implicit_sets.
	(pressure_p): New variable.
	(COVER_CLASS_BITS, INCREASE_BITS): New macros.
	(struct reg_pressure_data, struct reg_use_data): New.
	(INSN_REG_WEIGHT): Remove.
	(INSN_REG_PRESSURE, INSN_MAX_REG_PRESSURE, INSN_REG_USE_LIST,
	INSN_REG_SET_LIST, INSN_REG_PRESSURE_EXCESS_COST_CHANGE): New
	macros.
	(sched_init_region_reg_pressure_info,
	sched_setup_bb_reg_pressure_info): New prototypes.
	
        * reginfo.c (struct reg_pref): New member coverclass.
	(reg_cover_class): New function.
	(reginfo_init, pass_reginfo_init): Move after free_reg_info.
	(reg_info_size): New variable.
	(allocate_reg_info): Make static.  Setup reg_info_size.
	(resize_reg_info): Use reg_info_size.  Return flag of resizing.
	(setup_reg_classes): Add a new parameter.  Setup cover class too.

	* Makefile.in (reload.o, haifa-sched.o, sched-deps.o): Add ira.h to the
	dependencies.

	* sched-rgn.c (deps_join): Set up implicit_sets.
	(schedule_region): Set up region and basic blocks pressure
	relative info.
	
	* passes.c (init_optimization_passes): Move
	pass_subregs_of_mode_init before pass_sched.

From-SVN: r151348
parent f8563a3b
2009-09-02 Vladimir Makarov <vmakarov@redhat.com>
* doc/invoke.texi (-fsched-pressure): Document it.
(-fsched-reg-pressure-heuristic): Remove it.
* reload.c (ira.h): Include.
(find_reloads): Add choosing reload on number of small spilled
classes.
* haifa-sched.c (ira.h): Include.
(sched_pressure_p, sched_regno_cover_class, curr_reg_pressure,
saved_reg_pressure, curr_reg_live, saved_reg_live,
region_ref_regs): New variables.
(sched_init_region_reg_pressure_info, mark_regno_birth_or_death,
initiate_reg_pressure_info, setup_ref_regs,
initiate_bb_reg_pressure_info, save_reg_pressure,
restore_reg_pressure, dying_use_p, print_curr_reg_pressure): New
functions.
(setup_insn_reg_pressure_info): New function.
(rank_for_schedule): Add pressure checking and insn issue time.
Remove comparison of insn reg weights.
(ready_sort): Set insn reg pressure info.
(update_register_pressure, setup_insn_max_reg_pressure,
update_reg_and_insn_max_reg_pressure,
sched_setup_bb_reg_pressure_info): New functions.
(schedule_insn): Add code for printing and updating reg pressure
info.
(find_set_reg_weight, find_insn_reg_weight): Remove.
(ok_for_early_queue_removal): Do nothing if pressure_only_p.
(debug_ready_list): Print reg pressure info.
(schedule_block): Ditto. Check insn issue time.
(sched_init): Set up sched_pressure_p. Allocate and set up some
reg pressure related info.
(sched_finish): Free some reg pressure related info.
(fix_tick_ready): Make insn always ready if pressure_p.
(init_h_i_d): Don't call find_insn_reg_weight.
(haifa_finish_h_i_d): Free insn reg pressure info.
* ira-int.h (ira_hard_regno_cover_class, ira_reg_class_nregs,
ira_memory_move_cost, ira_class_hard_regs,
ira_class_hard_regs_num, ira_no_alloc_regs,
ira_available_class_regs, ira_reg_class_cover_size,
ira_reg_class_cover, ira_class_translate): Move to ira.h.
* ira-lives.c (single_reg_class): Check mode to find how many
registers are necessary for operand.
(ira_implicitly_set_insn_hard_regs): New.
* common.opt (fsched-pressure): New options.
(fsched-reg-pressure-heuristic): Remove.
* ira.c (setup_eliminable_regset): Rename to
ira_setup_eliminable_regset. Make it external.
(expand_reg_info): Pass cover class to setup_reg_classes.
(ira): Call resize_reg_info instead of allocate_reg_info.
* sched-deps.c: Include ira.h.
(implicit_reg_pending_clobbers, implicit_reg_pending_uses): New.
(create_insn_reg_use, create_insn_reg_set, setup_insn_reg_uses,
reg_pressure_info, insn_use_p, mark_insn_pseudo_birth,
mark_insn_hard_regno_birth, mark_insn_reg_birth,
mark_pseudo_death, mark_hard_regno_death, mark_reg_death,
mark_insn_reg_store, mark_insn_reg_clobber,
setup_insn_reg_pressure_info): New.
(sched_analyze_1): Update implicit_reg_pending_uses.
(sched_analyze_insn): Find implicit sets, uses, clobbers of regs.
Use them to create dependencies. Set insn reg uses and pressure
info. Process reg_pending_uses in one place.
(free_deps): Free implicit sets.
(remove_from_deps): Remove implicit sets if necessary. Check
implicit sets when clearing reg_last_in_use.
(init_deps_global): Clear implicit_reg_pending_clobbers and
implicit_reg_pending_uses.
* ira.h (ira_hard_regno_cover_class, ira_reg_class_nregs,
ira_memory_move_cost, ira_class_hard_regs,
ira_class_hard_regs_num, ira_no_alloc_regs,
ira_available_class_regs, ira_reg_class_cover_size,
ira_reg_class_cover, ira_class_translate): Move from ira-int.h.
(ira_setup_eliminable_regset, ira_set_pseudo_classes,
ira_implicitly_set_insn_hard_regs): New prototypes.
* ira-costs.c (pseudo_classes_defined_p, allocno_p,
cost_elements_num): New variables.
(allocno_costs, total_costs): Rename to costs and
total_allocno_costs.
(COSTS_OF_ALLOCNO): Rename to COSTS.
(allocno_pref): Rename to pref.
(allocno_pref_buffer): Rename to pref_buffer.
(common_classes): Rename to regno_cover_class.
(COST_INDEX): New.
(record_reg_classes): Set allocno attributes only if allocno_p.
(record_address_regs): Ditto. Use COST_INDEX instead of
ALLOCNO_NUM.
(scan_one_insn): Use COST_INDEX and COSTS instead of ALLOCNO_NUM
and COSTS_OF_ALLOCNO.
(print_costs): Rename to print_allocno_costs.
(print_pseudo_costs): New.
(process_bb_node_for_costs): Split into 2 functions with new
function process_bb_for_costs. Pass BB to process_bb_for_costs.
(find_allocno_class_costs): Rename to find_costs_and_classes. Add
new parameter dump_file. Use cost_elements_num instead of
ira_allocnos_num. Make one iteration if preferred classes were
already calculated for scheduler. Make 2 versions of code
depending on allocno_p.
(setup_allocno_cover_class_and_costs): Check allocno_p. Use
regno_cover_class and COSTS instead of common_classes and
COSTS_OF_ALLOCNO.
(init_costs, finish_costs): New.
(ira_costs): Set up allocno_p and cost_elements_num. Call
init_costs and finish_costs.
(ira_set_pseudo_classes): New.
* rtl.h (allocate_reg_info): Remove.
(resize_reg_info): Change return type.
(reg_cover_class): New.
(setup_reg_classes): Add new parameter.
* sched-int.h (struct deps_reg): New member implicit_sets.
(sched_pressure_p, sched_regno_cover_class): New external
definitions.
(INCREASE_BITS): New macro.
(struct reg_pressure_data, struct reg_use_data): New.
(struct _haifa_insn_data): Remove reg_weight. Add members
reg_pressure, reg_use_list, reg_set_list, and
reg_pressure_excess_cost_change.
(struct deps): New member implicit_sets.
(pressure_p): New variable.
(COVER_CLASS_BITS, INCREASE_BITS): New macros.
(struct reg_pressure_data, struct reg_use_data): New.
(INSN_REG_WEIGHT): Remove.
(INSN_REG_PRESSURE, INSN_MAX_REG_PRESSURE, INSN_REG_USE_LIST,
INSN_REG_SET_LIST, INSN_REG_PRESSURE_EXCESS_COST_CHANGE): New
macros.
(sched_init_region_reg_pressure_info,
sched_setup_bb_reg_pressure_info): New prototypes.
* reginfo.c (struct reg_pref): New member coverclass.
(reg_cover_class): New function.
(reginfo_init, pass_reginfo_init): Move after free_reg_info.
(reg_info_size): New variable.
(allocate_reg_info): Make static. Setup reg_info_size.
(resize_reg_info): Use reg_info_size. Return flag of resizing.
(setup_reg_classes): Add a new parameter. Setup cover class too.
* Makefile.in (reload.o, haifa-sched.o, sched-deps.o): Add ira.h to the
dependencies.
* sched-rgn.c (deps_join): Set up implicit_sets.
(schedule_region): Set up region and basic blocks pressure
relative info.
* passes.c (init_optimization_passes): Move
pass_subregs_of_mode_init before pass_sched.
2009-09-02 Martin Jambor <mjambor@suse.cz>
* tree-sra.c (struct access): New field grp_hint.
......
......@@ -3030,7 +3030,7 @@ vec.o : vec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h vec.h $(GGC_H) \
reload.o : reload.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(FLAGS_H) output.h $(EXPR_H) $(OPTABS_H) reload.h $(RECOG_H) \
hard-reg-set.h insn-config.h $(REGS_H) $(FUNCTION_H) real.h $(TOPLEV_H) \
addresses.h $(TM_P_H) $(PARAMS_H) $(TARGET_H) $(REAL_H) $(DF_H)
addresses.h $(TM_P_H) $(PARAMS_H) $(TARGET_H) $(REAL_H) $(DF_H) ira.h
reload1.o : reload1.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(EXPR_H) $(OPTABS_H) reload.h $(REGS_H) hard-reg-set.h insn-config.h \
$(BASIC_BLOCK_H) $(RECOG_H) output.h $(FUNCTION_H) $(TOPLEV_H) $(TM_P_H) \
......@@ -3126,11 +3126,11 @@ modulo-sched.o : modulo-sched.c $(DDG_H) $(CONFIG_H) $(CONFIG_H) $(SYSTEM_H) \
haifa-sched.o : haifa-sched.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(FUNCTION_H) \
$(INSN_ATTR_H) $(TOPLEV_H) $(RECOG_H) $(EXCEPT_H) $(TM_P_H) $(TARGET_H) output.h \
$(PARAMS_H) $(DBGCNT_H)
$(PARAMS_H) $(DBGCNT_H) ira.h
sched-deps.o : sched-deps.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
$(FUNCTION_H) $(INSN_ATTR_H) $(TOPLEV_H) $(RECOG_H) $(EXCEPT_H) cselib.h \
$(PARAMS_H) $(TM_P_H)
ira.h $(PARAMS_H) $(TM_P_H) ira.h
sched-rgn.o : sched-rgn.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
$(FUNCTION_H) $(INSN_ATTR_H) $(TOPLEV_H) $(RECOG_H) $(EXCEPT_H) $(PARAMS_H) \
......
......@@ -982,6 +982,10 @@ fsched-interblock
Common Report Var(flag_schedule_interblock) Init(1) Optimization
Enable scheduling across basic blocks
fsched-pressure
Common Report Var(flag_sched_pressure) Init(0) Optimization
Enable register pressure sensitive insn scheduling
fsched-spec
Common Report Var(flag_schedule_speculative) Init(1) Optimization
Allow speculative motion of non-loads
......@@ -1071,10 +1075,6 @@ fsched-spec-insn-heuristic
Common Report Var(flag_sched_spec_insn_heuristic) Init(1) Optimization
Enable the speculative instruction heuristic in the scheduler
fsched-reg-pressure-heuristic
Common Report Var(flag_sched_reg_pressure_heuristic) Init(1) Optimization
Enable the register pressure heuristic in the scheduler
fsched-rank-heuristic
Common Report Var(flag_sched_rank_heuristic) Init(1) Optimization
Enable the rank heuristic in the scheduler
......
......@@ -365,12 +365,12 @@ Objective-C and Objective-C++ Dialects}.
-freorder-blocks-and-partition -freorder-functions @gol
-frerun-cse-after-loop -freschedule-modulo-scheduled-loops @gol
-frounding-math -fsched2-use-superblocks @gol
-fsched2-use-traces -fsched-spec-load -fsched-spec-load-dangerous @gol
-fsched2-use-traces -fsched-pressure @gol
-fsched-spec-load -fsched-spec-load-dangerous @gol
-fsched-stalled-insns-dep[=@var{n}] -fsched-stalled-insns[=@var{n}] @gol
-fsched-group-heuristic -fsched-critical-path-heuristic @gol
-fsched-spec-insn-heuristic -fsched-reg-pressure-heuristic @gol
-fsched-rank-heuristic -fsched-last-insn-heuristic @gol
-fsched-dep-count-heuristic @gol
-fsched-spec-insn-heuristic -fsched-rank-heuristic @gol
-fsched-last-insn-heuristic -fsched-dep-count-heuristic @gol
-fschedule-insns -fschedule-insns2 -fsection-anchors @gol
-fselective-scheduling -fselective-scheduling2 @gol
-fsel-sched-pipelining -fsel-sched-pipelining-outer-loops @gol
......@@ -6226,6 +6226,16 @@ Don't allow speculative motion of non-load instructions. This is normally
enabled by default when scheduling before register allocation, i.e.@:
with @option{-fschedule-insns} or at @option{-O2} or higher.
@item -fsched-pressure
@opindex fsched-pressure
Enable register pressure sensitive insn scheduling before the register
allocation. This only makes sense when scheduling before register
allocation is enabled, i.e.@: with @option{-fschedule-insns} or at
@option{-O2} or higher. Usage of this option can improve the
generated code and decrease its size by preventing register pressure
increase above the number of available hard registers and as a
consequence register spills in the register allocation.
@item -fsched-spec-load
@opindex fsched-spec-load
Allow speculative motion of some load instructions. This only makes
......@@ -6294,13 +6304,6 @@ This is enabled by default when scheduling is enabled, i.e.@:
with @option{-fschedule-insns} or @option{-fschedule-insns2}
or at @option{-O2} or higher.
@item -fsched-reg-pressure-heuristic
@opindex fsched-reg-pressure-heuristic
Enable the register pressure heuristic in the scheduler. This heuristic
favors the instruction with smaller contribution to register pressure.
This only makes sense when scheduling before register allocation, i.e.@:
with @option{-fschedule-insns} or at @option{-O2} or higher.
@item -fsched-rank-heuristic
@opindex fsched-rank-heuristic
Enable the rank heuristic in the scheduler. This heuristic favors
......
......@@ -565,18 +565,7 @@ extern int ira_reg_cost, ira_mem_cost;
extern int ira_load_cost, ira_store_cost, ira_shuffle_cost;
extern int ira_move_loops_num, ira_additional_jumps_num;
/* Map: hard register number -> cover class it belongs to. If the
corresponding class is NO_REGS, the hard register is not available
for allocation. */
extern enum reg_class ira_hard_regno_cover_class[FIRST_PSEUDO_REGISTER];
/* Map: register class x machine mode -> number of hard registers of
given class needed to store value of given mode. If the number for
some hard-registers of the register class is different, the size
will be negative. */
extern int ira_reg_class_nregs[N_REG_CLASSES][MAX_MACHINE_MODE];
/* Maximal value of the previous array elements. */
/* Maximal value of element of array ira_reg_class_nregs. */
extern int ira_max_nregs;
/* The number of bits in each element of array used to implement a bit
......@@ -730,10 +719,9 @@ ira_allocno_set_iter_next (ira_allocno_set_iterator *i)
extern HARD_REG_SET ira_reg_mode_hard_regset
[FIRST_PSEUDO_REGISTER][NUM_MACHINE_MODES];
/* Arrays analogous to macros MEMORY_MOVE_COST and REGISTER_MOVE_COST.
Don't use ira_register_move_cost directly. Use function of
/* Array analogous to macro REGISTER_MOVE_COST. Don't use
ira_register_move_cost directly. Use function of
ira_get_may_move_cost instead. */
extern short ira_memory_move_cost[MAX_MACHINE_MODE][N_REG_CLASSES][2];
extern move_table *ira_register_move_cost[MAX_MACHINE_MODE];
/* Similar to may_move_in_cost but it is calculated in IRA instead of
......@@ -755,29 +743,12 @@ extern move_table *ira_may_move_out_cost[MAX_MACHINE_MODE];
allocation. */
extern int ira_class_subset_p[N_REG_CLASSES][N_REG_CLASSES];
/* Array of number of hard registers of given class which are
available for the allocation. The order is defined by the
allocation order. */
extern short ira_class_hard_regs[N_REG_CLASSES][FIRST_PSEUDO_REGISTER];
/* The number of elements of the above array for given register
class. */
extern int ira_class_hard_regs_num[N_REG_CLASSES];
/* Index (in ira_class_hard_regs) for given register class and hard
register (in general case a hard register can belong to several
register classes). The index is negative for hard registers
unavailable for the allocation. */
extern short ira_class_hard_reg_index[N_REG_CLASSES][FIRST_PSEUDO_REGISTER];
/* Function specific hard registers can not be used for the register
allocation. */
extern HARD_REG_SET ira_no_alloc_regs;
/* Number of given class hard registers available for the register
allocation for given classes. */
extern int ira_available_class_regs[N_REG_CLASSES];
/* Array whose values are hard regset of hard registers available for
the allocation of given register class whose HARD_REGNO_MODE_OK
values for given mode are zero. */
......@@ -789,16 +760,6 @@ extern HARD_REG_SET prohibited_class_mode_regs
prohibited. */
extern HARD_REG_SET ira_prohibited_mode_move_regs[NUM_MACHINE_MODES];
/* Number of cover classes. Cover classes is non-intersected register
classes containing all hard-registers available for the
allocation. */
extern int ira_reg_class_cover_size;
/* The array containing cover classes (see also comments for macro
IRA_COVER_CLASSES). Only first IRA_REG_CLASS_COVER_SIZE elements are
used for this. */
extern enum reg_class ira_reg_class_cover[N_REG_CLASSES];
/* The value is number of elements in the subsequent array. */
extern int ira_important_classes_num;
......@@ -812,11 +773,6 @@ extern enum reg_class ira_important_classes[N_REG_CLASSES];
classes. */
extern int ira_important_class_nums[N_REG_CLASSES];
/* Map of all register classes to corresponding cover class containing
the given class. If given class is not a subset of a cover class,
we translate it into the cheapest cover class. */
extern enum reg_class ira_class_translate[N_REG_CLASSES];
/* The biggest important class inside of intersection of the two
classes (that is calculated taking only hard registers available
for allocation into account). If the both classes contain no hard
......
......@@ -702,7 +702,8 @@ single_reg_class (const char *constraints, rtx op, rtx equiv_const)
? GENERAL_REGS
: REG_CLASS_FROM_CONSTRAINT (c, constraints));
if ((cl != NO_REGS && next_cl != cl)
|| ira_available_class_regs[next_cl] > 1)
|| (ira_available_class_regs[next_cl]
> ira_reg_class_nregs[next_cl][GET_MODE (op)]))
return NO_REGS;
cl = next_cl;
break;
......@@ -712,8 +713,10 @@ single_reg_class (const char *constraints, rtx op, rtx equiv_const)
next_cl
= single_reg_class (recog_data.constraints[c - '0'],
recog_data.operand[c - '0'], NULL_RTX);
if ((cl != NO_REGS && next_cl != cl) || next_cl == NO_REGS
|| ira_available_class_regs[next_cl] > 1)
if ((cl != NO_REGS && next_cl != cl)
|| next_cl == NO_REGS
|| (ira_available_class_regs[next_cl]
> ira_reg_class_nregs[next_cl][GET_MODE (op)]))
return NO_REGS;
cl = next_cl;
break;
......@@ -736,6 +739,62 @@ single_reg_operand_class (int op_num)
recog_data.operand[op_num], NULL_RTX);
}
/* The function sets up hard register set *SET to hard registers which
might be used by insn reloads because the constraints are too
strict. */
void
ira_implicitly_set_insn_hard_regs (HARD_REG_SET *set)
{
int i, c, regno;
bool ignore_p;
enum reg_class cl;
rtx op;
enum machine_mode mode;
CLEAR_HARD_REG_SET (*set);
for (i = 0; i < recog_data.n_operands; i++)
{
op = recog_data.operand[i];
if (GET_CODE (op) == SUBREG)
op = SUBREG_REG (op);
if (GET_CODE (op) == SCRATCH
|| (REG_P (op) && (regno = REGNO (op)) >= FIRST_PSEUDO_REGISTER))
{
const char *p = recog_data.constraints[i];
mode = (GET_CODE (op) == SCRATCH
? GET_MODE (op) : PSEUDO_REGNO_MODE (regno));
cl = NO_REGS;
for (ignore_p = false; (c = *p); p += CONSTRAINT_LEN (c, p))
if (c == '#')
ignore_p = true;
else if (c == ',')
ignore_p = false;
else if (! ignore_p)
switch (c)
{
case 'r':
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
case 'h': case 'j': case 'k': case 'l':
case 'q': case 't': case 'u':
case 'v': case 'w': case 'x': case 'y': case 'z':
case 'A': case 'B': case 'C': case 'D':
case 'Q': case 'R': case 'S': case 'T': case 'U':
case 'W': case 'Y': case 'Z':
cl = (c == 'r'
? GENERAL_REGS
: REG_CLASS_FROM_CONSTRAINT (c, p));
if (cl != NO_REGS
&& (ira_available_class_regs[cl]
<= ira_reg_class_nregs[cl][mode]))
IOR_HARD_REG_SET (*set, reg_class_contents[cl]);
break;
}
}
}
}
/* Processes input operands, if IN_P, or output operands otherwise of
the current insn with FREQ to find allocno which can use only one
hard register and makes other currently living allocnos conflicting
......
......@@ -1422,8 +1422,8 @@ compute_regs_asm_clobbered (char *regs_asm_clobbered)
/* Set up ELIMINABLE_REGSET, IRA_NO_ALLOC_REGS, and REGS_EVER_LIVE. */
static void
setup_eliminable_regset (void)
void
ira_setup_eliminable_regset (void)
{
/* Like regs_ever_live, but 1 if a reg is set or clobbered from an
asm. Unlike regs_ever_live, elements of this array corresponding
......@@ -1827,7 +1827,8 @@ setup_preferred_alternate_classes_for_new_pseudos (int start)
old_regno = ORIGINAL_REGNO (regno_reg_rtx[i]);
ira_assert (i != old_regno);
setup_reg_classes (i, reg_preferred_class (old_regno),
reg_alternate_class (old_regno));
reg_alternate_class (old_regno),
reg_cover_class (old_regno));
if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
fprintf (ira_dump_file,
" New r%d: setting preferred %s, alternative %s\n",
......@@ -1848,10 +1849,7 @@ expand_reg_info (int old_size)
resize_reg_info ();
for (i = old_size; i < size; i++)
{
reg_renumber[i] = -1;
setup_reg_classes (i, GENERAL_REGS, ALL_REGS);
}
setup_reg_classes (i, GENERAL_REGS, ALL_REGS, GENERAL_REGS);
}
/* Return TRUE if there is too high register pressure in the function.
......@@ -3160,8 +3158,8 @@ ira (FILE *f)
}
max_regno_before_ira = allocated_reg_info_size = max_reg_num ();
allocate_reg_info ();
setup_eliminable_regset ();
resize_reg_info ();
ira_setup_eliminable_regset ();
ira_overall_cost = ira_reg_cost = ira_mem_cost = 0;
ira_load_cost = ira_store_cost = ira_shuffle_cost = 0;
......
......@@ -20,14 +20,63 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
/* Number of given class hard registers available for the register
allocation for given classes. */
extern int ira_available_class_regs[N_REG_CLASSES];
/* Map: hard register number -> cover class it belongs to. If the
corresponding class is NO_REGS, the hard register is not available
for allocation. */
extern enum reg_class ira_hard_regno_cover_class[FIRST_PSEUDO_REGISTER];
/* Number of cover classes. Cover classes is non-intersected register
classes containing all hard-registers available for the
allocation. */
extern int ira_reg_class_cover_size;
/* The array containing cover classes (see also comments for macro
IRA_COVER_CLASSES). Only first IRA_REG_CLASS_COVER_SIZE elements are
used for this. */
extern enum reg_class ira_reg_class_cover[N_REG_CLASSES];
/* Map of all register classes to corresponding cover class containing
the given class. If given class is not a subset of a cover class,
we translate it into the cheapest cover class. */
extern enum reg_class ira_class_translate[N_REG_CLASSES];
/* Map: register class x machine mode -> number of hard registers of
given class needed to store value of given mode. If the number for
some hard-registers of the register class is different, the size
will be negative. */
extern int ira_reg_class_nregs[N_REG_CLASSES][MAX_MACHINE_MODE];
/* Function specific hard registers can not be used for the register
allocation. */
extern HARD_REG_SET ira_no_alloc_regs;
/* True if we have allocno conflicts. It is false for non-optimized
mode or when the conflict table is too big. */
extern bool ira_conflicts_p;
/* Array analogous to macro MEMORY_MOVE_COST. */
extern short ira_memory_move_cost[MAX_MACHINE_MODE][N_REG_CLASSES][2];
/* Array of number of hard registers of given class which are
available for the allocation. The order is defined by the
allocation order. */
extern short ira_class_hard_regs[N_REG_CLASSES][FIRST_PSEUDO_REGISTER];
/* The number of elements of the above array for given register
class. */
extern int ira_class_hard_regs_num[N_REG_CLASSES];
extern void ira_init_once (void);
extern void ira_init (void);
extern void ira_finish_once (void);
extern void ira_setup_eliminable_regset (void);
extern rtx ira_eliminate_regs (rtx, enum machine_mode);
extern void ira_set_pseudo_classes (FILE *);
extern void ira_implicitly_set_insn_hard_regs (HARD_REG_SET *);
extern void ira_sort_regnos_for_alter_reg (int *, int, unsigned int *);
extern void ira_mark_allocation_change (int);
......
......@@ -776,8 +776,8 @@ init_optimization_passes (void)
NEXT_PASS (pass_mode_switching);
NEXT_PASS (pass_match_asm_constraints);
NEXT_PASS (pass_sms);
NEXT_PASS (pass_sched);
NEXT_PASS (pass_subregs_of_mode_init);
NEXT_PASS (pass_sched);
NEXT_PASS (pass_ira);
NEXT_PASS (pass_subregs_of_mode_finish);
NEXT_PASS (pass_postreload);
......
......@@ -898,6 +898,10 @@ struct reg_pref
but since it is recommended that there be a class corresponding to the
union of most major pair of classes, that generality is not required. */
char altclass;
/* coverclass is a register class that IRA uses for allocating
the pseudo. */
char coverclass;
};
/* Record preferences of each pseudo. This is available after RA is
......@@ -925,65 +929,51 @@ reg_alternate_class (int regno)
return (enum reg_class) reg_pref[regno].altclass;
}
/* Initialize some global data for this pass. */
static unsigned int
reginfo_init (void)
/* Return the reg_class which is used by IRA for its allocation. */
enum reg_class
reg_cover_class (int regno)
{
if (df)
df_compute_regs_ever_live (true);
/* This prevents dump_flow_info from losing if called
before reginfo is run. */
reg_pref = NULL;
if (reg_pref == 0)
return NO_REGS;
/* No more global register variables may be declared. */
no_global_reg_vars = 1;
return 1;
return (enum reg_class) reg_pref[regno].coverclass;
}
struct rtl_opt_pass pass_reginfo_init =
{
{
RTL_PASS,
"reginfo", /* name */
NULL, /* gate */
reginfo_init, /* execute */
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
TV_NONE, /* tv_id */
0, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
0 /* todo_flags_finish */
}
};
/* Current size of reg_info. */
static int reg_info_size;
/* Allocate space for reg info. */
void
static void
allocate_reg_info (void)
{
int size = max_reg_num ();
reg_info_size = max_reg_num ();
gcc_assert (! reg_pref && ! reg_renumber);
reg_renumber = XNEWVEC (short, size);
reg_pref = XCNEWVEC (struct reg_pref, size);
memset (reg_renumber, -1, size * sizeof (short));
reg_renumber = XNEWVEC (short, reg_info_size);
reg_pref = XCNEWVEC (struct reg_pref, reg_info_size);
memset (reg_renumber, -1, reg_info_size * sizeof (short));
}
/* Resize reg info. The new elements will be uninitialized. */
void
bool
resize_reg_info (void)
{
int size = max_reg_num ();
int old;
gcc_assert (reg_pref != NULL);
if (reg_info_size == max_reg_num ())
return false;
old = reg_info_size;
reg_info_size = max_reg_num ();
gcc_assert (reg_pref && reg_renumber);
reg_renumber = XRESIZEVEC (short, reg_renumber, size);
reg_pref = XRESIZEVEC (struct reg_pref, reg_pref, size);
reg_renumber = XRESIZEVEC (short, reg_renumber, reg_info_size);
reg_pref = XRESIZEVEC (struct reg_pref, reg_pref, reg_info_size);
memset (reg_pref + old, -1,
(reg_info_size - old) * sizeof (struct reg_pref));
memset (reg_renumber + old, -1, (reg_info_size - old) * sizeof (short));
return true;
}
......@@ -1004,19 +994,55 @@ free_reg_info (void)
}
}
/* Initialize some global data for this pass. */
static unsigned int
reginfo_init (void)
{
if (df)
df_compute_regs_ever_live (true);
/* This prevents dump_flow_info from losing if called
before reginfo is run. */
reg_pref = NULL;
allocate_reg_info ();
/* No more global register variables may be declared. */
no_global_reg_vars = 1;
return 1;
}
struct rtl_opt_pass pass_reginfo_init =
{
{
RTL_PASS,
"reginfo", /* name */
NULL, /* gate */
reginfo_init, /* execute */
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
TV_NONE, /* tv_id */
0, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
0 /* todo_flags_finish */
}
};
/* Set up preferred and alternate classes for REGNO as PREFCLASS and
ALTCLASS. */
/* Set up preferred, alternate, and cover classes for REGNO as
PREFCLASS, ALTCLASS, and COVERCLASS. */
void
setup_reg_classes (int regno,
enum reg_class prefclass, enum reg_class altclass)
enum reg_class prefclass, enum reg_class altclass,
enum reg_class coverclass)
{
if (reg_pref == NULL)
return;
reg_pref[regno].prefclass = prefclass;
reg_pref[regno].altclass = altclass;
reg_pref[regno].coverclass = coverclass;
}
......
......@@ -112,6 +112,7 @@ a register with any other reload. */
#include "params.h"
#include "target.h"
#include "df.h"
#include "ira.h"
/* True if X is a constant that can be forced into the constant pool. */
#define CONST_POOL_OK_P(X) \
......@@ -2589,6 +2590,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
char goal_alternative_earlyclobber[MAX_RECOG_OPERANDS];
int goal_alternative_swapped;
int best;
int best_small_class_operands_num;
int commutative;
char operands_match[MAX_RECOG_OPERANDS][MAX_RECOG_OPERANDS];
rtx substed_operand[MAX_RECOG_OPERANDS];
......@@ -2914,6 +2916,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
all the operands together against the register constraints. */
best = MAX_RECOG_OPERANDS * 2 + 600;
best_small_class_operands_num = 0;
swapped = 0;
goal_alternative_swapped = 0;
......@@ -3697,22 +3700,48 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
/* If this alternative can be made to work by reloading,
and it needs less reloading than the others checked so far,
record it as the chosen goal for reloading. */
if (! bad && best > losers)
if (! bad)
{
for (i = 0; i < noperands; i++)
bool change_p = false;
int small_class_operands_num = 0;
if (best >= losers)
{
goal_alternative[i] = this_alternative[i];
goal_alternative_win[i] = this_alternative_win[i];
goal_alternative_match_win[i] = this_alternative_match_win[i];
goal_alternative_offmemok[i] = this_alternative_offmemok[i];
goal_alternative_matches[i] = this_alternative_matches[i];
goal_alternative_earlyclobber[i]
= this_alternative_earlyclobber[i];
for (i = 0; i < noperands; i++)
small_class_operands_num
+= SMALL_REGISTER_CLASS_P (this_alternative[i]) ? 1 : 0;
if (best > losers
|| (best == losers
/* If the cost of the reloads is the same,
prefer alternative which requires minimal
number of small register classes for the
operands. This improves chances of reloads
for insn requiring small register
classes. */
&& (small_class_operands_num
< best_small_class_operands_num)))
change_p = true;
}
if (change_p)
{
for (i = 0; i < noperands; i++)
{
goal_alternative[i] = this_alternative[i];
goal_alternative_win[i] = this_alternative_win[i];
goal_alternative_match_win[i]
= this_alternative_match_win[i];
goal_alternative_offmemok[i]
= this_alternative_offmemok[i];
goal_alternative_matches[i] = this_alternative_matches[i];
goal_alternative_earlyclobber[i]
= this_alternative_earlyclobber[i];
}
goal_alternative_swapped = swapped;
best = losers;
best_small_class_operands_num = small_class_operands_num;
goal_alternative_number = this_alternative_number;
goal_earlyclobber = this_earlyclobber;
}
goal_alternative_swapped = swapped;
best = losers;
goal_alternative_number = this_alternative_number;
goal_earlyclobber = this_earlyclobber;
}
}
......
......@@ -1898,10 +1898,8 @@ extern rtx remove_free_EXPR_LIST_node (rtx *);
/* Initialize may_move_cost and friends for mode M. */
extern void init_move_cost (enum machine_mode);
/* Allocate register info memory. */
extern void allocate_reg_info (void);
/* Resize reg info. */
extern void resize_reg_info (void);
extern bool resize_reg_info (void);
/* Free up register info memory. */
extern void free_reg_info (void);
......@@ -1912,7 +1910,9 @@ extern const char *decode_asm_operands (rtx, rtx *, rtx **, const char **,
extern enum reg_class reg_preferred_class (int);
extern enum reg_class reg_alternate_class (int);
extern void setup_reg_classes (int, enum reg_class, enum reg_class);
extern enum reg_class reg_cover_class (int);
extern void setup_reg_classes (int, enum reg_class, enum reg_class,
enum reg_class);
extern void split_all_insns (void);
extern unsigned int split_all_insns_noflow (void);
......
......@@ -441,6 +441,7 @@ struct deps_reg
{
rtx uses;
rtx sets;
rtx implicit_sets;
rtx clobbers;
int uses_length;
int clobbers_length;
......@@ -642,6 +643,14 @@ extern spec_info_t spec_info;
extern struct haifa_sched_info *current_sched_info;
/* Do register pressure sensitive insn scheduling if the flag is set
up. */
extern bool sched_pressure_p;
/* Map regno -> its cover class. The map defined only when
SCHED_PRESSURE_P is true. */
extern enum reg_class *sched_regno_cover_class;
/* Indexed by INSN_UID, the collection of all data associated with
a single instruction. */
......@@ -687,6 +696,52 @@ struct _haifa_deps_insn_data
unsigned int cant_move : 1;
};
/* Bits used for storing values of the fields in the following
structure. */
#define INCREASE_BITS 8
/* The structure describes how the corresponding insn increases the
register pressure for each cover class. */
struct reg_pressure_data
{
/* Pressure increase for given class because of clobber. */
unsigned int clobber_increase : INCREASE_BITS;
/* Increase in register pressure for given class because of register
sets. */
unsigned int set_increase : INCREASE_BITS;
/* Pressure increase for given class because of unused register
set. */
unsigned int unused_set_increase : INCREASE_BITS;
/* Pressure change: #sets - #deaths. */
int change : INCREASE_BITS;
};
/* The following structure describes usage of registers by insns. */
struct reg_use_data
{
/* Regno used in the insn. */
int regno;
/* Insn using the regno. */
rtx insn;
/* Cyclic list of elements with the same regno. */
struct reg_use_data *next_regno_use;
/* List of elements with the same insn. */
struct reg_use_data *next_insn_use;
};
/* The following structure describes used sets of registers by insns.
Registers are pseudos whose cover class is not NO_REGS or hard
registers available for allocations. */
struct reg_set_data
{
/* Regno used in the insn. */
int regno;
/* Insn setting the regno. */
rtx insn;
/* List of elements with the same insn. */
struct reg_set_data *next_insn_set;
};
struct _haifa_insn_data
{
/* We can't place 'struct _deps_list' into h_i_d instead of deps_list_t
......@@ -712,10 +767,6 @@ struct _haifa_insn_data
short cost;
/* This weight is an estimation of the insn's contribution to
register pressure. */
short reg_weight;
/* Set if there's DEF-USE dependence between some speculatively
moved load insn and this one. */
unsigned int fed_by_spec_load : 1;
......@@ -740,6 +791,26 @@ struct _haifa_insn_data
/* Original pattern of the instruction. */
rtx orig_pat;
/* The following array contains info how the insn increases register
pressure. There is an element for each cover class of pseudos
referenced in insns. */
struct reg_pressure_data *reg_pressure;
/* The following array contains maximal reg pressure between last
scheduled insn and given insn. There is an element for each
cover class of pseudos referenced in insns. This info updated
after scheduling each insn for each insn between the two
mentioned insns. */
int *max_reg_pressure;
/* The following list contains info about used pseudos and hard
registers available for allocation. */
struct reg_use_data *reg_use_list;
/* The following list contains info about set pseudos and hard
registers available for allocation. */
struct reg_set_data *reg_set_list;
/* Info about how scheduling the insn changes cost of register
pressure excess (between source and target). */
int reg_pressure_excess_cost_change;
};
typedef struct _haifa_insn_data haifa_insn_data_def;
......@@ -755,7 +826,12 @@ extern VEC(haifa_insn_data_def, heap) *h_i_d;
/* Accessor macros for h_i_d. There are more in haifa-sched.c and
sched-rgn.c. */
#define INSN_PRIORITY(INSN) (HID (INSN)->priority)
#define INSN_REG_WEIGHT(INSN) (HID (INSN)->reg_weight)
#define INSN_REG_PRESSURE(INSN) (HID (INSN)->reg_pressure)
#define INSN_MAX_REG_PRESSURE(INSN) (HID (INSN)->max_reg_pressure)
#define INSN_REG_USE_LIST(INSN) (HID (INSN)->reg_use_list)
#define INSN_REG_SET_LIST(INSN) (HID (INSN)->reg_set_list)
#define INSN_REG_PRESSURE_EXCESS_COST_CHANGE(INSN) \
(HID (INSN)->reg_pressure_excess_cost_change)
#define INSN_PRIORITY_STATUS(INSN) (HID (INSN)->priority_status)
typedef struct _haifa_deps_insn_data haifa_deps_insn_data_def;
......@@ -1153,7 +1229,9 @@ extern void extend_dependency_caches (int, bool);
extern void debug_ds (ds_t);
/* Functions in haifa-sched.c. */
extern void sched_init_region_reg_pressure_info (void);
extern int haifa_classify_insn (const_rtx);
extern void get_ebb_head_tail (basic_block, basic_block, rtx *, rtx *);
extern int no_real_insns_p (const_rtx, const_rtx);
......@@ -1163,6 +1241,7 @@ extern int dep_cost_1 (dep_t, dw_t);
extern int dep_cost (dep_t);
extern int set_priorities (rtx, rtx);
extern void sched_setup_bb_reg_pressure_info (basic_block, rtx);
extern void schedule_block (basic_block *);
extern int cycle_issued_insns;
......
......@@ -2613,6 +2613,8 @@ deps_join (struct deps *succ_deps, struct deps *pred_deps)
succ_rl->uses = concat_INSN_LIST (pred_rl->uses, succ_rl->uses);
succ_rl->sets = concat_INSN_LIST (pred_rl->sets, succ_rl->sets);
succ_rl->implicit_sets
= concat_INSN_LIST (pred_rl->implicit_sets, succ_rl->implicit_sets);
succ_rl->clobbers = concat_INSN_LIST (pred_rl->clobbers,
succ_rl->clobbers);
succ_rl->uses_length += pred_rl->uses_length;
......@@ -2690,12 +2692,14 @@ propagate_deps (int bb, struct deps *pred_deps)
bb's successors.
Specifically for reg-reg data dependences, the block insns are
scanned by sched_analyze () top-to-bottom. Two lists are
scanned by sched_analyze () top-to-bottom. Three lists are
maintained by sched_analyze (): reg_last[].sets for register DEFs,
and reg_last[].uses for register USEs.
reg_last[].implicit_sets for implicit hard register DEFs, and
reg_last[].uses for register USEs.
When analysis is completed for bb, we update for its successors:
; - DEFS[succ] = Union (DEFS [succ], DEFS [bb])
; - IMPLICIT_DEFS[succ] = Union (IMPLICIT_DEFS [succ], IMPLICIT_DEFS [bb])
; - USES[succ] = Union (USES [succ], DEFS [bb])
The mechanism for computing mem-mem data dependence is very
......@@ -2934,6 +2938,28 @@ schedule_region (int rgn)
sched_extend_ready_list (rgn_n_insns);
if (sched_pressure_p)
{
sched_init_region_reg_pressure_info ();
for (bb = 0; bb < current_nr_blocks; bb++)
{
basic_block first_bb, last_bb;
rtx head, tail;
first_bb = EBB_FIRST_BB (bb);
last_bb = EBB_LAST_BB (bb);
get_ebb_head_tail (first_bb, last_bb, &head, &tail);
if (no_real_insns_p (head, tail))
{
gcc_assert (first_bb == last_bb);
continue;
}
sched_setup_bb_reg_pressure_info (first_bb, PREV_INSN (head));
}
}
/* Now we can schedule all blocks. */
for (bb = 0; bb < current_nr_blocks; bb++)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment