Commit 82b33628 by Vladimir Makarov Committed by Vladimir Makarov

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
parent 6ff5d1e4
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> 2008-09-12 Anatoly Sokolov <aesok@post.ru>
PR target/37466 PR target/37466
......
...@@ -2037,21 +2037,59 @@ create_caps (void) ...@@ -2037,21 +2037,59 @@ create_caps (void)
the IR for one region but we don't do it because it takes a lot of the IR for one region but we don't do it because it takes a lot of
time. */ time. */
/* This recursive function returns immediate common dominator of two /* Map: regno -> allocnos which will finally represent the regno for
loop tree nodes N1 and N2. */ IR with one region. */
static ira_loop_tree_node_t static ira_allocno_t *regno_top_level_allocno_map;
common_loop_tree_node_dominator (ira_loop_tree_node_t n1,
ira_loop_tree_node_t n2) /* Process all allocnos originated from pseudo REGNO and copy live
{ ranges from low level allocnos to final allocnos which are
ira_assert (n1 != NULL && n2 != NULL); destinations of removed stores at a loop exit. Return true if we
if (n1 == n2) copied live ranges. */
return n1; static bool
if (n1->level < n2->level) copy_live_ranges_to_removed_store_destinations (int regno)
return common_loop_tree_node_dominator (n1, n2->parent); {
else if (n1->level > n2->level) ira_allocno_t a, parent_a;
return common_loop_tree_node_dominator (n1->parent, n2); ira_loop_tree_node_t parent;
else allocno_live_range_t r;
return common_loop_tree_node_dominator (n1->parent, n2->parent); 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 /* 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) ...@@ -2066,20 +2104,16 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
int i, j, num; int i, j, num;
bool propagate_p, stop_p, keep_p; bool propagate_p, stop_p, keep_p;
int hard_regs_num; int hard_regs_num;
bool new_pseudos_p, merged_p; bool new_pseudos_p, merged_p, mem_dest_p;
unsigned int n; unsigned int n;
enum reg_class cover_class; enum reg_class cover_class;
ira_allocno_t a, parent_a, first, second, node_first, node_second; ira_allocno_t a, parent_a, first, second, node_first, node_second;
ira_allocno_t dominator_a;
ira_copy_t cp; ira_copy_t cp;
ira_loop_tree_node_t parent, node, dominator; ira_loop_tree_node_t parent, node;
allocno_live_range_t r; allocno_live_range_t r;
ira_allocno_iterator ai; ira_allocno_iterator ai;
ira_copy_iterator ci; ira_copy_iterator ci;
sparseset allocnos_live; 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; bool *allocno_propagated_p;
regno_top_level_allocno_map regno_top_level_allocno_map
...@@ -2093,7 +2127,7 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit) ...@@ -2093,7 +2127,7 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
/* Fix final allocno attributes. */ /* Fix final allocno attributes. */
for (i = max_regno_before_emit - 1; i >= FIRST_PSEUDO_REGISTER; i--) 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]; for (a = ira_regno_allocno_map[i];
a != NULL; a != NULL;
a = ALLOCNO_NEXT_REGNO_ALLOCNO (a)) a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
...@@ -2111,6 +2145,8 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit) ...@@ -2111,6 +2145,8 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
continue; continue;
} }
ira_assert (ALLOCNO_CAP_MEMBER (parent_a) == NULL); ira_assert (ALLOCNO_CAP_MEMBER (parent_a) == NULL);
if (ALLOCNO_MEM_OPTIMIZED_DEST (a) != NULL)
mem_dest_p = true;
if (propagate_p) if (propagate_p)
{ {
if (!allocno_propagated_p [ALLOCNO_NUM (parent_a)]) 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) ...@@ -2198,49 +2234,11 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
[ALLOCNO_REGNO (parent_a)])) == NULL) [ALLOCNO_REGNO (parent_a)])) == NULL)
break; 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; ALLOCNO_COPIES (a) = NULL;
regno_top_level_allocno_map[REGNO (ALLOCNO_REG (a))] = a; 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_free (allocno_propagated_p);
ira_assert (new_pseudos_p || ira_max_point_before_emit == ira_max_point); ira_assert (new_pseudos_p || ira_max_point_before_emit == ira_max_point);
......
...@@ -311,9 +311,11 @@ generate_edge_moves (edge e) ...@@ -311,9 +311,11 @@ generate_edge_moves (edge e)
if (REGNO (ALLOCNO_REG (src_allocno)) if (REGNO (ALLOCNO_REG (src_allocno))
== REGNO (ALLOCNO_REG (dest_allocno))) == REGNO (ALLOCNO_REG (dest_allocno)))
continue; continue;
/* Actually it is not a optimization we need this code because /* Remove unnecessary stores at the region exit. We should do
the memory (remember about equivalent memory) might be ROM this for readonly memory for sure and this is guaranteed by
(or placed in read only section). */ 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 if (ALLOCNO_HARD_REGNO (dest_allocno) < 0
&& ALLOCNO_HARD_REGNO (src_allocno) >= 0 && ALLOCNO_HARD_REGNO (src_allocno) >= 0
&& not_modified_p (src_allocno, dest_allocno)) && not_modified_p (src_allocno, dest_allocno))
......
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