tree-ssa-forwprop.c (simplify_vector_constructor): New function.
2012-09-11 Marc Glisse <marc.glisse@inria.fr> gcc/ * tree-ssa-forwprop.c (simplify_vector_constructor): New function. (ssa_forward_propagate_and_combine): Call it. gcc/testsuite/ * gcc.dg/tree-ssa/forwprop-22.c: New testcase. From-SVN: r191198
This commit is contained in:
parent
4595475a43
commit
148e45e516
|
@ -1,3 +1,8 @@
|
|||
2012-09-11 Marc Glisse <marc.glisse@inria.fr>
|
||||
|
||||
* tree-ssa-forwprop.c (simplify_vector_constructor): New function.
|
||||
(ssa_forward_propagate_and_combine): Call it.
|
||||
|
||||
2012-09-11 Diego Novillo <dnovillo@google.com>
|
||||
|
||||
* var-tracking.c (vt_add_function_parameter): Adjust for VEC
|
||||
|
|
|
@ -2244,7 +2244,8 @@ tree-ssa-dse.o : tree-ssa-dse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
|
|||
tree-ssa-forwprop.o : tree-ssa-forwprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
|
||||
$(TM_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) $(CFGLOOP_H) \
|
||||
$(TREE_FLOW_H) $(TREE_PASS_H) $(DIAGNOSTIC_H) \
|
||||
langhooks.h $(FLAGS_H) $(GIMPLE_H) $(GIMPLE_PRETTY_PRINT_H) $(EXPR_H)
|
||||
langhooks.h $(FLAGS_H) $(GIMPLE_H) $(GIMPLE_PRETTY_PRINT_H) $(EXPR_H) \
|
||||
$(TREE_VECTORIZER_H)
|
||||
tree-ssa-phiprop.o : tree-ssa-phiprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
|
||||
$(TM_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) \
|
||||
$(TREE_FLOW_H) $(TREE_PASS_H) $(DIAGNOSTIC_H) \
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2012-09-11 Marc Glisse <marc.glisse@inria.fr>
|
||||
|
||||
* gcc.dg/tree-ssa/forwprop-22.c: New testcase.
|
||||
|
||||
2012-09-11 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
|
||||
Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
|
||||
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-effective-target vect_double } */
|
||||
/* { dg-require-effective-target vect_perm } */
|
||||
/* { dg-options "-O -fdump-tree-optimized" } */
|
||||
|
||||
typedef double vec __attribute__((vector_size (2 * sizeof (double))));
|
||||
void f (vec *px, vec *y, vec *z)
|
||||
{
|
||||
vec x = *px;
|
||||
vec t1 = { x[1], x[0] };
|
||||
vec t2 = { x[0], x[1] };
|
||||
*y = t1;
|
||||
*z = t2;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 1 "optimized" } } */
|
||||
/* { dg-final { scan-tree-dump-not "BIT_FIELD_REF" "optimized" } } */
|
||||
/* { dg-final { cleanup-tree-dump "optimized" } } */
|
|
@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "gimple.h"
|
||||
#include "expr.h"
|
||||
#include "cfgloop.h"
|
||||
#include "tree-vectorizer.h"
|
||||
|
||||
/* This pass propagates the RHS of assignment statements into use
|
||||
sites of the LHS of the assignment. It's basically a specialized
|
||||
|
@ -2794,6 +2795,84 @@ simplify_permutation (gimple_stmt_iterator *gsi)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Recognize a VEC_PERM_EXPR. Returns true if there were any changes. */
|
||||
|
||||
static bool
|
||||
simplify_vector_constructor (gimple_stmt_iterator *gsi)
|
||||
{
|
||||
gimple stmt = gsi_stmt (*gsi);
|
||||
gimple def_stmt;
|
||||
tree op, op2, orig, type, elem_type;
|
||||
unsigned elem_size, nelts, i;
|
||||
enum tree_code code;
|
||||
constructor_elt *elt;
|
||||
unsigned char *sel;
|
||||
bool maybe_ident;
|
||||
|
||||
gcc_checking_assert (gimple_assign_rhs_code (stmt) == CONSTRUCTOR);
|
||||
|
||||
op = gimple_assign_rhs1 (stmt);
|
||||
type = TREE_TYPE (op);
|
||||
gcc_checking_assert (TREE_CODE (type) == VECTOR_TYPE);
|
||||
|
||||
nelts = TYPE_VECTOR_SUBPARTS (type);
|
||||
elem_type = TREE_TYPE (type);
|
||||
elem_size = TREE_INT_CST_LOW (TYPE_SIZE (elem_type));
|
||||
|
||||
sel = XALLOCAVEC (unsigned char, nelts);
|
||||
orig = NULL;
|
||||
maybe_ident = true;
|
||||
FOR_EACH_VEC_ELT (constructor_elt, CONSTRUCTOR_ELTS (op), i, elt)
|
||||
{
|
||||
tree ref, op1;
|
||||
|
||||
if (i >= nelts)
|
||||
return false;
|
||||
|
||||
if (TREE_CODE (elt->value) != SSA_NAME)
|
||||
return false;
|
||||
def_stmt = SSA_NAME_DEF_STMT (elt->value);
|
||||
if (!def_stmt || !is_gimple_assign (def_stmt))
|
||||
return false;
|
||||
code = gimple_assign_rhs_code (def_stmt);
|
||||
if (code != BIT_FIELD_REF)
|
||||
return false;
|
||||
op1 = gimple_assign_rhs1 (def_stmt);
|
||||
ref = TREE_OPERAND (op1, 0);
|
||||
if (orig)
|
||||
{
|
||||
if (ref != orig)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TREE_CODE (ref) != SSA_NAME)
|
||||
return false;
|
||||
orig = ref;
|
||||
}
|
||||
if (TREE_INT_CST_LOW (TREE_OPERAND (op1, 1)) != elem_size)
|
||||
return false;
|
||||
sel[i] = TREE_INT_CST_LOW (TREE_OPERAND (op1, 2)) / elem_size;
|
||||
if (sel[i] != i) maybe_ident = false;
|
||||
}
|
||||
if (i < nelts)
|
||||
return false;
|
||||
|
||||
if (maybe_ident)
|
||||
{
|
||||
gimple_assign_set_rhs_from_tree (gsi, orig);
|
||||
}
|
||||
else
|
||||
{
|
||||
op2 = vect_gen_perm_mask (type, sel);
|
||||
if (!op2)
|
||||
return false;
|
||||
gimple_assign_set_rhs_with_ops_1 (gsi, VEC_PERM_EXPR, orig, orig, op2);
|
||||
}
|
||||
update_stmt (gsi_stmt (*gsi));
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Main entry point for the forward propagation and statement combine
|
||||
optimizer. */
|
||||
|
||||
|
@ -2965,6 +3044,9 @@ ssa_forward_propagate_and_combine (void)
|
|||
}
|
||||
else if (code == BIT_FIELD_REF)
|
||||
changed = simplify_bitfield_ref (&gsi);
|
||||
else if (code == CONSTRUCTOR
|
||||
&& TREE_CODE (TREE_TYPE (rhs1)) == VECTOR_TYPE)
|
||||
changed = simplify_vector_constructor (&gsi);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue