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/genmatch.c | |
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/genmatch.c')
-rw-r--r-- | gcc/genmatch.c | 25 |
1 files changed, 18 insertions, 7 deletions
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)) |