OSDN Git Service

* expr.c (clear_storage): Don't use emit_move_insn unless
authorkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 1 Sep 2000 15:10:52 +0000 (15:10 +0000)
committerkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 1 Sep 2000 15:10:52 +0000 (15:10 +0000)
either BLKmode or proper size.
(store_constructor): Don't call clear_storage if REG of wrong size.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@36101 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/expr.c

index a395190..3c62375 100644 (file)
@@ -1,5 +1,9 @@
 Fri Sep  1 10:59:47 2000  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
 
+       * expr.c (clear_storage): Don't use emit_move_insn unless
+       either BLKmode or proper size.
+       (store_constructor): Don't call clear_storage if REG of wrong size.
+
        * flow.c (init_propagate_block_info): Don't mark frame dead at end
        of function if returns wiht stack pointer depressed.
 
index 341586a..9c4237b 100644 (file)
@@ -2392,7 +2392,13 @@ clear_storage (object, size, align)
 #endif
   rtx retval = 0;
 
-  if (GET_MODE (object) == BLKmode)
+  /* If OBJECT is not BLKmode and SIZE is the same size as its mode,
+     just move a zero.  Otherwise, do this a piece at a time.  */
+  if (GET_MODE (object) != BLKmode
+      && GET_CODE (size) == CONST_INT
+      && GET_MODE_SIZE (GET_MODE (object)) == INTVAL (size))
+    emit_move_insn (object, CONST0_RTX (GET_MODE (object)));
+  else
     {
       object = protect_from_queue (object, 1);
       size = protect_from_queue (size, 0);
@@ -2544,8 +2550,6 @@ clear_storage (object, size, align)
 #endif
        }
     }
-  else
-    emit_move_insn (object, CONST0_RTX (GET_MODE (object)));
 
   return retval;
 }
@@ -4263,11 +4267,15 @@ store_constructor (exp, target, align, cleared, size)
 
       /* If the constructor has fewer fields than the structure
         or if we are initializing the structure to mostly zeros,
-        clear the whole structure first.  */
+        clear the whole structure first.  Don't do this is TARGET is
+        register whose mode size isn't equal to SIZE since clear_storage
+        can't handle this case.  */
       else if (size > 0
               && ((list_length (CONSTRUCTOR_ELTS (exp))
                    != fields_length (type))
-                  || mostly_zeros_p (exp)))
+                  || mostly_zeros_p (exp))
+              && (GET_CODE (target) != REG
+                  || GET_MODE_SIZE (GET_MODE (target)) == size))
        {
          if (! cleared)
            clear_storage (target, GEN_INT (size), align);