Commit d93d4205 by Mike Stump

fix temp lifetime (FOR TARGET_EXPRs only)

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