summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/alias.c45
-rw-r--r--gcc/emit-rtl.c2
-rw-r--r--gcc/expr.c154
-rw-r--r--gcc/expr.h10
5 files changed, 138 insertions, 87 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8c22804e8a0..1762d1ebcdc 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+Mon Oct 1 19:20:57 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * alias.c (get_alias_set): Try to replace PLACEHOLDER_EXPR.
+ Loop through NOPs, placeholders, and components.
+ Don't go through NOPs if change mode.
+ (record_alias_subset): Do nothing if SUBSET and SET are the same.
+ * emit-rtl.c (set_mem_alias_set): Enable check.
+ * expr.c (find_placeholder): New function.
+ (expand_expr, case PLACEHOLDER_EXPR): Use it.
+ (expand_expr, case COMPONENT_EXPR): Always copy OP0 when we need
+ to modify it and avoid unneeded copies.
+ * expr.h (expand_expr): Always define.
+ (find_placeholder): New declaration.
+
2001-10-01 Stephane Carrez <Stephane.Carrez@worldnet.fr>
* config/m68hc11/m68hc11.md ("add-split"): Fix add split when
diff --git a/gcc/alias.c b/gcc/alias.c
index bf7c5e33e4f..37a8790c2ee 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -470,16 +470,32 @@ get_alias_set (t)
return 0;
/* We can be passed either an expression or a type. This and the
- language-specific routine may make mutually-recursive calls to
- each other to figure out what to do. At each juncture, we see if
- this is a tree that the language may need to handle specially.
- First handle things that aren't types and start by removing nops
- since we care only about the actual object. */
+ language-specific routine may make mutually-recursive calls to each other
+ to figure out what to do. At each juncture, we see if this is a tree
+ that the language may need to handle specially. First handle things that
+ aren't types and start by removing nops since we care only about the
+ actual object. Also replace PLACEHOLDER_EXPRs and pick up the outermost
+ object that we could have a pointer to. */
if (! TYPE_P (t))
{
- while (TREE_CODE (t) == NOP_EXPR || TREE_CODE (t) == CONVERT_EXPR
- || TREE_CODE (t) == NON_LVALUE_EXPR)
- t = TREE_OPERAND (t, 0);
+ /* Remove any NOPs and see what any PLACEHOLD_EXPRs will expand to. */
+ while (((TREE_CODE (t) == NOP_EXPR || TREE_CODE (t) == CONVERT_EXPR)
+ && (TYPE_MODE (TREE_TYPE (t))
+ == TYPE_MODE (TREE_TYPE (TREE_OPERAND (t, 0)))))
+ || TREE_CODE (t) == NON_LVALUE_EXPR
+ || TREE_CODE (t) == PLACEHOLDER_EXPR
+ || (handled_component_p (t) && ! can_address_p (t)))
+ {
+ /* Give the language a chance to do something with this tree
+ before we go inside it. */
+ if ((set = lang_get_alias_set (t)) != -1)
+ return set;
+
+ if (TREE_CODE (t) == PLACEHOLDER_EXPR)
+ t = find_placeholder (t, 0);
+ else
+ t = TREE_OPERAND (t, 0);
+ }
/* Now give the language a chance to do something but record what we
gave it this time. */
@@ -487,15 +503,9 @@ get_alias_set (t)
if ((set = lang_get_alias_set (t)) != -1)
return set;
- /* Now loop the same way as get_inner_reference and get the alias
- set to use. Pick up the outermost object that we could have
- a pointer to. */
- while (handled_component_p (t) && ! can_address_p (t))
- t = TREE_OPERAND (t, 0);
-
+ /* Check for accesses through restrict-qualified pointers. */
if (TREE_CODE (t) == INDIRECT_REF)
{
- /* Check for accesses through restrict-qualified pointers. */
tree decl = find_base_decl (TREE_OPERAND (t, 0));
if (decl && DECL_POINTER_ALIAS_SET_KNOWN_P (decl))
@@ -587,6 +597,11 @@ record_alias_subset (superset, subset)
alias_set_entry superset_entry;
alias_set_entry subset_entry;
+ /* It is possible in complex type situations for both sets to be the same,
+ in which case we can ignore this operation. */
+ if (superset == subset)
+ return;
+
if (superset == 0)
abort ();
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index eeb5128fec9..ea0eef2c29b 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -1716,13 +1716,11 @@ set_mem_alias_set (mem, set)
HOST_WIDE_INT set;
{
/* It would be nice to enable this check, but we can't quite yet. */
-#if 0
#ifdef ENABLE_CHECKING
/* If the new and old alias sets don't conflict, something is wrong. */
if (!alias_sets_conflict_p (set, MEM_ALIAS_SET (mem)))
abort ();
#endif
-#endif
MEM_ATTRS (mem) = get_mem_attrs (set, MEM_DECL (mem), MEM_OFFSET (mem),
MEM_SIZE (mem), MEM_ALIGN (mem));
diff --git a/gcc/expr.c b/gcc/expr.c
index 7d23c7ac824..52f9cc0f2e0 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -5955,6 +5955,69 @@ check_max_integer_computation_mode (exp)
}
#endif
+/* Return an object on the placeholder list that matches EXP, a
+ PLACEHOLDER_EXPR. An object "matches" if it is of the type of the
+ PLACEHOLDER_EXPR or a pointer type to it. For further information,
+ see tree.def. If no such object is found, abort. If PLIST is nonzero,
+ it is a location into which a pointer into the placeholder list at
+ which the object is found is placed. */
+
+tree
+find_placeholder (exp, plist)
+ tree exp;
+ tree *plist;
+{
+ tree type = TREE_TYPE (exp);
+ tree placeholder_expr;
+
+ for (placeholder_expr = placeholder_list; placeholder_expr != 0;
+ placeholder_expr = TREE_CHAIN (placeholder_expr))
+ {
+ tree need_type = TYPE_MAIN_VARIANT (type);
+ tree elt;
+
+ /* Find the outermost reference that is of the type we want. If none,
+ see if any object has a type that is a pointer to the type we
+ want. */
+ for (elt = TREE_PURPOSE (placeholder_expr); elt != 0;
+ elt = ((TREE_CODE (elt) == COMPOUND_EXPR
+ || TREE_CODE (elt) == COND_EXPR)
+ ? TREE_OPERAND (elt, 1)
+ : (TREE_CODE_CLASS (TREE_CODE (elt)) == 'r'
+ || TREE_CODE_CLASS (TREE_CODE (elt)) == '1'
+ || TREE_CODE_CLASS (TREE_CODE (elt)) == '2'
+ || TREE_CODE_CLASS (TREE_CODE (elt)) == 'e')
+ ? TREE_OPERAND (elt, 0) : 0))
+ if (TYPE_MAIN_VARIANT (TREE_TYPE (elt)) == need_type)
+ {
+ if (plist)
+ *plist = placeholder_expr;
+ return elt;
+ }
+
+ for (elt = TREE_PURPOSE (placeholder_expr); elt != 0;
+ elt
+ = ((TREE_CODE (elt) == COMPOUND_EXPR
+ || TREE_CODE (elt) == COND_EXPR)
+ ? TREE_OPERAND (elt, 1)
+ : (TREE_CODE_CLASS (TREE_CODE (elt)) == 'r'
+ || TREE_CODE_CLASS (TREE_CODE (elt)) == '1'
+ || TREE_CODE_CLASS (TREE_CODE (elt)) == '2'
+ || TREE_CODE_CLASS (TREE_CODE (elt)) == 'e')
+ ? TREE_OPERAND (elt, 0) : 0))
+ if (POINTER_TYPE_P (TREE_TYPE (elt))
+ && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (elt)))
+ == need_type))
+ {
+ if (plist)
+ *plist = placeholder_expr;
+ return build1 (INDIRECT_REF, need_type, elt);
+ }
+ }
+
+ abort ();
+}
+
/* expand_expr: generate code for computing expression EXP.
An rtx for the computed value is returned. The value is never null.
In the case of a void EXP, const0_rtx is returned.
@@ -6482,66 +6545,14 @@ expand_expr (exp, target, tmode, modifier)
case PLACEHOLDER_EXPR:
{
+ tree old_list = placeholder_list;
tree placeholder_expr;
- /* If there is an object on the head of the placeholder list,
- see if some object in it of type TYPE or a pointer to it. For
- further information, see tree.def. */
- for (placeholder_expr = placeholder_list;
- placeholder_expr != 0;
- placeholder_expr = TREE_CHAIN (placeholder_expr))
- {
- tree need_type = TYPE_MAIN_VARIANT (type);
- tree object = 0;
- tree old_list = placeholder_list;
- tree elt;
-
- /* Find the outermost reference that is of the type we want.
- If none, see if any object has a type that is a pointer to
- the type we want. */
- for (elt = TREE_PURPOSE (placeholder_expr);
- elt != 0 && object == 0;
- elt
- = ((TREE_CODE (elt) == COMPOUND_EXPR
- || TREE_CODE (elt) == COND_EXPR)
- ? TREE_OPERAND (elt, 1)
- : (TREE_CODE_CLASS (TREE_CODE (elt)) == 'r'
- || TREE_CODE_CLASS (TREE_CODE (elt)) == '1'
- || TREE_CODE_CLASS (TREE_CODE (elt)) == '2'
- || TREE_CODE_CLASS (TREE_CODE (elt)) == 'e')
- ? TREE_OPERAND (elt, 0) : 0))
- if (TYPE_MAIN_VARIANT (TREE_TYPE (elt)) == need_type)
- object = elt;
-
- for (elt = TREE_PURPOSE (placeholder_expr);
- elt != 0 && object == 0;
- elt
- = ((TREE_CODE (elt) == COMPOUND_EXPR
- || TREE_CODE (elt) == COND_EXPR)
- ? TREE_OPERAND (elt, 1)
- : (TREE_CODE_CLASS (TREE_CODE (elt)) == 'r'
- || TREE_CODE_CLASS (TREE_CODE (elt)) == '1'
- || TREE_CODE_CLASS (TREE_CODE (elt)) == '2'
- || TREE_CODE_CLASS (TREE_CODE (elt)) == 'e')
- ? TREE_OPERAND (elt, 0) : 0))
- if (POINTER_TYPE_P (TREE_TYPE (elt))
- && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (elt)))
- == need_type))
- object = build1 (INDIRECT_REF, need_type, elt);
-
- if (object != 0)
- {
- /* Expand this object skipping the list entries before
- it was found in case it is also a PLACEHOLDER_EXPR.
- In that case, we want to translate it using subsequent
- entries. */
- placeholder_list = TREE_CHAIN (placeholder_expr);
- temp = expand_expr (object, original_target, tmode,
- ro_modifier);
- placeholder_list = old_list;
- return temp;
- }
- }
+ exp = find_placeholder (exp, &placeholder_expr);
+ placeholder_list = TREE_CHAIN (placeholder_expr);
+ temp = expand_expr (exp, original_target, tmode, ro_modifier);
+ placeholder_list = old_list;
+ return temp;
}
/* We can't find the object or there was a missing WITH_RECORD_EXPR. */
@@ -6923,6 +6934,7 @@ expand_expr (exp, target, tmode, modifier)
tree tem = get_inner_reference (exp, &bitsize, &bitpos, &offset,
&mode1, &unsignedp, &volatilep,
&alignment);
+ rtx orig_op0;
/* If we got back the original object, something is wrong. Perhaps
we are evaluating an expression too early. In any event, don't
@@ -6934,15 +6946,16 @@ expand_expr (exp, target, tmode, modifier)
computation, since it will need a temporary and TARGET is known
to have to do. This occurs in unchecked conversion in Ada. */
- op0 = expand_expr (tem,
- (TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE
- && (TREE_CODE (TYPE_SIZE (TREE_TYPE (tem)))
- != INTEGER_CST)
- ? target : NULL_RTX),
- VOIDmode,
- (modifier == EXPAND_INITIALIZER
- || modifier == EXPAND_CONST_ADDRESS)
- ? modifier : EXPAND_NORMAL);
+ orig_op0 = op0
+ = expand_expr (tem,
+ (TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE
+ && (TREE_CODE (TYPE_SIZE (TREE_TYPE (tem)))
+ != INTEGER_CST)
+ ? target : NULL_RTX),
+ VOIDmode,
+ (modifier == EXPAND_INITIALIZER
+ || modifier == EXPAND_CONST_ADDRESS)
+ ? modifier : EXPAND_NORMAL);
/* If this is a constant, put it into a register if it is a
legitimate constant and OFFSET is 0 and memory if it isn't. */
@@ -7031,7 +7044,9 @@ expand_expr (exp, target, tmode, modifier)
/* Don't forget about volatility even if this is a bitfield. */
if (GET_CODE (op0) == MEM && volatilep && ! MEM_VOLATILE_P (op0))
{
- op0 = copy_rtx (op0);
+ if (op0 == orig_op0)
+ op0 = copy_rtx (op0);
+
MEM_VOLATILE_P (op0) = 1;
}
@@ -7173,6 +7188,9 @@ expand_expr (exp, target, tmode, modifier)
else
op0 = adjust_address (op0, mode1, bitpos / BITS_PER_UNIT);
+ if (op0 == orig_op0)
+ op0 = copy_rtx (op0);
+
set_mem_attributes (op0, exp, 0);
if (GET_CODE (XEXP (op0, 0)) == REG)
mark_reg_pointer (XEXP (op0, 0), alignment);
diff --git a/gcc/expr.h b/gcc/expr.h
index 9addf7f7326..62e90b0d211 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -498,13 +498,19 @@ extern rtx store_expr PARAMS ((tree, rtx, int));
Useful after calling expand_expr with 1 as sum_ok. */
extern rtx force_operand PARAMS ((rtx, rtx));
-#ifdef TREE_CODE
+/* Return an object on the placeholder list that matches EXP, a
+ PLACEHOLDER_EXPR. An object "matches" if it is of the type of the
+ PLACEHOLDER_EXPR or a pointer type to it. For further information,
+ see tree.def. If no such object is found, abort. If PLIST is nonzero,
+ it is a location into which a pointer into the placeholder list at
+ which the object is found is placed. */
+extern tree find_placeholder PARAMS ((tree, tree *));
+
/* Generate code for computing expression EXP.
An rtx for the computed value is returned. The value is never null.
In the case of a void EXP, const0_rtx is returned. */
extern rtx expand_expr PARAMS ((tree, rtx, enum machine_mode,
enum expand_modifier));
-#endif
/* At the start of a function, record that we have no previously-pushed
arguments waiting to be popped. */