Commit c11c10d8 by Richard Kenner Committed by Richard Kenner

expr.c (expand_expr, [...]): Refine slightly and also support TREE_ADDRESSABLE.

	* expr.c (expand_expr, case VIEW_CONVERT_EXPR): Refine slightly
	and also support TREE_ADDRESSABLE.
	* tree.def (VIEW_CONVERT_EXPR): Document TREE_ADDRESSABLE.

From-SVN: r47249
parent 2e7d5318
Wed Nov 21 17:37:16 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* expr.c (expand_expr, case VIEW_CONVERT_EXPR): Refine slightly
and also support TREE_ADDRESSABLE.
* tree.def (VIEW_CONVERT_EXPR): Document TREE_ADDRESSABLE.
2001-11-21 David Edelsohn <edelsohn@gnu.org> 2001-11-21 David Edelsohn <edelsohn@gnu.org>
* rs6000.md (cmptf_internal1): Replace %$ with $. * rs6000.md (cmptf_internal1): Replace %$ with $.
......
...@@ -7542,47 +7542,43 @@ expand_expr (exp, target, tmode, modifier) ...@@ -7542,47 +7542,43 @@ expand_expr (exp, target, tmode, modifier)
/* If the input and output modes are both the same, we are done. /* If the input and output modes are both the same, we are done.
Otherwise, if neither mode is BLKmode and both are within a word, we Otherwise, if neither mode is BLKmode and both are within a word, we
can use gen_lowpart. If neither is true, store the operand into can use gen_lowpart. If neither is true, make sure the operand is
memory and convert the MEM to the new mode. */ in memory and convert the MEM to the new mode. */
if (TYPE_MODE (type) == GET_MODE (op0)) if (TYPE_MODE (type) == GET_MODE (op0))
; ;
else if (TYPE_MODE (type) != BLKmode && GET_MODE (op0) != BLKmode else if (TYPE_MODE (type) != BLKmode && GET_MODE (op0) != BLKmode
&& GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_WORD && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_WORD
&& GET_MODE_SIZE (GET_MODE (op0)) <= UNITS_PER_WORD) && GET_MODE_SIZE (GET_MODE (op0)) <= UNITS_PER_WORD)
op0 = gen_lowpart (TYPE_MODE (type), op0); op0 = gen_lowpart (TYPE_MODE (type), op0);
else else if (GET_CODE (op0) != MEM)
{ {
/* If the operand is not a MEM, force it into memory. Since we
are going to be be changing the mode of the MEM, don't call
force_const_mem for constants because we don't allow pool
constants to change mode. */
tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0)); tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
enum machine_mode non_blkmode
= GET_MODE (op0) == BLKmode ? TYPE_MODE (type) : GET_MODE (op0);
if (CONSTANT_P (op0)) if (TREE_ADDRESSABLE (exp))
op0 = validize_mem (force_const_mem (TYPE_MODE (inner_type), op0)); abort ();
else
{
if (target == 0 || GET_MODE (target) != TYPE_MODE (inner_type))
target
= assign_stack_temp_for_type (TYPE_MODE (inner_type),
GET_MODE_SIZE (non_blkmode),
0, inner_type);
if (GET_MODE (target) == BLKmode) if (target == 0 || GET_MODE (target) != TYPE_MODE (inner_type))
emit_block_move (target, op0, target
expr_size (TREE_OPERAND (exp, 0))); = assign_stack_temp_for_type
else (TYPE_MODE (inner_type),
emit_move_insn (target, op0); GET_MODE_SIZE (TYPE_MODE (inner_type)), 0, inner_type);
op0 = target; emit_move_insn (target, op0);
} op0 = target;
} }
/* At this point, OP0 is in the correct mode. If the output type is such
that the operand is known to be aligned, indicate that it is.
Otherwise, we need only be concerned about alignment for non-BLKmode
results. */
if (GET_CODE (op0) == MEM) if (GET_CODE (op0) == MEM)
{ {
op0 = copy_rtx (op0); op0 = copy_rtx (op0);
/* If the output type is such that the operand is known to be
aligned, indicate that it is. Otherwise, we need only be
concerned about alignment for non-BLKmode results. */
if (TYPE_ALIGN_OK (type)) if (TYPE_ALIGN_OK (type))
set_mem_align (op0, MAX (MEM_ALIGN (op0), TYPE_ALIGN (type))); set_mem_align (op0, MAX (MEM_ALIGN (op0), TYPE_ALIGN (type)));
else if (TYPE_MODE (type) != BLKmode && STRICT_ALIGNMENT else if (TYPE_MODE (type) != BLKmode && STRICT_ALIGNMENT
...@@ -7595,6 +7591,9 @@ expand_expr (exp, target, tmode, modifier) ...@@ -7595,6 +7591,9 @@ expand_expr (exp, target, tmode, modifier)
temp_size, 0, type); temp_size, 0, type);
rtx new_with_op0_mode = copy_rtx (new); rtx new_with_op0_mode = copy_rtx (new);
if (TREE_ADDRESSABLE (exp))
abort ();
PUT_MODE (new_with_op0_mode, GET_MODE (op0)); PUT_MODE (new_with_op0_mode, GET_MODE (op0));
if (GET_MODE (op0) == BLKmode) if (GET_MODE (op0) == BLKmode)
emit_block_move (new_with_op0_mode, op0, emit_block_move (new_with_op0_mode, op0,
......
...@@ -695,7 +695,12 @@ DEFTREECODE (NON_LVALUE_EXPR, "non_lvalue_expr", '1', 1) ...@@ -695,7 +695,12 @@ DEFTREECODE (NON_LVALUE_EXPR, "non_lvalue_expr", '1', 1)
This corresponds to an "Unchecked Conversion" in Ada and roughly to This corresponds to an "Unchecked Conversion" in Ada and roughly to
the idiom *(type2 *)&X in C. The only operand is the value to be the idiom *(type2 *)&X in C. The only operand is the value to be
viewed as being of another type. It is undefined if the type of the viewed as being of another type. It is undefined if the type of the
input and of the expression have different sizes. */ input and of the expression have different sizes.
This code may also be used within the LHS of a MODIFY_EXPR, in which
case no actual data motion may occur. TREE_ADDRESSABLE will be set in
this case and GCC must abort if it could not do the operation without
generating insns. */
DEFTREECODE (VIEW_CONVERT_EXPR, "view_convert_expr", '1', 1) DEFTREECODE (VIEW_CONVERT_EXPR, "view_convert_expr", '1', 1)
/* Represents something we computed once and will use multiple times. /* Represents something we computed once and will use multiple times.
......
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