summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/emit-rtl.c20
-rw-r--r--gcc/except.c2
-rw-r--r--gcc/expr.c2
-rw-r--r--gcc/function.c52
-rw-r--r--gcc/function.h7
-rw-r--r--gcc/rtl.h1
-rw-r--r--gcc/stmt.c2
-rw-r--r--gcc/tree.h2
9 files changed, 89 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e71a4c7fd3f..fa779241d56 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2000-03-05 Mark Mitchell <mark@codesourcery.com>
+
+ Revert this patch:
+ 2000-03-04 Mark Mitchell <mark@codesourcery.com>
+
2000-03-04 Thomas Schuster <Thomas.Schuster@gmx.net>
* regmove.c (copy_src_to_dest) Do not create src->dest move
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 6b1b3b78e60..27b837447f0 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -3376,6 +3376,7 @@ start_sequence ()
tem->next = seq_stack;
tem->first = first_insn;
tem->last = last_insn;
+ tem->sequence_rtl_expr = seq_rtl_expr;
seq_stack = tem;
@@ -3383,6 +3384,19 @@ start_sequence ()
last_insn = 0;
}
+/* Similarly, but indicate that this sequence will be placed in T, an
+ RTL_EXPR. See the documentation for start_sequence for more
+ information about how to use this function. */
+
+void
+start_sequence_for_rtl_expr (t)
+ tree t;
+{
+ start_sequence ();
+
+ seq_rtl_expr = t;
+}
+
/* Set up the insn chain starting with FIRST as the current sequence,
saving the previously current one. See the documentation for
start_sequence for more information about how to use this function. */
@@ -3416,6 +3430,7 @@ push_topmost_sequence ()
first_insn = top->first;
last_insn = top->last;
+ seq_rtl_expr = top->sequence_rtl_expr;
}
/* After emitting to the outer-level insn chain, update the outer-level
@@ -3431,6 +3446,7 @@ pop_topmost_sequence ()
top->first = first_insn;
top->last = last_insn;
+ /* ??? Why don't we save seq_rtl_expr here? */
end_sequence ();
}
@@ -3455,6 +3471,7 @@ end_sequence ()
first_insn = tem->first;
last_insn = tem->last;
+ seq_rtl_expr = tem->sequence_rtl_expr;
seq_stack = tem->next;
free (tem);
@@ -3743,6 +3760,7 @@ init_emit ()
f->emit = (struct emit_status *) xmalloc (sizeof (struct emit_status));
first_insn = NULL;
last_insn = NULL;
+ seq_rtl_expr = NULL;
cur_insn_uid = 1;
reg_rtx_no = LAST_VIRTUAL_REGISTER + 1;
last_linenum = 0;
@@ -3816,6 +3834,7 @@ mark_sequence_stack (ss)
while (ss)
{
ggc_mark_rtx (ss->first);
+ ggc_mark_tree (ss->sequence_rtl_expr);
ss = ss->next;
}
}
@@ -3837,6 +3856,7 @@ mark_emit_status (es)
ggc_mark_rtx (*r);
mark_sequence_stack (es->sequence_stack);
+ ggc_mark_tree (es->sequence_rtl_expr);
ggc_mark_rtx (es->x_first_insn);
}
diff --git a/gcc/except.c b/gcc/except.c
index c04e73479d3..0a563b49592 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -2095,7 +2095,7 @@ protect_with_terminate (e)
TREE_TYPE (handler) = void_type_node;
RTL_EXPR_RTL (handler) = const0_rtx;
TREE_SIDE_EFFECTS (handler) = 1;
- start_sequence ();
+ start_sequence_for_rtl_expr (handler);
emit_library_call (terminate_libfunc, 0, VOIDmode, 0);
emit_barrier ();
diff --git a/gcc/expr.c b/gcc/expr.c
index 544176c652a..fb266e27226 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -6306,6 +6306,8 @@ expand_expr (exp, target, tmode, modifier)
emit_insns (RTL_EXPR_SEQUENCE (exp));
RTL_EXPR_SEQUENCE (exp) = const0_rtx;
}
+ preserve_rtl_expr_result (RTL_EXPR_RTL (exp));
+ free_temps_for_rtl_expr (exp);
return RTL_EXPR_RTL (exp);
case CONSTRUCTOR:
diff --git a/gcc/function.c b/gcc/function.c
index df5d2477a4f..78c5ab85ef1 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -708,6 +708,7 @@ assign_stack_temp_for_type (mode, size, keep, type)
rounded_size));
p->align = best_p->align;
p->address = 0;
+ p->rtl_expr = 0;
p->next = temp_slots;
temp_slots = p;
@@ -775,6 +776,7 @@ assign_stack_temp_for_type (mode, size, keep, type)
p->in_use = 1;
p->addr_taken = 0;
+ p->rtl_expr = seq_rtl_expr;
if (keep == 2)
{
@@ -1127,6 +1129,34 @@ preserve_temp_slots (x)
p->level--;
}
+/* X is the result of an RTL_EXPR. If it is a temporary slot associated
+ with that RTL_EXPR, promote it into a temporary slot at the present
+ level so it will not be freed when we free slots made in the
+ RTL_EXPR. */
+
+void
+preserve_rtl_expr_result (x)
+ rtx x;
+{
+ struct temp_slot *p;
+
+ /* If X is not in memory or is at a constant address, it cannot be in
+ a temporary slot. */
+ if (x == 0 || GET_CODE (x) != MEM || CONSTANT_P (XEXP (x, 0)))
+ return;
+
+ /* If we can find a match, move it to our level unless it is already at
+ an upper level. */
+ p = find_temp_slot_from_address (XEXP (x, 0));
+ if (p != 0)
+ {
+ p->level = MIN (p->level, temp_slot_level);
+ p->rtl_expr = 0;
+ }
+
+ return;
+}
+
/* Free all temporaries used so far. This is normally called at the end
of generating code for a statement. Don't free any temporaries
currently in use for an RTL_EXPR that hasn't yet been emitted.
@@ -1140,7 +1170,23 @@ free_temp_slots ()
struct temp_slot *p;
for (p = temp_slots; p; p = p->next)
- if (p->in_use && p->level == temp_slot_level && ! p->keep)
+ if (p->in_use && p->level == temp_slot_level && ! p->keep
+ && p->rtl_expr == 0)
+ p->in_use = 0;
+
+ combine_temp_slots ();
+}
+
+/* Free all temporary slots used in T, an RTL_EXPR node. */
+
+void
+free_temps_for_rtl_expr (t)
+ tree t;
+{
+ struct temp_slot *p;
+
+ for (p = temp_slots; p; p = p->next)
+ if (p->rtl_expr == t)
p->in_use = 0;
combine_temp_slots ();
@@ -1218,7 +1264,7 @@ pop_temp_slots ()
struct temp_slot *p;
for (p = temp_slots; p; p = p->next)
- if (p->in_use && p->level == temp_slot_level)
+ if (p->in_use && p->level == temp_slot_level && p->rtl_expr == 0)
p->in_use = 0;
combine_temp_slots ();
@@ -6934,6 +6980,8 @@ mark_temp_slot (t)
{
ggc_mark_rtx (t->slot);
ggc_mark_rtx (t->address);
+ ggc_mark_tree (t->rtl_expr);
+
t = t->next;
}
}
diff --git a/gcc/function.h b/gcc/function.h
index 510ddcfad8d..9ede7a73d08 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -46,6 +46,7 @@ struct sequence_stack
{
/* First and last insns in the chain of the saved sequence. */
rtx first, last;
+ tree sequence_rtl_expr;
struct sequence_stack *next;
};
@@ -76,6 +77,11 @@ struct emit_status
rtx x_first_insn;
rtx x_last_insn;
+ /* RTL_EXPR within which the current sequence will be placed. Use to
+ prevent reuse of any temporaries within the sequence until after the
+ RTL_EXPR is emitted. */
+ tree sequence_rtl_expr;
+
/* Stack of pending (incomplete) sequences saved by `start_sequence'.
Each element describes one pending sequence.
The main insn-chain is saved in the last element of the chain,
@@ -111,6 +117,7 @@ struct emit_status
/* For backward compatibility... eventually these should all go away. */
#define reg_rtx_no (cfun->emit->x_reg_rtx_no)
+#define seq_rtl_expr (cfun->emit->sequence_rtl_expr)
#define regno_reg_rtx (cfun->emit->x_regno_reg_rtx)
#define seq_stack (cfun->emit->sequence_stack)
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 4ef60db6d6e..c736600b058 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1508,6 +1508,7 @@ extern void reposition_prologue_and_epilogue_notes PARAMS ((rtx));
extern void thread_prologue_and_epilogue_insns PARAMS ((rtx));
extern int prologue_epilogue_contains PARAMS ((rtx));
extern HOST_WIDE_INT get_frame_size PARAMS ((void));
+extern void preserve_rtl_expr_result PARAMS ((rtx));
extern void mark_temp_addr_taken PARAMS ((rtx));
extern void update_temp_slot_address PARAMS ((rtx, rtx));
extern void purge_addressof PARAMS ((rtx));
diff --git a/gcc/stmt.c b/gcc/stmt.c
index d165b83c302..cd5277eb1ae 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -2025,7 +2025,7 @@ expand_start_stmt_expr ()
t = make_node (RTL_EXPR);
resume_momentary (momentary);
do_pending_stack_adjust ();
- start_sequence ();
+ start_sequence_for_rtl_expr (t);
NO_DEFER_POP;
expr_stmts_for_value++;
return t;
diff --git a/gcc/tree.h b/gcc/tree.h
index 4746360cf51..1a827581c6b 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2452,6 +2452,7 @@ extern void preserve_temp_slots PARAMS ((struct rtx_def *));
extern int aggregate_value_p PARAMS ((tree));
extern tree reorder_blocks PARAMS ((tree,
struct rtx_def *));
+extern void free_temps_for_rtl_expr PARAMS ((tree));
extern void instantiate_virtual_regs PARAMS ((tree, struct rtx_def *));
extern void unshare_all_rtl PARAMS ((tree, struct rtx_def *));
extern int max_parm_reg_num PARAMS ((void));
@@ -2485,6 +2486,7 @@ extern struct rtx_def *store_expr PARAMS ((tree, struct rtx_def *,
extern void check_max_integer_computation_mode PARAMS ((tree));
/* In emit-rtl.c */
+extern void start_sequence_for_rtl_expr PARAMS ((tree));
extern struct rtx_def *emit_line_note_after PARAMS ((char *, int,
struct rtx_def *));
extern struct rtx_def *emit_line_note PARAMS ((char *, int));