aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRevital Eres <revital.eres@linaro.org>2011-06-16 04:03:06 +0000
committerRevital Eres <revitale@gcc.gnu.org>2011-06-16 04:03:06 +0000
commitd24dc7b33c9190f8c48cad5b53411c97956c3a59 (patch)
treeb98657e95e8fda46eb6fead6e44a426e08423e4e
parentc5b7af242c0d4bcb7dd0b207202a3a2622321ffb (diff)
downloadgcc-d24dc7b33c9190f8c48cad5b53411c97956c3a59.zip
gcc-d24dc7b33c9190f8c48cad5b53411c97956c3a59.tar.gz
gcc-d24dc7b33c9190f8c48cad5b53411c97956c3a59.tar.bz2
SMS: Fix violation of memory dependence
From-SVN: r175090
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/ddg.c43
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/sms-9.c60
4 files changed, 110 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6ce868b..3bf4c72 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/ddg.c b/gcc/ddg.c
index b8ae375..d06bdbb 100644
--- 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);
+ }
}
}
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6fcd1dc..f8bce24 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..9d1f881
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/sms-9.c
@@ -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;
+}