aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Kenner <kenner@vlsi1.ultra.nyu.edu>2001-11-21 23:32:03 +0000
committerRichard Kenner <kenner@gcc.gnu.org>2001-11-21 18:32:03 -0500
commitc11c10d87b229fc9bfa4a1e0a5a342e3344f737d (patch)
treec9328a6f72e26ab58f5c08b5f144508cc16878e1
parent2e7d5318fc0902a682ef1a2b1e43df40f7f3de29 (diff)
downloadgcc-c11c10d87b229fc9bfa4a1e0a5a342e3344f737d.zip
gcc-c11c10d87b229fc9bfa4a1e0a5a342e3344f737d.tar.gz
gcc-c11c10d87b229fc9bfa4a1e0a5a342e3344f737d.tar.bz2
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
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/expr.c47
-rw-r--r--gcc/tree.def7
3 files changed, 35 insertions, 25 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6c62584..9b9595f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+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>
* rs6000.md (cmptf_internal1): Replace %$ with $.
diff --git a/gcc/expr.c b/gcc/expr.c
index 0c5429e..9ea2345 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -7542,47 +7542,43 @@ expand_expr (exp, target, tmode, modifier)
/* 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
- can use gen_lowpart. If neither is true, store the operand into
- memory and convert the MEM to the new mode. */
+ can use gen_lowpart. If neither is true, make sure the operand is
+ in memory and convert the MEM to the new mode. */
if (TYPE_MODE (type) == GET_MODE (op0))
;
else if (TYPE_MODE (type) != BLKmode && GET_MODE (op0) != BLKmode
&& GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_WORD
&& GET_MODE_SIZE (GET_MODE (op0)) <= UNITS_PER_WORD)
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));
- enum machine_mode non_blkmode
- = GET_MODE (op0) == BLKmode ? TYPE_MODE (type) : GET_MODE (op0);
- if (CONSTANT_P (op0))
- op0 = validize_mem (force_const_mem (TYPE_MODE (inner_type), op0));
- 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 (TREE_ADDRESSABLE (exp))
+ abort ();
- if (GET_MODE (target) == BLKmode)
- emit_block_move (target, op0,
- expr_size (TREE_OPERAND (exp, 0)));
- else
- emit_move_insn (target, op0);
+ if (target == 0 || GET_MODE (target) != TYPE_MODE (inner_type))
+ target
+ = assign_stack_temp_for_type
+ (TYPE_MODE (inner_type),
+ 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)
{
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))
set_mem_align (op0, MAX (MEM_ALIGN (op0), TYPE_ALIGN (type)));
else if (TYPE_MODE (type) != BLKmode && STRICT_ALIGNMENT
@@ -7595,6 +7591,9 @@ expand_expr (exp, target, tmode, modifier)
temp_size, 0, type);
rtx new_with_op0_mode = copy_rtx (new);
+ if (TREE_ADDRESSABLE (exp))
+ abort ();
+
PUT_MODE (new_with_op0_mode, GET_MODE (op0));
if (GET_MODE (op0) == BLKmode)
emit_block_move (new_with_op0_mode, op0,
diff --git a/gcc/tree.def b/gcc/tree.def
index c4f08cf..39ea31c 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -695,7 +695,12 @@ DEFTREECODE (NON_LVALUE_EXPR, "non_lvalue_expr", '1', 1)
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
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)
/* Represents something we computed once and will use multiple times.