This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

More Division optimization using match and simplify


Hi,  

Please find attached the patch that moves some more division optimizations
from fold-const using match and simplify.  

Please review the patch and let me know if any modifications are required.
Hopefully got the converts right this time :-)  

Regression tested the patch on X86 without any issues.  

Thanks, 
Naveen  

ChangeLog

2015-11-17  Naveen H.S  <Naveen.Hurugalawadi@caviumnetworks.com>

	* fold-const.c (fold_binary_loc) : Move Simplify A / (B << N) where A
	and B are positive and B is a power of 2, to A >> (N + log2(B)) 
	to match.pd.
	Move If arg0 is a multiple of arg1, then rewrite to the fastest div
	operation, EXACT_DIV_EXPR to match.pd.

	* match.pd (floor_div (convert? @0) (lshift @1 INTEGER_CST@2)):
	New simplifier.
	(div (convert? @0) (convert? @1)): New simplifier.
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index ce59c48..0c72a75 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -10220,32 +10220,6 @@ fold_binary_loc (location_t loc,
       /* Fall through */
       
     case FLOOR_DIV_EXPR:
-      /* Simplify A / (B << N) where A and B are positive and B is
-	 a power of 2, to A >> (N + log2(B)).  */
-      strict_overflow_p = false;
-      if (TREE_CODE (arg1) == LSHIFT_EXPR
-	  && (TYPE_UNSIGNED (type)
-	      || tree_expr_nonnegative_warnv_p (op0, &strict_overflow_p)))
-	{
-	  tree sval = TREE_OPERAND (arg1, 0);
-	  if (integer_pow2p (sval) && tree_int_cst_sgn (sval) > 0)
-	    {
-	      tree sh_cnt = TREE_OPERAND (arg1, 1);
-	      tree pow2 = build_int_cst (TREE_TYPE (sh_cnt),
-					 wi::exact_log2 (sval));
-
-	      if (strict_overflow_p)
-		fold_overflow_warning (("assuming signed overflow does not "
-					"occur when simplifying A / (B << N)"),
-				       WARN_STRICT_OVERFLOW_MISC);
-
-	      sh_cnt = fold_build2_loc (loc, PLUS_EXPR, TREE_TYPE (sh_cnt),
-					sh_cnt, pow2);
-	      return fold_build2_loc (loc, RSHIFT_EXPR, type,
-				      fold_convert_loc (loc, type, arg0), sh_cnt);
-	    }
-	}
-
       /* Fall through */
 
     case ROUND_DIV_EXPR:
@@ -10287,18 +10261,6 @@ fold_binary_loc (location_t loc,
 						TREE_OPERAND (arg1, 0)));
 	}
 
-      /* If arg0 is a multiple of arg1, then rewrite to the fastest div
-	 operation, EXACT_DIV_EXPR.
-
-	 Note that only CEIL_DIV_EXPR and FLOOR_DIV_EXPR are rewritten now.
-	 At one time others generated faster code, it's not clear if they do
-	 after the last round to changes to the DIV code in expmed.c.  */
-      if ((code == CEIL_DIV_EXPR || code == FLOOR_DIV_EXPR)
-	  && multiple_of_p (type, arg0, arg1))
-	return fold_build2_loc (loc, EXACT_DIV_EXPR, type,
-				fold_convert (type, arg0),
-				fold_convert (type, arg1));
-
       strict_overflow_p = false;
       if (TREE_CODE (arg1) == INTEGER_CST
 	  && 0 != (tem = extract_muldiv (op0, arg1, code, NULL_TREE,
diff --git a/gcc/match.pd b/gcc/match.pd
index d552beb..5ca2778 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -269,6 +269,27 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
    (rshift (convert @0) { build_int_cst (integer_type_node,
 					 wi::exact_log2 (@2)); }))))
 
+/* Simplify A / (B << N) where A and B are positive and B is a power of 2,
+   to A >> (N + log2(B)).  */
+(simplify
+ (floor_div (convert? @0) (lshift @1 INTEGER_CST@2))
+ (if ((TYPE_UNSIGNED (type)
+       || tree_expr_nonnegative_warnv_p (@0, NULL))
+      && integer_pow2p (@1)
+      && tree_int_cst_sgn (@1) > 0
+      && tree_nop_conversion_p (type, TREE_TYPE (@0)))
+  (with
+   { tree pow2 = build_int_cst (TREE_TYPE (@2), wi::exact_log2 (@1));
+     tree temp = const_binop (PLUS_EXPR, TREE_TYPE (@2), @2, pow2); }
+   (rshift (convert @0) { temp; }))))
+
+/* Convert A/B to A/B  */
+(for div (CEIL_DIV_EXPR FLOOR_DIV_EXPR)
+ (simplify
+  (div (convert? @0) (convert? @1))
+  (if (wi::multiple_of_p (@0, @1, TYPE_SIGN (type)))
+   (exact_div (convert @0) (convert @1)))))
+
 /* If ARG1 is a constant, we can convert this to a multiply by the
    reciprocal.  This does not have the same rounding properties,
    so only do this if -freciprocal-math.  We can actually

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]