diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-07-21 14:03:57 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-07-21 14:03:57 +0000 |
commit | 9fe7e117bf462cc501594a04890da0e21d408b5e (patch) | |
tree | 9d1fbe883757df7ca019c76a26b10b1a9cb1fa9d /gcc/genmatch.c | |
parent | 7de5731e9d64cbcc68b697badf74202348767ee5 (diff) | |
download | gcc-9fe7e117bf462cc501594a04890da0e21d408b5e.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@226041 138bc75d-0d04-0410-961f-82ee72b054a4
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 1434719a88e..8f1fbcd47e1 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)) |