OSDN Git Service

2011-03-28 Vladimir Makarov <vmakarov@redhat.com>
authorvmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 29 Mar 2011 01:02:05 +0000 (01:02 +0000)
committervmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 29 Mar 2011 01:02:05 +0000 (01:02 +0000)
* ira-color.c (update_left_conflict_sizes_p): Don't assume that
conflict object hard regset nodes have intersecting hard reg sets.

* regmove.c (regmove_optimize): Move ira_set_pseudo_classes call
after regstat_init_n_sets_and_refs.

* ira.c: Add more comments at the top.
(setup_stack_reg_pressure_class, setup_pressure_classes):
Add comments how we compute the register pressure classes.
(setup_allocno_and_important_classes): Add more comments.
(setup_class_translate_array, reorder_important_classes)
(setup_reg_class_relations): Add comments.

* ira-emit.c: Add 2011 to the Copyright line.  Add comments at the
start of the file.

* ira-color.c: Add 2011 to the Copyright line.
(assign_hard_reg):  Add more comments.
(improve_allocation): Ditto.

* ira-costs.c: Add 2011 to the Copyright line.
(setup_cost_classes, setup_regno_cost_classes_by_aclass): Add more
comments.
(setup_regno_cost_classes_by_mode): Ditto.

Initial patches from ira-improv branch:

2010-08-13  Vladimir Makarov  <vmakarov@redhat.com>

* ira-build.c: (ira_create_object): Remove initialization of
OBJECT_PROFITABLE_HARD_REGS.  Initialize OBJECT_ADD_DATA.
(ira_create_allocno): Remove initialization of
ALLOCNO_MEM_OPTIMIZED_DEST, ALLOCNO_MEM_OPTIMIZED_DEST_P,
ALLOCNO_SOMEWHERE_RENAMED_P, ALLOCNO_CHILD_RENAMED_P,
ALLOCNO_IN_GRAPH_P, ALLOCNO_MAY_BE_SPILLED_P, ALLOCNO_COLORABLE_P,
ALLOCNO_NEXT_BUCKET_ALLOCNO, ALLOCNO_PREV_BUCKET_ALLOCNO,
ALLOCNO_FIRST_COALESCED_ALLOCNO, ALLOCNO_NEXT_COALESCED_ALLOCNO.
Initialize ALLOCNO_ADD_DATA.
(copy_info_to_removed_store_destinations): Use ALLOCNO_EMIT_DATA
and allocno_emit_reg instead of ALLOCNO_MEM_OPTIMIZED_DEST_P and
ALLOCNO_REG.
(ira_flattening): Ditto.  Use ALLOCNO_EMIT_DATA instead of
ALLOCNO_MEM_OPTIMIZED_DEST and ALLOCNO_SOMEWHERE_RENAMED_P.

* ira.c (ira_reallocate): Remove.
(setup_pressure_classes): Call
ira_init_register_move_cost_if_necessary.  Use
ira_register_move_cost instead of ira_get_register_move_cost.
(setup_allocno_assignment_flags): Use ALLOCNO_EMIT_DATA.
(ira): Call ira_initiate_emit_data and ira_finish_emit_data.

* ira-color.c: Use ALLOCNO_COLOR_DATA instead of
ALLOCNO_IN_GRAPH_P, ALLOCNO_MAY_BE_SPILLED_P, ALLOCNO_COLORABLE_P,
ALLOCNO_AVAILABLE_REGS_NUM, ALLOCNO_NEXT_BUCKET_ALLOCNO,
ALLOCNO_PREV_BUCKET_ALLOCNO. ALLOCNO_TEMP. Use OBJECT_COLOR_DATA
instead of OBJECT_PROFITABLE_HARD_REGS, OBJECT_HARD_REGS_NODE,
OBJECT_HARD_REGS_SUBNODES_START, OBJECT_HARD_REGS_SUBNODES_NUM.
Fix formatting.
(object_hard_regs_t, object_hard_regs_node_t): Move from
ira-int.h.
(struct object_hard_regs, struct object_hard_regs_node): Ditto.
(struct allocno_color_data): New.
(allocno_color_data_t): New typedef.
(allocno_color_data): New definition.
(ALLOCNO_COLOR_DATA): New macro.
(struct object_color_data): New.
(object_color_data_t): New typedef.
(object_color_data): New definition.
(OBJECT_COLOR_DATA): New macro.
(update_copy_costs, calculate_allocno_spill_cost): Call
ira_init_register_move_cost_if_necessary.  Use
ira_register_move_cost instead of ira_get_register_move_cost.
(move_spill_restore, update_curr_costs): Ditto.
(allocno_spill_priority): Make it inline.
(color_pass): Allocate and free allocno_color_dat and
object_color_data.
(struct coalesce_data, coalesce_data_t): New.
(allocno_coalesce_data): New definition.
(ALLOCNO_COALESCE_DATA): New macro.
(merge_allocnos, coalesced_allocno_conflict_p): Use
ALLOCNO_COALESCED_DATA instead of ALLOCNO_FIRST_COALESCED_ALLOCNO,
ALLOCNO_NEXT_COALESCED_ALLOCNO, ALLOCNO_TEMP.
(coalesce_allocnos): Ditto.
(setup_coalesced_allocno_costs_and_nums): Ditto.
(collect_spilled_coalesced_allocnos): Ditto.
(slot_coalesced_allocno_live_ranges_intersect_p): Ditto.
(setup_slot_coalesced_allocno_live_ranges): Ditto.
(coalesce_spill_slots): Ditto.
(ira_sort_regnos_for_alter_reg): Ditto.  Allocate, initialize and
free allocno_coalesce_data.

* ira-conflicts.c: Fix formatting.
(process_regs_for_copy): Call
ira_init_register_move_cost_if_necessary.  Use
ira_register_move_cost instead of ira_get_register_move_cost.
(build_object_conflicts): Optimize.

* ira-costs.c (record_reg_classes): Optimize.  Call
ira_init_register_move_cost_if_necessary.  Use
ira_register_move_cost, ira_may_move_in_cost, and
ira_may_move_out_cost instead of ira_get_register_move_cost and
ira_get_may_move_cost.
(record_address_regs): Ditto.
(scan_one_insn): Optimize.
(find_costs_and_classes): Optimize.
(process_bb_node_for_hard_reg_moves): Call
ira_init_register_move_cost_if_necessary.  Use
ira_register_move_cost instead of ira_get_register_move_cost.

* ira-emit.c: Use allocno_emit_reg, ALLOCNO_EMIT_DATA instead of
ALLOCNO_REG, ALLOCNO_CHILD_RENAMED_P, ALLOCNO_MEM_OPTIMIZED_DEST,
ALLOCNO_MEM_OPTIMIZED_DEST_P, and ALLOCNO_SOMEWHERE_RENAMED_P.
(ira_allocno_emit_data, void_p, new_allocno_emit_data_vec): New
definitions.
(ira_initiate_emit_data, ira_finish_emit_data)
(create_new_allocno): New functions.
(modify_move_list): Call create_new_alloc instead of
ira_create_allocno.
(emit_move_list): Call ira_init_register_move_cost_if_necessary.
Use ira_register_move_cost instead of ira_get_register_move_cost.

* ira-int.h: Fix some comments.
(object_hard_regs_t, object_hard_regs_node_t): Move
to ira-color.c.
(struct object_hard_regs, struct object_hard_regs_node):
Ditto.
(struct ira_object): Remove profitable_hard_regs, hard_regs_node,
hard_regs_subnodes_start, hard_regs_subnodes_num.  Add new member
add_data.
(struct ira_allocno): Make mode and aclass a bitfield.  Move other
bitfield after mode.  Make hard_regno a short int.  Make
hard_regno short.  Remove first_coalesced_allocno and
next_coalesced_allocno.  Move mem_optimized_dest_p,
somewhere_renamed_p, child_renamed_p, reg, and mem_optimized_dest
into struct ira_emit_data.  Remove in_graph_p, may_be_spilled_p,
available_regs_num, next_bucket_allocno, prev_bucket_allocno,
temp, colorable_p.  Add new member add_data.
(ALLOCNO_IN_GRAPH_P, ALLOCNO_MAY_BE_SPILLED_P): Remove.
(ALLOCNO_COLORABLE_P, ALLOCNO_AVAILABLE_REGS_NUM): Remove.
(ALLOCNO_NEXT_BUCKET_ALLOCNO, ALLOCNO_PREV_BUCKET_ALLOCNO): Remove.
(ALLOCNO_TEMP, ALLOCNO_FIRST_COALESCED_ALLOCNO): Remove.
(ALLOCNO_NEXT_COALESCED_ALLOCNO): Remove.
(ALLOCNO_ADD_DATA): New macro.
(ira_emit_data_t): New typedef.
(struct ira_emit_data): New.  Move mem_optimized_dest_p,
somewhere_renamed_p, child_renamed_p, reg, mem_optimized_dest
from struct ira_allocno.
(ALLOCNO_EMIT_DATA): New macro.
(ira_allocno_emit_data, allocno_emit_reg): New.
(ALLOCNO_PROFITABLE_HARD_REGS, OBJECT_HARD_REGS_NODE): Remove.
(OBJECT_HARD_REGS_SUBNODES_STAR, OBJECT_HARD_REGS_SUBNODES_NUM):
Remove.
(OBJECT_ADD_DATA): New macro.
(ira_reallocate): Remove.
(ira_initiate_emit_data, ira_finish_emit_data): New.
(ira_get_register_move_cost, ira_get_may_move_cost): Remove.
(ira_init_register_move_cost_if_necessary): New.
(ira_object_conflict_iter_next): Merge into
ira_object_conflict_iter_cond.
(FOR_EACH_OBJECT_CONFLICT): Don't use
ira_object_conflict_iter_next.

* ira-live.c: (process_single_reg_class_operands): Call
ira_init_register_move_cost_if_necessary.  Use
ira_register_move_cost instead of ira_get_register_move_cost.

2010-08-13  Vladimir Makarov  <vmakarov@redhat.com>

* ira-int.h (struct target_ira_int): Remove x_cost_classes.

* ira-costs.c: Fix formatting.
(cost_classes, cost_classes_num): Remove.
(struct cost_classes, cost_classes_t, const_cost_classes_t): New.
(regno_cost_classes, cost_classes_hash, cost_classes_eq): New.
(cost_classes_del, cost_classes_htab): New.
(cost_classes_aclass_cache, cost_classes_mode_cache): New.
(initiate_regno_cost_classes, setup_cost_classes): New.
(setup_regno_cost_classes_by_aclass): New.
(setup_regno_cost_classes_by_mode, finish_regno_cost_classes):
New.
(record_reg_classes): Use regno_cost_classes instead of
cost_classes.  Move checking opposite operand up.
(record_address_regs): Use regno_cost_classes
instead of cost_classes.
(scan_one_insn): Ditto.  Use always general register.
(print_allocno_costs): Use regno_cost_classes instead of
cost_classes.
(print_pseudo_costs): Ditto.  Use Reg_N_REFS.
(find_costs_and_classes): Set up cost classes for each registers.
Use also their mode for this.  Use regno_cost_classes instead of
cost_classes.
(setup_allocno_class_and_costs): Use regno_cost_classes instead of
cost_classes.
(free_ira_costs, ira_init_costs): Don't use cost_classes.
(ira_costs, ira_set_pseudo_classes): Call
initiate_regno_cost_classes and finish_regno_cost_classes.

2010-10-04  Vladimir Makarov  <vmakarov@redhat.com>

* target-def.h (TARGET_IRA_COVER_CLASSES): Remove.

* target.def (ira_cover_classes): Remove.

* doc/tm.texi: Remove TARGET_IRA_COVER_CLASSES and
IRA_COVER_CLASSES.

* doc/tm.texi.in: Ditto.

* ira-conflicts.c: Remove mentioning cover classes from the file.
Use ALLOCNO_CLASS instead of ALLOCNO_COVER_CLASS.  Use
ALLOCNO_COVER_CLASS_COST instead of ALLOCNO_CLASS_COST.  Fix
formatting.

* targhooks.c (default_ira_cover_classes): Remove.

* targhooks.h (default_ira_cover_classes): Ditto.

* haifa-sched.c: Remove mentioning cover classes from the file.
Use ira_reg_pressure_cover instead of ira_reg_class_cover.  Use
ira_pressure_classes and ira_pressure_classes_num instead of
ira_reg_class_cover_size and ira_reg_class_cover.  Use
sched_regno_pressure_class instead of sched_regno_cover_class.
(mark_regno_birth_or_death, setup_insn_reg_pressure_info): Use
ira_reg_class_max_nregs instead of ira_reg_class_nregs.

* ira-int.h: Add 2010 to Copyright.  Remove mentioning cover
classes from the file.
(object_hard_regs_t, object_hard_regs_node_t): New typedefs.
(struct object_hard_regs, struct object_hard_regs_node): New.
(struct ira_object): New members profitable_hard_regs,
hard_regs_node, hard_regs_subnodes_start, hard_regs_subnodes_num.
(struct ira_allocno): Rename cover_class to aclass.  Rename
cover_class_cost and updated_cover_class_cost to class_cost and
updated_class_cost.  Remove splay_removed_p and
left_conflict_size.  Add new members colorable_p.
(ALLOCNO_SPLAY_REMOVED_P, ALLOCNO_LEFT_CONFLICTS_SIZE): Remove.
(ALLOCNO_COLORABLE_P): New macro.
(ALLOCNO_COVER_CLASS): Rename to ALLOCNO_CLASS.
(ALLOCNO_COVER_CLASS_COST, ALLOCNO_UPDATED_COVER_CLASS_COST):
Rename to ALLOCNO_CLASS_COST and ALLOCNO_UPDATED__CLASS_COST.
(OBJECT_...): Rename parameter C to O.
(OBJECT_PROFITABLE_HARD_REGS): New macro.
(OBJECT_HARD_REGS_NODE, OBJECT_HARD_REGS_SUBNODES_START)
(OBJECT_HARD_REGS_SUBNODES_NUM): New macros.
(struct target_ira_int): New members x_ira_max_memory_move_cost,
x_ira_max_register_move_cost, x_ira_max_may_move_in_cost,
x_ira_max_may_move_out_cost, x_ira_reg_allocno_class_p,
x_ira_reg_pressure_class_p, x_ira_important_class_nums,
x_ira_reg_class_superunion.  Rename x_prohibited_class_mode_reg to
x_ira_prohibited_class_mode_reg.  Rename x_ira_reg_class_union to
x_ira_reg_class_subunion.
(ira_max_memory_move_cost, ira_max_register_move_cost)
(ira_max_may_move_in_cost, ira_max_may_move_out_cost)
(ira_reg_allocno_class_p, ira_reg_pressure_class_p)
(ira_important_class_nums, ira_reg_class_superunion): New macros.
(prohibited_class_mode_regs): Rename to
ira_prohibited_class_mode_regs.
(ira_reg_class_union): Rename to ira_reg_class_subunion.
(ira_debug_class_cover): Rename to ira_debug_allocno_classes.
(ira_set_allocno_cover_class): Rename to ira_set_allocno_class.
(ira_tune_allocno_costs_and_cover_classes): Rename to
ira_tune_allocno_costs.
(ira_debug_hard_regs_forest): New.
(ira_object_conflict_iter_init, ira_object_conflict_iter_cond)
(ira_object_conflict_iter_next): Fix comments.
(ira_hard_reg_set_intersection_p, hard_reg_set_size): New
functions.
(ira_allocate_and_set_costs, ira_allocate_and_copy_costs): Rename
cover_class to aclass.
(ira_allocate_and_accumulate_costs): Ditto.
(ira_allocate_and_set_or_copy_costs): Ditto.

* opts.c (decode_options): Remove ira_cover_class check.

* ira-color.c: Remove mentioning cover classes from the file.  Use
ALLOCNO_CLASS, ALLOCNO_CLASS_COST, and ALLOCNO_UPDATED_CLASS_COST
instead of ALLOCNO_COVER_CLASS, ALLOCNO_COVER_CLASS_COST, and
ALLOCNO_UPDATED_COVER_CLASS_COST.  Fix formatting.
(splay-tree.h): Remove include.
(allocno_coalesced_p, processed_coalesced_allocno_bitmap): Move
before copy_freq_compare_func.
(allocnos_for_spilling, removed_splay_allocno_vec): Remove.
(object_hard_regs_vec, object_hard_regs_htab, node_check_tick):
New definitions.
(hard_regs_roots, hard_regs_node_vec): Ditto.
(object_hard_regs_hash, object_hard_regs_eq, find_hard_regs): Ditto.
(insert_hard_regs, init_object_hard_regs, add_object_hard_regs): Ditto.
(finish_object_hard_regs, object_hard_regs_compare): Ditto.
(create_new_object_hard_regs_node): Ditto.
(add_new_object_hard_regs_node_to_forest): Ditto.
(add_object_hard_regs_to_forest, collect_object_hard_regs_cover):
Ditto.
(setup_object_hard_regs_nodes_parent, first_common_ancestor_node):
Ditto.
(print_hard_reg_set, print_hard_regs_subforest): Ditto.
(print_hard_regs_forest, ira_debug_hard_regs_forest): Ditto.
(remove_unused_object_hard_regs_nodes): Ditto.
(enumerate_object_hard_regs_nodes): Ditto.
(object_hard_regs_nodes_num, object_hard_regs_nodes): Ditto.
(object_hard_regs_subnode_t): Ditto.
(struct object_hard_regs_subnode): Ditto.
(object_hard_regs_subnodes, object_hard_regs_subnode_index): Ditto.
(setup_object_hard_regs_subnode_index): Ditto.
(get_object_hard_regs_subnodes_num): Ditto.
(form_object_hard_regs_nodes_forest): Ditto.
(finish_object_hard_regs_nodes_tree): Ditto.
(finish_object_hard_regs_nodes_forest): Ditto.
(allocnos_have_intersected_live_ranges_p): Rename to
allocnos_conflict_by_live_ranges_p.  Move before
copy_freq_compare_func.
(pseudos_have_intersected_live_ranges_p): Rename to
conflict_by_live_ranges_p.  Move before copy_freq_compare_func.
(setup_left_conflict_sizes_p, update_left_conflict_sizes_p): Ditto.
(empty_profitable_hard_regs, setup_profitable_hard_regs): Ditto.
(update_copy_costs): Remove assert.  Skip cost update if the hard
reg does not belong the class.
(assign_hard_reg): Process only profitable hard regs.
(uncolorable_allocnos_num): Make it scalar.
(allocno_spill_priority): Use ALLOCNO_EXCESS_PRESSURE_POINTS_NUM
and ira_reg_class_max_nregs instead of ALLOCNO_LEFT_CONFLICTS_SIZE
and ira_reg_class_max_nregs.
(bucket_allocno_compare_func): Check frequency first.
(sort_bucket): Add compare function as a parameter.
(add_allocno_to_ordered_bucket): Assume no coalesced allocnos.
(uncolorable_allocnos_splay_tree, USE_SPLAY_P): Remove.
(push_allocno_to_stack): Rewrite for checking new allocno
colorability.
(remove_allocno_from_bucket_and_push): Print cost too.  Remove
assert.
(push_only_colorable): Pass new parameter to sort_bucket.
(push_allocno_to_spill): Remove.
(allocno_spill_priority_compare): Make it inline and rewrite.
(splay_tree_allocate, splay_tree_free): Remove.
(allocno_spill_sort_compare): New function.
(push_allocnos_to_stack): Sort allocnos for spilling once.  Don't
build and use splay tree.  Choose first allocno in uncolorable
allocno bucket to spill.  Remove setting spill cost.
(all_conflicting_hard_regs): Remove.
(setup_allocno_available_regs_num): Check only profitable hard
regs.  Print info about hard regs nodes.
(setup_allocno_left_conflicts_size): Remove.
(put_allocno_into_bucket): Don't call
setup_allocno_left_conflicts_size.  Use
setup_left_conflict_sizes_p.
(improve_allocation): New.
(color_allocnos): Call setup_profitable_hard_regs,
form_object_hard_regs_nodes_forest, improve_allocation,
finish_object_hard_regs_nodes_forest.  Setup spill cost.
(print_loop_title): Use pressure classes.
(color_allocnso): Ditto.
(do_coloring): Remove allocation and freeing splay_tree_node_pool
and allocnos_for_spilling.
(ira_sort_regnos_for_alter_reg): Don't setup members
{first,next}_coalesced_allocno.
(color): Remove allocating and freeing removed_splay_allocno_vec.
(fast_allocation): Use ira_prohibited_class_mode_regs instead of
prohibited_class_mode_regs.

* ira-lives.c: Remove mentioning cover classes from the file.  Fix
formatting.
(update_allocno_pressure_excess_length): Use pressure classes.
(inc_register_pressure, dec_register_pressure): Check for pressure
class.
(mark_pseudo_regno_live, mark_pseudo_regno_subword_live): Use
pressure class.  Use ira_reg_class_nregs instead of
ira_reg_class_max_nregs.
(mark_pseudo_regno_dead, mark_pseudo_regno_subword_dead): Ditto.
(mark_hard_reg_live, mark_hard_reg_dead): Use pressure class.
(single_reg_class): Use ira_reg_class_nregs instead of
ira_reg_class_max_nregs.
(process_bb_node_lives): Use pressure classes.

* ira-emit.c: Remove mentioning cover classes from the file.  Use
ALLOCNO_CLASS instead of ALLOCNO_COVER_CLASS.  Fix formatting.
(change_loop): Use pressure classes.
(modify_move_list): Call ira_set_allocno_class instead of
ira_set_allocno_cover_class.

* ira-build.c: Remove mentioning cover classes from the file.  Use
ALLOCNO_CLASS and ALLOCNO_CLASS_COST instead of
ALLOCNO_COVER_CLASS and ALLOCNO_COVER_CLASS_COST.  Use
ALLOCNO_UPDATED_CLASS_COST instead of
ALLOCNO_UPDATED_COVER_CLASS_COST.  Fix formatting.
(ira_create_object): Initiate OBJECT_PROFITABLE_HARD_REGS.
(ira_create_allocno): Remove initialization of
ALLOCNO_SPLAY_REMOVED_P, ALLOCNO_LEFT_CONFLICT_SIZE.  Initialize
ALLOCNO_COLORABLE_P.
(ira_set_allocno_cover_class): Rename to ira_set_allocno_class.
Update conflict regs for the objects.
(create_cap_allocno): Remove assert.  Don't propagate
ALLOCNO_AVAILABLE_REGS_NUM.
(ira_free_allocno_costs): New function.
(finish_allocno): Change a part of code into call of
ira_free_allocno_costs.
(low_pressure_loop_node_p): Use pressure classes.
(object_range_compare_func): Don't compare classes.
(setup_min_max_conflict_allocno_ids): Ditto.

* loop-invariant.c: Remove mentioning cover classes from the file.
Use ira_pressure_classes and ira_pressure_classes_num instead of
ira_reg_class_cover_size and ira_reg_class_cover.  Fix formatting.
(get_cover_class_and_nregs): Rename to
get_cover_pressure_and_nregs.  Use ira_reg_class_max_nregs instead
of ira_reg_class_nregs.  Use reg_allocno_class instead of
reg_cover_class.
(get_inv_cost): Use instead ira_stack_reg_pressure_class of
STACK_REG_COVER_CLASS.
(get_regno_cover_class): Rename to get_regno_pressure_class.
(move_loop_invariants): Initialize and finalize regstat.

* ira.c: Remove mentioning cover classes from the file.  Add
comments about coloring without cover classes.  Use ALLOCNO_CLASS
instead of ALLOCNO_COVER_CLASS.  Fix formatting.
(alloc_reg_class_subclasses, setup_reg_subclasses): Move it before
setup_class_subset_and_memory_move_costs.
(setup_stack_reg_pressure_class, setup_pressure_classes): New.
(setup_cover_and_important_classes): Rename to
setup_allocno_and_important_classes.
(setup_class_translate_array): New.
(setup_class_translate): Call it for allocno and pressure classes.
(cover_class_order): Rename to allocno_class_order.
(comp_reg_classes_func): Use ira_allocno_class_translate instead
of ira_class_translate.
(reorder_important_classes): Set up ira_important_class_nums.
(setup_reg_class_relations): Set up ira_reg_class_superunion.
(print_class_cover): Rename to print_classes.  Add parameter.
(ira_debug_class_cover): Rename to ira_debug_allocno_classes.
Print pressure classes too.
(find_reg_class_closure): Rename to find_reg_classes.  Don't call
setup_reg_subclasses.
(ira_hard_regno_cover_class): Rename to
ira_hard_regno_allocno_class.
(ira_reg_class_nregs): Rename to ira_reg_class_max_nregs.
(setup_prohibited_class_mode_regs): Use
ira_prohibited_class_mode_regs instead of
prohibited_class_mode_regs.
(clarify_prohibited_class_mode_regs): New function.
(ira_init_register_move_cost): Set up ira_max_register_move_cost,
ira_max_may_move_in_cost, and ira_max_may_move_out_cost.
(ira_init_once): Initialize them.
(free_register_move_costs): Process them.
(ira_init): Move calls of find_reg_classes and
setup_hard_regno_aclass after setup_prohibited_class_mode_regs.
Call clarify_prohibited_class_mode_regs.
(ira_no_alloc_reg): Remove.
(too_high_register_pressure_p): Use pressure classes.

* sched-deps.c: Remove mentioning cover classes from the file.
Use ira_reg_pressure_cover instead of ira_reg_class_cover.  Use
ira_pressure_classes and ira_pressure_classes_num instead of
ira_reg_class_cover_size and ira_reg_class_cover.
(mark_insn_hard_regno_birth, mark_hard_regno_death): Use
sched_regno_pressure_class instead of sched_regno_cover_class.
(mark_insn_pseudo_birth, mark_pseudo_death): Ditto.  Use
ira_reg_class_max_nregs instead of ira_reg_class_nregs.

* ira.h: Add 2010 to Copyright.
(ira_no_alloc_reg): Remove external.
(struct target_ira): Rename x_ira_hard_regno_cover_class,
x_ira_reg_class_cover_size, x_ira_reg_class_cover, and
x_ira_class_translate to x_ira_hard_regno_allocno_class,
x_ira_allocno_classes_num, x_ira_allocno_classes, and
x_ira_allocno_class_translate.  Add x_ira_pressure_classes_num,
x_ira_pressure_classes, x_ira_pressure_class_translate, and
x_ira_stack_reg_pressure_class.  Rename x_ira_reg_class_nregs to
x_ira_reg_class_max_nregs.  Add x_ira_reg_class_min_nregs and
x_ira_no_alloc_regs.
(ira_hard_regno_cover_class): Rename to
ira_hard_regno_allocno_class.
(ira_reg_class_cover_size, ira_reg_class_cover): Rename to
ira_allocno_classes_num and ira_allocno_classes.
(ira_class_translate): Rename to ira_allocno_class_translate.
(ira_pressure_classes_num, ira_pressure_classes): New definitions.
(ira_pressure_class_translate, ira_stack_reg_pressure_class): Ditto.
(ira_reg_class_nregs): Rename to ira_reg_class_max_nregs.
(ira_reg_class_min_nregs, ira_stack_reg_pressure_class): New
(ira_no_alloc_regs): New.

* ira-costs.c: Add 2010 to Copyright.  Remove mentioning cover
classes from the file.  Use ALLOCNO_CLASS instead of
ALLOCNO_COVER_CLASS.  Use ALLOCNO_CLASS_COST instead of
ALLOCNO_COVER_CLASS_COST.
(regno_cover_class): Rename to regno_aclass.
(record_reg_classes): Use ira_reg_class_subunion instead of
ira_reg_class_union.
(record_address_regs): Check overflow.
(scan_one_insn): Ditto.
(print_allocno_costs): Print total mem cost fore regional
allocation.
(print_pseudo_costs): Use REG_N_REFS.
(find_costs_and_classes): Use classes intersected with them on the
1st pass. Check overflow.  Use ira_reg_class_subunion instead of
ira_reg_class_union.  Use ira_allocno_class_translate and
regno_aclass instead of ira_class_translate and regno_cover_class.
Modify code for finding regno_aclass.  Setup preferred classes for
the next pass.
(setup_allocno_cover_class_and_costs): Rename to
setup_allocno_class_and_costs.  Use regno_aclass instead of
regno_cover_class.  Use ira_set_allocno_class instead of
ira_set_allocno_cover_class.
(init_costs, finish_costs): Use regno_aclass instead of
regno_cover_class.
(ira_costs): Use setup_allocno_class_and_costs instead of
setup_allocno_cover_class_and_costs.
(ira_tune_allocno_costs_and_cover_classes): Rename to
ira_tune_allocno_costs.  Check overflow.  Skip conflict hard regs
by processing objects.  Use ira_reg_class_max_nregs instead of
ira_reg_class_nregs.

* rtl.h (reg_cover_class): Rename to reg_allocno_class.

* sched-int.h: Remove mentioning cover classes from the file.
(sched_regno_cover_class): Rename to sched_regno_pressure_class.

* reginfo.c: Add 2010 to Copyright.  Remove mentioning cover
classes from the file.
(struct reg_pref): Rename coverclass into allocnoclass.
(reg_cover_class): Rename to reg_allocno_class.

* Makefile.in (ira-color.o): Remove SPLAY_TREE_H from
dependencies.

* config/alpha/alpha.h (IRA_COVER_CLASSES): Remove.

* config/arm/arm.h (IRA_COVER_CLASSES): Ditto.

* config/avr/avr.h (IRA_COVER_CLASSES): Ditto.

* config/bfin/bfin.h (IRA_COVER_CLASSES): Ditto.

* config/cris/cris.h (IRA_COVER_CLASSES): Ditto.

* config/fr30/fr30.h (IRA_COVER_CLASSES): Ditto.

* config/frv/frv.h (IRA_COVER_CLASSES): Ditto.

* config/h8300/h8300.h (IRA_COVER_CLASSES): Ditto.

* config/i386/i386.h (STACK_REG_COVER_CLASS): Ditto.

* config/i386/i386.c (TARGET_IRA_COVER_CLASSES)
(i386_ira_cover_classes): Ditto.

* config/ia64/ia64.h (IRA_COVER_CLASSES): Ditto.

* config/iq2000/iq2000.h (IRA_COVER_CLASSES): Ditto.

* config/m32r/m32r.h (IRA_COVER_CLASSES): Ditto.

* config/m68k/m68k.h (IRA_COVER_CLASSES): Ditto.

* config/mcore/mcore.h (IRA_COVER_CLASSES): Ditto.

* config/mep/mep.h (IRA_COVER_CLASSES): Ditto.

* config/mips/mips.c (TARGET_IRA_COVER_CLASSES)
(mips_ira_cover_classes): Ditto.

* config/mn10300/mn10300.h (IRA_COVER_CLASSES): Ditto.

* config/moxie/moxie.h (IRA_COVER_CLASSES): Ditto.

* config/pa/pa64-regs.h (IRA_COVER_CLASSES): Ditto.

* config/pa/pa32-regs.h (IRA_COVER_CLASSES): Ditto.

* config/picochip/picochip.h (IRA_COVER_CLASSES): Ditto.

* config/rs6000/rs6000.h (IRA_COVER_CLASSES_PRE_VSX)
(IRA_COVER_CLASSES_VSX): Ditto.

* config/rs6000/rs6000.c (TARGET_IRA_COVER_CLASSES)
(rs6000_ira_cover_classes): Ditto.

* config/rx/rx.h (IRA_COVER_CLASSES): Ditto.

* config/s390/s390.h (IRA_COVER_CLASSES): Ditto.

* config/score/score.h (IRA_COVER_CLASSES): Ditto.

* config/sh/sh.h (IRA_COVER_CLASSES): Ditto.

* config/sparc/sparc.h (IRA_COVER_CLASSES): Ditto.

* config/spu/spu.h (IRA_COVER_CLASSES): Ditto.

* config/stormy16/stormy16.h (IRA_COVER_CLASSES): Ditto.

* config/v850/v850.h (IRA_COVER_CLASSES): Ditto.

* config/vax/vax.h (IRA_COVER_CLASSES): Ditto.

* config/xtensa/xtensa.h (IRA_COVER_CLASSES): Ditto.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@171649 138bc75d-0d04-0410-961f-82ee72b054a4

60 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/config/alpha/alpha.h
gcc/config/arm/arm.h
gcc/config/avr/avr.h
gcc/config/bfin/bfin.h
gcc/config/cris/cris.h
gcc/config/fr30/fr30.h
gcc/config/frv/frv.h
gcc/config/h8300/h8300.h
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/config/ia64/ia64.h
gcc/config/iq2000/iq2000.h
gcc/config/m32r/m32r.h
gcc/config/m68k/m68k.h
gcc/config/mcore/mcore.h
gcc/config/mep/mep.h
gcc/config/mips/mips.c
gcc/config/mn10300/mn10300.h
gcc/config/moxie/moxie.h
gcc/config/pa/pa32-regs.h
gcc/config/pa/pa64-regs.h
gcc/config/picochip/picochip.h
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/rx/rx.h
gcc/config/s390/s390.h
gcc/config/score/score.h
gcc/config/sh/sh.h
gcc/config/sparc/sparc.h
gcc/config/spu/spu.h
gcc/config/stormy16/stormy16.h
gcc/config/v850/v850.h
gcc/config/vax/vax.h
gcc/config/xtensa/xtensa.h
gcc/doc/tm.texi
gcc/doc/tm.texi.in
gcc/haifa-sched.c
gcc/ira-build.c
gcc/ira-color.c
gcc/ira-conflicts.c
gcc/ira-costs.c
gcc/ira-emit.c
gcc/ira-int.h
gcc/ira-lives.c
gcc/ira.c
gcc/ira.h
gcc/loop-invariant.c
gcc/opts.c
gcc/reginfo.c
gcc/regmove.c
gcc/rtl.h
gcc/sched-deps.c
gcc/sched-int.h
gcc/system.h
gcc/target-def.h
gcc/target.def
gcc/targhooks.c
gcc/targhooks.h

index 3b84d40..ff5d8e4 100644 (file)
@@ -1,3 +1,599 @@
+2011-03-28  Vladimir Makarov  <vmakarov@redhat.com>
+
+       * ira-color.c (update_left_conflict_sizes_p): Don't assume that
+       conflict object hard regset nodes have intersecting hard reg sets.
+       
+       * regmove.c (regmove_optimize): Move ira_set_pseudo_classes call
+       after regstat_init_n_sets_and_refs.
+
+       * ira.c: Add more comments at the top.
+       (setup_stack_reg_pressure_class, setup_pressure_classes):
+       Add comments how we compute the register pressure classes.
+       (setup_allocno_and_important_classes): Add more comments.
+       (setup_class_translate_array, reorder_important_classes)
+       (setup_reg_class_relations): Add comments.
+
+       * ira-emit.c: Add 2011 to the Copyright line.  Add comments at the
+       start of the file.
+
+       * ira-color.c: Add 2011 to the Copyright line.
+       (assign_hard_reg):  Add more comments.
+       (improve_allocation): Ditto.
+
+       * ira-costs.c: Add 2011 to the Copyright line.
+       (setup_cost_classes, setup_regno_cost_classes_by_aclass): Add more
+       comments.
+       (setup_regno_cost_classes_by_mode): Ditto.
+
+       Initial patches from ira-improv branch:
+
+       2010-08-13  Vladimir Makarov  <vmakarov@redhat.com>
+
+       * ira-build.c: (ira_create_object): Remove initialization of
+       OBJECT_PROFITABLE_HARD_REGS.  Initialize OBJECT_ADD_DATA.
+       (ira_create_allocno): Remove initialization of
+       ALLOCNO_MEM_OPTIMIZED_DEST, ALLOCNO_MEM_OPTIMIZED_DEST_P,
+       ALLOCNO_SOMEWHERE_RENAMED_P, ALLOCNO_CHILD_RENAMED_P,
+       ALLOCNO_IN_GRAPH_P, ALLOCNO_MAY_BE_SPILLED_P, ALLOCNO_COLORABLE_P,
+       ALLOCNO_NEXT_BUCKET_ALLOCNO, ALLOCNO_PREV_BUCKET_ALLOCNO,
+       ALLOCNO_FIRST_COALESCED_ALLOCNO, ALLOCNO_NEXT_COALESCED_ALLOCNO.
+       Initialize ALLOCNO_ADD_DATA.
+       (copy_info_to_removed_store_destinations): Use ALLOCNO_EMIT_DATA
+       and allocno_emit_reg instead of ALLOCNO_MEM_OPTIMIZED_DEST_P and
+       ALLOCNO_REG.
+       (ira_flattening): Ditto.  Use ALLOCNO_EMIT_DATA instead of
+       ALLOCNO_MEM_OPTIMIZED_DEST and ALLOCNO_SOMEWHERE_RENAMED_P.
+
+       * ira.c (ira_reallocate): Remove.
+       (setup_pressure_classes): Call
+       ira_init_register_move_cost_if_necessary.  Use
+       ira_register_move_cost instead of ira_get_register_move_cost.
+       (setup_allocno_assignment_flags): Use ALLOCNO_EMIT_DATA.
+       (ira): Call ira_initiate_emit_data and ira_finish_emit_data.
+
+       * ira-color.c: Use ALLOCNO_COLOR_DATA instead of
+       ALLOCNO_IN_GRAPH_P, ALLOCNO_MAY_BE_SPILLED_P, ALLOCNO_COLORABLE_P,
+       ALLOCNO_AVAILABLE_REGS_NUM, ALLOCNO_NEXT_BUCKET_ALLOCNO,
+       ALLOCNO_PREV_BUCKET_ALLOCNO. ALLOCNO_TEMP. Use OBJECT_COLOR_DATA
+       instead of OBJECT_PROFITABLE_HARD_REGS, OBJECT_HARD_REGS_NODE,
+       OBJECT_HARD_REGS_SUBNODES_START, OBJECT_HARD_REGS_SUBNODES_NUM.
+       Fix formatting.
+       (object_hard_regs_t, object_hard_regs_node_t): Move from
+       ira-int.h.
+       (struct object_hard_regs, struct object_hard_regs_node): Ditto.
+       (struct allocno_color_data): New.
+       (allocno_color_data_t): New typedef.
+       (allocno_color_data): New definition.
+       (ALLOCNO_COLOR_DATA): New macro.
+       (struct object_color_data): New.
+       (object_color_data_t): New typedef.
+       (object_color_data): New definition.
+       (OBJECT_COLOR_DATA): New macro.
+       (update_copy_costs, calculate_allocno_spill_cost): Call
+       ira_init_register_move_cost_if_necessary.  Use
+       ira_register_move_cost instead of ira_get_register_move_cost.
+       (move_spill_restore, update_curr_costs): Ditto.
+       (allocno_spill_priority): Make it inline.
+       (color_pass): Allocate and free allocno_color_dat and
+       object_color_data.
+       (struct coalesce_data, coalesce_data_t): New.
+       (allocno_coalesce_data): New definition.
+       (ALLOCNO_COALESCE_DATA): New macro.
+       (merge_allocnos, coalesced_allocno_conflict_p): Use
+       ALLOCNO_COALESCED_DATA instead of ALLOCNO_FIRST_COALESCED_ALLOCNO,
+       ALLOCNO_NEXT_COALESCED_ALLOCNO, ALLOCNO_TEMP.
+       (coalesce_allocnos): Ditto.
+       (setup_coalesced_allocno_costs_and_nums): Ditto.
+       (collect_spilled_coalesced_allocnos): Ditto.
+       (slot_coalesced_allocno_live_ranges_intersect_p): Ditto.
+       (setup_slot_coalesced_allocno_live_ranges): Ditto.
+       (coalesce_spill_slots): Ditto.
+       (ira_sort_regnos_for_alter_reg): Ditto.  Allocate, initialize and
+       free allocno_coalesce_data.
+
+       * ira-conflicts.c: Fix formatting.
+       (process_regs_for_copy): Call
+       ira_init_register_move_cost_if_necessary.  Use
+       ira_register_move_cost instead of ira_get_register_move_cost.
+       (build_object_conflicts): Optimize.
+
+       * ira-costs.c (record_reg_classes): Optimize.  Call
+       ira_init_register_move_cost_if_necessary.  Use
+       ira_register_move_cost, ira_may_move_in_cost, and
+       ira_may_move_out_cost instead of ira_get_register_move_cost and
+       ira_get_may_move_cost.
+       (record_address_regs): Ditto.
+       (scan_one_insn): Optimize.
+       (find_costs_and_classes): Optimize.
+       (process_bb_node_for_hard_reg_moves): Call
+       ira_init_register_move_cost_if_necessary.  Use
+       ira_register_move_cost instead of ira_get_register_move_cost.
+
+       * ira-emit.c: Use allocno_emit_reg, ALLOCNO_EMIT_DATA instead of
+       ALLOCNO_REG, ALLOCNO_CHILD_RENAMED_P, ALLOCNO_MEM_OPTIMIZED_DEST,
+       ALLOCNO_MEM_OPTIMIZED_DEST_P, and ALLOCNO_SOMEWHERE_RENAMED_P.
+       (ira_allocno_emit_data, void_p, new_allocno_emit_data_vec): New
+       definitions.
+       (ira_initiate_emit_data, ira_finish_emit_data)
+       (create_new_allocno): New functions.
+       (modify_move_list): Call create_new_alloc instead of
+       ira_create_allocno.
+       (emit_move_list): Call ira_init_register_move_cost_if_necessary.
+       Use ira_register_move_cost instead of ira_get_register_move_cost.
+
+       * ira-int.h: Fix some comments.
+       (object_hard_regs_t, object_hard_regs_node_t): Move
+       to ira-color.c.
+       (struct object_hard_regs, struct object_hard_regs_node):
+       Ditto.
+       (struct ira_object): Remove profitable_hard_regs, hard_regs_node,
+       hard_regs_subnodes_start, hard_regs_subnodes_num.  Add new member
+       add_data.
+       (struct ira_allocno): Make mode and aclass a bitfield.  Move other
+       bitfield after mode.  Make hard_regno a short int.  Make
+       hard_regno short.  Remove first_coalesced_allocno and
+       next_coalesced_allocno.  Move mem_optimized_dest_p,
+       somewhere_renamed_p, child_renamed_p, reg, and mem_optimized_dest
+       into struct ira_emit_data.  Remove in_graph_p, may_be_spilled_p,
+       available_regs_num, next_bucket_allocno, prev_bucket_allocno,
+       temp, colorable_p.  Add new member add_data.
+       (ALLOCNO_IN_GRAPH_P, ALLOCNO_MAY_BE_SPILLED_P): Remove.
+       (ALLOCNO_COLORABLE_P, ALLOCNO_AVAILABLE_REGS_NUM): Remove.
+       (ALLOCNO_NEXT_BUCKET_ALLOCNO, ALLOCNO_PREV_BUCKET_ALLOCNO): Remove.
+       (ALLOCNO_TEMP, ALLOCNO_FIRST_COALESCED_ALLOCNO): Remove.
+       (ALLOCNO_NEXT_COALESCED_ALLOCNO): Remove.
+       (ALLOCNO_ADD_DATA): New macro.
+       (ira_emit_data_t): New typedef.
+       (struct ira_emit_data): New.  Move mem_optimized_dest_p,
+       somewhere_renamed_p, child_renamed_p, reg, mem_optimized_dest
+       from struct ira_allocno.
+       (ALLOCNO_EMIT_DATA): New macro.
+       (ira_allocno_emit_data, allocno_emit_reg): New.
+       (ALLOCNO_PROFITABLE_HARD_REGS, OBJECT_HARD_REGS_NODE): Remove.
+       (OBJECT_HARD_REGS_SUBNODES_STAR, OBJECT_HARD_REGS_SUBNODES_NUM):
+       Remove.
+       (OBJECT_ADD_DATA): New macro.
+       (ira_reallocate): Remove.
+       (ira_initiate_emit_data, ira_finish_emit_data): New.
+       (ira_get_register_move_cost, ira_get_may_move_cost): Remove.
+       (ira_init_register_move_cost_if_necessary): New.
+       (ira_object_conflict_iter_next): Merge into
+       ira_object_conflict_iter_cond.
+       (FOR_EACH_OBJECT_CONFLICT): Don't use
+       ira_object_conflict_iter_next.
+
+       * ira-live.c: (process_single_reg_class_operands): Call
+       ira_init_register_move_cost_if_necessary.  Use
+       ira_register_move_cost instead of ira_get_register_move_cost.
+
+       2010-08-13  Vladimir Makarov  <vmakarov@redhat.com>
+
+       * ira-int.h (struct target_ira_int): Remove x_cost_classes.
+
+       * ira-costs.c: Fix formatting.
+       (cost_classes, cost_classes_num): Remove.
+       (struct cost_classes, cost_classes_t, const_cost_classes_t): New.
+       (regno_cost_classes, cost_classes_hash, cost_classes_eq): New.
+       (cost_classes_del, cost_classes_htab): New.
+       (cost_classes_aclass_cache, cost_classes_mode_cache): New.
+       (initiate_regno_cost_classes, setup_cost_classes): New.
+       (setup_regno_cost_classes_by_aclass): New.
+       (setup_regno_cost_classes_by_mode, finish_regno_cost_classes):
+       New.
+       (record_reg_classes): Use regno_cost_classes instead of
+       cost_classes.  Move checking opposite operand up.
+       (record_address_regs): Use regno_cost_classes
+       instead of cost_classes.
+       (scan_one_insn): Ditto.  Use always general register.
+       (print_allocno_costs): Use regno_cost_classes instead of
+       cost_classes.
+       (print_pseudo_costs): Ditto.  Use Reg_N_REFS.
+       (find_costs_and_classes): Set up cost classes for each registers.
+       Use also their mode for this.  Use regno_cost_classes instead of
+       cost_classes.
+       (setup_allocno_class_and_costs): Use regno_cost_classes instead of
+       cost_classes.
+       (free_ira_costs, ira_init_costs): Don't use cost_classes.
+       (ira_costs, ira_set_pseudo_classes): Call
+       initiate_regno_cost_classes and finish_regno_cost_classes.
+
+       2010-10-04  Vladimir Makarov  <vmakarov@redhat.com>
+
+       * target-def.h (TARGET_IRA_COVER_CLASSES): Remove.
+
+       * target.def (ira_cover_classes): Remove.
+
+       * doc/tm.texi: Remove TARGET_IRA_COVER_CLASSES and
+       IRA_COVER_CLASSES.
+
+       * doc/tm.texi.in: Ditto.
+
+       * ira-conflicts.c: Remove mentioning cover classes from the file.
+       Use ALLOCNO_CLASS instead of ALLOCNO_COVER_CLASS.  Use
+       ALLOCNO_COVER_CLASS_COST instead of ALLOCNO_CLASS_COST.  Fix
+       formatting.
+
+       * targhooks.c (default_ira_cover_classes): Remove.
+
+       * targhooks.h (default_ira_cover_classes): Ditto.
+
+       * haifa-sched.c: Remove mentioning cover classes from the file.
+       Use ira_reg_pressure_cover instead of ira_reg_class_cover.  Use
+       ira_pressure_classes and ira_pressure_classes_num instead of
+       ira_reg_class_cover_size and ira_reg_class_cover.  Use
+       sched_regno_pressure_class instead of sched_regno_cover_class.
+       (mark_regno_birth_or_death, setup_insn_reg_pressure_info): Use
+       ira_reg_class_max_nregs instead of ira_reg_class_nregs.
+
+       * ira-int.h: Add 2010 to Copyright.  Remove mentioning cover
+       classes from the file.
+       (object_hard_regs_t, object_hard_regs_node_t): New typedefs.
+       (struct object_hard_regs, struct object_hard_regs_node): New.
+       (struct ira_object): New members profitable_hard_regs,
+       hard_regs_node, hard_regs_subnodes_start, hard_regs_subnodes_num.
+       (struct ira_allocno): Rename cover_class to aclass.  Rename
+       cover_class_cost and updated_cover_class_cost to class_cost and
+       updated_class_cost.  Remove splay_removed_p and
+       left_conflict_size.  Add new members colorable_p.
+       (ALLOCNO_SPLAY_REMOVED_P, ALLOCNO_LEFT_CONFLICTS_SIZE): Remove.
+       (ALLOCNO_COLORABLE_P): New macro.
+       (ALLOCNO_COVER_CLASS): Rename to ALLOCNO_CLASS.
+       (ALLOCNO_COVER_CLASS_COST, ALLOCNO_UPDATED_COVER_CLASS_COST):
+       Rename to ALLOCNO_CLASS_COST and ALLOCNO_UPDATED__CLASS_COST.
+       (OBJECT_...): Rename parameter C to O.
+       (OBJECT_PROFITABLE_HARD_REGS): New macro.
+       (OBJECT_HARD_REGS_NODE, OBJECT_HARD_REGS_SUBNODES_START)
+       (OBJECT_HARD_REGS_SUBNODES_NUM): New macros.
+       (struct target_ira_int): New members x_ira_max_memory_move_cost,
+       x_ira_max_register_move_cost, x_ira_max_may_move_in_cost,
+       x_ira_max_may_move_out_cost, x_ira_reg_allocno_class_p,
+       x_ira_reg_pressure_class_p, x_ira_important_class_nums,
+       x_ira_reg_class_superunion.  Rename x_prohibited_class_mode_reg to
+       x_ira_prohibited_class_mode_reg.  Rename x_ira_reg_class_union to
+       x_ira_reg_class_subunion.
+       (ira_max_memory_move_cost, ira_max_register_move_cost)
+       (ira_max_may_move_in_cost, ira_max_may_move_out_cost)
+       (ira_reg_allocno_class_p, ira_reg_pressure_class_p)
+       (ira_important_class_nums, ira_reg_class_superunion): New macros.
+       (prohibited_class_mode_regs): Rename to
+       ira_prohibited_class_mode_regs.
+       (ira_reg_class_union): Rename to ira_reg_class_subunion.
+       (ira_debug_class_cover): Rename to ira_debug_allocno_classes.
+       (ira_set_allocno_cover_class): Rename to ira_set_allocno_class.
+       (ira_tune_allocno_costs_and_cover_classes): Rename to
+       ira_tune_allocno_costs.
+       (ira_debug_hard_regs_forest): New.
+       (ira_object_conflict_iter_init, ira_object_conflict_iter_cond)
+       (ira_object_conflict_iter_next): Fix comments.
+       (ira_hard_reg_set_intersection_p, hard_reg_set_size): New
+       functions.
+       (ira_allocate_and_set_costs, ira_allocate_and_copy_costs): Rename
+       cover_class to aclass.
+       (ira_allocate_and_accumulate_costs): Ditto.
+       (ira_allocate_and_set_or_copy_costs): Ditto.
+
+       * opts.c (decode_options): Remove ira_cover_class check.
+
+       * ira-color.c: Remove mentioning cover classes from the file.  Use
+       ALLOCNO_CLASS, ALLOCNO_CLASS_COST, and ALLOCNO_UPDATED_CLASS_COST
+       instead of ALLOCNO_COVER_CLASS, ALLOCNO_COVER_CLASS_COST, and
+       ALLOCNO_UPDATED_COVER_CLASS_COST.  Fix formatting.
+       (splay-tree.h): Remove include.
+       (allocno_coalesced_p, processed_coalesced_allocno_bitmap): Move
+       before copy_freq_compare_func.
+       (allocnos_for_spilling, removed_splay_allocno_vec): Remove.
+       (object_hard_regs_vec, object_hard_regs_htab, node_check_tick):
+       New definitions.
+       (hard_regs_roots, hard_regs_node_vec): Ditto.
+       (object_hard_regs_hash, object_hard_regs_eq, find_hard_regs): Ditto.
+       (insert_hard_regs, init_object_hard_regs, add_object_hard_regs): Ditto.
+       (finish_object_hard_regs, object_hard_regs_compare): Ditto.
+       (create_new_object_hard_regs_node): Ditto.
+       (add_new_object_hard_regs_node_to_forest): Ditto.
+       (add_object_hard_regs_to_forest, collect_object_hard_regs_cover):
+       Ditto.
+       (setup_object_hard_regs_nodes_parent, first_common_ancestor_node):
+       Ditto.
+       (print_hard_reg_set, print_hard_regs_subforest): Ditto.
+       (print_hard_regs_forest, ira_debug_hard_regs_forest): Ditto.
+       (remove_unused_object_hard_regs_nodes): Ditto.
+       (enumerate_object_hard_regs_nodes): Ditto.
+       (object_hard_regs_nodes_num, object_hard_regs_nodes): Ditto.
+       (object_hard_regs_subnode_t): Ditto.
+       (struct object_hard_regs_subnode): Ditto.
+       (object_hard_regs_subnodes, object_hard_regs_subnode_index): Ditto.
+       (setup_object_hard_regs_subnode_index): Ditto.
+       (get_object_hard_regs_subnodes_num): Ditto.
+       (form_object_hard_regs_nodes_forest): Ditto.
+       (finish_object_hard_regs_nodes_tree): Ditto.
+       (finish_object_hard_regs_nodes_forest): Ditto.
+       (allocnos_have_intersected_live_ranges_p): Rename to
+       allocnos_conflict_by_live_ranges_p.  Move before
+       copy_freq_compare_func.
+       (pseudos_have_intersected_live_ranges_p): Rename to
+       conflict_by_live_ranges_p.  Move before copy_freq_compare_func.
+       (setup_left_conflict_sizes_p, update_left_conflict_sizes_p): Ditto.
+       (empty_profitable_hard_regs, setup_profitable_hard_regs): Ditto.
+       (update_copy_costs): Remove assert.  Skip cost update if the hard
+       reg does not belong the class.
+       (assign_hard_reg): Process only profitable hard regs.
+       (uncolorable_allocnos_num): Make it scalar.
+       (allocno_spill_priority): Use ALLOCNO_EXCESS_PRESSURE_POINTS_NUM
+       and ira_reg_class_max_nregs instead of ALLOCNO_LEFT_CONFLICTS_SIZE
+       and ira_reg_class_max_nregs.
+       (bucket_allocno_compare_func): Check frequency first.
+       (sort_bucket): Add compare function as a parameter.
+       (add_allocno_to_ordered_bucket): Assume no coalesced allocnos.
+       (uncolorable_allocnos_splay_tree, USE_SPLAY_P): Remove.
+       (push_allocno_to_stack): Rewrite for checking new allocno
+       colorability.
+       (remove_allocno_from_bucket_and_push): Print cost too.  Remove
+       assert.
+       (push_only_colorable): Pass new parameter to sort_bucket.
+       (push_allocno_to_spill): Remove.
+       (allocno_spill_priority_compare): Make it inline and rewrite.
+       (splay_tree_allocate, splay_tree_free): Remove.
+       (allocno_spill_sort_compare): New function.
+       (push_allocnos_to_stack): Sort allocnos for spilling once.  Don't
+       build and use splay tree.  Choose first allocno in uncolorable
+       allocno bucket to spill.  Remove setting spill cost.
+       (all_conflicting_hard_regs): Remove.
+       (setup_allocno_available_regs_num): Check only profitable hard
+       regs.  Print info about hard regs nodes.
+       (setup_allocno_left_conflicts_size): Remove.
+       (put_allocno_into_bucket): Don't call
+       setup_allocno_left_conflicts_size.  Use
+       setup_left_conflict_sizes_p.
+       (improve_allocation): New.
+       (color_allocnos): Call setup_profitable_hard_regs,
+       form_object_hard_regs_nodes_forest, improve_allocation,
+       finish_object_hard_regs_nodes_forest.  Setup spill cost.
+       (print_loop_title): Use pressure classes.
+       (color_allocnso): Ditto.
+       (do_coloring): Remove allocation and freeing splay_tree_node_pool
+       and allocnos_for_spilling.
+       (ira_sort_regnos_for_alter_reg): Don't setup members
+       {first,next}_coalesced_allocno.
+       (color): Remove allocating and freeing removed_splay_allocno_vec.
+       (fast_allocation): Use ira_prohibited_class_mode_regs instead of
+       prohibited_class_mode_regs.
+
+       * ira-lives.c: Remove mentioning cover classes from the file.  Fix
+       formatting.
+       (update_allocno_pressure_excess_length): Use pressure classes.
+       (inc_register_pressure, dec_register_pressure): Check for pressure
+       class.
+       (mark_pseudo_regno_live, mark_pseudo_regno_subword_live): Use
+       pressure class.  Use ira_reg_class_nregs instead of
+       ira_reg_class_max_nregs.
+       (mark_pseudo_regno_dead, mark_pseudo_regno_subword_dead): Ditto.
+       (mark_hard_reg_live, mark_hard_reg_dead): Use pressure class.
+       (single_reg_class): Use ira_reg_class_nregs instead of
+       ira_reg_class_max_nregs.
+       (process_bb_node_lives): Use pressure classes.
+
+       * ira-emit.c: Remove mentioning cover classes from the file.  Use
+       ALLOCNO_CLASS instead of ALLOCNO_COVER_CLASS.  Fix formatting.
+       (change_loop): Use pressure classes.
+       (modify_move_list): Call ira_set_allocno_class instead of
+       ira_set_allocno_cover_class.
+
+       * ira-build.c: Remove mentioning cover classes from the file.  Use
+       ALLOCNO_CLASS and ALLOCNO_CLASS_COST instead of
+       ALLOCNO_COVER_CLASS and ALLOCNO_COVER_CLASS_COST.  Use
+       ALLOCNO_UPDATED_CLASS_COST instead of
+       ALLOCNO_UPDATED_COVER_CLASS_COST.  Fix formatting.
+       (ira_create_object): Initiate OBJECT_PROFITABLE_HARD_REGS.
+       (ira_create_allocno): Remove initialization of
+       ALLOCNO_SPLAY_REMOVED_P, ALLOCNO_LEFT_CONFLICT_SIZE.  Initialize
+       ALLOCNO_COLORABLE_P.
+       (ira_set_allocno_cover_class): Rename to ira_set_allocno_class.
+       Update conflict regs for the objects.
+       (create_cap_allocno): Remove assert.  Don't propagate
+       ALLOCNO_AVAILABLE_REGS_NUM.
+       (ira_free_allocno_costs): New function.
+       (finish_allocno): Change a part of code into call of
+       ira_free_allocno_costs.
+       (low_pressure_loop_node_p): Use pressure classes.
+       (object_range_compare_func): Don't compare classes.
+       (setup_min_max_conflict_allocno_ids): Ditto.
+
+       * loop-invariant.c: Remove mentioning cover classes from the file.
+       Use ira_pressure_classes and ira_pressure_classes_num instead of
+       ira_reg_class_cover_size and ira_reg_class_cover.  Fix formatting.
+       (get_cover_class_and_nregs): Rename to
+       get_cover_pressure_and_nregs.  Use ira_reg_class_max_nregs instead
+       of ira_reg_class_nregs.  Use reg_allocno_class instead of
+       reg_cover_class.
+       (get_inv_cost): Use instead ira_stack_reg_pressure_class of
+       STACK_REG_COVER_CLASS.
+       (get_regno_cover_class): Rename to get_regno_pressure_class.
+       (move_loop_invariants): Initialize and finalize regstat.
+
+       * ira.c: Remove mentioning cover classes from the file.  Add
+       comments about coloring without cover classes.  Use ALLOCNO_CLASS
+       instead of ALLOCNO_COVER_CLASS.  Fix formatting.
+       (alloc_reg_class_subclasses, setup_reg_subclasses): Move it before
+       setup_class_subset_and_memory_move_costs.
+       (setup_stack_reg_pressure_class, setup_pressure_classes): New.
+       (setup_cover_and_important_classes): Rename to
+       setup_allocno_and_important_classes.
+       (setup_class_translate_array): New.
+       (setup_class_translate): Call it for allocno and pressure classes.
+       (cover_class_order): Rename to allocno_class_order.
+       (comp_reg_classes_func): Use ira_allocno_class_translate instead
+       of ira_class_translate.
+       (reorder_important_classes): Set up ira_important_class_nums.
+       (setup_reg_class_relations): Set up ira_reg_class_superunion.
+       (print_class_cover): Rename to print_classes.  Add parameter.
+       (ira_debug_class_cover): Rename to ira_debug_allocno_classes.
+       Print pressure classes too.
+       (find_reg_class_closure): Rename to find_reg_classes.  Don't call
+       setup_reg_subclasses.
+       (ira_hard_regno_cover_class): Rename to
+       ira_hard_regno_allocno_class.
+       (ira_reg_class_nregs): Rename to ira_reg_class_max_nregs.
+       (setup_prohibited_class_mode_regs): Use
+       ira_prohibited_class_mode_regs instead of
+       prohibited_class_mode_regs.
+       (clarify_prohibited_class_mode_regs): New function.
+       (ira_init_register_move_cost): Set up ira_max_register_move_cost,
+       ira_max_may_move_in_cost, and ira_max_may_move_out_cost.
+       (ira_init_once): Initialize them.
+       (free_register_move_costs): Process them.
+       (ira_init): Move calls of find_reg_classes and
+       setup_hard_regno_aclass after setup_prohibited_class_mode_regs.
+       Call clarify_prohibited_class_mode_regs.
+       (ira_no_alloc_reg): Remove.
+       (too_high_register_pressure_p): Use pressure classes.
+
+       * sched-deps.c: Remove mentioning cover classes from the file.
+       Use ira_reg_pressure_cover instead of ira_reg_class_cover.  Use
+       ira_pressure_classes and ira_pressure_classes_num instead of
+       ira_reg_class_cover_size and ira_reg_class_cover.
+       (mark_insn_hard_regno_birth, mark_hard_regno_death): Use
+       sched_regno_pressure_class instead of sched_regno_cover_class.
+       (mark_insn_pseudo_birth, mark_pseudo_death): Ditto.  Use
+       ira_reg_class_max_nregs instead of ira_reg_class_nregs.
+
+       * ira.h: Add 2010 to Copyright.
+       (ira_no_alloc_reg): Remove external.
+       (struct target_ira): Rename x_ira_hard_regno_cover_class,
+       x_ira_reg_class_cover_size, x_ira_reg_class_cover, and
+       x_ira_class_translate to x_ira_hard_regno_allocno_class,
+       x_ira_allocno_classes_num, x_ira_allocno_classes, and
+       x_ira_allocno_class_translate.  Add x_ira_pressure_classes_num,
+       x_ira_pressure_classes, x_ira_pressure_class_translate, and
+       x_ira_stack_reg_pressure_class.  Rename x_ira_reg_class_nregs to
+       x_ira_reg_class_max_nregs.  Add x_ira_reg_class_min_nregs and
+       x_ira_no_alloc_regs.
+       (ira_hard_regno_cover_class): Rename to
+       ira_hard_regno_allocno_class.
+       (ira_reg_class_cover_size, ira_reg_class_cover): Rename to
+       ira_allocno_classes_num and ira_allocno_classes.
+       (ira_class_translate): Rename to ira_allocno_class_translate.
+       (ira_pressure_classes_num, ira_pressure_classes): New definitions.
+       (ira_pressure_class_translate, ira_stack_reg_pressure_class): Ditto.
+       (ira_reg_class_nregs): Rename to ira_reg_class_max_nregs.
+       (ira_reg_class_min_nregs, ira_stack_reg_pressure_class): New
+       (ira_no_alloc_regs): New.
+
+       * ira-costs.c: Add 2010 to Copyright.  Remove mentioning cover
+       classes from the file.  Use ALLOCNO_CLASS instead of
+       ALLOCNO_COVER_CLASS.  Use ALLOCNO_CLASS_COST instead of
+       ALLOCNO_COVER_CLASS_COST.
+       (regno_cover_class): Rename to regno_aclass.
+       (record_reg_classes): Use ira_reg_class_subunion instead of
+       ira_reg_class_union.
+       (record_address_regs): Check overflow.
+       (scan_one_insn): Ditto.
+       (print_allocno_costs): Print total mem cost fore regional
+       allocation.
+       (print_pseudo_costs): Use REG_N_REFS.
+       (find_costs_and_classes): Use classes intersected with them on the
+       1st pass. Check overflow.  Use ira_reg_class_subunion instead of
+       ira_reg_class_union.  Use ira_allocno_class_translate and
+       regno_aclass instead of ira_class_translate and regno_cover_class.
+       Modify code for finding regno_aclass.  Setup preferred classes for
+       the next pass.
+       (setup_allocno_cover_class_and_costs): Rename to
+       setup_allocno_class_and_costs.  Use regno_aclass instead of
+       regno_cover_class.  Use ira_set_allocno_class instead of
+       ira_set_allocno_cover_class.
+       (init_costs, finish_costs): Use regno_aclass instead of
+       regno_cover_class.
+       (ira_costs): Use setup_allocno_class_and_costs instead of
+       setup_allocno_cover_class_and_costs.
+       (ira_tune_allocno_costs_and_cover_classes): Rename to
+       ira_tune_allocno_costs.  Check overflow.  Skip conflict hard regs
+       by processing objects.  Use ira_reg_class_max_nregs instead of
+       ira_reg_class_nregs.
+
+       * rtl.h (reg_cover_class): Rename to reg_allocno_class.
+
+       * sched-int.h: Remove mentioning cover classes from the file.
+       (sched_regno_cover_class): Rename to sched_regno_pressure_class.
+
+       * reginfo.c: Add 2010 to Copyright.  Remove mentioning cover
+       classes from the file.
+       (struct reg_pref): Rename coverclass into allocnoclass.
+       (reg_cover_class): Rename to reg_allocno_class.
+
+       * Makefile.in (ira-color.o): Remove SPLAY_TREE_H from
+       dependencies.
+
+       * config/alpha/alpha.h (IRA_COVER_CLASSES): Remove.
+
+       * config/arm/arm.h (IRA_COVER_CLASSES): Ditto.
+
+       * config/avr/avr.h (IRA_COVER_CLASSES): Ditto.
+
+       * config/bfin/bfin.h (IRA_COVER_CLASSES): Ditto.
+
+       * config/cris/cris.h (IRA_COVER_CLASSES): Ditto.
+
+       * config/fr30/fr30.h (IRA_COVER_CLASSES): Ditto.
+
+       * config/frv/frv.h (IRA_COVER_CLASSES): Ditto.
+
+       * config/h8300/h8300.h (IRA_COVER_CLASSES): Ditto.
+
+       * config/i386/i386.h (STACK_REG_COVER_CLASS): Ditto.
+
+       * config/i386/i386.c (TARGET_IRA_COVER_CLASSES)
+       (i386_ira_cover_classes): Ditto.
+
+       * config/ia64/ia64.h (IRA_COVER_CLASSES): Ditto.
+
+       * config/iq2000/iq2000.h (IRA_COVER_CLASSES): Ditto.
+
+       * config/m32r/m32r.h (IRA_COVER_CLASSES): Ditto.
+
+       * config/m68k/m68k.h (IRA_COVER_CLASSES): Ditto.
+
+       * config/mcore/mcore.h (IRA_COVER_CLASSES): Ditto.
+
+       * config/mep/mep.h (IRA_COVER_CLASSES): Ditto.
+
+       * config/mips/mips.c (TARGET_IRA_COVER_CLASSES)
+       (mips_ira_cover_classes): Ditto.
+
+       * config/mn10300/mn10300.h (IRA_COVER_CLASSES): Ditto.
+
+       * config/moxie/moxie.h (IRA_COVER_CLASSES): Ditto.
+
+       * config/pa/pa64-regs.h (IRA_COVER_CLASSES): Ditto.
+
+       * config/pa/pa32-regs.h (IRA_COVER_CLASSES): Ditto.
+
+       * config/picochip/picochip.h (IRA_COVER_CLASSES): Ditto.
+
+       * config/rs6000/rs6000.h (IRA_COVER_CLASSES_PRE_VSX)
+       (IRA_COVER_CLASSES_VSX): Ditto.
+
+       * config/rs6000/rs6000.c (TARGET_IRA_COVER_CLASSES)
+       (rs6000_ira_cover_classes): Ditto.
+
+       * config/rx/rx.h (IRA_COVER_CLASSES): Ditto.
+
+       * config/s390/s390.h (IRA_COVER_CLASSES): Ditto.
+
+       * config/score/score.h (IRA_COVER_CLASSES): Ditto.
+
+       * config/sh/sh.h (IRA_COVER_CLASSES): Ditto.
+
+       * config/sparc/sparc.h (IRA_COVER_CLASSES): Ditto.
+
+       * config/spu/spu.h (IRA_COVER_CLASSES): Ditto.
+
+       * config/stormy16/stormy16.h (IRA_COVER_CLASSES): Ditto.
+
+       * config/v850/v850.h (IRA_COVER_CLASSES): Ditto.
+
+       * config/vax/vax.h (IRA_COVER_CLASSES): Ditto.
+
+       * config/xtensa/xtensa.h (IRA_COVER_CLASSES): Ditto.
+
 2011-03-29  Jakub Jelinek  <jakub@redhat.com>
 
        PR debug/48253
index 65e042a..16779bd 100644 (file)
@@ -3318,7 +3318,7 @@ ira-conflicts.o: ira-conflicts.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
 ira-color.o: ira-color.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(TARGET_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \
    $(EXPR_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_CORE_H) $(TM_P_H) reload.h $(PARAMS_H) \
-   $(DF_H) $(SPLAY_TREE_H) $(IRA_INT_H)
+   $(DF_H) $(IRA_INT_H)
 ira-emit.o: ira-emit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(REGS_H) $(RTL_H) $(TM_P_H) $(TARGET_H) $(FLAGS_H) hard-reg-set.h \
    $(BASIC_BLOCK_H) $(EXPR_H) $(RECOG_H) $(PARAMS_H) $(TIMEVAR_H) \
index 14fc731..bfb443c 100644 (file)
@@ -511,19 +511,6 @@ enum reg_class {
   {0x00000000, 0x7fffffff},    /* FLOAT_REGS */        \
   {0xffffffff, 0xffffffff} }
 
-/* The following macro defines cover classes for Integrated Register
-   Allocator.  Cover classes is a set of non-intersected register
-   classes covering all hard registers used for register allocation
-   purpose.  Any move between two registers of a cover class should be
-   cheaper than load or store of the registers.  The macro value is
-   array of register classes with LIM_REG_CLASSES used as the end
-   marker.  */
-
-#define IRA_COVER_CLASSES                                                   \
-{                                                                           \
-  GENERAL_REGS, FLOAT_REGS, LIM_REG_CLASSES                                 \
-}
-
 /* The same information, inverted:
    Return the class number of the smallest class containing
    reg number REGNO.  This could be a conditional expression
index add8ece..276005c 100644 (file)
@@ -1152,20 +1152,6 @@ enum reg_class
    or could index an array.  */
 #define REGNO_REG_CLASS(REGNO)  arm_regno_class (REGNO)
 
-/* The following macro defines cover classes for Integrated Register
-   Allocator.  Cover classes is a set of non-intersected register
-   classes covering all hard registers used for register allocation
-   purpose.  Any move between two registers of a cover class should be
-   cheaper than load or store of the registers.  The macro value is
-   array of register classes with LIM_REG_CLASSES used as the end
-   marker.  */
-
-#define IRA_COVER_CLASSES                                                   \
-{                                                                           \
-  GENERAL_REGS, FPA_REGS, CIRRUS_REGS, VFP_REGS, IWMMXT_GR_REGS, IWMMXT_REGS,\
-  LIM_REG_CLASSES                                                           \
-}
-
 /* FPA registers can't do subreg as all values are reformatted to internal
    precision.  In VFPv1, VFP registers could only be accessed in the mode
    they were set, so subregs would be invalid there too.  However, we don't
index 37fb3ed..47bb3fb 100644 (file)
@@ -296,19 +296,6 @@ enum reg_class {
 
 #define REGNO_REG_CLASS(R) avr_regno_reg_class(R)
 
-/* The following macro defines cover classes for Integrated Register
-   Allocator.  Cover classes is a set of non-intersected register
-   classes covering all hard registers used for register allocation
-   purpose.  Any move between two registers of a cover class should be
-   cheaper than load or store of the registers.  The macro value is
-   array of register classes with LIM_REG_CLASSES used as the end
-   marker.  */
-
-#define IRA_COVER_CLASSES               \
-{                                       \
-  GENERAL_REGS, LIM_REG_CLASSES         \
-}
-
 #define BASE_REG_CLASS (reload_completed ? BASE_POINTER_REGS : POINTER_REGS)
 
 #define INDEX_REG_CLASS NO_REGS
index 441e202..6ebaa44 100644 (file)
@@ -664,19 +664,6 @@ enum reg_class
  : (REGNO) >= REG_RETS ? PROLOGUE_REGS                 \
  : NO_REGS)
 
-/* The following macro defines cover classes for Integrated Register
-   Allocator.  Cover classes is a set of non-intersected register
-   classes covering all hard registers used for register allocation
-   purpose.  Any move between two registers of a cover class should be
-   cheaper than load or store of the registers.  The macro value is
-   array of register classes with LIM_REG_CLASSES used as the end
-   marker.  */
-
-#define IRA_COVER_CLASSES                              \
-{                                                      \
-    MOST_REGS, AREGS, CCREGS, LIM_REG_CLASSES          \
-}
-
 /* When this hook returns true for MODE, the compiler allows
    registers explicitly used in the rtl to be used as spill registers
    but prevents the compiler from extending the lifetime of these
index e8172bb..c8b7d2f 100644 (file)
@@ -550,8 +550,6 @@ enum reg_class
 
 #define INDEX_REG_CLASS GENERAL_REGS
 
-#define IRA_COVER_CLASSES { GENERAL_REGS, SPECIAL_REGS, LIM_REG_CLASSES }
-
 #define REG_CLASS_FROM_LETTER(C)               \
   (                                            \
    (C) == 'a' ? ACR_REGS :                     \
index d20d7fb..9f8be86 100644 (file)
@@ -290,11 +290,6 @@ enum reg_class
 #define GENERAL_REGS   REAL_REGS
 #define N_REG_CLASSES  ((int) LIM_REG_CLASSES)
 
-#define IRA_COVER_CLASSES                              \
-{                                                      \
-  REAL_REGS, MULTIPLY_64_REG, LIM_REG_CLASSES          \
-}
-
 /* An initializer containing the names of the register classes as C string
    constants.  These names are used in writing some of the debugging dumps.  */
 #define REG_CLASS_NAMES \
index 299a856..2c1abf3 100644 (file)
@@ -970,21 +970,6 @@ enum reg_class
   { 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0x1fff}, /* ALL_REGS */\
 }
 
-/* The following macro defines cover classes for Integrated Register
-   Allocator.  Cover classes is a set of non-intersected register
-   classes covering all hard registers used for register allocation
-   purpose.  Any move between two registers of a cover class should be
-   cheaper than load or store of the registers.  The macro value is
-   array of register classes with LIM_REG_CLASSES used as the end
-   marker.  */
-
-#define IRA_COVER_CLASSES                                              \
-{                                                                      \
-  GPR_REGS, FPR_REGS, ACC_REGS, ICR_REGS, FCR_REGS, ICC_REGS, FCC_REGS, \
-  ACCG_REGS, SPR_REGS,                                                 \
-  LIM_REG_CLASSES                                                      \
-}
-
 /* A C expression whose value is a register class containing hard register
    REGNO.  In general there is more than one such class; choose a class which
    is "minimal", meaning that no smaller class also contains the register.  */
index 57fffda..70777c0 100644 (file)
@@ -330,19 +330,6 @@ enum reg_class {
 { "NO_REGS", "COUNTER_REGS", "SOURCE_REGS", "DESTINATION_REGS", \
   "GENERAL_REGS", "MAC_REGS", "ALL_REGS", "LIM_REGS" }
 
-/* The following macro defines cover classes for Integrated Register
-   Allocator.  Cover classes is a set of non-intersected register
-   classes covering all hard registers used for register allocation
-   purpose.  Any move between two registers of a cover class should be
-   cheaper than load or store of the registers.  The macro value is
-   array of register classes with LIM_REG_CLASSES used as the end
-   marker.  */
-
-#define IRA_COVER_CLASSES \
-{                                              \
-  GENERAL_REGS, MAC_REGS, LIM_REG_CLASSES      \
-}
-
 /* Define which registers fit in which classes.
    This is an initializer for a vector of HARD_REG_SET
    of length N_REG_CLASSES.  */
index 8542238..a985b2b 100644 (file)
@@ -28434,22 +28434,6 @@ ix86_free_from_memory (enum machine_mode mode)
     }
 }
 
-/* Implement TARGET_IRA_COVER_CLASSES.  If -mfpmath=sse, we prefer
-   SSE_REGS to FLOAT_REGS if their costs for a pseudo are the
-   same.  */
-static const reg_class_t *
-i386_ira_cover_classes (void)
-{
-  static const reg_class_t sse_fpmath_classes[] = {
-    GENERAL_REGS, SSE_REGS, MMX_REGS, FLOAT_REGS, LIM_REG_CLASSES
-  };
-  static const reg_class_t no_sse_fpmath_classes[] = {
-    GENERAL_REGS, FLOAT_REGS, MMX_REGS, SSE_REGS, LIM_REG_CLASSES
-  };
-
- return TARGET_SSE_MATH ? sse_fpmath_classes : no_sse_fpmath_classes;
-}
-
 /* Implement TARGET_PREFERRED_RELOAD_CLASS.
 
    Put float CONST_DOUBLE in the constant pool instead of fp regs.
@@ -35349,9 +35333,6 @@ ix86_autovectorize_vector_sizes (void)
 #undef TARGET_LEGITIMATE_ADDRESS_P
 #define TARGET_LEGITIMATE_ADDRESS_P ix86_legitimate_address_p
 
-#undef TARGET_IRA_COVER_CLASSES
-#define TARGET_IRA_COVER_CLASSES i386_ira_cover_classes
-
 #undef TARGET_FRAME_POINTER_REQUIRED
 #define TARGET_FRAME_POINTER_REQUIRED ix86_frame_pointer_required
 
index 12edeba..326b8bc 100644 (file)
@@ -870,9 +870,6 @@ enum target_cpu_default
    || ((MODE) == DFmode && !(TARGET_SSE2 && TARGET_SSE_MATH))  \
    || (MODE) == XFmode)
 
-/* Cover class containing the stack registers.  */
-#define STACK_REG_COVER_CLASS FLOAT_REGS
-
 /* Number of actual hardware registers.
    The hardware registers are assigned numbers for the compiler
    from 0 to just below FIRST_PSEUDO_REGISTER.
index ed618f2..a894df8 100644 (file)
@@ -774,19 +774,6 @@ enum reg_class
     0xFFFFFFFF, 0xFFFFFFFF, 0x3FFF },                  \
 }
 
-/* The following macro defines cover classes for Integrated Register
-   Allocator.  Cover classes is a set of non-intersected register
-   classes covering all hard registers used for register allocation
-   purpose.  Any move between two registers of a cover class should be
-   cheaper than load or store of the registers.  The macro value is
-   array of register classes with LIM_REG_CLASSES used as the end
-   marker.  */
-
-#define IRA_COVER_CLASSES                                                   \
-{                                                                           \
-  PR_REGS, BR_REGS, AR_M_REGS, AR_I_REGS, GR_REGS, FR_REGS, LIM_REG_CLASSES  \
-}
-
 /* A C expression whose value is a register class containing hard register
    REGNO.  In general there is more than one such class; choose a class which
    is "minimal", meaning that no smaller class also contains the register.  */
index 62cddea..8a3c653 100644 (file)
@@ -209,11 +209,6 @@ enum reg_class
 
 #define N_REG_CLASSES (int) LIM_REG_CLASSES
 
-#define IRA_COVER_CLASSES      \
-{                              \
-  GR_REGS, LIM_REG_CLASSES     \
-}
-
 #define REG_CLASS_NAMES                                                \
 {                                                              \
   "NO_REGS",                                                   \
index a43e295..31c6cb1 100644 (file)
@@ -459,11 +459,6 @@ enum reg_class
   NO_REGS, CARRY_REG, ACCUM_REGS, GENERAL_REGS, ALL_REGS, LIM_REG_CLASSES
 };
 
-#define IRA_COVER_CLASSES                              \
-{                                                      \
-  ACCUM_REGS, GENERAL_REGS, LIM_REG_CLASSES            \
-}
-
 #define N_REG_CLASSES ((int) LIM_REG_CLASSES)
 
 /* Give names of register classes as strings for dump file.  */
index 71b7c4f..e537379 100644 (file)
@@ -496,10 +496,6 @@ extern enum reg_class regno_reg_class[];
 #define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2)       \
   ((((CLASS1) == FP_REGS) != ((CLASS2) == FP_REGS)) ? 4 : 2)
 
-#define IRA_COVER_CLASSES                                              \
-{                                                                      \
-  ALL_REGS, LIM_REG_CLASSES                                            \
-}
 \f
 /* Stack layout; function entry, exit and calling.  */
 
index 54c12ef..fa3909e 100644 (file)
@@ -324,11 +324,6 @@ enum reg_class
 
 #define N_REG_CLASSES  (int) LIM_REG_CLASSES
 
-#define IRA_COVER_CLASSES              \
-{                                      \
-  GENERAL_REGS, C_REGS, LIM_REG_CLASSES        \
-}
-
 
 /* Give names of register classes as strings for dump file.  */
 #define REG_CLASS_NAMES  \
index 5244bb3..ed2d660 100644 (file)
@@ -407,8 +407,6 @@ enum reg_class
 
 #define REGNO_REG_CLASS(REGNO) (enum reg_class) mep_regno_reg_class (REGNO)
 
-#define IRA_COVER_CLASSES { GENERAL_REGS, CONTROL_REGS, CR_REGS, CCR_REGS, LIM_REG_CLASSES }
-
 #define BASE_REG_CLASS GENERAL_REGS
 #define INDEX_REG_CLASS GENERAL_REGS
 
index 0692902..643e507 100644 (file)
@@ -11017,29 +11017,6 @@ mips_memory_move_cost (enum machine_mode mode, reg_class_t rclass, bool in)
          + memory_move_secondary_cost (mode, rclass, in));
 } 
 
-/* Implement TARGET_IRA_COVER_CLASSES.  */
-
-static const reg_class_t *
-mips_ira_cover_classes (void)
-{
-  static const reg_class_t acc_classes[] = {
-    GR_AND_ACC_REGS, FP_REGS, COP0_REGS, COP2_REGS, COP3_REGS,
-    ST_REGS, LIM_REG_CLASSES
-  };
-  static const reg_class_t no_acc_classes[] = {
-    GR_REGS, FP_REGS, COP0_REGS, COP2_REGS, COP3_REGS,
-    ST_REGS, LIM_REG_CLASSES
-  };
-
-  /* Don't allow the register allocators to use LO and HI in MIPS16 mode,
-     which has no MTLO or MTHI instructions.  Also, using GR_AND_ACC_REGS
-     as a cover class only works well when we keep per-register costs.
-     Using it when not optimizing can cause us to think accumulators
-     have the same cost as GPRs in cases where GPRs are actually much
-     cheaper.  */
-  return TARGET_MIPS16 || !optimize ? no_acc_classes : acc_classes;
-}
-
 /* Return the register class required for a secondary register when
    copying between one of the registers in RCLASS and value X, which
    has mode MODE.  X is the source of the move if IN_P, otherwise it
@@ -16618,9 +16595,6 @@ mips_shift_truncation_mask (enum machine_mode mode)
 #undef TARGET_DWARF_REGISTER_SPAN
 #define TARGET_DWARF_REGISTER_SPAN mips_dwarf_register_span
 
-#undef TARGET_IRA_COVER_CLASSES
-#define TARGET_IRA_COVER_CLASSES mips_ira_cover_classes
-
 #undef TARGET_ASM_FINAL_POSTSCAN_INSN
 #define TARGET_ASM_FINAL_POSTSCAN_INSN mips_final_postscan_insn
 
index ac23f58..f660dca 100644 (file)
@@ -309,19 +309,6 @@ enum reg_class
   { 0xffffffff, 0xfffff } /* ALL_REGS */                       \
 }
 
-/* The following macro defines cover classes for Integrated Register
-   Allocator.  Cover classes is a set of non-intersected register
-   classes covering all hard registers used for register allocation
-   purpose.  Any move between two registers of a cover class should be
-   cheaper than load or store of the registers.  The macro value is
-   array of register classes with LIM_REG_CLASSES used as the end
-   marker.  */
-
-#define IRA_COVER_CLASSES                                      \
-{                                                              \
-  GENERAL_REGS, FP_REGS, MDR_REGS, LIM_REG_CLASSES             \
-}
-
 /* The same information, inverted:
    Return the class number of the smallest class containing
    reg number REGNO.  This could be a conditional expression
index 41f66cb..1b5e0a3 100644 (file)
@@ -135,15 +135,6 @@ enum reg_class
 };
 
 
-/* The following macro defines cover classes for Integrated Register
-   Allocator.  Cover classes is a set of non-intersected register
-   classes covering all hard registers used for register allocation
-   purpose.  Any move between two registers of a cover class should be
-   cheaper than load or store of the registers.  The macro value is
-   array of register classes with LIM_REG_CLASSES used as the end
-   marker.  */
-#define IRA_COVER_CLASSES { GENERAL_REGS, LIM_REG_CLASSES }
-
 #define REG_CLASS_CONTENTS \
 { { 0x00000000 }, /* Empty */                     \
   { 0x0003FFFF }, /* $fp, $sp, $r0 to $r13, ?fp */ \
index 7e8e05d..d207c0a 100644 (file)
@@ -294,19 +294,6 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FPUPPER_REGS, FP_REGS,
   {0x00000000, 0x00000000, 0x01000000},        /* SHIFT_REGS */                \
   {0xfffffffe, 0xffffffff, 0x03ffffff}}        /* ALL_REGS */
 
-/* The following macro defines cover classes for Integrated Register
-   Allocator.  Cover classes is a set of non-intersected register
-   classes covering all hard registers used for register allocation
-   purpose.  Any move between two registers of a cover class should be
-   cheaper than load or store of the registers.  The macro value is
-   array of register classes with LIM_REG_CLASSES used as the end
-   marker.  */
-
-#define IRA_COVER_CLASSES                                              \
-{                                                                      \
-  GENERAL_REGS, FP_REGS, SHIFT_REGS, LIM_REG_CLASSES                   \
-}
-
 /* Defines invalid mode changes.  */
 
 #define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
index 23dc778..810e945 100644 (file)
@@ -230,19 +230,6 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FPUPPER_REGS, FP_REGS,
   {0x00000000, 0x10000000},    /* SHIFT_REGS */                \
   {0xfffffffe, 0x3fffffff}}    /* ALL_REGS */
 
-/* The following macro defines cover classes for Integrated Register
-   Allocator.  Cover classes is a set of non-intersected register
-   classes covering all hard registers used for register allocation
-   purpose.  Any move between two registers of a cover class should be
-   cheaper than load or store of the registers.  The macro value is
-   array of register classes with LIM_REG_CLASSES used as the end
-   marker.  */
-
-#define IRA_COVER_CLASSES                                              \
-{                                                                      \
-  GENERAL_REGS, FP_REGS, SHIFT_REGS, LIM_REG_CLASSES                   \
-}
-
 /* Defines invalid mode changes.  */
 
 #define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
index 5f6bc7b..cb0a8f9 100644 (file)
@@ -292,19 +292,6 @@ enum reg_class
 
 #define N_REG_CLASSES (int) LIM_REG_CLASSES
 
-/* The following macro defines cover classes for Integrated Register
-   Allocator.  Cover classes is a set of non-intersected register
-   classes covering all hard registers used for register allocation
-   purpose.  Any move between two registers of a cover class should be
-   cheaper than load or store of the registers.  The macro value is
-   array of register classes with LIM_REG_CLASSES used as the end
-   marker.  */
-
-#define IRA_COVER_CLASSES                                              \
-{                                                                      \
-  GR_REGS, LIM_REG_CLASSES                                             \
-}
-
 
 /* The names of the register classes  */
 #define REG_CLASS_NAMES                                                        \
index b1efc0d..8b1d412 100644 (file)
@@ -1208,8 +1208,6 @@ static reg_class_t rs6000_secondary_reload (bool, rtx, reg_class_t,
                                            enum machine_mode,
                                            struct secondary_reload_info *);
 
-static const reg_class_t *rs6000_ira_cover_classes (void);
-
 const int INSN_NOT_AVAILABLE = -1;
 static enum machine_mode rs6000_eh_return_filter_mode (void);
 static bool rs6000_can_eliminate (const int, const int);
@@ -1636,9 +1634,6 @@ static const struct default_options rs6000_option_optimization_table[] =
 #undef TARGET_SECONDARY_RELOAD
 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
 
-#undef TARGET_IRA_COVER_CLASSES
-#define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
-
 #undef TARGET_LEGITIMATE_ADDRESS_P
 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
 
@@ -15288,26 +15283,6 @@ rs6000_secondary_reload_ppc64 (rtx reg, rtx mem, rtx scratch, bool store_p)
   return;
 }
 
-/* Target hook to return the cover classes for Integrated Register Allocator.
-   Cover classes is a set of non-intersected register classes covering all hard
-   registers used for register allocation purpose.  Any move between two
-   registers of a cover class should be cheaper than load or store of the
-   registers.  The value is array of register classes with LIM_REG_CLASSES used
-   as the end marker.
-
-   We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
-   account for the Altivec and Floating registers being subsets of the VSX
-   register set under VSX, but distinct register sets on pre-VSX machines.  */
-
-static const reg_class_t *
-rs6000_ira_cover_classes (void)
-{
-  static const reg_class_t cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
-  static const reg_class_t cover_vsx[]     = IRA_COVER_CLASSES_VSX;
-
-  return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
-}
-
 /* Allocate a 64-bit stack slot to be used for copying SDmode
    values through if this function has any SDmode references.  */
 
index 4913456..0193db5 100644 (file)
@@ -1252,34 +1252,6 @@ enum reg_class
   { 0xffffffff, 0xffffffff, 0xffffffff, 0x0003ffff }  /* ALL_REGS */        \
 }
 
-/* The following macro defines cover classes for Integrated Register
-   Allocator.  Cover classes is a set of non-intersected register
-   classes covering all hard registers used for register allocation
-   purpose.  Any move between two registers of a cover class should be
-   cheaper than load or store of the registers.  The macro value is
-   array of register classes with LIM_REG_CLASSES used as the end
-   marker.
-
-   We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
-   account for the Altivec and Floating registers being subsets of the VSX
-   register set.  */
-
-#define IRA_COVER_CLASSES_PRE_VSX                                           \
-{                                                                           \
-  GENERAL_REGS, SPECIAL_REGS, FLOAT_REGS, ALTIVEC_REGS, /* VSX_REGS, */             \
-  /* VRSAVE_REGS,*/ VSCR_REGS, SPE_ACC_REGS, SPEFSCR_REGS,                  \
-  /* MQ_REGS, LINK_REGS, CTR_REGS, */                                       \
-  CR_REGS, CA_REGS, LIM_REG_CLASSES                                         \
-}
-
-#define IRA_COVER_CLASSES_VSX                                               \
-{                                                                           \
-  GENERAL_REGS, SPECIAL_REGS, /* FLOAT_REGS, ALTIVEC_REGS, */ VSX_REGS,             \
-  /* VRSAVE_REGS,*/ VSCR_REGS, SPE_ACC_REGS, SPEFSCR_REGS,                  \
-  /* MQ_REGS, LINK_REGS, CTR_REGS, */                                       \
-  CR_REGS, CA_REGS, LIM_REG_CLASSES                                         \
-}
-
 /* The same information, inverted:
    Return the class number of the smallest class containing
    reg number REGNO.  This could be a conditional expression
index bd54a2b..f9ea209 100644 (file)
@@ -187,11 +187,6 @@ enum reg_class
   { 0x0000ffff }       /* All registers.  */           \
 }
 
-#define IRA_COVER_CLASSES                              \
-  {                                                    \
-    GR_REGS, LIM_REG_CLASSES                           \
-  }
-
 #define SMALL_REGISTER_CLASSES                 0
 #define N_REG_CLASSES                  (int) LIM_REG_CLASSES
 #define CLASS_MAX_NREGS(CLASS, MODE)    ((GET_MODE_SIZE (MODE) \
index c6ba4ff..8825ae2 100644 (file)
@@ -468,19 +468,6 @@ enum reg_class
   { 0xffffffff, 0x0000003f },  /* ALL_REGS */          \
 }
 
-/* The following macro defines cover classes for Integrated Register
-   Allocator.  Cover classes is a set of non-intersected register
-   classes covering all hard registers used for register allocation
-   purpose.  Any move between two registers of a cover class should be
-   cheaper than load or store of the registers.  The macro value is
-   array of register classes with LIM_REG_CLASSES used as the end
-   marker.  */
-
-#define IRA_COVER_CLASSES                                                   \
-{                                                                           \
-  GENERAL_REGS, FP_REGS, CC_REGS, ACCESS_REGS, LIM_REG_CLASSES              \
-}
-
 /* In some case register allocation order is not enough for IRA to
    generate a good code.  The following macro (if defined) increases
    cost of REGNO for a pseudo approximately by pseudo usage frequency
index 4554e26..c66e0e9 100644 (file)
@@ -390,18 +390,6 @@ enum reg_class
    also contains the register.  */
 #define REGNO_REG_CLASS(REGNO) (enum reg_class) score_reg_class (REGNO)
 
-/* The following macro defines cover classes for Integrated Register
-   Allocator.  Cover classes is a set of non-intersected register
-   classes covering all hard registers used for register allocation
-   purpose.  Any move between two registers of a cover class should be
-   cheaper than load or store of the registers.  The macro value is
-   array of register classes with LIM_REG_CLASSES used as the end
-   marker.  */
-#define IRA_COVER_CLASSES                                      \
-{                                                              \
-  G32_REGS, CE_REGS, SP_REGS, LIM_REG_CLASSES                  \
-}
-
 /* A macro whose definition is the name of the class to which a
    valid base register must belong.  A base register is one used in
    an address which is the register value plus a displacement.  */
index 4579af3..d45f8c0 100644 (file)
@@ -1133,20 +1133,6 @@ enum reg_class
 extern enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
 #define REGNO_REG_CLASS(REGNO) regno_reg_class[(REGNO)]
 
-/* The following macro defines cover classes for Integrated Register
-   Allocator.  Cover classes is a set of non-intersected register
-   classes covering all hard registers used for register allocation
-   purpose.  Any move between two registers of a cover class should be
-   cheaper than load or store of the registers.  The macro value is
-   array of register classes with LIM_REG_CLASSES used as the end
-   marker.  */
-
-#define IRA_COVER_CLASSES                                                   \
-{                                                                           \
-  GENERAL_REGS, FP_REGS, PR_REGS, T_REGS, MAC_REGS, TARGET_REGS,            \
-  FPUL_REGS, LIM_REG_CLASSES                                                \
-}
-
 /* When this hook returns true for MODE, the compiler allows
    registers explicitly used in the rtl to be used as spill registers
    but prevents the compiler from extending the lifetime of these
index 9b68f13..96733bf 100644 (file)
@@ -972,19 +972,6 @@ extern enum reg_class sparc_regno_reg_class[FIRST_PSEUDO_REGISTER];
 
 #define REGNO_REG_CLASS(REGNO) sparc_regno_reg_class[(REGNO)]
 
-/* The following macro defines cover classes for Integrated Register
-   Allocator.  Cover classes is a set of non-intersected register
-   classes covering all hard registers used for register allocation
-   purpose.  Any move between two registers of a cover class should be
-   cheaper than load or store of the registers.  The macro value is
-   array of register classes with LIM_REG_CLASSES used as the end
-   marker.  */
-
-#define IRA_COVER_CLASSES                                                   \
-{                                                                           \
-  GENERAL_REGS, EXTRA_FP_REGS, FPCC_REGS, LIM_REG_CLASSES                   \
-}
-
 /* Defines invalid mode changes.  Borrowed from pa64-regs.h.
 
    SImode loads to floating-point registers are not zero-extended.
index 51bfa51..b3bdcf5 100644 (file)
@@ -196,9 +196,6 @@ enum reg_class {
    LIM_REG_CLASSES 
 };
 
-/* SPU is simple, it really only has one class of registers.  */
-#define IRA_COVER_CLASSES { GENERAL_REGS, LIM_REG_CLASSES }
-
 #define N_REG_CLASSES (int) LIM_REG_CLASSES
 
 #define REG_CLASS_NAMES \
index a838b8a..53f4d2d 100644 (file)
@@ -179,11 +179,6 @@ enum reg_class
 
 #define N_REG_CLASSES ((int) LIM_REG_CLASSES)
 
-#define IRA_COVER_CLASSES                      \
-{                                              \
-  GENERAL_REGS, LIM_REG_CLASSES                        \
-}
-
 #define REG_CLASS_NAMES                                \
 {                                              \
   "NO_REGS",                                   \
index d1c4320..1171399 100644 (file)
@@ -304,11 +304,6 @@ enum reg_class
 
 #define N_REG_CLASSES (int) LIM_REG_CLASSES
 
-#define IRA_COVER_CLASSES              \
-{                                      \
-  GENERAL_REGS, LIM_REG_CLASSES                \
-}
-
 /* Give names of register classes as strings for dump file.  */
 
 #define REG_CLASS_NAMES \
index 272dfbb..15b7daa 100644 (file)
@@ -226,15 +226,6 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
 #define REG_CLASS_NAMES        \
   { "NO_REGS", "ALL_REGS" }
 
-/* The following macro defines cover classes for Integrated Register
-   Allocator.  Cover classes is a set of non-intersected register
-   classes covering all hard registers used for register allocation
-   purpose.  Any move between two registers of a cover class should be
-   cheaper than load or store of the registers.  The macro value is
-   array of register classes with LIM_REG_CLASSES used as the end
-   marker.  */
-#define IRA_COVER_CLASSES { ALL_REGS, LIM_REG_CLASSES }
-
 /* Return the maximum number of consecutive registers
    needed to represent mode MODE in a register of class CLASS.  */
 #define CLASS_MAX_NREGS(CLASS, MODE)   \
index 0a096cd..c9ff80c 100644 (file)
@@ -432,11 +432,6 @@ enum reg_class
   { 0xffffffff, 0x0000000f }  /* all registers */ \
 }
 
-#define IRA_COVER_CLASSES                                              \
-{                                                                      \
-  BR_REGS, FP_REGS, ACC_REG, AR_REGS, LIM_REG_CLASSES                  \
-}
-
 /* A C expression whose value is a register class containing hard
    register REGNO.  In general there is more that one such class;
    choose a class which is "minimal", meaning that no smaller class
index bdd1dd3..716be18 100644 (file)
@@ -2854,36 +2854,6 @@ as below:
 @end smallexample
 @end defmac
 
-@deftypefn {Target Hook} {const reg_class_t *} TARGET_IRA_COVER_CLASSES (void)
-Return an array of cover classes for the Integrated Register Allocator
-(@acronym{IRA}).  Cover classes are a set of non-intersecting register
-classes covering all hard registers used for register allocation
-purposes.  If a move between two registers in the same cover class is
-possible, it should be cheaper than a load or store of the registers.
-The array is terminated by a @code{LIM_REG_CLASSES} element.
-
-The order of cover classes in the array is important.  If two classes
-have the same cost of usage for a pseudo, the class occurred first in
-the array is chosen for the pseudo.
-
-This hook is called once at compiler startup, after the command-line
-options have been processed. It is then re-examined by every call to
-@code{target_reinit}.
-
-The default implementation returns @code{IRA_COVER_CLASSES}, if defined,
-otherwise there is no default implementation.  You must define either this
-macro or @code{IRA_COVER_CLASSES} in order to use the integrated register
-allocator with Chaitin-Briggs coloring. If the macro is not defined,
-the only available coloring algorithm is Chow's priority coloring.
-
-This hook must not be modified from @code{NULL} to non-@code{NULL} or
-vice versa by command-line option processing.
-@end deftypefn
-
-@defmac IRA_COVER_CLASSES
-See the documentation for @code{TARGET_IRA_COVER_CLASSES}.
-@end defmac
-
 @node Old Constraints
 @section Obsolete Macros for Defining Constraints
 @cindex defining constraints, obsolete method
index 654773e..eb19da2 100644 (file)
@@ -2842,36 +2842,6 @@ as below:
 @end smallexample
 @end defmac
 
-@hook TARGET_IRA_COVER_CLASSES
-Return an array of cover classes for the Integrated Register Allocator
-(@acronym{IRA}).  Cover classes are a set of non-intersecting register
-classes covering all hard registers used for register allocation
-purposes.  If a move between two registers in the same cover class is
-possible, it should be cheaper than a load or store of the registers.
-The array is terminated by a @code{LIM_REG_CLASSES} element.
-
-The order of cover classes in the array is important.  If two classes
-have the same cost of usage for a pseudo, the class occurred first in
-the array is chosen for the pseudo.
-
-This hook is called once at compiler startup, after the command-line
-options have been processed. It is then re-examined by every call to
-@code{target_reinit}.
-
-The default implementation returns @code{IRA_COVER_CLASSES}, if defined,
-otherwise there is no default implementation.  You must define either this
-macro or @code{IRA_COVER_CLASSES} in order to use the integrated register
-allocator with Chaitin-Briggs coloring. If the macro is not defined,
-the only available coloring algorithm is Chow's priority coloring.
-
-This hook must not be modified from @code{NULL} to non-@code{NULL} or
-vice versa by command-line option processing.
-@end deftypefn
-
-@defmac IRA_COVER_CLASSES
-See the documentation for @code{TARGET_IRA_COVER_CLASSES}.
-@end defmac
-
 @node Old Constraints
 @section Obsolete Macros for Defining Constraints
 @cindex defining constraints, obsolete method
index ea69254..12cb205 100644 (file)
@@ -573,11 +573,11 @@ schedule_insns (void)
    up.  */
 bool sched_pressure_p;
 
-/* Map regno -> its cover class.  The map defined only when
+/* Map regno -> its pressure class.  The map defined only when
    SCHED_PRESSURE_P is true.  */
-enum reg_class *sched_regno_cover_class;
+enum reg_class *sched_regno_pressure_class;
 
-/* The current register pressure.  Only elements corresponding cover
+/* The current register pressure.  Only elements corresponding pressure
    classes are defined.  */
 static int curr_reg_pressure[N_REG_CLASSES];
 
@@ -607,39 +607,41 @@ sched_init_region_reg_pressure_info (void)
 static void
 mark_regno_birth_or_death (int regno, bool birth_p)
 {
-  enum reg_class cover_class;
+  enum reg_class pressure_class;
 
-  cover_class = sched_regno_cover_class[regno];
+  pressure_class = sched_regno_pressure_class[regno];
   if (regno >= FIRST_PSEUDO_REGISTER)
     {
-      if (cover_class != NO_REGS)
+      if (pressure_class != NO_REGS)
        {
          if (birth_p)
            {
              bitmap_set_bit (curr_reg_live, regno);
-             curr_reg_pressure[cover_class]
-               += ira_reg_class_nregs[cover_class][PSEUDO_REGNO_MODE (regno)];
+             curr_reg_pressure[pressure_class]
+               += (ira_reg_class_max_nregs
+                   [pressure_class][PSEUDO_REGNO_MODE (regno)]);
            }
          else
            {
              bitmap_clear_bit (curr_reg_live, regno);
-             curr_reg_pressure[cover_class]
-               -= ira_reg_class_nregs[cover_class][PSEUDO_REGNO_MODE (regno)];
+             curr_reg_pressure[pressure_class]
+               -= (ira_reg_class_max_nregs
+                   [pressure_class][PSEUDO_REGNO_MODE (regno)]);
            }
        }
     }
-  else if (cover_class != NO_REGS
+  else if (pressure_class != NO_REGS
           && ! TEST_HARD_REG_BIT (ira_no_alloc_regs, regno))
     {
       if (birth_p)
        {
          bitmap_set_bit (curr_reg_live, regno);
-         curr_reg_pressure[cover_class]++;
+         curr_reg_pressure[pressure_class]++;
        }
       else
        {
          bitmap_clear_bit (curr_reg_live, regno);
-         curr_reg_pressure[cover_class]--;
+         curr_reg_pressure[pressure_class]--;
        }
     }
 }
@@ -653,8 +655,8 @@ initiate_reg_pressure_info (bitmap live)
   unsigned int j;
   bitmap_iterator bi;
 
-  for (i = 0; i < ira_reg_class_cover_size; i++)
-    curr_reg_pressure[ira_reg_class_cover[i]] = 0;
+  for (i = 0; i < ira_pressure_classes_num; i++)
+    curr_reg_pressure[ira_pressure_classes[i]] = 0;
   bitmap_clear (curr_reg_live);
   EXECUTE_IF_SET_IN_BITMAP (live, 0, j, bi)
     if (current_nr_blocks == 1 || bitmap_bit_p (region_ref_regs, j))
@@ -723,9 +725,9 @@ save_reg_pressure (void)
 {
   int i;
 
-  for (i = 0; i < ira_reg_class_cover_size; i++)
-    saved_reg_pressure[ira_reg_class_cover[i]]
-      = curr_reg_pressure[ira_reg_class_cover[i]];
+  for (i = 0; i < ira_pressure_classes_num; i++)
+    saved_reg_pressure[ira_pressure_classes[i]]
+      = curr_reg_pressure[ira_pressure_classes[i]];
   bitmap_copy (saved_reg_live, curr_reg_live);
 }
 
@@ -735,9 +737,9 @@ restore_reg_pressure (void)
 {
   int i;
 
-  for (i = 0; i < ira_reg_class_cover_size; i++)
-    curr_reg_pressure[ira_reg_class_cover[i]]
-      = saved_reg_pressure[ira_reg_class_cover[i]];
+  for (i = 0; i < ira_pressure_classes_num; i++)
+    curr_reg_pressure[ira_pressure_classes[i]]
+      = saved_reg_pressure[ira_pressure_classes[i]];
   bitmap_copy (curr_reg_live, saved_reg_live);
 }
 
@@ -755,7 +757,7 @@ dying_use_p (struct reg_use_data *use)
 }
 
 /* Print info about the current register pressure and its excess for
-   each cover class.  */
+   each pressure class.  */
 static void
 print_curr_reg_pressure (void)
 {
@@ -763,9 +765,9 @@ print_curr_reg_pressure (void)
   enum reg_class cl;
 
   fprintf (sched_dump, ";;\t");
-  for (i = 0; i < ira_reg_class_cover_size; i++)
+  for (i = 0; i < ira_pressure_classes_num; i++)
     {
-      cl = ira_reg_class_cover[i];
+      cl = ira_pressure_classes[i];
       gcc_assert (curr_reg_pressure[cl] >= 0);
       fprintf (sched_dump, "  %s:%d(%d)", reg_class_names[cl],
               curr_reg_pressure[cl],
@@ -1108,23 +1110,24 @@ setup_insn_reg_pressure_info (rtx insn)
   gcc_checking_assert (!DEBUG_INSN_P (insn));
 
   excess_cost_change = 0;
-  for (i = 0; i < ira_reg_class_cover_size; i++)
-    death[ira_reg_class_cover[i]] = 0;
+  for (i = 0; i < ira_pressure_classes_num; i++)
+    death[ira_pressure_classes[i]] = 0;
   for (use = INSN_REG_USE_LIST (insn); use != NULL; use = use->next_insn_use)
     if (dying_use_p (use))
       {
-       cl = sched_regno_cover_class[use->regno];
+       cl = sched_regno_pressure_class[use->regno];
        if (use->regno < FIRST_PSEUDO_REGISTER)
          death[cl]++;
        else
-         death[cl] += ira_reg_class_nregs[cl][PSEUDO_REGNO_MODE (use->regno)];
+         death[cl]
+           += ira_reg_class_max_nregs[cl][PSEUDO_REGNO_MODE (use->regno)];
       }
   pressure_info = INSN_REG_PRESSURE (insn);
   max_reg_pressure = INSN_MAX_REG_PRESSURE (insn);
   gcc_assert (pressure_info != NULL && max_reg_pressure != NULL);
-  for (i = 0; i < ira_reg_class_cover_size; i++)
+  for (i = 0; i < ira_pressure_classes_num; i++)
     {
-      cl = ira_reg_class_cover[i];
+      cl = ira_pressure_classes[i];
       gcc_assert (curr_reg_pressure[cl] >= 0);
       change = (int) pressure_info[i].set_increase - death[cl];
       before = MAX (0, max_reg_pressure[i] - ira_available_class_regs[cl]);
@@ -1569,9 +1572,9 @@ setup_insn_max_reg_pressure (rtx after, bool update_p)
   static int max_reg_pressure[N_REG_CLASSES];
 
   save_reg_pressure ();
-  for (i = 0; i < ira_reg_class_cover_size; i++)
-    max_reg_pressure[ira_reg_class_cover[i]]
-      = curr_reg_pressure[ira_reg_class_cover[i]];
+  for (i = 0; i < ira_pressure_classes_num; i++)
+    max_reg_pressure[ira_pressure_classes[i]]
+      = curr_reg_pressure[ira_pressure_classes[i]];
   for (insn = NEXT_INSN (after);
        insn != NULL_RTX && ! BARRIER_P (insn)
         && BLOCK_FOR_INSN (insn) == BLOCK_FOR_INSN (after);
@@ -1579,24 +1582,24 @@ setup_insn_max_reg_pressure (rtx after, bool update_p)
     if (NONDEBUG_INSN_P (insn))
       {
        eq_p = true;
-       for (i = 0; i < ira_reg_class_cover_size; i++)
+       for (i = 0; i < ira_pressure_classes_num; i++)
          {
-           p = max_reg_pressure[ira_reg_class_cover[i]];
+           p = max_reg_pressure[ira_pressure_classes[i]];
            if (INSN_MAX_REG_PRESSURE (insn)[i] != p)
              {
                eq_p = false;
                INSN_MAX_REG_PRESSURE (insn)[i]
-                 = max_reg_pressure[ira_reg_class_cover[i]];
+                 = max_reg_pressure[ira_pressure_classes[i]];
              }
          }
        if (update_p && eq_p)
          break;
        update_register_pressure (insn);
-       for (i = 0; i < ira_reg_class_cover_size; i++)
-         if (max_reg_pressure[ira_reg_class_cover[i]]
-             < curr_reg_pressure[ira_reg_class_cover[i]])
-           max_reg_pressure[ira_reg_class_cover[i]]
-             = curr_reg_pressure[ira_reg_class_cover[i]];
+       for (i = 0; i < ira_pressure_classes_num; i++)
+         if (max_reg_pressure[ira_pressure_classes[i]]
+             < curr_reg_pressure[ira_pressure_classes[i]])
+           max_reg_pressure[ira_pressure_classes[i]]
+             = curr_reg_pressure[ira_pressure_classes[i]];
       }
   restore_reg_pressure ();
 }
@@ -1610,13 +1613,13 @@ update_reg_and_insn_max_reg_pressure (rtx insn)
   int i;
   int before[N_REG_CLASSES];
 
-  for (i = 0; i < ira_reg_class_cover_size; i++)
-    before[i] = curr_reg_pressure[ira_reg_class_cover[i]];
+  for (i = 0; i < ira_pressure_classes_num; i++)
+    before[i] = curr_reg_pressure[ira_pressure_classes[i]];
   update_register_pressure (insn);
-  for (i = 0; i < ira_reg_class_cover_size; i++)
-    if (curr_reg_pressure[ira_reg_class_cover[i]] != before[i])
+  for (i = 0; i < ira_pressure_classes_num; i++)
+    if (curr_reg_pressure[ira_pressure_classes[i]] != before[i])
       break;
-  if (i < ira_reg_class_cover_size)
+  if (i < ira_pressure_classes_num)
     setup_insn_max_reg_pressure (insn, true);
 }
 
@@ -1662,9 +1665,9 @@ schedule_insn (rtx insn)
       if (pressure_info != NULL)
        {
          fputc (':', sched_dump);
-         for (i = 0; i < ira_reg_class_cover_size; i++)
+         for (i = 0; i < ira_pressure_classes_num; i++)
            fprintf (sched_dump, "%s%+d(%d)",
-                    reg_class_names[ira_reg_class_cover[i]],
+                    reg_class_names[ira_pressure_classes[i]],
                     pressure_info[i].set_increase, pressure_info[i].change);
        }
       fputc ('\n', sched_dump);
@@ -3509,13 +3512,13 @@ sched_init (void)
       int i, max_regno = max_reg_num ();
 
       ira_set_pseudo_classes (sched_verbose ? sched_dump : NULL);
-      sched_regno_cover_class
+      sched_regno_pressure_class
        = (enum reg_class *) xmalloc (max_regno * sizeof (enum reg_class));
       for (i = 0; i < max_regno; i++)
-       sched_regno_cover_class[i]
+       sched_regno_pressure_class[i]
          = (i < FIRST_PSEUDO_REGISTER
-            ? ira_class_translate[REGNO_REG_CLASS (i)]
-            : reg_cover_class (i));
+            ? ira_pressure_class_translate[REGNO_REG_CLASS (i)]
+            : ira_pressure_class_translate[reg_allocno_class (i)]);
       curr_reg_live = BITMAP_ALLOC (NULL);
       saved_reg_live = BITMAP_ALLOC (NULL);
       region_ref_regs = BITMAP_ALLOC (NULL);
@@ -3620,7 +3623,7 @@ sched_finish (void)
   haifa_finish_h_i_d ();
   if (sched_pressure_p)
     {
-      free (sched_regno_cover_class);
+      free (sched_regno_pressure_class);
       BITMAP_FREE (region_ref_regs);
       BITMAP_FREE (saved_reg_live);
       BITMAP_FREE (curr_reg_live);
index b3c1e14..f7cb36e 100644 (file)
@@ -415,7 +415,8 @@ initiate_allocnos (void)
     = VEC_alloc (ira_object_t, heap, max_reg_num () * 2);
   ira_object_id_map = NULL;
   ira_regno_allocno_map
-    = (ira_allocno_t *) ira_allocate (max_reg_num () * sizeof (ira_allocno_t));
+    = (ira_allocno_t *) ira_allocate (max_reg_num ()
+                                     * sizeof (ira_allocno_t));
   memset (ira_regno_allocno_map, 0, max_reg_num () * sizeof (ira_allocno_t));
 }
 
@@ -423,7 +424,7 @@ initiate_allocnos (void)
 static ira_object_t
 ira_create_object (ira_allocno_t a, int subword)
 {
-  enum reg_class cover_class = ALLOCNO_COVER_CLASS (a);
+  enum reg_class aclass = ALLOCNO_CLASS (a);
   ira_object_t obj = (ira_object_t) pool_alloc (object_pool);
 
   OBJECT_ALLOCNO (obj) = a;
@@ -435,12 +436,13 @@ ira_create_object (ira_allocno_t a, int subword)
   COPY_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), ira_no_alloc_regs);
   COPY_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), ira_no_alloc_regs);
   IOR_COMPL_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj),
-                         reg_class_contents[cover_class]);
+                         reg_class_contents[aclass]);
   IOR_COMPL_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
-                         reg_class_contents[cover_class]);
+                         reg_class_contents[aclass]);
   OBJECT_MIN (obj) = INT_MAX;
   OBJECT_MAX (obj) = -1;
   OBJECT_LIVE_RANGES (obj) = NULL;
+  OBJECT_ADD_DATA (obj) = NULL;
 
   VEC_safe_push (ira_object_t, heap, ira_object_id_map_vec, obj);
   ira_object_id_map
@@ -454,7 +456,8 @@ ira_create_object (ira_allocno_t a, int subword)
    LOOP_TREE_NODE.  Add the allocno to the list of allocnos with the
    same regno if CAP_P is FALSE.  */
 ira_allocno_t
-ira_create_allocno (int regno, bool cap_p, ira_loop_tree_node_t loop_tree_node)
+ira_create_allocno (int regno, bool cap_p,
+                   ira_loop_tree_node_t loop_tree_node)
 {
   ira_allocno_t a;
 
@@ -484,35 +487,24 @@ ira_create_allocno (int regno, bool cap_p, ira_loop_tree_node_t loop_tree_node)
   ALLOCNO_NO_STACK_REG_P (a) = false;
   ALLOCNO_TOTAL_NO_STACK_REG_P (a) = false;
 #endif
-  ALLOCNO_MEM_OPTIMIZED_DEST (a) = NULL;
-  ALLOCNO_MEM_OPTIMIZED_DEST_P (a) = false;
-  ALLOCNO_SOMEWHERE_RENAMED_P (a) = false;
-  ALLOCNO_CHILD_RENAMED_P (a) = false;
   ALLOCNO_DONT_REASSIGN_P (a) = false;
   ALLOCNO_BAD_SPILL_P (a) = false;
-  ALLOCNO_IN_GRAPH_P (a) = false;
   ALLOCNO_ASSIGNED_P (a) = false;
-  ALLOCNO_MAY_BE_SPILLED_P (a) = false;
-  ALLOCNO_SPLAY_REMOVED_P (a) = false;
   ALLOCNO_MODE (a) = (regno < 0 ? VOIDmode : PSEUDO_REGNO_MODE (regno));
   ALLOCNO_COPIES (a) = NULL;
   ALLOCNO_HARD_REG_COSTS (a) = NULL;
   ALLOCNO_CONFLICT_HARD_REG_COSTS (a) = NULL;
   ALLOCNO_UPDATED_HARD_REG_COSTS (a) = NULL;
   ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) = NULL;
-  ALLOCNO_LEFT_CONFLICTS_SIZE (a) = -1;
-  ALLOCNO_COVER_CLASS (a) = NO_REGS;
-  ALLOCNO_UPDATED_COVER_CLASS_COST (a) = 0;
-  ALLOCNO_COVER_CLASS_COST (a) = 0;
+  ALLOCNO_CLASS (a) = NO_REGS;
+  ALLOCNO_UPDATED_CLASS_COST (a) = 0;
+  ALLOCNO_CLASS_COST (a) = 0;
   ALLOCNO_MEMORY_COST (a) = 0;
   ALLOCNO_UPDATED_MEMORY_COST (a) = 0;
   ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a) = 0;
-  ALLOCNO_NEXT_BUCKET_ALLOCNO (a) = NULL;
-  ALLOCNO_PREV_BUCKET_ALLOCNO (a) = NULL;
-  ALLOCNO_FIRST_COALESCED_ALLOCNO (a) = a;
-  ALLOCNO_NEXT_COALESCED_ALLOCNO (a) = a;
   ALLOCNO_NUM_OBJECTS (a) = 0;
 
+  ALLOCNO_ADD_DATA (a) = NULL;
   VEC_safe_push (ira_allocno_t, heap, allocno_vec, a);
   ira_allocnos = VEC_address (ira_allocno_t, allocno_vec);
   ira_allocnos_num = VEC_length (ira_allocno_t, allocno_vec);
@@ -520,11 +512,22 @@ ira_create_allocno (int regno, bool cap_p, ira_loop_tree_node_t loop_tree_node)
   return a;
 }
 
-/* Set up cover class for A and update its conflict hard registers.  */
+/* Set up register class for A and update its conflict hard
+   registers.  */
 void
-ira_set_allocno_cover_class (ira_allocno_t a, enum reg_class cover_class)
+ira_set_allocno_class (ira_allocno_t a, enum reg_class aclass)
 {
-  ALLOCNO_COVER_CLASS (a) = cover_class;
+  ira_allocno_object_iterator oi;
+  ira_object_t obj;
+
+  ALLOCNO_CLASS (a) = aclass;
+  FOR_EACH_ALLOCNO_OBJECT (a, obj, oi)
+    {
+      IOR_COMPL_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj),
+                             reg_class_contents[aclass]);
+      IOR_COMPL_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
+                             reg_class_contents[aclass]);
+    }
 }
 
 /* Determine the number of objects we should associate with allocno A
@@ -533,8 +536,8 @@ void
 ira_create_allocno_objects (ira_allocno_t a)
 {
   enum machine_mode mode = ALLOCNO_MODE (a);
-  enum reg_class cover_class = ALLOCNO_COVER_CLASS (a);
-  int n = ira_reg_class_nregs[cover_class][mode];
+  enum reg_class aclass = ALLOCNO_CLASS (a);
+  int n = ira_reg_class_max_nregs[aclass][mode];
   int i;
 
   if (GET_MODE_SIZE (mode) != 2 * UNITS_PER_WORD || n != 2)
@@ -546,7 +549,7 @@ ira_create_allocno_objects (ira_allocno_t a)
 }
 
 /* For each allocno, set ALLOCNO_NUM_OBJECTS and create the
-   ALLOCNO_OBJECT structures.  This must be called after the cover
+   ALLOCNO_OBJECT structures.  This must be called after the allocno
    classes are known.  */
 static void
 create_allocno_objects (void)
@@ -571,6 +574,7 @@ merge_hard_reg_conflicts (ira_allocno_t from, ira_allocno_t to,
     {
       ira_object_t from_obj = ALLOCNO_OBJECT (from, i);
       ira_object_t to_obj = ALLOCNO_OBJECT (to, i);
+
       if (!total_only)
        IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (to_obj),
                          OBJECT_CONFLICT_HARD_REGS (from_obj));
@@ -592,6 +596,7 @@ ior_hard_reg_conflicts (ira_allocno_t a, HARD_REG_SET *set)
 {
   ira_allocno_object_iterator i;
   ira_object_t obj;
+
   FOR_EACH_ALLOCNO_OBJECT (a, obj, i)
     {
       IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), *set);
@@ -849,25 +854,22 @@ create_cap_allocno (ira_allocno_t a)
 {
   ira_allocno_t cap;
   ira_loop_tree_node_t parent;
-  enum reg_class cover_class;
+  enum reg_class aclass;
 
-  ira_assert (ALLOCNO_FIRST_COALESCED_ALLOCNO (a) == a
-             && ALLOCNO_NEXT_COALESCED_ALLOCNO (a) == a);
   parent = ALLOCNO_LOOP_TREE_NODE (a)->parent;
   cap = ira_create_allocno (ALLOCNO_REGNO (a), true, parent);
   ALLOCNO_MODE (cap) = ALLOCNO_MODE (a);
-  cover_class = ALLOCNO_COVER_CLASS (a);
-  ira_set_allocno_cover_class (cap, cover_class);
+  aclass = ALLOCNO_CLASS (a);
+  ira_set_allocno_class (cap, aclass);
   ira_create_allocno_objects (cap);
-  ALLOCNO_AVAILABLE_REGS_NUM (cap) = ALLOCNO_AVAILABLE_REGS_NUM (a);
   ALLOCNO_CAP_MEMBER (cap) = a;
   ALLOCNO_CAP (a) = cap;
-  ALLOCNO_COVER_CLASS_COST (cap) = ALLOCNO_COVER_CLASS_COST (a);
+  ALLOCNO_CLASS_COST (cap) = ALLOCNO_CLASS_COST (a);
   ALLOCNO_MEMORY_COST (cap) = ALLOCNO_MEMORY_COST (a);
   ira_allocate_and_copy_costs
-    (&ALLOCNO_HARD_REG_COSTS (cap), cover_class, ALLOCNO_HARD_REG_COSTS (a));
+    (&ALLOCNO_HARD_REG_COSTS (cap), aclass, ALLOCNO_HARD_REG_COSTS (a));
   ira_allocate_and_copy_costs
-    (&ALLOCNO_CONFLICT_HARD_REG_COSTS (cap), cover_class,
+    (&ALLOCNO_CONFLICT_HARD_REG_COSTS (cap), aclass,
      ALLOCNO_CONFLICT_HARD_REG_COSTS (a));
   ALLOCNO_BAD_SPILL_P (cap) = ALLOCNO_BAD_SPILL_P (a);
   ALLOCNO_NREFS (cap) = ALLOCNO_NREFS (a);
@@ -1063,23 +1065,24 @@ ira_finish_live_range_list (live_range_t r)
 void
 ira_free_allocno_updated_costs (ira_allocno_t a)
 {
-  enum reg_class cover_class;
+  enum reg_class aclass;
 
-  cover_class = ALLOCNO_COVER_CLASS (a);
+  aclass = ALLOCNO_CLASS (a);
   if (ALLOCNO_UPDATED_HARD_REG_COSTS (a) != NULL)
-    ira_free_cost_vector (ALLOCNO_UPDATED_HARD_REG_COSTS (a), cover_class);
+    ira_free_cost_vector (ALLOCNO_UPDATED_HARD_REG_COSTS (a), aclass);
   ALLOCNO_UPDATED_HARD_REG_COSTS (a) = NULL;
   if (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) != NULL)
     ira_free_cost_vector (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a),
-                         cover_class);
+                         aclass);
   ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) = NULL;
 }
 
-/* Free the memory allocated for allocno A.  */
+/* Free and nullify all cost vectors allocated earlier for allocno
+   A.  */
 static void
-finish_allocno (ira_allocno_t a)
+ira_free_allocno_costs (ira_allocno_t a)
 {
-  enum reg_class cover_class = ALLOCNO_COVER_CLASS (a);
+  enum reg_class aclass = ALLOCNO_CLASS (a);
   ira_object_t obj;
   ira_allocno_object_iterator oi;
 
@@ -1094,14 +1097,25 @@ finish_allocno (ira_allocno_t a)
 
   ira_allocnos[ALLOCNO_NUM (a)] = NULL;
   if (ALLOCNO_HARD_REG_COSTS (a) != NULL)
-    ira_free_cost_vector (ALLOCNO_HARD_REG_COSTS (a), cover_class);
+    ira_free_cost_vector (ALLOCNO_HARD_REG_COSTS (a), aclass);
   if (ALLOCNO_CONFLICT_HARD_REG_COSTS (a) != NULL)
-    ira_free_cost_vector (ALLOCNO_CONFLICT_HARD_REG_COSTS (a), cover_class);
+    ira_free_cost_vector (ALLOCNO_CONFLICT_HARD_REG_COSTS (a), aclass);
   if (ALLOCNO_UPDATED_HARD_REG_COSTS (a) != NULL)
-    ira_free_cost_vector (ALLOCNO_UPDATED_HARD_REG_COSTS (a), cover_class);
+    ira_free_cost_vector (ALLOCNO_UPDATED_HARD_REG_COSTS (a), aclass);
   if (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) != NULL)
     ira_free_cost_vector (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a),
-                         cover_class);
+                         aclass);
+  ALLOCNO_HARD_REG_COSTS (a) = NULL;
+  ALLOCNO_CONFLICT_HARD_REG_COSTS (a) = NULL;
+  ALLOCNO_UPDATED_HARD_REG_COSTS (a) = NULL;
+  ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) = NULL;
+}
+
+/* Free the memory allocated for allocno A.  */
+static void
+finish_allocno (ira_allocno_t a)
+{
+  ira_free_allocno_costs (a);
   pool_free (allocno_pool, a);
 }
 
@@ -1365,55 +1379,54 @@ finish_copies (void)
 
 \f
 
-/* Pools for cost vectors.  It is defined only for cover classes.  */
+/* Pools for cost vectors.  It is defined only for allocno classes.  */
 static alloc_pool cost_vector_pool[N_REG_CLASSES];
 
 /* The function initiates work with hard register cost vectors.  It
-   creates allocation pool for each cover class.  */
+   creates allocation pool for each allocno class.  */
 static void
 initiate_cost_vectors (void)
 {
   int i;
-  enum reg_class cover_class;
+  enum reg_class aclass;
 
-  for (i = 0; i < ira_reg_class_cover_size; i++)
+  for (i = 0; i < ira_allocno_classes_num; i++)
     {
-      cover_class = ira_reg_class_cover[i];
-      cost_vector_pool[cover_class]
+      aclass = ira_allocno_classes[i];
+      cost_vector_pool[aclass]
        = create_alloc_pool ("cost vectors",
-                            sizeof (int)
-                            * ira_class_hard_regs_num[cover_class],
+                            sizeof (int) * ira_class_hard_regs_num[aclass],
                             100);
     }
 }
 
-/* Allocate and return a cost vector VEC for COVER_CLASS.  */
+/* Allocate and return a cost vector VEC for ACLASS.  */
 int *
-ira_allocate_cost_vector (enum reg_class cover_class)
+ira_allocate_cost_vector (enum reg_class aclass)
 {
-  return (int *) pool_alloc (cost_vector_pool[cover_class]);
+  return (int *) pool_alloc (cost_vector_pool[aclass]);
 }
 
-/* Free a cost vector VEC for COVER_CLASS.  */
+/* Free a cost vector VEC for ACLASS.  */
 void
-ira_free_cost_vector (int *vec, enum reg_class cover_class)
+ira_free_cost_vector (int *vec, enum reg_class aclass)
 {
   ira_assert (vec != NULL);
-  pool_free (cost_vector_pool[cover_class], vec);
+  pool_free (cost_vector_pool[aclass], vec);
 }
 
 /* Finish work with hard register cost vectors.  Release allocation
-   pool for each cover class.  */
+   pool for each allocno class.  */
 static void
 finish_cost_vectors (void)
 {
   int i;
-  enum reg_class cover_class;
+  enum reg_class aclass;
 
-  for (i = 0; i < ira_reg_class_cover_size; i++)
+  for (i = 0; i < ira_allocno_classes_num; i++)
     {
-      cover_class = ira_reg_class_cover[i];
-      free_alloc_pool (cost_vector_pool[cover_class]);
+      aclass = ira_allocno_classes[i];
+      free_alloc_pool (cost_vector_pool[aclass]);
     }
 }
 
@@ -1644,7 +1657,7 @@ propagate_allocno_info (void)
   int i;
   ira_allocno_t a, parent_a;
   ira_loop_tree_node_t parent;
-  enum reg_class cover_class;
+  enum reg_class aclass;
 
   if (flag_ira_region != IRA_REGION_ALL
       && flag_ira_region != IRA_REGION_MIXED)
@@ -1670,17 +1683,17 @@ propagate_allocno_info (void)
            += ALLOCNO_CALLS_CROSSED_NUM (a);
          ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (parent_a)
            += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a);
-         cover_class = ALLOCNO_COVER_CLASS (a);
-         ira_assert (cover_class == ALLOCNO_COVER_CLASS (parent_a));
+         aclass = ALLOCNO_CLASS (a);
+         ira_assert (aclass == ALLOCNO_CLASS (parent_a));
          ira_allocate_and_accumulate_costs
-           (&ALLOCNO_HARD_REG_COSTS (parent_a), cover_class,
+           (&ALLOCNO_HARD_REG_COSTS (parent_a), aclass,
             ALLOCNO_HARD_REG_COSTS (a));
          ira_allocate_and_accumulate_costs
            (&ALLOCNO_CONFLICT_HARD_REG_COSTS (parent_a),
-            cover_class,
+            aclass,
             ALLOCNO_CONFLICT_HARD_REG_COSTS (a));
-         ALLOCNO_COVER_CLASS_COST (parent_a)
-           += ALLOCNO_COVER_CLASS_COST (a);
+         ALLOCNO_CLASS_COST (parent_a)
+           += ALLOCNO_CLASS_COST (a);
          ALLOCNO_MEMORY_COST (parent_a) += ALLOCNO_MEMORY_COST (a);
        }
 }
@@ -1778,16 +1791,16 @@ static bool
 low_pressure_loop_node_p (ira_loop_tree_node_t node)
 {
   int i;
-  enum reg_class cover_class;
+  enum reg_class pclass;
 
   if (node->bb != NULL)
     return false;
 
-  for (i = 0; i < ira_reg_class_cover_size; i++)
+  for (i = 0; i < ira_pressure_classes_num; i++)
     {
-      cover_class = ira_reg_class_cover[i];
-      if (node->reg_pressure[cover_class]
-         > ira_available_class_regs[cover_class])
+      pclass = ira_pressure_classes[i];
+      if (node->reg_pressure[pclass] > ira_available_class_regs[pclass]
+         && ira_available_class_regs[pclass] > 1)
        return false;
     }
   return true;
@@ -2003,7 +2016,7 @@ ira_rebuild_regno_allocno_list (int regno)
 static void
 propagate_some_info_from_allocno (ira_allocno_t a, ira_allocno_t from_a)
 {
-  enum reg_class cover_class;
+  enum reg_class aclass;
 
   merge_hard_reg_conflicts (from_a, a, false);
   ALLOCNO_NREFS (a) += ALLOCNO_NREFS (from_a);
@@ -2014,14 +2027,14 @@ propagate_some_info_from_allocno (ira_allocno_t a, ira_allocno_t from_a)
     += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (from_a);
   if (! ALLOCNO_BAD_SPILL_P (from_a))
     ALLOCNO_BAD_SPILL_P (a) = false;
-  cover_class = ALLOCNO_COVER_CLASS (from_a);
-  ira_assert (cover_class == ALLOCNO_COVER_CLASS (a));
-  ira_allocate_and_accumulate_costs (&ALLOCNO_HARD_REG_COSTS (a), cover_class,
+  aclass = ALLOCNO_CLASS (from_a);
+  ira_assert (aclass == ALLOCNO_CLASS (a));
+  ira_allocate_and_accumulate_costs (&ALLOCNO_HARD_REG_COSTS (a), aclass,
                                     ALLOCNO_HARD_REG_COSTS (from_a));
   ira_allocate_and_accumulate_costs (&ALLOCNO_CONFLICT_HARD_REG_COSTS (a),
-                                    cover_class,
+                                    aclass,
                                     ALLOCNO_CONFLICT_HARD_REG_COSTS (from_a));
-  ALLOCNO_COVER_CLASS_COST (a) += ALLOCNO_COVER_CLASS_COST (from_a);
+  ALLOCNO_CLASS_COST (a) += ALLOCNO_CLASS_COST (from_a);
   ALLOCNO_MEMORY_COST (a) += ALLOCNO_MEMORY_COST (from_a);
 }
 
@@ -2173,8 +2186,8 @@ remove_low_level_allocnos (void)
 /* Remove loops from consideration.  We remove all loops except for
    root if ALL_P or loops for which a separate allocation will not
    improve the result.  We have to do this after allocno creation and
-   their costs and cover class evaluation because only after that the
-   register pressure can be known and is calculated.  */
+   their costs and allocno class evaluation because only after that
+   the register pressure can be known and is calculated.  */
 static void
 remove_unnecessary_regions (bool all_p)
 {
@@ -2223,27 +2236,27 @@ update_bad_spill_attribute (void)
   ira_allocno_object_iterator aoi;
   ira_object_t obj;
   live_range_t r;
-  enum reg_class cover_class;
+  enum reg_class aclass;
   bitmap_head dead_points[N_REG_CLASSES];
 
-  for (i = 0; i < ira_reg_class_cover_size; i++)
+  for (i = 0; i < ira_allocno_classes_num; i++)
     {
-      cover_class = ira_reg_class_cover[i];
-      bitmap_initialize (&dead_points[cover_class], &reg_obstack);
+      aclass = ira_allocno_classes[i];
+      bitmap_initialize (&dead_points[aclass], &reg_obstack);
     }
   FOR_EACH_ALLOCNO (a, ai)
     {
-      cover_class = ALLOCNO_COVER_CLASS (a);
-      if (cover_class == NO_REGS)
+      aclass = ALLOCNO_CLASS (a);
+      if (aclass == NO_REGS)
        continue;
       FOR_EACH_ALLOCNO_OBJECT (a, obj, aoi)
        for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
-         bitmap_set_bit (&dead_points[cover_class], r->finish);
+         bitmap_set_bit (&dead_points[aclass], r->finish);
     }
   FOR_EACH_ALLOCNO (a, ai)
     {
-      cover_class = ALLOCNO_COVER_CLASS (a);
-      if (cover_class == NO_REGS)
+      aclass = ALLOCNO_CLASS (a);
+      if (aclass == NO_REGS)
        continue;
       if (! ALLOCNO_BAD_SPILL_P (a))
        continue;
@@ -2252,7 +2265,7 @@ update_bad_spill_attribute (void)
          for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
            {
              for (i = r->start + 1; i < r->finish; i++)
-               if (bitmap_bit_p (&dead_points[cover_class], i))
+               if (bitmap_bit_p (&dead_points[aclass], i))
                  break;
              if (i < r->finish)
                break;
@@ -2264,10 +2277,10 @@ update_bad_spill_attribute (void)
            }
        }
     }
-  for (i = 0; i < ira_reg_class_cover_size; i++)
+  for (i = 0; i < ira_allocno_classes_num; i++)
     {
-      cover_class = ira_reg_class_cover[i];
-      bitmap_clear (&dead_points[cover_class]);
+      aclass = ira_allocno_classes[i];
+      bitmap_clear (&dead_points[aclass]);
     }
 }
 
@@ -2290,6 +2303,7 @@ setup_min_max_allocno_live_range_point (void)
   FOR_EACH_ALLOCNO (a, ai)
     {
       int n = ALLOCNO_NUM_OBJECTS (a);
+
       for (i = 0; i < n; i++)
        {
          ira_object_t obj = ALLOCNO_OBJECT (a, i);
@@ -2309,6 +2323,7 @@ setup_min_max_allocno_live_range_point (void)
       {
        int j;
        int n = ALLOCNO_NUM_OBJECTS (a);
+
        for (j = 0; j < n; j++)
          {
            ira_object_t obj = ALLOCNO_OBJECT (a, j);
@@ -2352,10 +2367,10 @@ setup_min_max_allocno_live_range_point (void)
 }
 
 /* Sort allocnos according to their live ranges.  Allocnos with
-   smaller cover class are put first unless we use priority coloring.
-   Allocnos with the same cover class are ordered according their start
-   (min).  Allocnos with the same start are ordered according their
-   finish (max).  */
+   smaller allocno class are put first unless we use priority
+   coloring.  Allocnos with the same class are ordered according
+   their start (min).  Allocnos with the same start are ordered
+   according their finish (max).  */
 static int
 object_range_compare_func (const void *v1p, const void *v2p)
 {
@@ -2365,9 +2380,6 @@ object_range_compare_func (const void *v1p, const void *v2p)
   ira_allocno_t a1 = OBJECT_ALLOCNO (obj1);
   ira_allocno_t a2 = OBJECT_ALLOCNO (obj2);
 
-  if (flag_ira_algorithm != IRA_ALGORITHM_PRIORITY
-      && (diff = ALLOCNO_COVER_CLASS (a1) - ALLOCNO_COVER_CLASS (a2)) != 0)
-    return diff;
   if ((diff = OBJECT_MIN (obj1) - OBJECT_MIN (obj2)) != 0)
     return diff;
   if ((diff = OBJECT_MAX (obj1) - OBJECT_MAX (obj2)) != 0)
@@ -2397,6 +2409,7 @@ sort_conflict_id_map (void)
   for (i = 0; i < num; i++)
     {
       ira_object_t obj = ira_object_id_map[i];
+
       gcc_assert (obj != NULL);
       OBJECT_CONFLICT_ID (obj) = i;
     }
@@ -2409,7 +2422,7 @@ sort_conflict_id_map (void)
 static void
 setup_min_max_conflict_allocno_ids (void)
 {
-  int cover_class;
+  int aclass;
   int i, j, min, max, start, finish, first_not_finished, filled_area_start;
   int *live_range_min, *last_lived;
   int word0_min, word0_max;
@@ -2417,21 +2430,20 @@ setup_min_max_conflict_allocno_ids (void)
   ira_allocno_iterator ai;
 
   live_range_min = (int *) ira_allocate (sizeof (int) * ira_objects_num);
-  cover_class = -1;
+  aclass = -1;
   first_not_finished = -1;
   for (i = 0; i < ira_objects_num; i++)
     {
       ira_object_t obj = ira_object_id_map[i];
+
       if (obj == NULL)
        continue;
 
       a = OBJECT_ALLOCNO (obj);
 
-      if (cover_class < 0
-         || (flag_ira_algorithm != IRA_ALGORITHM_PRIORITY
-             && cover_class != (int) ALLOCNO_COVER_CLASS (a)))
+      if (aclass < 0)
        {
-         cover_class = ALLOCNO_COVER_CLASS (a);
+         aclass = ALLOCNO_CLASS (a);
          min = i;
          first_not_finished = i;
        }
@@ -2456,20 +2468,19 @@ setup_min_max_conflict_allocno_ids (void)
       OBJECT_MIN (obj) = min;
     }
   last_lived = (int *) ira_allocate (sizeof (int) * ira_max_point);
-  cover_class = -1;
+  aclass = -1;
   filled_area_start = -1;
   for (i = ira_objects_num - 1; i >= 0; i--)
     {
       ira_object_t obj = ira_object_id_map[i];
+
       if (obj == NULL)
        continue;
 
       a = OBJECT_ALLOCNO (obj);
-      if (cover_class < 0
-         || (flag_ira_algorithm != IRA_ALGORITHM_PRIORITY
-             && cover_class != (int) ALLOCNO_COVER_CLASS (a)))
+      if (aclass < 0)
        {
-         cover_class = ALLOCNO_COVER_CLASS (a);
+         aclass = ALLOCNO_CLASS (a);
          for (j = 0; j < ira_max_point; j++)
            last_lived[j] = -1;
          filled_area_start = ira_max_point;
@@ -2507,6 +2518,7 @@ setup_min_max_conflict_allocno_ids (void)
     {
       int n = ALLOCNO_NUM_OBJECTS (a);
       ira_object_t obj0;
+
       if (n < 2)
        continue;
       obj0 = ALLOCNO_OBJECT (a, 0);
@@ -2519,6 +2531,7 @@ setup_min_max_conflict_allocno_ids (void)
     {
       int n = ALLOCNO_NUM_OBJECTS (a);
       ira_object_t obj0;
+
       if (n < 2)
        continue;
       obj0 = ALLOCNO_OBJECT (a, 0);
@@ -2611,7 +2624,7 @@ copy_info_to_removed_store_destinations (int regno)
        a != NULL;
        a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
     {
-      if (a != regno_top_level_allocno_map[REGNO (ALLOCNO_REG (a))])
+      if (a != regno_top_level_allocno_map[REGNO (allocno_emit_reg (a))])
        /* This allocno will be removed.  */
        continue;
 
@@ -2621,9 +2634,10 @@ copy_info_to_removed_store_destinations (int regno)
           parent != NULL;
           parent = parent->parent)
        if ((parent_a = parent->regno_allocno_map[regno]) == NULL
-           || (parent_a == regno_top_level_allocno_map[REGNO (ALLOCNO_REG
-                                                              (parent_a))]
-               && ALLOCNO_MEM_OPTIMIZED_DEST_P (parent_a)))
+           || (parent_a
+               == regno_top_level_allocno_map[REGNO
+                                              (allocno_emit_reg (parent_a))]
+               && ALLOCNO_EMIT_DATA (parent_a)->mem_optimized_dest_p))
          break;
       if (parent == NULL || parent_a == NULL)
        continue;
@@ -2655,7 +2669,7 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
   int hard_regs_num;
   bool new_pseudos_p, merged_p, mem_dest_p;
   unsigned int n;
-  enum reg_class cover_class;
+  enum reg_class aclass;
   ira_allocno_t a, parent_a, first, second, node_first, node_second;
   ira_copy_t cp;
   ira_loop_tree_node_t node;
@@ -2664,7 +2678,8 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
   ira_copy_iterator ci;
 
   regno_top_level_allocno_map
-    = (ira_allocno_t *) ira_allocate (max_reg_num () * sizeof (ira_allocno_t));
+    = (ira_allocno_t *) ira_allocate (max_reg_num ()
+                                     * sizeof (ira_allocno_t));
   memset (regno_top_level_allocno_map, 0,
          max_reg_num () * sizeof (ira_allocno_t));
   new_pseudos_p = merged_p = false;
@@ -2672,6 +2687,7 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
     {
       ira_allocno_object_iterator oi;
       ira_object_t obj;
+
       if (ALLOCNO_CAP_MEMBER (a) != NULL)
        /* Caps are not in the regno allocno maps and they are never
           will be transformed into allocnos existing after IR
@@ -2692,28 +2708,31 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
           a != NULL;
           a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
        {
+         ira_emit_data_t parent_data, data = ALLOCNO_EMIT_DATA (a);
+
          ira_assert (ALLOCNO_CAP_MEMBER (a) == NULL);
-         if (ALLOCNO_SOMEWHERE_RENAMED_P (a))
+         if (data->somewhere_renamed_p)
            new_pseudos_p = true;
          parent_a = ira_parent_allocno (a);
          if (parent_a == NULL)
            {
              ALLOCNO_COPIES (a) = NULL;
-             regno_top_level_allocno_map[REGNO (ALLOCNO_REG (a))] = a;
+             regno_top_level_allocno_map[REGNO (data->reg)] = a;
              continue;
            }
          ira_assert (ALLOCNO_CAP_MEMBER (parent_a) == NULL);
 
-         if (ALLOCNO_MEM_OPTIMIZED_DEST (a) != NULL)
+         if (data->mem_optimized_dest != NULL)
            mem_dest_p = true;
-         if (REGNO (ALLOCNO_REG (a)) == REGNO (ALLOCNO_REG (parent_a)))
+         parent_data = ALLOCNO_EMIT_DATA (parent_a);
+         if (REGNO (data->reg) == REGNO (parent_data->reg))
            {
              merge_hard_reg_conflicts (a, parent_a, true);
              move_allocno_live_ranges (a, parent_a);
              merged_p = true;
-             ALLOCNO_MEM_OPTIMIZED_DEST_P (parent_a)
-               = (ALLOCNO_MEM_OPTIMIZED_DEST_P (parent_a)
-                  || ALLOCNO_MEM_OPTIMIZED_DEST_P (a));
+             parent_data->mem_optimized_dest_p
+               = (parent_data->mem_optimized_dest_p
+                  || data->mem_optimized_dest_p);
              continue;
            }
          new_pseudos_p = true;
@@ -2729,8 +2748,8 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
              ira_assert (ALLOCNO_CALLS_CROSSED_NUM (parent_a) >= 0
                          && ALLOCNO_NREFS (parent_a) >= 0
                          && ALLOCNO_FREQ (parent_a) >= 0);
-             cover_class = ALLOCNO_COVER_CLASS (parent_a);
-             hard_regs_num = ira_class_hard_regs_num[cover_class];
+             aclass = ALLOCNO_CLASS (parent_a);
+             hard_regs_num = ira_class_hard_regs_num[aclass];
              if (ALLOCNO_HARD_REG_COSTS (a) != NULL
                  && ALLOCNO_HARD_REG_COSTS (parent_a) != NULL)
                for (j = 0; j < hard_regs_num; j++)
@@ -2741,15 +2760,15 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
                for (j = 0; j < hard_regs_num; j++)
                  ALLOCNO_CONFLICT_HARD_REG_COSTS (parent_a)[j]
                    -= ALLOCNO_CONFLICT_HARD_REG_COSTS (a)[j];
-             ALLOCNO_COVER_CLASS_COST (parent_a)
-               -= ALLOCNO_COVER_CLASS_COST (a);
+             ALLOCNO_CLASS_COST (parent_a)
+               -= ALLOCNO_CLASS_COST (a);
              ALLOCNO_MEMORY_COST (parent_a) -= ALLOCNO_MEMORY_COST (a);
              parent_a = ira_parent_allocno (parent_a);
              if (parent_a == NULL)
                break;
            }
          ALLOCNO_COPIES (a) = NULL;
-         regno_top_level_allocno_map[REGNO (ALLOCNO_REG (a))] = a;
+         regno_top_level_allocno_map[REGNO (data->reg)] = a;
        }
       if (mem_dest_p && copy_info_to_removed_store_destinations (i))
        merged_p = true;
@@ -2766,7 +2785,8 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
        {
          ira_allocno_object_iterator oi;
          ira_object_t obj;
-         if (a != regno_top_level_allocno_map[REGNO (ALLOCNO_REG (a))]
+
+         if (a != regno_top_level_allocno_map[REGNO (allocno_emit_reg (a))]
              || ALLOCNO_CAP_MEMBER (a) != NULL)
            continue;
          FOR_EACH_ALLOCNO_OBJECT (a, obj, oi)
@@ -2782,19 +2802,21 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
          for (r = ira_start_point_ranges[i]; r != NULL; r = r->start_next)
            {
              ira_object_t obj = r->object;
+
              a = OBJECT_ALLOCNO (obj);
-             if (a != regno_top_level_allocno_map[REGNO (ALLOCNO_REG (a))]
+             if (a != regno_top_level_allocno_map[REGNO (allocno_emit_reg (a))]
                  || ALLOCNO_CAP_MEMBER (a) != NULL)
                continue;
 
-             cover_class = ALLOCNO_COVER_CLASS (a);
+             aclass = ALLOCNO_CLASS (a);
              sparseset_set_bit (objects_live, OBJECT_CONFLICT_ID (obj));
              EXECUTE_IF_SET_IN_SPARSESET (objects_live, n)
                {
                  ira_object_t live_obj = ira_object_id_map[n];
                  ira_allocno_t live_a = OBJECT_ALLOCNO (live_obj);
-                 enum reg_class live_cover = ALLOCNO_COVER_CLASS (live_a);
-                 if (ira_reg_classes_intersect_p[cover_class][live_cover]
+                 enum reg_class live_aclass = ALLOCNO_CLASS (live_a);
+
+                 if (ira_reg_classes_intersect_p[aclass][live_aclass]
                      /* Don't set up conflict for the allocno with itself.  */
                      && live_a != a)
                    ira_add_conflict (obj, live_obj);
@@ -2818,14 +2840,18 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
            fprintf
              (ira_dump_file, "      Remove cp%d:%c%dr%d-%c%dr%d\n",
               cp->num, ALLOCNO_CAP_MEMBER (cp->first) != NULL ? 'c' : 'a',
-              ALLOCNO_NUM (cp->first), REGNO (ALLOCNO_REG (cp->first)),
+              ALLOCNO_NUM (cp->first),
+              REGNO (allocno_emit_reg (cp->first)),
               ALLOCNO_CAP_MEMBER (cp->second) != NULL ? 'c' : 'a',
-              ALLOCNO_NUM (cp->second), REGNO (ALLOCNO_REG (cp->second)));
+              ALLOCNO_NUM (cp->second),
+              REGNO (allocno_emit_reg (cp->second)));
          cp->loop_tree_node = NULL;
          continue;
        }
-      first = regno_top_level_allocno_map[REGNO (ALLOCNO_REG (cp->first))];
-      second = regno_top_level_allocno_map[REGNO (ALLOCNO_REG (cp->second))];
+      first
+       = regno_top_level_allocno_map[REGNO (allocno_emit_reg (cp->first))];
+      second
+       = regno_top_level_allocno_map[REGNO (allocno_emit_reg (cp->second))];
       node = cp->loop_tree_node;
       if (node == NULL)
        keep_p = true; /* It copy generated in ira-emit.c.  */
@@ -2835,10 +2861,10 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
             which we will have different pseudos.  */
          node_first = node->regno_allocno_map[ALLOCNO_REGNO (cp->first)];
          node_second = node->regno_allocno_map[ALLOCNO_REGNO (cp->second)];
-         keep_p = ((REGNO (ALLOCNO_REG (first))
-                    == REGNO (ALLOCNO_REG (node_first)))
-                    && (REGNO (ALLOCNO_REG (second))
-                        == REGNO (ALLOCNO_REG (node_second))));
+         keep_p = ((REGNO (allocno_emit_reg (first))
+                    == REGNO (allocno_emit_reg (node_first)))
+                    && (REGNO (allocno_emit_reg (second))
+                        == REGNO (allocno_emit_reg (node_second))));
        }
       if (keep_p)
        {
@@ -2852,28 +2878,29 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
          if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
            fprintf (ira_dump_file, "      Remove cp%d:a%dr%d-a%dr%d\n",
                     cp->num, ALLOCNO_NUM (cp->first),
-                    REGNO (ALLOCNO_REG (cp->first)), ALLOCNO_NUM (cp->second),
-                    REGNO (ALLOCNO_REG (cp->second)));
+                    REGNO (allocno_emit_reg (cp->first)),
+                    ALLOCNO_NUM (cp->second),
+                    REGNO (allocno_emit_reg (cp->second)));
        }
     }
   /* Remove unnecessary allocnos on lower levels of the loop tree.  */
   FOR_EACH_ALLOCNO (a, ai)
     {
-      if (a != regno_top_level_allocno_map[REGNO (ALLOCNO_REG (a))]
+      if (a != regno_top_level_allocno_map[REGNO (allocno_emit_reg (a))]
          || ALLOCNO_CAP_MEMBER (a) != NULL)
        {
          if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
            fprintf (ira_dump_file, "      Remove a%dr%d\n",
-                    ALLOCNO_NUM (a), REGNO (ALLOCNO_REG (a)));
+                    ALLOCNO_NUM (a), REGNO (allocno_emit_reg (a)));
          finish_allocno (a);
          continue;
        }
       ALLOCNO_LOOP_TREE_NODE (a) = ira_loop_tree_root;
-      ALLOCNO_REGNO (a) = REGNO (ALLOCNO_REG (a));
+      ALLOCNO_REGNO (a) = REGNO (allocno_emit_reg (a));
       ALLOCNO_CAP (a) = NULL;
       /* Restore updated costs for assignments from reload.  */
       ALLOCNO_UPDATED_MEMORY_COST (a) = ALLOCNO_MEMORY_COST (a);
-      ALLOCNO_UPDATED_COVER_CLASS_COST (a) = ALLOCNO_COVER_CLASS_COST (a);
+      ALLOCNO_UPDATED_CLASS_COST (a) = ALLOCNO_CLASS_COST (a);
       if (! ALLOCNO_ASSIGNED_P (a))
        ira_free_allocno_updated_costs (a);
       ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
@@ -2942,29 +2969,28 @@ update_conflict_hard_reg_costs (void)
 
   FOR_EACH_ALLOCNO (a, ai)
     {
-      enum reg_class cover_class = ALLOCNO_COVER_CLASS (a);
+      enum reg_class aclass = ALLOCNO_CLASS (a);
       enum reg_class pref = reg_preferred_class (ALLOCNO_REGNO (a));
 
       if (reg_class_size[pref] != 1)
        continue;
-      index = (ira_class_hard_reg_index[cover_class]
-              [ira_class_hard_regs[pref][0]]);
+      index = ira_class_hard_reg_index[aclass][ira_class_hard_regs[pref][0]];
       if (index < 0)
        continue;
       if (ALLOCNO_CONFLICT_HARD_REG_COSTS (a) == NULL
          || ALLOCNO_HARD_REG_COSTS (a) == NULL)
        continue;
       min = INT_MAX;
-      for (i = ira_class_hard_regs_num[cover_class] - 1; i >= 0; i--)
-       if (ALLOCNO_HARD_REG_COSTS (a)[i] > ALLOCNO_COVER_CLASS_COST (a)
+      for (i = ira_class_hard_regs_num[aclass] - 1; i >= 0; i--)
+       if (ALLOCNO_HARD_REG_COSTS (a)[i] > ALLOCNO_CLASS_COST (a)
            && min > ALLOCNO_HARD_REG_COSTS (a)[i])
          min = ALLOCNO_HARD_REG_COSTS (a)[i];
       if (min == INT_MAX)
        continue;
       ira_allocate_and_set_costs (&ALLOCNO_CONFLICT_HARD_REG_COSTS (a),
-                                 cover_class, 0);
+                                 aclass, 0);
       ALLOCNO_CONFLICT_HARD_REG_COSTS (a)[index]
-       -= min - ALLOCNO_COVER_CLASS_COST (a);
+       -= min - ALLOCNO_CLASS_COST (a);
     }
 }
 
@@ -3000,7 +3026,7 @@ ira_build (bool loops_p)
       propagate_allocno_info ();
       create_caps ();
     }
-  ira_tune_allocno_costs_and_cover_classes ();
+  ira_tune_allocno_costs ();
 #ifdef ENABLE_IRA_CHECKING
   check_allocno_creation ();
 #endif
@@ -3042,6 +3068,7 @@ ira_build (bool loops_p)
       FOR_EACH_ALLOCNO (a, ai)
        {
          int j, nobj = ALLOCNO_NUM_OBJECTS (a);
+
          if (nobj > 1)
            nr_big++;
          for (j = 0; j < nobj; j++)
index 6024f7d..f7ac594 100644 (file)
@@ -1,5 +1,5 @@
 /* IRA allocation based on graph coloring.
-   Copyright (C) 2006, 2007, 2008, 2009, 2010
+   Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
    Contributed by Vladimir Makarov <vmakarov@redhat.com>.
 
@@ -37,9 +37,119 @@ along with GCC; see the file COPYING3.  If not see
 #include "reload.h"
 #include "params.h"
 #include "df.h"
-#include "splay-tree.h"
 #include "ira-int.h"
 
+typedef struct object_hard_regs *object_hard_regs_t;
+
+/* The structure contains information about hard registers can be
+   assigned to objects.  Usually it is allocno profitable hard
+   registers but in some cases this set can be a bit different.  Major
+   reason of the difference is a requirement to use hard register sets
+   that form a tree or a forest (set of trees), i.e. hard register set
+   of a node should contain hard register sets of its subnodes.  */
+struct object_hard_regs
+{
+  /* Hard registers can be assigned to an allocno.  */
+  HARD_REG_SET set;
+  /* Overall (spilling) cost of all allocnos with given register
+     set.  */
+  long long int cost;
+};
+
+typedef struct object_hard_regs_node *object_hard_regs_node_t;
+
+/* A node representing object hard registers.  Such nodes form a
+   forest (set of trees).  Each subnode of given node in the forest
+   refers for hard register set (usually object profitable hard
+   register set) which is a subset of one referred from given
+   node.  */
+struct object_hard_regs_node
+{
+  /* Set up number of the node in preorder traversing of the forest.  */
+  int preorder_num;
+  /* Used for different calculation like finding conflict size of an
+     allocno.  */
+  int check;
+  /* Used for calculation of conflict size of an allocno.  The
+     conflict size of the allocno is maximal number of given object
+     hard registers needed for allocation of the conflicting allocnos.
+     Given allocno is trivially colored if this number plus the number
+     of hard registers needed for given allocno is not greater than
+     the number of given allocno hard register set.  */
+  int conflict_size;
+  /* The number of hard registers given by member hard_regs.  */
+  int hard_regs_num;
+  /* The following member is used to form the final forest.  */
+  bool used_p;
+  /* Pointer to the corresponding profitable hard registers.  */
+  object_hard_regs_t hard_regs;
+  /* Parent, first subnode, previous and next node with the same
+     parent in the forest.  */
+  object_hard_regs_node_t parent, first, prev, next;
+};
+
+/* To decrease footprint of ira_allocno structure we store all data
+   needed only for coloring in the following structure.  */
+struct allocno_color_data
+{
+  /* TRUE value means that the allocno was not removed yet from the
+     conflicting graph during colouring.  */
+  unsigned int in_graph_p : 1;
+  /* TRUE if it is put on the stack to make other allocnos
+     colorable.  */
+  unsigned int may_be_spilled_p : 1;
+  /* TRUE if the object is trivially colorable.  */
+  unsigned int colorable_p : 1;
+  /* Number of hard registers of the allocno class really
+     available for the allocno allocation.  It is number of the
+     profitable hard regs.  */
+  int available_regs_num;
+  /* Allocnos in a bucket (used in coloring) chained by the following
+     two members.  */
+  ira_allocno_t next_bucket_allocno;
+  ira_allocno_t prev_bucket_allocno;
+  /* Used for temporary purposes.  */
+  int temp;
+};
+
+/* See above.  */
+typedef struct allocno_color_data *allocno_color_data_t;
+
+/* Container for storing allocno data concerning coloring.  */
+static allocno_color_data_t allocno_color_data;
+
+/* Macro to access the data concerning coloring.  */
+#define ALLOCNO_COLOR_DATA(a) ((allocno_color_data_t) ALLOCNO_ADD_DATA (a))
+
+/* To decrease footprint of ira_object structure we store all data
+   needed only for coloring in the following structure.  */
+struct object_color_data
+{
+  /* Profitable hard regs available for this pseudo allocation.  It
+     means that the set excludes unavailable hard regs and hard regs
+     conflicting with given pseudo.  They should be of the allocno
+     class.  */
+  HARD_REG_SET profitable_hard_regs;
+  /* The object hard registers node.  */
+  object_hard_regs_node_t hard_regs_node;
+  /* Array of structures object_hard_regs_subnode representing
+     given object hard registers node (the 1st element in the array)
+     and all its subnodes in the tree (forest) of object hard
+     register nodes (see comments above).  */
+  int hard_regs_subnodes_start;
+  /* The length of the previous array. */
+  int hard_regs_subnodes_num;
+};
+
+/* See above.  */
+typedef struct object_color_data *object_color_data_t;
+
+/* Container for storing object data concerning coloring.  */
+static object_color_data_t object_color_data;
+
+/* Macro to access the data concerning coloring.  */
+#define OBJECT_COLOR_DATA(o) ((object_color_data_t) OBJECT_ADD_DATA (o))
+
 /* This file contains code for regional graph coloring, spill/restore
    code placement optimization, and code helping the reload pass to do
    a better job.  */
@@ -59,20 +169,6 @@ static ira_allocno_t *sorted_allocnos;
 /* Vec representing the stack of allocnos used during coloring.  */
 static VEC(ira_allocno_t,heap) *allocno_stack_vec;
 
-/* Array used to choose an allocno for spilling.  */
-static ira_allocno_t *allocnos_for_spilling;
-
-/* Pool for splay tree nodes.  */
-static alloc_pool splay_tree_node_pool;
-
-/* When an allocno is removed from the splay tree, it is put in the
-   following vector for subsequent inserting it into the splay tree
-   after putting all colorable allocnos onto the stack.  The allocno
-   could be removed from and inserted to the splay tree every time
-   when its spilling priority is changed but such solution would be
-   more costly although simpler.  */
-static VEC(ira_allocno_t,heap) *removed_splay_allocno_vec;
-
 /* Helper for qsort comparison callbacks - return a positive integer if
    X > Y, or a negative value otherwise.  Use a conditional expression
    instead of a difference computation to insulate from possible overflow
@@ -81,61 +177,1004 @@ static VEC(ira_allocno_t,heap) *removed_splay_allocno_vec;
 
 \f
 
-/* This page contains functions used to find conflicts using allocno
-   live ranges.  */
+/* Definition of vector of object hard registers.  */
+DEF_VEC_P(object_hard_regs_t);
+DEF_VEC_ALLOC_P(object_hard_regs_t, heap);
 
-/* Return TRUE if live ranges of allocnos A1 and A2 intersect.  It is
-   used to find a conflict for new allocnos or allocnos with the
-   different cover classes.  */
+/* Vector of unique object hard registers.  */
+static VEC(object_hard_regs_t, heap) *object_hard_regs_vec;
+
+/* Returns hash value for object hard registers V.  */
+static hashval_t
+object_hard_regs_hash (const void *v)
+{
+  const struct object_hard_regs *hv = (const struct object_hard_regs *) v;
+
+  return iterative_hash (&hv->set, sizeof (HARD_REG_SET), 0);
+}
+
+/* Compares object hard registers V1 and V2.  */
+static int
+object_hard_regs_eq (const void *v1, const void *v2)
+{
+  const struct object_hard_regs *hv1 = (const struct object_hard_regs *) v1;
+  const struct object_hard_regs *hv2 = (const struct object_hard_regs *) v2;
+
+  return hard_reg_set_equal_p (hv1->set, hv2->set);
+}
+
+/* Hash table of unique object hard registers.  */
+static htab_t object_hard_regs_htab;
+
+/* Return object hard registers in the hash table equal to HV.  */
+static object_hard_regs_t
+find_hard_regs (object_hard_regs_t hv)
+{
+  return (object_hard_regs_t) htab_find (object_hard_regs_htab, hv);
+}
+
+/* Insert allocno hard registers HV in the hash table (if it is not
+   there yet) and return the value which in the table.  */
+static object_hard_regs_t
+insert_hard_regs (object_hard_regs_t hv)
+{
+  PTR *slot = htab_find_slot (object_hard_regs_htab, hv, INSERT);
+
+  if (*slot == NULL)
+    *slot = hv;
+  return (object_hard_regs_t) *slot;
+}
+
+/* Initialize data concerning object hard registers.  */
+static void
+init_object_hard_regs (void)
+{
+  object_hard_regs_vec = VEC_alloc (object_hard_regs_t, heap, 200);
+  object_hard_regs_htab
+    = htab_create (200, object_hard_regs_hash, object_hard_regs_eq, NULL);
+}
+
+/* Add (or update info about) object hard registers with SET and
+   COST.  */
+static object_hard_regs_t
+add_object_hard_regs (HARD_REG_SET set, long long int cost)
+{
+  struct object_hard_regs temp;
+  object_hard_regs_t hv;
+
+  gcc_assert (! hard_reg_set_empty_p (set));
+  COPY_HARD_REG_SET (temp.set, set);
+  if ((hv = find_hard_regs (&temp)) != NULL)
+    hv->cost += cost;
+  else
+    {
+      hv = ((struct object_hard_regs *)
+           ira_allocate (sizeof (struct object_hard_regs)));
+      COPY_HARD_REG_SET (hv->set, set);
+      hv->cost = cost;
+      VEC_safe_push (object_hard_regs_t, heap, object_hard_regs_vec, hv);
+      insert_hard_regs (hv);
+    }
+  return hv;
+}
+
+/* Finalize data concerning allocno hard registers.  */
+static void
+finish_object_hard_regs (void)
+{
+  int i;
+  object_hard_regs_t hv;
+
+  for (i = 0;
+       VEC_iterate (object_hard_regs_t, object_hard_regs_vec, i, hv);
+       i++)
+    ira_free (hv);
+  htab_delete (object_hard_regs_htab);
+  VEC_free (object_hard_regs_t, heap, object_hard_regs_vec);
+}
+
+/* Sort hard regs according to their frequency of usage. */
+static int
+object_hard_regs_compare (const void *v1p, const void *v2p)
+{
+  object_hard_regs_t hv1 = *(const object_hard_regs_t *) v1p;
+  object_hard_regs_t hv2 = *(const object_hard_regs_t *) v2p;
+
+  if (hv2->cost > hv1->cost)
+    return 1;
+  else if (hv2->cost < hv1->cost)
+    return -1;
+  else
+    return 0;
+}
+
+\f
+
+/* Used for finding a common ancestor of two allocno hard registers
+   nodes in the forest.  We use the current value of
+   'node_check_tick' to mark all nodes from one node to the top and
+   then walking up from another node until we find a marked node.
+
+   It is also used to figure out allocno colorability as a mark that
+   we already reset value of member 'conflict_size' for the forest
+   node corresponding to the processed allocno.  */
+static int node_check_tick;
+
+/* Roots of the forest containing hard register sets can be assigned
+   to objects.  */
+static object_hard_regs_node_t hard_regs_roots;
+
+/* Definition of vector of object hard register nodes.  */
+DEF_VEC_P(object_hard_regs_node_t);
+DEF_VEC_ALLOC_P(object_hard_regs_node_t, heap);
+
+/* Vector used to create the forest.  */
+static VEC(object_hard_regs_node_t, heap) *hard_regs_node_vec;
+
+/* Create and return object hard registers node containing object
+   hard registers HV.  */
+static object_hard_regs_node_t
+create_new_object_hard_regs_node (object_hard_regs_t hv)
+{
+  object_hard_regs_node_t new_node;
+
+  new_node = ((struct object_hard_regs_node *)
+             ira_allocate (sizeof (struct object_hard_regs_node)));
+  new_node->check = 0;
+  new_node->hard_regs = hv;
+  new_node->hard_regs_num = hard_reg_set_size (hv->set);
+  new_node->first = NULL;
+  new_node->used_p = false;
+  return new_node;
+}
+
+/* Add object hard registers node NEW_NODE to the forest on its level
+   given by ROOTS.  */
+static void
+add_new_object_hard_regs_node_to_forest (object_hard_regs_node_t *roots,
+                                         object_hard_regs_node_t new_node)
+{
+  new_node->next = *roots;
+  if (new_node->next != NULL)
+    new_node->next->prev = new_node;
+  new_node->prev = NULL;
+  *roots = new_node;
+}
+
+/* Add object hard registers HV (or its best approximation if it is
+   not possible) to the forest on its level given by ROOTS.  */
+static void
+add_object_hard_regs_to_forest (object_hard_regs_node_t *roots,
+                               object_hard_regs_t hv)
+{
+  unsigned int i, start;
+  object_hard_regs_node_t node, prev, new_node;
+  HARD_REG_SET temp_set;
+  object_hard_regs_t hv2;
+
+  start = VEC_length (object_hard_regs_node_t, hard_regs_node_vec);
+  for (node = *roots; node != NULL; node = node->next)
+    {
+      if (hard_reg_set_equal_p (hv->set, node->hard_regs->set))
+       return;
+      if (hard_reg_set_subset_p (hv->set, node->hard_regs->set))
+       {
+         add_object_hard_regs_to_forest (&node->first, hv);
+         return;
+       }
+      if (hard_reg_set_subset_p (node->hard_regs->set, hv->set))
+       VEC_safe_push (object_hard_regs_node_t, heap,
+                      hard_regs_node_vec, node);
+      else if (hard_reg_set_intersect_p (hv->set, node->hard_regs->set))
+       {
+         COPY_HARD_REG_SET (temp_set, hv->set);
+         AND_HARD_REG_SET (temp_set, node->hard_regs->set);
+         hv2 = add_object_hard_regs (temp_set, hv->cost);
+         add_object_hard_regs_to_forest (&node->first, hv2);
+       }
+    }
+  if (VEC_length (object_hard_regs_node_t, hard_regs_node_vec)
+      > start + 1)
+    {
+      /* Create a new node which contains nodes in hard_regs_node_vec.  */
+      CLEAR_HARD_REG_SET (temp_set);
+      for (i = start;
+          i < VEC_length (object_hard_regs_node_t, hard_regs_node_vec);
+          i++)
+       {
+         node = VEC_index (object_hard_regs_node_t, hard_regs_node_vec, i);
+         IOR_HARD_REG_SET (temp_set, node->hard_regs->set);
+       }
+      hv = add_object_hard_regs (temp_set, hv->cost);
+      new_node = create_new_object_hard_regs_node (hv);
+      prev = NULL;
+      for (i = start;
+          i < VEC_length (object_hard_regs_node_t, hard_regs_node_vec);
+          i++)
+       {
+         node = VEC_index (object_hard_regs_node_t, hard_regs_node_vec, i);
+         if (node->prev == NULL)
+           *roots = node->next;
+         else
+           node->prev->next = node->next;
+         if (node->next != NULL)
+           node->next->prev = node->prev;
+         if (prev == NULL)
+           new_node->first = node;
+         else
+           prev->next = node;
+         node->prev = prev;
+         node->next = NULL;
+         prev = node;
+       }
+      add_new_object_hard_regs_node_to_forest (roots, new_node);
+    }
+  VEC_truncate (object_hard_regs_node_t, hard_regs_node_vec, start);
+}
+
+/* Add object hard registers nodes starting with the forest level
+   given by FIRST which contains biggest set inside SET.  */
+static void
+collect_object_hard_regs_cover (object_hard_regs_node_t first,
+                                HARD_REG_SET set)
+{
+  object_hard_regs_node_t node;
+
+  ira_assert (first != NULL);
+  for (node = first; node != NULL; node = node->next)
+    if (hard_reg_set_subset_p (node->hard_regs->set, set))
+      VEC_safe_push (object_hard_regs_node_t, heap, hard_regs_node_vec,
+                    node);
+    else if (hard_reg_set_intersect_p (set, node->hard_regs->set))
+      collect_object_hard_regs_cover (node->first, set);
+}
+
+/* Set up field parent as PARENT in all object hard registers nodes
+   in forest given by FIRST.  */
+static void
+setup_object_hard_regs_nodes_parent (object_hard_regs_node_t first,
+                                    object_hard_regs_node_t parent)
+{
+  object_hard_regs_node_t node;
+
+  for (node = first; node != NULL; node = node->next)
+    {
+      node->parent = parent;
+      setup_object_hard_regs_nodes_parent (node->first, node);
+    }
+}
+
+/* Return object hard registers node which is a first common ancestor
+   node of FIRST and SECOND in the forest.  */
+static object_hard_regs_node_t
+first_common_ancestor_node (object_hard_regs_node_t first,
+                           object_hard_regs_node_t second)
+{
+  object_hard_regs_node_t node;
+
+  node_check_tick++;
+  for (node = first; node != NULL; node = node->parent)
+    node->check = node_check_tick;
+  for (node = second; node != NULL; node = node->parent)
+    if (node->check == node_check_tick)
+      return node;
+  return first_common_ancestor_node (second, first);
+}
+
+/* Print hard reg set SET to F.  */
+static void
+print_hard_reg_set (FILE *f, HARD_REG_SET set, bool new_line_p)
+{
+  int i, start;
+
+  for (start = -1, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+    {
+      if (TEST_HARD_REG_BIT (set, i))
+       {
+         if (i == 0 || ! TEST_HARD_REG_BIT (set, i - 1))
+           start = i;
+       }
+      if (start >= 0
+         && (i == FIRST_PSEUDO_REGISTER - 1 || ! TEST_HARD_REG_BIT (set, i)))
+       {
+         if (start == i - 1)
+           fprintf (f, " %d", start);
+         else if (start == i - 2)
+           fprintf (f, " %d %d", start, start + 1);
+         else
+           fprintf (f, " %d-%d", start, i - 1);
+         start = -1;
+       }
+    }
+  if (new_line_p)
+    fprintf (f, "\n");
+}
+
+/* Print object hard register subforest given by ROOTS and its LEVEL
+   to F.  */
+static void
+print_hard_regs_subforest (FILE *f, object_hard_regs_node_t roots,
+                          int level)
+{
+  int i;
+  object_hard_regs_node_t node;
+
+  for (node = roots; node != NULL; node = node->next)
+    {
+      fprintf (f, "    ");
+      for (i = 0; i < level * 2; i++)
+       fprintf (f, " ");
+      fprintf (f, "%d:(", node->preorder_num);
+      print_hard_reg_set (f, node->hard_regs->set, false);
+      fprintf (f, ")@%lld\n", node->hard_regs->cost);
+      print_hard_regs_subforest (f, node->first, level + 1);
+    }
+}
+
+/* Print the object hard register forest to F.  */
+static void
+print_hard_regs_forest (FILE *f)
+{
+  fprintf (f, "    Hard reg set forest:\n");
+  print_hard_regs_subforest (f, hard_regs_roots, 1);
+}
+
+/* Print the object hard register forest to stderr.  */
+void
+ira_debug_hard_regs_forest (void)
+{
+  print_hard_regs_forest (stderr);
+}
+
+/* Remove unused object hard registers nodes from forest given by its
+   *ROOTS.  */
+static void
+remove_unused_object_hard_regs_nodes (object_hard_regs_node_t *roots)
+{
+  object_hard_regs_node_t node, prev, next, last;
+
+  for (prev = NULL, node = *roots; node != NULL; node = next)
+    {
+      next = node->next;
+      if (node->used_p)
+       {
+         remove_unused_object_hard_regs_nodes (&node->first);
+         prev = node;
+       }
+      else
+       {
+         for (last = node->first;
+              last != NULL && last->next != NULL;
+              last = last->next)
+           ;
+         if (last != NULL)
+           {
+             if (prev == NULL)
+               *roots = node->first;
+             else 
+               prev->next = node->first;
+             if (next != NULL)
+               next->prev = last;
+             last->next = next;
+             next = node->first;
+           }
+         else
+           {
+             if (prev == NULL)
+               *roots = next;
+             else
+               prev->next = next;
+             if (next != NULL)
+               next->prev = prev;
+           }
+         ira_free (node);
+       }
+    }
+}
+
+/* Set up fields preorder_num starting with START_NUM in all object
+   hard registers nodes in forest given by FIRST.  Return biggest set
+   PREORDER_NUM increased by 1.  */
+static int
+enumerate_object_hard_regs_nodes (object_hard_regs_node_t first,
+                                 object_hard_regs_node_t parent,
+                                 int start_num)
+{
+  object_hard_regs_node_t node;
+
+  for (node = first; node != NULL; node = node->next)
+    {
+      node->preorder_num = start_num++;
+      node->parent = parent;
+      start_num        = enumerate_object_hard_regs_nodes (node->first, node,
+                                                   start_num);
+    }
+  return start_num;
+}
+
+/* Number of object hard registers nodes in the forest.  */
+static int object_hard_regs_nodes_num;
+
+/* Table preorder number of object hard registers node in the forest
+   -> the object hard registers node.  */
+static object_hard_regs_node_t *object_hard_regs_nodes;
+
+/* See below.  */
+typedef struct object_hard_regs_subnode *object_hard_regs_subnode_t;
+
+/* The structure is used to describes all subnodes (not only immediate
+   ones) in the mentioned above tree for given object hard register
+   node.  The usage of such data accelerates calculation of
+   colorability of given allocno.  */
+struct object_hard_regs_subnode
+{
+  /* The conflict size of conflicting allocnos whose hard register
+     sets are equal sets (plus supersets if given node is given
+     object hard registers node) of one in the given node.  */
+  int left_conflict_size;
+  /* The summary conflict size of conflicting allocnos whose hard
+     register sets are strict subsets of one in the given node.
+     Overall conflict size is
+     left_conflict_subnodes_size
+       + MIN (max_node_impact - left_conflict_subnodes_size,
+              left_conflict_size)
+  */
+  short left_conflict_subnodes_size;
+  short max_node_impact;
+};
+
+/* Container for hard regs subnodes of all objects.  */
+static object_hard_regs_subnode_t object_hard_regs_subnodes;
+
+/* Table (preorder number of object hard registers node in the
+   forest, preorder number of object hard registers subnode) -> index
+   of the subnode relative to the node.  -1 if it is not a
+   subnode.  */
+static int *object_hard_regs_subnode_index;
+
+/* Setup arrays OBJECT_HARD_REGS_NODES and
+   OBJECT_HARD_REGS_SUBNODE_INDEX.  */
+static void
+setup_object_hard_regs_subnode_index (object_hard_regs_node_t first)
+{
+  object_hard_regs_node_t node, parent;
+  int index;
+
+  for (node = first; node != NULL; node = node->next)
+    {
+      object_hard_regs_nodes[node->preorder_num] = node;
+      for (parent = node; parent != NULL; parent = parent->parent)
+       {
+         index = parent->preorder_num * object_hard_regs_nodes_num;
+         object_hard_regs_subnode_index[index + node->preorder_num]
+           = node->preorder_num - parent->preorder_num;
+       }
+      setup_object_hard_regs_subnode_index (node->first);
+    }
+}
+
+/* Count all object hard registers nodes in tree ROOT.  */
+static int
+get_object_hard_regs_subnodes_num (object_hard_regs_node_t root)
+{
+  int len = 1;
+
+  for (root = root->first; root != NULL; root = root->next)
+    len += get_object_hard_regs_subnodes_num (root);
+  return len;
+}
+
+/* Build the forest of object hard registers nodes and assign each
+   allocno a node from the forest.  */
+static void
+form_object_hard_regs_nodes_forest (void)
+{
+  unsigned int i, j, size, len;
+  int start, k;
+  ira_allocno_t a;
+  object_hard_regs_t hv;
+  bitmap_iterator bi;
+  HARD_REG_SET temp;
+  object_hard_regs_node_t node, object_hard_regs_node;
+
+  node_check_tick = 0;
+  init_object_hard_regs ();
+  hard_regs_roots = NULL;
+  hard_regs_node_vec = VEC_alloc (object_hard_regs_node_t, heap, 100);
+  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+    if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, i))
+      {
+       CLEAR_HARD_REG_SET (temp);
+       SET_HARD_REG_BIT (temp, i);
+       hv = add_object_hard_regs (temp, 0);
+       node = create_new_object_hard_regs_node (hv);
+       add_new_object_hard_regs_node_to_forest (&hard_regs_roots, node);
+      }
+  start = VEC_length (object_hard_regs_t, object_hard_regs_vec);
+  EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
+    {
+      a = ira_allocnos[i];
+      for (k = 0; k < ALLOCNO_NUM_OBJECTS (a); k++)
+       {
+         ira_object_t obj = ALLOCNO_OBJECT (a, k);
+         object_color_data_t obj_data = OBJECT_COLOR_DATA (obj);
+
+         if (hard_reg_set_empty_p (obj_data->profitable_hard_regs))
+           continue;
+         hv = (add_object_hard_regs
+               (obj_data->profitable_hard_regs,
+                ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a)));
+       }
+    }
+  SET_HARD_REG_SET (temp);
+  AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs);
+  add_object_hard_regs (temp, 0);
+  qsort (VEC_address (object_hard_regs_t, object_hard_regs_vec) + start,
+        VEC_length (object_hard_regs_t, object_hard_regs_vec) - start,
+        sizeof (object_hard_regs_t), object_hard_regs_compare);
+  for (i = start;
+       VEC_iterate (object_hard_regs_t, object_hard_regs_vec, i, hv);
+       i++)
+    {
+      add_object_hard_regs_to_forest (&hard_regs_roots, hv);
+      ira_assert (VEC_length (object_hard_regs_node_t,
+                             hard_regs_node_vec) == 0);
+    }
+  /* We need to set up parent fields for right work of
+     first_common_ancestor_node. */
+  setup_object_hard_regs_nodes_parent (hard_regs_roots, NULL);
+  EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
+    {
+      a = ira_allocnos[i];
+      for (k = 0; k < ALLOCNO_NUM_OBJECTS (a); k++)
+       {
+         ira_object_t obj = ALLOCNO_OBJECT (a, k);
+         object_color_data_t obj_data = OBJECT_COLOR_DATA (obj);
+         
+         if (hard_reg_set_empty_p (obj_data->profitable_hard_regs))
+           continue;
+         VEC_truncate (object_hard_regs_node_t, hard_regs_node_vec, 0);
+         collect_object_hard_regs_cover (hard_regs_roots,
+                                         obj_data->profitable_hard_regs);
+         object_hard_regs_node = NULL;
+         for (j = 0;
+              VEC_iterate (object_hard_regs_node_t, hard_regs_node_vec,
+                           j, node);
+              j++)
+           object_hard_regs_node
+             = (j == 0
+                ? node
+                : first_common_ancestor_node (node, object_hard_regs_node));
+         /* That is a temporary storage.  */
+         object_hard_regs_node->used_p = true;
+         obj_data->hard_regs_node = object_hard_regs_node;
+       }
+    }
+  ira_assert (hard_regs_roots->next == NULL);
+  hard_regs_roots->used_p = true;
+  remove_unused_object_hard_regs_nodes (&hard_regs_roots);
+  object_hard_regs_nodes_num
+    = enumerate_object_hard_regs_nodes (hard_regs_roots, NULL, 0);
+  object_hard_regs_nodes
+    = ((object_hard_regs_node_t *)
+       ira_allocate (object_hard_regs_nodes_num
+                    * sizeof (object_hard_regs_node_t)));
+  size = object_hard_regs_nodes_num * object_hard_regs_nodes_num;
+  object_hard_regs_subnode_index
+    = (int *) ira_allocate (size * sizeof (int));
+  for (i = 0; i < size; i++)
+    object_hard_regs_subnode_index[i] = -1;
+  setup_object_hard_regs_subnode_index (hard_regs_roots);
+  start = 0;
+  EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
+    {
+      a = ira_allocnos[i];
+      for (k = 0; k < ALLOCNO_NUM_OBJECTS (a); k++)
+       {
+         ira_object_t obj = ALLOCNO_OBJECT (a, k);
+         object_color_data_t obj_data = OBJECT_COLOR_DATA (obj);
+         
+         if (hard_reg_set_empty_p (obj_data->profitable_hard_regs))
+           continue;
+         len = get_object_hard_regs_subnodes_num (obj_data->hard_regs_node);
+         obj_data->hard_regs_subnodes_start = start;
+         obj_data->hard_regs_subnodes_num = len;
+         start += len;
+       }
+    }
+  object_hard_regs_subnodes
+    = ((object_hard_regs_subnode_t)
+       ira_allocate (sizeof (struct object_hard_regs_subnode) * start));
+  VEC_free (object_hard_regs_node_t, heap, hard_regs_node_vec);
+}
+
+/* Free tree of object hard registers nodes given by its ROOT.  */
+static void
+finish_object_hard_regs_nodes_tree (object_hard_regs_node_t root)
+{
+  object_hard_regs_node_t child, next;
+
+  for (child = root->first; child != NULL; child = next)
+    {
+      next = child->next;
+      finish_object_hard_regs_nodes_tree (child);
+    }
+  ira_free (root);
+}
+
+/* Finish work with the forest of object hard registers nodes.  */
+static void
+finish_object_hard_regs_nodes_forest (void)
+{
+  object_hard_regs_node_t node, next;
+  
+  ira_free (object_hard_regs_subnodes);
+  for (node = hard_regs_roots; node != NULL; node = next)
+    {
+      next = node->next;
+      finish_object_hard_regs_nodes_tree (node);
+    }
+  ira_free (object_hard_regs_nodes);
+  ira_free (object_hard_regs_subnode_index);
+  finish_object_hard_regs ();
+}
+
+/* Set up left conflict sizes and left conflict subnodes sizes of hard
+   registers subnodes of allocno A.  Return TRUE if allocno A is
+   trivially colorable.  */
 static bool
-allocnos_have_intersected_live_ranges_p (ira_allocno_t a1, ira_allocno_t a2)
+setup_left_conflict_sizes_p (ira_allocno_t a)
 {
-  int i, j;
-  int n1 = ALLOCNO_NUM_OBJECTS (a1);
-  int n2 = ALLOCNO_NUM_OBJECTS (a2);
+  int k, nobj, conflict_size;
+  allocno_color_data_t data;
 
-  if (a1 == a2)
-    return false;
-  if (ALLOCNO_REG (a1) != NULL && ALLOCNO_REG (a2) != NULL
-      && (ORIGINAL_REGNO (ALLOCNO_REG (a1))
-         == ORIGINAL_REGNO (ALLOCNO_REG (a2))))
-    return false;
+  nobj = ALLOCNO_NUM_OBJECTS (a);
+  conflict_size = 0;
+  data = ALLOCNO_COLOR_DATA (a);
+  for (k = 0; k < nobj; k++)
+    {
+      int i, node_preorder_num, start, left_conflict_subnodes_size;
+      HARD_REG_SET profitable_hard_regs;
+      object_hard_regs_subnode_t subnodes;
+      object_hard_regs_node_t node;
+      HARD_REG_SET node_set;
+      ira_object_t obj = ALLOCNO_OBJECT (a, k);
+      ira_object_t conflict_obj;
+      ira_object_conflict_iterator oci;
+      object_color_data_t obj_data;
+      
+      node_check_tick++;
+      obj_data = OBJECT_COLOR_DATA (obj);
+      subnodes = object_hard_regs_subnodes + obj_data->hard_regs_subnodes_start;
+      COPY_HARD_REG_SET (profitable_hard_regs, obj_data->profitable_hard_regs);
+      node = obj_data->hard_regs_node;
+      node_preorder_num = node->preorder_num;
+      COPY_HARD_REG_SET (node_set, node->hard_regs->set);
+      FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
+       {
+         int size;
+         ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
+         object_hard_regs_node_t conflict_node, temp_node;
+         HARD_REG_SET conflict_node_set;
+         object_color_data_t conflict_obj_data;
+
+         conflict_obj_data = OBJECT_COLOR_DATA (conflict_obj);
+         if (! ALLOCNO_COLOR_DATA (conflict_a)->in_graph_p
+             || ! hard_reg_set_intersect_p (profitable_hard_regs,
+                                            conflict_obj_data
+                                            ->profitable_hard_regs))
+           continue;
+         conflict_node = conflict_obj_data->hard_regs_node;
+         COPY_HARD_REG_SET (conflict_node_set, conflict_node->hard_regs->set);
+         if (hard_reg_set_subset_p (node_set, conflict_node_set))
+           temp_node = node;
+         else
+           {
+             ira_assert (hard_reg_set_subset_p (conflict_node_set, node_set));
+             temp_node = conflict_node;
+           }
+         if (temp_node->check != node_check_tick)
+           {
+             temp_node->check = node_check_tick;
+             temp_node->conflict_size = 0;
+           }
+         size = (ira_reg_class_max_nregs
+                 [ALLOCNO_CLASS (conflict_a)][ALLOCNO_MODE (conflict_a)]);
+         if (ALLOCNO_NUM_OBJECTS (conflict_a) > 1)
+           /* We will deal with the subwords individually.  */
+           size = 1;
+         temp_node->conflict_size += size;
+       }
+      for (i = 0; i < obj_data->hard_regs_subnodes_num; i++)
+       {
+         object_hard_regs_node_t temp_node;
+
+         temp_node = object_hard_regs_nodes[i + node_preorder_num];
+         ira_assert (temp_node->preorder_num == i + node_preorder_num);
+         subnodes[i].left_conflict_size = (temp_node->check != node_check_tick
+                                           ? 0 : temp_node->conflict_size);
+         if (hard_reg_set_subset_p (temp_node->hard_regs->set,
+                                    profitable_hard_regs))
+           subnodes[i].max_node_impact = temp_node->hard_regs_num;
+         else
+           {
+             HARD_REG_SET temp_set;
+             int j, n;
+             enum reg_class aclass;
+             
+             COPY_HARD_REG_SET (temp_set, temp_node->hard_regs->set);
+             AND_HARD_REG_SET (temp_set, profitable_hard_regs);
+             aclass = ALLOCNO_CLASS (a);
+             for (n = 0, j = ira_class_hard_regs_num[aclass] - 1; j >= 0; j--)
+               if (TEST_HARD_REG_BIT (temp_set, ira_class_hard_regs[aclass][j]))
+                 n++;
+             subnodes[i].max_node_impact = n;
+           }
+         subnodes[i].left_conflict_subnodes_size = 0;
+       }
+      start = node_preorder_num * object_hard_regs_nodes_num;
+      for (i = obj_data->hard_regs_subnodes_num - 1; i >= 0; i--)
+       {
+         int size, parent_i;
+         object_hard_regs_node_t parent;
+
+         size = (subnodes[i].left_conflict_subnodes_size
+                 + MIN (subnodes[i].max_node_impact
+                        - subnodes[i].left_conflict_subnodes_size,
+                        subnodes[i].left_conflict_size));
+         parent = object_hard_regs_nodes[i + node_preorder_num]->parent;
+         if (parent == NULL)
+           continue;
+         parent_i
+           = object_hard_regs_subnode_index[start + parent->preorder_num];
+         if (parent_i < 0)
+           continue;
+         subnodes[parent_i].left_conflict_subnodes_size += size;
+       }
+      left_conflict_subnodes_size = subnodes[0].left_conflict_subnodes_size;
+      conflict_size
+       += (left_conflict_subnodes_size
+           + MIN (subnodes[0].max_node_impact - left_conflict_subnodes_size,
+                  subnodes[0].left_conflict_size));
+    }
+  conflict_size += ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)];
+  data->colorable_p = conflict_size <= data->available_regs_num;
+  return data->colorable_p;
+}
 
-  for (i = 0; i < n1; i++)
+/* Update left conflict sizes of hard registers subnodes of allocno A
+   after removing allocno containing object REMOVED_OBJ with SIZE from
+   the conflict graph.  Return TRUE if A is trivially colorable.  */
+static bool
+update_left_conflict_sizes_p (ira_allocno_t a,
+                             ira_object_t removed_obj, int size)
+{
+  int i, k, conflict_size, before_conflict_size, diff, start;
+  int node_preorder_num, parent_i;
+  object_hard_regs_node_t node, removed_node, parent;
+  object_hard_regs_subnode_t subnodes;
+  allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
+  bool colorable_p = true;
+
+  ira_assert (! data->colorable_p);
+  for (k = 0; k < ALLOCNO_NUM_OBJECTS (a); k++)
     {
-      ira_object_t c1 = ALLOCNO_OBJECT (a1, i);
-      for (j = 0; j < n2; j++)
+      ira_object_t obj = ALLOCNO_OBJECT (a, k);
+      object_color_data_t obj_data = OBJECT_COLOR_DATA (obj);
+
+      node = obj_data->hard_regs_node;
+      node_preorder_num = node->preorder_num;
+      removed_node = OBJECT_COLOR_DATA (removed_obj)->hard_regs_node;
+      if (! hard_reg_set_subset_p (removed_node->hard_regs->set,
+                                  node->hard_regs->set)
+         && ! hard_reg_set_subset_p (node->hard_regs->set,
+                                     removed_node->hard_regs->set))
+       /* It is a rare case which can happen for conflicting
+          multi-object allocnos where only one pair of objects might
+          conflict.  */
+       continue;
+      start = node_preorder_num * object_hard_regs_nodes_num;
+      i = object_hard_regs_subnode_index[start + removed_node->preorder_num];
+      if (i < 0)
+       i = 0;
+      subnodes = object_hard_regs_subnodes + obj_data->hard_regs_subnodes_start;
+      before_conflict_size
+       = (subnodes[i].left_conflict_subnodes_size
+          + MIN (subnodes[i].max_node_impact
+                 - subnodes[i].left_conflict_subnodes_size,
+                 subnodes[i].left_conflict_size));
+      subnodes[i].left_conflict_size -= size;
+      for (;;)
        {
-         ira_object_t c2 = ALLOCNO_OBJECT (a2, j);
-         if (ira_live_ranges_intersect_p (OBJECT_LIVE_RANGES (c1),
-                                          OBJECT_LIVE_RANGES (c2)))
-           return true;
+         conflict_size
+           = (subnodes[i].left_conflict_subnodes_size
+              + MIN (subnodes[i].max_node_impact
+                     - subnodes[i].left_conflict_subnodes_size,
+                     subnodes[i].left_conflict_size));
+         if ((diff = before_conflict_size - conflict_size) == 0)
+           break;
+         ira_assert (conflict_size < before_conflict_size);
+         parent = object_hard_regs_nodes[i + node_preorder_num]->parent;
+         if (parent == NULL)
+           break;
+         parent_i
+           = object_hard_regs_subnode_index[start + parent->preorder_num];
+         if (parent_i < 0)
+           break;
+         i = parent_i;
+         before_conflict_size
+           = (subnodes[i].left_conflict_subnodes_size
+              + MIN (subnodes[i].max_node_impact
+                     - subnodes[i].left_conflict_subnodes_size,
+                     subnodes[i].left_conflict_size));
+         subnodes[i].left_conflict_subnodes_size -= diff;
        }
+      if (i != 0
+         || (conflict_size 
+             + ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]
+             > data->available_regs_num))
+       {
+         colorable_p = false;
+         break;
+       }
+      }
+  if (colorable_p)
+    {
+      data->colorable_p = true;
+      return true;
     }
   return false;
 }
 
-#ifdef ENABLE_IRA_CHECKING
-
-/* Return TRUE if live ranges of pseudo-registers REGNO1 and REGNO2
-   intersect.  This should be used when there is only one region.
-   Currently this is used during reload.  */
+/* Return true if allocno A has an object with empty profitable hard
+   regs.  */
 static bool
-pseudos_have_intersected_live_ranges_p (int regno1, int regno2)
+empty_profitable_hard_regs (ira_allocno_t a)
 {
-  ira_allocno_t a1, a2;
+  int k, nobj;
 
-  ira_assert (regno1 >= FIRST_PSEUDO_REGISTER
-             && regno2 >= FIRST_PSEUDO_REGISTER);
-  /* Reg info caclulated by dataflow infrastructure can be different
-     from one calculated by regclass.  */
-  if ((a1 = ira_loop_tree_root->regno_allocno_map[regno1]) == NULL
-      || (a2 = ira_loop_tree_root->regno_allocno_map[regno2]) == NULL)
-    return false;
-  return allocnos_have_intersected_live_ranges_p (a1, a2);
+  nobj = ALLOCNO_NUM_OBJECTS (a);
+  for (k = 0; k < nobj; k++)
+    {
+      ira_object_t obj = ALLOCNO_OBJECT (a, k);
+      object_color_data_t obj_data = OBJECT_COLOR_DATA (obj);
+
+      if (hard_reg_set_empty_p (obj_data->profitable_hard_regs))
+       return true;
+    }
+  return false;
 }
 
-#endif
+/* Set up profitable hard registers for each allocno being
+   colored.  */
+static void
+setup_profitable_hard_regs (void)
+{
+  unsigned int i;
+  int j, k, nobj, hard_regno, nregs, class_size;
+  ira_allocno_t a;
+  bitmap_iterator bi;
+  enum reg_class aclass;
+  enum machine_mode mode;
+
+  EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
+    {
+      a = ira_allocnos[i];
+      if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS)
+       continue;
+      mode = ALLOCNO_MODE (a);
+      nobj = ALLOCNO_NUM_OBJECTS (a);
+      for (k = 0; k < nobj; k++)
+       {
+         ira_object_t obj = ALLOCNO_OBJECT (a, k);
+         object_color_data_t obj_data = OBJECT_COLOR_DATA (obj);
+
+         if (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL
+             && ALLOCNO_CLASS_COST (a) > ALLOCNO_MEMORY_COST (a))
+           CLEAR_HARD_REG_SET (obj_data->profitable_hard_regs);
+         else
+           {
+             COPY_HARD_REG_SET (obj_data->profitable_hard_regs,
+                                reg_class_contents[aclass]);
+             AND_COMPL_HARD_REG_SET
+               (obj_data->profitable_hard_regs,
+                ira_prohibited_class_mode_regs[aclass][mode]);
+             AND_COMPL_HARD_REG_SET (obj_data->profitable_hard_regs,
+                                     ira_no_alloc_regs);
+             AND_COMPL_HARD_REG_SET (obj_data->profitable_hard_regs,
+                                     OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
+           }
+       }
+    }
+  EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, i, bi)
+    {
+      a = ira_allocnos[i];
+      if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS
+         || ! ALLOCNO_ASSIGNED_P (a)
+         || (hard_regno = ALLOCNO_HARD_REGNO (a)) < 0)
+       continue;
+      mode = ALLOCNO_MODE (a);
+      nregs = hard_regno_nregs[hard_regno][mode];
+      nobj = ALLOCNO_NUM_OBJECTS (a);
+      for (k = 0; k < nobj; k++)
+       {
+         ira_object_t obj = ALLOCNO_OBJECT (a, k);
+         ira_object_t conflict_obj;
+         ira_object_conflict_iterator oci;
+
+         FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
+           {
+             if (nregs == nobj && nregs > 1)
+               {
+                 int num = OBJECT_SUBWORD (conflict_obj);
+                 
+                 if (WORDS_BIG_ENDIAN)
+                   CLEAR_HARD_REG_BIT
+                     (OBJECT_COLOR_DATA (conflict_obj)->profitable_hard_regs,
+                      hard_regno + nobj - num - 1);
+                 else
+                   CLEAR_HARD_REG_BIT
+                     (OBJECT_COLOR_DATA (conflict_obj)->profitable_hard_regs,
+                      hard_regno + num);
+               }
+             else
+               AND_COMPL_HARD_REG_SET
+                 (OBJECT_COLOR_DATA (conflict_obj)->profitable_hard_regs,
+                  ira_reg_mode_hard_regset[hard_regno][mode]);
+           }
+       }
+    }
+  EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
+    {
+      int min_cost = INT_MAX;
+      int *costs;
+
+      a = ira_allocnos[i];
+      if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS
+         || empty_profitable_hard_regs (a))
+       continue;
+      mode = ALLOCNO_MODE (a);
+      nobj = ALLOCNO_NUM_OBJECTS (a);
+      for (k = 0; k < nobj; k++)
+       {
+         ira_object_t obj = ALLOCNO_OBJECT (a, k);
+         object_color_data_t obj_data = OBJECT_COLOR_DATA (obj);
+
+         if ((costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a)) != NULL
+             || (costs = ALLOCNO_HARD_REG_COSTS (a)) != NULL)
+           {
+             class_size = ira_class_hard_regs_num[aclass];
+             for (j = 0; j < class_size; j++)
+               {
+                 hard_regno = ira_class_hard_regs[aclass][j];
+                 nregs = hard_regno_nregs[hard_regno][mode];
+                 if (nregs == nobj && nregs > 1)
+                   {
+                     int num = OBJECT_SUBWORD (obj);
+
+                     if (WORDS_BIG_ENDIAN)
+                       hard_regno += nobj - num - 1;
+                     else
+                       hard_regno += num;
+                   }
+                 if (! TEST_HARD_REG_BIT (obj_data->profitable_hard_regs,
+                                          hard_regno))
+                   continue;
+                 if (ALLOCNO_UPDATED_MEMORY_COST (a) < costs[j])
+                   CLEAR_HARD_REG_BIT (obj_data->profitable_hard_regs,
+                                       hard_regno);
+                 else if (min_cost > costs[j])
+                   min_cost = costs[j];
+               }
+           }
+         else if (ALLOCNO_UPDATED_MEMORY_COST (a)
+                  < ALLOCNO_UPDATED_CLASS_COST (a))
+           CLEAR_HARD_REG_SET (obj_data->profitable_hard_regs);
+       }
+      if (ALLOCNO_UPDATED_CLASS_COST (a) > min_cost)
+       ALLOCNO_UPDATED_CLASS_COST (a) = min_cost;
+    }
+}
 
 \f
 
@@ -147,7 +1186,8 @@ pseudos_have_intersected_live_ranges_p (int regno1, int regno2)
 static bool allocated_hardreg_p[FIRST_PSEUDO_REGISTER];
 
 /* Describes one element in a queue of allocnos whose costs need to be
-   updated.  Each allocno in the queue is known to have a cover class.  */
+   updated.  Each allocno in the queue is known to have an allocno
+   class.  */
 struct update_cost_queue_elem
 {
   /* This element is in the queue iff CHECK == update_cost_check.  */
@@ -210,8 +1250,8 @@ start_update_cost (void)
   update_cost_queue = NULL;
 }
 
-/* Add (ALLOCNO, DIVISOR) to the end of update_cost_queue,
-   unless ALLOCNO is already in the queue, or has no cover class.  */
+/* Add (ALLOCNO, DIVISOR) to the end of update_cost_queue, unless
+   ALLOCNO is already in the queue, or has NO_REGS class.  */
 static inline void
 queue_update_cost (ira_allocno_t allocno, int divisor)
 {
@@ -219,7 +1259,7 @@ queue_update_cost (ira_allocno_t allocno, int divisor)
 
   elem = &update_cost_queue_elems[ALLOCNO_NUM (allocno)];
   if (elem->check != update_cost_check
-      && ALLOCNO_COVER_CLASS (allocno) != NO_REGS)
+      && ALLOCNO_CLASS (allocno) != NO_REGS)
     {
       elem->check = update_cost_check;
       elem->divisor = divisor;
@@ -257,17 +1297,17 @@ update_copy_costs (ira_allocno_t allocno, bool decr_p)
 {
   int i, cost, update_cost, hard_regno, divisor;
   enum machine_mode mode;
-  enum reg_class rclass, cover_class;
+  enum reg_class rclass, aclass;
   ira_allocno_t another_allocno;
   ira_copy_t cp, next_cp;
 
   hard_regno = ALLOCNO_HARD_REGNO (allocno);
   ira_assert (hard_regno >= 0);
 
-  cover_class = ALLOCNO_COVER_CLASS (allocno);
-  if (cover_class == NO_REGS)
+  aclass = ALLOCNO_CLASS (allocno);
+  if (aclass == NO_REGS)
     return;
-  i = ira_class_hard_reg_index[cover_class][hard_regno];
+  i = ira_class_hard_reg_index[aclass][hard_regno];
   ira_assert (i >= 0);
   rclass = REGNO_REG_CLASS (hard_regno);
 
@@ -276,6 +1316,7 @@ update_copy_costs (ira_allocno_t allocno, bool decr_p)
   do
     {
       mode = ALLOCNO_MODE (allocno);
+      ira_init_register_move_cost_if_necessary (mode);
       for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp)
        {
          if (cp->first == allocno)
@@ -291,15 +1332,15 @@ update_copy_costs (ira_allocno_t allocno, bool decr_p)
          else
            gcc_unreachable ();
 
-         cover_class = ALLOCNO_COVER_CLASS (another_allocno);
-         if (! TEST_HARD_REG_BIT (reg_class_contents[cover_class],
+         aclass = ALLOCNO_CLASS (another_allocno);
+         if (! TEST_HARD_REG_BIT (reg_class_contents[aclass],
                                   hard_regno)
              || ALLOCNO_ASSIGNED_P (another_allocno))
            continue;
 
          cost = (cp->second == allocno
-                 ? ira_get_register_move_cost (mode, rclass, cover_class)
-                 : ira_get_register_move_cost (mode, cover_class, rclass));
+                 ? ira_register_move_cost[mode][rclass][aclass]
+                 : ira_register_move_cost[mode][aclass][rclass]);
          if (decr_p)
            cost = -cost;
 
@@ -308,15 +1349,15 @@ update_copy_costs (ira_allocno_t allocno, bool decr_p)
            continue;
 
          ira_allocate_and_set_or_copy_costs
-           (&ALLOCNO_UPDATED_HARD_REG_COSTS (another_allocno), cover_class,
-            ALLOCNO_UPDATED_COVER_CLASS_COST (another_allocno),
+           (&ALLOCNO_UPDATED_HARD_REG_COSTS (another_allocno), aclass,
+            ALLOCNO_UPDATED_CLASS_COST (another_allocno),
             ALLOCNO_HARD_REG_COSTS (another_allocno));
          ira_allocate_and_set_or_copy_costs
            (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno),
-            cover_class, 0,
-            ALLOCNO_CONFLICT_HARD_REG_COSTS (another_allocno));
-         i = ira_class_hard_reg_index[cover_class][hard_regno];
-         ira_assert (i >= 0);
+            aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (another_allocno));
+         i = ira_class_hard_reg_index[aclass][hard_regno];
+         if (i < 0)
+           continue;
          ALLOCNO_UPDATED_HARD_REG_COSTS (another_allocno)[i] += update_cost;
          ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno)[i]
            += update_cost;
@@ -328,18 +1369,18 @@ update_copy_costs (ira_allocno_t allocno, bool decr_p)
 }
 
 /* This function updates COSTS (decrease if DECR_P) for hard_registers
-   of COVER_CLASS by conflict costs of the unassigned allocnos
+   of ACLASS by conflict costs of the unassigned allocnos
    connected by copies with allocnos in update_cost_queue.  This
    update increases chances to remove some copies.  */
 static void
-update_conflict_hard_regno_costs (int *costs, enum reg_class cover_class,
+update_conflict_hard_regno_costs (int *costs, enum reg_class aclass,
                                  bool decr_p)
 {
   int i, cost, class_size, freq, mult, div, divisor;
   int index, hard_regno;
   int *conflict_costs;
   bool cont_p;
-  enum reg_class another_cover_class;
+  enum reg_class another_aclass;
   ira_allocno_t allocno, another_allocno;
   ira_copy_t cp, next_cp;
 
@@ -358,16 +1399,15 @@ update_conflict_hard_regno_costs (int *costs, enum reg_class cover_class,
          }
        else
          gcc_unreachable ();
-       another_cover_class = ALLOCNO_COVER_CLASS (another_allocno);
-       if (! ira_reg_classes_intersect_p[cover_class][another_cover_class]
+       another_aclass = ALLOCNO_CLASS (another_allocno);
+       if (! ira_reg_classes_intersect_p[aclass][another_aclass]
            || ALLOCNO_ASSIGNED_P (another_allocno)
-           || ALLOCNO_MAY_BE_SPILLED_P (another_allocno))
+           || ALLOCNO_COLOR_DATA (another_allocno)->may_be_spilled_p)
          continue;
-       class_size = ira_class_hard_regs_num[another_cover_class];
+       class_size = ira_class_hard_regs_num[another_aclass];
        ira_allocate_and_copy_costs
          (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno),
-          another_cover_class,
-          ALLOCNO_CONFLICT_HARD_REG_COSTS (another_allocno));
+          another_aclass, ALLOCNO_CONFLICT_HARD_REG_COSTS (another_allocno));
        conflict_costs
          = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno);
        if (conflict_costs == NULL)
@@ -382,9 +1422,9 @@ update_conflict_hard_regno_costs (int *costs, enum reg_class cover_class,
            cont_p = false;
            for (i = class_size - 1; i >= 0; i--)
              {
-               hard_regno = ira_class_hard_regs[another_cover_class][i];
+               hard_regno = ira_class_hard_regs[another_aclass][i];
                ira_assert (hard_regno >= 0);
-               index = ira_class_hard_reg_index[cover_class][hard_regno];
+               index = ira_class_hard_reg_index[aclass][hard_regno];
                if (index < 0)
                  continue;
                cost = conflict_costs [i] * mult / div;
@@ -406,17 +1446,96 @@ update_conflict_hard_regno_costs (int *costs, enum reg_class cover_class,
       }
 }
 
+/* Set up conflicting and profitable regs (through CONFLICT_REGS and
+   PROFITABLE_REGS) for each object of allocno A.  */
+static inline void
+setup_conflict_profitable_regs (ira_allocno_t a, bool retry_p,
+                               HARD_REG_SET *conflict_regs,
+                               HARD_REG_SET *profitable_regs)
+{
+  int i, nwords;
+  ira_object_t obj;
+
+  nwords = ALLOCNO_NUM_OBJECTS (a);
+  for (i = 0; i < nwords; i++)
+    {
+      obj = ALLOCNO_OBJECT (a, i);
+      COPY_HARD_REG_SET (conflict_regs[i],
+                        OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
+      if (retry_p)
+       COPY_HARD_REG_SET (profitable_regs[i],
+                          reg_class_contents[ALLOCNO_CLASS (a)]);
+      else
+       COPY_HARD_REG_SET (profitable_regs[i],
+                          OBJECT_COLOR_DATA (obj)->profitable_hard_regs);
+    }
+}
+
+/* Return true if HARD_REGNO is ok for assigning to allocno A whose
+   objects have corresponding CONFLICT_REGS and PROFITABLE_REGS.  */
+static inline bool
+check_hard_reg_p (ira_allocno_t a, int hard_regno,
+                 HARD_REG_SET *conflict_regs, HARD_REG_SET *profitable_regs)
+{
+  int j, nwords, nregs;
+
+  nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (a)];
+  nwords = ALLOCNO_NUM_OBJECTS (a);
+  for (j = 0; j < nregs; j++)
+    {
+      int k;
+      int set_to_test_start = 0, set_to_test_end = nwords;
+      
+      if (nregs == nwords)
+       {
+         if (WORDS_BIG_ENDIAN)
+           set_to_test_start = nwords - j - 1;
+         else
+           set_to_test_start = j;
+         set_to_test_end = set_to_test_start + 1;
+       }
+      for (k = set_to_test_start; k < set_to_test_end; k++)
+       /* Checking only profitable hard regs.  */
+       if (TEST_HARD_REG_BIT (conflict_regs[k], hard_regno + j)
+           || ! TEST_HARD_REG_BIT (profitable_regs[k], hard_regno + j))
+         break;
+      if (k != set_to_test_end)
+       break;
+    }
+  return j == nregs;
+}
+
 /* Choose a hard register for allocno A.  If RETRY_P is TRUE, it means
    that the function called from function
-   `ira_reassign_conflict_allocnos' and `allocno_reload_assign'.  */
+   `ira_reassign_conflict_allocnos' and `allocno_reload_assign'.  In
+   this case some allocno data are not defined or updated and we
+   should not touch these data.  The function returns true if we
+   managed to assign a hard register to the allocno.
+
+   To assign a hard register, first of all we calculate all conflict
+   hard registers which can come from conflicting allocnos with
+   already assigned hard registers.  After that we find first free
+   hard register with the minimal cost.  During hard register cost
+   calculation we take conflict hard register costs into account to
+   give a chance for conflicting allocnos to get a better hard
+   register in the future.
+
+   If the best hard register cost is bigger than cost of memory usage
+   for the allocno, we don't assign a hard register to given allocno
+   at all.
+
+   If we assign a hard register to the allocno, we update costs of the
+   hard register for allocnos connected by copies to improve a chance
+   to coalesce insns represented by the copies when we assign hard
+   registers to the allocnos connected by the copies.  */
 static bool
 assign_hard_reg (ira_allocno_t a, bool retry_p)
 {
-  HARD_REG_SET conflicting_regs[2];
-  int i, j, hard_regno, nregs, best_hard_regno, class_size;
+  HARD_REG_SET conflicting_regs[2], profitable_hard_regs[2];
+  int i, j, hard_regno, best_hard_regno, class_size;
   int cost, mem_cost, min_cost, full_cost, min_full_cost, nwords, word;
   int *a_costs;
-  enum reg_class cover_class;
+  enum reg_class aclass;
   enum machine_mode mode;
   static int costs[FIRST_PSEUDO_REGISTER], full_costs[FIRST_PSEUDO_REGISTER];
 #ifndef HONOR_REG_ALLOC_ORDER
@@ -427,13 +1546,11 @@ assign_hard_reg (ira_allocno_t a, bool retry_p)
   bool no_stack_reg_p;
 #endif
 
-  nwords = ALLOCNO_NUM_OBJECTS (a);
   ira_assert (! ALLOCNO_ASSIGNED_P (a));
-  cover_class = ALLOCNO_COVER_CLASS (a);
-  class_size = ira_class_hard_regs_num[cover_class];
-  mode = ALLOCNO_MODE (a);
-  for (i = 0; i < nwords; i++)
-    CLEAR_HARD_REG_SET (conflicting_regs[i]);
+  setup_conflict_profitable_regs (a, retry_p,
+                                 conflicting_regs, profitable_hard_regs);
+  aclass = ALLOCNO_CLASS (a);
+  class_size = ira_class_hard_regs_num[aclass];
   best_hard_regno = -1;
   memset (full_costs, 0, sizeof (int) * class_size);
   mem_cost = 0;
@@ -442,16 +1559,17 @@ assign_hard_reg (ira_allocno_t a, bool retry_p)
 #ifdef STACK_REGS
   no_stack_reg_p = false;
 #endif
-  start_update_cost ();
+  if (! retry_p)
+    start_update_cost ();
   mem_cost += ALLOCNO_UPDATED_MEMORY_COST (a);
   
   ira_allocate_and_copy_costs (&ALLOCNO_UPDATED_HARD_REG_COSTS (a),
-                              cover_class, ALLOCNO_HARD_REG_COSTS (a));
+                              aclass, ALLOCNO_HARD_REG_COSTS (a));
   a_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a);
 #ifdef STACK_REGS
   no_stack_reg_p = no_stack_reg_p || ALLOCNO_TOTAL_NO_STACK_REG_P (a);
 #endif
-  cost = ALLOCNO_UPDATED_COVER_CLASS_COST (a);
+  cost = ALLOCNO_UPDATED_CLASS_COST (a);
   for (i = 0; i < class_size; i++)
     if (a_costs != NULL)
       {
@@ -463,38 +1581,44 @@ assign_hard_reg (ira_allocno_t a, bool retry_p)
        costs[i] += cost;
        full_costs[i] += cost;
       }
+  nwords = ALLOCNO_NUM_OBJECTS (a);
   for (word = 0; word < nwords; word++)
     {
       ira_object_t conflict_obj;
       ira_object_t obj = ALLOCNO_OBJECT (a, word);
       ira_object_conflict_iterator oci;
       
-      IOR_HARD_REG_SET (conflicting_regs[word],
-                       OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
       /* Take preferences of conflicting allocnos into account.  */
       FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
-       {
+        {
          ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
-         enum reg_class conflict_cover_class;
-         
+         enum reg_class conflict_aclass;
+
          /* Reload can give another class so we need to check all
             allocnos.  */
-         if (!retry_p && !bitmap_bit_p (consideration_allocno_bitmap,
-                                        ALLOCNO_NUM (conflict_a)))
+         if (!retry_p
+             && (!bitmap_bit_p (consideration_allocno_bitmap,
+                                ALLOCNO_NUM (conflict_a))
+                 || ((!ALLOCNO_ASSIGNED_P (conflict_a)
+                      || ALLOCNO_HARD_REGNO (conflict_a) < 0)
+                     && !(hard_reg_set_intersect_p
+                          (profitable_hard_regs[word],
+                           OBJECT_COLOR_DATA
+                           (conflict_obj)->profitable_hard_regs)))))
            continue;
-         conflict_cover_class = ALLOCNO_COVER_CLASS (conflict_a);
+         conflict_aclass = ALLOCNO_CLASS (conflict_a);
          ira_assert (ira_reg_classes_intersect_p
-                     [cover_class][conflict_cover_class]);
+                     [aclass][conflict_aclass]);
          if (ALLOCNO_ASSIGNED_P (conflict_a))
            {
              hard_regno = ALLOCNO_HARD_REGNO (conflict_a);
              if (hard_regno >= 0
-                 && ira_class_hard_reg_index[cover_class][hard_regno] >= 0)
+                 && ira_class_hard_reg_index[aclass][hard_regno] >= 0)
                {
                  enum machine_mode mode = ALLOCNO_MODE (conflict_a);
                  int conflict_nregs = hard_regno_nregs[hard_regno][mode];
                  int n_objects = ALLOCNO_NUM_OBJECTS (conflict_a);
-                 
+
                  if (conflict_nregs == n_objects && conflict_nregs > 1)
                    {
                      int num = OBJECT_SUBWORD (conflict_obj);
@@ -510,28 +1634,28 @@ assign_hard_reg (ira_allocno_t a, bool retry_p)
                    IOR_HARD_REG_SET
                      (conflicting_regs[word],
                       ira_reg_mode_hard_regset[hard_regno][mode]);
-                 if (hard_reg_set_subset_p (reg_class_contents[cover_class],
+                 if (hard_reg_set_subset_p (profitable_hard_regs[word],
                                             conflicting_regs[word]))
                    goto fail;
                }
            }
-         else if (! ALLOCNO_MAY_BE_SPILLED_P (conflict_a))
+         else if (! retry_p
+                  && ! ALLOCNO_COLOR_DATA (conflict_a)->may_be_spilled_p)
            {
              int k, *conflict_costs;
              
              ira_allocate_and_copy_costs
                (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a),
-                conflict_cover_class,
+                conflict_aclass,
                 ALLOCNO_CONFLICT_HARD_REG_COSTS (conflict_a));
              conflict_costs
                = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a);
              if (conflict_costs != NULL)
                for (j = class_size - 1; j >= 0; j--)
                  {
-                   hard_regno = ira_class_hard_regs[cover_class][j];
+                   hard_regno = ira_class_hard_regs[aclass][j];
                    ira_assert (hard_regno >= 0);
-                   k = (ira_class_hard_reg_index
-                        [conflict_cover_class][hard_regno]);
+                   k = ira_class_hard_reg_index[conflict_aclass][hard_regno];
                    if (k < 0)
                      continue;
                    full_costs[j] -= conflict_costs[k];
@@ -540,52 +1664,36 @@ assign_hard_reg (ira_allocno_t a, bool retry_p)
            }
        }
     }
-  /* Take into account preferences of allocnos connected by copies to
-     the conflict allocnos.  */
-  update_conflict_hard_regno_costs (full_costs, cover_class, true);
+  if (! retry_p)
+    /* Take into account preferences of allocnos connected by copies to
+       the conflict allocnos.  */
+    update_conflict_hard_regno_costs (full_costs, aclass, true);
 
   /* Take preferences of allocnos connected by copies into
      account.  */
-  start_update_cost ();
-  queue_update_cost (a, COST_HOP_DIVISOR);
-  update_conflict_hard_regno_costs (full_costs, cover_class, false);
+  if (! retry_p)
+    {
+      start_update_cost ();
+      queue_update_cost (a, COST_HOP_DIVISOR);
+      update_conflict_hard_regno_costs (full_costs, aclass, false);
+    }
   min_cost = min_full_cost = INT_MAX;
 
   /* We don't care about giving callee saved registers to allocnos no
      living through calls because call clobbered registers are
      allocated first (it is usual practice to put them first in
      REG_ALLOC_ORDER).  */
+  mode = ALLOCNO_MODE (a);
   for (i = 0; i < class_size; i++)
     {
-      hard_regno = ira_class_hard_regs[cover_class][i];
-      nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (a)];
+      hard_regno = ira_class_hard_regs[aclass][i];
 #ifdef STACK_REGS
       if (no_stack_reg_p
          && FIRST_STACK_REG <= hard_regno && hard_regno <= LAST_STACK_REG)
        continue;
 #endif
-      if (TEST_HARD_REG_BIT (prohibited_class_mode_regs[cover_class][mode],
-                            hard_regno))
-       continue;
-      for (j = 0; j < nregs; j++)
-       {
-         int k;
-         int set_to_test_start = 0, set_to_test_end = nwords;
-         if (nregs == nwords)
-           {
-             if (WORDS_BIG_ENDIAN)
-               set_to_test_start = nwords - j - 1;
-             else
-               set_to_test_start = j;
-             set_to_test_end = set_to_test_start + 1;
-           }
-         for (k = set_to_test_start; k < set_to_test_end; k++)
-           if (TEST_HARD_REG_BIT (conflicting_regs[k], hard_regno + j))
-             break;
-         if (k != set_to_test_end)
-           break;
-       }
-      if (j != nregs)
+      if (! check_hard_reg_p (a, hard_regno,
+                             conflicting_regs, profitable_hard_regs))
        continue;
       cost = costs[i];
       full_cost = full_costs[i];
@@ -627,6 +1735,7 @@ assign_hard_reg (ira_allocno_t a, bool retry_p)
   ALLOCNO_ASSIGNED_P (a) = true;
   if (best_hard_regno >= 0)
     update_copy_costs (a, true);
+  ira_assert (ALLOCNO_CLASS (a) == aclass);
   /* We don't need updated costs anymore: */
   ira_free_allocno_updated_costs (a);
   return best_hard_regno >= 0;
@@ -643,41 +1752,43 @@ static ira_allocno_t colorable_allocno_bucket;
    spilling.  */
 static ira_allocno_t uncolorable_allocno_bucket;
 
-/* Each element of the array contains the current number of allocnos
-   of given *cover* class in the uncolorable_bucket.  */
-static int uncolorable_allocnos_num[N_REG_CLASSES];
+/* The current number of allocnos in the uncolorable_bucket.  */
+static int uncolorable_allocnos_num;
 
 /* Return the current spill priority of allocno A.  The less the
    number, the more preferable the allocno for spilling.  */
-static int
+static inline int
 allocno_spill_priority (ira_allocno_t a)
 {
-  return (ALLOCNO_TEMP (a)
-         / (ALLOCNO_LEFT_CONFLICTS_SIZE (a)
-            * ira_reg_class_nregs[ALLOCNO_COVER_CLASS (a)][ALLOCNO_MODE (a)]
+  allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
+
+  return (data->temp
+         / (ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a)
+            * ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]
             + 1));
 }
 
-/* Add ALLOCNO to bucket *BUCKET_PTR.  ALLOCNO should be not in a bucket
+/* Add allocno A to bucket *BUCKET_PTR.  A should be not in a bucket
    before the call.  */
 static void
-add_allocno_to_bucket (ira_allocno_t allocno, ira_allocno_t *bucket_ptr)
+add_allocno_to_bucket (ira_allocno_t a, ira_allocno_t *bucket_ptr)
 {
-  ira_allocno_t first_allocno;
-  enum reg_class cover_class;
+  ira_allocno_t first_a;
+  allocno_color_data_t data;
 
   if (bucket_ptr == &uncolorable_allocno_bucket
-      && (cover_class = ALLOCNO_COVER_CLASS (allocno)) != NO_REGS)
+      && ALLOCNO_CLASS (a) != NO_REGS)
     {
-      uncolorable_allocnos_num[cover_class]++;
-      ira_assert (uncolorable_allocnos_num[cover_class] > 0);
+      uncolorable_allocnos_num++;
+      ira_assert (uncolorable_allocnos_num > 0);
     }
-  first_allocno = *bucket_ptr;
-  ALLOCNO_NEXT_BUCKET_ALLOCNO (allocno) = first_allocno;
-  ALLOCNO_PREV_BUCKET_ALLOCNO (allocno) = NULL;
-  if (first_allocno != NULL)
-    ALLOCNO_PREV_BUCKET_ALLOCNO (first_allocno) = allocno;
-  *bucket_ptr = allocno;
+  first_a = *bucket_ptr;
+  data = ALLOCNO_COLOR_DATA (a);
+  data->next_bucket_allocno = first_a;
+  data->prev_bucket_allocno = NULL;
+  if (first_a != NULL)
+    ALLOCNO_COLOR_DATA (first_a)->prev_bucket_allocno = a;
+  *bucket_ptr = a;
 }
 
 /* Compare two allocnos to define which allocno should be pushed first
@@ -694,15 +1805,15 @@ bucket_allocno_compare_func (const void *v1p, const void *v2p)
   ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
   int diff, a1_freq, a2_freq, a1_num, a2_num;
 
-  if ((diff = (int) ALLOCNO_COVER_CLASS (a2) - ALLOCNO_COVER_CLASS (a1)) != 0)
+  if ((diff = (int) ALLOCNO_CLASS (a2) - ALLOCNO_CLASS (a1)) != 0)
     return diff;
   a1_freq = ALLOCNO_FREQ (a1);
-  a1_num = ALLOCNO_AVAILABLE_REGS_NUM (a1);
   a2_freq = ALLOCNO_FREQ (a2);
-  a2_num = ALLOCNO_AVAILABLE_REGS_NUM (a2);
-  if ((diff = a2_num - a1_num) != 0)
+  if ((diff = a1_freq - a2_freq) != 0)
     return diff;
-  else if ((diff = a1_freq - a2_freq) != 0)
+  a1_num = ALLOCNO_COLOR_DATA (a1)->available_regs_num;
+  a2_num = ALLOCNO_COLOR_DATA (a2)->available_regs_num;
+  if ((diff = a2_num - a1_num) != 0)
     return diff;
   return ALLOCNO_NUM (a2) - ALLOCNO_NUM (a1);
 }
@@ -710,25 +1821,27 @@ bucket_allocno_compare_func (const void *v1p, const void *v2p)
 /* Sort bucket *BUCKET_PTR and return the result through
    BUCKET_PTR.  */
 static void
-sort_bucket (ira_allocno_t *bucket_ptr)
+sort_bucket (ira_allocno_t *bucket_ptr,
+            int (*compare_func) (const void *, const void *))
 {
   ira_allocno_t a, head;
   int n;
 
-  for (n = 0, a = *bucket_ptr; a != NULL; a = ALLOCNO_NEXT_BUCKET_ALLOCNO (a))
+  for (n = 0, a = *bucket_ptr;
+       a != NULL;
+       a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
     sorted_allocnos[n++] = a;
   if (n <= 1)
     return;
-  qsort (sorted_allocnos, n, sizeof (ira_allocno_t),
-        bucket_allocno_compare_func);
+  qsort (sorted_allocnos, n, sizeof (ira_allocno_t), compare_func);
   head = NULL;
   for (n--; n >= 0; n--)
     {
       a = sorted_allocnos[n];
-      ALLOCNO_NEXT_BUCKET_ALLOCNO (a) = head;
-      ALLOCNO_PREV_BUCKET_ALLOCNO (a) = NULL;
+      ALLOCNO_COLOR_DATA (a)->next_bucket_allocno = head;
+      ALLOCNO_COLOR_DATA (a)->prev_bucket_allocno = NULL;
       if (head != NULL)
-       ALLOCNO_PREV_BUCKET_ALLOCNO (head) = a;
+       ALLOCNO_COLOR_DATA (head)->prev_bucket_allocno = a;
       head = a;
     }
   *bucket_ptr = head;
@@ -742,27 +1855,27 @@ add_allocno_to_ordered_bucket (ira_allocno_t allocno,
                               ira_allocno_t *bucket_ptr)
 {
   ira_allocno_t before, after;
-  enum reg_class cover_class;
 
   if (bucket_ptr == &uncolorable_allocno_bucket
-      && (cover_class = ALLOCNO_COVER_CLASS (allocno)) != NO_REGS)
+      && ALLOCNO_CLASS (allocno) != NO_REGS)
     {
-      uncolorable_allocnos_num[cover_class]++;
-      ira_assert (uncolorable_allocnos_num[cover_class] > 0);
+      uncolorable_allocnos_num++;
+      ira_assert (uncolorable_allocnos_num > 0);
     }
   for (before = *bucket_ptr, after = NULL;
        before != NULL;
-       after = before, before = ALLOCNO_NEXT_BUCKET_ALLOCNO (before))
+       after = before,
+        before = ALLOCNO_COLOR_DATA (before)->next_bucket_allocno)
     if (bucket_allocno_compare_func (&allocno, &before) < 0)
       break;
-  ALLOCNO_NEXT_BUCKET_ALLOCNO (allocno) = before;
-  ALLOCNO_PREV_BUCKET_ALLOCNO (allocno) = after;
+  ALLOCNO_COLOR_DATA (allocno)->next_bucket_allocno = before;
+  ALLOCNO_COLOR_DATA (allocno)->prev_bucket_allocno = after;
   if (after == NULL)
     *bucket_ptr = allocno;
   else
-    ALLOCNO_NEXT_BUCKET_ALLOCNO (after) = allocno;
+    ALLOCNO_COLOR_DATA (after)->next_bucket_allocno = allocno;
   if (before != NULL)
-    ALLOCNO_PREV_BUCKET_ALLOCNO (before) = allocno;
+    ALLOCNO_COLOR_DATA (before)->prev_bucket_allocno = allocno;
 }
 
 /* Delete ALLOCNO from bucket *BUCKET_PTR.  It should be there before
@@ -771,42 +1884,26 @@ static void
 delete_allocno_from_bucket (ira_allocno_t allocno, ira_allocno_t *bucket_ptr)
 {
   ira_allocno_t prev_allocno, next_allocno;
-  enum reg_class cover_class;
 
   if (bucket_ptr == &uncolorable_allocno_bucket
-      && (cover_class = ALLOCNO_COVER_CLASS (allocno)) != NO_REGS)
+      && ALLOCNO_CLASS (allocno) != NO_REGS)
     {
-      uncolorable_allocnos_num[cover_class]--;
-      ira_assert (uncolorable_allocnos_num[cover_class] >= 0);
+      uncolorable_allocnos_num--;
+      ira_assert (uncolorable_allocnos_num >= 0);
     }
-  prev_allocno = ALLOCNO_PREV_BUCKET_ALLOCNO (allocno);
-  next_allocno = ALLOCNO_NEXT_BUCKET_ALLOCNO (allocno);
+  prev_allocno = ALLOCNO_COLOR_DATA (allocno)->prev_bucket_allocno;
+  next_allocno = ALLOCNO_COLOR_DATA (allocno)->next_bucket_allocno;
   if (prev_allocno != NULL)
-    ALLOCNO_NEXT_BUCKET_ALLOCNO (prev_allocno) = next_allocno;
+    ALLOCNO_COLOR_DATA (prev_allocno)->next_bucket_allocno = next_allocno;
   else
     {
       ira_assert (*bucket_ptr == allocno);
       *bucket_ptr = next_allocno;
     }
   if (next_allocno != NULL)
-    ALLOCNO_PREV_BUCKET_ALLOCNO (next_allocno) = prev_allocno;
+    ALLOCNO_COLOR_DATA (next_allocno)->prev_bucket_allocno = prev_allocno;
 }
 
-/* Splay tree for each cover class.  The trees are indexed by the
-   corresponding cover classes.  Splay trees contain uncolorable
-   allocnos.  */
-static splay_tree uncolorable_allocnos_splay_tree[N_REG_CLASSES];
-
-/* If the following macro is TRUE, splay tree is used to choose an
-   allocno of the corresponding cover class for spilling.  When the
-   number uncolorable allocnos of given cover class decreases to some
-   threshold, linear array search is used to find the best allocno for
-   spilling.  This threshold is actually pretty big because, although
-   splay trees asymptotically is much faster, each splay tree
-   operation is sufficiently costly especially taking cache locality
-   into account.  */
-#define USE_SPLAY_P(CLASS) (uncolorable_allocnos_num[CLASS] > 4000)
-
 /* Put allocno A onto the coloring stack without removing it from its
    bucket.  Pushing allocno to the coloring stack can result in moving
    conflicting allocnos from the uncolorable bucket to the colorable
@@ -814,17 +1911,18 @@ static splay_tree uncolorable_allocnos_splay_tree[N_REG_CLASSES];
 static void
 push_allocno_to_stack (ira_allocno_t a)
 {
-  int size;
-  enum reg_class cover_class;
-  int i, n = ALLOCNO_NUM_OBJECTS (a);
-
-  ALLOCNO_IN_GRAPH_P (a) = false;
+  enum reg_class aclass;
+  allocno_color_data_t data, conflict_data;
+  int size, i, n = ALLOCNO_NUM_OBJECTS (a);
+    
+  data = ALLOCNO_COLOR_DATA (a);
+  data->in_graph_p = false;
   VEC_safe_push (ira_allocno_t, heap, allocno_stack_vec, a);
-  cover_class = ALLOCNO_COVER_CLASS (a);
-  if (cover_class == NO_REGS)
+  aclass = ALLOCNO_CLASS (a);
+  if (aclass == NO_REGS)
     return;
-  size = ira_reg_class_nregs[cover_class][ALLOCNO_MODE (a)];
-  if (ALLOCNO_NUM_OBJECTS (a) > 1)
+  size = ira_reg_class_max_nregs[aclass][ALLOCNO_MODE (a)];
+  if (n > 1)
     {
       /* We will deal with the subwords individually.  */
       gcc_assert (size == ALLOCNO_NUM_OBJECTS (a));
@@ -833,64 +1931,37 @@ push_allocno_to_stack (ira_allocno_t a)
   for (i = 0; i < n; i++)
     {
       ira_object_t obj = ALLOCNO_OBJECT (a, i);
-      int conflict_size;
       ira_object_t conflict_obj;
       ira_object_conflict_iterator oci;
       
       FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
        {
          ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
-         int left_conflicts_size;
-         
-         conflict_a = conflict_a;
-         if (!bitmap_bit_p (coloring_allocno_bitmap,
-                            ALLOCNO_NUM (conflict_a)))
-           continue;
          
-         ira_assert (cover_class
-                     == ALLOCNO_COVER_CLASS (conflict_a));
-         if (!ALLOCNO_IN_GRAPH_P (conflict_a)
-             || ALLOCNO_ASSIGNED_P (conflict_a))
+         conflict_data = ALLOCNO_COLOR_DATA (conflict_a);
+         if (conflict_data->colorable_p
+             || ! conflict_data->in_graph_p
+             || ALLOCNO_ASSIGNED_P (conflict_a)
+             || !(hard_reg_set_intersect_p
+                  (OBJECT_COLOR_DATA (obj)->profitable_hard_regs,
+                   OBJECT_COLOR_DATA (conflict_obj)->profitable_hard_regs)))
            continue;
-         
-         left_conflicts_size = ALLOCNO_LEFT_CONFLICTS_SIZE (conflict_a);
-         conflict_size
-           = (ira_reg_class_nregs
-              [cover_class][ALLOCNO_MODE (conflict_a)]);
-         ira_assert (left_conflicts_size >= size);
-         if (left_conflicts_size + conflict_size
-             <= ALLOCNO_AVAILABLE_REGS_NUM (conflict_a))
-           {
-             ALLOCNO_LEFT_CONFLICTS_SIZE (conflict_a) -= size;
-             continue;
-           }
-         left_conflicts_size -= size;
-         if (uncolorable_allocnos_splay_tree[cover_class] != NULL
-             && !ALLOCNO_SPLAY_REMOVED_P (conflict_a)
-             && USE_SPLAY_P (cover_class))
-           {
-             ira_assert
-               (splay_tree_lookup
-                (uncolorable_allocnos_splay_tree[cover_class],
-                 (splay_tree_key) conflict_a) != NULL);
-             splay_tree_remove
-               (uncolorable_allocnos_splay_tree[cover_class],
-                (splay_tree_key) conflict_a);
-             ALLOCNO_SPLAY_REMOVED_P (conflict_a) = true;
-             VEC_safe_push (ira_allocno_t, heap,
-                            removed_splay_allocno_vec,
-                            conflict_a);
-           }
-         ALLOCNO_LEFT_CONFLICTS_SIZE (conflict_a)
-           = left_conflicts_size;
-         if (left_conflicts_size + conflict_size
-             <= ALLOCNO_AVAILABLE_REGS_NUM (conflict_a))
+         ira_assert (bitmap_bit_p (coloring_allocno_bitmap,
+                                   ALLOCNO_NUM (conflict_a)));
+         if (update_left_conflict_sizes_p (conflict_a, obj, size))
            {
              delete_allocno_from_bucket
-               (conflict_a, &uncolorable_allocno_bucket);
+                   (conflict_a, &uncolorable_allocno_bucket);
              add_allocno_to_ordered_bucket
                (conflict_a, &colorable_allocno_bucket);
+             if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
+               {
+                 fprintf (ira_dump_file, "        Making");
+                 ira_print_expanded_allocno (conflict_a);
+                 fprintf (ira_dump_file, " colorable\n");
+               }
            }
+         
        }
     }
 }
@@ -900,8 +1971,6 @@ push_allocno_to_stack (ira_allocno_t a)
 static void
 remove_allocno_from_bucket_and_push (ira_allocno_t allocno, bool colorable_p)
 {
-  enum reg_class cover_class;
-
   if (colorable_p)
     delete_allocno_from_bucket (allocno, &colorable_allocno_bucket);
   else
@@ -911,24 +1980,16 @@ remove_allocno_from_bucket_and_push (ira_allocno_t allocno, bool colorable_p)
       fprintf (ira_dump_file, "      Pushing");
       ira_print_expanded_allocno (allocno);
       if (colorable_p)
-       fprintf (ira_dump_file, "\n");
+       fprintf (ira_dump_file, "(cost %d)\n",
+                ALLOCNO_COLOR_DATA (allocno)->temp);
       else
        fprintf (ira_dump_file, "(potential spill: %spri=%d, cost=%d)\n",
                 ALLOCNO_BAD_SPILL_P (allocno) ? "bad spill, " : "",
-                allocno_spill_priority (allocno), ALLOCNO_TEMP (allocno));
-    }
-  cover_class = ALLOCNO_COVER_CLASS (allocno);
-  ira_assert ((colorable_p
-              && (ALLOCNO_LEFT_CONFLICTS_SIZE (allocno)
-                  + ira_reg_class_nregs[cover_class][ALLOCNO_MODE (allocno)]
-                  <= ALLOCNO_AVAILABLE_REGS_NUM (allocno)))
-             || (! colorable_p
-                 && (ALLOCNO_LEFT_CONFLICTS_SIZE (allocno)
-                     + ira_reg_class_nregs[cover_class][ALLOCNO_MODE
-                                                        (allocno)]
-                     > ALLOCNO_AVAILABLE_REGS_NUM (allocno))));
+                allocno_spill_priority (allocno),
+                ALLOCNO_COLOR_DATA (allocno)->temp);
+    }
   if (! colorable_p)
-    ALLOCNO_MAY_BE_SPILLED_P (allocno) = true;
+    ALLOCNO_COLOR_DATA (allocno)->may_be_spilled_p = true;
   push_allocno_to_stack (allocno);
 }
 
@@ -936,24 +1997,11 @@ remove_allocno_from_bucket_and_push (ira_allocno_t allocno, bool colorable_p)
 static void
 push_only_colorable (void)
 {
-  sort_bucket (&colorable_allocno_bucket);
+  sort_bucket (&colorable_allocno_bucket, bucket_allocno_compare_func);
   for (;colorable_allocno_bucket != NULL;)
     remove_allocno_from_bucket_and_push (colorable_allocno_bucket, true);
 }
 
-/* Puts ALLOCNO chosen for potential spilling onto the coloring
-   stack.  */
-static void
-push_allocno_to_spill (ira_allocno_t allocno)
-{
-  delete_allocno_from_bucket (allocno, &uncolorable_allocno_bucket);
-  ALLOCNO_MAY_BE_SPILLED_P (allocno) = true;
-  if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
-    fprintf (ira_dump_file, "      Pushing p%d(%d) (spill for NO_REGS)\n",
-            ALLOCNO_NUM (allocno), ALLOCNO_REGNO (allocno));
-  push_allocno_to_stack (allocno);
-}
-
 /* Return the frequency of exit edges (if EXIT_P) or entry from/to the
    loop given by its LOOP_NODE.  */
 int
@@ -1001,7 +2049,7 @@ calculate_allocno_spill_cost (ira_allocno_t a)
   ira_loop_tree_node_t parent_node, loop_node;
 
   regno = ALLOCNO_REGNO (a);
-  cost = ALLOCNO_UPDATED_MEMORY_COST (a) - ALLOCNO_UPDATED_COVER_CLASS_COST (a);
+  cost = ALLOCNO_UPDATED_MEMORY_COST (a) - ALLOCNO_UPDATED_CLASS_COST (a);
   if (ALLOCNO_CAP (a) != NULL)
     return cost;
   loop_node = ALLOCNO_LOOP_TREE_NODE (a);
@@ -1010,242 +2058,87 @@ calculate_allocno_spill_cost (ira_allocno_t a)
   if ((parent_allocno = parent_node->regno_allocno_map[regno]) == NULL)
     return cost;
   mode = ALLOCNO_MODE (a);
-  rclass = ALLOCNO_COVER_CLASS (a);
+  rclass = ALLOCNO_CLASS (a);
   if (ALLOCNO_HARD_REGNO (parent_allocno) < 0)
     cost -= (ira_memory_move_cost[mode][rclass][0]
             * ira_loop_edge_freq (loop_node, regno, true)
             + ira_memory_move_cost[mode][rclass][1]
             * ira_loop_edge_freq (loop_node, regno, false));
   else
-    cost += ((ira_memory_move_cost[mode][rclass][1]
-             * ira_loop_edge_freq (loop_node, regno, true)
-             + ira_memory_move_cost[mode][rclass][0]
-             * ira_loop_edge_freq (loop_node, regno, false))
-            - (ira_get_register_move_cost (mode, rclass, rclass)
-               * (ira_loop_edge_freq (loop_node, regno, false)
-                  + ira_loop_edge_freq (loop_node, regno, true))));
+    {
+      ira_init_register_move_cost_if_necessary (mode);
+      cost += ((ira_memory_move_cost[mode][rclass][1]
+               * ira_loop_edge_freq (loop_node, regno, true)
+               + ira_memory_move_cost[mode][rclass][0]
+               * ira_loop_edge_freq (loop_node, regno, false))
+              - (ira_register_move_cost[mode][rclass][rclass]
+                 * (ira_loop_edge_freq (loop_node, regno, false)
+                    + ira_loop_edge_freq (loop_node, regno, true))));
+    }
   return cost;
 }
 
-/* Compare keys in the splay tree used to choose best allocno for
-   spilling.  The best allocno has the minimal key.  */
-static int
-allocno_spill_priority_compare (splay_tree_key k1, splay_tree_key k2)
+/* Used for sorting allocnos for spilling.  */
+static inline int
+allocno_spill_priority_compare (ira_allocno_t a1, ira_allocno_t a2)
 {
   int pri1, pri2, diff;
-  ira_allocno_t a1 = (ira_allocno_t) k1, a2 = (ira_allocno_t) k2;
 
-  pri1 = (ALLOCNO_TEMP (a1)
-         / (ALLOCNO_LEFT_CONFLICTS_SIZE (a1)
-            * ira_reg_class_nregs[ALLOCNO_COVER_CLASS (a1)][ALLOCNO_MODE (a1)]
-            + 1));
-  pri2 = (ALLOCNO_TEMP (a2)
-         / (ALLOCNO_LEFT_CONFLICTS_SIZE (a2)
-            * ira_reg_class_nregs[ALLOCNO_COVER_CLASS (a2)][ALLOCNO_MODE (a2)]
-            + 1));
+  if (ALLOCNO_BAD_SPILL_P (a1) && ! ALLOCNO_BAD_SPILL_P (a2))
+    return 1;
+  if (ALLOCNO_BAD_SPILL_P (a2) && ! ALLOCNO_BAD_SPILL_P (a1))
+    return -1;
+  pri1 = allocno_spill_priority (a1);
+  pri2 = allocno_spill_priority (a2);
   if ((diff = pri1 - pri2) != 0)
     return diff;
-  if ((diff = ALLOCNO_TEMP (a1) - ALLOCNO_TEMP (a2)) != 0)
+  if ((diff
+       = ALLOCNO_COLOR_DATA (a1)->temp - ALLOCNO_COLOR_DATA (a2)->temp) != 0)
     return diff;
   return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2);
 }
 
-/* Allocate data of SIZE for the splay trees.  We allocate only spay
-   tree roots or splay tree nodes.  If you change this, please rewrite
-   the function.  */
-static void *
-splay_tree_allocate (int size, void *data ATTRIBUTE_UNUSED)
-{
-  if (size != sizeof (struct splay_tree_node_s))
-    return ira_allocate (size);
-  return pool_alloc (splay_tree_node_pool);
-}
-
-/* Free data NODE for the splay trees.  We allocate and free only spay
-   tree roots or splay tree nodes.  If you change this, please rewrite
-   the function.  */
-static void
-splay_tree_free (void *node, void *data ATTRIBUTE_UNUSED)
+/* Used for sorting allocnos for spilling.  */
+static int
+allocno_spill_sort_compare (const void *v1p, const void *v2p)
 {
-  int i;
-  enum reg_class cover_class;
+  ira_allocno_t p1 = *(const ira_allocno_t *) v1p;
+  ira_allocno_t p2 = *(const ira_allocno_t *) v2p;
 
-  for (i = 0; i < ira_reg_class_cover_size; i++)
-    {
-      cover_class = ira_reg_class_cover[i];
-      if (node == uncolorable_allocnos_splay_tree[cover_class])
-       {
-         ira_free (node);
-         return;
-       }
-    }
-  pool_free (splay_tree_node_pool, node);
+  return allocno_spill_priority_compare (p1, p2);
 }
 
 /* Push allocnos to the coloring stack.  The order of allocnos in the
-   stack defines the order for the subsequent coloring.  */
-static void
-push_allocnos_to_stack (void)
-{
-  ira_allocno_t allocno, i_allocno, *allocno_vec;
-  enum reg_class cover_class, rclass;
-  int allocno_pri, i_allocno_pri, allocno_cost, i_allocno_cost;
-  int i, j, num, cover_class_allocnos_num[N_REG_CLASSES];
-  ira_allocno_t *cover_class_allocnos[N_REG_CLASSES];
-  int cost;
-
-  /* Initialize.  */
-  VEC_truncate(ira_allocno_t, removed_splay_allocno_vec, 0);
-  for (i = 0; i < ira_reg_class_cover_size; i++)
-    {
-      cover_class = ira_reg_class_cover[i];
-      cover_class_allocnos_num[cover_class] = 0;
-      cover_class_allocnos[cover_class] = NULL;
-      uncolorable_allocnos_splay_tree[cover_class] = NULL;
-    }
-  /* Calculate uncolorable allocno spill costs.  */
-  for (allocno = uncolorable_allocno_bucket;
-       allocno != NULL;
-       allocno = ALLOCNO_NEXT_BUCKET_ALLOCNO (allocno))
-    if ((cover_class = ALLOCNO_COVER_CLASS (allocno)) != NO_REGS)
-      {
-       cover_class_allocnos_num[cover_class]++;
-       cost = calculate_allocno_spill_cost (allocno);
-       ALLOCNO_TEMP (allocno) = cost;
-      }
-  /* Define place where to put uncolorable allocnos of the same cover
-     class.  */
-  for (num = i = 0; i < ira_reg_class_cover_size; i++)
-    {
-      cover_class = ira_reg_class_cover[i];
-      ira_assert (cover_class_allocnos_num[cover_class]
-                 == uncolorable_allocnos_num[cover_class]);
-      if (cover_class_allocnos_num[cover_class] != 0)
-       {
-         cover_class_allocnos[cover_class] = allocnos_for_spilling + num;
-         num += cover_class_allocnos_num[cover_class];
-         cover_class_allocnos_num[cover_class] = 0;
-       }
-      if (USE_SPLAY_P (cover_class))
-       uncolorable_allocnos_splay_tree[cover_class]
-         = splay_tree_new_with_allocator (allocno_spill_priority_compare,
-                                          NULL, NULL, splay_tree_allocate,
-                                          splay_tree_free, NULL);
-    }
-  ira_assert (num <= ira_allocnos_num);
-  /* Collect uncolorable allocnos of each cover class.  */
-  for (allocno = uncolorable_allocno_bucket;
-       allocno != NULL;
-       allocno = ALLOCNO_NEXT_BUCKET_ALLOCNO (allocno))
-    if ((cover_class = ALLOCNO_COVER_CLASS (allocno)) != NO_REGS)
-      {
-       cover_class_allocnos
-         [cover_class][cover_class_allocnos_num[cover_class]++] = allocno;
-       if (uncolorable_allocnos_splay_tree[cover_class] != NULL)
-         splay_tree_insert (uncolorable_allocnos_splay_tree[cover_class],
-                            (splay_tree_key) allocno,
-                            (splay_tree_value) allocno);
-      }
-  for (;;)
-    {
-      push_only_colorable ();
-      allocno = uncolorable_allocno_bucket;
-      if (allocno == NULL)
-       break;
-      cover_class = ALLOCNO_COVER_CLASS (allocno);
-      if (cover_class == NO_REGS)
-       {
-         push_allocno_to_spill (allocno);
-         continue;
-       }
-      /* Potential spilling.  */
-      ira_assert
-       (ira_reg_class_nregs[cover_class][ALLOCNO_MODE (allocno)] > 0);
-      if (USE_SPLAY_P (cover_class))
-       {
-         for (;VEC_length (ira_allocno_t, removed_splay_allocno_vec) != 0;)
-           {
-             allocno = VEC_pop (ira_allocno_t, removed_splay_allocno_vec);
-             ALLOCNO_SPLAY_REMOVED_P (allocno) = false;
-             rclass = ALLOCNO_COVER_CLASS (allocno);
-             if (ALLOCNO_LEFT_CONFLICTS_SIZE (allocno)
-                 + ira_reg_class_nregs [rclass][ALLOCNO_MODE (allocno)]
-                 > ALLOCNO_AVAILABLE_REGS_NUM (allocno))
-               splay_tree_insert
-                 (uncolorable_allocnos_splay_tree[rclass],
-                  (splay_tree_key) allocno, (splay_tree_value) allocno);
-           }
-         allocno = ((ira_allocno_t)
-                    splay_tree_min
-                    (uncolorable_allocnos_splay_tree[cover_class])->key);
-         splay_tree_remove (uncolorable_allocnos_splay_tree[cover_class],
-                            (splay_tree_key) allocno);
-       }
-      else
-       {
-         num = cover_class_allocnos_num[cover_class];
-         ira_assert (num > 0);
-         allocno_vec = cover_class_allocnos[cover_class];
-         allocno = NULL;
-         allocno_pri = allocno_cost = 0;
-         /* Sort uncolorable allocno to find the one with the lowest
-            spill cost.  */
-         for (i = 0, j = num - 1; i <= j;)
-           {
-             i_allocno = allocno_vec[i];
-             if (! ALLOCNO_IN_GRAPH_P (i_allocno)
-                 && ALLOCNO_IN_GRAPH_P (allocno_vec[j]))
-               {
-                 i_allocno = allocno_vec[j];
-                 allocno_vec[j] = allocno_vec[i];
-                 allocno_vec[i] = i_allocno;
-               }
-             if (ALLOCNO_IN_GRAPH_P (i_allocno))
-               {
-                 i++;
-                 ira_assert (ALLOCNO_TEMP (i_allocno) != INT_MAX);
-                 i_allocno_cost = ALLOCNO_TEMP (i_allocno);
-                 i_allocno_pri = allocno_spill_priority (i_allocno);
-                 if (allocno == NULL
-                     || (! ALLOCNO_BAD_SPILL_P (i_allocno)
-                         && ALLOCNO_BAD_SPILL_P (allocno))
-                     || (! (ALLOCNO_BAD_SPILL_P (i_allocno)
-                            && ! ALLOCNO_BAD_SPILL_P (allocno))
-                         && (allocno_pri > i_allocno_pri
-                             || (allocno_pri == i_allocno_pri
-                                 && (allocno_cost > i_allocno_cost
-                                     || (allocno_cost == i_allocno_cost
-                                         && (ALLOCNO_NUM (allocno)
-                                             > ALLOCNO_NUM (i_allocno))))))))
-                   {
-                     allocno = i_allocno;
-                     allocno_cost = i_allocno_cost;
-                     allocno_pri = i_allocno_pri;
-                   }
-               }
-             if (! ALLOCNO_IN_GRAPH_P (allocno_vec[j]))
-               j--;
-           }
-         ira_assert (allocno != NULL && j >= 0);
-         cover_class_allocnos_num[cover_class] = j + 1;
-       }
-      ira_assert (ALLOCNO_IN_GRAPH_P (allocno)
-                 && ALLOCNO_COVER_CLASS (allocno) == cover_class
-                 && (ALLOCNO_LEFT_CONFLICTS_SIZE (allocno)
-                     + ira_reg_class_nregs[cover_class][ALLOCNO_MODE
-                                                        (allocno)]
-                     > ALLOCNO_AVAILABLE_REGS_NUM (allocno)));
-      remove_allocno_from_bucket_and_push (allocno, false);
+   stack defines the order for the subsequent coloring.  */
+static void
+push_allocnos_to_stack (void)
+{
+  ira_allocno_t a;
+  int cost;
+
+  /* Calculate uncolorable allocno spill costs.  */
+  for (a = uncolorable_allocno_bucket;
+       a != NULL;
+       a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
+    if (ALLOCNO_CLASS (a) != NO_REGS)
+      {
+       cost = calculate_allocno_spill_cost (a);
+       /* ??? Remove cost of copies between the coalesced
+          allocnos.  */
+       ALLOCNO_COLOR_DATA (a)->temp = cost;
+      }
+  sort_bucket (&uncolorable_allocno_bucket, allocno_spill_sort_compare);
+  for (;;)
+    {
+      push_only_colorable ();
+      a = uncolorable_allocno_bucket;
+      if (a == NULL)
+       break;
+      remove_allocno_from_bucket_and_push (a, false);
     }
   ira_assert (colorable_allocno_bucket == NULL
              && uncolorable_allocno_bucket == NULL);
-  for (i = 0; i < ira_reg_class_cover_size; i++)
-    {
-      cover_class = ira_reg_class_cover[i];
-      ira_assert (uncolorable_allocnos_num[cover_class] == 0);
-      if (uncolorable_allocnos_splay_tree[cover_class] != NULL)
-       splay_tree_delete (uncolorable_allocnos_splay_tree[cover_class]);
-    }
+  ira_assert (uncolorable_allocnos_num == 0);
 }
 
 /* Pop the coloring stack and assign hard registers to the popped
@@ -1254,19 +2147,19 @@ static void
 pop_allocnos_from_stack (void)
 {
   ira_allocno_t allocno;
-  enum reg_class cover_class;
+  enum reg_class aclass;
 
   for (;VEC_length (ira_allocno_t, allocno_stack_vec) != 0;)
     {
       allocno = VEC_pop (ira_allocno_t, allocno_stack_vec);
-      cover_class = ALLOCNO_COVER_CLASS (allocno);
+      aclass = ALLOCNO_CLASS (allocno);
       if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
        {
          fprintf (ira_dump_file, "      Popping");
          ira_print_expanded_allocno (allocno);
          fprintf (ira_dump_file, "  -- ");
        }
-      if (cover_class == NO_REGS)
+      if (aclass == NO_REGS)
        {
          ALLOCNO_HARD_REGNO (allocno) = -1;
          ALLOCNO_ASSIGNED_P (allocno) = true;
@@ -1287,23 +2180,7 @@ pop_allocnos_from_stack (void)
          if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
            fprintf (ira_dump_file, "spill\n");
        }
-      ALLOCNO_IN_GRAPH_P (allocno) = true;
-    }
-}
-
-/* Loop over all subobjects of allocno A, collecting total hard
-   register conflicts in PSET (which the caller must initialize).  */
-static void
-all_conflicting_hard_regs (ira_allocno_t a, HARD_REG_SET *pset)
-{
-  int i;
-  int n = ALLOCNO_NUM_OBJECTS (a);
-  
-  for (i = 0; i < n; i++)
-    {
-      ira_object_t obj = ALLOCNO_OBJECT (a, i);
-
-      IOR_HARD_REG_SET (*pset, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
+      ALLOCNO_COLOR_DATA (allocno)->in_graph_p = true;
     }
 }
 
@@ -1311,107 +2188,86 @@ all_conflicting_hard_regs (ira_allocno_t a, HARD_REG_SET *pset)
 static void
 setup_allocno_available_regs_num (ira_allocno_t a)
 {
-  int i, n, hard_regs_num, hard_regno;
+  int i, j, n, hard_regno, hard_regs_num, nwords, nregs;
+  enum reg_class aclass;
   enum machine_mode mode;
-  enum reg_class cover_class;
-  HARD_REG_SET temp_set;
+  allocno_color_data_t data;
 
-  cover_class = ALLOCNO_COVER_CLASS (a);
-  ALLOCNO_AVAILABLE_REGS_NUM (a) = ira_available_class_regs[cover_class];
-  if (cover_class == NO_REGS)
+  aclass = ALLOCNO_CLASS (a);
+  data = ALLOCNO_COLOR_DATA (a);
+  data->available_regs_num = 0;
+  if (aclass == NO_REGS)
     return;
-  CLEAR_HARD_REG_SET (temp_set);
-  ira_assert (ALLOCNO_FIRST_COALESCED_ALLOCNO (a) == a);
-  hard_regs_num = ira_class_hard_regs_num[cover_class];
-  all_conflicting_hard_regs (a, &temp_set);
-
+  hard_regs_num = ira_class_hard_regs_num[aclass];
   mode = ALLOCNO_MODE (a);
+  nwords = ALLOCNO_NUM_OBJECTS (a);
   for (n = 0, i = hard_regs_num - 1; i >= 0; i--)
     {
-      hard_regno = ira_class_hard_regs[cover_class][i];
-      if (TEST_HARD_REG_BIT (temp_set, hard_regno)
-         || TEST_HARD_REG_BIT (prohibited_class_mode_regs[cover_class][mode],
-                               hard_regno))
+      hard_regno = ira_class_hard_regs[aclass][i];
+      nregs = hard_regno_nregs[hard_regno][mode];
+      for (j = 0; j < nregs; j++)
+       {
+         int k;
+         int set_to_test_start = 0, set_to_test_end = nwords;
+
+         if (nregs == nwords)
+           {
+             if (WORDS_BIG_ENDIAN)
+               set_to_test_start = nwords - j - 1;
+             else
+               set_to_test_start = j;
+             set_to_test_end = set_to_test_start + 1;
+           }
+         for (k = set_to_test_start; k < set_to_test_end; k++)
+           {
+             ira_object_t obj = ALLOCNO_OBJECT (a, k);
+             object_color_data_t obj_data = OBJECT_COLOR_DATA (obj);
+
+             /* Checking only profitable hard regs.  */
+             if (TEST_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
+                                    hard_regno + j)
+                 || ! TEST_HARD_REG_BIT (obj_data->profitable_hard_regs,
+                                         hard_regno + j))
+               break;
+           }
+         if (k != set_to_test_end)
+           break;
+       }
+      if (j == nregs)
        n++;
     }
-  if (internal_flag_ira_verbose > 2 && n > 0 && ira_dump_file != NULL)
-    fprintf (ira_dump_file, "    Reg %d of %s has %d regs less\n",
-            ALLOCNO_REGNO (a), reg_class_names[cover_class], n);
-  ALLOCNO_AVAILABLE_REGS_NUM (a) -= n;
-}
-
-/* Set up ALLOCNO_LEFT_CONFLICTS_SIZE for allocno A.  */
-static void
-setup_allocno_left_conflicts_size (ira_allocno_t a)
-{
-  int i, hard_regs_num, hard_regno, conflict_allocnos_size;
-  enum reg_class cover_class;
-  HARD_REG_SET temp_set;
-
-  cover_class = ALLOCNO_COVER_CLASS (a);
-  hard_regs_num = ira_class_hard_regs_num[cover_class];
-  CLEAR_HARD_REG_SET (temp_set);
-  ira_assert (ALLOCNO_FIRST_COALESCED_ALLOCNO (a) == a);
-  all_conflicting_hard_regs (a, &temp_set);
-
-  AND_HARD_REG_SET (temp_set, reg_class_contents[cover_class]);
-  AND_COMPL_HARD_REG_SET (temp_set, ira_no_alloc_regs);
-
-  conflict_allocnos_size = 0;
-  if (! hard_reg_set_empty_p (temp_set))
-    for (i = 0; i < (int) hard_regs_num; i++)
-      {
-       hard_regno = ira_class_hard_regs[cover_class][i];
-       if (TEST_HARD_REG_BIT (temp_set, hard_regno))
-         {
-           conflict_allocnos_size++;
-           CLEAR_HARD_REG_BIT (temp_set, hard_regno);
-           if (hard_reg_set_empty_p (temp_set))
-             break;
-         }
-      }
-  CLEAR_HARD_REG_SET (temp_set);
-  if (cover_class != NO_REGS)
+  data->available_regs_num = n;
+  if (internal_flag_ira_verbose <= 2 || ira_dump_file == NULL)
+    return;
+  fprintf
+    (ira_dump_file,
+     "      Allocno a%dr%d of %s(%d) has %d avail. regs",
+     ALLOCNO_NUM (a), ALLOCNO_REGNO (a),
+     reg_class_names[aclass], ira_class_hard_regs_num[aclass], n);
+  for (i = 0; i < nwords; i++)
     {
-      int n = ALLOCNO_NUM_OBJECTS (a);
+      ira_object_t obj = ALLOCNO_OBJECT (a, i);
+      object_color_data_t obj_data = OBJECT_COLOR_DATA (obj);
 
-      for (i = 0; i < n; i++)
+      if (nwords != 1)
        {
-         ira_object_t obj = ALLOCNO_OBJECT (a, i);
-         ira_object_t conflict_obj;
-         ira_object_conflict_iterator oci;
-         
-         FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
-           {
-             ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
-             
-             ira_assert (cover_class
-                         == ALLOCNO_COVER_CLASS (conflict_a));
-             if (! ALLOCNO_ASSIGNED_P (conflict_a))
-               conflict_allocnos_size
-                 += (ira_reg_class_nregs
-                     [cover_class][ALLOCNO_MODE (conflict_a)]);
-             else if ((hard_regno = ALLOCNO_HARD_REGNO (conflict_a))
-                      >= 0)
-               {
-                 int last = (hard_regno
-                             + hard_regno_nregs
-                             [hard_regno][ALLOCNO_MODE (conflict_a)]);
-                 
-                 while (hard_regno < last)
-                   {
-                     if (! TEST_HARD_REG_BIT (temp_set, hard_regno))
-                       {
-                         conflict_allocnos_size++;
-                         SET_HARD_REG_BIT (temp_set, hard_regno);
-                       }
-                     hard_regno++;
-                   }
-               }
-           }
+         if (i != 0)
+           fprintf (ira_dump_file, ", ");
+         fprintf (ira_dump_file, " obj %d", i);
        }
+      print_hard_reg_set (ira_dump_file, obj_data->profitable_hard_regs, false);
+      fprintf (ira_dump_file, " (confl regs = ");
+      print_hard_reg_set (ira_dump_file, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
+                         false);
+      fprintf (ira_dump_file, " ) %snode: ",
+              hard_reg_set_equal_p (obj_data->profitable_hard_regs,
+                                    obj_data->hard_regs_node->hard_regs->set)
+              ? "" : "^");
+      print_hard_reg_set (ira_dump_file,
+                         obj_data->hard_regs_node->hard_regs->set, false);
+
     }
-  ALLOCNO_LEFT_CONFLICTS_SIZE (a) = conflict_allocnos_size;
+  fprintf (ira_dump_file, "\n");
 }
 
 /* Put ALLOCNO in a bucket corresponding to its number and size of its
@@ -1419,15 +2275,9 @@ setup_allocno_left_conflicts_size (ira_allocno_t a)
 static void
 put_allocno_into_bucket (ira_allocno_t allocno)
 {
-  enum reg_class cover_class;
-
-  cover_class = ALLOCNO_COVER_CLASS (allocno);
-  ALLOCNO_IN_GRAPH_P (allocno) = true;
-  setup_allocno_left_conflicts_size (allocno);
+  ALLOCNO_COLOR_DATA (allocno)->in_graph_p = true;
   setup_allocno_available_regs_num (allocno);
-  if (ALLOCNO_LEFT_CONFLICTS_SIZE (allocno)
-      + ira_reg_class_nregs[cover_class][ALLOCNO_MODE (allocno)]
-      <= ALLOCNO_AVAILABLE_REGS_NUM (allocno))
+  if (setup_left_conflict_sizes_p (allocno))
     add_allocno_to_bucket (allocno, &colorable_allocno_bucket);
   else
     add_allocno_to_bucket (allocno, &uncolorable_allocno_bucket);
@@ -1455,8 +2305,8 @@ setup_allocno_priorities (ira_allocno_t *consideration_allocnos, int n)
       allocno_priorities[ALLOCNO_NUM (a)]
        = priority
        = (mult
-          * (ALLOCNO_MEMORY_COST (a) - ALLOCNO_COVER_CLASS_COST (a))
-          * ira_reg_class_nregs[ALLOCNO_COVER_CLASS (a)][ALLOCNO_MODE (a)]);
+          * (ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a))
+          * ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]);
       if (priority < 0)
        priority = -priority;
       if (max_priority < priority)
@@ -1476,6 +2326,242 @@ setup_allocno_priorities (ira_allocno_t *consideration_allocnos, int n)
     }
 }
 
+/* Sort allocnos according to the profit of usage of a hard register
+   instead of memory for them. */
+static int
+allocno_cost_compare_func (const void *v1p, const void *v2p)
+{
+  ira_allocno_t p1 = *(const ira_allocno_t *) v1p;
+  ira_allocno_t p2 = *(const ira_allocno_t *) v2p;
+  int c1, c2;
+
+  c1 = ALLOCNO_UPDATED_MEMORY_COST (p1) - ALLOCNO_UPDATED_CLASS_COST (p1);
+  c2 = ALLOCNO_UPDATED_MEMORY_COST (p2) - ALLOCNO_UPDATED_CLASS_COST (p2);
+  if (c1 - c2)
+    return c1 - c2;
+
+  /* If regs are equally good, sort by allocno numbers, so that the
+     results of qsort leave nothing to chance.  */
+  return ALLOCNO_NUM (p1) - ALLOCNO_NUM (p2);
+}
+
+/* We used Chaitin-Briggs coloring to assign as many pseudos as
+   possible to hard registers.  Let us try to improve allocation with
+   cost point of view.  This function improves the allocation by
+   spilling some allocnos and assigning the freed hard registers to
+   other allocnos if it decreases the overall allocation cost.  */
+static void
+improve_allocation (void)
+{
+  unsigned int i;
+  int j, k, n, hregno, conflict_hregno, base_cost, class_size, word, nwords;
+  int check, spill_cost, min_cost, nregs, conflict_nregs, r, best;
+  bool try_p;
+  enum reg_class aclass;
+  enum machine_mode mode;
+  int *allocno_costs;
+  int costs[FIRST_PSEUDO_REGISTER];
+  HARD_REG_SET conflicting_regs[2], profitable_hard_regs[2];
+  ira_allocno_t a;
+  bitmap_iterator bi;
+
+  /* Clear counts used to process conflicting allocnos only once for
+     each allocno.  */
+  EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
+    ALLOCNO_COLOR_DATA (ira_allocnos[i])->temp = 0;
+  check = n = 0;
+  /* Process each allocno and try to assign a hard register to it by
+     spilling some its conflicting allocnos.  */
+  EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
+    {
+      a = ira_allocnos[i];
+      ALLOCNO_COLOR_DATA (a)->temp = 0;
+      if (empty_profitable_hard_regs (a))
+       continue;
+      check++;
+      aclass = ALLOCNO_CLASS (a);
+      allocno_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a);
+      if (allocno_costs == NULL)
+       allocno_costs = ALLOCNO_HARD_REG_COSTS (a);
+      if ((hregno = ALLOCNO_HARD_REGNO (a)) < 0)
+       base_cost = ALLOCNO_UPDATED_MEMORY_COST (a);
+      else if (allocno_costs == NULL)
+       /* It means that assigning a hard register is not profitable
+          (we don't waste memory for hard register costs in this
+          case).  */
+       continue;
+      else
+       base_cost = allocno_costs[ira_class_hard_reg_index[aclass][hregno]];
+      try_p = false;
+      setup_conflict_profitable_regs (a, false,
+                                     conflicting_regs, profitable_hard_regs);
+      class_size = ira_class_hard_regs_num[aclass];
+      /* Set up cost improvement for usage of each profitable hard
+        register for allocno A.  */
+      for (j = 0; j < class_size; j++)
+       {
+         hregno = ira_class_hard_regs[aclass][j];
+         if (! check_hard_reg_p (a, hregno,
+                                 conflicting_regs, profitable_hard_regs))
+           continue;
+         ira_assert (ira_class_hard_reg_index[aclass][hregno] == j);
+         k = allocno_costs == NULL ? 0 : j;
+         costs[hregno] = (allocno_costs == NULL
+                          ? ALLOCNO_UPDATED_CLASS_COST (a) : allocno_costs[k]);
+         costs[hregno] -= base_cost;
+         if (costs[hregno] < 0)
+           try_p = true;
+       }
+      if (! try_p)
+       /* There is no chance to improve the allocation cost by
+          assigning hard register to allocno A even without spilling
+          conflicting allocnos.  */
+       continue;
+      mode = ALLOCNO_MODE (a);
+      nwords = ALLOCNO_NUM_OBJECTS (a);
+      /* Process each allocno conflicting with A and update the cost
+        improvement for profitable hard registers of A.  To use a
+        hard register for A we need to spill some conflicting
+        allocnos and that creates penalty for the cost
+        improvement.  */
+      for (word = 0; word < nwords; word++)
+       {
+         ira_object_t conflict_obj;
+         ira_object_t obj = ALLOCNO_OBJECT (a, word);
+         ira_object_conflict_iterator oci;
+      
+         FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
+           {
+             ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
+
+             if (ALLOCNO_COLOR_DATA (conflict_a)->temp == check)
+               /* We already processed this conflicting allocno
+                  because we processed earlier another object of the
+                  conflicting allocno.  */
+               continue;
+             ALLOCNO_COLOR_DATA (conflict_a)->temp = check;
+             if ((conflict_hregno = ALLOCNO_HARD_REGNO (conflict_a)) < 0)
+               continue;
+             spill_cost = ALLOCNO_UPDATED_MEMORY_COST (conflict_a);
+             k = (ira_class_hard_reg_index
+                  [ALLOCNO_CLASS (conflict_a)][conflict_hregno]);
+             ira_assert (k >= 0);
+             if ((allocno_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (conflict_a))
+                 != NULL)
+               spill_cost -= allocno_costs[k];
+             else if ((allocno_costs = ALLOCNO_HARD_REG_COSTS (conflict_a))
+                      != NULL)
+               spill_cost -= allocno_costs[k];
+             else
+               spill_cost -= ALLOCNO_UPDATED_CLASS_COST (conflict_a);
+             conflict_nregs
+               = hard_regno_nregs[conflict_hregno][ALLOCNO_MODE (conflict_a)];
+             for (r = conflict_hregno;
+                  r >= 0 && r + hard_regno_nregs[r][mode] > conflict_hregno;
+                  r--)
+               if (check_hard_reg_p (a, r,
+                                     conflicting_regs, profitable_hard_regs))
+                 costs[r] += spill_cost;
+             for (r = conflict_hregno + 1;
+                  r < conflict_hregno + conflict_nregs;
+                  r++)
+               if (check_hard_reg_p (a, r,
+                                     conflicting_regs, profitable_hard_regs))
+                 costs[r] += spill_cost;
+           }
+       }
+      min_cost = INT_MAX;
+      best = -1;
+      /* Now we choose hard register for A which results in highest
+        allocation cost improvement.  */
+      for (j = 0; j < class_size; j++)
+       {
+         hregno = ira_class_hard_regs[aclass][j];
+         if (check_hard_reg_p (a, hregno,
+                               conflicting_regs, profitable_hard_regs)
+             && min_cost > costs[hregno])
+           {
+             best = hregno;
+             min_cost = costs[hregno];
+           }
+       }
+      if (min_cost >= 0)
+       /* We are in a situation when assigning any hard register to A
+          by spilling some conflicting allocnos does not improve the
+          allocation cost.  */
+       continue;
+      nregs = hard_regno_nregs[best][mode];
+      /* Now spill conflicting allocnos which contain a hard register
+        of A when we assign the best chosen hard register to it.  */
+      for (word = 0; word < nwords; word++)
+       {
+         ira_object_t conflict_obj;
+         ira_object_t obj = ALLOCNO_OBJECT (a, word);
+         ira_object_conflict_iterator oci;
+      
+         FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
+           {
+             ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
+
+             if ((conflict_hregno = ALLOCNO_HARD_REGNO (conflict_a)) < 0)
+               continue;
+             conflict_nregs
+               = hard_regno_nregs[conflict_hregno][ALLOCNO_MODE (conflict_a)];
+             if (best + nregs <= conflict_hregno
+                 || conflict_hregno + conflict_nregs <= best)
+               /* No intersection.  */
+               continue;
+             ALLOCNO_HARD_REGNO (conflict_a) = -1;
+             sorted_allocnos[n++] = conflict_a;
+             if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
+               fprintf (ira_dump_file, "Spilling a%dr%d for a%dr%d\n",
+                        ALLOCNO_NUM (conflict_a), ALLOCNO_REGNO (conflict_a),
+                        ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
+           }
+       }
+      /* Assign the best chosen hard register to A.  */
+      ALLOCNO_HARD_REGNO (a) = best;
+      if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
+       fprintf (ira_dump_file, "Assigning %d to a%dr%d\n",
+                best, ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
+    }
+  if (n == 0)
+    return;
+  /* We spilled some allocnos to assign their hard registers to other
+     allocnos.  The spilled allocnos are now in array
+     'sorted_allocnos'.  There is still a possibility that some of the
+     spilled allocnos can get hard registers.  So let us try assign
+     them hard registers again (just a reminder -- function
+     'assign_hard_reg' assigns hard registers only if it is possible
+     and profitable).  We process the spilled allocnos with biggest
+     benefit to get hard register first -- see function
+     'allocno_cost_compare_func'.  */
+  qsort (sorted_allocnos, n, sizeof (ira_allocno_t),
+        allocno_cost_compare_func);
+  for (j = 0; j < n; j++)
+    {
+      a = sorted_allocnos[j];
+      ALLOCNO_ASSIGNED_P (a) = false;
+      if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
+       {
+         fprintf (ira_dump_file, "      ");
+         ira_print_expanded_allocno (a);
+         fprintf (ira_dump_file, "  -- ");
+       }
+      if (assign_hard_reg (a, false))
+       {
+         if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
+           fprintf (ira_dump_file, "assign hard reg %d\n",
+                    ALLOCNO_HARD_REGNO (a));
+       }
+      else
+       {
+         if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
+           fprintf (ira_dump_file, "assign memory\n");
+       }
+    }
+}
+
 /* Sort allocnos according to their priorities which are calculated
    analogous to ones in file `global.c'.  */
 static int
@@ -1510,7 +2596,7 @@ color_allocnos (void)
       EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
        {
          a = ira_allocnos[i];
-         if (ALLOCNO_COVER_CLASS (a) == NO_REGS)
+         if (ALLOCNO_CLASS (a) == NO_REGS)
            {
              ALLOCNO_HARD_REGNO (a) = -1;
              ALLOCNO_ASSIGNED_P (a) = true;
@@ -1556,31 +2642,43 @@ color_allocnos (void)
     }
   else
     {
-      /* Put the allocnos into the corresponding buckets.  */
-      colorable_allocno_bucket = NULL;
-      uncolorable_allocno_bucket = NULL;
+      setup_profitable_hard_regs ();
+      form_object_hard_regs_nodes_forest ();
+      if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
+       print_hard_regs_forest (ira_dump_file);
       EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
        {
          a = ira_allocnos[i];
-         if (ALLOCNO_COVER_CLASS (a) == NO_REGS)
+         if (ALLOCNO_CLASS (a) != NO_REGS && ! empty_profitable_hard_regs (a))
+           ALLOCNO_COLOR_DATA (a)->in_graph_p = true;
+         else
            {
              ALLOCNO_HARD_REGNO (a) = -1;
              ALLOCNO_ASSIGNED_P (a) = true;
-             ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
-             ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) == NULL);
+             /* We don't need updated costs anymore.  */
+             ira_free_allocno_updated_costs (a);
              if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
                {
                  fprintf (ira_dump_file, "      Spill");
                  ira_print_expanded_allocno (a);
                  fprintf (ira_dump_file, "\n");
                }
-             continue;
            }
-         put_allocno_into_bucket (a);
+       }
+      /* Put the allocnos into the corresponding buckets.  */
+      colorable_allocno_bucket = NULL;
+      uncolorable_allocno_bucket = NULL;
+      EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
+       {
+         a = ira_allocnos[i];
+         if (ALLOCNO_COLOR_DATA (a)->in_graph_p)
+           put_allocno_into_bucket (a);
        }
       push_allocnos_to_stack ();
       pop_allocnos_from_stack ();
+      finish_object_hard_regs_nodes_forest ();
     }
+  improve_allocation ();
 }
 
 \f
@@ -1626,15 +2724,15 @@ print_loop_title (ira_loop_tree_node_t loop_tree_node)
   EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->border_allocnos, 0, j, bi)
     fprintf (ira_dump_file, " %dr%d", j, ALLOCNO_REGNO (ira_allocnos[j]));
   fprintf (ira_dump_file, "\n    Pressure:");
-  for (j = 0; (int) j < ira_reg_class_cover_size; j++)
+  for (j = 0; (int) j < ira_pressure_classes_num; j++)
     {
-      enum reg_class cover_class;
+      enum reg_class pclass;
 
-      cover_class = ira_reg_class_cover[j];
-      if (loop_tree_node->reg_pressure[cover_class] == 0)
+      pclass = ira_pressure_classes[j];
+      if (loop_tree_node->reg_pressure[pclass] == 0)
        continue;
-      fprintf (ira_dump_file, " %s=%d", reg_class_names[cover_class],
-              loop_tree_node->reg_pressure[cover_class]);
+      fprintf (ira_dump_file, " %s=%d", reg_class_names[pclass],
+              loop_tree_node->reg_pressure[pclass]);
     }
   fprintf (ira_dump_file, "\n");
 }
@@ -1646,12 +2744,12 @@ print_loop_title (ira_loop_tree_node_t loop_tree_node)
 static void
 color_pass (ira_loop_tree_node_t loop_tree_node)
 {
-  int regno, hard_regno, index = -1;
+  int i, regno, hard_regno, index = -1, n, nobj;
   int cost, exit_freq, enter_freq;
   unsigned int j;
   bitmap_iterator bi;
   enum machine_mode mode;
-  enum reg_class rclass, cover_class;
+  enum reg_class rclass, aclass, pclass;
   ira_allocno_t a, subloop_allocno;
   ira_loop_tree_node_t subloop_node;
 
@@ -1661,11 +2759,35 @@ color_pass (ira_loop_tree_node_t loop_tree_node)
 
   bitmap_copy (coloring_allocno_bitmap, loop_tree_node->all_allocnos);
   bitmap_copy (consideration_allocno_bitmap, coloring_allocno_bitmap);
+  n = nobj = 0;
+  EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
+    {
+      a = ira_allocnos[j];
+      n++;
+      nobj += ALLOCNO_NUM_OBJECTS (a);
+      if (! ALLOCNO_ASSIGNED_P (a))
+       continue;
+      bitmap_clear_bit (coloring_allocno_bitmap, ALLOCNO_NUM (a));
+    }
+  allocno_color_data
+    = (allocno_color_data_t) ira_allocate (sizeof (struct allocno_color_data)
+                                          * n);
+  memset (allocno_color_data, 0, sizeof (struct allocno_color_data) * n);
+  object_color_data
+    = (object_color_data_t) ira_allocate (sizeof (struct object_color_data)
+                                          * nobj);
+  memset (object_color_data, 0, sizeof (struct object_color_data) * nobj);
+  n = nobj = 0;
   EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
     {
       a = ira_allocnos[j];
-      if (ALLOCNO_ASSIGNED_P (a))
-       bitmap_clear_bit (coloring_allocno_bitmap, ALLOCNO_NUM (a));
+      ALLOCNO_ADD_DATA (a) = allocno_color_data + n;
+      n++;
+      for (i = 0; i < ALLOCNO_NUM_OBJECTS (a); i++)
+       {
+         OBJECT_ADD_DATA (ALLOCNO_OBJECT (a, i)) = object_color_data + nobj;
+         nobj++;
+       }
     }
   /* Color all mentioned allocnos including transparent ones.  */
   color_allocnos ();
@@ -1679,10 +2801,11 @@ color_pass (ira_loop_tree_node_t loop_tree_node)
          continue;
        /* Remove from processing in the next loop.  */
        bitmap_clear_bit (consideration_allocno_bitmap, j);
-       rclass = ALLOCNO_COVER_CLASS (a);
+       rclass = ALLOCNO_CLASS (a);
+       pclass = ira_pressure_class_translate[rclass];
        if (flag_ira_region == IRA_REGION_MIXED
-           && (loop_tree_node->reg_pressure[rclass]
-               <= ira_available_class_regs[rclass]))
+           && (loop_tree_node->reg_pressure[pclass]
+               <= ira_available_class_regs[pclass]))
          {
            mode = ALLOCNO_MODE (a);
            hard_regno = ALLOCNO_HARD_REGNO (a);
@@ -1715,7 +2838,8 @@ color_pass (ira_loop_tree_node_t loop_tree_node)
          a = ira_allocnos[j];
          ira_assert (ALLOCNO_CAP_MEMBER (a) == NULL);
          mode = ALLOCNO_MODE (a);
-         rclass = ALLOCNO_COVER_CLASS (a);
+         rclass = ALLOCNO_CLASS (a);
+         pclass = ira_pressure_class_translate[rclass];
          hard_regno = ALLOCNO_HARD_REGNO (a);
          /* Use hard register class here.  ??? */
          if (hard_regno >= 0)
@@ -1729,12 +2853,12 @@ color_pass (ira_loop_tree_node_t loop_tree_node)
          if (subloop_allocno == NULL
              || ALLOCNO_CAP (subloop_allocno) != NULL)
            continue;
-         ira_assert (ALLOCNO_COVER_CLASS (subloop_allocno) == rclass);
+         ira_assert (ALLOCNO_CLASS (subloop_allocno) == rclass);
          ira_assert (bitmap_bit_p (subloop_node->all_allocnos,
                                    ALLOCNO_NUM (subloop_allocno)));
          if ((flag_ira_region == IRA_REGION_MIXED)
-             && (loop_tree_node->reg_pressure[rclass]
-                 <= ira_available_class_regs[rclass]))
+             && (loop_tree_node->reg_pressure[pclass]
+                 <= ira_available_class_regs[pclass]))
            {
              if (! ALLOCNO_ASSIGNED_P (subloop_allocno))
                {
@@ -1771,23 +2895,23 @@ color_pass (ira_loop_tree_node_t loop_tree_node)
            }
          else
            {
-             cover_class = ALLOCNO_COVER_CLASS (subloop_allocno);
-             cost = (ira_get_register_move_cost (mode, rclass, rclass)
+             aclass = ALLOCNO_CLASS (subloop_allocno);
+             ira_init_register_move_cost_if_necessary (mode);
+             cost = (ira_register_move_cost[mode][rclass][rclass]
                      * (exit_freq + enter_freq));
              ira_allocate_and_set_or_copy_costs
-               (&ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno), cover_class,
-                ALLOCNO_UPDATED_COVER_CLASS_COST (subloop_allocno),
+               (&ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno), aclass,
+                ALLOCNO_UPDATED_CLASS_COST (subloop_allocno),
                 ALLOCNO_HARD_REG_COSTS (subloop_allocno));
              ira_allocate_and_set_or_copy_costs
                (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno),
-                cover_class, 0,
-                ALLOCNO_CONFLICT_HARD_REG_COSTS (subloop_allocno));
+                aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (subloop_allocno));
              ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index] -= cost;
              ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno)[index]
                -= cost;
-             if (ALLOCNO_UPDATED_COVER_CLASS_COST (subloop_allocno)
+             if (ALLOCNO_UPDATED_CLASS_COST (subloop_allocno)
                  > ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index])
-               ALLOCNO_UPDATED_COVER_CLASS_COST (subloop_allocno)
+               ALLOCNO_UPDATED_CLASS_COST (subloop_allocno)
                  = ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index];
              ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno)
                += (ira_memory_move_cost[mode][rclass][0] * enter_freq
@@ -1795,6 +2919,15 @@ color_pass (ira_loop_tree_node_t loop_tree_node)
            }
        }
     }
+  ira_free (object_color_data);
+  ira_free (allocno_color_data);
+  EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, j, bi)
+    {
+      a = ira_allocnos[j];
+      ALLOCNO_ADD_DATA (a) = NULL;
+      for (i = 0; i < ALLOCNO_NUM_OBJECTS (a); i++)
+       OBJECT_ADD_DATA (a) = NULL;
+    }
 }
 
 /* Initialize the common data for coloring and calls functions to do
@@ -1803,12 +2936,6 @@ static void
 do_coloring (void)
 {
   coloring_allocno_bitmap = ira_allocate_bitmap ();
-  allocnos_for_spilling
-    = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t)
-                                     * ira_allocnos_num);
-  splay_tree_node_pool = create_alloc_pool ("splay tree nodes",
-                                           sizeof (struct splay_tree_node_s),
-                                           100);
   if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
     fprintf (ira_dump_file, "\n**** Allocnos coloring:\n\n");
 
@@ -1817,9 +2944,7 @@ do_coloring (void)
   if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
     ira_print_disposition (ira_dump_file);
 
-  free_alloc_pool (splay_tree_node_pool);
   ira_free_bitmap (coloring_allocno_bitmap);
-  ira_free (allocnos_for_spilling);
 }
 
 \f
@@ -1863,13 +2988,14 @@ move_spill_restore (void)
              || !bitmap_bit_p (loop_node->border_allocnos, ALLOCNO_NUM (a)))
            continue;
          mode = ALLOCNO_MODE (a);
-         rclass = ALLOCNO_COVER_CLASS (a);
+         rclass = ALLOCNO_CLASS (a);
          index = ira_class_hard_reg_index[rclass][hard_regno];
          ira_assert (index >= 0);
          cost = (ALLOCNO_MEMORY_COST (a)
                  - (ALLOCNO_HARD_REG_COSTS (a) == NULL
-                    ? ALLOCNO_COVER_CLASS_COST (a)
+                    ? ALLOCNO_CLASS_COST (a)
                     : ALLOCNO_HARD_REG_COSTS (a)[index]));
+         ira_init_register_move_cost_if_necessary (mode);
          for (subloop_node = loop_node->subloops;
               subloop_node != NULL;
               subloop_node = subloop_node->subloop_next)
@@ -1878,13 +3004,13 @@ move_spill_restore (void)
              subloop_allocno = subloop_node->regno_allocno_map[regno];
              if (subloop_allocno == NULL)
                continue;
-             ira_assert (rclass == ALLOCNO_COVER_CLASS (subloop_allocno));
+             ira_assert (rclass == ALLOCNO_CLASS (subloop_allocno));
              /* We have accumulated cost.  To get the real cost of
                 allocno usage in the loop we should subtract costs of
                 the subloop allocnos.  */
              cost -= (ALLOCNO_MEMORY_COST (subloop_allocno)
                       - (ALLOCNO_HARD_REG_COSTS (subloop_allocno) == NULL
-                         ? ALLOCNO_COVER_CLASS_COST (subloop_allocno)
+                         ? ALLOCNO_CLASS_COST (subloop_allocno)
                          : ALLOCNO_HARD_REG_COSTS (subloop_allocno)[index]));
              exit_freq = ira_loop_edge_freq (subloop_node, regno, true);
              enter_freq = ira_loop_edge_freq (subloop_node, regno, false);
@@ -1897,14 +3023,14 @@ move_spill_restore (void)
                    += (ira_memory_move_cost[mode][rclass][0] * exit_freq
                        + ira_memory_move_cost[mode][rclass][1] * enter_freq);
                  if (hard_regno2 != hard_regno)
-                   cost -= (ira_get_register_move_cost (mode, rclass, rclass)
+                   cost -= (ira_register_move_cost[mode][rclass][rclass]
                             * (exit_freq + enter_freq));
                }
            }
          if ((parent = loop_node->parent) != NULL
              && (parent_allocno = parent->regno_allocno_map[regno]) != NULL)
            {
-             ira_assert (rclass == ALLOCNO_COVER_CLASS (parent_allocno));
+             ira_assert (rclass == ALLOCNO_CLASS (parent_allocno));
              exit_freq = ira_loop_edge_freq (loop_node, regno, true);
              enter_freq = ira_loop_edge_freq (loop_node, regno, false);
              if ((hard_regno2 = ALLOCNO_HARD_REGNO (parent_allocno)) < 0)
@@ -1916,7 +3042,7 @@ move_spill_restore (void)
                    += (ira_memory_move_cost[mode][rclass][1] * exit_freq
                        + ira_memory_move_cost[mode][rclass][0] * enter_freq);
                  if (hard_regno2 != hard_regno)
-                   cost -= (ira_get_register_move_cost (mode, rclass, rclass)
+                   cost -= (ira_register_move_cost[mode][rclass][rclass]
                             * (exit_freq + enter_freq));
                }
            }
@@ -1949,16 +3075,17 @@ update_curr_costs (ira_allocno_t a)
 {
   int i, hard_regno, cost;
   enum machine_mode mode;
-  enum reg_class cover_class, rclass;
+  enum reg_class aclass, rclass;
   ira_allocno_t another_a;
   ira_copy_t cp, next_cp;
 
   ira_free_allocno_updated_costs (a);
   ira_assert (! ALLOCNO_ASSIGNED_P (a));
-  cover_class = ALLOCNO_COVER_CLASS (a);
-  if (cover_class == NO_REGS)
+  aclass = ALLOCNO_CLASS (a);
+  if (aclass == NO_REGS)
     return;
   mode = ALLOCNO_MODE (a);
+  ira_init_register_move_cost_if_necessary (mode);
   for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
     {
       if (cp->first == a)
@@ -1973,25 +3100,23 @@ update_curr_costs (ira_allocno_t a)
        }
       else
        gcc_unreachable ();
-      if (! ira_reg_classes_intersect_p[cover_class][ALLOCNO_COVER_CLASS
-                                                    (another_a)]
+      if (! ira_reg_classes_intersect_p[aclass][ALLOCNO_CLASS (another_a)]
          || ! ALLOCNO_ASSIGNED_P (another_a)
          || (hard_regno = ALLOCNO_HARD_REGNO (another_a)) < 0)
        continue;
       rclass = REGNO_REG_CLASS (hard_regno);
-      i = ira_class_hard_reg_index[cover_class][hard_regno];
+      i = ira_class_hard_reg_index[aclass][hard_regno];
       if (i < 0)
        continue;
       cost = (cp->first == a
-             ? ira_get_register_move_cost (mode, rclass, cover_class)
-             : ira_get_register_move_cost (mode, cover_class, rclass));
+             ? ira_register_move_cost[mode][rclass][aclass]
+             : ira_register_move_cost[mode][aclass][rclass]);
       ira_allocate_and_set_or_copy_costs
-       (&ALLOCNO_UPDATED_HARD_REG_COSTS (a),
-        cover_class, ALLOCNO_COVER_CLASS_COST (a),
+       (&ALLOCNO_UPDATED_HARD_REG_COSTS (a), aclass, ALLOCNO_CLASS_COST (a),
         ALLOCNO_HARD_REG_COSTS (a));
       ira_allocate_and_set_or_copy_costs
        (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a),
-        cover_class, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (a));
+        aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (a));
       ALLOCNO_UPDATED_HARD_REG_COSTS (a)[i] -= cp->freq * cost;
       ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a)[i] -= cp->freq * cost;
     }
@@ -2008,7 +3133,7 @@ ira_reassign_conflict_allocnos (int start_regno)
 {
   int i, allocnos_to_color_num;
   ira_allocno_t a;
-  enum reg_class cover_class;
+  enum reg_class aclass;
   bitmap allocnos_to_color;
   ira_allocno_iterator ai;
 
@@ -2021,7 +3146,7 @@ ira_reassign_conflict_allocnos (int start_regno)
       if (! ALLOCNO_ASSIGNED_P (a)
          && ! bitmap_bit_p (allocnos_to_color, ALLOCNO_NUM (a)))
        {
-         if (ALLOCNO_COVER_CLASS (a) != NO_REGS)
+         if (ALLOCNO_CLASS (a) != NO_REGS)
            sorted_allocnos[allocnos_to_color_num++] = a;
          else
            {
@@ -2033,18 +3158,20 @@ ira_reassign_conflict_allocnos (int start_regno)
          bitmap_set_bit (allocnos_to_color, ALLOCNO_NUM (a));
        }
       if (ALLOCNO_REGNO (a) < start_regno
-         || (cover_class = ALLOCNO_COVER_CLASS (a)) == NO_REGS)
+         || (aclass = ALLOCNO_CLASS (a)) == NO_REGS)
        continue;
       for (i = 0; i < n; i++)
        {
          ira_object_t obj = ALLOCNO_OBJECT (a, i);
          ira_object_t conflict_obj;
          ira_object_conflict_iterator oci;
+
          FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
            {
              ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
+
              ira_assert (ira_reg_classes_intersect_p
-                         [cover_class][ALLOCNO_COVER_CLASS (conflict_a)]);
+                         [aclass][ALLOCNO_CLASS (conflict_a)]);
              if (!bitmap_set_bit (allocnos_to_color, ALLOCNO_NUM (conflict_a)))
                continue;
              sorted_allocnos[allocnos_to_color_num++] = conflict_a;
@@ -2080,6 +3207,68 @@ ira_reassign_conflict_allocnos (int start_regno)
 
 \f
 
+/* This page contains functions used to find conflicts using allocno
+   live ranges.  */
+
+/* Return TRUE if live ranges of allocnos A1 and A2 intersect.  It is
+   used to find a conflict for new allocnos or allocnos with the
+   different allocno classes.  */
+static bool
+allocnos_conflict_by_live_ranges_p (ira_allocno_t a1, ira_allocno_t a2)
+{
+  rtx reg1, reg2;
+  int i, j;
+  int n1 = ALLOCNO_NUM_OBJECTS (a1);
+  int n2 = ALLOCNO_NUM_OBJECTS (a2);
+
+  if (a1 == a2)
+    return false;
+  reg1 = regno_reg_rtx[ALLOCNO_REGNO (a1)];
+  reg2 = regno_reg_rtx[ALLOCNO_REGNO (a2)];
+  if (reg1 != NULL && reg2 != NULL
+      && ORIGINAL_REGNO (reg1) == ORIGINAL_REGNO (reg2))
+    return false;
+
+  for (i = 0; i < n1; i++)
+    {
+      ira_object_t c1 = ALLOCNO_OBJECT (a1, i);
+
+      for (j = 0; j < n2; j++)
+       {
+         ira_object_t c2 = ALLOCNO_OBJECT (a2, j);
+
+         if (ira_live_ranges_intersect_p (OBJECT_LIVE_RANGES (c1),
+                                          OBJECT_LIVE_RANGES (c2)))
+           return true;
+       }
+    }
+  return false;
+}
+
+#ifdef ENABLE_IRA_CHECKING
+
+/* Return TRUE if live ranges of pseudo-registers REGNO1 and REGNO2
+   intersect.  This should be used when there is only one region.
+   Currently this is used during reload.  */
+static bool
+conflict_by_live_ranges_p (int regno1, int regno2)
+{
+  ira_allocno_t a1, a2;
+
+  ira_assert (regno1 >= FIRST_PSEUDO_REGISTER
+             && regno2 >= FIRST_PSEUDO_REGISTER);
+  /* Reg info caclulated by dataflow infrastructure can be different
+     from one calculated by regclass.  */
+  if ((a1 = ira_loop_tree_root->regno_allocno_map[regno1]) == NULL
+      || (a2 = ira_loop_tree_root->regno_allocno_map[regno2]) == NULL)
+    return false;
+  return allocnos_conflict_by_live_ranges_p (a1, a2);
+}
+
+#endif
+
+\f
+
 /* This page contains code to coalesce memory stack slots used by
    spilled allocnos.  This results in smaller stack frame, better data
    locality, and in smaller code for some architectures like
@@ -2096,6 +3285,27 @@ static bool allocno_coalesced_p;
    coalescing.  */
 static bitmap processed_coalesced_allocno_bitmap;
 
+/* See below.  */
+typedef struct coalesce_data *coalesce_data_t;
+
+/* To decrease footprint of ira_allocno structure we store all data
+   needed only for coalescing in the following structure.  */
+struct coalesce_data
+{
+  /* Coalesced allocnos form a cyclic list.  One allocno given by
+     FIRST represents all coalesced allocnos.  The
+     list is chained by NEXT.  */
+  ira_allocno_t first;
+  ira_allocno_t next;
+  int temp;
+};
+
+/* Container for storing allocno data concerning coalescing.  */
+static coalesce_data_t allocno_coalesce_data;
+
+/* Macro to access the data concerning coalescing.  */
+#define ALLOCNO_COALESCE_DATA(a) ((coalesce_data_t) ALLOCNO_ADD_DATA (a))
+
 /* The function is used to sort allocnos according to their execution
    frequencies.  */
 static int
@@ -2122,58 +3332,55 @@ merge_allocnos (ira_allocno_t a1, ira_allocno_t a2)
 {
   ira_allocno_t a, first, last, next;
 
-  first = ALLOCNO_FIRST_COALESCED_ALLOCNO (a1);
-  if (first == ALLOCNO_FIRST_COALESCED_ALLOCNO (a2))
+  first = ALLOCNO_COALESCE_DATA (a1)->first;
+  a = ALLOCNO_COALESCE_DATA (a2)->first;
+  if (first == a)
     return;
-  for (last = a2, a = ALLOCNO_NEXT_COALESCED_ALLOCNO (a2);;
-       a = ALLOCNO_NEXT_COALESCED_ALLOCNO (a))
+  for (last = a2, a = ALLOCNO_COALESCE_DATA (a2)->next;;
+       a = ALLOCNO_COALESCE_DATA (a)->next)
     {
-      ALLOCNO_FIRST_COALESCED_ALLOCNO (a) = first;
+      ALLOCNO_COALESCE_DATA (a)->first = first;
       if (a == a2)
        break;
       last = a;
     }
-  next = ALLOCNO_NEXT_COALESCED_ALLOCNO (first);
-  ALLOCNO_NEXT_COALESCED_ALLOCNO (first) = a2;
-  ALLOCNO_NEXT_COALESCED_ALLOCNO (last) = next;
+  next = allocno_coalesce_data[ALLOCNO_NUM (first)].next;
+  allocno_coalesce_data[ALLOCNO_NUM (first)].next = a2;
+  allocno_coalesce_data[ALLOCNO_NUM (last)].next = next;
 }
 
-/* Given two sets of coalesced sets of allocnos, A1 and A2, this
-   function determines if any conflicts exist between the two sets.
-   We use live ranges to find conflicts because conflicts are
-   represented only for allocnos of the same cover class and during
-   the reload pass we coalesce allocnos for sharing stack memory
-   slots.  */
+/* Return TRUE if there are conflicting allocnos from two sets of
+   coalesced allocnos given correspondingly by allocnos A1 and A2.  We
+   use live ranges to find conflicts because conflicts are represented
+   only for allocnos of the same allocno class and during the reload
+   pass we coalesce allocnos for sharing stack memory slots.  */
 static bool
 coalesced_allocno_conflict_p (ira_allocno_t a1, ira_allocno_t a2)
 {
-  ira_allocno_t a, conflict_allocno;
+  ira_allocno_t a, conflict_a;
 
-  bitmap_clear (processed_coalesced_allocno_bitmap);
   if (allocno_coalesced_p)
     {
-      for (a = ALLOCNO_NEXT_COALESCED_ALLOCNO (a1);;
-          a = ALLOCNO_NEXT_COALESCED_ALLOCNO (a))
+      bitmap_clear (processed_coalesced_allocno_bitmap);
+      for (a = ALLOCNO_COALESCE_DATA (a1)->next;;
+          a = ALLOCNO_COALESCE_DATA (a)->next)
        {
-         bitmap_set_bit (processed_coalesced_allocno_bitmap,
-                         OBJECT_CONFLICT_ID (ALLOCNO_OBJECT (a, 0)));
+         bitmap_set_bit (processed_coalesced_allocno_bitmap, ALLOCNO_NUM (a));
          if (a == a1)
            break;
        }
     }
-  for (a = ALLOCNO_NEXT_COALESCED_ALLOCNO (a2);;
-       a = ALLOCNO_NEXT_COALESCED_ALLOCNO (a))
+  for (a = ALLOCNO_COALESCE_DATA (a2)->next;;
+       a = ALLOCNO_COALESCE_DATA (a)->next)
     {
-      for (conflict_allocno = ALLOCNO_NEXT_COALESCED_ALLOCNO (a1);;
-          conflict_allocno
-            = ALLOCNO_NEXT_COALESCED_ALLOCNO (conflict_allocno))
+      for (conflict_a = ALLOCNO_COALESCE_DATA (a1)->next;;
+          conflict_a = ALLOCNO_COALESCE_DATA (conflict_a)->next)
        {
-         if (allocnos_have_intersected_live_ranges_p (a, conflict_allocno))
+         if (allocnos_conflict_by_live_ranges_p (a, conflict_a))
            return true;
-         if (conflict_allocno == a1)
+         if (conflict_a == a1)
            break;
        }
-
       if (a == a2)
        break;
     }
@@ -2212,7 +3419,7 @@ coalesce_allocnos (void)
              next_cp = cp->next_first_allocno_copy;
              regno = ALLOCNO_REGNO (cp->second);
              /* For priority coloring we coalesce allocnos only with
-                the same cover class not with intersected cover
+                the same allocno class not with intersected allocno
                 classes as it were possible.  It is done for
                 simplicity.  */
              if ((cp->insn != NULL || cp->constraint_p)
@@ -2255,8 +3462,8 @@ coalesce_allocnos (void)
       for (n = 0; i < cp_num; i++)
        {
          cp = sorted_copies[i];
-         if (ALLOCNO_FIRST_COALESCED_ALLOCNO (cp->first)
-             != ALLOCNO_FIRST_COALESCED_ALLOCNO (cp->second))
+         if (allocno_coalesce_data[ALLOCNO_NUM (cp->first)].first
+             != allocno_coalesce_data[ALLOCNO_NUM (cp->second)].first)
            sorted_copies[n++] = cp;
        }
       cp_num = n;
@@ -2326,8 +3533,10 @@ coalesced_pseudo_reg_slot_compare (const void *v1p, const void *v2p)
   if ((diff = slot_num1 - slot_num2) != 0)
     return (frame_pointer_needed
            || !FRAME_GROWS_DOWNWARD == STACK_GROWS_DOWNWARD ? diff : -diff);
-  total_size1 = MAX (PSEUDO_REGNO_BYTES (regno1), regno_max_ref_width[regno1]);
-  total_size2 = MAX (PSEUDO_REGNO_BYTES (regno2), regno_max_ref_width[regno2]);
+  total_size1 = MAX (PSEUDO_REGNO_BYTES (regno1),
+                    regno_max_ref_width[regno1]);
+  total_size2 = MAX (PSEUDO_REGNO_BYTES (regno2),
+                    regno_max_ref_width[regno2]);
   if ((diff = total_size2 - total_size1) != 0)
     return diff;
   return regno1 - regno2;
@@ -2352,18 +3561,18 @@ setup_coalesced_allocno_costs_and_nums (int *pseudo_regnos, int n)
          regno_coalesced_allocno_num[regno] = ++num;
          continue;
        }
-      if (ALLOCNO_FIRST_COALESCED_ALLOCNO (allocno) != allocno)
+      if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno)
        continue;
       num++;
-      for (cost = 0, a = ALLOCNO_NEXT_COALESCED_ALLOCNO (allocno);;
-          a = ALLOCNO_NEXT_COALESCED_ALLOCNO (a))
+      for (cost = 0, a = ALLOCNO_COALESCE_DATA (allocno)->next;;
+          a = ALLOCNO_COALESCE_DATA (a)->next)
        {
          cost += ALLOCNO_FREQ (a);
          if (a == allocno)
            break;
        }
-      for (a = ALLOCNO_NEXT_COALESCED_ALLOCNO (allocno);;
-          a = ALLOCNO_NEXT_COALESCED_ALLOCNO (a))
+      for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
+          a = ALLOCNO_COALESCE_DATA (a)->next)
        {
          regno_coalesced_allocno_num[ALLOCNO_REGNO (a)] = num;
          regno_coalesced_allocno_cost[ALLOCNO_REGNO (a)] = cost;
@@ -2390,7 +3599,7 @@ collect_spilled_coalesced_allocnos (int *pseudo_regnos, int n,
       regno = pseudo_regnos[i];
       allocno = ira_regno_allocno_map[regno];
       if (allocno == NULL || ALLOCNO_HARD_REGNO (allocno) >= 0
-         || ALLOCNO_FIRST_COALESCED_ALLOCNO (allocno) != allocno)
+         || ALLOCNO_COALESCE_DATA (allocno)->first != allocno)
        continue;
       spilled_coalesced_allocnos[num++] = allocno;
     }
@@ -2410,16 +3619,19 @@ slot_coalesced_allocno_live_ranges_intersect_p (ira_allocno_t allocno, int n)
 {
   ira_allocno_t a;
 
-  for (a = ALLOCNO_NEXT_COALESCED_ALLOCNO (allocno);;
-       a = ALLOCNO_NEXT_COALESCED_ALLOCNO (a))
+  for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
+       a = ALLOCNO_COALESCE_DATA (a)->next)
     {
       int i;
       int nr = ALLOCNO_NUM_OBJECTS (a);
+
       for (i = 0; i < nr; i++)
        {
          ira_object_t obj = ALLOCNO_OBJECT (a, i);
-         if (ira_live_ranges_intersect_p (slot_coalesced_allocnos_live_ranges[n],
-                                          OBJECT_LIVE_RANGES (obj)))
+
+         if (ira_live_ranges_intersect_p
+             (slot_coalesced_allocnos_live_ranges[n],
+              OBJECT_LIVE_RANGES (obj)))
            return true;
        }
       if (a == allocno)
@@ -2437,18 +3649,19 @@ setup_slot_coalesced_allocno_live_ranges (ira_allocno_t allocno)
   ira_allocno_t a;
   live_range_t r;
 
-  n = ALLOCNO_TEMP (allocno);
-  for (a = ALLOCNO_NEXT_COALESCED_ALLOCNO (allocno);;
-       a = ALLOCNO_NEXT_COALESCED_ALLOCNO (a))
+  n = ALLOCNO_COALESCE_DATA (allocno)->temp;
+  for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
+       a = ALLOCNO_COALESCE_DATA (a)->next)
     {
       int nr = ALLOCNO_NUM_OBJECTS (a);
       for (i = 0; i < nr; i++)
        {
          ira_object_t obj = ALLOCNO_OBJECT (a, i);
+
          r = ira_copy_live_range_list (OBJECT_LIVE_RANGES (obj));
          slot_coalesced_allocnos_live_ranges[n]
            = ira_merge_live_ranges
-           (slot_coalesced_allocnos_live_ranges[n], r);
+             (slot_coalesced_allocnos_live_ranges[n], r);
        }
       if (a == allocno)
        break;
@@ -2478,7 +3691,7 @@ coalesce_spill_slots (ira_allocno_t *spilled_coalesced_allocnos, int num)
   for (i = 0; i < num; i++)
     {
       allocno = spilled_coalesced_allocnos[i];
-      if (ALLOCNO_FIRST_COALESCED_ALLOCNO (allocno) != allocno
+      if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno
          || bitmap_bit_p (set_jump_crosses, ALLOCNO_REGNO (allocno))
          || (ALLOCNO_REGNO (allocno) < ira_reg_equiv_len
              && (ira_reg_equiv_const[ALLOCNO_REGNO (allocno)] != NULL_RTX
@@ -2487,8 +3700,8 @@ coalesce_spill_slots (ira_allocno_t *spilled_coalesced_allocnos, int num)
       for (j = 0; j < i; j++)
        {
          a = spilled_coalesced_allocnos[j];
-         n = ALLOCNO_TEMP (a);
-         if (ALLOCNO_FIRST_COALESCED_ALLOCNO (a) == a
+         n = ALLOCNO_COALESCE_DATA (a)->temp;
+         if (ALLOCNO_COALESCE_DATA (a)->first == a
              && ! bitmap_bit_p (set_jump_crosses, ALLOCNO_REGNO (a))
              && (ALLOCNO_REGNO (a) >= ira_reg_equiv_len
                  || (! ira_reg_equiv_invariant_p[ALLOCNO_REGNO (a)]
@@ -2500,7 +3713,7 @@ coalesce_spill_slots (ira_allocno_t *spilled_coalesced_allocnos, int num)
        {
          /* No coalescing: set up number for coalesced allocnos
             represented by ALLOCNO.  */
-         ALLOCNO_TEMP (allocno) = last_coalesced_allocno_num++;
+         ALLOCNO_COALESCE_DATA (allocno)->temp = last_coalesced_allocno_num++;
          setup_slot_coalesced_allocno_live_ranges (allocno);
        }
       else
@@ -2512,10 +3725,11 @@ coalesce_spill_slots (ira_allocno_t *spilled_coalesced_allocnos, int num)
                     "      Coalescing spilled allocnos a%dr%d->a%dr%d\n",
                     ALLOCNO_NUM (allocno), ALLOCNO_REGNO (allocno),
                     ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
-         ALLOCNO_TEMP (allocno) = ALLOCNO_TEMP (a);
+         ALLOCNO_COALESCE_DATA (allocno)->temp
+           = ALLOCNO_COALESCE_DATA (a)->temp;
          setup_slot_coalesced_allocno_live_ranges (allocno);
          merge_allocnos (a, allocno);
-         ira_assert (ALLOCNO_FIRST_COALESCED_ALLOCNO (a) == a);
+         ira_assert (ALLOCNO_COALESCE_DATA (a)->first == a);
        }
     }
   for (i = 0; i < ira_allocnos_num; i++)
@@ -2546,11 +3760,20 @@ ira_sort_regnos_for_alter_reg (int *pseudo_regnos, int n,
       regno = pseudo_regnos[i];
       allocno = ira_regno_allocno_map[regno];
       if (allocno != NULL)
-       bitmap_set_bit (coloring_allocno_bitmap,
-                       ALLOCNO_NUM (allocno));
+       bitmap_set_bit (coloring_allocno_bitmap, ALLOCNO_NUM (allocno));
     }
   allocno_coalesced_p = false;
   processed_coalesced_allocno_bitmap = ira_allocate_bitmap ();
+  allocno_coalesce_data
+    = (coalesce_data_t) ira_allocate (sizeof (struct coalesce_data)
+                                     * ira_allocnos_num);
+  /* Initialize coalesce data for allocnos.  */
+  FOR_EACH_ALLOCNO (a, ai)
+    {
+      ALLOCNO_ADD_DATA (a) = allocno_coalesce_data + ALLOCNO_NUM (a);
+      ALLOCNO_COALESCE_DATA (a)->first = a;
+      ALLOCNO_COALESCE_DATA (a)->next = a;
+    }
   coalesce_allocnos ();
   ira_free_bitmap (coloring_allocno_bitmap);
   regno_coalesced_allocno_cost
@@ -2588,7 +3811,7 @@ ira_sort_regnos_for_alter_reg (int *pseudo_regnos, int n,
   for (i = 0; i < num; i++)
     {
       allocno = spilled_coalesced_allocnos[i];
-      if (ALLOCNO_FIRST_COALESCED_ALLOCNO (allocno) != allocno
+      if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno
          || ALLOCNO_HARD_REGNO (allocno) >= 0
          || (ALLOCNO_REGNO (allocno) < ira_reg_equiv_len
              && (ira_reg_equiv_const[ALLOCNO_REGNO (allocno)] != NULL_RTX
@@ -2597,8 +3820,8 @@ ira_sort_regnos_for_alter_reg (int *pseudo_regnos, int n,
       if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
        fprintf (ira_dump_file, "      Slot %d (freq,size):", slot_num);
       slot_num++;
-      for (a = ALLOCNO_NEXT_COALESCED_ALLOCNO (allocno);;
-          a = ALLOCNO_NEXT_COALESCED_ALLOCNO (a))
+      for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
+          a = ALLOCNO_COALESCE_DATA (a)->next)
        {
          ira_assert (ALLOCNO_HARD_REGNO (a) < 0);
          ALLOCNO_HARD_REGNO (a) = -slot_num;
@@ -2619,13 +3842,9 @@ ira_sort_regnos_for_alter_reg (int *pseudo_regnos, int n,
   /* Sort regnos according the slot numbers.  */
   regno_max_ref_width = reg_max_ref_width;
   qsort (pseudo_regnos, n, sizeof (int), coalesced_pseudo_reg_slot_compare);
-  /* Uncoalesce allocnos which is necessary for (re)assigning during
-     the reload pass.  */
   FOR_EACH_ALLOCNO (a, ai)
-    {
-      ALLOCNO_FIRST_COALESCED_ALLOCNO (a) = a;
-      ALLOCNO_NEXT_COALESCED_ALLOCNO (a) = a;
-    }
+    ALLOCNO_ADD_DATA (a) = NULL;
+  ira_free (allocno_coalesce_data);
   ira_free (regno_coalesced_allocno_num);
   ira_free (regno_coalesced_allocno_cost);
 }
@@ -2643,7 +3862,7 @@ ira_mark_allocation_change (int regno)
 {
   ira_allocno_t a = ira_regno_allocno_map[regno];
   int old_hard_regno, hard_regno, cost;
-  enum reg_class cover_class = ALLOCNO_COVER_CLASS (a);
+  enum reg_class aclass = ALLOCNO_CLASS (a);
 
   ira_assert (a != NULL);
   hard_regno = reg_renumber[regno];
@@ -2653,11 +3872,11 @@ ira_mark_allocation_change (int regno)
     cost = -ALLOCNO_MEMORY_COST (a);
   else
     {
-      ira_assert (ira_class_hard_reg_index[cover_class][old_hard_regno] >= 0);
+      ira_assert (ira_class_hard_reg_index[aclass][old_hard_regno] >= 0);
       cost = -(ALLOCNO_HARD_REG_COSTS (a) == NULL
-              ? ALLOCNO_COVER_CLASS_COST (a)
+              ? ALLOCNO_CLASS_COST (a)
               : ALLOCNO_HARD_REG_COSTS (a)
-                [ira_class_hard_reg_index[cover_class][old_hard_regno]]);
+                [ira_class_hard_reg_index[aclass][old_hard_regno]]);
       update_copy_costs (a, false);
     }
   ira_overall_cost -= cost;
@@ -2667,12 +3886,12 @@ ira_mark_allocation_change (int regno)
       ALLOCNO_HARD_REGNO (a) = -1;
       cost += ALLOCNO_MEMORY_COST (a);
     }
-  else if (ira_class_hard_reg_index[cover_class][hard_regno] >= 0)
+  else if (ira_class_hard_reg_index[aclass][hard_regno] >= 0)
     {
       cost += (ALLOCNO_HARD_REG_COSTS (a) == NULL
-              ? ALLOCNO_COVER_CLASS_COST (a)
+              ? ALLOCNO_CLASS_COST (a)
               : ALLOCNO_HARD_REG_COSTS (a)
-                [ira_class_hard_reg_index[cover_class][hard_regno]]);
+                [ira_class_hard_reg_index[aclass][hard_regno]]);
       update_copy_costs (a, true);
     }
   else
@@ -2704,7 +3923,7 @@ static bool
 allocno_reload_assign (ira_allocno_t a, HARD_REG_SET forbidden_regs)
 {
   int hard_regno;
-  enum reg_class cover_class;
+  enum reg_class aclass;
   int regno = ALLOCNO_REGNO (a);
   HARD_REG_SET saved[2];
   int i, n;
@@ -2720,7 +3939,7 @@ allocno_reload_assign (ira_allocno_t a, HARD_REG_SET forbidden_regs)
                          call_used_reg_set);
     }
   ALLOCNO_ASSIGNED_P (a) = false;
-  cover_class = ALLOCNO_COVER_CLASS (a);
+  aclass = ALLOCNO_CLASS (a);
   update_curr_costs (a);
   assign_hard_reg (a, true);
   hard_regno = ALLOCNO_HARD_REGNO (a);
@@ -2729,13 +3948,13 @@ allocno_reload_assign (ira_allocno_t a, HARD_REG_SET forbidden_regs)
     ALLOCNO_HARD_REGNO (a) = -1;
   else
     {
-      ira_assert (ira_class_hard_reg_index[cover_class][hard_regno] >= 0);
-      ira_overall_cost -= (ALLOCNO_MEMORY_COST (a)
-                          - (ALLOCNO_HARD_REG_COSTS (a) == NULL
-                             ? ALLOCNO_COVER_CLASS_COST (a)
-                             : ALLOCNO_HARD_REG_COSTS (a)
-                               [ira_class_hard_reg_index
-                                [cover_class][hard_regno]]));
+      ira_assert (ira_class_hard_reg_index[aclass][hard_regno] >= 0);
+      ira_overall_cost
+       -= (ALLOCNO_MEMORY_COST (a)
+           - (ALLOCNO_HARD_REG_COSTS (a) == NULL
+              ? ALLOCNO_CLASS_COST (a)
+              : ALLOCNO_HARD_REG_COSTS (a)[ira_class_hard_reg_index
+                                           [aclass][hard_regno]]));
       if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0
          && ! ira_hard_reg_not_in_set_p (hard_regno, ALLOCNO_MODE (a),
                                          call_used_reg_set))
@@ -2856,7 +4075,7 @@ ira_reassign_pseudos (int *spilled_pseudo_regs, int num,
        fprintf (ira_dump_file,
                 "      Try Assign %d(a%d), cost=%d", regno, ALLOCNO_NUM (a),
                 ALLOCNO_MEMORY_COST (a)
-                - ALLOCNO_COVER_CLASS_COST (a));
+                - ALLOCNO_CLASS_COST (a));
       allocno_reload_assign (a, forbidden_regs);
       if (reg_renumber[regno] >= 0)
        {
@@ -2917,8 +4136,8 @@ ira_reuse_stack_slot (int regno, unsigned int inherent_size,
                                    FIRST_PSEUDO_REGISTER, i, bi)
            {
              another_allocno = ira_regno_allocno_map[i];
-             if (allocnos_have_intersected_live_ranges_p (allocno,
-                                                          another_allocno))
+             if (allocnos_conflict_by_live_ranges_p (allocno,
+                                                     another_allocno))
                goto cont;
            }
          for (cost = 0, cp = ALLOCNO_COPIES (allocno);
@@ -2967,7 +4186,7 @@ ira_reuse_stack_slot (int regno, unsigned int inherent_size,
       EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
                                FIRST_PSEUDO_REGISTER, i, bi)
        {
-         ira_assert (! pseudos_have_intersected_live_ranges_p (regno, i));
+         ira_assert (! conflict_by_live_ranges_p (regno, i));
        }
 #endif
       SET_REGNO_REG_SET (&slot->spilled_regs, regno);
@@ -3046,7 +4265,7 @@ calculate_spill_cost (int *regnos, rtx in, rtx out, rtx insn,
       ira_assert (hard_regno >= 0);
       a = ira_regno_allocno_map[regno];
       length += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a) / ALLOCNO_NUM_OBJECTS (a);
-      cost += ALLOCNO_MEMORY_COST (a) - ALLOCNO_COVER_CLASS_COST (a);
+      cost += ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a);
       nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (a)];
       for (j = 0; j < nregs; j++)
        if (! TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + j))
@@ -3061,11 +4280,11 @@ calculate_spill_cost (int *regnos, rtx in, rtx out, rtx insn,
          saved_cost = 0;
          if (in_p)
            saved_cost += ira_memory_move_cost
-                         [ALLOCNO_MODE (a)][ALLOCNO_COVER_CLASS (a)][1];
+                         [ALLOCNO_MODE (a)][ALLOCNO_CLASS (a)][1];
          if (out_p)
            saved_cost
              += ira_memory_move_cost
-                [ALLOCNO_MODE (a)][ALLOCNO_COVER_CLASS (a)][0];
+                [ALLOCNO_MODE (a)][ALLOCNO_CLASS (a)][0];
          cost -= REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn)) * saved_cost;
        }
     }
@@ -3151,13 +4370,10 @@ static void
 color (void)
 {
   allocno_stack_vec = VEC_alloc (ira_allocno_t, heap, ira_allocnos_num);
-  removed_splay_allocno_vec
-    = VEC_alloc (ira_allocno_t, heap, ira_allocnos_num);
   memset (allocated_hardreg_p, 0, sizeof (allocated_hardreg_p));
   ira_initiate_assign ();
   do_coloring ();
   ira_finish_assign ();
-  VEC_free (ira_allocno_t, heap, removed_splay_allocno_vec);
   VEC_free (ira_allocno_t, heap, allocno_stack_vec);
   move_spill_restore ();
 }
@@ -3177,7 +4393,7 @@ fast_allocation (void)
 #ifdef STACK_REGS
   bool no_stack_reg_p;
 #endif
-  enum reg_class cover_class;
+  enum reg_class aclass;
   enum machine_mode mode;
   ira_allocno_t a;
   ira_allocno_iterator ai;
@@ -3213,20 +4429,20 @@ fast_allocation (void)
            for (j = r->start; j <= r->finish; j++)
              IOR_HARD_REG_SET (conflict_hard_regs, used_hard_regs[j]);
        }
-      cover_class = ALLOCNO_COVER_CLASS (a);
+      aclass = ALLOCNO_CLASS (a);
       ALLOCNO_ASSIGNED_P (a) = true;
       ALLOCNO_HARD_REGNO (a) = -1;
-      if (hard_reg_set_subset_p (reg_class_contents[cover_class],
+      if (hard_reg_set_subset_p (reg_class_contents[aclass],
                                 conflict_hard_regs))
        continue;
       mode = ALLOCNO_MODE (a);
 #ifdef STACK_REGS
       no_stack_reg_p = ALLOCNO_NO_STACK_REG_P (a);
 #endif
-      class_size = ira_class_hard_regs_num[cover_class];
+      class_size = ira_class_hard_regs_num[aclass];
       for (j = 0; j < class_size; j++)
        {
-         hard_regno = ira_class_hard_regs[cover_class][j];
+         hard_regno = ira_class_hard_regs[aclass][j];
 #ifdef STACK_REGS
          if (no_stack_reg_p && FIRST_STACK_REG <= hard_regno
              && hard_regno <= LAST_STACK_REG)
@@ -3234,7 +4450,7 @@ fast_allocation (void)
 #endif
          if (!ira_hard_reg_not_in_set_p (hard_regno, mode, conflict_hard_regs)
              || (TEST_HARD_REG_BIT
-                 (prohibited_class_mode_regs[cover_class][mode], hard_regno)))
+                 (ira_prohibited_class_mode_regs[aclass][mode], hard_regno)))
            continue;
          ALLOCNO_HARD_REGNO (a) = hard_regno;
          for (l = 0; l < nr; l++)
@@ -3268,7 +4484,7 @@ ira_color (void)
   FOR_EACH_ALLOCNO (a, ai)
     {
       ALLOCNO_UPDATED_MEMORY_COST (a) = ALLOCNO_MEMORY_COST (a);
-      ALLOCNO_UPDATED_COVER_CLASS_COST (a) = ALLOCNO_COVER_CLASS_COST (a);
+      ALLOCNO_UPDATED_CLASS_COST (a) = ALLOCNO_CLASS_COST (a);
     }
   if (ira_conflicts_p)
     color ();
index 498b38b..04d881e 100644 (file)
@@ -97,7 +97,7 @@ build_conflict_bit_table (void)
 {
   int i;
   unsigned int j;
-  enum reg_class cover_class;
+  enum reg_class aclass;
   int object_set_words, allocated_words_num, conflict_bit_vec_words_num;
   live_range_t r;
   ira_allocno_t allocno;
@@ -170,15 +170,15 @@ build_conflict_bit_table (void)
 
          gcc_assert (id < ira_objects_num);
 
-         cover_class = ALLOCNO_COVER_CLASS (allocno);
+         aclass = ALLOCNO_CLASS (allocno);
          sparseset_set_bit (objects_live, id);
          EXECUTE_IF_SET_IN_SPARSESET (objects_live, j)
            {
              ira_object_t live_obj = ira_object_id_map[j];
              ira_allocno_t live_a = OBJECT_ALLOCNO (live_obj);
-             enum reg_class live_cover_class = ALLOCNO_COVER_CLASS (live_a);
+             enum reg_class live_aclass = ALLOCNO_CLASS (live_a);
 
-             if (ira_reg_classes_intersect_p[cover_class][live_cover_class]
+             if (ira_reg_classes_intersect_p[aclass][live_aclass]
                  /* Don't set up conflict for the allocno with itself.  */
                  && live_a != allocno)
                {
@@ -205,6 +205,7 @@ allocnos_conflict_for_copy_p (ira_allocno_t a1, ira_allocno_t a2)
      the lowest order words.  */
   ira_object_t obj1 = ALLOCNO_OBJECT (a1, 0);
   ira_object_t obj2 = ALLOCNO_OBJECT (a2, 0);
+
   return OBJECTS_CONFLICT_P (obj1, obj2);
 }
 
@@ -389,7 +390,7 @@ process_regs_for_copy (rtx reg1, rtx reg2, bool constraint_p,
   int allocno_preferenced_hard_regno, cost, index, offset1, offset2;
   bool only_regs_p;
   ira_allocno_t a;
-  enum reg_class rclass, cover_class;
+  enum reg_class rclass, aclass;
   enum machine_mode mode;
   ira_copy_t cp;
 
@@ -426,35 +427,37 @@ process_regs_for_copy (rtx reg1, rtx reg2, bool constraint_p,
        return false;
     }
 
-  if (! IN_RANGE (allocno_preferenced_hard_regno, 0, FIRST_PSEUDO_REGISTER - 1))
+  if (! IN_RANGE (allocno_preferenced_hard_regno,
+                 0, FIRST_PSEUDO_REGISTER - 1))
     /* Can not be tied.  */
     return false;
   rclass = REGNO_REG_CLASS (allocno_preferenced_hard_regno);
   mode = ALLOCNO_MODE (a);
-  cover_class = ALLOCNO_COVER_CLASS (a);
+  aclass = ALLOCNO_CLASS (a);
   if (only_regs_p && insn != NULL_RTX
       && reg_class_size[rclass] <= (unsigned) CLASS_MAX_NREGS (rclass, mode))
     /* It is already taken into account in ira-costs.c.  */
     return false;
-  index = ira_class_hard_reg_index[cover_class][allocno_preferenced_hard_regno];
+  index = ira_class_hard_reg_index[aclass][allocno_preferenced_hard_regno];
   if (index < 0)
-    /* Can not be tied.  It is not in the cover class.  */
+    /* Can not be tied.  It is not in the allocno class.  */
     return false;
+  ira_init_register_move_cost_if_necessary (mode);
   if (HARD_REGISTER_P (reg1))
-    cost = ira_get_register_move_cost (mode, cover_class, rclass) * freq;
+    cost = ira_register_move_cost[mode][aclass][rclass] * freq;
   else
-    cost = ira_get_register_move_cost (mode, rclass, cover_class) * freq;
+    cost = ira_register_move_cost[mode][rclass][aclass] * freq;
   do
     {
       ira_allocate_and_set_costs
-       (&ALLOCNO_HARD_REG_COSTS (a), cover_class,
-        ALLOCNO_COVER_CLASS_COST (a));
+       (&ALLOCNO_HARD_REG_COSTS (a), aclass,
+        ALLOCNO_CLASS_COST (a));
       ira_allocate_and_set_costs
-       (&ALLOCNO_CONFLICT_HARD_REG_COSTS (a), cover_class, 0);
+       (&ALLOCNO_CONFLICT_HARD_REG_COSTS (a), aclass, 0);
       ALLOCNO_HARD_REG_COSTS (a)[index] -= cost;
       ALLOCNO_CONFLICT_HARD_REG_COSTS (a)[index] -= cost;
-      if (ALLOCNO_HARD_REG_COSTS (a)[index] < ALLOCNO_COVER_CLASS_COST (a))
-       ALLOCNO_COVER_CLASS_COST (a) = ALLOCNO_HARD_REG_COSTS (a)[index];
+      if (ALLOCNO_HARD_REG_COSTS (a)[index] < ALLOCNO_CLASS_COST (a))
+       ALLOCNO_CLASS_COST (a) = ALLOCNO_HARD_REG_COSTS (a)[index];
       a = ira_parent_or_cap_allocno (a);
     }
   while (a != NULL);
@@ -507,7 +510,8 @@ add_insn_allocno_copies (rtx insn)
                        ? SET_SRC (set)
                        : SUBREG_REG (SET_SRC (set))) != NULL_RTX)
     {
-      process_regs_for_copy (SET_DEST (set), SET_SRC (set), false, insn, freq);
+      process_regs_for_copy (SET_DEST (set), SET_SRC (set),
+                            false, insn, freq);
       return;
     }
   /* Fast check of possibility of constraint or shuffle copies.  If
@@ -608,6 +612,7 @@ build_object_conflicts (ira_object_t obj)
   ira_allocno_t a = OBJECT_ALLOCNO (obj);
   IRA_INT_TYPE *object_conflicts;
   minmax_set_iterator asi;
+  int parent_min, parent_max;
 
   object_conflicts = conflicts[OBJECT_CONFLICT_ID (obj)];
   px = 0;
@@ -616,8 +621,9 @@ build_object_conflicts (ira_object_t obj)
     {
       ira_object_t another_obj = ira_object_id_map[i];
       ira_allocno_t another_a = OBJECT_ALLOCNO (obj);
+
       ira_assert (ira_reg_classes_intersect_p
-                 [ALLOCNO_COVER_CLASS (a)][ALLOCNO_COVER_CLASS (another_a)]);
+                 [ALLOCNO_CLASS (a)][ALLOCNO_CLASS (another_a)]);
       collected_conflict_objects[px++] = another_obj;
     }
   if (ira_conflict_vector_profitable_p (obj, px))
@@ -632,6 +638,7 @@ build_object_conflicts (ira_object_t obj)
   else
     {
       int conflict_bit_vec_words_num;
+
       OBJECT_CONFLICT_ARRAY (obj) = object_conflicts;
       if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
        conflict_bit_vec_words_num = 0;
@@ -646,10 +653,12 @@ build_object_conflicts (ira_object_t obj)
   parent_a = ira_parent_or_cap_allocno (a);
   if (parent_a == NULL)
     return;
-  ira_assert (ALLOCNO_COVER_CLASS (a) == ALLOCNO_COVER_CLASS (parent_a));
+  ira_assert (ALLOCNO_CLASS (a) == ALLOCNO_CLASS (parent_a));
   ira_assert (ALLOCNO_NUM_OBJECTS (a) == ALLOCNO_NUM_OBJECTS (parent_a));
   parent_obj = ALLOCNO_OBJECT (parent_a, OBJECT_SUBWORD (obj));
   parent_num = OBJECT_CONFLICT_ID (parent_obj);
+  parent_min = OBJECT_MIN (parent_obj);
+  parent_max = OBJECT_MAX (parent_obj);
   FOR_EACH_BIT_IN_MINMAX_SET (object_conflicts,
                              OBJECT_MIN (obj), OBJECT_MAX (obj), i, asi)
     {
@@ -658,21 +667,20 @@ build_object_conflicts (ira_object_t obj)
       int another_word = OBJECT_SUBWORD (another_obj);
 
       ira_assert (ira_reg_classes_intersect_p
-                 [ALLOCNO_COVER_CLASS (a)][ALLOCNO_COVER_CLASS (another_a)]);
+                 [ALLOCNO_CLASS (a)][ALLOCNO_CLASS (another_a)]);
 
       another_parent_a = ira_parent_or_cap_allocno (another_a);
       if (another_parent_a == NULL)
        continue;
       ira_assert (ALLOCNO_NUM (another_parent_a) >= 0);
-      ira_assert (ALLOCNO_COVER_CLASS (another_a)
-                 == ALLOCNO_COVER_CLASS (another_parent_a));
+      ira_assert (ALLOCNO_CLASS (another_a)
+                 == ALLOCNO_CLASS (another_parent_a));
       ira_assert (ALLOCNO_NUM_OBJECTS (another_a)
                  == ALLOCNO_NUM_OBJECTS (another_parent_a));
       SET_MINMAX_SET_BIT (conflicts[parent_num],
                          OBJECT_CONFLICT_ID (ALLOCNO_OBJECT (another_parent_a,
-                                                    another_word)),
-                         OBJECT_MIN (parent_obj),
-                         OBJECT_MAX (parent_obj));
+                                                             another_word)),
+                         parent_min, parent_max);
     }
 }
 
@@ -792,14 +800,14 @@ print_allocno_conflicts (FILE * file, bool reg_p, ira_allocno_t a)
       COPY_HARD_REG_SET (conflicting_hard_regs, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
       AND_COMPL_HARD_REG_SET (conflicting_hard_regs, ira_no_alloc_regs);
       AND_HARD_REG_SET (conflicting_hard_regs,
-                       reg_class_contents[ALLOCNO_COVER_CLASS (a)]);
+                       reg_class_contents[ALLOCNO_CLASS (a)]);
       print_hard_reg_set (file, "\n;;     total conflict hard regs:",
                          conflicting_hard_regs);
 
       COPY_HARD_REG_SET (conflicting_hard_regs, OBJECT_CONFLICT_HARD_REGS (obj));
       AND_COMPL_HARD_REG_SET (conflicting_hard_regs, ira_no_alloc_regs);
       AND_HARD_REG_SET (conflicting_hard_regs,
-                       reg_class_contents[ALLOCNO_COVER_CLASS (a)]);
+                       reg_class_contents[ALLOCNO_CLASS (a)]);
       print_hard_reg_set (file, ";;     conflict hard regs:",
                          conflicting_hard_regs);
       putc ('\n', file);
@@ -876,6 +884,7 @@ ira_build_conflicts (void)
   FOR_EACH_ALLOCNO (a, ai)
     {
       int i, n = ALLOCNO_NUM_OBJECTS (a);
+
       for (i = 0; i < n; i++)
        {
          ira_object_t obj = ALLOCNO_OBJECT (a, i);
index 6db5bf2..4a3083a 100644 (file)
@@ -62,8 +62,7 @@ struct costs
 {
   int mem_cost;
   /* Costs for register classes start here.  We process only some
-     register classes (cover classes on the 1st cost calculation
-     iteration and important classes on the 2nd iteration).  */
+     allocno classes.  */
   int cost[1];
 };
 
@@ -77,8 +76,6 @@ struct costs
   (this_target_ira_int->x_op_costs)
 #define this_op_costs \
   (this_target_ira_int->x_this_op_costs)
-#define cost_classes \
-  (this_target_ira_int->x_cost_classes)
 
 /* Costs of each class for each allocno or pseudo.  */
 static struct costs *costs;
@@ -86,13 +83,6 @@ static struct costs *costs;
 /* Accumulated costs of each class for each allocno.  */
 static struct costs *total_allocno_costs;
 
-/* The size of the previous array.  */
-static int cost_classes_num;
-
-/* Map: cost class -> order number (they start with 0) of the cost
-   class.  The order number is negative for non-cost classes.  */
-static int cost_class_nums[N_REG_CLASSES];
-
 /* It is the current size of struct costs.  */
 static int struct_costs_size;
 
@@ -102,8 +92,8 @@ static int struct_costs_size;
   ((struct costs *) ((char *) (arr) + (num) * struct_costs_size))
 
 /* Return index in COSTS when processing reg with REGNO.  */
-#define COST_INDEX(regno) (allocno_p                                         \
-                           ? ALLOCNO_NUM (ira_curr_regno_allocno_map[regno])  \
+#define COST_INDEX(regno) (allocno_p                                        \
+                           ? ALLOCNO_NUM (ira_curr_regno_allocno_map[regno]) \
                           : (int) regno)
 
 /* Record register class preferences of each allocno or pseudo.  Null
@@ -114,8 +104,8 @@ static enum reg_class *pref;
 /* Allocated buffers for pref.  */
 static enum reg_class *pref_buffer;
 
-/* Record cover register class of each allocno with the same regno.  */
-static enum reg_class *regno_cover_class;
+/* Record allocno class of each allocno with the same regno.  */
+static enum reg_class *regno_aclass;
 
 /* Record cost gains for not allocating a register with an invariant
    equivalence.  */
@@ -126,6 +116,204 @@ static int frequency;
 
 \f
 
+/* Info about reg classes whose costs are calculated for a pseudo.  */
+struct cost_classes
+{
+  /* Number of the cost classes in the subsequent array.  */
+  int num;
+  /* Container of the cost classes.  */
+  enum reg_class classes[N_REG_CLASSES];
+  /* Map reg class -> index of the reg class in the previous array.
+     -1 if it is not a cost classe.  */
+  int index[N_REG_CLASSES];
+  /* Map hard regno index of first class in array CLASSES containing
+     the hard regno, -1 otherwise.  */
+  int hard_regno_index[FIRST_PSEUDO_REGISTER];
+};
+
+/* Types of pointers to the structure above.  */
+typedef struct cost_classes *cost_classes_t;
+typedef const struct cost_classes *const_cost_classes_t;
+
+/* Info about cost classes for each pseudo.  */
+static cost_classes_t *regno_cost_classes;
+
+/* Returns hash value for cost classes info V.  */
+static hashval_t
+cost_classes_hash (const void *v)
+{
+  const_cost_classes_t hv = (const_cost_classes_t) v;
+
+  return iterative_hash (&hv->classes, sizeof (enum reg_class) * hv->num, 0);
+}
+
+/* Compares cost classes info V1 and V2.  */
+static int
+cost_classes_eq (const void *v1, const void *v2)
+{
+  const_cost_classes_t hv1 = (const_cost_classes_t) v1;
+  const_cost_classes_t hv2 = (const_cost_classes_t) v2;
+
+  return hv1->num == hv2->num && memcmp (hv1->classes, hv2->classes,
+                                        sizeof (enum reg_class) * hv1->num);
+}
+
+/* Delete cost classes info V from the hash table.  */
+static void
+cost_classes_del (void *v)
+{
+  ira_free (v);
+}
+
+/* Hash table of unique cost classes.  */
+static htab_t cost_classes_htab;
+
+/* Map allocno class -> cost classes for pseudo of given allocno
+   class.  */
+static cost_classes_t cost_classes_aclass_cache[N_REG_CLASSES];
+
+/* Map mode -> cost classes for pseudo of give mode.  */
+static cost_classes_t cost_classes_mode_cache[MAX_MACHINE_MODE];
+
+/* Initialize info about the cost classes for each pseudo.  */
+static void
+initiate_regno_cost_classes (void)
+{
+  int size = sizeof (cost_classes_t) * max_reg_num ();
+
+  regno_cost_classes = (cost_classes_t *) ira_allocate (size);
+  memset (regno_cost_classes, 0, size);
+  memset (cost_classes_aclass_cache, 0,
+         sizeof (cost_classes_t) * N_REG_CLASSES);
+  memset (cost_classes_mode_cache, 0,
+         sizeof (cost_classes_t) * MAX_MACHINE_MODE);
+  cost_classes_htab
+    = htab_create (200, cost_classes_hash, cost_classes_eq, cost_classes_del);
+}
+
+/* Create new cost classes from cost classes FROM and set up members
+   index and hard_regno_index.  Return the new classes.  The function
+   implements some common code of two functions
+   setup_regno_cost_classes_by_aclass and
+   setup_regno_cost_classes_by_mode.  */
+static cost_classes_t
+setup_cost_classes (cost_classes_t from)
+{
+  cost_classes_t classes_ptr;
+  enum reg_class cl;
+  int i, j, hard_regno;
+
+  classes_ptr = (cost_classes_t) ira_allocate (sizeof (struct cost_classes));
+  classes_ptr->num = from->num;
+  for (i = 0; i < N_REG_CLASSES; i++)
+    classes_ptr->index[i] = -1;
+  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+    classes_ptr->hard_regno_index[i] = -1;
+  for (i = 0; i < from->num; i++)
+    {
+      cl = classes_ptr->classes[i] = from->classes[i];
+      classes_ptr->index[cl] = i;
+      for (j = ira_class_hard_regs_num[cl] - 1; j >= 0; j--)
+       {
+         hard_regno = ira_class_hard_regs[cl][j];
+         if (classes_ptr->hard_regno_index[hard_regno] < 0)
+           classes_ptr->hard_regno_index[hard_regno] = i;
+       }
+    }
+  return classes_ptr;
+}
+
+/* Setup cost classes for pseudo REGNO whose allocno class is ACLASS.
+   This function is used when we know an initial approximation of
+   allocno class of the pseudo already, e.g. on the second iteration
+   of class cost calculation or after class cost calculation in
+   register-pressure sensitive insn scheduling or register-pressure
+   sensitive loop-invariant motion.  */
+static void
+setup_regno_cost_classes_by_aclass (int regno, enum reg_class aclass)
+{
+  static struct cost_classes classes;
+  cost_classes_t classes_ptr;
+  enum reg_class cl;
+  int i;
+  PTR *slot;
+  HARD_REG_SET temp, temp2;
+
+  if ((classes_ptr = cost_classes_aclass_cache[aclass]) == NULL)
+    {
+      COPY_HARD_REG_SET (temp, reg_class_contents[aclass]);
+      AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs);
+      classes.num = 0;
+      for (i = 0; i < ira_important_classes_num; i++)
+       {
+         cl = ira_important_classes[i];
+         COPY_HARD_REG_SET (temp2, reg_class_contents[cl]);
+         AND_COMPL_HARD_REG_SET (temp2, ira_no_alloc_regs);
+         if (! ira_reg_pressure_class_p[cl]
+             && hard_reg_set_subset_p (temp2, temp) && cl != aclass)
+           continue;
+         classes.classes[classes.num++] = cl;
+       }
+      slot = htab_find_slot (cost_classes_htab, &classes, INSERT);
+      if (*slot == NULL)
+       {
+         classes_ptr = setup_cost_classes (&classes);
+         *slot = classes_ptr;
+       }
+      classes_ptr = cost_classes_aclass_cache[aclass] = (cost_classes_t) *slot;
+    }
+  regno_cost_classes[regno] = classes_ptr;
+}
+
+/* Setup cost classes for pseudo REGNO with MODE.  Usage of MODE can
+   decrease number of cost classes for the pseudo, if hard registers
+   of some important classes can not hold a value of MODE.  So the
+   pseudo can not get hard register of some important classes and cost
+   calculation for such important classes is only waisting CPU
+   time.  */
+static void
+setup_regno_cost_classes_by_mode (int regno, enum machine_mode mode)
+{
+  static struct cost_classes classes;
+  cost_classes_t classes_ptr;
+  enum reg_class cl;
+  int i;
+  PTR *slot;
+  HARD_REG_SET temp;
+
+  if ((classes_ptr = cost_classes_mode_cache[mode]) == NULL)
+    {
+      classes.num = 0;
+      for (i = 0; i < ira_important_classes_num; i++)
+       {
+         cl = ira_important_classes[i];
+         COPY_HARD_REG_SET (temp, ira_prohibited_class_mode_regs[cl][mode]);
+         IOR_HARD_REG_SET (temp, ira_no_alloc_regs);
+         if (hard_reg_set_subset_p (reg_class_contents[cl], temp))
+           continue;
+         classes.classes[classes.num++] = cl;
+       }
+      slot = htab_find_slot (cost_classes_htab, &classes, INSERT);
+      if (*slot == NULL)
+       {
+         classes_ptr = setup_cost_classes (&classes);
+         *slot = classes_ptr;
+       }
+      cost_classes_mode_cache[mode] = (cost_classes_t) *slot;
+    }
+  regno_cost_classes[regno] = classes_ptr;
+}
+
+/* Finilize info about the cost classes for each pseudo.  */
+static void
+finish_regno_cost_classes (void)
+{
+  ira_free (regno_cost_classes);
+  htab_delete (cost_classes_htab);
+}
+
+\f
+
 /* Compute the cost of loading X into (if TO_P is TRUE) or from (if
    TO_P is FALSE) a register of class RCLASS in mode MODE.  X must not
    be a pseudo register.  */
@@ -313,53 +501,78 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
                     Moreover, if we cannot tie them, this alternative
                     needs to do a copy, which is one insn.  */
                  struct costs *pp = this_op_costs[i];
-
-                 for (k = 0; k < cost_classes_num; k++)
+                 int *pp_costs = pp->cost;
+                 cost_classes_t cost_classes_ptr
+                   = regno_cost_classes[REGNO (op)];
+                 enum reg_class *cost_classes = cost_classes_ptr->classes;
+                 bool in_p = recog_data.operand_type[i] != OP_OUT;
+                 bool out_p = recog_data.operand_type[i] != OP_IN;
+                 enum reg_class op_class = classes[i];
+                 move_table *move_in_cost, *move_out_cost;
+
+                 ira_init_register_move_cost_if_necessary (mode);
+                 if (! in_p)
                    {
-                     rclass = cost_classes[k];
-                     pp->cost[k]
-                       = (((recog_data.operand_type[i] != OP_OUT
-                            ? ira_get_may_move_cost (mode, rclass,
-                                                     classes[i], true) : 0)
-                           + (recog_data.operand_type[i] != OP_IN
-                              ? ira_get_may_move_cost (mode, classes[i],
-                                                       rclass, false) : 0))
-                          * frequency);
+                     ira_assert (out_p);
+                     move_out_cost = ira_may_move_out_cost[mode];
+                     for (k = cost_classes_ptr->num - 1; k >= 0; k--)
+                       {
+                         rclass = cost_classes[k];
+                         pp_costs[k]
+                           = move_out_cost[op_class][rclass] * frequency;
+                       }
+                   }
+                 else if (! out_p)
+                   {
+                     ira_assert (in_p);
+                     move_in_cost = ira_may_move_in_cost[mode];
+                     for (k = cost_classes_ptr->num - 1; k >= 0; k--)
+                       {
+                         rclass = cost_classes[k];
+                         pp_costs[k]
+                           = move_in_cost[rclass][op_class] * frequency;
+                       }
+                   }
+                 else
+                   {
+                     move_in_cost = ira_may_move_in_cost[mode];
+                     move_out_cost = ira_may_move_out_cost[mode];
+                     for (k = cost_classes_ptr->num - 1; k >= 0; k--)
+                       {
+                         rclass = cost_classes[k];
+                         pp_costs[k] = ((move_in_cost[rclass][op_class]
+                                         + move_out_cost[op_class][rclass])
+                                        * frequency);
+                       }
                    }
 
                  /* If the alternative actually allows memory, make
                     things a bit cheaper since we won't need an extra
                     insn to load it.  */
                  pp->mem_cost
-                   = ((recog_data.operand_type[i] != OP_IN
-                       ? ira_memory_move_cost[mode][classes[i]][0] : 0)
-                      + (recog_data.operand_type[i] != OP_OUT
-                         ? ira_memory_move_cost[mode][classes[i]][1] : 0)
+                   = ((out_p ? ira_memory_move_cost[mode][op_class][0] : 0)
+                      + (in_p ? ira_memory_move_cost[mode][op_class][1] : 0)
                       - allows_mem[i]) * frequency;
 
-                 /* If we have assigned a class to this allocno in our
-                    first pass, add a cost to this alternative
-                    corresponding to what we would add if this allocno
-                    were not in the appropriate class.  We could use
-                    cover class here but it is less accurate
-                    approximation.  */
+                 /* If we have assigned a class to this allocno in
+                    our first pass, add a cost to this alternative
+                    corresponding to what we would add if this
+                    allocno were not in the appropriate class.  */
                  if (pref)
                    {
                      enum reg_class pref_class = pref[COST_INDEX (REGNO (op))];
 
                      if (pref_class == NO_REGS)
                        alt_cost
-                         += ((recog_data.operand_type[i] != OP_IN
-                              ? ira_memory_move_cost[mode][classes[i]][0]
-                              : 0)
-                             + (recog_data.operand_type[i] != OP_OUT
-                                ? ira_memory_move_cost[mode][classes[i]][1]
+