expr.c (expand_expr, [...]): Refine slightly and also support TREE_ADDRESSABLE.
authorRichard Kenner <kenner@vlsi1.ultra.nyu.edu>
Wed, 21 Nov 2001 23:32:03 +0000 (23:32 +0000)
committerRichard Kenner <kenner@gcc.gnu.org>
Wed, 21 Nov 2001 23:32:03 +0000 (18:32 -0500)
* 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

gcc/ChangeLog
gcc/expr.c
gcc/tree.def

index 6c625845cb4a30b852f76fd3cf576a60ec5a08f5..9b9595fb09aa7964ec145634f662890684a32f93 100644 (file)
@@ -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 $.
index 0c5429ec1873180781e8c0a667888a723df9b49b..9ea2345ffa24e0b15952a056ecb717f150f571cc 100644 (file)
@@ -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,
index c4f08cf5f0d2fa426d97232d793b54dd6b63c2d1..39ea31c033bc1f9913dc51ee8c72df6bafb68961 100644 (file)
@@ -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.