]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
check alias sets in add_inter_loop_mem_dep
authorBingfeng Mei <bmei@broadcom.com>
Wed, 21 Jan 2009 11:39:19 +0000 (11:39 +0000)
committerRevital Eres <revitale@gcc.gnu.org>
Wed, 21 Jan 2009 11:39:19 +0000 (11:39 +0000)
From-SVN: r143540

gcc/ChangeLog
gcc/alias.c
gcc/alias.h
gcc/ddg.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/sms-6.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/sms-7.c [new file with mode: 0644]

index aca8760485e20d4da5e1dca43f7c3a9f92388ee8..35de52a867a196418fc7227ff73f8ee833b60f73 100644 (file)
@@ -1,3 +1,14 @@
+2009-01-21  Bingfeng Mei  <bmei@broadcom.com>
+
+       * alias.c (walk_mems_1, walk_mems_2, insn_alias_sets_conflict_p):
+       Check whether two instructions have memory references that
+       belong to conflicting alias sets.  walk_mems_1 and walk_mems_2
+       are helper functions for traversing.
+       * alias.h (insn_alias_sets_confilict_p): New prototypes.
+       * ddg.c (add_inter_loop_mem_dep): Call insn_alias_sets_conflict_p
+       not to draw dependency edge for instructions with non-conflicting
+       alias sets.
+
 2009-01-20  Joseph Myers  <joseph@codesourcery.com>
 
        PR other/38758
index e5133d6a8c085c3c5db979893b13323f1851a066..18c7d87a52f981bd3b34f2227edf89d43afe47ef 100644 (file)
@@ -344,6 +344,43 @@ alias_sets_conflict_p (alias_set_type set1, alias_set_type set2)
   return 0;
 }
 
+static int
+walk_mems_2 (rtx *x, rtx mem)
+{
+  if (MEM_P (*x))
+    {
+      if (alias_sets_conflict_p (MEM_ALIAS_SET(*x), MEM_ALIAS_SET(mem)))
+        return 1;
+        
+      return -1;  
+    }
+  return 0;
+}
+
+static int
+walk_mems_1 (rtx *x, rtx *pat)
+{
+  if (MEM_P (*x))
+    {
+      /* Visit all MEMs in *PAT and check indepedence.  */
+      if (for_each_rtx (pat, (rtx_function) walk_mems_2, *x))
+        /* Indicate that dependence was determined and stop traversal.  */
+        return 1;
+        
+      return -1;
+    }
+  return 0;
+}
+
+/* Return 1 if two specified instructions have mem expr with conflict alias sets*/
+bool
+insn_alias_sets_conflict_p (rtx insn1, rtx insn2)
+{
+  /* For each pair of MEMs in INSN1 and INSN2 check their independence.  */
+  return  for_each_rtx (&PATTERN (insn1), (rtx_function) walk_mems_1,
+                        &PATTERN (insn2));
+}
+
 /* Return 1 if the two specified alias sets will always conflict.  */
 
 int
index 73811d302b198c05dd9fa4436a5490e49d26fbe5..3492d7ee6ca6a66b827d5650c7b657fe36155fb8 100644 (file)
@@ -41,6 +41,7 @@ extern int alias_sets_conflict_p (alias_set_type, alias_set_type);
 extern int alias_sets_must_conflict_p (alias_set_type, alias_set_type);
 extern int objects_must_conflict_p (tree, tree);
 extern int nonoverlapping_memrefs_p (const_rtx, const_rtx);
+extern bool insn_alias_sets_conflict_p (rtx, rtx);
 
 /* This alias set can be used to force a memory to conflict with all
    other memories, creating a barrier across which no memory reference
index 6ae2ae25b65c1fd1ac2bba01f98df81666852fd8..a0eaaea7d2c3c98b1e1cf5e42e19690e8532f2d4 100644 (file)
--- a/gcc/ddg.c
+++ b/gcc/ddg.c
@@ -345,6 +345,10 @@ build_inter_loop_deps (ddg_ptr g)
 static void
 add_inter_loop_mem_dep (ddg_ptr g, ddg_node_ptr from, ddg_node_ptr to)
 {
+  if (!insn_alias_sets_conflict_p (from->insn, to->insn))
+    /* Do not create edge if memory references have disjoint alias sets.  */
+    return;
+    
   if (mem_write_insn_p (from->insn))
     {
       if (mem_read_insn_p (to->insn))
index 8b2d31da084412c3e32aa0d2f15677939d44e2ee..4bf0f2fc8563886c9bf9c1157cb38e5f163cf32e 100644 (file)
@@ -1,3 +1,8 @@
+2009-01-21  Bingfeng Mei  <bmei@broadcom.com>
+
+       * gcc.dg/sms-6.c: New test.
+       * gcc.dg/sms-7.c: Likewise.
+
 2009-01-20  Paul Thomas  <pault@gcc.gnu.org>
 
        PR fortran/38907
diff --git a/gcc/testsuite/gcc.dg/sms-6.c b/gcc/testsuite/gcc.dg/sms-6.c
new file mode 100644 (file)
index 0000000..3fe8ecd
--- /dev/null
@@ -0,0 +1,40 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fmodulo-sched " } */
+
+extern void abort (void);
+
+void foo (int * __restrict__ a, int * __restrict__ b, int * __restrict__ c)
+{
+   int i;
+   for(i = 0; i < 100; i+=4)
+     {
+       a[i] = b[i] * c[i];
+       a[i+1] = b[i+1] * c[i+1];
+       a[i+2] = b[i+2] * c[i+2];
+       a[i+3] = b[i+3] * c[i+3];
+     }
+}   
+
+
+int a[100], b[100], c[100];
+int main()
+{
+  int i, res;
+  for(i = 0; i < 100; i++)
+    {
+      b[i] = c[i] = i;
+    }  
+  foo(a, b, c);
+  
+  res = 0;  
+  for(i = 0; i < 100; i++)
+    {
+      res += a[i];
+    }
+  if(res != 328350)
+    abort();
+  
+  return 0;        
+}
+
+
diff --git a/gcc/testsuite/gcc.dg/sms-7.c b/gcc/testsuite/gcc.dg/sms-7.c
new file mode 100644 (file)
index 0000000..35f04a5
--- /dev/null
@@ -0,0 +1,41 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fmodulo-sched -fstrict-aliasing " } */
+
+extern void abort (void);
+
+void foo (int *a, short * __restrict__ b, short * __restrict__ c) 
+{
+   int i;
+   for(i = 0; i < 100; i+=4)
+     {
+       a[i] = b[i] * c[i];
+       a[i+1] = b[i+1] * c[i+1];
+       a[i+2] = b[i+2] * c[i+2];
+       a[i+3] = b[i+3] * c[i+3];
+     }
+}   
+
+int a[100];
+short b[100], c[100];
+
+int main()
+{
+  int i, res;
+  for(i = 0; i < 100; i++)
+    {
+      b[i] = c[i] = i;
+    }  
+  foo(a, b, c);
+  
+  res = 0;  
+  for(i = 0; i < 100; i++)
+    {
+      res += a[i];
+    }
+  if(res != 328350)
+    abort();
+  
+  return 0;        
+}
+
+