Commit ac0ab4f7 by Bernd Schmidt Committed by Bernd Schmidt

ira-build.c (ira_create_object): New arg SUBWORD; all callers changed.

	* ira-build.c (ira_create_object): New arg SUBWORD; all callers changed.
	Initialize OBJECT_SUBWORD.
	(ira_create_allocno): Clear ALLOCNO_NUM_OBJECTS.
	(ira_create_allocno_objects): Renamed from ira_create_allocno_object;
	all callers changed.
	(merge_hard_reg_conflicts): Iterate over allocno subobjects.
	(finish_allocno): Likewise.
	(move_allocno_live_ranges, copy_allocno_live_ranges): Likewise.
	(remove_low_level_allocnos): Likewise.
	(update_bad_spill_attribute): Likewise.
	(setup_min_max_allocno_live_range_point): Likewise.
	(sort_conflict_id_map): Likewise.
	(ira_flattening): Likewise.  Use ior_hard_reg_conflicts.
	(ior_hard_reg_conflicts): New function.
	(ior_allocate_object_conflicts): Renamed first argument to OBJ.
	(compress_conflict_vecs): Iterate over objects, not allocnos.
	(ira_add_live_range_to_object): New function.
	(object_range_compare_func): Renamed from allocno_range_compare_func.
	All callers changed.
	(setup_min_max_conflict_allocno_ids): For allocnos with multiple
	subobjects, widen the min/max range of the lowest-order object to
	potentially include all other such low-order objects.
	* ira.c (ira_bad_reload_regno_1): Iterate over allocno subobjects.
	(check_allocation): Likewise.  Use more fine-grained tests for register
	conflicts.
	* ira-color.c (allocnos_have_intersected_live_ranges_p): Iterate over
	allocno subobjects.
	(assign_hard_reg): Keep multiple sets of conflicts.  Make finer-grained
	choices about which bits to set in each set.  Don't use
	ira_hard_reg_not_in_set_p, perform a more elaborate test for conflicts
	using the multiple sets we computed.
	(push_allocno_to_stack): Iterate over allocno subobjects.
	(all_conflicting_hard_regs_coalesced): New static function.
	(setup_allocno_available_regs_num): Use it.
	(setup_allocno_left_conflicts_size): Likewise.  Iterate over allocno
	subobjects.
	(coalesced_allocno_conflict): Test subobject 0 in each allocno.
	(setup_allocno_priorities): Divide ALLOCNO_EXCESS_PRESSURE_POINTS_NUM
	by ALLOCNO_NUM_OBJECTS.
	(calculate_spill_cost): Likewise.
	(color_pass): Express if statement in a more normal way.
	(ira_reassign_conflict_allocnos): Iterate over allocno subobjects.
	(slot_coalesced_allocno_live_ranges_intersect_p): Likewise.
	(setup_slot_coalesced_allocno_live_ranges): Likewise.
	(allocno_reload_assign): Likewise.
	(ira_reassign_pseudos): Likewise.
	(fast_allocation): Likewise.
	* ira-conflicts.c (build_conflict_bit_table): Likewise.
	(print_allocno_conflicts): Likewise.
	(ira_build_conflicts): Likewise.
	(allocnos_conflict_for_copy_p): Renamed from allocnos_conflict_p.  All
	callers changed.  Test subword 0 of each allocno for conflicts.
	(build_object_conflicts): Renamed from build_allocno_conflicts.  All
	callers changed.  Iterate over allocno subobjects.
	* ira-emit.c (modify_move_list): Iterate over allocno subobjects.
	* ira-int.h (struct ira_allocno): New member. num_objects.  Rename object
	to objects and change it into an array.
	(ALLOCNO_OBJECT): Add new argument N.
	(ALLOCNO_NUM_OBJECTS, OBJECT_SUBWORD): New macros.
	(ira_create_allocno_objects): Renamed from ira_create_allocno_object.
	(ior_hard_reg_conflicts): Declare.
	(ira_add_live_range_to_object): Declare.
	(ira_allocno_object_iterator): New.
	(ira_allocno_object_iter_init, ira_allocno_object_iter_cond): New.
	(FOR_EACH_ALLOCNO_OBJECT): New macro.
	* ira-lives.c (objects_live): Renamed from allocnos_live; all uses changed.
	(allocnos_processed): New sparseset.
	(make_object_born): Renamed from make_allocno_born; take an ira_object_t
	argument.  All callers changed.
	(make_object_dead): Renamed from make_allocno_dead; take an ira_object t
	argument.  All callers changed.
	(update_allocno_pressure_excess_length): Take an ira_obejct_t argument.
	All callers changed.
	(mark_pseudo_regno_live): Iterate over allocno subobjects.
	(mark_pseudo_regno_dead): Likewise.
	(mark_pseudo_regno_subword_live, mark_pseudo_regno_subword_dead): New
	functions.
	(mark_ref_live): Detect subword accesses and call
	mark_pseudo_regno_subword_live as appropriate.
	(mark_ref_dead): Likewise for mark_pseudo_regno_subword_dead.
	(process_bb_nodes_live): Deal with object-related updates first; set
	and test bits in allocnos_processed to avoid computing allocno
	statistics more than once.
	(create_start_finish_chains): Iterate over objects, not allocnos.
	(print_object_live_ranges): New function.
	(print_allocno_live_ranges): Use it.
	(ira_create_allocno_live_ranges): Allocate and free allocnos_processed
	and objects_live.

From-SVN: r162418
parent cd1822b8
2010-07-22 Bernd Schmidt <bernds@codesourcery.com>
* ira-build.c (ira_create_object): New arg SUBWORD; all callers changed.
Initialize OBJECT_SUBWORD.
(ira_create_allocno): Clear ALLOCNO_NUM_OBJECTS.
(ira_create_allocno_objects): Renamed from ira_create_allocno_object;
all callers changed.
(merge_hard_reg_conflicts): Iterate over allocno subobjects.
(finish_allocno): Likewise.
(move_allocno_live_ranges, copy_allocno_live_ranges): Likewise.
(remove_low_level_allocnos): Likewise.
(update_bad_spill_attribute): Likewise.
(setup_min_max_allocno_live_range_point): Likewise.
(sort_conflict_id_map): Likewise.
(ira_flattening): Likewise. Use ior_hard_reg_conflicts.
(ior_hard_reg_conflicts): New function.
(ior_allocate_object_conflicts): Renamed first argument to OBJ.
(compress_conflict_vecs): Iterate over objects, not allocnos.
(ira_add_live_range_to_object): New function.
(object_range_compare_func): Renamed from allocno_range_compare_func.
All callers changed.
(setup_min_max_conflict_allocno_ids): For allocnos with multiple
subobjects, widen the min/max range of the lowest-order object to
potentially include all other such low-order objects.
* ira.c (ira_bad_reload_regno_1): Iterate over allocno subobjects.
(check_allocation): Likewise. Use more fine-grained tests for register
conflicts.
* ira-color.c (allocnos_have_intersected_live_ranges_p): Iterate over
allocno subobjects.
(assign_hard_reg): Keep multiple sets of conflicts. Make finer-grained
choices about which bits to set in each set. Don't use
ira_hard_reg_not_in_set_p, perform a more elaborate test for conflicts
using the multiple sets we computed.
(push_allocno_to_stack): Iterate over allocno subobjects.
(all_conflicting_hard_regs_coalesced): New static function.
(setup_allocno_available_regs_num): Use it.
(setup_allocno_left_conflicts_size): Likewise. Iterate over allocno
subobjects.
(coalesced_allocno_conflict): Test subobject 0 in each allocno.
(setup_allocno_priorities): Divide ALLOCNO_EXCESS_PRESSURE_POINTS_NUM
by ALLOCNO_NUM_OBJECTS.
(calculate_spill_cost): Likewise.
(color_pass): Express if statement in a more normal way.
(ira_reassign_conflict_allocnos): Iterate over allocno subobjects.
(slot_coalesced_allocno_live_ranges_intersect_p): Likewise.
(setup_slot_coalesced_allocno_live_ranges): Likewise.
(allocno_reload_assign): Likewise.
(ira_reassign_pseudos): Likewise.
(fast_allocation): Likewise.
* ira-conflicts.c (build_conflict_bit_table): Likewise.
(print_allocno_conflicts): Likewise.
(ira_build_conflicts): Likewise.
(allocnos_conflict_for_copy_p): Renamed from allocnos_conflict_p. All
callers changed. Test subword 0 of each allocno for conflicts.
(build_object_conflicts): Renamed from build_allocno_conflicts. All
callers changed. Iterate over allocno subobjects.
* ira-emit.c (modify_move_list): Iterate over allocno subobjects.
* ira-int.h (struct ira_allocno): New member. num_objects. Rename object
to objects and change it into an array.
(ALLOCNO_OBJECT): Add new argument N.
(ALLOCNO_NUM_OBJECTS, OBJECT_SUBWORD): New macros.
(ira_create_allocno_objects): Renamed from ira_create_allocno_object.
(ior_hard_reg_conflicts): Declare.
(ira_add_live_range_to_object): Declare.
(ira_allocno_object_iterator): New.
(ira_allocno_object_iter_init, ira_allocno_object_iter_cond): New.
(FOR_EACH_ALLOCNO_OBJECT): New macro.
* ira-lives.c (objects_live): Renamed from allocnos_live; all uses changed.
(allocnos_processed): New sparseset.
(make_object_born): Renamed from make_allocno_born; take an ira_object_t
argument. All callers changed.
(make_object_dead): Renamed from make_allocno_dead; take an ira_object t
argument. All callers changed.
(update_allocno_pressure_excess_length): Take an ira_obejct_t argument.
All callers changed.
(mark_pseudo_regno_live): Iterate over allocno subobjects.
(mark_pseudo_regno_dead): Likewise.
(mark_pseudo_regno_subword_live, mark_pseudo_regno_subword_dead): New
functions.
(mark_ref_live): Detect subword accesses and call
mark_pseudo_regno_subword_live as appropriate.
(mark_ref_dead): Likewise for mark_pseudo_regno_subword_dead.
(process_bb_nodes_live): Deal with object-related updates first; set
and test bits in allocnos_processed to avoid computing allocno
statistics more than once.
(create_start_finish_chains): Iterate over objects, not allocnos.
(print_object_live_ranges): New function.
(print_allocno_live_ranges): Use it.
(ira_create_allocno_live_ranges): Allocate and free allocnos_processed
and objects_live.
2010-07-22 Richard Guenther <rguenther@suse.de>
PR lto/42451
......
......@@ -715,8 +715,8 @@ modify_move_list (move_t list)
&& ALLOCNO_HARD_REGNO
(hard_regno_last_set[hard_regno + i]->to) >= 0)
{
int n, j;
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
......@@ -729,19 +729,25 @@ 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);
ira_create_allocno_objects (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));
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. */
OBJECT_MIN (new_obj) = 0;
OBJECT_MAX (new_obj) = ira_objects_num - 1;
n = ALLOCNO_NUM_OBJECTS (new_allocno);
gcc_assert (n == ALLOCNO_NUM_OBJECTS (set_move->to));
for (j = 0; j < n; j++)
{
ira_object_t new_obj = ALLOCNO_OBJECT (new_allocno, j);
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);
......@@ -937,21 +943,26 @@ add_range_and_copies_from_move_list (move_t list, ira_loop_tree_node_t node,
{
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_object_conflicts (to_obj, n);
}
int nr, i;
bitmap_clear_bit (live_through, ALLOCNO_REGNO (from));
bitmap_clear_bit (live_through, ALLOCNO_REGNO (to));
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);
nr = ALLOCNO_NUM_OBJECTS (to);
for (i = 0; i < nr; i++)
{
ira_object_t to_obj = ALLOCNO_OBJECT (to, i);
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_object_conflicts (to_obj, n);
}
}
ior_hard_reg_conflicts (from, &hard_regs_live);
ior_hard_reg_conflicts (to, &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);
......@@ -960,58 +971,73 @@ add_range_and_copies_from_move_list (move_t list, ira_loop_tree_node_t node,
cp->num, ALLOCNO_NUM (cp->first),
REGNO (ALLOCNO_REG (cp->first)), ALLOCNO_NUM (cp->second),
REGNO (ALLOCNO_REG (cp->second)));
r = OBJECT_LIVE_RANGES (from_obj);
if (r == NULL || r->finish >= 0)
nr = ALLOCNO_NUM_OBJECTS (from);
for (i = 0; i < nr; i++)
{
OBJECT_LIVE_RANGES (from_obj)
= ira_create_live_range (from_obj, start, ira_max_point, r);
if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
fprintf (ira_dump_file,
" Adding range [%d..%d] to allocno a%dr%d\n",
start, ira_max_point, ALLOCNO_NUM (from),
REGNO (ALLOCNO_REG (from)));
ira_object_t from_obj = ALLOCNO_OBJECT (from, i);
r = OBJECT_LIVE_RANGES (from_obj);
if (r == NULL || r->finish >= 0)
{
ira_add_live_range_to_object (from_obj, start, ira_max_point);
if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
fprintf (ira_dump_file,
" Adding range [%d..%d] to allocno a%dr%d\n",
start, ira_max_point, ALLOCNO_NUM (from),
REGNO (ALLOCNO_REG (from)));
}
else
{
r->finish = ira_max_point;
if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
fprintf (ira_dump_file,
" Adding range [%d..%d] to allocno a%dr%d\n",
r->start, ira_max_point, ALLOCNO_NUM (from),
REGNO (ALLOCNO_REG (from)));
}
}
else
ira_max_point++;
nr = ALLOCNO_NUM_OBJECTS (to);
for (i = 0; i < nr; i++)
{
r->finish = ira_max_point;
if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
fprintf (ira_dump_file,
" Adding range [%d..%d] to allocno a%dr%d\n",
r->start, ira_max_point, ALLOCNO_NUM (from),
REGNO (ALLOCNO_REG (from)));
ira_object_t to_obj = ALLOCNO_OBJECT (to, i);
ira_add_live_range_to_object (to_obj, ira_max_point, -1);
}
ira_max_point++;
OBJECT_LIVE_RANGES (to_obj)
= ira_create_live_range (to_obj, ira_max_point, -1,
OBJECT_LIVE_RANGES (to_obj));
ira_max_point++;
}
for (move = list; move != NULL; move = move->next)
{
ira_object_t to_obj = ALLOCNO_OBJECT (move->to);
r = OBJECT_LIVE_RANGES (to_obj);
if (r->finish < 0)
int nr, i;
nr = ALLOCNO_NUM_OBJECTS (move->to);
for (i = 0; i < nr; i++)
{
r->finish = ira_max_point - 1;
if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
fprintf (ira_dump_file,
" Adding range [%d..%d] to allocno a%dr%d\n",
r->start, r->finish, ALLOCNO_NUM (move->to),
REGNO (ALLOCNO_REG (move->to)));
ira_object_t to_obj = ALLOCNO_OBJECT (move->to, i);
r = OBJECT_LIVE_RANGES (to_obj);
if (r->finish < 0)
{
r->finish = ira_max_point - 1;
if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
fprintf (ira_dump_file,
" Adding range [%d..%d] to allocno a%dr%d\n",
r->start, r->finish, ALLOCNO_NUM (move->to),
REGNO (ALLOCNO_REG (move->to)));
}
}
}
EXECUTE_IF_SET_IN_BITMAP (live_through, FIRST_PSEUDO_REGISTER, regno, bi)
{
ira_allocno_t to;
ira_object_t obj;
int nr, i;
a = node->regno_allocno_map[regno];
to = ALLOCNO_MEM_OPTIMIZED_DEST (a);
if (to != NULL)
if ((to = ALLOCNO_MEM_OPTIMIZED_DEST (a)) != NULL)
a = to;
obj = ALLOCNO_OBJECT (a);
OBJECT_LIVE_RANGES (obj)
= ira_create_live_range (obj, start, ira_max_point - 1,
OBJECT_LIVE_RANGES (obj));
nr = ALLOCNO_NUM_OBJECTS (a);
for (i = 0; i < nr; i++)
{
ira_object_t obj = ALLOCNO_OBJECT (a, i);
ira_add_live_range_to_object (obj, start, ira_max_point - 1);
}
if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
fprintf
(ira_dump_file,
......
......@@ -192,7 +192,6 @@ extern ira_loop_tree_node_t ira_loop_nodes;
#define IRA_LOOP_NODE(loop) IRA_LOOP_NODE_BY_INDEX ((loop)->num)
/* The structure describes program points where a given allocno lives.
To save memory we store allocno conflicts only for the same cover
class allocnos which is enough to assign hard registers. To find
......@@ -201,7 +200,7 @@ extern ira_loop_tree_node_t ira_loop_nodes;
intersected, the allocnos are in conflict. */
struct live_range
{
/* Allocno whose live range is described by given structure. */
/* Object whose live range is described by given structure. */
ira_object_t object;
/* Program point range. */
int start, finish;
......@@ -233,7 +232,7 @@ struct ira_object
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
otherwise. Only ira_objects belonging to allocnos with the
same cover class are in the vector or in the bit vector. */
void *conflicts_array;
/* Pointer to structures describing at what program point the
......@@ -241,25 +240,27 @@ struct ira_object
ranges in the list are not intersected and ordered by decreasing
their program points*. */
live_range_t live_ranges;
/* The subword within ALLOCNO which is represented by this object.
Zero means the lowest-order subword (or the entire allocno in case
it is not being tracked in subwords). */
int subword;
/* Allocated size of the conflicts array. */
unsigned int conflicts_array_size;
/* A unique number for every instance of this structure which is used
/* 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. */
live ranges. Afterwards, they hold the minimal and maximal ids
of other ira_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. */
object 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. */
objects. */
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
......@@ -346,9 +347,13 @@ struct ira_allocno
list is chained by NEXT_COALESCED_ALLOCNO. */
ira_allocno_t first_coalesced_allocno;
ira_allocno_t next_coalesced_allocno;
/* Pointer to a structure describing conflict information about this
allocno. */
ira_object_t object;
/* The number of objects tracked in the following array. */
int num_objects;
/* An array of structures describing conflict information and live
ranges for each object associated with the allocno. There may be
more than one such object in cases where the allocno represents a
multi-word register. */
ira_object_t objects[2];
/* Accumulated frequency of calls which given allocno
intersects. */
int call_freq;
......@@ -483,9 +488,11 @@ struct ira_allocno
#define ALLOCNO_TEMP(A) ((A)->temp)
#define ALLOCNO_FIRST_COALESCED_ALLOCNO(A) ((A)->first_coalesced_allocno)
#define ALLOCNO_NEXT_COALESCED_ALLOCNO(A) ((A)->next_coalesced_allocno)
#define ALLOCNO_OBJECT(A) ((A)->object)
#define ALLOCNO_OBJECT(A,N) ((A)->objects[N])
#define ALLOCNO_NUM_OBJECTS(A) ((A)->num_objects)
#define OBJECT_ALLOCNO(C) ((C)->allocno)
#define OBJECT_SUBWORD(C) ((C)->subword)
#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)
......@@ -497,7 +504,7 @@ struct ira_allocno
#define OBJECT_MIN(C) ((C)->min)
#define OBJECT_MAX(C) ((C)->max)
#define OBJECT_CONFLICT_ID(C) ((C)->id)
#define OBJECT_LIVE_RANGES(C) ((C)->live_ranges)
#define OBJECT_LIVE_RANGES(A) ((A)->live_ranges)
/* Map regno -> allocnos with given regno (see comments for
allocno member `next_regno_allocno'). */
......@@ -593,6 +600,7 @@ extern int ira_move_loops_num, ira_additional_jumps_num;
/* The type used as elements in the array, and the number of bits in
this type. */
#define IRA_INT_BITS HOST_BITS_PER_WIDE_INT
#define IRA_INT_TYPE HOST_WIDE_INT
......@@ -690,7 +698,7 @@ minmax_set_iter_init (minmax_set_iterator *i, IRA_INT_TYPE *vec, int min,
i->word = i->nel == 0 ? 0 : vec[0];
}
/* Return TRUE if we have more elements to visit, in which case *N is
/* Return TRUE if we have more allocnos to visit, in which case *N is
set to the number of the element to be visited. Otherwise, return
FALSE. */
static inline bool
......@@ -929,12 +937,14 @@ 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_create_allocno_objects (ira_allocno_t);
extern void ira_set_allocno_cover_class (ira_allocno_t, enum reg_class);
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 ior_hard_reg_conflicts (ira_allocno_t, HARD_REG_SET *);
extern void ira_print_expanded_allocno (ira_allocno_t);
extern void ira_add_live_range_to_object (ira_object_t, int, int);
extern live_range_t ira_create_live_range (ira_object_t, int, int,
live_range_t);
extern live_range_t ira_copy_live_range_list (live_range_t);
......@@ -1059,7 +1069,7 @@ ira_allocno_iter_cond (ira_allocno_iterator *i, ira_allocno_t *a)
/* The iterator for all objects. */
typedef struct {
/* The number of the current element in IRA_OBJECT_ID_MAP. */
/* The number of the current element in ira_object_id_map. */
int n;
} ira_object_iterator;
......@@ -1087,13 +1097,44 @@ ira_object_iter_cond (ira_object_iterator *i, ira_object_t *obj)
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
/* Loop over all objects. In each iteration, OBJ is set to the next
object. 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 objects associated with an allocno. */
typedef struct {
/* The number of the element the allocno's object array. */
int n;
} ira_allocno_object_iterator;
/* Initialize the iterator I. */
static inline void
ira_allocno_object_iter_init (ira_allocno_object_iterator *i)
{
i->n = 0;
}
/* Return TRUE if we have more objects to visit in allocno A, in which
case *O is set to the object to be visited. Otherwise, return
FALSE. */
static inline bool
ira_allocno_object_iter_cond (ira_allocno_object_iterator *i, ira_allocno_t a,
ira_object_t *o)
{
*o = ALLOCNO_OBJECT (a, i->n);
return i->n++ < ALLOCNO_NUM_OBJECTS (a);
}
/* Loop over all objects associated with allocno A. In each
iteration, O is set to the next object. ITER is an instance of
ira_allocno_object_iterator used to iterate the conflicts. */
#define FOR_EACH_ALLOCNO_OBJECT(A, O, ITER) \
for (ira_allocno_object_iter_init (&(ITER)); \
ira_allocno_object_iter_cond (&(ITER), (A), &(O));)
/* The iterator for copies. */
typedef struct {
......@@ -1132,9 +1173,10 @@ ira_copy_iter_cond (ira_copy_iterator *i, ira_copy_t *cp)
for (ira_copy_iter_init (&(ITER)); \
ira_copy_iter_cond (&(ITER), &(C));)
/* The iterator for allocno conflicts. */
/* The iterator for object conflicts. */
typedef struct {
/* TRUE if the conflicts are represented by vector of objects. */
/* TRUE if the conflicts are represented by vector of allocnos. */
bool conflict_vec_p;
/* The conflict vector or conflict bit vector. */
......
......@@ -1241,9 +1241,8 @@ setup_prohibited_mode_move_regs (void)
static bool
ira_bad_reload_regno_1 (int regno, rtx x)
{
int x_regno;
int x_regno, n, i;
ira_allocno_t a;
ira_object_t obj;
enum reg_class pref;
/* We only deal with pseudo regs. */
......@@ -1263,10 +1262,13 @@ 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];
obj = ALLOCNO_OBJECT (a);
if (TEST_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), regno))
return true;
n = ALLOCNO_NUM_OBJECTS (a);
for (i = 0; i < n; i++)
{
ira_object_t obj = ALLOCNO_OBJECT (a, i);
if (TEST_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), regno))
return true;
}
return false;
}
......@@ -1610,32 +1612,60 @@ static void
check_allocation (void)
{
ira_allocno_t a;
int hard_regno, nregs;
int hard_regno, nregs, conflict_nregs;
ira_allocno_iterator ai;
FOR_EACH_ALLOCNO (a, ai)
{
ira_object_t obj, conflict_obj;
ira_object_conflict_iterator oci;
int n = ALLOCNO_NUM_OBJECTS (a);
int i;
if (ALLOCNO_CAP_MEMBER (a) != NULL
|| (hard_regno = ALLOCNO_HARD_REGNO (a)) < 0)
continue;
nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (a)];
obj = ALLOCNO_OBJECT (a);
FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
if (n > 1)
{
gcc_assert (n == nregs);
nregs = 1;
}
for (i = 0; i < n; i++)
{
ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
int conflict_hard_regno = ALLOCNO_HARD_REGNO (conflict_a);
if (conflict_hard_regno >= 0)
ira_object_t obj = ALLOCNO_OBJECT (a, i);
ira_object_t conflict_obj;
ira_object_conflict_iterator oci;
int this_regno = hard_regno;
if (n > 1)
{
int conflict_nregs
= (hard_regno_nregs
[conflict_hard_regno][ALLOCNO_MODE (conflict_a)]);
if ((conflict_hard_regno <= hard_regno
&& hard_regno < conflict_hard_regno + conflict_nregs)
|| (hard_regno <= conflict_hard_regno
&& conflict_hard_regno < hard_regno + nregs))
if (WORDS_BIG_ENDIAN)
this_regno += n - i - 1;
else
this_regno += i;
}
FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
{
ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
int conflict_hard_regno = ALLOCNO_HARD_REGNO (conflict_a);
if (conflict_hard_regno < 0)
continue;
if (ALLOCNO_NUM_OBJECTS (conflict_a) > 1)
{
if (WORDS_BIG_ENDIAN)
conflict_hard_regno += (ALLOCNO_NUM_OBJECTS (conflict_a)
- OBJECT_SUBWORD (conflict_obj) - 1);
else
conflict_hard_regno += OBJECT_SUBWORD (conflict_obj);
conflict_nregs = 1;
}
else
conflict_nregs
= (hard_regno_nregs
[conflict_hard_regno][ALLOCNO_MODE (conflict_a)]);
if ((conflict_hard_regno <= this_regno
&& this_regno < conflict_hard_regno + conflict_nregs)
|| (this_regno <= conflict_hard_regno
&& conflict_hard_regno < this_regno + nregs))
{
fprintf (stderr, "bad allocation for %d and %d\n",
ALLOCNO_REGNO (a), ALLOCNO_REGNO (conflict_a));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment