re PR tree-optimization/66948 (Performance regression in bit manipulation code)
authorRichard Biener <rguenther@suse.de>
Tue, 21 Jul 2015 14:03:57 +0000 (14:03 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 21 Jul 2015 14:03:57 +0000 (14:03 +0000)
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

gcc/ChangeLog
gcc/genmatch.c
gcc/match.pd

index 69e5bbef35b5b57a8a6f812199bb1de8b11e3ac8..fa9d3ef40e8beefe4f221aa977b944dc384ef499 100644 (file)
@@ -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.
index 1434719a88ed023047e5180d4ce3e60459938081..8f1fbcd47e14277f7d1135bd6fac4ca673994260 100644 (file)
@@ -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))
index 4226fb16c366f039f519f6f89323aac8fce3b275..9a66f5274bb6316ded3f9afece86a7566797c4a0 100644 (file)
@@ -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; })))))