re PR rtl-optimization/37377 (Bootstrap failure compiling libgcc)
2008-09-12 Vladimir Makarov <vmakarov@redhat.com> PR rtl-opt/37377 * ira-build.c (common_loop_tree_node_dominator): Remove. (copy_live_ranges_to_removed_store_destinations): New function. (regno_top_level_allocno_map): Move to top level from ... (ira_flattening): ... here. Use copy_live_ranges_to_removed_store_destinations. * ira-emit.c (generate_edge_moves): Fix a comment. From-SVN: r140325
This commit is contained in:
parent
6ff5d1e447
commit
82b336287a
3 changed files with 76 additions and 64 deletions
|
@ -1,3 +1,15 @@
|
|||
2008-09-12 Vladimir Makarov <vmakarov@redhat.com>
|
||||
|
||||
PR rtl-opt/37377
|
||||
|
||||
* ira-build.c (common_loop_tree_node_dominator): Remove.
|
||||
(copy_live_ranges_to_removed_store_destinations): New function.
|
||||
(regno_top_level_allocno_map): Move to top level from ...
|
||||
(ira_flattening): ... here. Use
|
||||
copy_live_ranges_to_removed_store_destinations.
|
||||
|
||||
* ira-emit.c (generate_edge_moves): Fix a comment.
|
||||
|
||||
2008-09-12 Anatoly Sokolov <aesok@post.ru>
|
||||
|
||||
PR target/37466
|
||||
|
|
120
gcc/ira-build.c
120
gcc/ira-build.c
|
@ -2037,21 +2037,59 @@ create_caps (void)
|
|||
the IR for one region but we don't do it because it takes a lot of
|
||||
time. */
|
||||
|
||||
/* This recursive function returns immediate common dominator of two
|
||||
loop tree nodes N1 and N2. */
|
||||
static ira_loop_tree_node_t
|
||||
common_loop_tree_node_dominator (ira_loop_tree_node_t n1,
|
||||
ira_loop_tree_node_t n2)
|
||||
/* Map: regno -> allocnos which will finally represent the regno for
|
||||
IR with one region. */
|
||||
static ira_allocno_t *regno_top_level_allocno_map;
|
||||
|
||||
/* Process all allocnos originated from pseudo REGNO and copy live
|
||||
ranges from low level allocnos to final allocnos which are
|
||||
destinations of removed stores at a loop exit. Return true if we
|
||||
copied live ranges. */
|
||||
static bool
|
||||
copy_live_ranges_to_removed_store_destinations (int regno)
|
||||
{
|
||||
ira_assert (n1 != NULL && n2 != NULL);
|
||||
if (n1 == n2)
|
||||
return n1;
|
||||
if (n1->level < n2->level)
|
||||
return common_loop_tree_node_dominator (n1, n2->parent);
|
||||
else if (n1->level > n2->level)
|
||||
return common_loop_tree_node_dominator (n1->parent, n2);
|
||||
else
|
||||
return common_loop_tree_node_dominator (n1->parent, n2->parent);
|
||||
ira_allocno_t a, parent_a;
|
||||
ira_loop_tree_node_t parent;
|
||||
allocno_live_range_t r;
|
||||
bool merged_p;
|
||||
|
||||
merged_p = false;
|
||||
for (a = ira_regno_allocno_map[regno];
|
||||
a != NULL;
|
||||
a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
|
||||
{
|
||||
if (a != regno_top_level_allocno_map[REGNO (ALLOCNO_REG (a))])
|
||||
/* This allocno will be removed. */
|
||||
continue;
|
||||
/* Caps will be removed. */
|
||||
ira_assert (ALLOCNO_CAP_MEMBER (a) == NULL);
|
||||
for (parent = ALLOCNO_LOOP_TREE_NODE (a)->parent;
|
||||
parent != NULL;
|
||||
parent = parent->parent)
|
||||
if ((parent_a = parent->regno_allocno_map[regno]) == NULL
|
||||
|| (parent_a == regno_top_level_allocno_map[REGNO (ALLOCNO_REG
|
||||
(parent_a))]
|
||||
&& ALLOCNO_MEM_OPTIMIZED_DEST_P (parent_a)))
|
||||
break;
|
||||
if (parent == NULL || parent_a == NULL)
|
||||
continue;
|
||||
if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
|
||||
{
|
||||
fprintf
|
||||
(ira_dump_file,
|
||||
" Coping ranges of a%dr%d to a%dr%d: ",
|
||||
ALLOCNO_NUM (a), REGNO (ALLOCNO_REG (a)),
|
||||
ALLOCNO_NUM (parent_a), REGNO (ALLOCNO_REG (parent_a)));
|
||||
ira_print_live_range_list (ira_dump_file,
|
||||
ALLOCNO_LIVE_RANGES (a));
|
||||
}
|
||||
r = copy_allocno_live_range_list (ALLOCNO_LIVE_RANGES (a));
|
||||
change_allocno_in_range_list (r, parent_a);
|
||||
ALLOCNO_LIVE_RANGES (parent_a)
|
||||
= merge_ranges (r, ALLOCNO_LIVE_RANGES (parent_a));
|
||||
merged_p = true;
|
||||
}
|
||||
return merged_p;
|
||||
}
|
||||
|
||||
/* Flatten the IR. In other words, this function transforms IR as if
|
||||
|
@ -2066,20 +2104,16 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
|
|||
int i, j, num;
|
||||
bool propagate_p, stop_p, keep_p;
|
||||
int hard_regs_num;
|
||||
bool new_pseudos_p, merged_p;
|
||||
bool new_pseudos_p, merged_p, mem_dest_p;
|
||||
unsigned int n;
|
||||
enum reg_class cover_class;
|
||||
ira_allocno_t a, parent_a, first, second, node_first, node_second;
|
||||
ira_allocno_t dominator_a;
|
||||
ira_copy_t cp;
|
||||
ira_loop_tree_node_t parent, node, dominator;
|
||||
ira_loop_tree_node_t parent, node;
|
||||
allocno_live_range_t r;
|
||||
ira_allocno_iterator ai;
|
||||
ira_copy_iterator ci;
|
||||
sparseset allocnos_live;
|
||||
/* Map: regno -> allocnos which will finally represent the regno for
|
||||
IR with one region. */
|
||||
ira_allocno_t *regno_top_level_allocno_map;
|
||||
bool *allocno_propagated_p;
|
||||
|
||||
regno_top_level_allocno_map
|
||||
|
@ -2093,7 +2127,7 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
|
|||
/* Fix final allocno attributes. */
|
||||
for (i = max_regno_before_emit - 1; i >= FIRST_PSEUDO_REGISTER; i--)
|
||||
{
|
||||
propagate_p = false;
|
||||
mem_dest_p = propagate_p = false;
|
||||
for (a = ira_regno_allocno_map[i];
|
||||
a != NULL;
|
||||
a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
|
||||
|
@ -2111,6 +2145,8 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
|
|||
continue;
|
||||
}
|
||||
ira_assert (ALLOCNO_CAP_MEMBER (parent_a) == NULL);
|
||||
if (ALLOCNO_MEM_OPTIMIZED_DEST (a) != NULL)
|
||||
mem_dest_p = true;
|
||||
if (propagate_p)
|
||||
{
|
||||
if (!allocno_propagated_p [ALLOCNO_NUM (parent_a)])
|
||||
|
@ -2198,49 +2234,11 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
|
|||
[ALLOCNO_REGNO (parent_a)])) == NULL)
|
||||
break;
|
||||
}
|
||||
if (first != NULL)
|
||||
{
|
||||
parent_a = ALLOCNO_MEM_OPTIMIZED_DEST (first);
|
||||
dominator = common_loop_tree_node_dominator
|
||||
(ALLOCNO_LOOP_TREE_NODE (parent_a),
|
||||
ALLOCNO_LOOP_TREE_NODE (first));
|
||||
dominator_a = dominator->regno_allocno_map[ALLOCNO_REGNO (a)];
|
||||
ira_assert (parent_a != NULL);
|
||||
stop_p = first != a;
|
||||
/* Remember that exit can be to a grandparent (not only
|
||||
to a parent) or a child of the grandparent. */
|
||||
for (first = a;;)
|
||||
{
|
||||
if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
|
||||
{
|
||||
fprintf
|
||||
(ira_dump_file,
|
||||
" Coping ranges of a%dr%d to a%dr%d: ",
|
||||
ALLOCNO_NUM (first), REGNO (ALLOCNO_REG (first)),
|
||||
ALLOCNO_NUM (parent_a),
|
||||
REGNO (ALLOCNO_REG (parent_a)));
|
||||
ira_print_live_range_list (ira_dump_file,
|
||||
ALLOCNO_LIVE_RANGES (first));
|
||||
}
|
||||
r = copy_allocno_live_range_list (ALLOCNO_LIVE_RANGES
|
||||
(first));
|
||||
change_allocno_in_range_list (r, parent_a);
|
||||
ALLOCNO_LIVE_RANGES (parent_a)
|
||||
= merge_ranges (r, ALLOCNO_LIVE_RANGES (parent_a));
|
||||
merged_p = true;
|
||||
if (stop_p)
|
||||
break;
|
||||
parent = ALLOCNO_LOOP_TREE_NODE (first)->parent;
|
||||
ira_assert (parent != NULL);
|
||||
first = parent->regno_allocno_map[ALLOCNO_REGNO (a)];
|
||||
ira_assert (first != NULL);
|
||||
if (first == dominator_a)
|
||||
break;
|
||||
}
|
||||
}
|
||||
ALLOCNO_COPIES (a) = NULL;
|
||||
regno_top_level_allocno_map[REGNO (ALLOCNO_REG (a))] = a;
|
||||
}
|
||||
if (mem_dest_p && copy_live_ranges_to_removed_store_destinations (i))
|
||||
merged_p = true;
|
||||
}
|
||||
ira_free (allocno_propagated_p);
|
||||
ira_assert (new_pseudos_p || ira_max_point_before_emit == ira_max_point);
|
||||
|
|
|
@ -311,9 +311,11 @@ generate_edge_moves (edge e)
|
|||
if (REGNO (ALLOCNO_REG (src_allocno))
|
||||
== REGNO (ALLOCNO_REG (dest_allocno)))
|
||||
continue;
|
||||
/* Actually it is not a optimization we need this code because
|
||||
the memory (remember about equivalent memory) might be ROM
|
||||
(or placed in read only section). */
|
||||
/* Remove unnecessary stores at the region exit. We should do
|
||||
this for readonly memory for sure and this is guaranteed by
|
||||
that we never generate moves on region borders (see
|
||||
checking ira_reg_equiv_invariant_p in function
|
||||
change_loop). */
|
||||
if (ALLOCNO_HARD_REGNO (dest_allocno) < 0
|
||||
&& ALLOCNO_HARD_REGNO (src_allocno) >= 0
|
||||
&& not_modified_p (src_allocno, dest_allocno))
|
||||
|
|
Loading…
Add table
Reference in a new issue