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]

Division Optimization in match and simplify


Hi,

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

Please review the patch and let me know if any modifications are required.

Regression tested the patch on X86 without any issues.

Thanks,
Naveen

ChangeLog

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

        * fold-const.c (fold_binary_loc) : Move Convert A/B/C to A/(B*C)
	to match.pd.
        Move Convert A/(B/C) to (A/B)*C to match.pd.
        Move Convert C1/(X*C2) into (C1/C2)/X to match.pd.
        Move Optimize (X & (-A)) / A where A is a power of 2, to
	X >> log2(A) to match.pd.
        
        * match.pd (rdiv (convert? (rdiv @0 @1)) (convert? @2)):
	New simplifier.
	(rdiv (convert? @0) (convert? (rdiv @1 @2))): New simplifier.
	(trunc_div (bit_and (convert? @0) @1) INTEGER_CST@2): New simplifier.
	(rdiv (REAL_CST@0) (mult (convert? @1) REAL_CST@2)): New simplifier.

diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index ee9b349..88dbbdd 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -10163,54 +10163,9 @@ fold_binary_loc (location_t loc,
 	return fold_build2_loc (loc, RDIV_EXPR, type,
 			    negate_expr (arg0),
 			    TREE_OPERAND (arg1, 0));
-
-      /* Convert A/B/C to A/(B*C).  */
-      if (flag_reciprocal_math
-	  && TREE_CODE (arg0) == RDIV_EXPR)
-	return fold_build2_loc (loc, RDIV_EXPR, type, TREE_OPERAND (arg0, 0),
-			    fold_build2_loc (loc, MULT_EXPR, type,
-					 TREE_OPERAND (arg0, 1), arg1));
-
-      /* Convert A/(B/C) to (A/B)*C.  */
-      if (flag_reciprocal_math
-	  && TREE_CODE (arg1) == RDIV_EXPR)
-	return fold_build2_loc (loc, MULT_EXPR, type,
-			    fold_build2_loc (loc, RDIV_EXPR, type, arg0,
-					 TREE_OPERAND (arg1, 0)),
-			    TREE_OPERAND (arg1, 1));
-
-      /* Convert C1/(X*C2) into (C1/C2)/X.  */
-      if (flag_reciprocal_math
-	  && TREE_CODE (arg1) == MULT_EXPR
-	  && TREE_CODE (arg0) == REAL_CST
-	  && TREE_CODE (TREE_OPERAND (arg1, 1)) == REAL_CST)
-	{
-	  tree tem = const_binop (RDIV_EXPR, arg0,
-				  TREE_OPERAND (arg1, 1));
-	  if (tem)
-	    return fold_build2_loc (loc, RDIV_EXPR, type, tem,
-				TREE_OPERAND (arg1, 0));
-	}
-
       return NULL_TREE;
 
     case TRUNC_DIV_EXPR:
-      /* Optimize (X & (-A)) / A where A is a power of 2,
-	 to X >> log2(A) */
-      if (TREE_CODE (arg0) == BIT_AND_EXPR
-	  && !TYPE_UNSIGNED (type) && TREE_CODE (arg1) == INTEGER_CST
-	  && integer_pow2p (arg1) && tree_int_cst_sgn (arg1) > 0)
-	{
-	  tree sum = fold_binary_loc (loc, PLUS_EXPR, TREE_TYPE (arg1),
-				      arg1, TREE_OPERAND (arg0, 1));
-	  if (sum && integer_zerop (sum)) {
-	    tree pow2 = build_int_cst (integer_type_node,
-				       wi::exact_log2 (arg1));
-	    return fold_build2_loc (loc, RSHIFT_EXPR, type,
-				    TREE_OPERAND (arg0, 0), pow2);
-	  }
-	}
-
       /* Fall through */
       
     case FLOOR_DIV_EXPR:
diff --git a/gcc/match.pd b/gcc/match.pd
index f6c5c07..04f384c 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -247,6 +247,34 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (if (!HONOR_SNANS (type))
   (negate @0)))
 
+/* Convert (A/B)/C to A/(B*C)  */
+(simplify
+ (rdiv (convert? (rdiv @0 @1)) (convert? @2))
+  (if (flag_reciprocal_math
+       && tree_nop_conversion_p (type, TREE_TYPE (@0))
+       && tree_nop_conversion_p (type, TREE_TYPE (@2)))
+   (rdiv (convert @0) (convert (mult @1 @2)))))
+
+/* Convert A/(B/C) to (A/B)*C  */
+(simplify
+ (rdiv (convert? @0) (convert? (rdiv @1 @2)))
+  (if (flag_reciprocal_math
+       && tree_nop_conversion_p (type, TREE_TYPE (@0))
+       && tree_nop_conversion_p (type, TREE_TYPE (@2)))
+   (mult (convert (rdiv @0 @1)) (convert @2))))
+
+/* Optimize (X & (-A)) / A where A is a power of 2, to X >> log2(A) */
+(simplify
+ (trunc_div (bit_and (convert? @0) @1) INTEGER_CST@2)
+ (if (!TYPE_UNSIGNED (type) && integer_pow2p (@2)
+      && tree_int_cst_sgn (@2) > 0
+      && tree_nop_conversion_p (type, TREE_TYPE (@0)))
+  (with
+   { tree sum = fold_binary (PLUS_EXPR, TREE_TYPE (@2), @2, @1); }
+   (if (sum && integer_zerop (sum))
+    (rshift (convert @0) { build_int_cst (integer_type_node,
+					  wi::exact_log2 (@2)); })))))
+
 /* 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
@@ -464,6 +492,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
     (if (tem)
      (rdiv { tem; } @1)))))
 
+/* Convert C1/(X*C2) into (C1/C2)/X  */
+(simplify
+ (rdiv (REAL_CST@0) (mult (convert? @1) REAL_CST@2))
+  (if (flag_reciprocal_math)
+   (with
+    { tree tem = const_binop (RDIV_EXPR, type, @0, @2); }
+    (if (tem && tree_nop_conversion_p (type, TREE_TYPE (@1)))
+     (rdiv { tem; } @1)))))
+
 /* Simplify ~X & X as zero.  */
 (simplify
  (bit_and:c (convert? @0) (convert? (bit_not @0)))

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