Commit 2b3493c8 by Andreas Krebbel Committed by Ulrich Weigand

rtl.h (mem_expr_equal_p): Function prototype added.

2004-03-05  Andreas Krebbel  <krebbel1@de.ibm.com>

	* rtl.h (mem_expr_equal_p): Function prototype added.
	* cfgcleanup.c (merge_memattrs): New function.
	(flow_find_cross_jump): Call merge_memattrs for matching insns.
	* emit-rtl.c (mem_expr_equal_p): New function.

2004-03-05  Andreas Krebbel  <krebbel1@de.ibm.com>

	* gcc.dg/20040305-1.c: New test.

From-SVN: r79005
parent 1a4a7065
2004-03-05 Andreas Krebbel <krebbel1@de.ibm.com>
* rtl.h (mem_expr_equal_p): Function prototype added.
* cfgcleanup.c (merge_memattrs): New function.
(flow_find_cross_jump): Call merge_memattrs for matching insns.
* emit-rtl.c (mem_expr_equal_p): New function.
2004-03-05 Ziemowit Laski <zlaski@apple.com>
* objc/objc-act.c (synth_module_prologue): Const-qualify
......
......@@ -49,6 +49,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "tm_p.h"
#include "target.h"
#include "regs.h"
#include "expr.h"
/* cleanup_cfg maintains following flags for each basic block. */
......@@ -87,6 +88,7 @@ static bool mark_effect (rtx, bitmap);
static void notice_new_block (basic_block);
static void update_forwarder_flag (basic_block);
static int mentions_nonequal_regs (rtx *, void *);
static void merge_memattrs (rtx, rtx);
/* Set flags for newly created block. */
......@@ -862,6 +864,88 @@ merge_blocks_move (edge e, basic_block b, basic_block c, int mode)
}
/* Removes the memory attributes of MEM expression
if they are not equal. */
void
merge_memattrs (rtx x, rtx y)
{
int i;
int j;
enum rtx_code code;
const char *fmt;
if (x == y)
return;
if (x == 0 || y == 0)
return;
code = GET_CODE (x);
if (code != GET_CODE (y))
return;
if (GET_MODE (x) != GET_MODE (y))
return;
if (code == MEM && MEM_ATTRS (x) != MEM_ATTRS (y))
{
if (! MEM_ATTRS (x))
MEM_ATTRS (y) = 0;
else if (! MEM_ATTRS (y))
MEM_ATTRS (x) = 0;
else
{
if (MEM_ALIAS_SET (x) != MEM_ALIAS_SET (y))
{
set_mem_alias_set (x, 0);
set_mem_alias_set (y, 0);
}
if (! mem_expr_equal_p (MEM_EXPR (x), MEM_EXPR (y)))
{
set_mem_expr (x, 0);
set_mem_expr (y, 0);
set_mem_offset (x, 0);
set_mem_offset (y, 0);
}
else if (MEM_OFFSET (x) != MEM_OFFSET (y))
{
set_mem_offset (x, 0);
set_mem_offset (y, 0);
}
set_mem_size (x, MAX (MEM_SIZE (x), MEM_SIZE (y)));
set_mem_size (y, MEM_SIZE (x));
set_mem_align (x, MIN (MEM_ALIGN (x), MEM_ALIGN (y)));
set_mem_align (y, MEM_ALIGN (x));
}
}
fmt = GET_RTX_FORMAT (code);
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
switch (fmt[i])
{
case 'E':
/* Two vectors must have the same length. */
if (XVECLEN (x, i) != XVECLEN (y, i))
return;
for (j = 0; j < XVECLEN (x, i); j++)
merge_memattrs (XVECEXP (x, i, j), XVECEXP (y, i, j));
break;
case 'e':
merge_memattrs (XEXP (x, i), XEXP (y, i));
}
}
return;
}
/* Return true if I1 and I2 are equivalent and thus can be crossjumped. */
static bool
......@@ -1022,6 +1106,8 @@ flow_find_cross_jump (int mode ATTRIBUTE_UNUSED, basic_block bb1,
if (!insns_match_p (mode, i1, i2))
break;
merge_memattrs (i1, i2);
/* Don't begin a cross-jump with a NOTE insn. */
if (INSN_P (i1))
{
......
......@@ -1434,6 +1434,40 @@ component_ref_for_mem_expr (tree ref)
TREE_OPERAND (ref, 1));
}
/* Returns 1 if both MEM_EXPR can be considered equal
and 0 otherwise. */
int
mem_expr_equal_p (tree expr1, tree expr2)
{
if (expr1 == expr2)
return 1;
if (! expr1 || ! expr2)
return 0;
if (TREE_CODE (expr1) != TREE_CODE (expr2))
return 0;
if (TREE_CODE (expr1) == COMPONENT_REF)
return
mem_expr_equal_p (TREE_OPERAND (expr1, 0),
TREE_OPERAND (expr2, 0))
&& mem_expr_equal_p (TREE_OPERAND (expr1, 1), /* field decl */
TREE_OPERAND (expr2, 1));
if (TREE_CODE (expr1) == INDIRECT_REF)
return mem_expr_equal_p (TREE_OPERAND (expr1, 0),
TREE_OPERAND (expr2, 0));
/* Decls with different pointers can't be equal. */
if (DECL_P (expr1))
return 0;
abort(); /* ARRAY_REFs, ARRAY_RANGE_REFs and BIT_FIELD_REFs should already
have been resolved here. */
}
/* Given REF, a MEM, and T, either the type of X or the expression
corresponding to REF, set the memory attributes. OBJECTP is nonzero
if we are making a new object of this type. BITPOS is nonzero if
......
......@@ -1569,6 +1569,7 @@ extern void set_reg_attrs_from_mem (rtx, rtx);
extern void set_mem_attrs_from_reg (rtx, rtx);
extern void set_reg_attrs_for_parm (rtx, rtx);
extern void set_reg_pointer_align (rtx, unsigned int);
extern int mem_expr_equal_p (tree, tree);
/* In rtl.c */
extern rtx rtx_alloc_stat (RTX_CODE MEM_STAT_DECL);
......
2004-03-05 Andreas Krebbel <krebbel1@de.ibm.com>
* gcc.dg/20040305-1.c: New test.
2004-03-05 Hans-Peter Nilsson <hp@axis.com>
PR other/14354
......
/* The testcase failed due to corrupted alias information.
During the crossjump analyzing step the mem alias info of the
st instructions are merged and get copied during basic block
reordering which leads to an insn with wrong alias info.
The scheduler afterwards exchanges the mvc and st instructions
not recognizing the anti dependence. */
/* { dg-do run { target s390-*-* } } */
/* { dg-options "-O3 -mtune=z990 -fno-inline" } */
int f;
int g;
int h;
int* x = &f;
int* p1 = &g;
int* p2 = &h;
int
foo(void)
{
if (*x == 0)
{
x = p1; /* mvc - memory to memory */
p1 = (int*)0; /* st - register to memory */
return 1;
}
if (*x == 5)
{
f = 1;
g = 2;
p2 = (int*)0; /* st */
return 1;
}
}
int
main (int argc, char** argv)
{
foo ();
/* If the scheduler has exchanged the mvc and st instructions,
x is 0. The expected result is &g. */
if (x == &g)
exit (0);
else
abort ();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment