Message ID | CAKSNEw4PQKiX_MCtw5Go+K7i=ROjrtOar3dWKvKGYCNLqN75Kg@mail.gmail.com |
---|---|
State | New |
Headers | show |
On Wed, Sep 14, 2011 at 2:01 PM, Ira Rosen <ira.rosen@linaro.org> wrote: > Hi, > > This patch makes data-refs analysis to not fail if simple_iv returns > false in basic block SLP. > > Bootstrapped and tested on powerpc64-suse-linux. > OK for mainline? Ok if you instead of wrapping dr_analyze_innermost change the remaining callers to pass the loop nest parameter instead. Thanks, Richard. > Thanks, > Ira > > ChangeLog: > > * tree-data-ref.c (dr_analyze_innermost): Rename to... > (dr_analyze_innermost_1): ... this. Add new argument. > Allow not simple iv if analyzing basic block. > (dr_analyze_innermost): Call dr_analyze_innermost_1. > (create_data_ref): Call dr_analyze_innermost_1. > > testsuite/ChangeLog: > > * gcc.dg/vect/bb-slp-24.c: New test. > > Index: tree-data-ref.c > =================================================================== > --- tree-data-ref.c (revision 178755) > +++ tree-data-ref.c (working copy) > @@ -722,11 +722,11 @@ canonicalize_base_object_address (tree addr) > } > > /* Analyzes the behavior of the memory reference DR in the innermost loop or > - basic block that contains it. Returns true if analysis succeed or false > + basic block that contains it. Returns true if analysis succeed or false > otherwise. */ > > -bool > -dr_analyze_innermost (struct data_reference *dr) > +static bool > +dr_analyze_innermost_1 (struct data_reference *dr, struct loop *nest) > { > gimple stmt = DR_STMT (dr); > struct loop *loop = loop_containing_stmt (stmt); > @@ -769,14 +769,25 @@ canonicalize_base_object_address (tree addr) > } > else > base = build_fold_addr_expr (base); > + > if (in_loop) > { > if (!simple_iv (loop, loop_containing_stmt (stmt), base, &base_iv, > false)) > { > - if (dump_file && (dump_flags & TDF_DETAILS)) > - fprintf (dump_file, "failed: evolution of base is not affine.\n"); > - return false; > + if (nest) > + { > + if (dump_file && (dump_flags & TDF_DETAILS)) > + fprintf (dump_file, "failed: evolution of base is not" > + " affine.\n"); > + return false; > + } > + else > + { > + base_iv.base = base; > + base_iv.step = ssize_int (0); > + base_iv.no_overflow = true; > + } > } > } > else > @@ -801,10 +812,18 @@ canonicalize_base_object_address (tree addr) > else if (!simple_iv (loop, loop_containing_stmt (stmt), > poffset, &offset_iv, false)) > { > - if (dump_file && (dump_flags & TDF_DETAILS)) > - fprintf (dump_file, "failed: evolution of offset is not" > - " affine.\n"); > - return false; > + if (nest) > + { > + if (dump_file && (dump_flags & TDF_DETAILS)) > + fprintf (dump_file, "failed: evolution of offset is not" > + " affine.\n"); > + return false; > + } > + else > + { > + offset_iv.base = poffset; > + offset_iv.step = ssize_int (0); > + } > } > } > > @@ -832,6 +851,19 @@ canonicalize_base_object_address (tree addr) > return true; > } > > +/* Analyzes the behavior of the memory reference DR in the innermost loop or > + basic block that contains it. Returns true if analysis succeed or false > + otherwise. */ > + > +bool > +dr_analyze_innermost (struct data_reference *dr) > +{ > + gimple stmt = DR_STMT (dr); > + struct loop *loop = loop_containing_stmt (stmt); > + > + return dr_analyze_innermost_1 (dr, loop); > +} > + > /* Determines the base object and the list of indices of memory reference > DR, analyzed in LOOP and instantiated in loop nest NEST. */ > > @@ -972,7 +1004,7 @@ create_data_ref (loop_p nest, loop_p loop, tree me > DR_REF (dr) = memref; > DR_IS_READ (dr) = is_read; > > - dr_analyze_innermost (dr); > + dr_analyze_innermost_1 (dr, nest); > dr_analyze_indices (dr, nest, loop); > dr_analyze_alias (dr); > > Index: testsuite/gcc.dg/vect/bb-slp-24.c > =================================================================== > --- testsuite/gcc.dg/vect/bb-slp-24.c (revision 0) > +++ testsuite/gcc.dg/vect/bb-slp-24.c (revision 0) > @@ -0,0 +1,55 @@ > +/* { dg-require-effective-target vect_int } */ > + > +#include <stdarg.h> > +#include "tree-vect.h" > + > +#define A 3 > +#define N 256 > + > +short src[N], dst[N]; > + > +void foo (short * __restrict dst, short * __restrict src, int h, int stride) > +{ > + int i; > + h /= 8; > + for (i = 0; i < h; i++) { > + dst[0] += A*src[0]; > + dst[1] += A*src[1]; > + dst[2] += A*src[2]; > + dst[3] += A*src[3]; > + dst[4] += A*src[4]; > + dst[5] += A*src[5]; > + dst[6] += A*src[6]; > + dst[7] += A*src[7]; > + dst += stride; > + src += stride; > + } > +} > + > + > +int main (void) > +{ > + int i; > + > + check_vect (); > + > + for (i = 0; i < N; i++) > + { > + dst[i] = 0; > + src[i] = i; > + } > + > + foo (dst, src, N, 8); > + > + for (i = 0; i < N; i++) > + { > + if (dst[i] != A * i) > + abort (); > + } > + > + return 0; > +} > + > +/* { dg-final { scan-tree-dump-times "basic block vectorized using > SLP" 1 "slp" { target vect_element_align } } } */ > +/* { dg-final { cleanup-tree-dump "slp" } } */ > + >
Index: tree-data-ref.c =================================================================== --- tree-data-ref.c (revision 178755) +++ tree-data-ref.c (working copy) @@ -722,11 +722,11 @@ canonicalize_base_object_address (tree addr) } /* Analyzes the behavior of the memory reference DR in the innermost loop or - basic block that contains it. Returns true if analysis succeed or false + basic block that contains it. Returns true if analysis succeed or false otherwise. */ -bool -dr_analyze_innermost (struct data_reference *dr) +static bool +dr_analyze_innermost_1 (struct data_reference *dr, struct loop *nest) { gimple stmt = DR_STMT (dr); struct loop *loop = loop_containing_stmt (stmt); @@ -769,14 +769,25 @@ canonicalize_base_object_address (tree addr) } else base = build_fold_addr_expr (base); + if (in_loop) { if (!simple_iv (loop, loop_containing_stmt (stmt), base, &base_iv, false)) { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "failed: evolution of base is not affine.\n"); - return false; + if (nest) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "failed: evolution of base is not" + " affine.\n"); + return false; + } + else + { + base_iv.base = base; + base_iv.step = ssize_int (0); + base_iv.no_overflow = true; + } } } else @@ -801,10 +812,18 @@ canonicalize_base_object_address (tree addr) else if (!simple_iv (loop, loop_containing_stmt (stmt), poffset, &offset_iv, false)) { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "failed: evolution of offset is not" - " affine.\n"); - return false; + if (nest) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "failed: evolution of offset is not" + " affine.\n"); + return false; + } + else + { + offset_iv.base = poffset; + offset_iv.step = ssize_int (0); + } } } @@ -832,6 +851,19 @@ canonicalize_base_object_address (tree addr) return true; } +/* Analyzes the behavior of the memory reference DR in the innermost loop or + basic block that contains it. Returns true if analysis succeed or false + otherwise. */ + +bool +dr_analyze_innermost (struct data_reference *dr) +{ + gimple stmt = DR_STMT (dr); + struct loop *loop = loop_containing_stmt (stmt); + + return dr_analyze_innermost_1 (dr, loop); +} + /* Determines the base object and the list of indices of memory reference DR, analyzed in LOOP and instantiated in loop nest NEST. */ @@ -972,7 +1004,7 @@ create_data_ref (loop_p nest, loop_p loop, tree me DR_REF (dr) = memref; DR_IS_READ (dr) = is_read; - dr_analyze_innermost (dr); + dr_analyze_innermost_1 (dr, nest); dr_analyze_indices (dr, nest, loop); dr_analyze_alias (dr); Index: testsuite/gcc.dg/vect/bb-slp-24.c =================================================================== --- testsuite/gcc.dg/vect/bb-slp-24.c (revision 0) +++ testsuite/gcc.dg/vect/bb-slp-24.c (revision 0) @@ -0,0 +1,55 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define A 3 +#define N 256 + +short src[N], dst[N]; + +void foo (short * __restrict dst, short * __restrict src, int h, int stride) +{ + int i; + h /= 8; + for (i = 0; i < h; i++) { + dst[0] += A*src[0]; + dst[1] += A*src[1]; + dst[2] += A*src[2]; + dst[3] += A*src[3]; + dst[4] += A*src[4]; + dst[5] += A*src[5]; + dst[6] += A*src[6]; + dst[7] += A*src[7]; + dst += stride; + src += stride; + } +} + + +int main (void) +{ + int i; + + check_vect (); + + for (i = 0; i < N; i++) + { + dst[i] = 0; + src[i] = i; + } + + foo (dst, src, N, 8); + + for (i = 0; i < N; i++) + { + if (dst[i] != A * i) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_element_align } } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */