/* Alias analysis for GNU C
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
- 2007 Free Software Foundation, Inc.
+ 2007, 2008, 2009 Free Software Foundation, Inc.
Contributed by John Carr (jfc@mit.edu).
This file is part of GCC.
static int write_dependence_p (const_rtx, const_rtx, int);
static void memory_modified_1 (rtx, const_rtx, void *);
-static void record_alias_subset (alias_set_type, alias_set_type);
/* Set up all info needed to perform alias analysis on memory references. */
return 0;
}
+static int
+walk_mems_2 (rtx *x, rtx mem)
+{
+ if (MEM_P (*x))
+ {
+ if (alias_sets_conflict_p (MEM_ALIAS_SET(*x), MEM_ALIAS_SET(mem)))
+ return 1;
+
+ return -1;
+ }
+ return 0;
+}
+
+static int
+walk_mems_1 (rtx *x, rtx *pat)
+{
+ if (MEM_P (*x))
+ {
+ /* Visit all MEMs in *PAT and check indepedence. */
+ if (for_each_rtx (pat, (rtx_function) walk_mems_2, *x))
+ /* Indicate that dependence was determined and stop traversal. */
+ return 1;
+
+ return -1;
+ }
+ return 0;
+}
+
+/* Return 1 if two specified instructions have mem expr with conflict alias sets*/
+bool
+insn_alias_sets_conflict_p (rtx insn1, rtx insn2)
+{
+ /* For each pair of MEMs in INSN1 and INSN2 check their independence. */
+ return for_each_rtx (&PATTERN (insn1), (rtx_function) walk_mems_1,
+ &PATTERN (insn2));
+}
+
/* Return 1 if the two specified alias sets will always conflict. */
int
It is illegal for SUPERSET to be zero; everything is implicitly a
subset of alias set zero. */
-static void
+void
record_alias_subset (alias_set_type superset, alias_set_type subset)
{
alias_set_entry superset_entry;
{
unsigned int regno;
+#if defined (FIND_BASE_TERM)
+ /* Try machine-dependent ways to find the base term. */
+ src = FIND_BASE_TERM (src);
+#endif
+
switch (GET_CODE (src))
{
case SYMBOL_REF:
return 0;
/* Fall through. */
case LO_SUM:
+ /* The standard form is (lo_sum reg sym) so look only at the
+ second operand. */
+ return find_base_term (XEXP (x, 1));
case PLUS:
case MINUS:
{
if (rtx_equal_p (x_base, y_base))
return 1;
- /* The base addresses of the read and write are different expressions.
- If they are both symbols and they are not accessed via AND, there is
- no conflict. We can bring knowledge of object alignment into play
- here. For example, on alpha, "char a, b;" can alias one another,
- though "char a; long b;" cannot. */
+ /* The base addresses are different expressions. If they are not accessed
+ via AND, there is no conflict. We can bring knowledge of object
+ alignment into play here. For example, on alpha, "char a, b;" can
+ alias one another, though "char a; long b;" cannot. AND addesses may
+ implicitly alias surrounding objects; i.e. unaligned access in DImode
+ via AND address can alias all surrounding object types except those
+ with aligment 8 or higher. */
+ if (GET_CODE (x) == AND && GET_CODE (y) == AND)
+ return 1;
+ if (GET_CODE (x) == AND
+ && (GET_CODE (XEXP (x, 1)) != CONST_INT
+ || (int) GET_MODE_UNIT_SIZE (y_mode) < -INTVAL (XEXP (x, 1))))
+ return 1;
+ if (GET_CODE (y) == AND
+ && (GET_CODE (XEXP (y, 1)) != CONST_INT
+ || (int) GET_MODE_UNIT_SIZE (x_mode) < -INTVAL (XEXP (y, 1))))
+ return 1;
+
+ /* Differing symbols not accessed via AND never alias. */
if (GET_CODE (x_base) != ADDRESS && GET_CODE (y_base) != ADDRESS)
- {
- if (GET_CODE (x) == AND && GET_CODE (y) == AND)
- return 1;
- if (GET_CODE (x) == AND
- && (GET_CODE (XEXP (x, 1)) != CONST_INT
- || (int) GET_MODE_UNIT_SIZE (y_mode) < -INTVAL (XEXP (x, 1))))
- return 1;
- if (GET_CODE (y) == AND
- && (GET_CODE (XEXP (y, 1)) != CONST_INT
- || (int) GET_MODE_UNIT_SIZE (x_mode) < -INTVAL (XEXP (y, 1))))
- return 1;
- /* Differing symbols never alias. */
- return 0;
- }
+ return 0;
/* If one address is a stack reference there can be no alias:
stack references using different base registers do not alias,
return GEN_INT (ioffset);
}
-/* The function returns nonzero if X is an address containg VALUE. */
-static int
-value_addr_p (rtx x)
-{
- if (GET_CODE (x) == VALUE)
- return 1;
- if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == VALUE)
- return 1;
- return 0;
-}
-
-/* The function returns nonzero if X is a stack address. */
-static int
-stack_addr_p (rtx x)
-{
- if (x == hard_frame_pointer_rtx || x == frame_pointer_rtx
- || x == arg_pointer_rtx || x == stack_pointer_rtx)
- return 1;
- if (GET_CODE (x) == PLUS
- && (XEXP (x, 0) == hard_frame_pointer_rtx
- || XEXP (x, 0) == frame_pointer_rtx
- || XEXP (x, 0) == arg_pointer_rtx
- || XEXP (x, 0) == stack_pointer_rtx)
- && CONSTANT_P (XEXP (x, 1)))
- return 1;
- return 0;
-}
-
/* Return nonzero if we can determine the exprs corresponding to memrefs
X and Y and they do not overlap. */
tree exprx = MEM_EXPR (x), expry = MEM_EXPR (y);
rtx rtlx, rtly;
rtx basex, basey;
- rtx x_addr, y_addr;
rtx moffsetx, moffsety;
HOST_WIDE_INT offsetx = 0, offsety = 0, sizex, sizey, tem;
- if (flag_ira && optimize && reload_completed)
- {
- /* We need this code for IRA because of stack slot sharing. RTL
- in decl can be different than RTL used in insns. It is a
- safe code although it can be conservative sometime. */
- x_addr = canon_rtx (get_addr (XEXP (x, 0)));
- y_addr = canon_rtx (get_addr (XEXP (y, 0)));
-
- if (value_addr_p (x_addr) || value_addr_p (y_addr))
- return 0;
-
- if (stack_addr_p (x_addr) && stack_addr_p (y_addr)
- && memrefs_conflict_p (SIZE_FOR_MODE (y), y_addr,
- SIZE_FOR_MODE (x), x_addr, 0))
- return 0;
- }
-
/* Unless both have exprs, we can't tell anything. */
if (exprx == 0 || expry == 0)
return 0;