ira-int.h (struct ira_object): New.
* ira-int.h (struct ira_object): New. (ira_object_t): New typedef. Add DEF_VEC_P and DEF_VEC_ALLOC_P for it. (struct ira_allocno): Remove members min, max, conflict_allocno_array, conflict_id, conflict_allocno_array_size, conflict_allocnos_num and conflict_vec_p. Add new member object. (OBJECT_CONFLICT_ARRAY, OBJECT_CONFLICT_VEC_P, OBJECT_NUM_CONFLICTS, OBJECT_CONFLICT_ARRAY_SIZE, OBJECT_CONFLICT_HARD_REGS, OBJECT_TOTAL_CONFLICT_HARD_REGS, OBJECT_MIN, OBJECT_MAX, OBJECT_CONFLICT_ID): Renamed from ALLOCNO_CONFLICT_ALLOCNO_ARRAY, ALLOCNO_CONFLICT_VEC_P, ALLOCNO_CONFLICT_ALLOCNOS_NUM, ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE, ALLOCNO_CONFLICT_HARD_REGS, ALLOCNO_TOTAL_CONFLICT_HARD_REGS) ALLOCNO_MIN, ALLOCNO_MAX, and ALLOCNO_CONFLICT_ID; now operate on an ira_object_t rather than ira_allocno_t. All uses changed. (ira_object_id_map): Renamed from ira_conflict_id_allocno_map; now contains a vector of ira_object_t; all uses changed. (ira_objects_num): Declare variable. (ira_create_allocno_object): Declare function. (ira_conflict_vector_profitable_p): Adjust prototype. (ira_allocate_conflict_vec): Renamed from ira_allocate_allocno_conflict_vec; first arg now ira_object_t. (ira_allocate_object_conflicts): Renamed from ira_allocate_allocno_conflicts; first arg now ira_object_t. (struct ira_object_iterator): New. (ira_object_iter_init, ira_object_iter_cond, FOR_EACH_OBJECT): New. (ira_allocno_conflict_iterator): Renamed member allocno_conflict_vec_p to conflict_vec_p. All uses changed. (ira_allocno_conflict_iter_init, ira_allocno_conflict_iter_cond): Changed to take into account that conflicts are now tracked for objects. * ira-conflicts.c (OBJECTS_CONFLICT_P): Renamed from CONFLICT_ALLOCNO_P. Args changed to accept ira_object_t. All uses changed. (allocnos_conflict_p): New static function. (collected_conflict_objects): Renamed from collected_allocno_objects; now a vector of ira_object_t. All uses changed. (build_conflict_bit_table): Changed to take into account that conflicts are now tracked for objects. (process_regs_for_copy, propagate_copies, build_allocno_conflicts) (print_allocno_conflicts, ira_build_conflicts): Likewise. * ira-color.c (assign_hard_reg, setup_allocno_available_regs_num) setup_allocno_left_conflicts_size, allocno_reload_assign, fast_allocation): Likewise. * ira-lives.c (make_hard_regno_born, make_allocno_born) process_single_reg_class_operands, process_bb_node_lives): Likewise. * ira-emit.c (modify_move_list, add_range_and_copies_from_move_list): Likewise. * ira-build.c (ira_objects_num): New variable. (ira_object_id_map): Renamed from ira_conflict_id_allocno_map; now contains a vector of ira_object_t; all uses changed. (ira_object_id_map_vec): Corresponding change. (object_pool): New static variable. (initiate_allocnos): Initialize it. (finish_allocnos): Free it. (ira_create_object, ira_create_allocno_object, create_allocno_objects): New functions. (ira_create_allocno): Don't set members that were removed. (ira_set_allocno_cover_class): Don't change conflict hard regs. (merge_hard_reg_conflicts): Changed to take into account that conflicts are now tracked for objects. (ira_conflict_vector_profitable_p, ira_allocate_conflict_vec, allocate_conflict_bit_vec, ira_allocate_object_conflicts, compress_conflict_vecs, remove_low_level_allocnos, ira_flattening, setup_min_max_allocno_live_range_point, allocno_range_compare_func, setup_min_max_conflict_allocno_ids, ): Likewise. ((add_to_conflicts): Renamed from add_to_allocno_conflicts, args changed to ira_object_t; all callers changed. (ira_add_conflict): Renamed from ira_add_allocno_conflict, args changed to ira_object_t, all callers changed. (clear_conflicts): Renamed from clear_allocno_conflicts, arg changed to ira_object_t, all callers changed. (conflict_check, curr_conflict_check_tick): Renamed from allocno_conflict_check and curr_allocno_conflict_check_tick; all uses changed. (compress_conflict_vec): Renamed from compress_allocno_conflict_vec, arg changed to ira_object_t, all callers changed. (create_cap_allocno): Call ira_create_allocno_object. (finish_allocno): Free the corresponding object. (sort_conflict_id_map): Renamed from sort_conflict_id_allocno_map; all callers changed. Adjusted for dealing with objects. (ira_build): Call create_allocno_objects after ira_costs. Adjusted for dealing with objects. * ira.c (ira_bad_reload_regno_1): Adjusted for dealing with objects. From-SVN: r162166
This commit is contained in:
parent
5e0bf6cdff
commit
a49ae21794
|
@ -1,3 +1,90 @@
|
|||
2010-07-14 Bernd Schmidt <bernds@codesourcery.com>
|
||||
|
||||
* ira-int.h (struct ira_object): New.
|
||||
(ira_object_t): New typedef. Add DEF_VEC_P and DEF_VEC_ALLOC_P
|
||||
for it.
|
||||
(struct ira_allocno): Remove members min, max,
|
||||
conflict_allocno_array, conflict_id, conflict_allocno_array_size,
|
||||
conflict_allocnos_num and conflict_vec_p. Add new member object.
|
||||
(OBJECT_CONFLICT_ARRAY, OBJECT_CONFLICT_VEC_P,
|
||||
OBJECT_NUM_CONFLICTS, OBJECT_CONFLICT_ARRAY_SIZE,
|
||||
OBJECT_CONFLICT_HARD_REGS, OBJECT_TOTAL_CONFLICT_HARD_REGS,
|
||||
OBJECT_MIN, OBJECT_MAX, OBJECT_CONFLICT_ID): Renamed from
|
||||
ALLOCNO_CONFLICT_ALLOCNO_ARRAY, ALLOCNO_CONFLICT_VEC_P,
|
||||
ALLOCNO_CONFLICT_ALLOCNOS_NUM, ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE,
|
||||
ALLOCNO_CONFLICT_HARD_REGS, ALLOCNO_TOTAL_CONFLICT_HARD_REGS)
|
||||
ALLOCNO_MIN, ALLOCNO_MAX, and ALLOCNO_CONFLICT_ID; now operate on
|
||||
an ira_object_t rather than ira_allocno_t. All uses changed.
|
||||
(ira_object_id_map): Renamed from ira_conflict_id_allocno_map; now
|
||||
contains a vector of ira_object_t; all uses changed.
|
||||
(ira_objects_num): Declare variable.
|
||||
(ira_create_allocno_object): Declare function.
|
||||
(ira_conflict_vector_profitable_p): Adjust prototype.
|
||||
(ira_allocate_conflict_vec): Renamed from
|
||||
ira_allocate_allocno_conflict_vec; first arg now ira_object_t.
|
||||
(ira_allocate_object_conflicts): Renamed from
|
||||
ira_allocate_allocno_conflicts; first arg now ira_object_t.
|
||||
(struct ira_object_iterator): New.
|
||||
(ira_object_iter_init, ira_object_iter_cond, FOR_EACH_OBJECT): New.
|
||||
(ira_allocno_conflict_iterator): Renamed member allocno_conflict_vec_p
|
||||
to conflict_vec_p. All uses changed.
|
||||
(ira_allocno_conflict_iter_init, ira_allocno_conflict_iter_cond):
|
||||
Changed to take into account that conflicts are now tracked for
|
||||
objects.
|
||||
* ira-conflicts.c (OBJECTS_CONFLICT_P): Renamed from
|
||||
CONFLICT_ALLOCNO_P. Args changed to accept ira_object_t. All
|
||||
uses changed.
|
||||
(allocnos_conflict_p): New static function.
|
||||
(collected_conflict_objects): Renamed from collected_allocno_objects;
|
||||
now a vector of ira_object_t. All uses changed.
|
||||
(build_conflict_bit_table): Changed to take into account that
|
||||
conflicts are now tracked for objects.
|
||||
(process_regs_for_copy, propagate_copies, build_allocno_conflicts)
|
||||
(print_allocno_conflicts, ira_build_conflicts): Likewise.
|
||||
* ira-color.c (assign_hard_reg, setup_allocno_available_regs_num)
|
||||
setup_allocno_left_conflicts_size, allocno_reload_assign,
|
||||
fast_allocation): Likewise.
|
||||
* ira-lives.c (make_hard_regno_born, make_allocno_born)
|
||||
process_single_reg_class_operands, process_bb_node_lives): Likewise.
|
||||
* ira-emit.c (modify_move_list, add_range_and_copies_from_move_list):
|
||||
Likewise.
|
||||
* ira-build.c (ira_objects_num): New variable.
|
||||
(ira_object_id_map): Renamed from ira_conflict_id_allocno_map; now
|
||||
contains a vector of ira_object_t; all uses changed.
|
||||
(ira_object_id_map_vec): Corresponding change.
|
||||
(object_pool): New static variable.
|
||||
(initiate_allocnos): Initialize it.
|
||||
(finish_allocnos): Free it.
|
||||
(ira_create_object, ira_create_allocno_object, create_allocno_objects):
|
||||
New functions.
|
||||
(ira_create_allocno): Don't set members that were removed.
|
||||
(ira_set_allocno_cover_class): Don't change conflict hard regs.
|
||||
(merge_hard_reg_conflicts): Changed to take into account that
|
||||
conflicts are now tracked for objects.
|
||||
(ira_conflict_vector_profitable_p, ira_allocate_conflict_vec,
|
||||
allocate_conflict_bit_vec, ira_allocate_object_conflicts,
|
||||
compress_conflict_vecs, remove_low_level_allocnos, ira_flattening,
|
||||
setup_min_max_allocno_live_range_point, allocno_range_compare_func,
|
||||
setup_min_max_conflict_allocno_ids, ): Likewise.
|
||||
((add_to_conflicts): Renamed from add_to_allocno_conflicts, args changed
|
||||
to ira_object_t; all callers changed.
|
||||
(ira_add_conflict): Renamed from ira_add_allocno_conflict, args changed
|
||||
to ira_object_t, all callers changed.
|
||||
(clear_conflicts): Renamed from clear_allocno_conflicts, arg changed
|
||||
to ira_object_t, all callers changed.
|
||||
(conflict_check, curr_conflict_check_tick): Renamed from
|
||||
allocno_conflict_check and curr_allocno_conflict_check_tick; all uses
|
||||
changed.
|
||||
(compress_conflict_vec): Renamed from compress_allocno_conflict_vec,
|
||||
arg changed to ira_object_t, all callers changed.
|
||||
(create_cap_allocno): Call ira_create_allocno_object.
|
||||
(finish_allocno): Free the corresponding object.
|
||||
(sort_conflict_id_map): Renamed from sort_conflict_id_allocno_map; all
|
||||
callers changed. Adjusted for dealing with objects.
|
||||
(ira_build): Call create_allocno_objects after ira_costs. Adjusted for
|
||||
dealing with objects.
|
||||
* ira.c (ira_bad_reload_regno_1): Adjusted for dealing with objects.
|
||||
|
||||
2010-07-13 Joern Rennecke <joern.rennecke@embecosm.com>
|
||||
|
||||
PR other/44874
|
||||
|
|
467
gcc/ira-build.c
467
gcc/ira-build.c
|
@ -72,9 +72,12 @@ ira_allocno_t *ira_allocnos;
|
|||
/* Sizes of the previous array. */
|
||||
int ira_allocnos_num;
|
||||
|
||||
/* Map conflict id -> allocno with given conflict id (see comments for
|
||||
allocno member `conflict_id'). */
|
||||
ira_allocno_t *ira_conflict_id_allocno_map;
|
||||
/* Count of conflict record structures we've created, used when creating
|
||||
a new conflict id. */
|
||||
int ira_objects_num;
|
||||
|
||||
/* Map a conflict id to its conflict record. */
|
||||
ira_object_t *ira_object_id_map;
|
||||
|
||||
/* Array of references to all copies. The order number of the copy
|
||||
corresponds to the index in the array. Removed copies have NULL
|
||||
|
@ -381,19 +384,18 @@ rebuild_regno_allocno_maps (void)
|
|||
loop_tree_node->regno_allocno_map[regno] = a;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Pools for allocnos and live ranges. */
|
||||
static alloc_pool allocno_pool, live_range_pool;
|
||||
/* Pools for allocnos, allocno live ranges and objects. */
|
||||
static alloc_pool allocno_pool, live_range_pool, object_pool;
|
||||
|
||||
/* Vec containing references to all created allocnos. It is a
|
||||
container of array allocnos. */
|
||||
static VEC(ira_allocno_t,heap) *allocno_vec;
|
||||
|
||||
/* Vec containing references to all created allocnos. It is a
|
||||
container of ira_conflict_id_allocno_map. */
|
||||
static VEC(ira_allocno_t,heap) *ira_conflict_id_allocno_map_vec;
|
||||
/* Vec containing references to all created ira_objects. It is a
|
||||
container of ira_object_id_map. */
|
||||
static VEC(ira_object_t,heap) *ira_object_id_map_vec;
|
||||
|
||||
/* Initialize data concerning allocnos. */
|
||||
static void
|
||||
|
@ -404,17 +406,48 @@ initiate_allocnos (void)
|
|||
sizeof (struct live_range), 100);
|
||||
allocno_pool
|
||||
= create_alloc_pool ("allocnos", sizeof (struct ira_allocno), 100);
|
||||
object_pool
|
||||
= create_alloc_pool ("objects", sizeof (struct ira_object), 100);
|
||||
allocno_vec = VEC_alloc (ira_allocno_t, heap, max_reg_num () * 2);
|
||||
ira_allocnos = NULL;
|
||||
ira_allocnos_num = 0;
|
||||
ira_conflict_id_allocno_map_vec
|
||||
= VEC_alloc (ira_allocno_t, heap, max_reg_num () * 2);
|
||||
ira_conflict_id_allocno_map = NULL;
|
||||
ira_objects_num = 0;
|
||||
ira_object_id_map_vec
|
||||
= 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));
|
||||
memset (ira_regno_allocno_map, 0, max_reg_num () * sizeof (ira_allocno_t));
|
||||
}
|
||||
|
||||
/* Create and return an object corresponding to a new allocno A. */
|
||||
static ira_object_t
|
||||
ira_create_object (ira_allocno_t a)
|
||||
{
|
||||
enum reg_class cover_class = ALLOCNO_COVER_CLASS (a);
|
||||
ira_object_t obj = (ira_object_t) pool_alloc (object_pool);
|
||||
|
||||
OBJECT_ALLOCNO (obj) = a;
|
||||
OBJECT_CONFLICT_ID (obj) = ira_objects_num;
|
||||
OBJECT_CONFLICT_VEC_P (obj) = false;
|
||||
OBJECT_CONFLICT_ARRAY (obj) = NULL;
|
||||
OBJECT_NUM_CONFLICTS (obj) = 0;
|
||||
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]);
|
||||
IOR_COMPL_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
|
||||
reg_class_contents[cover_class]);
|
||||
OBJECT_MIN (obj) = INT_MAX;
|
||||
OBJECT_MAX (obj) = -1;
|
||||
|
||||
VEC_safe_push (ira_object_t, heap, ira_object_id_map_vec, obj);
|
||||
ira_object_id_map
|
||||
= VEC_address (ira_object_t, ira_object_id_map_vec);
|
||||
ira_objects_num = VEC_length (ira_object_t, ira_object_id_map_vec);
|
||||
return obj;
|
||||
}
|
||||
|
||||
/* Create and return the allocno corresponding to REGNO in
|
||||
LOOP_TREE_NODE. Add the allocno to the list of allocnos with the
|
||||
same regno if CAP_P is FALSE. */
|
||||
|
@ -440,10 +473,6 @@ ira_create_allocno (int regno, bool cap_p, ira_loop_tree_node_t loop_tree_node)
|
|||
ALLOCNO_CAP_MEMBER (a) = NULL;
|
||||
ALLOCNO_NUM (a) = ira_allocnos_num;
|
||||
bitmap_set_bit (loop_tree_node->all_allocnos, ALLOCNO_NUM (a));
|
||||
ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a) = NULL;
|
||||
ALLOCNO_CONFLICT_ALLOCNOS_NUM (a) = 0;
|
||||
COPY_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a), ira_no_alloc_regs);
|
||||
COPY_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a), ira_no_alloc_regs);
|
||||
ALLOCNO_NREFS (a) = 0;
|
||||
ALLOCNO_FREQ (a) = 0;
|
||||
ALLOCNO_HARD_REGNO (a) = -1;
|
||||
|
@ -463,7 +492,6 @@ ira_create_allocno (int regno, bool cap_p, ira_loop_tree_node_t loop_tree_node)
|
|||
ALLOCNO_ASSIGNED_P (a) = false;
|
||||
ALLOCNO_MAY_BE_SPILLED_P (a) = false;
|
||||
ALLOCNO_SPLAY_REMOVED_P (a) = false;
|
||||
ALLOCNO_CONFLICT_VEC_P (a) = false;
|
||||
ALLOCNO_MODE (a) = (regno < 0 ? VOIDmode : PSEUDO_REGNO_MODE (regno));
|
||||
ALLOCNO_COPIES (a) = NULL;
|
||||
ALLOCNO_HARD_REG_COSTS (a) = NULL;
|
||||
|
@ -482,15 +510,10 @@ ira_create_allocno (int regno, bool cap_p, ira_loop_tree_node_t loop_tree_node)
|
|||
ALLOCNO_FIRST_COALESCED_ALLOCNO (a) = a;
|
||||
ALLOCNO_NEXT_COALESCED_ALLOCNO (a) = a;
|
||||
ALLOCNO_LIVE_RANGES (a) = NULL;
|
||||
ALLOCNO_MIN (a) = INT_MAX;
|
||||
ALLOCNO_MAX (a) = -1;
|
||||
ALLOCNO_CONFLICT_ID (a) = ira_allocnos_num;
|
||||
|
||||
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);
|
||||
VEC_safe_push (ira_allocno_t, heap, ira_conflict_id_allocno_map_vec, a);
|
||||
ira_conflict_id_allocno_map
|
||||
= VEC_address (ira_allocno_t, ira_conflict_id_allocno_map_vec);
|
||||
return a;
|
||||
}
|
||||
|
||||
|
@ -499,10 +522,24 @@ void
|
|||
ira_set_allocno_cover_class (ira_allocno_t a, enum reg_class cover_class)
|
||||
{
|
||||
ALLOCNO_COVER_CLASS (a) = cover_class;
|
||||
IOR_COMPL_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a),
|
||||
reg_class_contents[cover_class]);
|
||||
IOR_COMPL_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a),
|
||||
reg_class_contents[cover_class]);
|
||||
}
|
||||
|
||||
/* Allocate an object for allocno A and set ALLOCNO_OBJECT. */
|
||||
void
|
||||
ira_create_allocno_object (ira_allocno_t a)
|
||||
{
|
||||
ALLOCNO_OBJECT (a) = ira_create_object (a);
|
||||
}
|
||||
|
||||
/* For each allocno, create the corresponding ALLOCNO_OBJECT structure. */
|
||||
static void
|
||||
create_allocno_objects (void)
|
||||
{
|
||||
ira_allocno_t a;
|
||||
ira_allocno_iterator ai;
|
||||
|
||||
FOR_EACH_ALLOCNO (a, ai)
|
||||
ira_create_allocno_object (a);
|
||||
}
|
||||
|
||||
/* Merge hard register conflicts from allocno FROM into allocno TO. If
|
||||
|
@ -511,11 +548,13 @@ static void
|
|||
merge_hard_reg_conflicts (ira_allocno_t from, ira_allocno_t to,
|
||||
bool total_only)
|
||||
{
|
||||
ira_object_t from_obj = ALLOCNO_OBJECT (from);
|
||||
ira_object_t to_obj = ALLOCNO_OBJECT (to);
|
||||
if (!total_only)
|
||||
IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (to),
|
||||
ALLOCNO_CONFLICT_HARD_REGS (from));
|
||||
IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (to),
|
||||
ALLOCNO_TOTAL_CONFLICT_HARD_REGS (from));
|
||||
IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (to_obj),
|
||||
OBJECT_CONFLICT_HARD_REGS (from_obj));
|
||||
IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (to_obj),
|
||||
OBJECT_TOTAL_CONFLICT_HARD_REGS (from_obj));
|
||||
#ifdef STACK_REGS
|
||||
if (!total_only && ALLOCNO_NO_STACK_REG_P (from))
|
||||
ALLOCNO_NO_STACK_REG_P (to) = true;
|
||||
|
@ -524,111 +563,110 @@ merge_hard_reg_conflicts (ira_allocno_t from, ira_allocno_t to,
|
|||
#endif
|
||||
}
|
||||
|
||||
/* Return TRUE if the conflict vector with NUM elements is more
|
||||
profitable than conflict bit vector for A. */
|
||||
/* Return TRUE if a conflict vector with NUM elements is more
|
||||
profitable than a conflict bit vector for OBJ. */
|
||||
bool
|
||||
ira_conflict_vector_profitable_p (ira_allocno_t a, int num)
|
||||
ira_conflict_vector_profitable_p (ira_object_t obj, int num)
|
||||
{
|
||||
int nw;
|
||||
int max = OBJECT_MAX (obj);
|
||||
int min = OBJECT_MIN (obj);
|
||||
|
||||
if (ALLOCNO_MAX (a) < ALLOCNO_MIN (a))
|
||||
/* We prefer bit vector in such case because it does not result in
|
||||
allocation. */
|
||||
if (max < min)
|
||||
/* We prefer a bit vector in such case because it does not result
|
||||
in allocation. */
|
||||
return false;
|
||||
|
||||
nw = (ALLOCNO_MAX (a) - ALLOCNO_MIN (a) + IRA_INT_BITS) / IRA_INT_BITS;
|
||||
return (2 * sizeof (ira_allocno_t) * (num + 1)
|
||||
nw = (max - min + IRA_INT_BITS) / IRA_INT_BITS;
|
||||
return (2 * sizeof (ira_object_t) * (num + 1)
|
||||
< 3 * nw * sizeof (IRA_INT_TYPE));
|
||||
}
|
||||
|
||||
/* Allocates and initialize the conflict vector of A for NUM
|
||||
conflicting allocnos. */
|
||||
/* Allocates and initialize the conflict vector of OBJ for NUM
|
||||
conflicting objects. */
|
||||
void
|
||||
ira_allocate_allocno_conflict_vec (ira_allocno_t a, int num)
|
||||
ira_allocate_conflict_vec (ira_object_t obj, int num)
|
||||
{
|
||||
int size;
|
||||
ira_allocno_t *vec;
|
||||
ira_object_t *vec;
|
||||
|
||||
ira_assert (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a) == NULL);
|
||||
ira_assert (OBJECT_CONFLICT_ARRAY (obj) == NULL);
|
||||
num++; /* for NULL end marker */
|
||||
size = sizeof (ira_allocno_t) * num;
|
||||
ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a) = ira_allocate (size);
|
||||
vec = (ira_allocno_t *) ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a);
|
||||
size = sizeof (ira_object_t) * num;
|
||||
OBJECT_CONFLICT_ARRAY (obj) = ira_allocate (size);
|
||||
vec = (ira_object_t *) OBJECT_CONFLICT_ARRAY (obj);
|
||||
vec[0] = NULL;
|
||||
ALLOCNO_CONFLICT_ALLOCNOS_NUM (a) = 0;
|
||||
ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a) = size;
|
||||
ALLOCNO_CONFLICT_VEC_P (a) = true;
|
||||
OBJECT_NUM_CONFLICTS (obj) = 0;
|
||||
OBJECT_CONFLICT_ARRAY_SIZE (obj) = size;
|
||||
OBJECT_CONFLICT_VEC_P (obj) = true;
|
||||
}
|
||||
|
||||
/* Allocate and initialize the conflict bit vector of A. */
|
||||
/* Allocate and initialize the conflict bit vector of OBJ. */
|
||||
static void
|
||||
allocate_allocno_conflict_bit_vec (ira_allocno_t a)
|
||||
allocate_conflict_bit_vec (ira_object_t obj)
|
||||
{
|
||||
unsigned int size;
|
||||
|
||||
ira_assert (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a) == NULL);
|
||||
size = ((ALLOCNO_MAX (a) - ALLOCNO_MIN (a) + IRA_INT_BITS)
|
||||
ira_assert (OBJECT_CONFLICT_ARRAY (obj) == NULL);
|
||||
size = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
|
||||
/ IRA_INT_BITS * sizeof (IRA_INT_TYPE));
|
||||
ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a) = ira_allocate (size);
|
||||
memset (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a), 0, size);
|
||||
ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a) = size;
|
||||
ALLOCNO_CONFLICT_VEC_P (a) = false;
|
||||
OBJECT_CONFLICT_ARRAY (obj) = ira_allocate (size);
|
||||
memset (OBJECT_CONFLICT_ARRAY (obj), 0, size);
|
||||
OBJECT_CONFLICT_ARRAY_SIZE (obj) = size;
|
||||
OBJECT_CONFLICT_VEC_P (obj) = false;
|
||||
}
|
||||
|
||||
/* Allocate and initialize the conflict vector or conflict bit vector
|
||||
of A for NUM conflicting allocnos whatever is more profitable. */
|
||||
void
|
||||
ira_allocate_allocno_conflicts (ira_allocno_t a, int num)
|
||||
ira_allocate_object_conflicts (ira_object_t a, int num)
|
||||
{
|
||||
if (ira_conflict_vector_profitable_p (a, num))
|
||||
ira_allocate_allocno_conflict_vec (a, num);
|
||||
ira_allocate_conflict_vec (a, num);
|
||||
else
|
||||
allocate_allocno_conflict_bit_vec (a);
|
||||
allocate_conflict_bit_vec (a);
|
||||
}
|
||||
|
||||
/* Add A2 to the conflicts of A1. */
|
||||
/* Add OBJ2 to the conflicts of OBJ1. */
|
||||
static void
|
||||
add_to_allocno_conflicts (ira_allocno_t a1, ira_allocno_t a2)
|
||||
add_to_conflicts (ira_object_t obj1, ira_object_t obj2)
|
||||
{
|
||||
int num;
|
||||
unsigned int size;
|
||||
|
||||
if (ALLOCNO_CONFLICT_VEC_P (a1))
|
||||
if (OBJECT_CONFLICT_VEC_P (obj1))
|
||||
{
|
||||
ira_allocno_t *vec;
|
||||
|
||||
num = ALLOCNO_CONFLICT_ALLOCNOS_NUM (a1) + 2;
|
||||
if (ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a1)
|
||||
>= num * sizeof (ira_allocno_t))
|
||||
vec = (ira_allocno_t *) ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1);
|
||||
else
|
||||
ira_object_t *vec = OBJECT_CONFLICT_VEC (obj1);
|
||||
int curr_num = OBJECT_NUM_CONFLICTS (obj1);
|
||||
num = curr_num + 2;
|
||||
if (OBJECT_CONFLICT_ARRAY_SIZE (obj1) < num * sizeof (ira_object_t))
|
||||
{
|
||||
ira_object_t *newvec;
|
||||
size = (3 * num / 2 + 1) * sizeof (ira_allocno_t);
|
||||
vec = (ira_allocno_t *) ira_allocate (size);
|
||||
memcpy (vec, ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1),
|
||||
sizeof (ira_allocno_t) * ALLOCNO_CONFLICT_ALLOCNOS_NUM (a1));
|
||||
ira_free (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1));
|
||||
ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1) = vec;
|
||||
ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a1) = size;
|
||||
newvec = (ira_object_t *) ira_allocate (size);
|
||||
memcpy (newvec, vec, curr_num * sizeof (ira_object_t));
|
||||
ira_free (vec);
|
||||
vec = newvec;
|
||||
OBJECT_CONFLICT_ARRAY (obj1) = vec;
|
||||
OBJECT_CONFLICT_ARRAY_SIZE (obj1) = size;
|
||||
}
|
||||
vec[num - 2] = a2;
|
||||
vec[num - 2] = obj2;
|
||||
vec[num - 1] = NULL;
|
||||
ALLOCNO_CONFLICT_ALLOCNOS_NUM (a1)++;
|
||||
OBJECT_NUM_CONFLICTS (obj1)++;
|
||||
}
|
||||
else
|
||||
{
|
||||
int nw, added_head_nw, id;
|
||||
IRA_INT_TYPE *vec;
|
||||
IRA_INT_TYPE *vec = OBJECT_CONFLICT_BITVEC (obj1);
|
||||
|
||||
id = ALLOCNO_CONFLICT_ID (a2);
|
||||
vec = (IRA_INT_TYPE *) ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1);
|
||||
if (ALLOCNO_MIN (a1) > id)
|
||||
id = OBJECT_CONFLICT_ID (obj2);
|
||||
if (OBJECT_MIN (obj1) > id)
|
||||
{
|
||||
/* Expand head of the bit vector. */
|
||||
added_head_nw = (ALLOCNO_MIN (a1) - id - 1) / IRA_INT_BITS + 1;
|
||||
nw = (ALLOCNO_MAX (a1) - ALLOCNO_MIN (a1)) / IRA_INT_BITS + 1;
|
||||
added_head_nw = (OBJECT_MIN (obj1) - id - 1) / IRA_INT_BITS + 1;
|
||||
nw = (OBJECT_MAX (obj1) - OBJECT_MIN (obj1)) / IRA_INT_BITS + 1;
|
||||
size = (nw + added_head_nw) * sizeof (IRA_INT_TYPE);
|
||||
if (ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a1) >= size)
|
||||
if (OBJECT_CONFLICT_ARRAY_SIZE (obj1) >= size)
|
||||
{
|
||||
memmove ((char *) vec + added_head_nw * sizeof (IRA_INT_TYPE),
|
||||
vec, nw * sizeof (IRA_INT_TYPE));
|
||||
|
@ -640,97 +678,93 @@ add_to_allocno_conflicts (ira_allocno_t a1, ira_allocno_t a2)
|
|||
= (3 * (nw + added_head_nw) / 2 + 1) * sizeof (IRA_INT_TYPE);
|
||||
vec = (IRA_INT_TYPE *) ira_allocate (size);
|
||||
memcpy ((char *) vec + added_head_nw * sizeof (IRA_INT_TYPE),
|
||||
ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1),
|
||||
nw * sizeof (IRA_INT_TYPE));
|
||||
OBJECT_CONFLICT_ARRAY (obj1), nw * sizeof (IRA_INT_TYPE));
|
||||
memset (vec, 0, added_head_nw * sizeof (IRA_INT_TYPE));
|
||||
memset ((char *) vec
|
||||
+ (nw + added_head_nw) * sizeof (IRA_INT_TYPE),
|
||||
0, size - (nw + added_head_nw) * sizeof (IRA_INT_TYPE));
|
||||
ira_free (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1));
|
||||
ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1) = vec;
|
||||
ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a1) = size;
|
||||
ira_free (OBJECT_CONFLICT_ARRAY (obj1));
|
||||
OBJECT_CONFLICT_ARRAY (obj1) = vec;
|
||||
OBJECT_CONFLICT_ARRAY_SIZE (obj1) = size;
|
||||
}
|
||||
ALLOCNO_MIN (a1) -= added_head_nw * IRA_INT_BITS;
|
||||
OBJECT_MIN (obj1) -= added_head_nw * IRA_INT_BITS;
|
||||
}
|
||||
else if (ALLOCNO_MAX (a1) < id)
|
||||
else if (OBJECT_MAX (obj1) < id)
|
||||
{
|
||||
nw = (id - ALLOCNO_MIN (a1)) / IRA_INT_BITS + 1;
|
||||
nw = (id - OBJECT_MIN (obj1)) / IRA_INT_BITS + 1;
|
||||
size = nw * sizeof (IRA_INT_TYPE);
|
||||
if (ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a1) < size)
|
||||
if (OBJECT_CONFLICT_ARRAY_SIZE (obj1) < size)
|
||||
{
|
||||
/* Expand tail of the bit vector. */
|
||||
size = (3 * nw / 2 + 1) * sizeof (IRA_INT_TYPE);
|
||||
vec = (IRA_INT_TYPE *) ira_allocate (size);
|
||||
memcpy (vec, ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1),
|
||||
ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a1));
|
||||
memset ((char *) vec + ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a1),
|
||||
0, size - ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a1));
|
||||
ira_free (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1));
|
||||
ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1) = vec;
|
||||
ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a1) = size;
|
||||
memcpy (vec, OBJECT_CONFLICT_ARRAY (obj1), OBJECT_CONFLICT_ARRAY_SIZE (obj1));
|
||||
memset ((char *) vec + OBJECT_CONFLICT_ARRAY_SIZE (obj1),
|
||||
0, size - OBJECT_CONFLICT_ARRAY_SIZE (obj1));
|
||||
ira_free (OBJECT_CONFLICT_ARRAY (obj1));
|
||||
OBJECT_CONFLICT_ARRAY (obj1) = vec;
|
||||
OBJECT_CONFLICT_ARRAY_SIZE (obj1) = size;
|
||||
}
|
||||
ALLOCNO_MAX (a1) = id;
|
||||
OBJECT_MAX (obj1) = id;
|
||||
}
|
||||
SET_MINMAX_SET_BIT (vec, id, ALLOCNO_MIN (a1), ALLOCNO_MAX (a1));
|
||||
SET_MINMAX_SET_BIT (vec, id, OBJECT_MIN (obj1), OBJECT_MAX (obj1));
|
||||
}
|
||||
}
|
||||
|
||||
/* Add A1 to the conflicts of A2 and vise versa. */
|
||||
void
|
||||
ira_add_allocno_conflict (ira_allocno_t a1, ira_allocno_t a2)
|
||||
{
|
||||
add_to_allocno_conflicts (a1, a2);
|
||||
add_to_allocno_conflicts (a2, a1);
|
||||
}
|
||||
|
||||
/* Clear all conflicts of allocno A. */
|
||||
/* Add OBJ1 to the conflicts of OBJ2 and vice versa. */
|
||||
static void
|
||||
clear_allocno_conflicts (ira_allocno_t a)
|
||||
ira_add_conflict (ira_object_t obj1, ira_object_t obj2)
|
||||
{
|
||||
if (ALLOCNO_CONFLICT_VEC_P (a))
|
||||
{
|
||||
ALLOCNO_CONFLICT_ALLOCNOS_NUM (a) = 0;
|
||||
((ira_allocno_t *) ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a))[0] = NULL;
|
||||
add_to_conflicts (obj1, obj2);
|
||||
add_to_conflicts (obj2, obj1);
|
||||
}
|
||||
else if (ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a) != 0)
|
||||
|
||||
/* Clear all conflicts of OBJ. */
|
||||
static void
|
||||
clear_conflicts (ira_object_t obj)
|
||||
{
|
||||
if (OBJECT_CONFLICT_VEC_P (obj))
|
||||
{
|
||||
OBJECT_NUM_CONFLICTS (obj) = 0;
|
||||
OBJECT_CONFLICT_VEC (obj)[0] = NULL;
|
||||
}
|
||||
else if (OBJECT_CONFLICT_ARRAY_SIZE (obj) != 0)
|
||||
{
|
||||
int nw;
|
||||
|
||||
nw = (ALLOCNO_MAX (a) - ALLOCNO_MIN (a)) / IRA_INT_BITS + 1;
|
||||
memset (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a), 0,
|
||||
nw * sizeof (IRA_INT_TYPE));
|
||||
nw = (OBJECT_MAX (obj) - OBJECT_MIN (obj)) / IRA_INT_BITS + 1;
|
||||
memset (OBJECT_CONFLICT_BITVEC (obj), 0, nw * sizeof (IRA_INT_TYPE));
|
||||
}
|
||||
}
|
||||
|
||||
/* The array used to find duplications in conflict vectors of
|
||||
allocnos. */
|
||||
static int *allocno_conflict_check;
|
||||
static int *conflict_check;
|
||||
|
||||
/* The value used to mark allocation presence in conflict vector of
|
||||
the current allocno. */
|
||||
static int curr_allocno_conflict_check_tick;
|
||||
static int curr_conflict_check_tick;
|
||||
|
||||
/* Remove duplications in conflict vector of A. */
|
||||
/* Remove duplications in conflict vector of OBJ. */
|
||||
static void
|
||||
compress_allocno_conflict_vec (ira_allocno_t a)
|
||||
compress_conflict_vec (ira_object_t obj)
|
||||
{
|
||||
ira_allocno_t *vec, conflict_a;
|
||||
ira_object_t *vec, conflict_obj;
|
||||
int i, j;
|
||||
|
||||
ira_assert (ALLOCNO_CONFLICT_VEC_P (a));
|
||||
vec = (ira_allocno_t *) ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a);
|
||||
curr_allocno_conflict_check_tick++;
|
||||
for (i = j = 0; (conflict_a = vec[i]) != NULL; i++)
|
||||
ira_assert (OBJECT_CONFLICT_VEC_P (obj));
|
||||
vec = OBJECT_CONFLICT_VEC (obj);
|
||||
curr_conflict_check_tick++;
|
||||
for (i = j = 0; (conflict_obj = vec[i]) != NULL; i++)
|
||||
{
|
||||
if (allocno_conflict_check[ALLOCNO_NUM (conflict_a)]
|
||||
!= curr_allocno_conflict_check_tick)
|
||||
int id = OBJECT_CONFLICT_ID (conflict_obj);
|
||||
if (conflict_check[id] != curr_conflict_check_tick)
|
||||
{
|
||||
allocno_conflict_check[ALLOCNO_NUM (conflict_a)]
|
||||
= curr_allocno_conflict_check_tick;
|
||||
vec[j++] = conflict_a;
|
||||
conflict_check[id] = curr_conflict_check_tick;
|
||||
vec[j++] = conflict_obj;
|
||||
}
|
||||
}
|
||||
ALLOCNO_CONFLICT_ALLOCNOS_NUM (a) = j;
|
||||
OBJECT_NUM_CONFLICTS (obj) = j;
|
||||
vec[j] = NULL;
|
||||
}
|
||||
|
||||
|
@ -741,14 +775,16 @@ compress_conflict_vecs (void)
|
|||
ira_allocno_t a;
|
||||
ira_allocno_iterator ai;
|
||||
|
||||
allocno_conflict_check
|
||||
= (int *) ira_allocate (sizeof (int) * ira_allocnos_num);
|
||||
memset (allocno_conflict_check, 0, sizeof (int) * ira_allocnos_num);
|
||||
curr_allocno_conflict_check_tick = 0;
|
||||
conflict_check = (int *) ira_allocate (sizeof (int) * ira_objects_num);
|
||||
memset (conflict_check, 0, sizeof (int) * ira_objects_num);
|
||||
curr_conflict_check_tick = 0;
|
||||
FOR_EACH_ALLOCNO (a, ai)
|
||||
if (ALLOCNO_CONFLICT_VEC_P (a))
|
||||
compress_allocno_conflict_vec (a);
|
||||
ira_free (allocno_conflict_check);
|
||||
{
|
||||
ira_object_t obj = ALLOCNO_OBJECT (a);
|
||||
if (OBJECT_CONFLICT_VEC_P (obj))
|
||||
compress_conflict_vec (obj);
|
||||
}
|
||||
ira_free (conflict_check);
|
||||
}
|
||||
|
||||
/* This recursive function outputs allocno A and if it is a cap the
|
||||
|
@ -787,6 +823,7 @@ create_cap_allocno (ira_allocno_t a)
|
|||
ALLOCNO_MODE (cap) = ALLOCNO_MODE (a);
|
||||
cover_class = ALLOCNO_COVER_CLASS (a);
|
||||
ira_set_allocno_cover_class (cap, cover_class);
|
||||
ira_create_allocno_object (cap);
|
||||
ALLOCNO_AVAILABLE_REGS_NUM (cap) = ALLOCNO_AVAILABLE_REGS_NUM (a);
|
||||
ALLOCNO_CAP_MEMBER (cap) = a;
|
||||
ALLOCNO_CAP (a) = cap;
|
||||
|
@ -995,11 +1032,9 @@ static void
|
|||
finish_allocno (ira_allocno_t a)
|
||||
{
|
||||
enum reg_class cover_class = ALLOCNO_COVER_CLASS (a);
|
||||
ira_object_t obj = ALLOCNO_OBJECT (a);
|
||||
|
||||
ira_allocnos[ALLOCNO_NUM (a)] = NULL;
|
||||
ira_conflict_id_allocno_map[ALLOCNO_CONFLICT_ID (a)] = NULL;
|
||||
if (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a) != NULL)
|
||||
ira_free (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a));
|
||||
if (ALLOCNO_HARD_REG_COSTS (a) != NULL)
|
||||
ira_free_cost_vector (ALLOCNO_HARD_REG_COSTS (a), cover_class);
|
||||
if (ALLOCNO_CONFLICT_HARD_REG_COSTS (a) != NULL)
|
||||
|
@ -1011,6 +1046,11 @@ finish_allocno (ira_allocno_t a)
|
|||
cover_class);
|
||||
ira_finish_allocno_live_range_list (ALLOCNO_LIVE_RANGES (a));
|
||||
pool_free (allocno_pool, a);
|
||||
|
||||
ira_object_id_map[OBJECT_CONFLICT_ID (obj)] = NULL;
|
||||
if (OBJECT_CONFLICT_ARRAY (obj) != NULL)
|
||||
ira_free (OBJECT_CONFLICT_ARRAY (obj));
|
||||
pool_free (object_pool, obj);
|
||||
}
|
||||
|
||||
/* Free the memory allocated for all allocnos. */
|
||||
|
@ -1023,9 +1063,10 @@ finish_allocnos (void)
|
|||
FOR_EACH_ALLOCNO (a, ai)
|
||||
finish_allocno (a);
|
||||
ira_free (ira_regno_allocno_map);
|
||||
VEC_free (ira_allocno_t, heap, ira_conflict_id_allocno_map_vec);
|
||||
VEC_free (ira_object_t, heap, ira_object_id_map_vec);
|
||||
VEC_free (ira_allocno_t, heap, allocno_vec);
|
||||
free_alloc_pool (allocno_pool);
|
||||
free_alloc_pool (object_pool);
|
||||
free_alloc_pool (live_range_pool);
|
||||
}
|
||||
|
||||
|
@ -2080,11 +2121,13 @@ remove_low_level_allocnos (void)
|
|||
regno = ALLOCNO_REGNO (a);
|
||||
if (ira_loop_tree_root->regno_allocno_map[regno] == a)
|
||||
{
|
||||
ira_object_t obj = ALLOCNO_OBJECT (a);
|
||||
|
||||
ira_regno_allocno_map[regno] = a;
|
||||
ALLOCNO_NEXT_REGNO_ALLOCNO (a) = NULL;
|
||||
ALLOCNO_CAP_MEMBER (a) = NULL;
|
||||
COPY_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a),
|
||||
ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a));
|
||||
COPY_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj),
|
||||
OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
|
||||
#ifdef STACK_REGS
|
||||
if (ALLOCNO_TOTAL_NO_STACK_REG_P (a))
|
||||
ALLOCNO_NO_STACK_REG_P (a) = true;
|
||||
|
@ -2203,20 +2246,24 @@ setup_min_max_allocno_live_range_point (void)
|
|||
|
||||
FOR_EACH_ALLOCNO (a, ai)
|
||||
{
|
||||
ira_object_t obj = ALLOCNO_OBJECT (a);
|
||||
r = ALLOCNO_LIVE_RANGES (a);
|
||||
if (r == NULL)
|
||||
continue;
|
||||
ALLOCNO_MAX (a) = r->finish;
|
||||
OBJECT_MAX (obj) = r->finish;
|
||||
for (; r->next != NULL; r = r->next)
|
||||
;
|
||||
ALLOCNO_MIN (a) = r->start;
|
||||
OBJECT_MIN (obj) = r->start;
|
||||
}
|
||||
for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--)
|
||||
for (a = ira_regno_allocno_map[i];
|
||||
a != NULL;
|
||||
a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
|
||||
{
|
||||
if (ALLOCNO_MAX (a) < 0)
|
||||
ira_object_t obj = ALLOCNO_OBJECT (a);
|
||||
ira_object_t parent_obj;
|
||||
|
||||
if (OBJECT_MAX (obj) < 0)
|
||||
continue;
|
||||
ira_assert (ALLOCNO_CAP_MEMBER (a) == NULL);
|
||||
/* Accumulation of range info. */
|
||||
|
@ -2224,26 +2271,29 @@ setup_min_max_allocno_live_range_point (void)
|
|||
{
|
||||
for (cap = ALLOCNO_CAP (a); cap != NULL; cap = ALLOCNO_CAP (cap))
|
||||
{
|
||||
if (ALLOCNO_MAX (cap) < ALLOCNO_MAX (a))
|
||||
ALLOCNO_MAX (cap) = ALLOCNO_MAX (a);
|
||||
if (ALLOCNO_MIN (cap) > ALLOCNO_MIN (a))
|
||||
ALLOCNO_MIN (cap) = ALLOCNO_MIN (a);
|
||||
ira_object_t cap_obj = ALLOCNO_OBJECT (cap);
|
||||
if (OBJECT_MAX (cap_obj) < OBJECT_MAX (obj))
|
||||
OBJECT_MAX (cap_obj) = OBJECT_MAX (obj);
|
||||
if (OBJECT_MIN (cap_obj) > OBJECT_MIN (obj))
|
||||
OBJECT_MIN (cap_obj) = OBJECT_MIN (obj);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ((parent = ALLOCNO_LOOP_TREE_NODE (a)->parent) == NULL)
|
||||
continue;
|
||||
parent_a = parent->regno_allocno_map[i];
|
||||
if (ALLOCNO_MAX (parent_a) < ALLOCNO_MAX (a))
|
||||
ALLOCNO_MAX (parent_a) = ALLOCNO_MAX (a);
|
||||
if (ALLOCNO_MIN (parent_a) > ALLOCNO_MIN (a))
|
||||
ALLOCNO_MIN (parent_a) = ALLOCNO_MIN (a);
|
||||
parent_obj = ALLOCNO_OBJECT (parent_a);
|
||||
if (OBJECT_MAX (parent_obj) < OBJECT_MAX (obj))
|
||||
OBJECT_MAX (parent_obj) = OBJECT_MAX (obj);
|
||||
if (OBJECT_MIN (parent_obj) > OBJECT_MIN (obj))
|
||||
OBJECT_MIN (parent_obj) = OBJECT_MIN (obj);
|
||||
}
|
||||
#ifdef ENABLE_IRA_CHECKING
|
||||
FOR_EACH_ALLOCNO (a, ai)
|
||||
{
|
||||
if ((0 <= ALLOCNO_MIN (a) && ALLOCNO_MIN (a) <= ira_max_point)
|
||||
&& (0 <= ALLOCNO_MAX (a) && ALLOCNO_MAX (a) <= ira_max_point))
|
||||
ira_object_t obj = ALLOCNO_OBJECT (a);
|
||||
if ((0 <= OBJECT_MIN (obj) && OBJECT_MIN (obj) <= ira_max_point)
|
||||
&& (0 <= OBJECT_MAX (obj) && OBJECT_MAX (obj) <= ira_max_point))
|
||||
continue;
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
@ -2252,30 +2302,31 @@ 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 cove class are ordered according their start
|
||||
Allocnos with the same cover class are ordered according their start
|
||||
(min). Allocnos with the same start are ordered according their
|
||||
finish (max). */
|
||||
static int
|
||||
allocno_range_compare_func (const void *v1p, const void *v2p)
|
||||
{
|
||||
int diff;
|
||||
ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
|
||||
ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
|
||||
ira_object_t obj1 = *(const ira_object_t *) v1p;
|
||||
ira_object_t obj2 = *(const ira_object_t *) 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 = ALLOCNO_MIN (a1) - ALLOCNO_MIN (a2)) != 0)
|
||||
if ((diff = OBJECT_MIN (obj1) - OBJECT_MIN (obj2)) != 0)
|
||||
return diff;
|
||||
if ((diff = ALLOCNO_MAX (a1) - ALLOCNO_MAX (a2)) != 0)
|
||||
if ((diff = OBJECT_MAX (obj1) - OBJECT_MAX (obj2)) != 0)
|
||||
return diff;
|
||||
return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2);
|
||||
}
|
||||
|
||||
/* Sort ira_conflict_id_allocno_map and set up conflict id of
|
||||
allocnos. */
|
||||
/* Sort ira_object_id_map and set up conflict id of allocnos. */
|
||||
static void
|
||||
sort_conflict_id_allocno_map (void)
|
||||
sort_conflict_id_map (void)
|
||||
{
|
||||
int i, num;
|
||||
ira_allocno_t a;
|
||||
|
@ -2283,14 +2334,17 @@ sort_conflict_id_allocno_map (void)
|
|||
|
||||
num = 0;
|
||||
FOR_EACH_ALLOCNO (a, ai)
|
||||
ira_conflict_id_allocno_map[num++] = a;
|
||||
qsort (ira_conflict_id_allocno_map, num, sizeof (ira_allocno_t),
|
||||
ira_object_id_map[num++] = ALLOCNO_OBJECT (a);
|
||||
qsort (ira_object_id_map, num, sizeof (ira_object_t),
|
||||
allocno_range_compare_func);
|
||||
for (i = 0; i < num; i++)
|
||||
if ((a = ira_conflict_id_allocno_map[i]) != NULL)
|
||||
ALLOCNO_CONFLICT_ID (a) = i;
|
||||
for (i = num; i < ira_allocnos_num; i++)
|
||||
ira_conflict_id_allocno_map[i] = NULL;
|
||||
{
|
||||
ira_object_t obj = ira_object_id_map[i];
|
||||
gcc_assert (obj != NULL);
|
||||
OBJECT_CONFLICT_ID (obj) = i;
|
||||
}
|
||||
for (i = num; i < ira_objects_num; i++)
|
||||
ira_object_id_map[i] = NULL;
|
||||
}
|
||||
|
||||
/* Set up minimal and maximal conflict ids of allocnos with which
|
||||
|
@ -2303,14 +2357,17 @@ setup_min_max_conflict_allocno_ids (void)
|
|||
int *live_range_min, *last_lived;
|
||||
ira_allocno_t a;
|
||||
|
||||
live_range_min = (int *) ira_allocate (sizeof (int) * ira_allocnos_num);
|
||||
live_range_min = (int *) ira_allocate (sizeof (int) * ira_objects_num);
|
||||
cover_class = -1;
|
||||
first_not_finished = -1;
|
||||
for (i = 0; i < ira_allocnos_num; i++)
|
||||
for (i = 0; i < ira_objects_num; i++)
|
||||
{
|
||||
a = ira_conflict_id_allocno_map[i];
|
||||
if (a == NULL)
|
||||
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)))
|
||||
|
@ -2321,13 +2378,13 @@ setup_min_max_conflict_allocno_ids (void)
|
|||
}
|
||||
else
|
||||
{
|
||||
start = ALLOCNO_MIN (a);
|
||||
start = OBJECT_MIN (obj);
|
||||
/* If we skip an allocno, the allocno with smaller ids will
|
||||
be also skipped because of the secondary sorting the
|
||||
range finishes (see function
|
||||
allocno_range_compare_func). */
|
||||
while (first_not_finished < i
|
||||
&& start > ALLOCNO_MAX (ira_conflict_id_allocno_map
|
||||
&& start > OBJECT_MAX (ira_object_id_map
|
||||
[first_not_finished]))
|
||||
first_not_finished++;
|
||||
min = first_not_finished;
|
||||
|
@ -2336,17 +2393,19 @@ setup_min_max_conflict_allocno_ids (void)
|
|||
/* We could increase min further in this case but it is good
|
||||
enough. */
|
||||
min++;
|
||||
live_range_min[i] = ALLOCNO_MIN (a);
|
||||
ALLOCNO_MIN (a) = min;
|
||||
live_range_min[i] = OBJECT_MIN (obj);
|
||||
OBJECT_MIN (obj) = min;
|
||||
}
|
||||
last_lived = (int *) ira_allocate (sizeof (int) * ira_max_point);
|
||||
cover_class = -1;
|
||||
filled_area_start = -1;
|
||||
for (i = ira_allocnos_num - 1; i >= 0; i--)
|
||||
for (i = ira_objects_num - 1; i >= 0; i--)
|
||||
{
|
||||
a = ira_conflict_id_allocno_map[i];
|
||||
if (a == NULL)
|
||||
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)))
|
||||
|
@ -2357,13 +2416,13 @@ setup_min_max_conflict_allocno_ids (void)
|
|||
filled_area_start = ira_max_point;
|
||||
}
|
||||
min = live_range_min[i];
|
||||
finish = ALLOCNO_MAX (a);
|
||||
finish = OBJECT_MAX (obj);
|
||||
max = last_lived[finish];
|
||||
if (max < 0)
|
||||
/* We could decrease max further in this case but it is good
|
||||
enough. */
|
||||
max = ALLOCNO_CONFLICT_ID (a) - 1;
|
||||
ALLOCNO_MAX (a) = max;
|
||||
max = OBJECT_CONFLICT_ID (obj) - 1;
|
||||
OBJECT_MAX (obj) = max;
|
||||
/* In filling, we can go further A range finish to recognize
|
||||
intersection quickly because if the finish of subsequently
|
||||
processed allocno (it has smaller conflict id) range is
|
||||
|
@ -2518,13 +2577,14 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
|
|||
new_pseudos_p = merged_p = false;
|
||||
FOR_EACH_ALLOCNO (a, ai)
|
||||
{
|
||||
ira_object_t obj = ALLOCNO_OBJECT (a);
|
||||
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
|
||||
flattening. */
|
||||
continue;
|
||||
COPY_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a),
|
||||
ALLOCNO_CONFLICT_HARD_REGS (a));
|
||||
COPY_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
|
||||
OBJECT_CONFLICT_HARD_REGS (obj));
|
||||
#ifdef STACK_REGS
|
||||
ALLOCNO_TOTAL_NO_STACK_REG_P (a) = ALLOCNO_NO_STACK_REG_P (a);
|
||||
#endif
|
||||
|
@ -2612,7 +2672,7 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
|
|||
continue;
|
||||
for (r = ALLOCNO_LIVE_RANGES (a); r != NULL; r = r->next)
|
||||
ira_assert (r->allocno == a);
|
||||
clear_allocno_conflicts (a);
|
||||
clear_conflicts (ALLOCNO_OBJECT (a));
|
||||
}
|
||||
allocnos_live = sparseset_alloc (ira_allocnos_num);
|
||||
for (i = 0; i < ira_max_point; i++)
|
||||
|
@ -2634,7 +2694,11 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
|
|||
[cover_class][ALLOCNO_COVER_CLASS (live_a)]
|
||||
/* Don't set up conflict for the allocno with itself. */
|
||||
&& num != (int) n)
|
||||
ira_add_allocno_conflict (a, live_a);
|
||||
{
|
||||
ira_object_t obj = ALLOCNO_OBJECT (a);
|
||||
ira_object_t live_obj = ALLOCNO_OBJECT (live_a);
|
||||
ira_add_conflict (obj, live_obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2826,6 +2890,7 @@ ira_build (bool loops_p)
|
|||
form_loop_tree ();
|
||||
create_allocnos ();
|
||||
ira_costs ();
|
||||
create_allocno_objects ();
|
||||
ira_create_allocno_live_ranges ();
|
||||
remove_unnecessary_regions (false);
|
||||
ira_compress_allocno_live_ranges ();
|
||||
|
@ -2841,7 +2906,7 @@ ira_build (bool loops_p)
|
|||
check_allocno_creation ();
|
||||
#endif
|
||||
setup_min_max_allocno_live_range_point ();
|
||||
sort_conflict_id_allocno_map ();
|
||||
sort_conflict_id_map ();
|
||||
setup_min_max_conflict_allocno_ids ();
|
||||
ira_build_conflicts ();
|
||||
update_conflict_hard_reg_costs ();
|
||||
|
@ -2862,9 +2927,10 @@ ira_build (bool loops_p)
|
|||
FOR_EACH_ALLOCNO (a, ai)
|
||||
if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
|
||||
{
|
||||
IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a),
|
||||
ira_object_t obj = ALLOCNO_OBJECT (a);
|
||||
IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
|
||||
call_used_reg_set);
|
||||
IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a),
|
||||
IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj),
|
||||
call_used_reg_set);
|
||||
}
|
||||
}
|
||||
|
@ -2879,7 +2945,10 @@ ira_build (bool loops_p)
|
|||
|
||||
n = 0;
|
||||
FOR_EACH_ALLOCNO (a, ai)
|
||||
n += ALLOCNO_CONFLICT_ALLOCNOS_NUM (a);
|
||||
{
|
||||
ira_object_t obj = ALLOCNO_OBJECT (a);
|
||||
n += OBJECT_NUM_CONFLICTS (obj);
|
||||
}
|
||||
nr = 0;
|
||||
FOR_EACH_ALLOCNO (a, ai)
|
||||
for (r = ALLOCNO_LIVE_RANGES (a); r != NULL; r = r->next)
|
||||
|
|
|
@ -477,9 +477,11 @@ assign_hard_reg (ira_allocno_t allocno, bool retry_p)
|
|||
for (a = ALLOCNO_NEXT_COALESCED_ALLOCNO (allocno);;
|
||||
a = ALLOCNO_NEXT_COALESCED_ALLOCNO (a))
|
||||
{
|
||||
ira_object_t obj = ALLOCNO_OBJECT (a);
|
||||
|
||||
mem_cost += ALLOCNO_UPDATED_MEMORY_COST (a);
|
||||
IOR_HARD_REG_SET (conflicting_regs,
|
||||
ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a));
|
||||
OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
|
||||
ira_allocate_and_copy_costs (&ALLOCNO_UPDATED_HARD_REG_COSTS (a),
|
||||
cover_class, ALLOCNO_HARD_REG_COSTS (a));
|
||||
a_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a);
|
||||
|
@ -1376,7 +1378,8 @@ setup_allocno_available_regs_num (ira_allocno_t allocno)
|
|||
for (a = ALLOCNO_NEXT_COALESCED_ALLOCNO (allocno);;
|
||||
a = ALLOCNO_NEXT_COALESCED_ALLOCNO (a))
|
||||
{
|
||||
IOR_HARD_REG_SET (temp_set, ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a));
|
||||
ira_object_t obj = ALLOCNO_OBJECT (a);
|
||||
IOR_HARD_REG_SET (temp_set, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
|
||||
if (a == allocno)
|
||||
break;
|
||||
}
|
||||
|
@ -1412,7 +1415,8 @@ setup_allocno_left_conflicts_size (ira_allocno_t allocno)
|
|||
for (a = ALLOCNO_NEXT_COALESCED_ALLOCNO (allocno);;
|
||||
a = ALLOCNO_NEXT_COALESCED_ALLOCNO (a))
|
||||
{
|
||||
IOR_HARD_REG_SET (temp_set, ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a));
|
||||
ira_object_t obj = ALLOCNO_OBJECT (a);
|
||||
IOR_HARD_REG_SET (temp_set, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
|
||||
if (a == allocno)
|
||||
break;
|
||||
}
|
||||
|
@ -2791,11 +2795,12 @@ allocno_reload_assign (ira_allocno_t a, HARD_REG_SET forbidden_regs)
|
|||
enum reg_class cover_class;
|
||||
int regno = ALLOCNO_REGNO (a);
|
||||
HARD_REG_SET saved;
|
||||
ira_object_t obj = ALLOCNO_OBJECT (a);
|
||||
|
||||
COPY_HARD_REG_SET (saved, ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a));
|
||||
IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a), forbidden_regs);
|
||||
COPY_HARD_REG_SET (saved, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
|
||||
IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), forbidden_regs);
|
||||
if (! flag_caller_saves && ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
|
||||
IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a), call_used_reg_set);
|
||||
IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), call_used_reg_set);
|
||||
ALLOCNO_ASSIGNED_P (a) = false;
|
||||
cover_class = ALLOCNO_COVER_CLASS (a);
|
||||
update_curr_costs (a);
|
||||
|
@ -2834,7 +2839,7 @@ allocno_reload_assign (ira_allocno_t a, HARD_REG_SET forbidden_regs)
|
|||
}
|
||||
else if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
|
||||
fprintf (ira_dump_file, "\n");
|
||||
COPY_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a), saved);
|
||||
COPY_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), saved);
|
||||
return reg_renumber[regno] >= 0;
|
||||
}
|
||||
|
||||
|
@ -3262,8 +3267,10 @@ fast_allocation (void)
|
|||
allocno_priority_compare_func);
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
ira_object_t obj;
|
||||
a = sorted_allocnos[i];
|
||||
COPY_HARD_REG_SET (conflict_hard_regs, ALLOCNO_CONFLICT_HARD_REGS (a));
|
||||
obj = ALLOCNO_OBJECT (a);
|
||||
COPY_HARD_REG_SET (conflict_hard_regs, OBJECT_CONFLICT_HARD_REGS (obj));
|
||||
for (r = ALLOCNO_LIVE_RANGES (a); r != NULL; r = r->next)
|
||||
for (j = r->start; j <= r->finish; j++)
|
||||
IOR_HARD_REG_SET (conflict_hard_regs, used_hard_regs[j]);
|
||||
|
|
|
@ -51,40 +51,38 @@ along with GCC; see the file COPYING3. If not see
|
|||
corresponding allocnos see function build_allocno_conflicts. */
|
||||
static IRA_INT_TYPE **conflicts;
|
||||
|
||||
/* Macro to test a conflict of A1 and A2 in `conflicts'. */
|
||||
#define CONFLICT_ALLOCNO_P(A1, A2) \
|
||||
(ALLOCNO_MIN (A1) <= ALLOCNO_CONFLICT_ID (A2) \
|
||||
&& ALLOCNO_CONFLICT_ID (A2) <= ALLOCNO_MAX (A1) \
|
||||
&& TEST_MINMAX_SET_BIT (conflicts[ALLOCNO_NUM (A1)], \
|
||||
ALLOCNO_CONFLICT_ID (A2), \
|
||||
ALLOCNO_MIN (A1), \
|
||||
ALLOCNO_MAX (A1)))
|
||||
/* Macro to test a conflict of C1 and C2 in `conflicts'. */
|
||||
#define OBJECTS_CONFLICT_P(C1, C2) \
|
||||
(OBJECT_MIN (C1) <= OBJECT_CONFLICT_ID (C2) \
|
||||
&& OBJECT_CONFLICT_ID (C2) <= OBJECT_MAX (C1) \
|
||||
&& TEST_MINMAX_SET_BIT (conflicts[OBJECT_CONFLICT_ID (C1)], \
|
||||
OBJECT_CONFLICT_ID (C2), \
|
||||
OBJECT_MIN (C1), OBJECT_MAX (C1)))
|
||||
|
||||
|
||||
|
||||
/* Build allocno conflict table by processing allocno live ranges.
|
||||
Return true if the table was built. The table is not built if it
|
||||
is too big. */
|
||||
static bool
|
||||
build_conflict_bit_table (void)
|
||||
{
|
||||
int i, num, id, allocated_words_num, conflict_bit_vec_words_num;
|
||||
int i;
|
||||
unsigned int j;
|
||||
enum reg_class cover_class;
|
||||
ira_allocno_t allocno, live_a;
|
||||
int object_set_words, allocated_words_num, conflict_bit_vec_words_num;
|
||||
live_range_t r;
|
||||
ira_allocno_t allocno;
|
||||
ira_allocno_iterator ai;
|
||||
sparseset allocnos_live;
|
||||
int allocno_set_words;
|
||||
sparseset objects_live;
|
||||
|
||||
allocno_set_words = (ira_allocnos_num + IRA_INT_BITS - 1) / IRA_INT_BITS;
|
||||
allocated_words_num = 0;
|
||||
FOR_EACH_ALLOCNO (allocno, ai)
|
||||
{
|
||||
if (ALLOCNO_MAX (allocno) < ALLOCNO_MIN (allocno))
|
||||
ira_object_t obj = ALLOCNO_OBJECT (allocno);
|
||||
if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
|
||||
continue;
|
||||
conflict_bit_vec_words_num
|
||||
= ((ALLOCNO_MAX (allocno) - ALLOCNO_MIN (allocno) + IRA_INT_BITS)
|
||||
= ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
|
||||
/ IRA_INT_BITS);
|
||||
allocated_words_num += conflict_bit_vec_words_num;
|
||||
if ((unsigned long long) allocated_words_num * sizeof (IRA_INT_TYPE)
|
||||
|
@ -98,70 +96,90 @@ build_conflict_bit_table (void)
|
|||
return false;
|
||||
}
|
||||
}
|
||||
allocnos_live = sparseset_alloc (ira_allocnos_num);
|
||||
|
||||
conflicts = (IRA_INT_TYPE **) ira_allocate (sizeof (IRA_INT_TYPE *)
|
||||
* ira_allocnos_num);
|
||||
* ira_objects_num);
|
||||
allocated_words_num = 0;
|
||||
FOR_EACH_ALLOCNO (allocno, ai)
|
||||
{
|
||||
num = ALLOCNO_NUM (allocno);
|
||||
if (ALLOCNO_MAX (allocno) < ALLOCNO_MIN (allocno))
|
||||
ira_object_t obj = ALLOCNO_OBJECT (allocno);
|
||||
int id = OBJECT_CONFLICT_ID (obj);
|
||||
if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
|
||||
{
|
||||
conflicts[num] = NULL;
|
||||
conflicts[id] = NULL;
|
||||
continue;
|
||||
}
|
||||
conflict_bit_vec_words_num
|
||||
= ((ALLOCNO_MAX (allocno) - ALLOCNO_MIN (allocno) + IRA_INT_BITS)
|
||||
= ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
|
||||
/ IRA_INT_BITS);
|
||||
allocated_words_num += conflict_bit_vec_words_num;
|
||||
conflicts[num]
|
||||
conflicts[id]
|
||||
= (IRA_INT_TYPE *) ira_allocate (sizeof (IRA_INT_TYPE)
|
||||
* conflict_bit_vec_words_num);
|
||||
memset (conflicts[num], 0,
|
||||
memset (conflicts[id], 0,
|
||||
sizeof (IRA_INT_TYPE) * conflict_bit_vec_words_num);
|
||||
}
|
||||
|
||||
object_set_words = (ira_objects_num + IRA_INT_BITS - 1) / IRA_INT_BITS;
|
||||
if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
|
||||
fprintf
|
||||
(ira_dump_file,
|
||||
"+++Allocating %ld bytes for conflict table (uncompressed size %ld)\n",
|
||||
(long) allocated_words_num * sizeof (IRA_INT_TYPE),
|
||||
(long) allocno_set_words * ira_allocnos_num * sizeof (IRA_INT_TYPE));
|
||||
(long) object_set_words * ira_objects_num * sizeof (IRA_INT_TYPE));
|
||||
|
||||
objects_live = sparseset_alloc (ira_objects_num);
|
||||
for (i = 0; i < ira_max_point; i++)
|
||||
{
|
||||
for (r = ira_start_point_ranges[i]; r != NULL; r = r->start_next)
|
||||
{
|
||||
allocno = r->allocno;
|
||||
num = ALLOCNO_NUM (allocno);
|
||||
id = ALLOCNO_CONFLICT_ID (allocno);
|
||||
ira_allocno_t allocno = r->allocno;
|
||||
ira_object_t obj = ALLOCNO_OBJECT (allocno);
|
||||
int id = OBJECT_CONFLICT_ID (obj);
|
||||
|
||||
cover_class = ALLOCNO_COVER_CLASS (allocno);
|
||||
sparseset_set_bit (allocnos_live, num);
|
||||
EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, j)
|
||||
sparseset_set_bit (objects_live, id);
|
||||
EXECUTE_IF_SET_IN_SPARSESET (objects_live, j)
|
||||
{
|
||||
live_a = ira_allocnos[j];
|
||||
if (ira_reg_classes_intersect_p
|
||||
[cover_class][ALLOCNO_COVER_CLASS (live_a)]
|
||||
ira_object_t live_cr = ira_object_id_map[j];
|
||||
ira_allocno_t live_a = OBJECT_ALLOCNO (live_cr);
|
||||
enum reg_class live_cover_class = ALLOCNO_COVER_CLASS (live_a);
|
||||
|
||||
if (ira_reg_classes_intersect_p[cover_class][live_cover_class]
|
||||
/* Don't set up conflict for the allocno with itself. */
|
||||
&& num != (int) j)
|
||||
&& id != (int) j)
|
||||
{
|
||||
SET_MINMAX_SET_BIT (conflicts[num],
|
||||
ALLOCNO_CONFLICT_ID (live_a),
|
||||
ALLOCNO_MIN (allocno),
|
||||
ALLOCNO_MAX (allocno));
|
||||
SET_MINMAX_SET_BIT (conflicts[id], j,
|
||||
OBJECT_MIN (obj),
|
||||
OBJECT_MAX (obj));
|
||||
SET_MINMAX_SET_BIT (conflicts[j], id,
|
||||
ALLOCNO_MIN (live_a),
|
||||
ALLOCNO_MAX (live_a));
|
||||
OBJECT_MIN (live_cr),
|
||||
OBJECT_MAX (live_cr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (r = ira_finish_point_ranges[i]; r != NULL; r = r->finish_next)
|
||||
sparseset_clear_bit (allocnos_live, ALLOCNO_NUM (r->allocno));
|
||||
{
|
||||
ira_allocno_t allocno = r->allocno;
|
||||
ira_object_t obj = ALLOCNO_OBJECT (allocno);
|
||||
sparseset_clear_bit (objects_live, OBJECT_CONFLICT_ID (obj));
|
||||
}
|
||||
sparseset_free (allocnos_live);
|
||||
}
|
||||
sparseset_free (objects_live);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Return true iff allocnos A1 and A2 cannot be allocated to the same
|
||||
register due to conflicts. */
|
||||
|
||||
static bool
|
||||
allocnos_conflict_p (ira_allocno_t a1, ira_allocno_t a2)
|
||||
{
|
||||
ira_object_t obj1 = ALLOCNO_OBJECT (a1);
|
||||
ira_object_t obj2 = ALLOCNO_OBJECT (a2);
|
||||
return OBJECTS_CONFLICT_P (obj1, obj2);
|
||||
}
|
||||
|
||||
/* Return TRUE if the operand constraint STR is commutative. */
|
||||
static bool
|
||||
|
@ -366,19 +384,21 @@ process_regs_for_copy (rtx reg1, rtx reg2, bool constraint_p,
|
|||
allocno_preferenced_hard_regno = REGNO (reg2) + offset2 - offset1;
|
||||
a = ira_curr_regno_allocno_map[REGNO (reg1)];
|
||||
}
|
||||
else if (!CONFLICT_ALLOCNO_P (ira_curr_regno_allocno_map[REGNO (reg1)],
|
||||
ira_curr_regno_allocno_map[REGNO (reg2)])
|
||||
&& offset1 == offset2)
|
||||
else
|
||||
{
|
||||
cp = ira_add_allocno_copy (ira_curr_regno_allocno_map[REGNO (reg1)],
|
||||
ira_curr_regno_allocno_map[REGNO (reg2)],
|
||||
freq, constraint_p, insn,
|
||||
ira_allocno_t a1 = ira_curr_regno_allocno_map[REGNO (reg1)];
|
||||
ira_allocno_t a2 = ira_curr_regno_allocno_map[REGNO (reg2)];
|
||||
if (!allocnos_conflict_p (a1, a2) && offset1 == offset2)
|
||||
{
|
||||
cp = ira_add_allocno_copy (a1, a2, freq, constraint_p, insn,
|
||||
ira_curr_loop_tree_node);
|
||||
bitmap_set_bit (ira_curr_loop_tree_node->local_copies, cp->num);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! IN_RANGE (allocno_preferenced_hard_regno, 0, FIRST_PSEUDO_REGISTER - 1))
|
||||
/* Can not be tied. */
|
||||
return false;
|
||||
|
@ -541,14 +561,14 @@ propagate_copies (void)
|
|||
parent_a1 = ira_parent_or_cap_allocno (a1);
|
||||
parent_a2 = ira_parent_or_cap_allocno (a2);
|
||||
ira_assert (parent_a1 != NULL && parent_a2 != NULL);
|
||||
if (! CONFLICT_ALLOCNO_P (parent_a1, parent_a2))
|
||||
if (! allocnos_conflict_p (parent_a1, parent_a2))
|
||||
ira_add_allocno_copy (parent_a1, parent_a2, cp->freq,
|
||||
cp->constraint_p, cp->insn, cp->loop_tree_node);
|
||||
}
|
||||
}
|
||||
|
||||
/* Array used to collect all conflict allocnos for given allocno. */
|
||||
static ira_allocno_t *collected_conflict_allocnos;
|
||||
static ira_object_t *collected_conflict_objects;
|
||||
|
||||
/* Build conflict vectors or bit conflict vectors (whatever is more
|
||||
profitable) for allocno A from the conflict table and propagate the
|
||||
|
@ -558,50 +578,56 @@ build_allocno_conflicts (ira_allocno_t a)
|
|||
{
|
||||
int i, px, parent_num;
|
||||
int conflict_bit_vec_words_num;
|
||||
ira_allocno_t parent_a, another_a, another_parent_a;
|
||||
ira_allocno_t *vec;
|
||||
ira_allocno_t parent_a, another_parent_a;
|
||||
ira_object_t *vec;
|
||||
IRA_INT_TYPE *allocno_conflicts;
|
||||
ira_object_t obj, parent_obj;
|
||||
minmax_set_iterator asi;
|
||||
|
||||
allocno_conflicts = conflicts[ALLOCNO_NUM (a)];
|
||||
obj = ALLOCNO_OBJECT (a);
|
||||
allocno_conflicts = conflicts[OBJECT_CONFLICT_ID (obj)];
|
||||
px = 0;
|
||||
FOR_EACH_BIT_IN_MINMAX_SET (allocno_conflicts,
|
||||
ALLOCNO_MIN (a), ALLOCNO_MAX (a), i, asi)
|
||||
OBJECT_MIN (obj), OBJECT_MAX (obj), i, asi)
|
||||
{
|
||||
another_a = ira_conflict_id_allocno_map[i];
|
||||
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)]);
|
||||
collected_conflict_allocnos[px++] = another_a;
|
||||
collected_conflict_objects[px++] = another_obj;
|
||||
}
|
||||
if (ira_conflict_vector_profitable_p (a, px))
|
||||
if (ira_conflict_vector_profitable_p (obj, px))
|
||||
{
|
||||
ira_allocate_allocno_conflict_vec (a, px);
|
||||
vec = (ira_allocno_t*) ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a);
|
||||
memcpy (vec, collected_conflict_allocnos, sizeof (ira_allocno_t) * px);
|
||||
ira_allocate_conflict_vec (obj, px);
|
||||
vec = OBJECT_CONFLICT_VEC (obj);
|
||||
memcpy (vec, collected_conflict_objects, sizeof (ira_object_t) * px);
|
||||
vec[px] = NULL;
|
||||
ALLOCNO_CONFLICT_ALLOCNOS_NUM (a) = px;
|
||||
OBJECT_NUM_CONFLICTS (obj) = px;
|
||||
}
|
||||
else
|
||||
{
|
||||
ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a) = conflicts[ALLOCNO_NUM (a)];
|
||||
if (ALLOCNO_MAX (a) < ALLOCNO_MIN (a))
|
||||
OBJECT_CONFLICT_ARRAY (obj) = allocno_conflicts;
|
||||
if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
|
||||
conflict_bit_vec_words_num = 0;
|
||||
else
|
||||
conflict_bit_vec_words_num
|
||||
= ((ALLOCNO_MAX (a) - ALLOCNO_MIN (a) + IRA_INT_BITS)
|
||||
= ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
|
||||
/ IRA_INT_BITS);
|
||||
ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a)
|
||||
OBJECT_CONFLICT_ARRAY_SIZE (obj)
|
||||
= conflict_bit_vec_words_num * sizeof (IRA_INT_TYPE);
|
||||
}
|
||||
parent_a = ira_parent_or_cap_allocno (a);
|
||||
if (parent_a == NULL)
|
||||
return;
|
||||
ira_assert (ALLOCNO_COVER_CLASS (a) == ALLOCNO_COVER_CLASS (parent_a));
|
||||
parent_num = ALLOCNO_NUM (parent_a);
|
||||
parent_obj = ALLOCNO_OBJECT (parent_a);
|
||||
parent_num = OBJECT_CONFLICT_ID (parent_obj);
|
||||
FOR_EACH_BIT_IN_MINMAX_SET (allocno_conflicts,
|
||||
ALLOCNO_MIN (a), ALLOCNO_MAX (a), i, asi)
|
||||
OBJECT_MIN (obj), OBJECT_MAX (obj), i, asi)
|
||||
{
|
||||
another_a = ira_conflict_id_allocno_map[i];
|
||||
ira_object_t another_obj = ira_object_id_map[i];
|
||||
ira_allocno_t another_a = OBJECT_ALLOCNO (another_obj);
|
||||
|
||||
ira_assert (ira_reg_classes_intersect_p
|
||||
[ALLOCNO_COVER_CLASS (a)][ALLOCNO_COVER_CLASS (another_a)]);
|
||||
another_parent_a = ira_parent_or_cap_allocno (another_a);
|
||||
|
@ -611,9 +637,9 @@ build_allocno_conflicts (ira_allocno_t a)
|
|||
ira_assert (ALLOCNO_COVER_CLASS (another_a)
|
||||
== ALLOCNO_COVER_CLASS (another_parent_a));
|
||||
SET_MINMAX_SET_BIT (conflicts[parent_num],
|
||||
ALLOCNO_CONFLICT_ID (another_parent_a),
|
||||
ALLOCNO_MIN (parent_a),
|
||||
ALLOCNO_MAX (parent_a));
|
||||
OBJECT_CONFLICT_ID (ALLOCNO_OBJECT (another_parent_a)),
|
||||
OBJECT_MIN (parent_obj),
|
||||
OBJECT_MAX (parent_obj));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -625,9 +651,9 @@ build_conflicts (void)
|
|||
int i;
|
||||
ira_allocno_t a, cap;
|
||||
|
||||
collected_conflict_allocnos
|
||||
= (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t)
|
||||
* ira_allocnos_num);
|
||||
collected_conflict_objects
|
||||
= (ira_object_t *) ira_allocate (sizeof (ira_object_t)
|
||||
* ira_objects_num);
|
||||
for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--)
|
||||
for (a = ira_regno_allocno_map[i];
|
||||
a != NULL;
|
||||
|
@ -637,7 +663,7 @@ build_conflicts (void)
|
|||
for (cap = ALLOCNO_CAP (a); cap != NULL; cap = ALLOCNO_CAP (cap))
|
||||
build_allocno_conflicts (cap);
|
||||
}
|
||||
ira_free (collected_conflict_allocnos);
|
||||
ira_free (collected_conflict_objects);
|
||||
}
|
||||
|
||||
|
||||
|
@ -675,6 +701,7 @@ static void
|
|||
print_allocno_conflicts (FILE * file, bool reg_p, ira_allocno_t a)
|
||||
{
|
||||
HARD_REG_SET conflicting_hard_regs;
|
||||
ira_object_t obj;
|
||||
ira_allocno_t conflict_a;
|
||||
ira_allocno_conflict_iterator aci;
|
||||
basic_block bb;
|
||||
|
@ -690,8 +717,10 @@ print_allocno_conflicts (FILE * file, bool reg_p, ira_allocno_t a)
|
|||
fprintf (file, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop->num);
|
||||
putc (')', file);
|
||||
}
|
||||
|
||||
fputs (" conflicts:", file);
|
||||
if (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a) != NULL)
|
||||
obj = ALLOCNO_OBJECT (a);
|
||||
if (OBJECT_CONFLICT_ARRAY (obj) != NULL)
|
||||
FOR_EACH_ALLOCNO_CONFLICT (a, conflict_a, aci)
|
||||
{
|
||||
if (reg_p)
|
||||
|
@ -707,15 +736,15 @@ print_allocno_conflicts (FILE * file, bool reg_p, ira_allocno_t a)
|
|||
ALLOCNO_LOOP_TREE_NODE (conflict_a)->loop->num);
|
||||
}
|
||||
}
|
||||
COPY_HARD_REG_SET (conflicting_hard_regs,
|
||||
ALLOCNO_TOTAL_CONFLICT_HARD_REGS (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)]);
|
||||
print_hard_reg_set (file, "\n;; total conflict hard regs:",
|
||||
conflicting_hard_regs);
|
||||
COPY_HARD_REG_SET (conflicting_hard_regs,
|
||||
ALLOCNO_CONFLICT_HARD_REGS (a));
|
||||
|
||||
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)]);
|
||||
|
@ -760,19 +789,22 @@ ira_build_conflicts (void)
|
|||
ira_conflicts_p = build_conflict_bit_table ();
|
||||
if (ira_conflicts_p)
|
||||
{
|
||||
ira_object_t obj;
|
||||
ira_object_iterator oi;
|
||||
|
||||
build_conflicts ();
|
||||
ira_traverse_loop_tree (true, ira_loop_tree_root, NULL, add_copies);
|
||||
/* We need finished conflict table for the subsequent call. */
|
||||
if (flag_ira_region == IRA_REGION_ALL
|
||||
|| flag_ira_region == IRA_REGION_MIXED)
|
||||
propagate_copies ();
|
||||
|
||||
/* Now we can free memory for the conflict table (see function
|
||||
build_allocno_conflicts for details). */
|
||||
FOR_EACH_ALLOCNO (a, ai)
|
||||
FOR_EACH_OBJECT (obj, oi)
|
||||
{
|
||||
if (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a)
|
||||
!= conflicts[ALLOCNO_NUM (a)])
|
||||
ira_free (conflicts[ALLOCNO_NUM (a)]);
|
||||
if (OBJECT_CONFLICT_ARRAY (obj) != conflicts[OBJECT_CONFLICT_ID (obj)])
|
||||
ira_free (conflicts[OBJECT_CONFLICT_ID (obj)]);
|
||||
}
|
||||
ira_free (conflicts);
|
||||
}
|
||||
|
@ -788,6 +820,7 @@ ira_build_conflicts (void)
|
|||
}
|
||||
FOR_EACH_ALLOCNO (a, ai)
|
||||
{
|
||||
ira_object_t obj = ALLOCNO_OBJECT (a);
|
||||
reg_attrs *attrs;
|
||||
tree decl;
|
||||
|
||||
|
@ -800,21 +833,16 @@ ira_build_conflicts (void)
|
|||
&& VAR_OR_FUNCTION_DECL_P (decl)
|
||||
&& ! DECL_ARTIFICIAL (decl)))
|
||||
{
|
||||
IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a),
|
||||
call_used_reg_set);
|
||||
IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a),
|
||||
call_used_reg_set);
|
||||
IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), call_used_reg_set);
|
||||
IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), call_used_reg_set);
|
||||
}
|
||||
else if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
|
||||
{
|
||||
IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a),
|
||||
IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
|
||||
no_caller_save_reg_set);
|
||||
IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a),
|
||||
temp_hard_reg_set);
|
||||
IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a),
|
||||
no_caller_save_reg_set);
|
||||
IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a),
|
||||
temp_hard_reg_set);
|
||||
IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), temp_hard_reg_set);
|
||||
IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), no_caller_save_reg_set);
|
||||
IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), temp_hard_reg_set);
|
||||
}
|
||||
}
|
||||
if (optimize && ira_conflicts_p
|
||||
|
|
|
@ -646,7 +646,7 @@ static move_t
|
|||
modify_move_list (move_t list)
|
||||
{
|
||||
int i, n, nregs, hard_regno;
|
||||
ira_allocno_t to, from, new_allocno;
|
||||
ira_allocno_t to, from;
|
||||
move_t move, new_move, set_move, first, last;
|
||||
|
||||
if (list == NULL)
|
||||
|
@ -715,6 +715,9 @@ modify_move_list (move_t list)
|
|||
&& ALLOCNO_HARD_REGNO
|
||||
(hard_regno_last_set[hard_regno + i]->to) >= 0)
|
||||
{
|
||||
ira_allocno_t new_allocno;
|
||||
ira_object_t new_obj;
|
||||
|
||||
set_move = hard_regno_last_set[hard_regno + i];
|
||||
/* It does not matter what loop_tree_node (of TO or
|
||||
FROM) to use for the new allocno because of
|
||||
|
@ -726,16 +729,19 @@ modify_move_list (move_t list)
|
|||
ALLOCNO_MODE (new_allocno) = ALLOCNO_MODE (set_move->to);
|
||||
ira_set_allocno_cover_class
|
||||
(new_allocno, ALLOCNO_COVER_CLASS (set_move->to));
|
||||
ira_create_allocno_object (new_allocno);
|
||||
ALLOCNO_ASSIGNED_P (new_allocno) = true;
|
||||
ALLOCNO_HARD_REGNO (new_allocno) = -1;
|
||||
ALLOCNO_REG (new_allocno)
|
||||
= create_new_reg (ALLOCNO_REG (set_move->to));
|
||||
ALLOCNO_CONFLICT_ID (new_allocno) = ALLOCNO_NUM (new_allocno);
|
||||
|
||||
new_obj = ALLOCNO_OBJECT (new_allocno);
|
||||
|
||||
/* Make it possibly conflicting with all earlier
|
||||
created allocnos. Cases where temporary allocnos
|
||||
created to remove the cycles are quite rare. */
|
||||
ALLOCNO_MIN (new_allocno) = 0;
|
||||
ALLOCNO_MAX (new_allocno) = ira_allocnos_num - 1;
|
||||
OBJECT_MIN (new_obj) = 0;
|
||||
OBJECT_MAX (new_obj) = ira_objects_num - 1;
|
||||
new_move = create_move (set_move->to, new_allocno);
|
||||
set_move->to = new_allocno;
|
||||
VEC_safe_push (move_t, heap, move_vec, new_move);
|
||||
|
@ -911,7 +917,7 @@ add_range_and_copies_from_move_list (move_t list, ira_loop_tree_node_t node,
|
|||
int start, n;
|
||||
unsigned int regno;
|
||||
move_t move;
|
||||
ira_allocno_t to, from, a;
|
||||
ira_allocno_t a;
|
||||
ira_copy_t cp;
|
||||
live_range_t r;
|
||||
bitmap_iterator bi;
|
||||
|
@ -929,22 +935,23 @@ add_range_and_copies_from_move_list (move_t list, ira_loop_tree_node_t node,
|
|||
start = ira_max_point;
|
||||
for (move = list; move != NULL; move = move->next)
|
||||
{
|
||||
from = move->from;
|
||||
to = move->to;
|
||||
if (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (to) == NULL)
|
||||
ira_allocno_t from = move->from;
|
||||
ira_allocno_t to = move->to;
|
||||
ira_object_t from_obj = ALLOCNO_OBJECT (from);
|
||||
ira_object_t to_obj = ALLOCNO_OBJECT (to);
|
||||
if (OBJECT_CONFLICT_ARRAY (to_obj) == NULL)
|
||||
{
|
||||
if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
|
||||
fprintf (ira_dump_file, " Allocate conflicts for a%dr%d\n",
|
||||
ALLOCNO_NUM (to), REGNO (ALLOCNO_REG (to)));
|
||||
ira_allocate_allocno_conflicts (to, n);
|
||||
ira_allocate_object_conflicts (to_obj, n);
|
||||
}
|
||||
bitmap_clear_bit (live_through, ALLOCNO_REGNO (from));
|
||||
bitmap_clear_bit (live_through, ALLOCNO_REGNO (to));
|
||||
IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (from), hard_regs_live);
|
||||
IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (to), hard_regs_live);
|
||||
IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (from),
|
||||
hard_regs_live);
|
||||
IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (to), hard_regs_live);
|
||||
IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (from_obj), hard_regs_live);
|
||||
IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (to_obj), hard_regs_live);
|
||||
IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (from_obj), hard_regs_live);
|
||||
IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (to_obj), hard_regs_live);
|
||||
update_costs (from, true, freq);
|
||||
update_costs (to, false, freq);
|
||||
cp = ira_add_allocno_copy (from, to, freq, false, move->insn, NULL);
|
||||
|
@ -994,6 +1001,7 @@ add_range_and_copies_from_move_list (move_t list, ira_loop_tree_node_t node,
|
|||
}
|
||||
EXECUTE_IF_SET_IN_BITMAP (live_through, FIRST_PSEUDO_REGISTER, regno, bi)
|
||||
{
|
||||
ira_allocno_t to;
|
||||
a = node->regno_allocno_map[regno];
|
||||
if ((to = ALLOCNO_MEM_OPTIMIZED_DEST (a)) != NULL)
|
||||
a = to;
|
||||
|
|
203
gcc/ira-int.h
203
gcc/ira-int.h
|
@ -62,10 +62,13 @@ extern FILE *ira_dump_file;
|
|||
typedef struct live_range *live_range_t;
|
||||
typedef struct ira_allocno *ira_allocno_t;
|
||||
typedef struct ira_allocno_copy *ira_copy_t;
|
||||
typedef struct ira_object *ira_object_t;
|
||||
|
||||
/* Definition of vector of allocnos and copies. */
|
||||
DEF_VEC_P(ira_allocno_t);
|
||||
DEF_VEC_ALLOC_P(ira_allocno_t, heap);
|
||||
DEF_VEC_P(ira_object_t);
|
||||
DEF_VEC_ALLOC_P(ira_object_t, heap);
|
||||
DEF_VEC_P(ira_copy_t);
|
||||
DEF_VEC_ALLOC_P(ira_copy_t, heap);
|
||||
|
||||
|
@ -222,6 +225,43 @@ extern int ira_max_point;
|
|||
live ranges with given start/finish point. */
|
||||
extern live_range_t *ira_start_point_ranges, *ira_finish_point_ranges;
|
||||
|
||||
/* A structure representing conflict information for an allocno
|
||||
(or one of its subwords). */
|
||||
struct ira_object
|
||||
{
|
||||
/* The allocno associated with this record. */
|
||||
ira_allocno_t allocno;
|
||||
/* Vector of accumulated conflicting conflict_redords with NULL end
|
||||
marker (if OBJECT_CONFLICT_VEC_P is true) or conflict bit vector
|
||||
otherwise. Only objects belonging to allocnos with the
|
||||
same cover class are in the vector or in the bit vector. */
|
||||
void *conflicts_array;
|
||||
/* Allocated size of the previous array. */
|
||||
unsigned int conflicts_array_size;
|
||||
/* A unique number for every instance of this structure which is used
|
||||
to represent it in conflict bit vectors. */
|
||||
int id;
|
||||
/* Before building conflicts, MIN and MAX are initialized to
|
||||
correspondingly minimal and maximal points of the accumulated
|
||||
allocno live ranges. Afterwards, they hold the minimal and
|
||||
maximal ids of other objects that this one can conflict
|
||||
with. */
|
||||
int min, max;
|
||||
/* Initial and accumulated hard registers conflicting with this
|
||||
conflict record and as a consequences can not be assigned to the
|
||||
allocno. All non-allocatable hard regs and hard regs of cover
|
||||
classes different from given allocno one are included in the
|
||||
sets. */
|
||||
HARD_REG_SET conflict_hard_regs, total_conflict_hard_regs;
|
||||
/* Number of accumulated conflicts in the vector of conflicting
|
||||
conflict records. */
|
||||
int num_accumulated_conflicts;
|
||||
/* TRUE if conflicts are represented by a vector of pointers to
|
||||
ira_object structures. Otherwise, we use a bit vector indexed
|
||||
by conflict ID numbers. */
|
||||
unsigned int conflict_vec_p : 1;
|
||||
};
|
||||
|
||||
/* A structure representing an allocno (allocation entity). Allocno
|
||||
represents a pseudo-register in an allocation region. If
|
||||
pseudo-register does not live in a region but it lives in the
|
||||
|
@ -306,30 +346,9 @@ struct ira_allocno
|
|||
ranges in the list are not intersected and ordered by decreasing
|
||||
their program points*. */
|
||||
live_range_t live_ranges;
|
||||
/* Before building conflicts the two member values are
|
||||
correspondingly minimal and maximal points of the accumulated
|
||||
allocno live ranges. After building conflicts the values are
|
||||
correspondingly minimal and maximal conflict ids of allocnos with
|
||||
which given allocno can conflict. */
|
||||
int min, max;
|
||||
/* Vector of accumulated conflicting allocnos with NULL end marker
|
||||
(if CONFLICT_VEC_P is true) or conflict bit vector otherwise.
|
||||
Only allocnos with the same cover class are in the vector or in
|
||||
the bit vector. */
|
||||
void *conflict_allocno_array;
|
||||
/* The unique member value represents given allocno in conflict bit
|
||||
vectors. */
|
||||
int conflict_id;
|
||||
/* Allocated size of the previous array. */
|
||||
unsigned int conflict_allocno_array_size;
|
||||
/* Initial and accumulated hard registers conflicting with this
|
||||
allocno and as a consequences can not be assigned to the allocno.
|
||||
All non-allocatable hard regs and hard regs of cover classes
|
||||
different from given allocno one are included in the sets. */
|
||||
HARD_REG_SET conflict_hard_regs, total_conflict_hard_regs;
|
||||
/* Number of accumulated conflicts in the vector of conflicting
|
||||
allocnos. */
|
||||
int conflict_allocnos_num;
|
||||
/* Pointer to a structure describing conflict information about this
|
||||
allocno. */
|
||||
ira_object_t object;
|
||||
/* Accumulated frequency of calls which given allocno
|
||||
intersects. */
|
||||
int call_freq;
|
||||
|
@ -374,11 +393,6 @@ struct ira_allocno
|
|||
/* TRUE if the allocno was removed from the splay tree used to
|
||||
choose allocn for spilling (see ira-color.c::. */
|
||||
unsigned int splay_removed_p : 1;
|
||||
/* TRUE if conflicts for given allocno are represented by vector of
|
||||
pointers to the conflicting allocnos. Otherwise, we use a bit
|
||||
vector where a bit with given index represents allocno with the
|
||||
same number. */
|
||||
unsigned int conflict_vec_p : 1;
|
||||
/* Non NULL if we remove restoring value from given allocno to
|
||||
MEM_OPTIMIZED_DEST at loop exit (see ira-emit.c) because the
|
||||
allocno value is not changed inside the loop. */
|
||||
|
@ -429,13 +443,6 @@ struct ira_allocno
|
|||
#define ALLOCNO_LOOP_TREE_NODE(A) ((A)->loop_tree_node)
|
||||
#define ALLOCNO_CAP(A) ((A)->cap)
|
||||
#define ALLOCNO_CAP_MEMBER(A) ((A)->cap_member)
|
||||
#define ALLOCNO_CONFLICT_ALLOCNO_ARRAY(A) ((A)->conflict_allocno_array)
|
||||
#define ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE(A) \
|
||||
((A)->conflict_allocno_array_size)
|
||||
#define ALLOCNO_CONFLICT_ALLOCNOS_NUM(A) \
|
||||
((A)->conflict_allocnos_num)
|
||||
#define ALLOCNO_CONFLICT_HARD_REGS(A) ((A)->conflict_hard_regs)
|
||||
#define ALLOCNO_TOTAL_CONFLICT_HARD_REGS(A) ((A)->total_conflict_hard_regs)
|
||||
#define ALLOCNO_NREFS(A) ((A)->nrefs)
|
||||
#define ALLOCNO_FREQ(A) ((A)->freq)
|
||||
#define ALLOCNO_HARD_REGNO(A) ((A)->hard_regno)
|
||||
|
@ -455,7 +462,6 @@ struct ira_allocno
|
|||
#define ALLOCNO_ASSIGNED_P(A) ((A)->assigned_p)
|
||||
#define ALLOCNO_MAY_BE_SPILLED_P(A) ((A)->may_be_spilled_p)
|
||||
#define ALLOCNO_SPLAY_REMOVED_P(A) ((A)->splay_removed_p)
|
||||
#define ALLOCNO_CONFLICT_VEC_P(A) ((A)->conflict_vec_p)
|
||||
#define ALLOCNO_MODE(A) ((A)->mode)
|
||||
#define ALLOCNO_COPIES(A) ((A)->allocno_copies)
|
||||
#define ALLOCNO_HARD_REG_COSTS(A) ((A)->hard_reg_costs)
|
||||
|
@ -478,9 +484,20 @@ struct ira_allocno
|
|||
#define ALLOCNO_FIRST_COALESCED_ALLOCNO(A) ((A)->first_coalesced_allocno)
|
||||
#define ALLOCNO_NEXT_COALESCED_ALLOCNO(A) ((A)->next_coalesced_allocno)
|
||||
#define ALLOCNO_LIVE_RANGES(A) ((A)->live_ranges)
|
||||
#define ALLOCNO_MIN(A) ((A)->min)
|
||||
#define ALLOCNO_MAX(A) ((A)->max)
|
||||
#define ALLOCNO_CONFLICT_ID(A) ((A)->conflict_id)
|
||||
#define ALLOCNO_OBJECT(A) ((A)->object)
|
||||
|
||||
#define OBJECT_ALLOCNO(C) ((C)->allocno)
|
||||
#define OBJECT_CONFLICT_ARRAY(C) ((C)->conflicts_array)
|
||||
#define OBJECT_CONFLICT_VEC(C) ((ira_object_t *)(C)->conflicts_array)
|
||||
#define OBJECT_CONFLICT_BITVEC(C) ((IRA_INT_TYPE *)(C)->conflicts_array)
|
||||
#define OBJECT_CONFLICT_ARRAY_SIZE(C) ((C)->conflicts_array_size)
|
||||
#define OBJECT_CONFLICT_VEC_P(C) ((C)->conflict_vec_p)
|
||||
#define OBJECT_NUM_CONFLICTS(C) ((C)->num_accumulated_conflicts)
|
||||
#define OBJECT_CONFLICT_HARD_REGS(C) ((C)->conflict_hard_regs)
|
||||
#define OBJECT_TOTAL_CONFLICT_HARD_REGS(C) ((C)->total_conflict_hard_regs)
|
||||
#define OBJECT_MIN(C) ((C)->min)
|
||||
#define OBJECT_MAX(C) ((C)->max)
|
||||
#define OBJECT_CONFLICT_ID(C) ((C)->id)
|
||||
|
||||
/* Map regno -> allocnos with given regno (see comments for
|
||||
allocno member `next_regno_allocno'). */
|
||||
|
@ -491,12 +508,14 @@ extern ira_allocno_t *ira_regno_allocno_map;
|
|||
have NULL element value. */
|
||||
extern ira_allocno_t *ira_allocnos;
|
||||
|
||||
/* Sizes of the previous array. */
|
||||
/* The size of the previous array. */
|
||||
extern int ira_allocnos_num;
|
||||
|
||||
/* Map conflict id -> allocno with given conflict id (see comments for
|
||||
allocno member `conflict_id'). */
|
||||
extern ira_allocno_t *ira_conflict_id_allocno_map;
|
||||
/* Map a conflict id to its corresponding ira_object structure. */
|
||||
extern ira_object_t *ira_object_id_map;
|
||||
|
||||
/* The size of the previous array. */
|
||||
extern int ira_objects_num;
|
||||
|
||||
/* The following structure represents a copy of two allocnos. The
|
||||
copies represent move insns or potential move insns usually because
|
||||
|
@ -910,11 +929,11 @@ extern void ira_traverse_loop_tree (bool, ira_loop_tree_node_t,
|
|||
extern ira_allocno_t ira_parent_allocno (ira_allocno_t);
|
||||
extern ira_allocno_t ira_parent_or_cap_allocno (ira_allocno_t);
|
||||
extern ira_allocno_t ira_create_allocno (int, bool, ira_loop_tree_node_t);
|
||||
extern void ira_create_allocno_object (ira_allocno_t);
|
||||
extern void ira_set_allocno_cover_class (ira_allocno_t, enum reg_class);
|
||||
extern bool ira_conflict_vector_profitable_p (ira_allocno_t, int);
|
||||
extern void ira_allocate_allocno_conflict_vec (ira_allocno_t, int);
|
||||
extern void ira_allocate_allocno_conflicts (ira_allocno_t, int);
|
||||
extern void ira_add_allocno_conflict (ira_allocno_t, ira_allocno_t);
|
||||
extern bool ira_conflict_vector_profitable_p (ira_object_t, int);
|
||||
extern void ira_allocate_conflict_vec (ira_object_t, int);
|
||||
extern void ira_allocate_object_conflicts (ira_object_t, int);
|
||||
extern void ira_print_expanded_allocno (ira_allocno_t);
|
||||
extern live_range_t ira_create_allocno_live_range (ira_allocno_t, int, int,
|
||||
live_range_t);
|
||||
|
@ -1037,8 +1056,43 @@ ira_allocno_iter_cond (ira_allocno_iterator *i, ira_allocno_t *a)
|
|||
#define FOR_EACH_ALLOCNO(A, ITER) \
|
||||
for (ira_allocno_iter_init (&(ITER)); \
|
||||
ira_allocno_iter_cond (&(ITER), &(A));)
|
||||
|
||||
/* The iterator for all objects. */
|
||||
typedef struct {
|
||||
/* The number of the current element in IRA_OBJECT_ID_MAP. */
|
||||
int n;
|
||||
} ira_object_iterator;
|
||||
|
||||
/* Initialize the iterator I. */
|
||||
static inline void
|
||||
ira_object_iter_init (ira_object_iterator *i)
|
||||
{
|
||||
i->n = 0;
|
||||
}
|
||||
|
||||
/* Return TRUE if we have more objects to visit, in which case *OBJ is
|
||||
set to the object to be visited. Otherwise, return FALSE. */
|
||||
static inline bool
|
||||
ira_object_iter_cond (ira_object_iterator *i, ira_object_t *obj)
|
||||
{
|
||||
int n;
|
||||
|
||||
for (n = i->n; n < ira_objects_num; n++)
|
||||
if (ira_object_id_map[n] != NULL)
|
||||
{
|
||||
*obj = ira_object_id_map[n];
|
||||
i->n = n + 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Loop over all objects. In each iteration, A is set to the next
|
||||
conflict. ITER is an instance of ira_object_iterator used to iterate
|
||||
the objects. */
|
||||
#define FOR_EACH_OBJECT(OBJ, ITER) \
|
||||
for (ira_object_iter_init (&(ITER)); \
|
||||
ira_object_iter_cond (&(ITER), &(OBJ));)
|
||||
|
||||
|
||||
/* The iterator for copies. */
|
||||
|
@ -1077,38 +1131,33 @@ ira_copy_iter_cond (ira_copy_iterator *i, ira_copy_t *cp)
|
|||
#define FOR_EACH_COPY(C, ITER) \
|
||||
for (ira_copy_iter_init (&(ITER)); \
|
||||
ira_copy_iter_cond (&(ITER), &(C));)
|
||||
|
||||
|
||||
|
||||
|
||||
/* The iterator for allocno conflicts. */
|
||||
typedef struct {
|
||||
|
||||
/* TRUE if the conflicts are represented by vector of allocnos. */
|
||||
bool allocno_conflict_vec_p;
|
||||
/* TRUE if the conflicts are represented by vector of objects. */
|
||||
bool conflict_vec_p;
|
||||
|
||||
/* The conflict vector or conflict bit vector. */
|
||||
void *vec;
|
||||
|
||||
/* The number of the current element in the vector (of type
|
||||
ira_allocno_t or IRA_INT_TYPE). */
|
||||
ira_object_t or IRA_INT_TYPE). */
|
||||
unsigned int word_num;
|
||||
|
||||
/* The bit vector size. It is defined only if
|
||||
ALLOCNO_CONFLICT_VEC_P is FALSE. */
|
||||
OBJECT_CONFLICT_VEC_P is FALSE. */
|
||||
unsigned int size;
|
||||
|
||||
/* The current bit index of bit vector. It is defined only if
|
||||
ALLOCNO_CONFLICT_VEC_P is FALSE. */
|
||||
OBJECT_CONFLICT_VEC_P is FALSE. */
|
||||
unsigned int bit_num;
|
||||
|
||||
/* Allocno conflict id corresponding to the 1st bit of the bit
|
||||
vector. It is defined only if ALLOCNO_CONFLICT_VEC_P is
|
||||
FALSE. */
|
||||
/* The object id corresponding to the 1st bit of the bit vector. It
|
||||
is defined only if OBJECT_CONFLICT_VEC_P is FALSE. */
|
||||
int base_conflict_id;
|
||||
|
||||
/* The word of bit vector currently visited. It is defined only if
|
||||
ALLOCNO_CONFLICT_VEC_P is FALSE. */
|
||||
OBJECT_CONFLICT_VEC_P is FALSE. */
|
||||
unsigned IRA_INT_TYPE word;
|
||||
} ira_allocno_conflict_iterator;
|
||||
|
||||
|
@ -1117,21 +1166,22 @@ static inline void
|
|||
ira_allocno_conflict_iter_init (ira_allocno_conflict_iterator *i,
|
||||
ira_allocno_t allocno)
|
||||
{
|
||||
i->allocno_conflict_vec_p = ALLOCNO_CONFLICT_VEC_P (allocno);
|
||||
i->vec = ALLOCNO_CONFLICT_ALLOCNO_ARRAY (allocno);
|
||||
ira_object_t obj = ALLOCNO_OBJECT (allocno);
|
||||
i->conflict_vec_p = OBJECT_CONFLICT_VEC_P (obj);
|
||||
i->vec = OBJECT_CONFLICT_ARRAY (obj);
|
||||
i->word_num = 0;
|
||||
if (i->allocno_conflict_vec_p)
|
||||
if (i->conflict_vec_p)
|
||||
i->size = i->bit_num = i->base_conflict_id = i->word = 0;
|
||||
else
|
||||
{
|
||||
if (ALLOCNO_MIN (allocno) > ALLOCNO_MAX (allocno))
|
||||
if (OBJECT_MIN (obj) > OBJECT_MAX (obj))
|
||||
i->size = 0;
|
||||
else
|
||||
i->size = ((ALLOCNO_MAX (allocno) - ALLOCNO_MIN (allocno)
|
||||
i->size = ((OBJECT_MAX (obj) - OBJECT_MIN (obj)
|
||||
+ IRA_INT_BITS)
|
||||
/ IRA_INT_BITS) * sizeof (IRA_INT_TYPE);
|
||||
i->bit_num = 0;
|
||||
i->base_conflict_id = ALLOCNO_MIN (allocno);
|
||||
i->base_conflict_id = OBJECT_MIN (obj);
|
||||
i->word = (i->size == 0 ? 0 : ((IRA_INT_TYPE *) i->vec)[0]);
|
||||
}
|
||||
}
|
||||
|
@ -1143,15 +1193,13 @@ static inline bool
|
|||
ira_allocno_conflict_iter_cond (ira_allocno_conflict_iterator *i,
|
||||
ira_allocno_t *a)
|
||||
{
|
||||
ira_allocno_t conflict_allocno;
|
||||
ira_object_t obj;
|
||||
|
||||
if (i->allocno_conflict_vec_p)
|
||||
if (i->conflict_vec_p)
|
||||
{
|
||||
conflict_allocno = ((ira_allocno_t *) i->vec)[i->word_num];
|
||||
if (conflict_allocno == NULL)
|
||||
obj = ((ira_object_t *) i->vec)[i->word_num];
|
||||
if (obj == NULL)
|
||||
return false;
|
||||
*a = conflict_allocno;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1171,17 +1219,18 @@ ira_allocno_conflict_iter_cond (ira_allocno_conflict_iterator *i,
|
|||
for (; (i->word & 1) == 0; i->word >>= 1)
|
||||
i->bit_num++;
|
||||
|
||||
*a = ira_conflict_id_allocno_map[i->bit_num + i->base_conflict_id];
|
||||
|
||||
return true;
|
||||
obj = ira_object_id_map[i->bit_num + i->base_conflict_id];
|
||||
}
|
||||
|
||||
*a = OBJECT_ALLOCNO (obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Advance to the next conflicting allocno. */
|
||||
static inline void
|
||||
ira_allocno_conflict_iter_next (ira_allocno_conflict_iterator *i)
|
||||
{
|
||||
if (i->allocno_conflict_vec_p)
|
||||
if (i->conflict_vec_p)
|
||||
i->word_num++;
|
||||
else
|
||||
{
|
||||
|
|
|
@ -92,10 +92,10 @@ make_hard_regno_born (int regno)
|
|||
SET_HARD_REG_BIT (hard_regs_live, regno);
|
||||
EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, i)
|
||||
{
|
||||
SET_HARD_REG_BIT (ALLOCNO_CONFLICT_HARD_REGS (ira_allocnos[i]),
|
||||
regno);
|
||||
SET_HARD_REG_BIT (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (ira_allocnos[i]),
|
||||
regno);
|
||||
ira_allocno_t allocno = ira_allocnos[i];
|
||||
ira_object_t obj = ALLOCNO_OBJECT (allocno);
|
||||
SET_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (obj), regno);
|
||||
SET_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), regno);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,10 +114,11 @@ static void
|
|||
make_allocno_born (ira_allocno_t a)
|
||||
{
|
||||
live_range_t p = ALLOCNO_LIVE_RANGES (a);
|
||||
ira_object_t obj = ALLOCNO_OBJECT (a);
|
||||
|
||||
sparseset_set_bit (allocnos_live, ALLOCNO_NUM (a));
|
||||
IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a), hard_regs_live);
|
||||
IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a), hard_regs_live);
|
||||
IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), hard_regs_live);
|
||||
IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), hard_regs_live);
|
||||
|
||||
if (p == NULL
|
||||
|| (p->finish != curr_point && p->finish + 1 != curr_point))
|
||||
|
@ -840,12 +841,14 @@ process_single_reg_class_operands (bool in_p, int freq)
|
|||
a = ira_allocnos[px];
|
||||
if (a != operand_a)
|
||||
{
|
||||
ira_object_t obj = ALLOCNO_OBJECT (a);
|
||||
|
||||
/* We could increase costs of A instead of making it
|
||||
conflicting with the hard register. But it works worse
|
||||
because it will be spilled in reload in anyway. */
|
||||
IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a),
|
||||
IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj),
|
||||
reg_class_contents[cl]);
|
||||
IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a),
|
||||
IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
|
||||
reg_class_contents[cl]);
|
||||
}
|
||||
}
|
||||
|
@ -1030,14 +1033,16 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
|
|||
|| find_reg_note (insn, REG_SETJMP,
|
||||
NULL_RTX) != NULL_RTX)
|
||||
{
|
||||
SET_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a));
|
||||
SET_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a));
|
||||
ira_object_t obj = ALLOCNO_OBJECT (a);
|
||||
SET_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj));
|
||||
SET_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
|
||||
}
|
||||
if (can_throw_internal (insn))
|
||||
{
|
||||
IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a),
|
||||
ira_object_t obj = ALLOCNO_OBJECT (a);
|
||||
IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
|
||||
call_used_reg_set);
|
||||
IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a),
|
||||
IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj),
|
||||
call_used_reg_set);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1243,6 +1243,7 @@ ira_bad_reload_regno_1 (int regno, rtx x)
|
|||
{
|
||||
int x_regno;
|
||||
ira_allocno_t a;
|
||||
ira_object_t obj;
|
||||
enum reg_class pref;
|
||||
|
||||
/* We only deal with pseudo regs. */
|
||||
|
@ -1262,7 +1263,8 @@ ira_bad_reload_regno_1 (int regno, rtx x)
|
|||
/* If the pseudo conflicts with REGNO, then we consider REGNO a
|
||||
poor choice for a reload regno. */
|
||||
a = ira_regno_allocno_map[x_regno];
|
||||
if (TEST_HARD_REG_BIT (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a), regno))
|
||||
obj = ALLOCNO_OBJECT (a);
|
||||
if (TEST_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), regno))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
Loading…
Reference in New Issue