tree-switch-conversion.c (build_constructors): Split a long line.

2009-04-21  Martin Jambor  <mjambor@suse.cz>

	* tree-switch-conversion.c (build_constructors): Split a long line.
	(constructor_contains_same_values_p): New function.
	(build_one_array): Create assigns of constants if possible, do not call
	mark_sym_for_renaming, call update_stmt.
	(build_arrays): Call make_ssa_name (create_tmp_var ()) instead of
	make_rename_temp.  Do not call mark_symbols_for_renaming, call
	update_stmt.
	(gen_def_assigns): Do not call mark_symbols_for_renaming or
	find_new_referenced_vars, call update_stmt.
	(gen_inbound_check): Use create_tmp_var and create ssa names manually
	instead of calling make_rename_temp.  Do not call
	find_new_referenced_vars or mark_symbols_for_renaming, call
	update_stmt.

	* testsuite/gcc.dg/tree-ssa/cswtch-2.c: New test.

From-SVN: r146517
This commit is contained in:
Martin Jambor 2009-04-21 13:55:41 +02:00 committed by Martin Jambor
parent ed2807f4cd
commit 7156c8abaf
4 changed files with 115 additions and 46 deletions

View File

@ -1,3 +1,19 @@
2009-04-21 Martin Jambor <mjambor@suse.cz>
* tree-switch-conversion.c (build_constructors): Split a long line.
(constructor_contains_same_values_p): New function.
(build_one_array): Create assigns of constants if possible, do not call
mark_sym_for_renaming, call update_stmt.
(build_arrays): Call make_ssa_name (create_tmp_var ()) instead of
make_rename_temp. Do not call mark_symbols_for_renaming, call
update_stmt.
(gen_def_assigns): Do not call mark_symbols_for_renaming or
find_new_referenced_vars, call update_stmt.
(gen_inbound_check): Use create_tmp_var and create ssa names manually
instead of calling make_rename_temp. Do not call
find_new_referenced_vars or mark_symbols_for_renaming, call
update_stmt.
2009-04-21 Richard Guenther <rguenther@suse.de> 2009-04-21 Richard Guenther <rguenther@suse.de>
PR tree-optimization/39827 PR tree-optimization/39827

View File

@ -1,3 +1,7 @@
2009-04-21 Martin Jambor <mjambor@suse.cz>
* gcc.dg/tree-ssa/cswtch-2.c: New test.
2009-04-21 Manuel López-Ibáñez <manu@gcc.gnu.org> 2009-04-21 Manuel López-Ibáñez <manu@gcc.gnu.org>
PR 16202 PR 16202

View File

@ -0,0 +1,21 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-switchconv" } */
typedef enum { a = 5, b = 6, c = 7, d = 8, e = 9 } X;
int h1 (X x)
{
switch (x) {
case a:
case b:
case c:
case d:
case e:
return 1;
default:
return 0;
}
}
/* { dg-final { scan-tree-dump-times "CSWTCH" 0 "switchconv" } } */
/* { dg-final { cleanup-tree-dump "switchconv" } } */

View File

