re PR rtl-optimization/57100 (ICE: in pre_and_rev_post_order_compute, at cfganal.c:869 with -fdump-rtl-pro_and_epilogue-graph)

2013-10-30  Richard Biener  <rguenther@suse.de>

	PR middle-end/57100
	* basic-block.h (pre_and_rev_post_order_compute_fn): New function.
	* cfganal.c (pre_and_rev_post_order_compute_fn): New function
	as worker for ...
	(pre_and_rev_post_order_compute): ... which now wraps it.
	* graph.c (draw_cfg_nodes_no_loops): Use
	pre_and_rev_post_order_compute_fn to avoid ICEing and dependence
	on cfun.

From-SVN: r204211
This commit is contained in:
Richard Biener 2013-10-30 14:22:01 +00:00 committed by Richard Biener
parent 193ea7bc8c
commit 1bef9b2340
4 changed files with 51 additions and 19 deletions

View File

@ -1,3 +1,14 @@
2013-10-30 Richard Biener <rguenther@suse.de>
PR middle-end/57100
* basic-block.h (pre_and_rev_post_order_compute_fn): New function.
* cfganal.c (pre_and_rev_post_order_compute_fn): New function
as worker for ...
(pre_and_rev_post_order_compute): ... which now wraps it.
* graph.c (draw_cfg_nodes_no_loops): Use
pre_and_rev_post_order_compute_fn to avoid ICEing and dependence
on cfun.
2013-10-30 Christian Bruel <christian.bruel@st.com> 2013-10-30 Christian Bruel <christian.bruel@st.com>
* gcc/config/sh/sh-mem.cc (sh_expand_cmpnstr): New function. * gcc/config/sh/sh-mem.cc (sh_expand_cmpnstr): New function.

View File

@ -795,6 +795,8 @@ extern void connect_infinite_loops_to_exit (void);
extern int post_order_compute (int *, bool, bool); extern int post_order_compute (int *, bool, bool);
extern basic_block dfs_find_deadend (basic_block); extern basic_block dfs_find_deadend (basic_block);
extern int inverted_post_order_compute (int *); extern int inverted_post_order_compute (int *);
extern int pre_and_rev_post_order_compute_fn (struct function *,
int *, int *, bool);
extern int pre_and_rev_post_order_compute (int *, int *, bool); extern int pre_and_rev_post_order_compute (int *, int *, bool);
extern int dfs_enumerate_from (basic_block, int, extern int dfs_enumerate_from (basic_block, int,
bool (*)(const_basic_block, const void *), bool (*)(const_basic_block, const void *),

View File

@ -878,20 +878,22 @@ inverted_post_order_compute (int *post_order)
return post_order_num; return post_order_num;
} }
/* Compute the depth first search order and store in the array /* Compute the depth first search order of FN and store in the array
PRE_ORDER if nonzero, marking the nodes visited in VISITED. If PRE_ORDER if nonzero. If REV_POST_ORDER is nonzero, return the
REV_POST_ORDER is nonzero, return the reverse completion number for each reverse completion number for each node. Returns the number of nodes
node. Returns the number of nodes visited. A depth first search visited. A depth first search tries to get as far away from the starting
tries to get as far away from the starting point as quickly as point as quickly as possible.
possible.
pre_order is a really a preorder numbering of the graph. In case the function has unreachable blocks the number of nodes
rev_post_order is really a reverse postorder numbering of the graph. visited does not include them.
*/
pre_order is a really a preorder numbering of the graph.
rev_post_order is really a reverse postorder numbering of the graph. */
int int
pre_and_rev_post_order_compute (int *pre_order, int *rev_post_order, pre_and_rev_post_order_compute_fn (struct function *fn,
bool include_entry_exit) int *pre_order, int *rev_post_order,
bool include_entry_exit)
{ {
edge_iterator *stack; edge_iterator *stack;
int sp; int sp;
@ -921,7 +923,7 @@ pre_and_rev_post_order_compute (int *pre_order, int *rev_post_order,
bitmap_clear (visited); bitmap_clear (visited);
/* Push the first edge on to the stack. */ /* Push the first edge on to the stack. */
stack[sp++] = ei_start (ENTRY_BLOCK_PTR->succs); stack[sp++] = ei_start (ENTRY_BLOCK_PTR_FOR_FUNCTION (fn)->succs);
while (sp) while (sp)
{ {
@ -935,7 +937,8 @@ pre_and_rev_post_order_compute (int *pre_order, int *rev_post_order,
dest = ei_edge (ei)->dest; dest = ei_edge (ei)->dest;
/* Check if the edge destination has been visited yet. */ /* Check if the edge destination has been visited yet. */
if (dest != EXIT_BLOCK_PTR && ! bitmap_bit_p (visited, dest->index)) if (dest != EXIT_BLOCK_PTR_FOR_FUNCTION (fn)
&& ! bitmap_bit_p (visited, dest->index))
{ {
/* Mark that we have visited the destination. */ /* Mark that we have visited the destination. */
bitmap_set_bit (visited, dest->index); bitmap_set_bit (visited, dest->index);
@ -956,7 +959,8 @@ pre_and_rev_post_order_compute (int *pre_order, int *rev_post_order,
} }
else else
{ {
if (ei_one_before_end_p (ei) && src != ENTRY_BLOCK_PTR if (ei_one_before_end_p (ei)
&& src != ENTRY_BLOCK_PTR_FOR_FUNCTION (fn)
&& rev_post_order) && rev_post_order)
/* There are no more successors for the SRC node /* There are no more successors for the SRC node
so assign its reverse completion number. */ so assign its reverse completion number. */
@ -979,9 +983,24 @@ pre_and_rev_post_order_compute (int *pre_order, int *rev_post_order,
pre_order_num++; pre_order_num++;
if (rev_post_order) if (rev_post_order)
rev_post_order[rev_post_order_num--] = EXIT_BLOCK; rev_post_order[rev_post_order_num--] = EXIT_BLOCK;
/* The number of nodes visited should be the number of blocks. */
gcc_assert (pre_order_num == n_basic_blocks);
} }
return pre_order_num;
}
/* Like pre_and_rev_post_order_compute_fn but operating on the
current function and asserting that all nodes were visited. */
int
pre_and_rev_post_order_compute (int *pre_order, int *rev_post_order,
bool include_entry_exit)
{
int pre_order_num
= pre_and_rev_post_order_compute_fn (cfun, pre_order, rev_post_order,
include_entry_exit);
if (include_entry_exit)
/* The number of nodes visited should be the number of blocks. */
gcc_assert (pre_order_num == n_basic_blocks);
else else
/* The number of nodes visited should be the number of blocks minus /* The number of nodes visited should be the number of blocks minus
the entry and exit blocks which are not visited here. */ the entry and exit blocks which are not visited here. */

View File

@ -160,9 +160,9 @@ draw_cfg_nodes_no_loops (pretty_printer *pp, struct function *fun)
visited = sbitmap_alloc (last_basic_block); visited = sbitmap_alloc (last_basic_block);
bitmap_clear (visited); bitmap_clear (visited);
/* FIXME: pre_and_rev_post_order_compute only works if fun == cfun. */ n = pre_and_rev_post_order_compute_fn (fun, NULL, rpo, true);
n = pre_and_rev_post_order_compute (NULL, rpo, true); for (i = n_basic_blocks_for_function (fun) - n;
for (i = 0; i < n; i++) i < n_basic_blocks_for_function (fun); i++)
{ {
basic_block bb = BASIC_BLOCK (rpo[i]); basic_block bb = BASIC_BLOCK (rpo[i]);
draw_cfg_node (pp, fun->funcdef_no, bb); draw_cfg_node (pp, fun->funcdef_no, bb);