diff options
author | Marc Glisse <marc.glisse@inria.fr> | 2012-09-10 20:48:34 +0200 |
---|---|---|
committer | Marc Glisse <glisse@gcc.gnu.org> | 2012-09-10 18:48:34 +0000 |
commit | 881a9dcdef0b5350bb535faa59488cfc9d7a1eeb (patch) | |
tree | 90f9e4ccf5c5a6dac2bb628c6b5c6b5aa196ccc0 /gcc | |
parent | 965c17988d6d4d0e8e943e087698bff6f9318a4a (diff) | |
download | gcc-881a9dcdef0b5350bb535faa59488cfc9d7a1eeb.zip gcc-881a9dcdef0b5350bb535faa59488cfc9d7a1eeb.tar.gz gcc-881a9dcdef0b5350bb535faa59488cfc9d7a1eeb.tar.bz2 |
tree-ssa-forwprop.c (simplify_bitfield_ref): New function.
2012-09-10 Marc Glisse <marc.glisse@inria.fr>
gcc/
* tree-ssa-forwprop.c (simplify_bitfield_ref): New function.
(ssa_forward_propagate_and_combine): Call it.
gcc/testsuite/
* gcc.dg/tree-ssa/forwprop-21.c: New testcase.
From-SVN: r191158
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/forwprop-21.c | 13 | ||||
-rw-r--r-- | gcc/tree-ssa-forwprop.c | 74 |
4 files changed, 96 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3abb393..281540f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2012-09-10 Marc Glisse <marc.glisse@inria.fr> + + * tree-ssa-forwprop.c (simplify_bitfield_ref): New function. + (ssa_forward_propagate_and_combine): Call it. + 2012-09-10 Steve Ellcey <sellcey@mips.com> * config.gcc: Add mips*-mti-linux* target diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b8f4c39..dc35774 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2012-09-10 Marc Glisse <marc.glisse@inria.fr> + + * gcc.dg/tree-ssa/forwprop-21.c: New testcase. + 2012-09-10 Aldy Hernandez <aldyh@redhat.com> * gcc.dg/tm/reg-promotion.c: Modify dump message check. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-21.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-21.c new file mode 100644 index 0000000..4859fa8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-21.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-optimized" } */ +typedef int v4si __attribute__ ((vector_size (4 * sizeof(int)))); + +int +test (v4si *x, v4si *y) +{ + v4si m = { 2, 3, 6, 5 }; + v4si z = __builtin_shuffle (*x, *y, m); + return z[2]; +} +/* { dg-final { scan-tree-dump-not "VEC_PERM_EXPR" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index 72217ec..5692e21 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -2574,6 +2574,78 @@ combine_conversions (gimple_stmt_iterator *gsi) return 0; } +/* Combine an element access with a shuffle. Returns true if there were + any changes made, else it returns false. */ + +static bool +simplify_bitfield_ref (gimple_stmt_iterator *gsi) +{ + gimple stmt = gsi_stmt (*gsi); + gimple def_stmt; + tree op, op0, op1, op2; + tree elem_type; + unsigned idx, n, size; + enum tree_code code; + + op = gimple_assign_rhs1 (stmt); + gcc_checking_assert (TREE_CODE (op) == BIT_FIELD_REF); + + op0 = TREE_OPERAND (op, 0); + if (TREE_CODE (op0) != SSA_NAME + || TREE_CODE (TREE_TYPE (op0)) != VECTOR_TYPE) + return false; + + elem_type = TREE_TYPE (TREE_TYPE (op0)); + if (TREE_TYPE (op) != elem_type) + return false; + + size = TREE_INT_CST_LOW (TYPE_SIZE (elem_type)); + op1 = TREE_OPERAND (op, 1); + n = TREE_INT_CST_LOW (op1) / size; + if (n != 1) + return false; + + def_stmt = SSA_NAME_DEF_STMT (op0); + if (!def_stmt || !is_gimple_assign (def_stmt) + || !can_propagate_from (def_stmt)) + return false; + + op2 = TREE_OPERAND (op, 2); + idx = TREE_INT_CST_LOW (op2) / size; + + code = gimple_assign_rhs_code (def_stmt); + + if (code == VEC_PERM_EXPR) + { + tree p, m, index, tem; + unsigned nelts; + m = gimple_assign_rhs3 (def_stmt); + if (TREE_CODE (m) != VECTOR_CST) + return false; + nelts = VECTOR_CST_NELTS (m); + idx = TREE_INT_CST_LOW (VECTOR_CST_ELT (m, idx)); + idx %= 2 * nelts; + if (idx < nelts) + { + p = gimple_assign_rhs1 (def_stmt); + } + else + { + p = gimple_assign_rhs2 (def_stmt); + idx -= nelts; + } + index = build_int_cst (TREE_TYPE (TREE_TYPE (m)), idx * size); + tem = build3 (BIT_FIELD_REF, TREE_TYPE (op), + unshare_expr (p), op1, index); + gimple_assign_set_rhs1 (stmt, tem); + fold_stmt (gsi); + update_stmt (gsi_stmt (*gsi)); + return true; + } + + return false; +} + /* Determine whether applying the 2 permutations (mask1 then mask2) gives back one of the input. */ @@ -2891,6 +2963,8 @@ ssa_forward_propagate_and_combine (void) cfg_changed = true; changed = did_something != 0; } + else if (code == BIT_FIELD_REF) + changed = simplify_bitfield_ref (&gsi); break; } |