@ -453,12 +453,35 @@ build_constructors (gimple swtch)
elt->value = val; elt->value = val;
pos = int_const_binop (PLUS_EXPR, pos, integer_one_node, 0); pos = int_const_binop (PLUS_EXPR, pos, integer_one_node, 0);
} while (!tree_int_cst_lt (high, pos) && tree_int_cst_lt (low, pos)); } while (!tree_int_cst_lt (high, pos)
&& tree_int_cst_lt (low, pos));
j++; j++;
} }
} }
} }
/* If all values in the constructor vector are the same, return the value.
Otherwise return NULL_TREE. Not supposed to be called for empty
vectors. */
static tree
constructor_contains_same_values_p (VEC (constructor_elt, gc) *vec)
{
int i, len = VEC_length (constructor_elt, vec);
tree prev = NULL_TREE;
for (i = 0; i < len; i++)
{
constructor_elt *elt = VEC_index (constructor_elt, vec, i);
if (!prev)
prev = elt->value;
else if (!operand_equal_p (elt->value, prev, OEP_ONLY_CONST))
return NULL_TREE;
}
return prev;
}
/* Create an appropriate array type and declaration and assemble a static array /* Create an appropriate array type and declaration and assemble a static array
variable. Also create a load statement that initializes the variable in variable. Also create a load statement that initializes the variable in
question with a value from the static array. SWTCH is the switch statement question with a value from the static array. SWTCH is the switch statement
@ -466,47 +489,53 @@ build_constructors (gimple swtch)
and target SSA names for this particular array. ARR_INDEX_TYPE is the type and target SSA names for this particular array. ARR_INDEX_TYPE is the type
of the index of the new array, PHI is the phi node of the final BB that of the index of the new array, PHI is the phi node of the final BB that
corresponds to the value that will be loaded from the created array. TIDX corresponds to the value that will be loaded from the created array. TIDX
is a temporary variable holding the index for loads from the new array. */ is an ssa name of a temporary variable holding the index for loads from the
new array. */
static void static void
build_one_array (gimple swtch, int num, tree arr_index_type, gimple phi, build_one_array (gimple swtch, int num, tree arr_index_type, gimple phi,
tree tidx) tree tidx)
{ {
tree array_type, ctor, decl, value_type, name, fetch; tree name, cst;
gimple load; gimple load;
gimple_stmt_iterator gsi; gimple_stmt_iterator gsi = gsi_for_stmt (swtch);
gcc_assert (info.default_values[num]); gcc_assert (info.default_values[num]);
value_type = TREE_TYPE (info.default_values[num]);
array_type = build_array_type (value_type, arr_index_type);
ctor = build_constructor (array_type, info.constructors[num]);
TREE_CONSTANT (ctor) = true;
decl = build_decl (VAR_DECL, NULL_TREE, array_type);
TREE_STATIC (decl) = 1;
DECL_INITIAL (decl) = ctor;
DECL_NAME (decl) = create_tmp_var_name ("CSWTCH");
DECL_ARTIFICIAL (decl) = 1;
TREE_CONSTANT (decl) = 1;
add_referenced_var (decl);
varpool_mark_needed_node (varpool_node (decl));
varpool_finalize_decl (decl);
mark_sym_for_renaming (decl);
name = make_ssa_name (SSA_NAME_VAR (PHI_RESULT (phi)), NULL); name = make_ssa_name (SSA_NAME_VAR (PHI_RESULT (phi)), NULL);
info.target_inbound_names[num] = name; info.target_inbound_names[num] = name;
fetch = build4 (ARRAY_REF, value_type, decl, tidx, NULL_TREE, cst = constructor_contains_same_values_p (info.constructors[num]);
NULL_TREE); if (cst)
load = gimple_build_assign (name, fetch); load = gimple_build_assign (name, cst);
else
{
tree array_type, ctor, decl, value_type, fetch;
value_type = TREE_TYPE (info.default_values[num]);
array_type = build_array_type (value_type, arr_index_type);
ctor = build_constructor (array_type, info.constructors[num]);
TREE_CONSTANT (ctor) = true;
decl = build_decl (VAR_DECL, NULL_TREE, array_type);
TREE_STATIC (decl) = 1;
DECL_INITIAL (decl) = ctor;
DECL_NAME (decl) = create_tmp_var_name ("CSWTCH");
DECL_ARTIFICIAL (decl) = 1;
TREE_CONSTANT (decl) = 1;
add_referenced_var (decl);
varpool_mark_needed_node (varpool_node (decl));
varpool_finalize_decl (decl);
fetch = build4 (ARRAY_REF, value_type, decl, tidx, NULL_TREE,
NULL_TREE);
load = gimple_build_assign (name, fetch);
}
SSA_NAME_DEF_STMT (name) = load; SSA_NAME_DEF_STMT (name) = load;
gsi = gsi_for_stmt (swtch);
gsi_insert_before (&gsi, load, GSI_SAME_STMT); gsi_insert_before (&gsi, load, GSI_SAME_STMT);
mark_symbols_for_renaming (load); update_stmt (load);
info.arr_ref_last = load; info.arr_ref_last = load;
} }
@ -526,16 +555,17 @@ build_arrays (gimple swtch)
gsi = gsi_for_stmt (swtch); gsi = gsi_for_stmt (swtch);
arr_index_type = build_index_type (info.range_size); arr_index_type = build_index_type (info.range_size);
tidx = make_rename_temp (arr_index_type, "csti"); tidx = make_ssa_name (create_tmp_var (arr_index_type, "csti"), NULL);
sub = fold_build2 (MINUS_EXPR, TREE_TYPE (info.index_expr), info.index_expr, sub = fold_build2 (MINUS_EXPR, TREE_TYPE (info.index_expr), info.index_expr,
fold_convert (TREE_TYPE (info.index_expr), fold_convert (TREE_TYPE (info.index_expr),
info.range_min)); info.range_min));
sub = force_gimple_operand_gsi (&gsi, fold_convert (arr_index_type, sub), sub = force_gimple_operand_gsi (&gsi, fold_convert (arr_index_type, sub),
false, NULL, true, GSI_SAME_STMT); false, NULL, true, GSI_SAME_STMT);
stmt = gimple_build_assign (tidx, sub); stmt = gimple_build_assign (tidx, sub);
SSA_NAME_DEF_STMT (tidx) = stmt;
gsi_insert_before (&gsi, stmt, GSI_SAME_STMT); gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
mark_symbols_for_renaming (stmt); update_stmt (stmt);
info.arr_ref_first = stmt; info.arr_ref_first = stmt;
for (gsi = gsi_start_phis (info.final_bb), i = 0; for (gsi = gsi_start_phis (info.final_bb), i = 0;
@ -561,8 +591,7 @@ gen_def_assigns (gimple_stmt_iterator *gsi)
assign = gimple_build_assign (name, info.default_values[i]); assign = gimple_build_assign (name, info.default_values[i]);
SSA_NAME_DEF_STMT (name) = assign; SSA_NAME_DEF_STMT (name) = assign;
gsi_insert_before (gsi, assign, GSI_SAME_STMT); gsi_insert_before (gsi, assign, GSI_SAME_STMT);
find_new_referenced_vars (assign); update_stmt (assign);
mark_symbols_for_renaming (assign);
} }
return assign; return assign;
} }
@ -640,7 +669,7 @@ gen_inbound_check (gimple swtch)
gimple label1, label2, label3; gimple label1, label2, label3;
tree utype; tree utype;
tree tmp_u; tree tmp_u_1, tmp_u_2, tmp_u_var;
tree cast; tree cast;
gimple cast_assign, minus_assign; gimple cast_assign, minus_assign;
tree ulb, minus; tree ulb, minus;
@ -664,30 +693,29 @@ gen_inbound_check (gimple swtch)
/* (end of) block 0 */ /* (end of) block 0 */
gsi = gsi_for_stmt (info.arr_ref_first); gsi = gsi_for_stmt (info.arr_ref_first);
tmp_u = make_rename_temp (utype, "csui"); tmp_u_var = create_tmp_var (utype, "csui");
tmp_u_1 = make_ssa_name (tmp_u_var, NULL);
cast = fold_convert (utype, info.index_expr); cast = fold_convert (utype, info.index_expr);
cast_assign = gimple_build_assign (tmp_u, cast); cast_assign = gimple_build_assign (tmp_u_1, cast);
find_new_referenced_vars (cast_assign); SSA_NAME_DEF_STMT (tmp_u_1) = cast_assign;
gsi_insert_before (&gsi, cast_assign, GSI_SAME_STMT); gsi_insert_before (&gsi, cast_assign, GSI_SAME_STMT);
mark_symbols_for_renaming (cast_assign); update_stmt (cast_assign);
ulb = fold_convert (utype, info.range_min); ulb = fold_convert (utype, info.range_min);
minus = fold_build2 (MINUS_EXPR, utype, tmp_u, ulb); minus = fold_build2 (MINUS_EXPR, utype, tmp_u_1, ulb);
minus = force_gimple_operand_gsi (&gsi, minus, false, NULL, true, minus = force_gimple_operand_gsi (&gsi, minus, false, NULL, true,
GSI_SAME_STMT); GSI_SAME_STMT);
minus_assign = gimple_build_assign (tmp_u, minus); tmp_u_2 = make_ssa_name (tmp_u_var, NULL);
find_new_referenced_vars (minus_assign); minus_assign = gimple_build_assign (tmp_u_2, minus);
SSA_NAME_DEF_STMT (tmp_u_2) = minus_assign;
gsi_insert_before (&gsi, minus_assign, GSI_SAME_STMT); gsi_insert_before (&gsi, minus_assign, GSI_SAME_STMT);
mark_symbols_for_renaming (minus_assign); update_stmt (minus_assign);
bound = fold_convert (utype, info.range_size); bound = fold_convert (utype, info.range_size);
cond_stmt = gimple_build_cond (LE_EXPR, tmp_u_2, bound, NULL_TREE, NULL_TREE);
cond_stmt = gimple_build_cond (LE_EXPR, tmp_u, bound, NULL_TREE, NULL_TREE);
find_new_referenced_vars (cond_stmt);
gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT); gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
mark_symbols_for_renaming (cond_stmt); update_stmt (cond_stmt);
/* block 2 */ /* block 2 */
gsi = gsi_for_stmt (info.arr_ref_first); gsi = gsi_for_stmt (info.arr_ref_first);