+2016-07-28 Yuri Rumyantsev <ysrumyan@gmail.com>
+
+ PR tree-optimization/71734
+ * tree-ssa-loop-im.c (ref_indep_loop_p_1): Pass value of safelen
+ attribute instead of REF_LOOP and use it.
+ (ref_indep_loop_p_2): Use SAFELEN argument instead of REF_LOOP and
+ set it for Loops having non-zero safelen attribute.
+ (ref_indep_loop_p): Pass zero as initial value for safelen.
+
2016-07-28 Ilya Enkovich <ilya.enkovich@intel.com>
PR middle-end/72657
--- /dev/null
+// { dg-do compile }
+// { dg-additional-options "-ffast-math -fopenmp-simd" }
+// { dg-additional-options "-msse2" { target x86_64-*-* i?86-*-* } }
+
+inline void* my_alloc (__SIZE_TYPE__ bytes) {void *ptr; __builtin_posix_memalign (&ptr, bytes, 128);}
+inline void my_free (void* memory) {__builtin_free (memory);}
+float W[100];
+
+template <typename T>
+class Vec
+{
+ const int isize;
+ T* data;
+
+public:
+
+ Vec (int n) : isize (n) {data = (T*)my_alloc (isize*sizeof (T));}
+ ~Vec () {my_free(data);}
+
+ Vec& operator = (const Vec& other)
+ {
+ if (this != &other)
+ __builtin_memcpy (data, other.data, isize*sizeof (T));
+ return *this;
+ }
+
+ T& operator [] (int i) {return data[i];}
+ const T& operator [] (int i) const {return data[i];}
+ T& at (int i) {return data[i];}
+ const T& at (int i) const {return data[i];}
+
+ operator T* () {return data;}
+ int size () const {return isize;}
+};
+
+template <typename T>
+class Cl
+{
+public:
+
+ Cl (int n, int m);
+ const int N, M;
+ Vec<T> v_x, v_y;
+ Vec<int> v_i;
+ Vec<float> v_z;
+};
+
+struct Ss
+{
+ const int S_n, S_m;
+ Cl<float> v1;
+ float* C1;
+ float* C2;
+ Ss (int n1, int n2): S_n(n1), S_m(n2), v1(n1, n2)
+ {
+ C1 = new float[n1 * 3];
+ C2 = new float[n2 * 4];
+ }
+
+ ~Ss () { delete C1; delete C2;}
+ void foo (int n);
+};
+void Ss::foo (int n)
+{
+ float w;
+ for (int j = 0; j < n; j++)
+ {
+ w = W[j];
+#pragma omp simd
+ for (int i = 0; i < S_n; i++)
+ {
+ float w1 = C2[S_n + i] * w;
+ v1.v_i[i] += (int)w1;
+ C1[S_n + i] += w1;
+ }
+ }
+}
+
+// { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target x86_64-*-* i?86-*-* } } }
references in LOOP. */
static bool
-ref_indep_loop_p_1 (struct loop *ref_loop, struct loop *loop,
+ref_indep_loop_p_1 (int safelen, struct loop *loop,
im_mem_ref *ref, bool stored_p)
{
bitmap refs_to_check;
if (bitmap_bit_p (refs_to_check, UNANALYZABLE_MEM_ID))
return false;
- if (ref_loop->safelen > 1)
+ if (safelen > 1)
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
- fprintf (dump_file,"REF is independent in ref_loop#%d\n",
- ref_loop->num);
+ fprintf (dump_file,"REF is independent due to safelen %d\n",
+ safelen);
print_generic_expr (dump_file, ref->mem.ref, TDF_SLIM);
fprintf (dump_file, "\n");
}
results. */
static bool
-ref_indep_loop_p_2 (struct loop *ref_loop, struct loop *loop,
+ref_indep_loop_p_2 (int safelen, struct loop *loop,
im_mem_ref *ref, bool stored_p)
{
stored_p |= (ref->stored && bitmap_bit_p (ref->stored, loop->num));
if (bitmap_bit_p (&ref->dep_loop, LOOP_DEP_BIT (loop->num, stored_p)))
return false;
+ if (loop->safelen > safelen)
+ safelen = loop->safelen;
+
struct loop *inner = loop->inner;
while (inner)
{
- if (!ref_indep_loop_p_2 (ref_loop, inner, ref, stored_p))
+ if (!ref_indep_loop_p_2 (safelen, inner, ref, stored_p))
return false;
inner = inner->next;
}
- bool indep_p = ref_indep_loop_p_1 (ref_loop, loop, ref, stored_p);
+ bool indep_p = ref_indep_loop_p_1 (safelen, loop, ref, stored_p);
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "Querying dependencies of ref %u in loop %d: %s\n",
{
gcc_checking_assert (MEM_ANALYZABLE (ref));
- return ref_indep_loop_p_2 (loop, loop, ref, false);
+ return ref_indep_loop_p_2 (0, loop, ref, false);
}
/* Returns true if we can perform store motion of REF from LOOP. */