diff options
author | Richard Biener <rguenther@suse.de> | 2015-07-21 14:03:57 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2015-07-21 14:03:57 +0000 |
commit | 2d79964613a139ba588c52c7d6390f5f6745d74e (patch) | |
tree | 9d1fbe883757df7ca019c76a26b10b1a9cb1fa9d /gcc | |
parent | 22be23495a1f0cd1ae6a1aca32c39edb9f7a9c51 (diff) | |
download | gcc-2d79964613a139ba588c52c7d6390f5f6745d74e.zip gcc-2d79964613a139ba588c52c7d6390f5f6745d74e.tar.gz gcc-2d79964613a139ba588c52c7d6390f5f6745d74e.tar.bz2 |
re PR tree-optimization/66948 (Performance regression in bit manipulation code)
2015-07-21 Richard Biener <rguenther@suse.de>
PR tree-optimization/66948
* genmatch.c (capture_info::walk_match): Also recurse to
captures. Properly compute expr state from captures of
captures.
* match.pd: Add single-use guards to
(X & C2) >> C1 into (X >> C1) & (C2 >> C1) transform.
From-SVN: r226041
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/genmatch.c | 25 | ||||
-rw-r--r-- | gcc/match.pd | 2 |
3 files changed, 28 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 69e5bbe..fa9d3ef 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2015-07-21 Richard Biener <rguenther@suse.de> + + PR tree-optimization/66948 + * genmatch.c (capture_info::walk_match): Also recurse to + captures. Properly compute expr state from captures of + captures. + * match.pd: Add single-use guards to + (X & C2) >> C1 into (X >> C1) & (C2 >> C1) transform. + 2015-07-21 Nathan Sidwell <nathan@codesourcery.com> * config/nvptx/mkoffload.c (process): Add static destructor call. diff --git a/gcc/genmatch.c b/gcc/genmatch.c index 1434719..8f1fbcd 100644 --- a/gcc/genmatch.c +++ b/gcc/genmatch.c @@ -1622,17 +1622,28 @@ capture_info::walk_match (operand *o, unsigned toplevel_arg, { if (capture *c = dyn_cast <capture *> (o)) { - info[c->where].toplevel_msk |= 1 << toplevel_arg; - info[c->where].force_no_side_effects_p |= conditional_p; - info[c->where].cond_expr_cond_p |= cond_expr_cond_p; - /* Mark expr (non-leaf) captures and recurse. */ + unsigned where = c->where; + info[where].toplevel_msk |= 1 << toplevel_arg; + info[where].force_no_side_effects_p |= conditional_p; + info[where].cond_expr_cond_p |= cond_expr_cond_p; + if (!c->what) + return; + /* Recurse to exprs and captures. */ + if (is_a <capture *> (c->what) + || is_a <expr *> (c->what)) + walk_match (c->what, toplevel_arg, conditional_p, false); + /* We need to look past multiple captures to find a captured + expression as with conditional converts two captures + can be collapsed onto the same expression. */ + while (c->what && is_a <capture *> (c->what)) + c = as_a <capture *> (c->what); + /* Mark expr (non-leaf) captures and forced single-use exprs. */ expr *e; if (c->what && (e = dyn_cast <expr *> (c->what))) { - info[c->where].expr_p = true; - info[c->where].force_single_use |= e->force_single_use; - walk_match (c->what, toplevel_arg, conditional_p, false); + info[where].expr_p = true; + info[where].force_single_use |= e->force_single_use; } } else if (expr *e = dyn_cast <expr *> (o)) diff --git a/gcc/match.pd b/gcc/match.pd index 4226fb1..9a66f52 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1052,7 +1052,7 @@ along with GCC; see the file COPYING3. If not see (X & C2) >> C1 into (X >> C1) & (C2 >> C1). */ (for shift (lshift rshift) (simplify - (shift (convert? (bit_and @0 INTEGER_CST@2)) INTEGER_CST@1) + (shift (convert?:s (bit_and:s @0 INTEGER_CST@2)) INTEGER_CST@1) (if (tree_nop_conversion_p (type, TREE_TYPE (@0))) (with { tree mask = int_const_binop (shift, fold_convert (type, @2), @1); } (bit_and (shift (convert @0) @1) { mask; }))))) |