Commit 19cf3a36 by Jackson Woodruff Committed by Wilco Dijkstra

Factor out division by squares

This patch implements the some of the division optimizations discussed in
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71026.

The division reciprocal optimization now handles divisions by squares:

     x / (y * y) -> x  * (1 / y) * (1 / y)

This requires at least one more division by y before it triggers - the
3 divisions of (1/ y) are then CSEd into a single division.  Overall
this changes 1 division into 1 multiply, which is generally much faster.


2017-11-24  Jackson Woodruff  <jackson.woodruff@arm.com>

    gcc/
	PR tree-optimization/71026
	* tree-ssa-math-opts (is_division_by_square, is_square_of): New.
	(insert_reciprocals): Change to insert reciprocals before a division
	by a square and to insert the square of a reciprocal.
	(execute_cse_reciprocals_1): Change to consider division by a square.
	(register_division_in): Add importance parameter.

    testsuite/
	PR tree-optimization/71026
	* gfortran.dg/extract_recip_1.f: New test.
	* gcc.dg/extract_recip_3.c: New test.
	* gcc.dg/extract_recip_4.c: New test.

From-SVN: r255141
parent 15b6695a
2017-11-24 Jackson Woodruff <jackson.woodruff@arm.com>
PR tree-optimization/71026
* tree-ssa-math-opts (is_division_by_square, is_square_of): New.
(insert_reciprocals): Change to insert reciprocals before a division
by a square and to insert the square of a reciprocal.
(execute_cse_reciprocals_1): Change to consider division by a square.
(register_division_in): Add importance parameter.
2017-11-24 Richard Biener <rguenther@suse.de> 2017-11-24 Richard Biener <rguenther@suse.de>
PR tree-optimization/82402 PR tree-optimization/82402
2017-11-24 Jackson Woodruff <jackson.woodruff@arm.com>
PR tree-optimization/71026
* gfortran.dg/extract_recip_1.f: New test.
* gcc.dg/extract_recip_3.c: New test.
* gcc.dg/extract_recip_4.c: New test.
2017-11-24 Richard Biener <rguenther@suse.de> 2017-11-24 Richard Biener <rguenther@suse.de>
PR tree-optimization/82402 PR tree-optimization/82402
......
/* { dg-do compile } */
/* { dg-options "-Ofast -fdump-tree-optimized-raw" } */
float
extract_square (float *a, float *b, float x, float y)
{
*a = 3 / (y * y);
*b = 5 / (y * y);
return x / (y * y);
}
/* Don't expect the 'powmult' (calculation of y * y)
to be deleted until a later pass, so look for one
more multiplication than strictly necessary. */
float
extract_recip (float *a, float *b, float x, float y, float z)
{
*a = 7 / y;
*b = x / (y * y);
return z / y;
}
/* 4 multiplications in 'extract_square', and 4 in 'extract_recip'. */
/* { dg-final { scan-tree-dump-times "mult_expr" 8 "optimized" } } */
/* 1 division in 'extract_square', 1 division in 'extract_recip'. */
/* { dg-final { scan-tree-dump-times "rdiv_expr" 2 "optimized" } } */
/* { dg-do compile } */
/* { dg-options "-Ofast -fdump-tree-optimized-raw" } */
/* Don't expect any of these divisions to be extracted. */
double f (double x, int p)
{
if (p > 0)
{
return 1.0/(x * x);
}
if (p > -1)
{
return x * x * x;
}
return 1.0 /(x);
}
/* Expect a reciprocal to be extracted here. */
double g (double *a, double x, double y)
{
*a = 3 / y;
double k = x / (y * y);
if (y * y == 2.0)
return k + 1 / y;
else
return k - 1 / y;
}
/* Expect 2 divisions in 'f' and 1 in 'g'. */
/* { dg-final { scan-tree-dump-times "rdiv_expr" 3 "optimized" } } */
/* Expect 3 multiplications in 'f' and 4 in 'g'. */
/* { dg-final { scan-tree-dump-times "mult_expr" 7 "optimized" } } */
! { dg-do compile }
! { dg-options "-Ofast -fdump-tree-optimized-raw" }
SUBROUTINE F(N,X,Y,Z,A,B)
DIMENSION X(4,4), Y(4), Z(4)
REAL, INTENT(INOUT) :: A, B
A = 1 / (Y(N)*Y(N))
DO I = 1, NV
X(I, I) = 1 + X(I, I)
ENDDO
Z(1) = B / Y(N)
Z(2) = N / Y(N)
RETURN
END
! { dg-final { scan-tree-dump-times "rdiv_expr" 1 "optimized" } }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment