From: Richard Biener Date: Tue, 21 Jul 2015 14:03:57 +0000 (+0000) Subject: re PR tree-optimization/66948 (Performance regression in bit manipulation code) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2d79964613a139ba588c52c7d6390f5f6745d74e;p=gcc.git re PR tree-optimization/66948 (Performance regression in bit manipulation code) 2015-07-21 Richard Biener 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 69e5bbef35b..fa9d3ef40e8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2015-07-21 Richard Biener + + 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 * config/nvptx/mkoffload.c (process): Add static destructor call. 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 (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 (c->what) + || is_a (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 (c->what)) + c = as_a (c->what); + /* Mark expr (non-leaf) captures and forced single-use exprs. */ expr *e; if (c->what && (e = dyn_cast (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 (o)) diff --git a/gcc/match.pd b/gcc/match.pd index 4226fb16c36..9a66f5274bb 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; })))))