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:
parent
ed2807f4cd
commit
7156c8abaf
@ -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
|
||||||
|
@ -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
|
||||||
|
21
gcc/testsuite/gcc.dg/tree-ssa/cswtch-2.c
Normal file
21
gcc/testsuite/gcc.dg/tree-ssa/cswtch-2.c
Normal 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" } } */
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user