OSDN Git Service

fix temp lifetime (FOR TARGET_EXPRs only)
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 8 Jul 1994 20:45:14 +0000 (20:45 +0000)
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 8 Jul 1994 20:45:14 +0000 (20:45 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@7681 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/expr.c
gcc/expr.h
gcc/function.c

index b9cd009..256f46f 100644 (file)
@@ -95,6 +95,12 @@ int inhibit_defer_pop;
    function calls being expanded by expand_call.  */
 tree cleanups_this_call;
 
+/* When temporaries are created by TARGET_EXPRs, they are created at
+   this level of temp_slot_level, so that they can remain allocated
+   until no longer needed.  CLEANUP_POINT_EXPRs define the lifetime
+   of TARGET_EXPRs.  */
+int target_temp_slot_level;
+
 /* Nonzero means __builtin_saveregs has already been done in this function.
    The value is the pseudoreg containing the value __builtin_saveregs
    returned.  */
@@ -4623,9 +4629,17 @@ expand_expr (exp, target, tmode, modifier)
 
     case CLEANUP_POINT_EXPR:
       {
+       extern int temp_slot_level;
        tree old_cleanups = cleanups_this_call;
+       int old_temp_level = target_temp_slot_level;
+       push_temp_slots ();
+       target_temp_slot_level = temp_slot_level;
        op0 = expand_expr (TREE_OPERAND (exp, 0), target, VOIDmode, modifier);
        expand_cleanups_to (old_cleanups);
+       preserve_temp_slots (op0);
+       free_temp_slots ();
+       pop_temp_slots ();
+       target_temp_slot_level = old_temp_level;
       }
       return op0;
 
@@ -5695,7 +5709,7 @@ expand_expr (exp, target, tmode, modifier)
              }
            else
              {
-               target = assign_stack_temp (mode, int_size_in_bytes (type), 0);
+               target = assign_stack_temp (mode, int_size_in_bytes (type), 2);
                /* All temp slots at this level must not conflict.  */
                preserve_temp_slots (target);
                DECL_RTL (slot) = target;
index 3b3ce5d..3bb9490 100644 (file)
@@ -119,6 +119,12 @@ extern int pending_stack_adjust;
 #ifdef TREE_CODE   /* Don't lose if tree.h not included.  */
 extern tree cleanups_this_call;
 #endif
+
+/* When temporaries are created by TARGET_EXPRs, they are created at
+   this level of temp_slot_level, so that they can remain allocated
+   until no longer needed.  CLEANUP_POINT_EXPRs define the lifetime
+   of TARGET_EXPRs.  */
+extern int target_temp_slot_level;
 \f
 #ifdef TREE_CODE /* Don't lose if tree.h not included.  */
 /* Structure to record the size of a sequence of arguments
index 4b9e33c..16d4a93 100644 (file)
@@ -771,9 +771,10 @@ assign_outer_stack_local (mode, size, align, function)
    SIZE is the size in units of the space required.  We do no rounding here
    since assign_stack_local will do any required rounding.
 
-   KEEP is non-zero if this slot is to be retained after a call to
-   free_temp_slots.  Automatic variables for a block are allocated with this
-   flag.  */
+   KEEP is 1 if this slot is to be retained after a call to
+   free_temp_slots.  Automatic variables for a block are allocated
+   with this flag.  KEEP is 2, if we allocate a longer term temporary,
+   whose lifetime is controlled by CLEANUP_POINT_EXPRs.  */
 
 rtx
 assign_stack_temp (mode, size, keep)
@@ -845,8 +846,16 @@ assign_stack_temp (mode, size, keep)
 
   p->in_use = 1;
   p->rtl_expr = sequence_rtl_expr;
-  p->level = temp_slot_level;
-  p->keep = keep;
+  if (keep == 2)
+    {
+      p->level = target_temp_slot_level;
+      p->keep = 0;
+    }
+  else
+    {
+      p->level = temp_slot_level;
+      p->keep = keep;
+    }
   return p->slot;
 }
 
@@ -4615,6 +4624,7 @@ init_function_start (subr, filename, line)
   /* We have not allocated any temporaries yet.  */
   temp_slots = 0;
   temp_slot_level = 0;
+  target_temp_slot_level = 0;
 
   /* Within function body, compute a type's size as soon it is laid out.  */
   immediate_size_expand++;