OSDN Git Service

SMS: Fix violation of memory dependence
authorrevitale <revitale@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 16 Jun 2011 04:03:06 +0000 (04:03 +0000)
committerrevitale <revitale@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 16 Jun 2011 04:03:06 +0000 (04:03 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@175090 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/ddg.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/sms-9.c [new file with mode: 0644]

index 6ce868b..3bf4c72 100644 (file)
@@ -1,3 +1,8 @@
+2011-06-16  Revital Eres  <revital.eres@linaro.org>
+
+       * ddg.c (add_intra_loop_mem_dep): New function.
+       (build_intra_loop_deps): Call it.
+
 2011-05-06  Jeff Law  <law@redhat.com>
 
        * df-problems.c (df_lr_local_compute): Manually CSE
index b8ae375..d06bdbb 100644 (file)
--- a/gcc/ddg.c
+++ b/gcc/ddg.c
@@ -390,6 +390,33 @@ insns_may_alias_p (rtx insn1, rtx insn2)
                         &PATTERN (insn2));
 }
 
+/* Given two nodes, analyze their RTL insns and add intra-loop mem deps
+   to ddg G.  */
+static void
+add_intra_loop_mem_dep (ddg_ptr g, ddg_node_ptr from, ddg_node_ptr to)
+{
+
+  if ((from->cuid == to->cuid)
+      || !insns_may_alias_p (from->insn, to->insn))
+    /* Do not create edge if memory references have disjoint alias sets
+       or 'to' and 'from' are the same instruction.  */
+    return;
+
+  if (mem_write_insn_p (from->insn))
+    {
+      if (mem_read_insn_p (to->insn))
+       create_ddg_dep_no_link (g, from, to,
+                               DEBUG_INSN_P (to->insn)
+                               ? ANTI_DEP : TRUE_DEP, MEM_DEP, 0);
+      else
+       create_ddg_dep_no_link (g, from, to,
+                               DEBUG_INSN_P (to->insn)
+                               ? ANTI_DEP : OUTPUT_DEP, MEM_DEP, 0);
+    }
+  else if (!mem_read_insn_p (to->insn))
+    create_ddg_dep_no_link (g, from, to, ANTI_DEP, MEM_DEP, 0);
+}
+
 /* Given two nodes, analyze their RTL insns and add inter-loop mem deps
    to ddg G.  */
 static void
@@ -477,10 +504,22 @@ build_intra_loop_deps (ddg_ptr g)
              if (DEBUG_INSN_P (j_node->insn))
                continue;
              if (mem_access_insn_p (j_node->insn))
-               /* Don't bother calculating inter-loop dep if an intra-loop dep
-                  already exists.  */
+               {
+                 /* Don't bother calculating inter-loop dep if an intra-loop dep
+                    already exists.  */
                  if (! TEST_BIT (dest_node->successors, j))
                    add_inter_loop_mem_dep (g, dest_node, j_node);
+                 /* If -fmodulo-sched-allow-regmoves
+                    is set certain anti-dep edges are not created.
+                    It might be that these anti-dep edges are on the
+                    path from one memory instruction to another such that
+                    removing these edges could cause a violation of the
+                    memory dependencies.  Thus we add intra edges between
+                    every two memory instructions in this case.  */
+                 if (flag_modulo_sched_allow_regmoves
+                     && !TEST_BIT (dest_node->predecessors, j))
+                   add_intra_loop_mem_dep (g, j_node, dest_node);
+               }
             }
         }
     }
index 6fcd1dc..f8bce24 100644 (file)
@@ -1,3 +1,7 @@
+2011-06-16  Revital Eres  <revital.eres@linaro.org>
+
+       * gcc.dg/sms-9.c: New file.
+
 2011-06-15  Easwaran Raman  <eraman@google.com>
 
        PR rtl-optimization/49414
diff --git a/gcc/testsuite/gcc.dg/sms-9.c b/gcc/testsuite/gcc.dg/sms-9.c
new file mode 100644 (file)
index 0000000..9d1f881
--- /dev/null
@@ -0,0 +1,60 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fmodulo-sched -fno-auto-inc-dec -O2 -fmodulo-sched-allow-regmoves" } */
+
+#include <stdlib.h>
+#include <stdarg.h>
+
+struct df_ref_info
+{
+  unsigned int *begin;
+  unsigned int *count;
+};
+
+extern void *memset (void *s, int c, __SIZE_TYPE__ n);
+
+
+__attribute__ ((noinline))
+int
+df_reorganize_refs_by_reg_by_insn (struct df_ref_info *ref_info,
+                                  int num, unsigned int start)
+{
+  unsigned int m = num;
+  unsigned int offset = 77;
+  unsigned int r;
+
+  for (r = start; r < m; r++)
+    {
+      ref_info->begin[r] = offset;
+      offset += ref_info->count[r];
+      ref_info->count[r] = 0;
+    }
+
+  return offset;
+}
+
+int
+main ()
+{
+  struct df_ref_info temp;
+  int num = 100;
+  unsigned int start = 5;
+  int i, offset;
+
+  temp.begin = malloc (100 * sizeof (unsigned int));
+  temp.count = malloc (100 * sizeof (unsigned int));
+
+  memset (temp.begin, 0, sizeof (unsigned int) * num);
+  memset (temp.count, 0, sizeof (unsigned int) * num);
+
+  for (i = 0; i < num; i++)
+    temp.count[i] = i + 1;
+
+  offset = df_reorganize_refs_by_reg_by_insn (&temp, num, start);
+
+  if (offset != 5112)
+    abort ();
+
+  free (temp.begin);
+  free (temp.count);
+  return 0;
+}