alias.c (get_alias_set): Try to replace PLACEHOLDER_EXPR.

* 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.

From-SVN: r45931
This commit is contained in:
Richard Kenner 2001-10-01 23:22:24 +00:00 committed by Richard Kenner
parent 477946a63d
commit f47e9b4ebf
5 changed files with 138 additions and 87 deletions

View File

@ -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

View File

@ -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 ();

View File

@ -1716,12 +1716,10 @@ 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),

View File

@ -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);

View File

@ -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. */