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:
Bernd Schmidt 2010-07-14 01:53:35 +00:00 committed by Bernd Schmidt
parent 5e0bf6cdff
commit a49ae21794
8 changed files with 668 additions and 413 deletions

View File

@ -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

View File

@ -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))
add_to_conflicts (obj1, obj2);
add_to_conflicts (obj2, obj1);
}
/* Clear all conflicts of OBJ. */
static void
clear_conflicts (ira_object_t obj)
{
if (OBJECT_CONFLICT_VEC_P (obj))
{
ALLOCNO_CONFLICT_ALLOCNOS_NUM (a) = 0;
((ira_allocno_t *) ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a))[0] = NULL;
OBJECT_NUM_CONFLICTS (obj) = 0;
OBJECT_CONFLICT_VEC (obj)[0] = NULL;
}
else if (ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a) != 0)
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)

View File

@ -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]);

View File

@ -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)
{
cp = ira_add_allocno_copy (ira_curr_regno_allocno_map[REGNO (reg1)],
ira_curr_regno_allocno_map[REGNO (reg2)],
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;
{
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;
@ -448,7 +468,7 @@ add_insn_allocno_copies (rtx insn)
const char *str;
bool commut_p, bound_p[MAX_RECOG_OPERANDS];
int i, j, n, freq;
freq = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn));
if (freq == 0)
freq = 1;
@ -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

View File

@ -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;

View File

@ -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
{

View File

@ -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);
}
}

View File

@ -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;