From: Revital Eres Date: Thu, 16 Jun 2011 04:03:06 +0000 (+0000) Subject: SMS: Fix violation of memory dependence X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d24dc7b33c9190f8c48cad5b53411c97956c3a59;p=gcc.git SMS: Fix violation of memory dependence From-SVN: r175090 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6ce868bf82b..3bf4c72b03d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2011-06-16 Revital Eres + + * ddg.c (add_intra_loop_mem_dep): New function. + (build_intra_loop_deps): Call it. + 2011-05-06 Jeff Law * df-problems.c (df_lr_local_compute): Manually CSE diff --git a/gcc/ddg.c b/gcc/ddg.c index b8ae375f153..d06bdbb5448 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 6fcd1dc2015..f8bce2443d5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2011-06-16 Revital Eres + + * gcc.dg/sms-9.c: New file. + 2011-06-15 Easwaran Raman 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 00000000000..9d1f8814257 --- /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 +#include + +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; +}