aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2000-03-05 20:43:44 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2000-03-05 20:43:44 +0000
commit9f93702662f417705f1fc306ffbd078fef8abe02 (patch)
tree7b9b1d01cf0d4c4508ab5b483e757d3c608c3305 /gcc
parent591ccf92b35994b10f846ef630cd1a58d53a8f12 (diff)
downloadgcc-9f93702662f417705f1fc306ffbd078fef8abe02.zip
gcc-9f93702662f417705f1fc306ffbd078fef8abe02.tar.gz
gcc-9f93702662f417705f1fc306ffbd078fef8abe02.tar.bz2
tree.def (RTL_EXPR): Update documentation.
* tree.def (RTL_EXPR): Update documentation. * tree.h (RTL_EXPR_HAS_NO_SCOPE): New macro. * expr.c (expand_expr): Handle RTL_EXPR_HAS_NO_SCOPE. * function.c (preserve_rtl_expr_temp): New function. (preserve_rtl_expr_temps): Likewise. (preserve_rtl_expr_result): Use it. From-SVN: r32344
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/expr.c9
-rw-r--r--gcc/function.c38
-rw-r--r--gcc/tree.def12
-rw-r--r--gcc/tree.h4
5 files changed, 59 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fa77924..59c4a14 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,12 @@
2000-03-05 Mark Mitchell <mark@codesourcery.com>
+ * tree.def (RTL_EXPR): Update documentation.
+ * tree.h (RTL_EXPR_HAS_NO_SCOPE): New macro.
+ * expr.c (expand_expr): Handle RTL_EXPR_HAS_NO_SCOPE.
+ * function.c (preserve_rtl_expr_temp): New function.
+ (preserve_rtl_expr_temps): Likewise.
+ (preserve_rtl_expr_result): Use it.
+
Revert this patch:
2000-03-04 Mark Mitchell <mark@codesourcery.com>
diff --git a/gcc/expr.c b/gcc/expr.c
index fb266e2..28b3b44 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -6306,8 +6306,13 @@ 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);
+ if (RTL_EXPR_HAS_NO_SCOPE (exp))
+ preserve_rtl_expr_temps (exp);
+ else
+ {
+ 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 78c5ab8..fe7f61b 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -293,6 +293,7 @@ static void mark_function_chain PARAMS ((void *));
static void prepare_function_start PARAMS ((void));
static void do_clobber_return_reg PARAMS ((rtx, void *));
static void do_use_return_reg PARAMS ((rtx, void *));
+static void preserve_rtl_expr_temp PARAMS ((struct temp_slot *));
/* Pointer to chain of `struct function' for containing functions. */
struct function *outer_function_chain;
@@ -1129,6 +1130,36 @@ preserve_temp_slots (x)
p->level--;
}
+/* Preserve the temporary slot given by P (originally created during
+ the building of an RTL_EXPR) at least as long as things in our
+ current scope. */
+
+static void
+preserve_rtl_expr_temp (p)
+ struct temp_slot *p;
+{
+ /* Set the slot level to that of the currently prevailing scope. */
+ p->level = MIN (p->level, temp_slot_level);
+ /* This slot is no longer associated with the RTL_EXPR from which it
+ originated. */
+ p->rtl_expr = NULL_TREE;
+}
+
+/* Preserve the temporary slots created during the building of the
+ RTL_EXPR given by T at least as long as things in our current
+ scope. */
+
+void
+preserve_rtl_expr_temps (t)
+ tree t;
+{
+ struct temp_slot *p;
+
+ for (p = temp_slots; p; p = p->next)
+ if (p->in_use && p->rtl_expr == t)
+ preserve_rtl_expr_temp (p);
+}
+
/* 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
@@ -1148,11 +1179,8 @@ preserve_rtl_expr_result (x)
/* 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;
- }
+ if (p)
+ preserve_rtl_expr_temp (p);
return;
}
diff --git a/gcc/tree.def b/gcc/tree.def
index 551d5cb..d691150 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -686,10 +686,14 @@ DEFTREECODE (SAVE_EXPR, "save_expr", 'e', 3)
but where we must re-expand. */
DEFTREECODE (UNSAVE_EXPR, "unsave_expr", 'e', 1)
-/* Represents something whose RTL has already been expanded
- as a sequence which should be emitted when this expression is expanded.
- The first operand is the RTL to emit. It is the first of a chain of insns.
- The second is the RTL expression for the result. */
+/* Represents something whose RTL has already been expanded as a
+ sequence which should be emitted when this expression is expanded.
+ The first operand is the RTL to emit. It is the first of a chain
+ of insns. The second is the RTL expression for the result. If
+ RTL_EXPR_HAS_NO_SCOPE does not hold for this expression, then all
+ temporaries created within this RTL_EXPR (except for the
+ RTL_EXPR_RTL) are out-of-scope after the RTL_EXPR is expanded. (In
+ other words, their stack slots may be reused.) */
DEFTREECODE (RTL_EXPR, "rtl_expr", 'e', 2)
/* & in C. Value is the address at which the operand's value resides.
diff --git a/gcc/tree.h b/gcc/tree.h
index 1a82758..722b219 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -749,6 +749,10 @@ struct tree_vec
/* In a RTL_EXPR node. */
#define RTL_EXPR_SEQUENCE(NODE) (*(struct rtx_def **) &EXPR_CHECK (NODE)->exp.operands[0])
#define RTL_EXPR_RTL(NODE) (*(struct rtx_def **) &EXPR_CHECK (NODE)->exp.operands[1])
+/* Nonzero if the RTL_EXPR does not define a scope, i.e., if
+ temporaries defined during its scope should persist even after the
+ RTL_EXPR has been expanded. */
+#define RTL_EXPR_HAS_NO_SCOPE(NODE) TREE_ASM_WRITTEN (NODE)
/* In a CALL_EXPR node. */
#define CALL_EXPR_RTL(NODE) (*(struct rtx_def **) &EXPR_CHECK (NODE)->exp.operands[2])