Richard Guenther - [PATCH] Fix PRs 19431 and 21463 (if conversion with loads) (original) (raw)

This is the mail archive of the gcc-patches@gcc.gnu.orgmailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

This is the second attempt at solving those PRs which finally allows us to optimize

std::max(std::min(a0, c), std::min(std::max(a1, c), b))

into a sequence of MIN/MAX exprs and get rid of the previously forced addressable variables a0, c, a1 and b.

It's got a little bit too ugly as moving loads with only virtual ssa form (and not pre-computing reaching VUSEs as PRE does), but as I expect the number of transformation opportunities pretty low walking virtual operands should be faster than precomputing reaching VUSEs.

There is the possibility to force PRE to do this transformation (in parts) and the new value numbering promises to also handle the more complex cases. Still PRE is running too late (and there's DCE and other cleanup missing after it) to get rid of the addressability and to trigger MIN/MAX conversion in the phiopt pass.

To allow phiopt to do the transformation to MIN/MAX expr we need at least one DCE, one copyprop and one DOM pass (maybe copyprop + CD-DCE would also do). So I put the new pass right before FRE (we are possibly exposing new FRE opportunities) to get all the required cleanup before the first phiopt run.

As with the previous version we get around 3% runtime improvement for tramp3d and selected libstdc++ performance tests. Compile time effects are in the noise for applications tested by the c++tester.

Bootstrapped and tested on x86_64-unknown-linux-gnu.

Ok for mainline?

Thanks, Richard.

2007-02-13 Richard Guenther rguenther@suse.de

PR tree-optimization/19431
PR tree-optimization/21463
* tree-pass.h (pass_phiprop): Declare.
* passes.c (init_optimization_passes): New phiprop pass.
* tree-ssa-forwprop.c (struct phiprop_d): New structure.
(phivn_valid_p): New helper function.
(phiprop_insert_phi): Likewise.
(propagate_with_phi): Likewise.
(tree_ssa_phiprop): New propagator propagating loads
through phi nodes if profitable.
(tree_ssa_forward_propagate_single_use_va): Call it.

* gcc.c-torture/execute/20070212-1.c: New testcase.
* gcc.c-torture/execute/20070212-2.c: Likewise.
* gcc.c-torture/execute/20070212-3.c: Likewise.
* gcc.dg/tree-ssa/pr21463.c: Likewise.
* g++.dg/tree-ssa/pr21463.C: Likewise.
* g++.dg/tree-ssa/pr30738.C: Likewise.

Index: tree-pass.h

*** tree-pass.h (revision 121946) --- tree-pass.h (working copy) *************** extern struct tree_opt_pass pass_warn_fu *** 288,293 **** --- 288,294 ---- extern struct tree_opt_pass pass_warn_function_noreturn; extern struct tree_opt_pass pass_phiopt; extern struct tree_opt_pass pass_forwprop; + extern struct tree_opt_pass pass_phiprop; extern struct tree_opt_pass pass_dse; extern struct tree_opt_pass pass_nrv; extern struct tree_opt_pass pass_mark_used_blocks; Index: passes.c

*** passes.c (revision 121946) --- passes.c (working copy) *************** init_optimization_passes (void) *** 523,528 **** --- 523,529 ----
/* Initial scalar cleanups. */ NEXT_PASS (pass_ccp); + NEXT_PASS (pass_phiprop); NEXT_PASS (pass_fre); NEXT_PASS (pass_dce); NEXT_PASS (pass_forwprop); Index: testsuite/gcc.c-torture/execute/20070212-1.c

*** testsuite/gcc.c-torture/execute/20070212-1.c (revision 0) --- testsuite/gcc.c-torture/execute/20070212-1.c (revision 0) *************** *** 0 **** --- 1,26 ---- + struct f + { + int i; + }; + + int g(int i, int c, struct f *ff, int *p) + { + int *t; + if (c) + t = &i; + else + t = &ff->i; + *p = 0; + return *t; + } + + extern void abort(void); + + int main() + { + struct f f; + f.i = 1; + if (g(5, 0, &f, &f.i) != 0) + abort (); + return 0; + } Index: testsuite/gcc.c-torture/execute/20070212-2.c

*** testsuite/gcc.c-torture/execute/20070212-2.c (revision 0) --- testsuite/gcc.c-torture/execute/20070212-2.c (revision 0) *************** *** 0 **** --- 1,19 ---- + int f(int k, int i1, int j1) + { + int *f1; + if(k) + f1 = &i1; + else + f1 = &j1; + i1 = 0; + return *f1; + } + + extern void abort (void); + + int main() + { + if (f(1, 1, 2) != 0) + abort (); + return 0; + } Index: testsuite/gcc.c-torture/execute/20070212-3.c

*** testsuite/gcc.c-torture/execute/20070212-3.c (revision 0) --- testsuite/gcc.c-torture/execute/20070212-3.c (revision 0) *************** *** 0 **** --- 1,30 ---- + struct foo { int i; int j; }; + + int bar (struct foo *k, int k2, int f, int f2) + { + int *p, *q; + int res; + if (f) + p = &k->i; + else + p = &k->j; + res = *p; + k->i = 1; + if (f2) + q = p; + else + q = &k2; + return res + *q; + } + + extern void abort (void); + + int main() + { + struct foo k; + k.i = 0; + k.j = 1; + if (bar (&k, 1, 1, 1) != 1) + abort (); + return 0; + } Index: testsuite/g++.dg/tree-ssa/pr30738.C

*** testsuite/g++.dg/tree-ssa/pr30738.C (revision 0) --- testsuite/g++.dg/tree-ssa/pr30738.C (revision 0) *************** *** 0 **** --- 1,17 ---- + /* { dg-do compile } / + / { dg-options "-O -fdump-tree-phiopt1" } / + + template + static inline const T& + min_ref (const T &x, const T &y) + { + return x < y ? x : y; + } + + int test_min_ref (int x, int y) + { + return min_ref (x, y); + } + + / { dg-final { scan-tree-dump "MIN_EXPR" "phiopt1" } } / + / { dg-final { cleanup-tree-dump "phiopt1" } } */ Index: testsuite/g++.dg/tree-ssa/pr21463.C

*** testsuite/g++.dg/tree-ssa/pr21463.C (revision 0) --- testsuite/g++.dg/tree-ssa/pr21463.C (revision 0) *************** *** 0 **** --- 1,20 ---- + /* { dg-do compile } / + / { dg-options "-O -fdump-tree-phiopt1" } / + + template static inline const T &ref_max(const T &a, const T &b) + { return a<b ? b : a; } + template static inline const T &ref_min(const T &a, const T &b) + { return a<b ? a : b; } + + template struct foo_t { + T a0, a1; + T bar_ref(const T b, const T c) { + return ref_max(ref_min(a0, c), ref_min(ref_max(a1, c), b)); + } + }; + + template struct foo_t; + + / { dg-final { scan-tree-dump-times "MIN_EXPR" 2 "phiopt1" } } / + / { dg-final { scan-tree-dump-times "MAX_EXPR" 2 "phiopt1" } } / + / { dg-final { cleanup-tree-dump "phiopt1" } } */ Index: testsuite/gcc.dg/tree-ssa/pr21463.c

*** testsuite/gcc.dg/tree-ssa/pr21463.c (revision 0) --- testsuite/gcc.dg/tree-ssa/pr21463.c (revision 0) *************** *** 0 **** --- 1,23 ---- + /* { dg-do compile } / + / { dg-options "-O -fdump-tree-phiprop" } */ + + struct f + { + int i; + }; + + int g(int i, int c, struct f *ff, int g) + { + int *t; + if (c) + t = &i; + else + t = &ff->i; + if (g) + return t; + else + return t; + } + + / { dg-final { scan-tree-dump-not "\t" "phiprop" } } / + / { dg-final { cleanup-tree-dump "phiprop" } } */ Index: tree-ssa-forwprop.c

*** tree-ssa-forwprop.c (revision 121950) --- tree-ssa-forwprop.c (working copy) *************** struct tree_opt_pass pass_forwprop = { *** 1071,1073 **** --- 1071,1372 ---- | TODO_verify_ssa, /* todo_flags_finish / 0 / letter */ };

+

+


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]