gcc/gcc44-cswtch.patch

130 lines
4.0 KiB
Diff

2009-04-21 Martin Jambor <mjambor@suse.cz>
* tree-switch-conversion.c (constructor_contains_same_values_p):
New function.
(build_one_array): Create assigns of constants if possible.
* gcc.dg/tree-ssa/cswtch-2.c: New test.
--- gcc/tree-switch-conversion.c.jj 2009-03-28 18:11:43.000000000 +0100
+++ gcc/tree-switch-conversion.c 2009-04-22 20:09:45.000000000 +0200
@@ -459,6 +459,28 @@ build_constructors (gimple swtch)
}
}
+/* 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
variable. Also create a load statement that initializes the variable in
question with a value from the static array. SWTCH is the switch statement
@@ -472,35 +494,44 @@ static void
build_one_array (gimple swtch, int num, tree arr_index_type, gimple phi,
tree tidx)
{
- tree array_type, ctor, decl, value_type, name, fetch;
+ tree name, cst;
gimple load;
gimple_stmt_iterator gsi;
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);
info.target_inbound_names[num] = name;
- fetch = build4 (ARRAY_REF, value_type, decl, tidx, NULL_TREE,
- NULL_TREE);
- load = gimple_build_assign (name, fetch);
+ cst = constructor_contains_same_values_p (info.constructors[num]);
+ if (cst)
+ 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);
+ mark_sym_for_renaming (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;
gsi = gsi_for_stmt (swtch);
--- gcc/testsuite/gcc.dg/tree-ssa/cswtch-2.c.jj 2009-04-22 20:01:40.000000000 +0200
+++ gcc/testsuite/gcc.dg/tree-ssa/cswtch-2.c 2009-04-22 20:01:40.000000000 +0200
@@ -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" } } */