SMS: Fix violation of memory dependence

From-SVN: r175090
This commit is contained in:
Revital Eres 2011-06-16 04:03:06 +00:00 committed by Revital Eres
parent c5b7af242c
commit d24dc7b33c
4 changed files with 110 additions and 2 deletions

View 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

View File

@ -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);
}
}
}
}

View 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

View File

@ -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;
}