Message ID | alpine.DEB.2.02.1210281554180.4597@stedding.saclay.inria.fr |
---|---|
State | New |
Headers | show |
On 10/28/2012 04:14 PM, Marc Glisse wrote: > Hello, > > this patch lets some predicates on floating point constants answer > true for vectors, so optimizations are applied. Great. I wonder how are we doing lately in terms of function pointer inlining?! If the current optimizers can already able to smoothly inline real_zerop & co we could have a single helper function and avoid all this redundancy... In case, I suppose other code could also benefit. Thanks, Paolo.
On 10/28/2012 04:46 PM, Paolo Carlini wrote: > On 10/28/2012 04:14 PM, Marc Glisse wrote: >> Hello, >> >> this patch lets some predicates on floating point constants answer >> true for vectors, so optimizations are applied. > Great. > > I wonder how are we doing lately in terms of function pointer > inlining?! If the current optimizers can already able to smoothly > inline real_zerop & co we could have a single helper function and > avoid all this redundancy... In case, I suppose other code could also > benefit. Uhm, sorry, I didn't notice the functions are recursive. The situation seems hopeless, too bad. Paolo.
On Sun, 28 Oct 2012, Paolo Carlini wrote: > On 10/28/2012 04:46 PM, Paolo Carlini wrote: >> On 10/28/2012 04:14 PM, Marc Glisse wrote: >>> Hello, >>> >>> this patch lets some predicates on floating point constants answer true >>> for vectors, so optimizations are applied. >> Great. >> >> I wonder how are we doing lately in terms of function pointer inlining?! If >> the current optimizers can already able to smoothly inline real_zerop & co Inlining real_zerop can only happen in lto builds. >> we could have a single helper function and avoid all this redundancy... In >> case, I suppose other code could also benefit. > Uhm, sorry, I didn't notice the functions are recursive. The situation seems > hopeless, too bad. The recursion has a bounded depth of 2 ;-) It is true that we could have a single function in tree.c: bool real_intcstp (const_tree, int); with possible trivial wrappers in tree.h.
On Sun, 28 Oct 2012, Marc Glisse wrote: [there are 4 real_*p that only differ by 1 character] > It is true that we could have a single function in tree.c: > bool real_intcstp (const_tree, int); The helper function could even take a REAL_VALUE_TYPE as second argument, so the non-inline part doesn't have more work than currently. Trying to also merge the real_*p predicates with the integer_*p predicates seems harder (in fancy C++, we'd have a number of ways of writing the code for complex and vectors only once, but I don't think we want to go there). > with possible trivial wrappers in tree.h.
On Sun, Oct 28, 2012 at 4:14 PM, Marc Glisse <marc.glisse@inria.fr> wrote: > Hello, > > this patch lets some predicates on floating point constants answer true for > vectors, so optimizations are applied. > > Tested bootstrap + testsuite (default languages). Ok. Bonus points if you quickly eyed users of whether they may be surprised in vectors coming through now. Thanks, Richard. > 2012-10-29 Marc Glisse <marc.glisse@inria.fr> > > PR middle-end/55027 > > gcc/ > * tree.c (real_zerop, real_onep, real_twop, real_minus_onep): > Handle VECTOR_CST. > > testsuite/ > * gcc.dg/pr55027.c: New testcase. > > -- > Marc Glisse > Index: gcc/testsuite/gcc.dg/pr55027.c > =================================================================== > --- gcc/testsuite/gcc.dg/pr55027.c (revision 0) > +++ gcc/testsuite/gcc.dg/pr55027.c (revision 0) > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-options "-Ofast -fdump-tree-optimized-raw" } */ > + > +typedef double v2df __attribute__ ((__vector_size__ (2 * sizeof > (double)))); > + > +void f (v2df *x) > +{ > + *x = 0 + 1 * *x; > +} > + > +/* { dg-final { scan-tree-dump-not "gimple_assign" "optimized" } } */ > +/* { dg-final { cleanup-tree-dump "optimized" } } */ > > Property changes on: gcc/testsuite/gcc.dg/pr55027.c > ___________________________________________________________________ > Added: svn:keywords > + Author Date Id Revision URL > Added: svn:eol-style > + native > > Index: gcc/tree.c > =================================================================== > --- gcc/tree.c (revision 192894) > +++ gcc/tree.c (working copy) > @@ -1985,75 +1985,127 @@ tree_floor_log2 (const_tree expr) > } > > /* Return 1 if EXPR is the real constant zero. Trailing zeroes matter for > decimal float constants, so don't return 1 for them. */ > > int > real_zerop (const_tree expr) > { > STRIP_NOPS (expr); > > - return ((TREE_CODE (expr) == REAL_CST > - && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst0) > - && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr))))) > - || (TREE_CODE (expr) == COMPLEX_CST > - && real_zerop (TREE_REALPART (expr)) > - && real_zerop (TREE_IMAGPART (expr)))); > + switch (TREE_CODE (expr)) > + { > + case REAL_CST: > + return REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst0) > + && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr)))); > + case COMPLEX_CST: > + return real_zerop (TREE_REALPART (expr)) > + && real_zerop (TREE_IMAGPART (expr)); > + case VECTOR_CST: > + { > + unsigned i; > + for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) > + if (!real_zerop (VECTOR_CST_ELT (expr, i))) > + return false; > + return true; > + } > + default: > + return false; > + } > } > > /* Return 1 if EXPR is the real constant one in real or complex form. > Trailing zeroes matter for decimal float constants, so don't return > 1 for them. */ > > int > real_onep (const_tree expr) > { > STRIP_NOPS (expr); > > - return ((TREE_CODE (expr) == REAL_CST > - && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst1) > - && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr))))) > - || (TREE_CODE (expr) == COMPLEX_CST > - && real_onep (TREE_REALPART (expr)) > - && real_zerop (TREE_IMAGPART (expr)))); > + switch (TREE_CODE (expr)) > + { > + case REAL_CST: > + return REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst1) > + && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr)))); > + case COMPLEX_CST: > + return real_onep (TREE_REALPART (expr)) > + && real_zerop (TREE_IMAGPART (expr)); > + case VECTOR_CST: > + { > + unsigned i; > + for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) > + if (!real_onep (VECTOR_CST_ELT (expr, i))) > + return false; > + return true; > + } > + default: > + return false; > + } > } > > /* Return 1 if EXPR is the real constant two. Trailing zeroes matter > for decimal float constants, so don't return 1 for them. */ > > int > real_twop (const_tree expr) > { > STRIP_NOPS (expr); > > - return ((TREE_CODE (expr) == REAL_CST > - && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst2) > - && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr))))) > - || (TREE_CODE (expr) == COMPLEX_CST > - && real_twop (TREE_REALPART (expr)) > - && real_zerop (TREE_IMAGPART (expr)))); > + switch (TREE_CODE (expr)) > + { > + case REAL_CST: > + return REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst2) > + && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr)))); > + case COMPLEX_CST: > + return real_twop (TREE_REALPART (expr)) > + && real_zerop (TREE_IMAGPART (expr)); > + case VECTOR_CST: > + { > + unsigned i; > + for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) > + if (!real_twop (VECTOR_CST_ELT (expr, i))) > + return false; > + return true; > + } > + default: > + return false; > + } > } > > /* Return 1 if EXPR is the real constant minus one. Trailing zeroes > matter for decimal float constants, so don't return 1 for them. */ > > int > real_minus_onep (const_tree expr) > { > STRIP_NOPS (expr); > > - return ((TREE_CODE (expr) == REAL_CST > - && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconstm1) > - && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr))))) > - || (TREE_CODE (expr) == COMPLEX_CST > - && real_minus_onep (TREE_REALPART (expr)) > - && real_zerop (TREE_IMAGPART (expr)))); > + switch (TREE_CODE (expr)) > + { > + case REAL_CST: > + return REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconstm1) > + && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr)))); > + case COMPLEX_CST: > + return real_minus_onep (TREE_REALPART (expr)) > + && real_zerop (TREE_IMAGPART (expr)); > + case VECTOR_CST: > + { > + unsigned i; > + for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) > + if (!real_minus_onep (VECTOR_CST_ELT (expr, i))) > + return false; > + return true; > + } > + default: > + return false; > + } > } > > /* Nonzero if EXP is a constant or a cast of a constant. */ > > int > really_constant_p (const_tree exp) > { > /* This is not quite the same as STRIP_NOPS. It does more. */ > while (CONVERT_EXPR_P (exp) > || TREE_CODE (exp) == NON_LVALUE_EXPR) >
On Mon, 29 Oct 2012, Richard Biener wrote: > On Sun, Oct 28, 2012 at 4:14 PM, Marc Glisse <marc.glisse@inria.fr> wrote: >> Hello, >> >> this patch lets some predicates on floating point constants answer true for >> vectors, so optimizations are applied. >> >> Tested bootstrap + testsuite (default languages). > > Ok. Bonus points if you quickly eyed users of whether they may be surprised > in vectors coming through now. I did (that's why I didn't also change integer_twop), but I won't claim the bonus points, because in fold-const.c: * there is probably an issue with signed zero in fold_real_zero_addition_p * the RDIV_EXPR case would like real_zerop to mean "at least one is zero" * abs(x)>=0 or <0 doesn't seem ready but that's not much compared to the broken integer vector optimizations ;-)
Index: gcc/testsuite/gcc.dg/pr55027.c =================================================================== --- gcc/testsuite/gcc.dg/pr55027.c (revision 0) +++ gcc/testsuite/gcc.dg/pr55027.c (revision 0) @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-Ofast -fdump-tree-optimized-raw" } */ + +typedef double v2df __attribute__ ((__vector_size__ (2 * sizeof (double)))); + +void f (v2df *x) +{ + *x = 0 + 1 * *x; +} + +/* { dg-final { scan-tree-dump-not "gimple_assign" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ Property changes on: gcc/testsuite/gcc.dg/pr55027.c ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision URL Added: svn:eol-style + native Index: gcc/tree.c =================================================================== --- gcc/tree.c (revision 192894) +++ gcc/tree.c (working copy) @@ -1985,75 +1985,127 @@ tree_floor_log2 (const_tree expr) } /* Return 1 if EXPR is the real constant zero. Trailing zeroes matter for decimal float constants, so don't return 1 for them. */ int real_zerop (const_tree expr) { STRIP_NOPS (expr); - return ((TREE_CODE (expr) == REAL_CST - && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst0) - && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr))))) - || (TREE_CODE (expr) == COMPLEX_CST - && real_zerop (TREE_REALPART (expr)) - && real_zerop (TREE_IMAGPART (expr)))); + switch (TREE_CODE (expr)) + { + case REAL_CST: + return REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst0) + && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr)))); + case COMPLEX_CST: + return real_zerop (TREE_REALPART (expr)) + && real_zerop (TREE_IMAGPART (expr)); + case VECTOR_CST: + { + unsigned i; + for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) + if (!real_zerop (VECTOR_CST_ELT (expr, i))) + return false; + return true; + } + default: + return false; + } } /* Return 1 if EXPR is the real constant one in real or complex form. Trailing zeroes matter for decimal float constants, so don't return 1 for them. */ int real_onep (const_tree expr) { STRIP_NOPS (expr); - return ((TREE_CODE (expr) == REAL_CST - && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst1) - && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr))))) - || (TREE_CODE (expr) == COMPLEX_CST - && real_onep (TREE_REALPART (expr)) - && real_zerop (TREE_IMAGPART (expr)))); + switch (TREE_CODE (expr)) + { + case REAL_CST: + return REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst1) + && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr)))); + case COMPLEX_CST: + return real_onep (TREE_REALPART (expr)) + && real_zerop (TREE_IMAGPART (expr)); + case VECTOR_CST: + { + unsigned i; + for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) + if (!real_onep (VECTOR_CST_ELT (expr, i))) + return false; + return true; + } + default: + return false; + } } /* Return 1 if EXPR is the real constant two. Trailing zeroes matter for decimal float constants, so don't return 1 for them. */ int real_twop (const_tree expr) { STRIP_NOPS (expr); - return ((TREE_CODE (expr) == REAL_CST - && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst2) - && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr))))) - || (TREE_CODE (expr) == COMPLEX_CST - && real_twop (TREE_REALPART (expr)) - && real_zerop (TREE_IMAGPART (expr)))); + switch (TREE_CODE (expr)) + { + case REAL_CST: + return REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst2) + && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr)))); + case COMPLEX_CST: + return real_twop (TREE_REALPART (expr)) + && real_zerop (TREE_IMAGPART (expr)); + case VECTOR_CST: + { + unsigned i; + for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) + if (!real_twop (VECTOR_CST_ELT (expr, i))) + return false; + return true; + } + default: + return false; + } } /* Return 1 if EXPR is the real constant minus one. Trailing zeroes matter for decimal float constants, so don't return 1 for them. */ int real_minus_onep (const_tree expr) { STRIP_NOPS (expr); - return ((TREE_CODE (expr) == REAL_CST - && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconstm1) - && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr))))) - || (TREE_CODE (expr) == COMPLEX_CST - && real_minus_onep (TREE_REALPART (expr)) - && real_zerop (TREE_IMAGPART (expr)))); + switch (TREE_CODE (expr)) + { + case REAL_CST: + return REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconstm1) + && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr)))); + case COMPLEX_CST: + return real_minus_onep (TREE_REALPART (expr)) + && real_zerop (TREE_IMAGPART (expr)); + case VECTOR_CST: + { + unsigned i; + for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) + if (!real_minus_onep (VECTOR_CST_ELT (expr, i))) + return false; + return true; + } + default: + return false; + } } /* Nonzero if EXP is a constant or a cast of a constant. */ int really_constant_p (const_tree exp) { /* This is not quite the same as STRIP_NOPS. It does more. */ while (CONVERT_EXPR_P (exp) || TREE_CODE (exp) == NON_LVALUE_EXPR)