return 0;
}
- /* For non-addressable fields we return the alias set of the
- outermost object that could have its address taken. If this
- is an SFT use the precomputed value. */
- if (TREE_CODE (t) == STRUCT_FIELD_TAG
- && SFT_NONADDRESSABLE_P (t))
- return SFT_ALIAS_SET (t);
-
/* Otherwise, pick up the outermost object that we could have a pointer
to, processing conversions as above. */
while (component_uses_parent_alias_set (t))
else if (TREE_CODE (t) == VECTOR_TYPE)
set = get_alias_set (TREE_TYPE (t));
+ /* Unless the language specifies otherwise, treat array types the
+ same as their components. This avoids the asymmetry we get
+ through recording the components. Consider accessing a
+ character(kind=1) through a reference to a character(kind=1)[1:1].
+ Or consider if we want to assign integer(kind=4)[0:D.1387] and
+ integer(kind=4)[4] the same alias set or not.
+ Just be pragmatic here and make sure the array and its element
+ type get the same alias set assigned. */
+ else if (TREE_CODE (t) == ARRAY_TYPE
+ && !TYPE_NONALIASED_COMPONENT (t))
+ set = get_alias_set (TREE_TYPE (t));
+
else
/* Otherwise make a new alias set for this type. */
set = new_alias_set ();
{
/* Create an entry for the SUPERSET, so that we have a place to
attach the SUBSET. */
- superset_entry = ggc_alloc (sizeof (struct alias_set_entry));
+ superset_entry = GGC_NEW (struct alias_set_entry);
superset_entry->alias_set = superset;
superset_entry->children
= splay_tree_new_ggc (splay_tree_compare_ints);
switch (TREE_CODE (type))
{
- case ARRAY_TYPE:
- if (!TYPE_NONALIASED_COMPONENT (type))
- record_alias_subset (superset, get_alias_set (TREE_TYPE (type)));
- break;
-
case RECORD_TYPE:
case UNION_TYPE:
case QUAL_UNION_TYPE:
record_alias_subset (superset, get_alias_set (TREE_TYPE (type)));
break;
+ /* VECTOR_TYPE and ARRAY_TYPE share the alias set with their
+ element type. */
+
default:
break;
}
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;
timevar_push (TV_ALIAS_ANALYSIS);
reg_known_value_size = maxreg - FIRST_PSEUDO_REGISTER;
- reg_known_value = ggc_calloc (reg_known_value_size, sizeof (rtx));
- reg_known_equiv_p = xcalloc (reg_known_value_size, sizeof (bool));
+ reg_known_value = GGC_CNEWVEC (rtx, reg_known_value_size);
+ reg_known_equiv_p = XCNEWVEC (bool, reg_known_value_size);
/* If we have memory allocated from the previous run, use it. */
if (old_reg_base_value)