This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] make data dependence analyzer more strict
- From: Sebastian Pop <sebastian dot pop at cri dot ensmp dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 9 May 2005 11:31:55 +0200
- Subject: [patch] make data dependence analyzer more strict
Hi,
Here are some changes that Daniel and Zdenek have asked for:
* tree-data-ref.c (find_data_references_in_loop): Give up when
the body of the loop contains a CALL_EXPR or an ASM_EXPR: they
may embed arbitrary side effects.
Remove the assumption that GIMPLE form contains a single array
access per statement.
When the statement contains virtual operands, fail if it is not
a MODIFY_EXPR.
Bootstrapped on amd64-linux. gcc.dg/tree-ssa/ltrans-5.c, one of the
tests for loop interchanging, is failing now. It contains a call in
the loop that has to be interchanged:
typedef struct rtx_
{
} *rtx;
static rtx regno_save_mem[53][16 / 4 + 1];
extern set_mem_alias_set (rtx, rtx);
int main(void)
{
int i, j;
for (i = 0; i < 53; i++)
for (j = (16 / (0 ? 8 : 4)); j > 0; j--)
if (regno_save_mem[i][j] != 0)
set_mem_alias_set (regno_save_mem[i][j], 0);
}
In order to transform this loop, we have to prove that set_mem_alias_set
does not contain side effects that may change the contents of the array.
I'm proposing to remove this testcase for the moment.
Sebastian
Index: tree-data-ref.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-data-ref.c,v
retrieving revision 2.26
diff -c -3 -p -r2.26 tree-data-ref.c
*** tree-data-ref.c 3 May 2005 12:19:36 -0000 2.26
--- tree-data-ref.c 9 May 2005 09:10:53 -0000
*************** find_data_references_in_loop (struct loo
*** 2232,2268 ****
{
tree stmt = bsi_stmt (bsi);
! if (TREE_CODE (stmt) != MODIFY_EXPR)
! continue;
if (ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
continue;
!
! /* In the GIMPLE representation, a modify expression
! contains a single load or store to memory. */
! if (TREE_CODE (TREE_OPERAND (stmt, 0)) == ARRAY_REF)
! VARRAY_PUSH_GENERIC_PTR
! (*datarefs, analyze_array (stmt, TREE_OPERAND (stmt, 0),
! false));
!
! else if (TREE_CODE (TREE_OPERAND (stmt, 1)) == ARRAY_REF)
! VARRAY_PUSH_GENERIC_PTR
! (*datarefs, analyze_array (stmt, TREE_OPERAND (stmt, 1),
! true));
! else
{
! if (dont_know_node_not_inserted)
! {
! struct data_reference *res;
! res = xmalloc (sizeof (struct data_reference));
! DR_STMT (res) = NULL_TREE;
! DR_REF (res) = NULL_TREE;
! DR_ACCESS_FNS (res) = NULL;
! DR_BASE_NAME (res) = NULL;
! DR_IS_READ (res) = false;
! VARRAY_PUSH_GENERIC_PTR (*datarefs, res);
! dont_know_node_not_inserted = false;
! }
}
/* When there are no defs in the loop, the loop is parallel. */
--- 2232,2276 ----
{
tree stmt = bsi_stmt (bsi);
! /* ASM_EXPR and CALL_EXPR may embed arbitrary side effects. */
! if (dont_know_node_not_inserted
! && (TREE_CODE (stmt) == CALL_EXPR
! || TREE_CODE (stmt) == ASM_EXPR))
! goto insert_dont_know_node;
if (ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
continue;
!
! if (TREE_CODE (stmt) == MODIFY_EXPR)
{
! if (TREE_CODE (TREE_OPERAND (stmt, 0)) == ARRAY_REF)
! VARRAY_PUSH_GENERIC_PTR
! (*datarefs, analyze_array (stmt, TREE_OPERAND (stmt, 0),
! false));
!
! if (TREE_CODE (TREE_OPERAND (stmt, 1)) == ARRAY_REF)
! VARRAY_PUSH_GENERIC_PTR
! (*datarefs, analyze_array (stmt, TREE_OPERAND (stmt, 1),
! true));
!
! if (dont_know_node_not_inserted
! && TREE_CODE (TREE_OPERAND (stmt, 0)) != ARRAY_REF
! && TREE_CODE (TREE_OPERAND (stmt, 1)) != ARRAY_REF)
! goto insert_dont_know_node;
! }
! else if (dont_know_node_not_inserted)
! {
! struct data_reference *res;
!
! insert_dont_know_node:;
! res = xmalloc (sizeof (struct data_reference));
! DR_STMT (res) = NULL_TREE;
! DR_REF (res) = NULL_TREE;
! DR_ACCESS_FNS (res) = NULL;
! DR_BASE_NAME (res) = NULL;
! DR_IS_READ (res) = false;
! VARRAY_PUSH_GENERIC_PTR (*datarefs, res);
! dont_know_node_not_inserted = false;
}
/* When there are no defs in the loop, the loop is parallel. */