This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] CSE path following thinko fix
- From: Steven Bosscher <stevenb dot gcc at gmail dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 16 Dec 2006 13:09:40 +0100
- Subject: [PATCH] CSE path following thinko fix
Hello,
This fixes four small mistakes in my CSE path following patch:
* There is a gcc_assert inside ENABLE_CHECKING tests. I've simply
removed the #ifdef/#endif.
* I accidentally commited a local static variale in gate_handle_cse
that I had used to track down the new Java failure I had after
the merge of Andrew M.'s TER changes.
* In cse_extended_basic_block, if the CFG is modified when processing
a path, we can sometimes purge the rest of the path because it is
no longer reachable through this path. But we still want to visit
these blocks later on, so we should clear the visited bits on them.
* In cse_main, I have to walk over the basic blocks in topological
order of the original CFG (i.e. before it changes when CSE removes
jumps or otherwise changes the CFG). I originally used DFS order
instead, but this can sometimes lead to situations where the JOIN
block of a diamond in the CFG is be visited before its predecessors.
This is the problem that breaks bootstrap on MIPSEL and PA.
Bootstrapped and tested on x86_64-unknown-linux-gnu.
OK for the trunk?
Gr.
Steven
* cse.c (cse_find_path): Don't wrap a gcc_assert in ENABLE_CHECKING.
(cse_extended_basic_block): When truncating a path while processing
it, make sure to clear the visited bit on the basic blocks in the
truncated part of the path.
(cse_main): Use reverse completion order, not DFS order, to walk
the CFG.
(gate_handle_cse): Revert erroneous commit of a counter.
Index: cse.c
===================================================================
--- cse.c (revision 119856)
+++ cse.c (working copy)
@@ -5924,11 +5924,10 @@ cse_find_path (basic_block first_bb, str
{
basic_block bb2 = e->dest;
-#if ENABLE_CHECKING
/* We should only see blocks here that we have not
visited yet. */
gcc_assert (!TEST_BIT (cse_visited_basic_blocks, bb2->index));
-#endif
+
SET_BIT (cse_visited_basic_blocks, bb2->index);
data->path[path_size++].bb = bb2;
bb = bb2;
@@ -6118,7 +6117,21 @@ cse_extended_basic_block (struct cse_bas
{
basic_block next_bb = ebb_data->path[path_entry + 1].bb;
if (!find_edge (bb, next_bb))
- ebb_data->path_size = path_entry + 1;
+ {
+ do
+ {
+ path_size--;
+
+ /* If we truncate the path, we must also reset the
+ visited bit on the remaining blocks in the path,
+ or we will never visit them at all. */
+ RESET_BIT (cse_visited_basic_blocks,
+ ebb_data->path[path_size].bb->index);
+ ebb_data->path[path_size].bb = NULL;
+ }
+ while (path_size - 1 != path_entry);
+ ebb_data->path_size = path_size;
+ }
}
/* If this is a conditional jump insn, record any known
@@ -6152,7 +6165,7 @@ cse_main (rtx f ATTRIBUTE_UNUSED, int nr
{
struct cse_basic_block_data ebb_data;
basic_block bb;
- int *dfs_order = XNEWVEC (int, last_basic_block);
+ int *rc_order = XNEWVEC (int, last_basic_block);
int i, n_blocks;
init_cse_reg_info (nregs);
@@ -6192,7 +6205,7 @@ cse_main (rtx f ATTRIBUTE_UNUSED, int nr
/* Loop over basic blocks in DFS order,
excluding the ENTRY and EXIT blocks. */
- n_blocks = pre_and_rev_post_order_compute (dfs_order, NULL, false);
+ n_blocks = pre_and_rev_post_order_compute (NULL, rc_order, false);
i = 0;
while (i < n_blocks)
{
@@ -6200,7 +6213,7 @@ cse_main (rtx f ATTRIBUTE_UNUSED, int nr
processed before. */
do
{
- bb = BASIC_BLOCK (dfs_order[i++]);
+ bb = BASIC_BLOCK (rc_order[i++]);
}
while (TEST_BIT (cse_visited_basic_blocks, bb->index)
&& i < n_blocks);
@@ -6236,7 +6249,7 @@ cse_main (rtx f ATTRIBUTE_UNUSED, int nr
free (reg_eqv_table);
free (ebb_data.path);
sbitmap_free (cse_visited_basic_blocks);
- free (dfs_order);
+ free (rc_order);
rtl_hooks = general_rtl_hooks;
return cse_jumps_altered || recorded_label_ref;
@@ -6956,9 +6969,7 @@ gate_handle_cse (void)
static unsigned int
rest_of_handle_cse (void)
{
-static int counter = 0;
int tem;
-counter++;
if (dump_file)
dump_flow_info (dump_file, dump_flags);