Message ID | b022acb6-081a-498f-90e2-7e66bfd6901f@zmail14.collab.prod.int.phx2.redhat.com |
---|---|
State | New |
Headers | show |
On Thu, Oct 20, 2011 at 3:08 PM, Kai Tietz <ktietz@redhat.com> wrote: > Hello, > > this patch re-enables the branch-cost optimization on simple boolean-typed operands, which are casted to a wider integral type. This happens due casts from > boolean-types are preserved, but FE might expands simple-expression to wider mode. > > I added two tests for already working branch-cost optimization for IA-architecture and > two for explicit checking for boolean-type. > > ChangeLog > > 2011-10-20 Kai Tietz <ktietz@redhat.com> > > * fold-const.c (simple_operand_p_2): Handle integral > casts from boolean-operands. > > 2011-10-20 Kai Tietz <ktietz@redhat.com> > > * gcc.target/i386/branch-cost1.c: New test. > * gcc.target/i386/branch-cost2.c: New test. > * gcc.target/i386/branch-cost3.c: New test. > * gcc.target/i386/branch-cost4.c: New test. > > Bootstrapped and regression tested on x86_64-unknown-linux-gnu for all languages including Ada and Obj-C++. Ok for apply? > > Regards, > Kai > > Index: gcc-head/gcc/testsuite/gcc.target/i386/branch-cost2.c > =================================================================== > --- /dev/null > +++ gcc-head/gcc/testsuite/gcc.target/i386/branch-cost2.c > @@ -0,0 +1,16 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-tree-gimple -mbranch-cost=2" } */ > + > +extern int doo (void); > + > +int > +foo (int a, int b) > +{ > + if (a && b) > + return doo (); > + return 0; > +} > + > +/* { dg-final { scan-tree-dump-times "if " 1 "gimple" } } */ > +/* { dg-final { scan-tree-dump-times " & " 1 "gimple" } } */ > +/* { dg-final { cleanup-tree-dump "gimple" } } */ > Index: gcc-head/gcc/testsuite/gcc.target/i386/branch-cost3.c > =================================================================== > --- /dev/null > +++ gcc-head/gcc/testsuite/gcc.target/i386/branch-cost3.c > @@ -0,0 +1,16 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-tree-gimple -mbranch-cost=2" } */ > + > +extern int doo (void); > + > +int > +foo (_Bool a, _Bool b) > +{ > + if (a && b) > + return doo (); > + return 0; > +} > + > +/* { dg-final { scan-tree-dump-times "if " 1 "gimple" } } */ > +/* { dg-final { scan-tree-dump-times " & " 1 "gimple" } } */ > +/* { dg-final { cleanup-tree-dump "gimple" } } */ > Index: gcc-head/gcc/testsuite/gcc.target/i386/branch-cost4.c > =================================================================== > --- /dev/null > +++ gcc-head/gcc/testsuite/gcc.target/i386/branch-cost4.c > @@ -0,0 +1,16 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-tree-gimple -mbranch-cost=0" } */ > + > +extern int doo (void); > + > +int > +foo (_Bool a, _Bool b) > +{ > + if (a && b) > + return doo (); > + return 0; > +} > + > +/* { dg-final { scan-tree-dump-times "if " 2 "gimple" } } */ > +/* { dg-final { scan-tree-dump-not " & " "gimple" } } */ > +/* { dg-final { cleanup-tree-dump "gimple" } } */ > Index: gcc-head/gcc/fold-const.c > =================================================================== > --- gcc-head.orig/gcc/fold-const.c > +++ gcc-head/gcc/fold-const.c > @@ -3706,6 +3706,19 @@ simple_operand_p_2 (tree exp) > /* Strip any conversions that don't change the machine mode. */ > STRIP_NOPS (exp); > > + /* Handle integral widening casts from boolean-typed > + expressions as simple. This happens due casts from > + boolean-types are preserved, but FE might expands > + simple-expression to wider mode. */ > + if (INTEGRAL_TYPE_P (TREE_TYPE (exp)) > + && CONVERT_EXPR_P (exp) > + && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) > + == BOOLEAN_TYPE) > + { > + exp = TREE_OPERAND (exp, 0); > + STRIP_NOPS (exp); > + } > + Huh, well. I think the above is just too special and you instead should replace the existing STRIP_NOPS by while (CONVERT_EXPR_P (exp)) exp = TREE_OPERAND (exp, 0); with a comment that conversions are considered simple. Ok with that change, if it bootstraps & tests ok. Richard. > code = TREE_CODE (exp); > > if (TREE_SIDE_EFFECTS (exp) > Index: gcc-head/gcc/testsuite/gcc.target/i386/branch-cost1.c > =================================================================== > --- /dev/null > +++ gcc-head/gcc/testsuite/gcc.target/i386/branch-cost1.c > @@ -0,0 +1,16 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-tree-gimple -mbranch-cost=0" } */ > + > +extern int doo (void); > + > +int > +foo (int a, int b) > +{ > + if (a && b) > + return doo (); > + return 0; > +} > + > +/* { dg-final { scan-tree-dump-times "if " 2 "gimple" } } */ > +/* { dg-final { scan-tree-dump-not " & " "gimple" } } */ > +/* { dg-final { cleanup-tree-dump "gimple" } } */ >
2011/10/21 Richard Guenther <richard.guenther@gmail.com>: > On Thu, Oct 20, 2011 at 3:08 PM, Kai Tietz <ktietz@redhat.com> wrote: >> Hello, >> >> this patch re-enables the branch-cost optimization on simple boolean-typed operands, which are casted to a wider integral type. This happens due casts from >> boolean-types are preserved, but FE might expands simple-expression to wider mode. >> >> I added two tests for already working branch-cost optimization for IA-architecture and >> two for explicit checking for boolean-type. >> >> ChangeLog >> >> 2011-10-20 Kai Tietz <ktietz@redhat.com> >> >> * fold-const.c (simple_operand_p_2): Handle integral >> casts from boolean-operands. >> >> 2011-10-20 Kai Tietz <ktietz@redhat.com> >> >> * gcc.target/i386/branch-cost1.c: New test. >> * gcc.target/i386/branch-cost2.c: New test. >> * gcc.target/i386/branch-cost3.c: New test. >> * gcc.target/i386/branch-cost4.c: New test. >> >> Bootstrapped and regression tested on x86_64-unknown-linux-gnu for all languages including Ada and Obj-C++. Ok for apply? >> >> Regards, >> Kai >> >> Index: gcc-head/gcc/testsuite/gcc.target/i386/branch-cost2.c >> =================================================================== >> --- /dev/null >> +++ gcc-head/gcc/testsuite/gcc.target/i386/branch-cost2.c >> @@ -0,0 +1,16 @@ >> +/* { dg-do compile } */ >> +/* { dg-options "-O2 -fdump-tree-gimple -mbranch-cost=2" } */ >> + >> +extern int doo (void); >> + >> +int >> +foo (int a, int b) >> +{ >> + if (a && b) >> + return doo (); >> + return 0; >> +} >> + >> +/* { dg-final { scan-tree-dump-times "if " 1 "gimple" } } */ >> +/* { dg-final { scan-tree-dump-times " & " 1 "gimple" } } */ >> +/* { dg-final { cleanup-tree-dump "gimple" } } */ >> Index: gcc-head/gcc/testsuite/gcc.target/i386/branch-cost3.c >> =================================================================== >> --- /dev/null >> +++ gcc-head/gcc/testsuite/gcc.target/i386/branch-cost3.c >> @@ -0,0 +1,16 @@ >> +/* { dg-do compile } */ >> +/* { dg-options "-O2 -fdump-tree-gimple -mbranch-cost=2" } */ >> + >> +extern int doo (void); >> + >> +int >> +foo (_Bool a, _Bool b) >> +{ >> + if (a && b) >> + return doo (); >> + return 0; >> +} >> + >> +/* { dg-final { scan-tree-dump-times "if " 1 "gimple" } } */ >> +/* { dg-final { scan-tree-dump-times " & " 1 "gimple" } } */ >> +/* { dg-final { cleanup-tree-dump "gimple" } } */ >> Index: gcc-head/gcc/testsuite/gcc.target/i386/branch-cost4.c >> =================================================================== >> --- /dev/null >> +++ gcc-head/gcc/testsuite/gcc.target/i386/branch-cost4.c >> @@ -0,0 +1,16 @@ >> +/* { dg-do compile } */ >> +/* { dg-options "-O2 -fdump-tree-gimple -mbranch-cost=0" } */ >> + >> +extern int doo (void); >> + >> +int >> +foo (_Bool a, _Bool b) >> +{ >> + if (a && b) >> + return doo (); >> + return 0; >> +} >> + >> +/* { dg-final { scan-tree-dump-times "if " 2 "gimple" } } */ >> +/* { dg-final { scan-tree-dump-not " & " "gimple" } } */ >> +/* { dg-final { cleanup-tree-dump "gimple" } } */ >> Index: gcc-head/gcc/fold-const.c >> =================================================================== >> --- gcc-head.orig/gcc/fold-const.c >> +++ gcc-head/gcc/fold-const.c >> @@ -3706,6 +3706,19 @@ simple_operand_p_2 (tree exp) >> /* Strip any conversions that don't change the machine mode. */ >> STRIP_NOPS (exp); >> >> + /* Handle integral widening casts from boolean-typed >> + expressions as simple. This happens due casts from >> + boolean-types are preserved, but FE might expands >> + simple-expression to wider mode. */ >> + if (INTEGRAL_TYPE_P (TREE_TYPE (exp)) >> + && CONVERT_EXPR_P (exp) >> + && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) >> + == BOOLEAN_TYPE) >> + { >> + exp = TREE_OPERAND (exp, 0); >> + STRIP_NOPS (exp); >> + } >> + > > Huh, well. I think the above is just too special and you instead should > replace the existing STRIP_NOPS by > > while (CONVERT_EXPR_P (exp)) > exp = TREE_OPERAND (exp, 0); > > with a comment that conversions are considered simple. > > Ok with that change, if it bootstraps & tests ok. > > Richard. Ok, bootstrapped and regression-tested on x86_64-unknown-linux-gnu and applied to trunk with modifying as you suggested. One question I have about handling of TRUTH-binaries in general in fold-const.c. Why aren't we enforcing already here in fold_binary for those operations, that operands get boolean-type? I see here some advantages of C-AST folding. I've tested it and saw that even later in SSA-passes we get slightly better results on that. Regards, Kai
On Fri, Oct 21, 2011 at 2:19 PM, Kai Tietz <ktietz70@googlemail.com> wrote: > 2011/10/21 Richard Guenther <richard.guenther@gmail.com>: >> On Thu, Oct 20, 2011 at 3:08 PM, Kai Tietz <ktietz@redhat.com> wrote: >>> Hello, >>> >>> this patch re-enables the branch-cost optimization on simple boolean-typed operands, which are casted to a wider integral type. This happens due casts from >>> boolean-types are preserved, but FE might expands simple-expression to wider mode. >>> >>> I added two tests for already working branch-cost optimization for IA-architecture and >>> two for explicit checking for boolean-type. >>> >>> ChangeLog >>> >>> 2011-10-20 Kai Tietz <ktietz@redhat.com> >>> >>> * fold-const.c (simple_operand_p_2): Handle integral >>> casts from boolean-operands. >>> >>> 2011-10-20 Kai Tietz <ktietz@redhat.com> >>> >>> * gcc.target/i386/branch-cost1.c: New test. >>> * gcc.target/i386/branch-cost2.c: New test. >>> * gcc.target/i386/branch-cost3.c: New test. >>> * gcc.target/i386/branch-cost4.c: New test. >>> >>> Bootstrapped and regression tested on x86_64-unknown-linux-gnu for all languages including Ada and Obj-C++. Ok for apply? >>> >>> Regards, >>> Kai >>> >>> Index: gcc-head/gcc/testsuite/gcc.target/i386/branch-cost2.c >>> =================================================================== >>> --- /dev/null >>> +++ gcc-head/gcc/testsuite/gcc.target/i386/branch-cost2.c >>> @@ -0,0 +1,16 @@ >>> +/* { dg-do compile } */ >>> +/* { dg-options "-O2 -fdump-tree-gimple -mbranch-cost=2" } */ >>> + >>> +extern int doo (void); >>> + >>> +int >>> +foo (int a, int b) >>> +{ >>> + if (a && b) >>> + return doo (); >>> + return 0; >>> +} >>> + >>> +/* { dg-final { scan-tree-dump-times "if " 1 "gimple" } } */ >>> +/* { dg-final { scan-tree-dump-times " & " 1 "gimple" } } */ >>> +/* { dg-final { cleanup-tree-dump "gimple" } } */ >>> Index: gcc-head/gcc/testsuite/gcc.target/i386/branch-cost3.c >>> =================================================================== >>> --- /dev/null >>> +++ gcc-head/gcc/testsuite/gcc.target/i386/branch-cost3.c >>> @@ -0,0 +1,16 @@ >>> +/* { dg-do compile } */ >>> +/* { dg-options "-O2 -fdump-tree-gimple -mbranch-cost=2" } */ >>> + >>> +extern int doo (void); >>> + >>> +int >>> +foo (_Bool a, _Bool b) >>> +{ >>> + if (a && b) >>> + return doo (); >>> + return 0; >>> +} >>> + >>> +/* { dg-final { scan-tree-dump-times "if " 1 "gimple" } } */ >>> +/* { dg-final { scan-tree-dump-times " & " 1 "gimple" } } */ >>> +/* { dg-final { cleanup-tree-dump "gimple" } } */ >>> Index: gcc-head/gcc/testsuite/gcc.target/i386/branch-cost4.c >>> =================================================================== >>> --- /dev/null >>> +++ gcc-head/gcc/testsuite/gcc.target/i386/branch-cost4.c >>> @@ -0,0 +1,16 @@ >>> +/* { dg-do compile } */ >>> +/* { dg-options "-O2 -fdump-tree-gimple -mbranch-cost=0" } */ >>> + >>> +extern int doo (void); >>> + >>> +int >>> +foo (_Bool a, _Bool b) >>> +{ >>> + if (a && b) >>> + return doo (); >>> + return 0; >>> +} >>> + >>> +/* { dg-final { scan-tree-dump-times "if " 2 "gimple" } } */ >>> +/* { dg-final { scan-tree-dump-not " & " "gimple" } } */ >>> +/* { dg-final { cleanup-tree-dump "gimple" } } */ >>> Index: gcc-head/gcc/fold-const.c >>> =================================================================== >>> --- gcc-head.orig/gcc/fold-const.c >>> +++ gcc-head/gcc/fold-const.c >>> @@ -3706,6 +3706,19 @@ simple_operand_p_2 (tree exp) >>> /* Strip any conversions that don't change the machine mode. */ >>> STRIP_NOPS (exp); >>> >>> + /* Handle integral widening casts from boolean-typed >>> + expressions as simple. This happens due casts from >>> + boolean-types are preserved, but FE might expands >>> + simple-expression to wider mode. */ >>> + if (INTEGRAL_TYPE_P (TREE_TYPE (exp)) >>> + && CONVERT_EXPR_P (exp) >>> + && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) >>> + == BOOLEAN_TYPE) >>> + { >>> + exp = TREE_OPERAND (exp, 0); >>> + STRIP_NOPS (exp); >>> + } >>> + >> >> Huh, well. I think the above is just too special and you instead should >> replace the existing STRIP_NOPS by >> >> while (CONVERT_EXPR_P (exp)) >> exp = TREE_OPERAND (exp, 0); >> >> with a comment that conversions are considered simple. >> >> Ok with that change, if it bootstraps & tests ok. >> >> Richard. > > Ok, bootstrapped and regression-tested on x86_64-unknown-linux-gnu and > applied to trunk with modifying as you suggested. > > One question I have about handling of TRUTH-binaries in general in > fold-const.c. Why aren't we enforcing already here in fold_binary for > those operations, that operands get boolean-type? I see here some > advantages of C-AST folding. I've tested it and saw that even later > in SSA-passes we get slightly better results on that. Because we do not want to mess with the Frontends AST. Richard. > Regards, > Kai >
Index: gcc-head/gcc/testsuite/gcc.target/i386/branch-cost2.c =================================================================== --- /dev/null +++ gcc-head/gcc/testsuite/gcc.target/i386/branch-cost2.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-gimple -mbranch-cost=2" } */ + +extern int doo (void); + +int +foo (int a, int b) +{ + if (a && b) + return doo (); + return 0; +} + +/* { dg-final { scan-tree-dump-times "if " 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times " & " 1 "gimple" } } */ +/* { dg-final { cleanup-tree-dump "gimple" } } */ Index: gcc-head/gcc/testsuite/gcc.target/i386/branch-cost3.c =================================================================== --- /dev/null +++ gcc-head/gcc/testsuite/gcc.target/i386/branch-cost3.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-gimple -mbranch-cost=2" } */ + +extern int doo (void); + +int +foo (_Bool a, _Bool b) +{ + if (a && b) + return doo (); + return 0; +} + +/* { dg-final { scan-tree-dump-times "if " 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times " & " 1 "gimple" } } */ +/* { dg-final { cleanup-tree-dump "gimple" } } */ Index: gcc-head/gcc/testsuite/gcc.target/i386/branch-cost4.c =================================================================== --- /dev/null +++ gcc-head/gcc/testsuite/gcc.target/i386/branch-cost4.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-gimple -mbranch-cost=0" } */ + +extern int doo (void); + +int +foo (_Bool a, _Bool b) +{ + if (a && b) + return doo (); + return 0; +} + +/* { dg-final { scan-tree-dump-times "if " 2 "gimple" } } */ +/* { dg-final { scan-tree-dump-not " & " "gimple" } } */ +/* { dg-final { cleanup-tree-dump "gimple" } } */ Index: gcc-head/gcc/fold-const.c =================================================================== --- gcc-head.orig/gcc/fold-const.c +++ gcc-head/gcc/fold-const.c @@ -3706,6 +3706,19 @@ simple_operand_p_2 (tree exp) /* Strip any conversions that don't change the machine mode. */ STRIP_NOPS (exp); + /* Handle integral widening casts from boolean-typed + expressions as simple. This happens due casts from + boolean-types are preserved, but FE might expands + simple-expression to wider mode. */ + if (INTEGRAL_TYPE_P (TREE_TYPE (exp)) + && CONVERT_EXPR_P (exp) + && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) + == BOOLEAN_TYPE) + { + exp = TREE_OPERAND (exp, 0); + STRIP_NOPS (exp); + } + code = TREE_CODE (exp); if (TREE_SIDE_EFFECTS (exp) Index: gcc-head/gcc/testsuite/gcc.target/i386/branch-cost1.c =================================================================== --- /dev/null +++ gcc-head/gcc/testsuite/gcc.target/i386/branch-cost1.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-gimple -mbranch-cost=0" } */ + +extern int doo (void); + +int +foo (int a, int b) +{ + if (a && b) + return doo (); + return 0; +} + +/* { dg-final { scan-tree-dump-times "if " 2 "gimple" } } */ +/* { dg-final { scan-tree-dump-not " & " "gimple" } } */ +/* { dg-final { cleanup-tree-dump "gimple" } } */