Commit fc249fe5 by Michael Matz Committed by Michael Matz

re PR tree-optimization/42963 (Redundant switch labels not cleaned up anymore)

	PR tree-optimization/42963
	* tree-cfg.c (touched_switch_bbs): New static variable.
	(group_case_labels_stmt): New function broken out from ...
	(group_case_labels): ... here, use the above.
	(start_recording_case_labels): Allocate touched_switch_bbs.
	(end_recording_case_labels): Deallocate it, call
	group_case_labels_stmt.
	(gimple_redirect_edge_and_branch): Remember index of affected BB.

testsuite/
	* testsuite/gcc.dg/pr42963.c: New testcase.

From-SVN: r158345
parent 289a9f86
2010-04-14 Michael Matz <matz@suse.de>
PR tree-optimization/42963
* tree-cfg.c (touched_switch_bbs): New static variable.
(group_case_labels_stmt): New function broken out from ...
(group_case_labels): ... here, use the above.
(start_recording_case_labels): Allocate touched_switch_bbs.
(end_recording_case_labels): Deallocate it, call
group_case_labels_stmt.
(gimple_redirect_edge_and_branch): Remember index of affected BB.
2010-04-14 Uros Bizjak <ubizjak@gmail.com> 2010-04-14 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.md (*popcountsi2_cmp_zext): Remove mode attribute * config/i386/i386.md (*popcountsi2_cmp_zext): Remove mode attribute
......
2010-04-14 Michael Matz <matz@suse.de>
PR tree-optimization/42963
* testsuite/gcc.dg/pr42963.c: New testcase.
2010-04-14 Eric Botcazou <ebotcazou@adacore.com> 2010-04-14 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/class_wide.adb: Rename into... * gnat.dg/class_wide.adb: Rename into...
......
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-cfg" } */
extern void foo (void);
extern int i;
void
bar (void)
{
switch (i)
{
case 0:
foo ();
break;
case 1:
break;
}
switch (i)
{
case 0:
foo ();
break;
case 1:
break;
}
}
/* { dg-final { scan-tree-dump-times "case 1:" 0 "cfg" } } */
/* { dg-final { cleanup-tree-dump "cfg" } } */
...@@ -71,6 +71,12 @@ static const int initial_cfg_capacity = 20; ...@@ -71,6 +71,12 @@ static const int initial_cfg_capacity = 20;
static struct pointer_map_t *edge_to_cases; static struct pointer_map_t *edge_to_cases;
/* If we record edge_to_cases, this bitmap will hold indexes
of basic blocks that end in a GIMPLE_SWITCH which we touched
due to edge manipulations. */
static bitmap touched_switch_bbs;
/* CFG statistics. */ /* CFG statistics. */
struct cfg_stats_d struct cfg_stats_d
{ {
...@@ -122,6 +128,7 @@ static edge find_taken_edge_computed_goto (basic_block, tree); ...@@ -122,6 +128,7 @@ static edge find_taken_edge_computed_goto (basic_block, tree);
static edge find_taken_edge_cond_expr (basic_block, tree); static edge find_taken_edge_cond_expr (basic_block, tree);
static edge find_taken_edge_switch_expr (basic_block, tree); static edge find_taken_edge_switch_expr (basic_block, tree);
static tree find_case_label_for_value (gimple, tree); static tree find_case_label_for_value (gimple, tree);
static void group_case_labels_stmt (gimple);
void void
init_empty_tree_cfg_for_function (struct function *fn) init_empty_tree_cfg_for_function (struct function *fn)
...@@ -848,6 +855,7 @@ start_recording_case_labels (void) ...@@ -848,6 +855,7 @@ start_recording_case_labels (void)
{ {
gcc_assert (edge_to_cases == NULL); gcc_assert (edge_to_cases == NULL);
edge_to_cases = pointer_map_create (); edge_to_cases = pointer_map_create ();
touched_switch_bbs = BITMAP_ALLOC (NULL);
} }
/* Return nonzero if we are recording information for case labels. */ /* Return nonzero if we are recording information for case labels. */
...@@ -863,9 +871,22 @@ recording_case_labels_p (void) ...@@ -863,9 +871,22 @@ recording_case_labels_p (void)
void void
end_recording_case_labels (void) end_recording_case_labels (void)
{ {
bitmap_iterator bi;
unsigned i;
pointer_map_traverse (edge_to_cases, edge_to_cases_cleanup, NULL); pointer_map_traverse (edge_to_cases, edge_to_cases_cleanup, NULL);
pointer_map_destroy (edge_to_cases); pointer_map_destroy (edge_to_cases);
edge_to_cases = NULL; edge_to_cases = NULL;
EXECUTE_IF_SET_IN_BITMAP (touched_switch_bbs, 0, i, bi)
{
basic_block bb = BASIC_BLOCK (i);
if (bb)
{
gimple stmt = last_stmt (bb);
if (stmt && gimple_code (stmt) == GIMPLE_SWITCH)
group_case_labels_stmt (stmt);
}
}
BITMAP_FREE (touched_switch_bbs);
} }
/* If we are inside a {start,end}_recording_cases block, then return /* If we are inside a {start,end}_recording_cases block, then return
...@@ -1278,21 +1299,13 @@ cleanup_dead_labels (void) ...@@ -1278,21 +1299,13 @@ cleanup_dead_labels (void)
free (label_for_bb); free (label_for_bb);
} }
/* Look for blocks ending in a multiway branch (a SWITCH_EXPR in GIMPLE), /* Scan the sorted vector of cases in STMT (a GIMPLE_SWITCH) and combine
and scan the sorted vector of cases. Combine the ones jumping to the the ones jumping to the same label.
same label.
Eg. three separate entries 1: 2: 3: become one entry 1..3: */ Eg. three separate entries 1: 2: 3: become one entry 1..3: */
void static void
group_case_labels (void) group_case_labels_stmt (gimple stmt)
{ {
basic_block bb;
FOR_EACH_BB (bb)
{
gimple stmt = last_stmt (bb);
if (stmt && gimple_code (stmt) == GIMPLE_SWITCH)
{
int old_size = gimple_switch_num_labels (stmt); int old_size = gimple_switch_num_labels (stmt);
int i, j, new_size = old_size; int i, j, new_size = old_size;
tree default_case = NULL_TREE; tree default_case = NULL_TREE;
...@@ -1379,7 +1392,22 @@ group_case_labels (void) ...@@ -1379,7 +1392,22 @@ group_case_labels (void)
gcc_assert (new_size <= old_size); gcc_assert (new_size <= old_size);
gimple_switch_set_num_labels (stmt, new_size); gimple_switch_set_num_labels (stmt, new_size);
} }
/* Look for blocks ending in a multiway branch (a GIMPLE_SWITCH),
and scan the sorted vector of cases. Combine the ones jumping to the
same label. */
void
group_case_labels (void)
{
basic_block bb;
FOR_EACH_BB (bb)
{
gimple stmt = last_stmt (bb);
if (stmt && gimple_code (stmt) == GIMPLE_SWITCH)
group_case_labels_stmt (stmt);
} }
} }
...@@ -4689,6 +4717,7 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest) ...@@ -4689,6 +4717,7 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest)
TREE_CHAIN (last) = TREE_CHAIN (cases2); TREE_CHAIN (last) = TREE_CHAIN (cases2);
TREE_CHAIN (cases2) = first; TREE_CHAIN (cases2) = first;
} }
bitmap_set_bit (touched_switch_bbs, gimple_bb (stmt)->index);
} }
else else
{ {
......
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