* tree.def (RTL_EXPR): Remove.
* c-typeck.c (lvalue_p): Don't handle it.
* expr.c (safe_from_p): Likewise.
(expand_expr_real_1): Likewise.
* fold-const.c (non_lvalue, operand_equal_p, fold): Likewise.
(fold_checksum_tree, tree_expr_nonnegative_p): Likewise.
* gengtype.c (adjust_field_tree_exp): Likewise.
* stmt.c (warn_if_unused_value): Likewise.
* tree-gimple.c (recalculate_side_effects): Likewise.
* tree-pretty-print.c (dump_generic_node): Likewise.
* tree.c (make_node_stat, first_rtl_op, unsave_expr_1): Likewise.
(unsafe_for_reeval, stabilize_reference, build1_stat): Likewise.
* tree.h (RTL_EXPR_SEQUENCE, RTL_EXPR_RTL, RTL_EXPR_ALT_RTL): Remove.
* stmt.c (struct stmt_status): Remove x_last_expr_type,
x_last_expr_value, x_last_expr_alt_rtl, x_expr_stmts_for_value.
(last_expr_type, last_expr_value, last_expr_alt_rtl): Remove.
(expand_expr_stmt): Merge with expand_expr_stmt_value. Remove
all the bits that tracked last_expr.
(expand_end_bindings): Don't track last_expr.
(expand_start_stmt_expr, expand_end_stmt_expr): Remove.
(clear_last_expr): Remove.
(expand_asm): Don't call it.
(expand_asm_operands, expand_end_cond): Likewise.
(expand_naked_return, expand_null_return_1): Likewise.
* c-typeck.c (c_begin_compound_stmt): Likewise.
* cfgexpand.c (expand_block): Use expand_expr_stmt.
* expr.c (expand_expr_real_1): Likewise.
* tree.h: Update prototypes.
* function.h (struct sequence_stack): Remove sequence_rtl_expr.
(struct emit_status): Remove sequence_rtl_expr.
(struct function): Remove x_rtl_expr_chain.
(seq_rtl_expr, rtl_expr_chain): Remove.
* function.c (struct temp_slot): Remove rtl_expr.
(assign_stack_temp_for_type): Don't set it.
(free_temp_slots, pop_temp_slots): Don't check it.
(free_after_compilation): Don't clear x_rtl_expr_chain.
(fixup_var_refs): Don't search it.
(preserve_rtl_expr_result, free_temps_for_rtl_expr): Remove.
* emit-rtl.c (start_sequence): Don't use sequence_rtl_expr
or seq_rtl_expr.
(push_topmost_sequence): Likewise.
(end_sequence, init_emit): Likewise.
(start_sequence_for_rtl_expr): Remove.
* expmed.c (make_tree): Build a VAR_DECL instead of an RTL_EXPR.
* rtl.h (preserve_rtl_expr_result): Remove.
ada/
* trans.c (gnat_stabilize_reference): Don't handle RTL_EXPR.
* utils.c (max_size): Likewise.
cp/
* class.c (fixed_type_or_null): Don't handle RTL_EXPR.
* method.c (synthesize_method): Don't clear_last_expr.
* name-lookup.c (maybe_push_cleanup_level): Likewise.
From-SVN: r84009
+2004-07-01 Richard Henderson <rth@redhat.com>
+
+ * tree.def (RTL_EXPR): Remove.
+ * c-typeck.c (lvalue_p): Don't handle it.
+ * expr.c (safe_from_p): Likewise.
+ (expand_expr_real_1): Likewise.
+ * fold-const.c (non_lvalue, operand_equal_p, fold): Likewise.
+ (fold_checksum_tree, tree_expr_nonnegative_p): Likewise.
+ * gengtype.c (adjust_field_tree_exp): Likewise.
+ * stmt.c (warn_if_unused_value): Likewise.
+ * tree-gimple.c (recalculate_side_effects): Likewise.
+ * tree-pretty-print.c (dump_generic_node): Likewise.
+ * tree.c (make_node_stat, first_rtl_op, unsave_expr_1): Likewise.
+ (unsafe_for_reeval, stabilize_reference, build1_stat): Likewise.
+ * tree.h (RTL_EXPR_SEQUENCE, RTL_EXPR_RTL, RTL_EXPR_ALT_RTL): Remove.
+
+ * stmt.c (struct stmt_status): Remove x_last_expr_type,
+ x_last_expr_value, x_last_expr_alt_rtl, x_expr_stmts_for_value.
+ (last_expr_type, last_expr_value, last_expr_alt_rtl): Remove.
+ (expand_expr_stmt): Merge with expand_expr_stmt_value. Remove
+ all the bits that tracked last_expr.
+ (expand_end_bindings): Don't track last_expr.
+ (expand_start_stmt_expr, expand_end_stmt_expr): Remove.
+ (clear_last_expr): Remove.
+ (expand_asm): Don't call it.
+ (expand_asm_operands, expand_end_cond): Likewise.
+ (expand_naked_return, expand_null_return_1): Likewise.
+ * c-typeck.c (c_begin_compound_stmt): Likewise.
+ * cfgexpand.c (expand_block): Use expand_expr_stmt.
+ * expr.c (expand_expr_real_1): Likewise.
+ * tree.h: Update prototypes.
+
+ * function.h (struct sequence_stack): Remove sequence_rtl_expr.
+ (struct emit_status): Remove sequence_rtl_expr.
+ (struct function): Remove x_rtl_expr_chain.
+ (seq_rtl_expr, rtl_expr_chain): Remove.
+ * function.c (struct temp_slot): Remove rtl_expr.
+ (assign_stack_temp_for_type): Don't set it.
+ (free_temp_slots, pop_temp_slots): Don't check it.
+ (free_after_compilation): Don't clear x_rtl_expr_chain.
+ (fixup_var_refs): Don't search it.
+ (preserve_rtl_expr_result, free_temps_for_rtl_expr): Remove.
+ * emit-rtl.c (start_sequence): Don't use sequence_rtl_expr
+ or seq_rtl_expr.
+ (push_topmost_sequence): Likewise.
+ (end_sequence, init_emit): Likewise.
+ (start_sequence_for_rtl_expr): Remove.
+ * expmed.c (make_tree): Build a VAR_DECL instead of an RTL_EXPR.
+ * rtl.h (preserve_rtl_expr_result): Remove.
+
2004-07-02 Kazu Hirata <kazu@cs.umass.edu>
* ifcvt.c, modulo-sched.c, tree-alias-common.c, tree-sra.c,
+2004-07-01 Richard Henderson <rth@redhat.com>
+
+ * trans.c (gnat_stabilize_reference): Don't handle RTL_EXPR.
+ * utils.c (max_size): Likewise.
+
2004-06-28 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* decl.c: Remove calls to add_decl_expr, pushdecl, rest_of_compilation,
force));
break;
- case RTL_EXPR:
- result = build1 (INDIRECT_REF, type,
- save_expr (build1 (ADDR_EXPR,
- build_reference_type (type), ref)));
- break;
-
/* If arg isn't a kind of lvalue we recognize, make no change.
Caller should recognize the error for an invalid lvalue. */
default:
code == NEGATE_EXPR ? ! max_p : max_p)));
case 2:
- if (code == RTL_EXPR)
- gigi_abort (407);
- else if (code == COMPOUND_EXPR)
+ if (code == COMPOUND_EXPR)
return max_size (TREE_OPERAND (exp, 1), max_p);
{
&& TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE);
case BIND_EXPR:
- case RTL_EXPR:
return TREE_CODE (TREE_TYPE (ref)) == ARRAY_TYPE;
default:
{
tree stmt = push_stmt_list ();
if (do_scope)
- {
- push_scope ();
- clear_last_expr ();
- }
+ push_scope ();
return stmt;
}
{
last = get_last_insn ();
- expand_expr_stmt_value (stmt, 0, 0);
+ expand_expr_stmt (stmt);
/* Java emits line number notes in the top of labels.
??? Make this go away once line number notes are obsoleted. */
case CALL_EXPR:
case MODIFY_EXPR:
case RETURN_EXPR:
- expand_expr_stmt_value (stmt, 0, 0);
+ expand_expr_stmt (stmt);
for (last = NEXT_INSN (last); last; last = NEXT_INSN (last))
{
if (GET_CODE (last) == CALL_INSN && SIBLING_CALL_P (last))
break;
default:
- expand_expr_stmt_value (stmt, 0, 0);
+ expand_expr_stmt (stmt);
break;
}
}
+2004-07-01 Richard Henderson <rth@redhat.com>
+
+ * class.c (fixed_type_or_null): Don't handle RTL_EXPR.
+ * method.c (synthesize_method): Don't clear_last_expr.
+ * name-lookup.c (maybe_push_cleanup_level): Likewise.
+
2004-07-01 Nick Clifton <nickc@redhat.com>
* decl2.c (import_export_class): Invoke the
}
return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
- case RTL_EXPR:
- return NULL_TREE;
-
case PLUS_EXPR:
case MINUS_EXPR:
if (TREE_CODE (TREE_OPERAND (instance, 0)) == ADDR_EXPR)
interface_unknown = 1;
start_preparsed_function (fndecl, NULL_TREE, SF_DEFAULT | SF_PRE_PARSED);
- clear_last_expr ();
stmt = begin_function_body ();
if (DECL_OVERLOADED_OPERATOR_P (fndecl) == NOP_EXPR)
{
begin_scope (sk_cleanup, NULL);
current_binding_level->statement_list = push_stmt_list ();
- clear_last_expr ();
}
}
/* Space for free sequence stack entries. */
static GTY ((deletable)) struct sequence_stack *free_sequence_stack;
-/* Begin emitting insns to a sequence which can be packaged in an
- RTL_EXPR. If this sequence will contain something that might cause
- the compiler to pop arguments to function calls (because those
- pops have previously been deferred; see INHIBIT_DEFER_POP for more
- details), use do_pending_stack_adjust before calling this function.
- That will ensure that the deferred pops are not accidentally
- emitted in the middle of this sequence. */
+/* Begin emitting insns to a sequence. If this sequence will contain
+ something that might cause the compiler to pop arguments to function
+ calls (because those pops have previously been deferred; see
+ INHIBIT_DEFER_POP for more details), use do_pending_stack_adjust
+ before calling this function. That will ensure that the deferred
+ pops are not accidentally emitted in the middle of this sequence. */
void
start_sequence (void)
tem->next = seq_stack;
tem->first = first_insn;
tem->last = last_insn;
- tem->sequence_rtl_expr = seq_rtl_expr;
seq_stack = tem;
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 (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. */
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
top->first = first_insn;
top->last = last_insn;
- /* ??? Why don't we save seq_rtl_expr here? */
end_sequence ();
}
first_insn = tem->first;
last_insn = tem->last;
- seq_rtl_expr = tem->sequence_rtl_expr;
seq_stack = tem->next;
memset (tem, 0, sizeof (*tem));
f->emit = ggc_alloc (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_location = UNKNOWN_LOCATION;
}
\f
/* Return a tree node with data type TYPE, describing the value of X.
- Usually this is an RTL_EXPR, if there is no obvious better choice.
+ Usually this is an VAR_DECL, if there is no obvious better choice.
X may be an expression, however we only support those expressions
generated by loop.c. */
GET_CODE (x) == ZERO_EXTEND);
return fold (convert (type, make_tree (t, XEXP (x, 0))));
- default:
- t = make_node (RTL_EXPR);
- TREE_TYPE (t) = type;
+ default:
+ t = build_decl (VAR_DECL, NULL_TREE, type);
/* If TYPE is a POINTER_TYPE, X might be Pmode with TYPE_MODE being
ptr_mode. So convert. */
if (POINTER_TYPE_P (type))
x = convert_memory_address (TYPE_MODE (type), x);
- RTL_EXPR_RTL (t) = x;
- /* There are no insns to be output
- when this rtl_expr is used. */
- RTL_EXPR_SEQUENCE (t) = 0;
+ SET_DECL_RTL (t, x);
+
return t;
}
}
could get the wrong value for an argument.
To avoid this problem we go ahead and emit code to copy the addresses of
- DST and SRC and SIZE into new pseudos. We can then place those new
- pseudos into an RTL_EXPR and use them later, even after a call to
- emit_queue.
+ DST and SRC and SIZE into new pseudos.
Note this is not strictly needed for library calls since they do not call
emit_queue before loading their arguments. However, we may need to have
not careful we could get the wrong value for an argument.
To avoid this problem we go ahead and emit code to copy OBJECT
- and SIZE into new pseudos. We can then place those new pseudos
- into an RTL_EXPR and use them later, even after a call to
- emit_queue.
+ and SIZE into new pseudos.
Note this is not strictly needed for library calls since they
do not call emit_queue before loading their arguments. However,
return 0;
break;
- case RTL_EXPR:
- /* If a sequence exists, we would have to scan every instruction
- in the sequence to see if it was safe. This is probably not
- worthwhile. */
- if (RTL_EXPR_SEQUENCE (exp))
- return 0;
-
- exp_rtl = RTL_EXPR_RTL (exp);
- break;
-
case WITH_CLEANUP_EXPR:
exp_rtl = WITH_CLEANUP_EXPR_RTL (exp);
break;
case LABELED_BLOCK_EXPR:
if (LABELED_BLOCK_BODY (exp))
- expand_expr_stmt_value (LABELED_BLOCK_BODY (exp), 0, 1);
+ expand_expr_stmt (LABELED_BLOCK_BODY (exp));
/* Should perhaps use expand_label, but this is simpler and safer. */
do_pending_stack_adjust ();
emit_label (label_rtx (LABELED_BLOCK_LABEL (exp)));
tree block = BIND_EXPR_BLOCK (exp);
int mark_ends;
- if (TREE_CODE (BIND_EXPR_BODY (exp)) != RTL_EXPR)
- {
- /* If we're in functions-as-trees mode, this BIND_EXPR represents
- the block, so we need to emit NOTE_INSN_BLOCK_* notes. */
- mark_ends = (block != NULL_TREE);
- expand_start_bindings_and_block (mark_ends ? 0 : 2, block);
- }
- else
- {
- /* If we're not in functions-as-trees mode, we've already emitted
- those notes into our RTL_EXPR, so we just want to splice our BLOCK
- into the enclosing one. */
- mark_ends = 0;
-
- /* Need to open a binding contour here because
- if there are any cleanups they must be contained here. */
- expand_start_bindings_and_block (2, NULL_TREE);
-
- /* Mark the corresponding BLOCK for output in its proper place. */
- if (block)
- {
- if (TREE_USED (block))
- abort ();
- lang_hooks.decls.insert_block (block);
- }
- }
+ /* If we're in functions-as-trees mode, this BIND_EXPR represents
+ the block, so we need to emit NOTE_INSN_BLOCK_* notes. */
+ mark_ends = (block != NULL_TREE);
+ expand_start_bindings_and_block (mark_ends ? 0 : 2, block);
/* If VARS have not yet been expanded, expand them now. */
expand_vars (BIND_EXPR_VARS (exp));
return temp;
}
- case RTL_EXPR:
- if (RTL_EXPR_SEQUENCE (exp))
- {
- if (RTL_EXPR_SEQUENCE (exp) == const0_rtx)
- abort ();
- emit_insn (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 (alt_rtl)
- *alt_rtl = RTL_EXPR_ALT_RTL (exp);
- return RTL_EXPR_RTL (exp);
-
case CONSTRUCTOR:
/* If we don't need the result, just ensure we evaluate any
subexpressions. */
&& (GET_MODE_CLASS (mode) == MODE_INT)
? addv_optab : add_optab;
- /* If we are adding a constant, an RTL_EXPR that is sp, fp, or ap, and
+ /* If we are adding a constant, a VAR_DECL that is sp, fp, or ap, and
something else, make sure we add the register to the constant and
then to the other thing. This case can occur during strength
reduction and doing it this way will produce better code if the
if (TREE_CODE (TREE_OPERAND (exp, 0)) == PLUS_EXPR
&& TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 1)) == INTEGER_CST
- && TREE_CODE (TREE_OPERAND (exp, 1)) == RTL_EXPR
- && (RTL_EXPR_RTL (TREE_OPERAND (exp, 1)) == frame_pointer_rtx
- || RTL_EXPR_RTL (TREE_OPERAND (exp, 1)) == stack_pointer_rtx
- || RTL_EXPR_RTL (TREE_OPERAND (exp, 1)) == arg_pointer_rtx))
+ && TREE_CODE (TREE_OPERAND (exp, 1)) == VAR_DECL
+ && (DECL_RTL (TREE_OPERAND (exp, 1)) == frame_pointer_rtx
+ || DECL_RTL (TREE_OPERAND (exp, 1)) == stack_pointer_rtx
+ || DECL_RTL (TREE_OPERAND (exp, 1)) == arg_pointer_rtx))
{
tree t = TREE_OPERAND (exp, 1);
case BIND_EXPR:
case MIN_EXPR:
case MAX_EXPR:
- case RTL_EXPR:
break;
default:
&& operand_equal_p (TREE_OPERAND (arg0, 1),
TREE_OPERAND (arg1, 0), flags));
- case RTL_EXPR:
- return rtx_equal_p (RTL_EXPR_RTL (arg0), RTL_EXPR_RTL (arg1));
-
case CALL_EXPR:
/* If the CALL_EXPRs call different functions, then they
clearly can not be equal. */
if all operands are constant. */
int wins = 1;
- /* Don't try to process an RTL_EXPR since its operands aren't trees.
- Likewise for a SAVE_EXPR that's already been evaluated. */
- if (code == RTL_EXPR || (code == SAVE_EXPR && SAVE_EXPR_RTL (t) != 0))
+ /* Don't try to process an SAVE_EXPR that's already been evaluated. */
+ if (code == SAVE_EXPR && SAVE_EXPR_RTL (t) != 0)
return t;
/* Return right away if a constant. */
{
case SAVE_EXPR: len = 2; break;
case GOTO_SUBROUTINE_EXPR: len = 0; break;
- case RTL_EXPR: len = 0; break;
case WITH_CLEANUP_EXPR: len = 2; break;
default: break;
}
return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
case FLOAT_EXPR:
return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
- case RTL_EXPR:
- return rtl_expr_nonnegative_p (RTL_EXPR_RTL (t));
case TARGET_EXPR:
{
It can be reused if objects of the type of the new slot will always
conflict with objects of the type of the old slot. */
tree type;
- /* The value of `sequence_rtl_expr' when this temporary is allocated. */
- tree rtl_expr;
/* Nonzero if this temporary is currently in use. */
char in_use;
/* Nonzero if this temporary has its address taken. */
f->x_naked_return_label = NULL;
f->x_save_expr_regs = NULL;
f->x_stack_slot_list = NULL;
- f->x_rtl_expr_chain = NULL;
f->x_tail_recursion_reentry = NULL;
f->x_arg_pointer_save_area = NULL;
f->x_parm_birth_insn = NULL;
rounded_size));
p->align = best_p->align;
p->address = 0;
- p->rtl_expr = 0;
p->type = best_p->type;
insert_slot_to_list (p, &avail_temp_slots);
p = selected;
p->in_use = 1;
p->addr_taken = 0;
- p->rtl_expr = seq_rtl_expr;
p->type = type;
if (keep == 2)
}
}
-/* 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 (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 || !MEM_P (x) || 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)
- {
- move_slot_to_level (p, 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.
- We could eventually do better than this since it can be reused while
- generating the same RTL_EXPR, but this is complex and probably not
- worthwhile. */
+/* Free all temporaries used so far. This is normally called at the
+ end of generating code for a statement. */
void
free_temp_slots (void)
{
next = p->next;
- if (!p->keep && p->rtl_expr == 0)
+ if (!p->keep)
make_slot_available (p);
}
combine_temp_slots ();
}
-/* Free all temporary slots used in T, an RTL_EXPR node. */
-
-void
-free_temps_for_rtl_expr (tree t)
-{
- struct temp_slot *p, *next;
-
- for (p = *temp_slots_at_level (temp_slot_level); p; p = next)
- {
- next = p->next;
-
- if (p->rtl_expr == t)
- {
- /* If this slot is below the current TEMP_SLOT_LEVEL, then it
- needs to be preserved. This can happen if a temporary in
- the RTL_EXPR was addressed; preserve_temp_slots will move
- the temporary into a higher level. */
- if (temp_slot_level <= p->level)
- make_slot_available (p);
- else
- p->rtl_expr = NULL_TREE;
- }
- }
-
- combine_temp_slots ();
-}
-
/* Push deeper into the nesting level for stack temporaries. */
void
for (p = *temp_slots_at_level (temp_slot_level); p; p = next)
{
next = p->next;
-
- if (p->rtl_expr == 0)
- make_slot_available (p);
+ make_slot_available (p);
}
combine_temp_slots ();
fixup_var_refs (rtx var, enum machine_mode promoted_mode, int unsignedp,
rtx may_share, htab_t ht)
{
- tree pending;
rtx first_insn = get_insns ();
struct sequence_stack *stack = seq_stack;
- tree rtl_exps = rtl_expr_chain;
int save_volatile_ok = volatile_ok;
/* If there's a hash table, it must record all uses of VAR. */
end_sequence ();
}
- /* Scan all waiting RTL_EXPRs too. */
- for (pending = rtl_exps; pending; pending = TREE_CHAIN (pending))
- {
- rtx seq = RTL_EXPR_SEQUENCE (TREE_VALUE (pending));
- if (seq != const0_rtx && seq != 0)
- {
- push_to_sequence (seq);
- fixup_var_refs_insns (seq, var, promoted_mode, unsignedp, 0,
- may_share);
- end_sequence ();
- }
- }
-
volatile_ok = save_volatile_ok;
}
\f
/* First and last insns in the chain of the saved sequence. */
rtx first;
rtx last;
- tree sequence_rtl_expr;
struct sequence_stack *next;
};
/* The ends of the doubly-linked chain of rtl for the current function.
Both are reset to null at the start of rtl generation for the function.
- start_sequence saves both of these on `sequence_stack' along with
- `sequence_rtl_expr' and then starts a new, nested sequence of insns. */
+ start_sequence saves both of these on `sequence_stack' and then starts
+ a new, nested sequence of insns. */
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,
/* 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)
Made for the sake of unshare_all_rtl. */
rtx x_stack_slot_list;
- /* Chain of all RTL_EXPRs that have insns in them. */
- tree x_rtl_expr_chain;
-
/* Place after which to insert the tail_recursion_label if we need one. */
rtx x_tail_recursion_reentry;
#define frame_offset (cfun->x_frame_offset)
#define tail_recursion_reentry (cfun->x_tail_recursion_reentry)
#define arg_pointer_save_area (cfun->x_arg_pointer_save_area)
-#define rtl_expr_chain (cfun->x_rtl_expr_chain)
#define used_temp_slots (cfun->x_used_temp_slots)
#define avail_temp_slots (cfun->x_avail_temp_slots)
#define temp_slot_level (cfun->x_temp_slot_level)
} data[] = {
{ "SAVE_EXPR", 2, 1 },
{ "GOTO_SUBROUTINE_EXPR", 0, 2 },
- { "RTL_EXPR", 0, 2 },
{ "WITH_CLEANUP_EXPR", 2, 1 },
};
extern void thread_prologue_and_epilogue_insns (rtx);
extern int prologue_epilogue_contains (rtx);
extern int sibcall_epilogue_contains (rtx);
-extern void preserve_rtl_expr_result (rtx);
extern void mark_temp_addr_taken (rtx);
extern void update_temp_slot_address (rtx, rtx);
extern void purge_addressof (rtx);
/* Number of binding contours started so far in this function. */
int x_block_start_count;
- /* Each time we expand an expression-statement,
- record the expr's type and its RTL value here. */
- tree x_last_expr_type;
- rtx x_last_expr_value;
- rtx x_last_expr_alt_rtl;
-
- /* Nonzero if within a ({...}) grouping, in which case we must
- always compute a value for each expr-stmt in case it is the last one. */
- int x_expr_stmts_for_value;
-
/* Location of last line-number note, whether we actually
emitted it or not. */
location_t x_emit_locus;
#define nesting_stack (cfun->stmt->x_nesting_stack)
#define nesting_depth (cfun->stmt->x_nesting_depth)
#define current_block_start_count (cfun->stmt->x_block_start_count)
-#define last_expr_type (cfun->stmt->x_last_expr_type)
-#define last_expr_value (cfun->stmt->x_last_expr_value)
-#define last_expr_alt_rtl (cfun->stmt->x_last_expr_alt_rtl)
-#define expr_stmts_for_value (cfun->stmt->x_expr_stmts_for_value)
#define emit_locus (cfun->stmt->x_emit_locus)
#define goto_fixup_chain (cfun->stmt->x_goto_fixup_chain)
MEM_VOLATILE_P (body) = vol;
emit_insn (body);
-
- clear_last_expr ();
}
/* Parse the output constraint pointed to by *CONSTRAINT_P. It is the
}
}
- clear_last_expr ();
-
/* First pass over inputs and outputs checks validity and sets
mark_addressable if needed. */
return p;
}
\f
-/* Generate RTL to evaluate the expression EXP
- and remember it in case this is the VALUE in a ({... VALUE; }) constr.
- Provided just for backward-compatibility. expand_expr_stmt_value()
- should be used for new code. */
+/* Generate RTL to evaluate the expression EXP. */
void
expand_expr_stmt (tree exp)
-{
- expand_expr_stmt_value (exp, -1, 1);
-}
-
-/* Generate RTL to evaluate the expression EXP. WANT_VALUE tells
- whether to (1) save the value of the expression, (0) discard it or
- (-1) use expr_stmts_for_value to tell. The use of -1 is
- deprecated, and retained only for backward compatibility. */
-
-void
-expand_expr_stmt_value (tree exp, int want_value, int maybe_last)
{
rtx value;
tree type;
- rtx alt_rtl = NULL;
-
- if (want_value == -1)
- want_value = expr_stmts_for_value != 0;
-
- /* If -Wextra, warn about statements with no side effects,
- except for an explicit cast to void (e.g. for assert()), and
- except for last statement in ({...}) where they may be useful. */
- if (! want_value
- && (expr_stmts_for_value == 0 || ! maybe_last)
- && exp != error_mark_node
- && warn_unused_value)
- {
- if (TREE_SIDE_EFFECTS (exp))
- warn_if_unused_value (exp, emit_locus);
- else if (!VOID_TYPE_P (TREE_TYPE (exp)) && !TREE_NO_WARNING (exp))
- warning ("%Hstatement with no effect", &emit_locus);
- }
-
- /* If EXP is of function type and we are expanding statements for
- value, convert it to pointer-to-function. */
- if (want_value && TREE_CODE (TREE_TYPE (exp)) == FUNCTION_TYPE)
- exp = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (exp)), exp);
- /* The call to `expand_expr' could cause last_expr_type and
- last_expr_value to get reset. Therefore, we set last_expr_value
- and last_expr_type *after* calling expand_expr. */
- value = expand_expr_real (exp, want_value ? NULL_RTX : const0_rtx,
- VOIDmode, 0, &alt_rtl);
+ value = expand_expr (exp, const0_rtx, VOIDmode, 0);
type = TREE_TYPE (exp);
/* If all we do is reference a volatile value in memory,
}
}
- /* If this expression is part of a ({...}) and is in memory, we may have
- to preserve temporaries. */
- preserve_temp_slots (value);
-
- /* Free any temporaries used to evaluate this expression. Any temporary
- used as a result of this expression will already have been preserved
- above. */
+ /* Free any temporaries used to evaluate this expression. */
free_temp_slots ();
- if (want_value)
- {
- last_expr_value = value;
- last_expr_alt_rtl = alt_rtl;
- last_expr_type = type;
- }
-
emit_queue ();
}
case INIT_EXPR:
case TARGET_EXPR:
case CALL_EXPR:
- case RTL_EXPR:
case TRY_CATCH_EXPR:
case WITH_CLEANUP_EXPR:
case EXIT_EXPR:
return 1;
}
}
-
-/* Clear out the memory of the last expression evaluated. */
-
-void
-clear_last_expr (void)
-{
- last_expr_type = NULL_TREE;
- last_expr_value = NULL_RTX;
- last_expr_alt_rtl = NULL_RTX;
-}
-
-/* Begin a statement-expression, i.e., a series of statements which
- may return a value. Return the RTL_EXPR for this statement expr.
- The caller must save that value and pass it to
- expand_end_stmt_expr. If HAS_SCOPE is nonzero, temporaries created
- in the statement-expression are deallocated at the end of the
- expression. */
-
-tree
-expand_start_stmt_expr (int has_scope)
-{
- tree t;
-
- /* Make the RTL_EXPR node temporary, not momentary,
- so that rtl_expr_chain doesn't become garbage. */
- t = make_node (RTL_EXPR);
- do_pending_stack_adjust ();
- if (has_scope)
- start_sequence_for_rtl_expr (t);
- else
- start_sequence ();
- NO_DEFER_POP;
- expr_stmts_for_value++;
- return t;
-}
-
-/* Restore the previous state at the end of a statement that returns a value.
- Returns a tree node representing the statement's value and the
- insns to compute the value.
-
- The nodes of that expression have been freed by now, so we cannot use them.
- But we don't want to do that anyway; the expression has already been
- evaluated and now we just want to use the value. So generate a RTL_EXPR
- with the proper type and RTL value.
-
- If the last substatement was not an expression,
- return something with type `void'. */
-
-tree
-expand_end_stmt_expr (tree t)
-{
- OK_DEFER_POP;
-
- if (! last_expr_value || ! last_expr_type)
- {
- last_expr_value = const0_rtx;
- last_expr_alt_rtl = NULL_RTX;
- last_expr_type = void_type_node;
- }
- else if (!REG_P (last_expr_value) && ! CONSTANT_P (last_expr_value))
- /* Remove any possible QUEUED. */
- last_expr_value = protect_from_queue (last_expr_value, 0);
-
- emit_queue ();
-
- TREE_TYPE (t) = last_expr_type;
- RTL_EXPR_RTL (t) = last_expr_value;
- RTL_EXPR_ALT_RTL (t) = last_expr_alt_rtl;
- RTL_EXPR_SEQUENCE (t) = get_insns ();
-
- rtl_expr_chain = tree_cons (NULL_TREE, t, rtl_expr_chain);
-
- end_sequence ();
-
- /* Don't consider deleting this expr or containing exprs at tree level. */
- TREE_SIDE_EFFECTS (t) = 1;
- /* Propagate volatility of the actual RTL expr. */
- TREE_THIS_VOLATILE (t) = volatile_refs_p (last_expr_value);
-
- clear_last_expr ();
- expr_stmts_for_value--;
-
- return t;
-}
\f
/* Generate RTL for the start of an if-then. COND is the expression
whose truth should be tested.
emit_label (thiscond->data.cond.endif_label);
POPSTACK (cond_stack);
- clear_last_expr ();
}
\f
/* Return nonzero if we should preserve sub-expressions as separate
clear_pending_stack_adjust ();
do_pending_stack_adjust ();
- clear_last_expr ();
if (end_label == 0)
end_label = naked_return_label = gen_label_rtx ();
clear_pending_stack_adjust ();
do_pending_stack_adjust ();
- clear_last_expr ();
if (end_label == 0)
end_label = return_label = gen_label_rtx ();
int reachable;
rtx insn;
- /* Don't let cleanups affect ({...}) constructs. */
- int old_expr_stmts_for_value = expr_stmts_for_value;
- rtx old_last_expr_value = last_expr_value;
- rtx old_last_expr_alt_rtl = last_expr_alt_rtl;
- tree old_last_expr_type = last_expr_type;
- expr_stmts_for_value = 0;
-
/* Only clean up here if this point can actually be reached. */
insn = get_last_insn ();
if (GET_CODE (insn) == NOTE)
if (reachable)
do_pending_stack_adjust ();
- expr_stmts_for_value = old_expr_stmts_for_value;
- last_expr_value = old_last_expr_value;
- last_expr_alt_rtl = old_last_expr_alt_rtl;
- last_expr_type = old_last_expr_type;
-
/* Restore the stack level. */
if (reachable && thisblock->data.block.stack_level != 0)
case INIT_EXPR:
case MODIFY_EXPR:
case VA_ARG_EXPR:
- case RTL_EXPR:
case PREDECREMENT_EXPR:
case PREINCREMENT_EXPR:
case POSTDECREMENT_EXPR:
pp_character (buffer, '>');
break;
- case RTL_EXPR:
- NIY;
- break;
-
case ENTRY_VALUE_EXPR:
NIY;
break;
case INIT_EXPR:
case MODIFY_EXPR:
case VA_ARG_EXPR:
- case RTL_EXPR:
case PREDECREMENT_EXPR:
case PREINCREMENT_EXPR:
case POSTDECREMENT_EXPR:
case SAVE_EXPR:
return 2;
case GOTO_SUBROUTINE_EXPR:
- case RTL_EXPR:
return 0;
case WITH_CLEANUP_EXPR:
return 2;
TREE_OPERAND (expr, 3) = NULL_TREE;
break;
- case RTL_EXPR:
- /* I don't yet know how to emit a sequence multiple times. */
- if (RTL_EXPR_SEQUENCE (expr) != 0)
- abort ();
- break;
-
default:
break;
}
SAVE_EXPRs basically *only* appear replicated in an expression tree,
occasionally across the whole of a function. It is therefore only
safe to unsave a SAVE_EXPR if you know that all occurrences appear
- below the UNSAVE_EXPR.
-
- RTL_EXPRs consume their rtl during evaluation. It is therefore
- never possible to unsave them. */
+ below the UNSAVE_EXPR. */
int
unsafe_for_reeval (tree expr)
switch (code)
{
case SAVE_EXPR:
- case RTL_EXPR:
return 2;
/* A label can only be emitted once. */
volatiles. */
return stabilize_reference_1 (ref);
- case RTL_EXPR:
- result = build1 (INDIRECT_REF, TREE_TYPE (ref),
- save_expr (build1 (ADDR_EXPR,
- build_pointer_type (TREE_TYPE (ref)),
- ref)));
- break;
-
/* If arg isn't a kind of lvalue we recognize, make no change.
Caller should recognize the error for an invalid lvalue. */
default:
case INIT_EXPR:
case MODIFY_EXPR:
case VA_ARG_EXPR:
- case RTL_EXPR:
case PREDECREMENT_EXPR:
case PREINCREMENT_EXPR:
case POSTDECREMENT_EXPR:
/* Specify a value to compute along with its corresponding cleanup.
Operand 0 argument is an expression whose value needs a cleanup.
Operand 1 is the cleanup expression for the object.
- Operand 2 is an RTL_EXPR which will eventually represent that value.
- The RTL_EXPR is used in this expression, which is how the expression
- manages to act on the proper value.
+ Operand 2 is unused.
The cleanup is executed by the first enclosing CLEANUP_POINT_EXPR, if
it exists, otherwise it is the responsibility of the caller to manually
call expand_start_target_temps/expand_end_target_temps, as needed.
DEFTREECODE (SAVE_EXPR, "save_expr", 'e', 3)
/* For a UNSAVE_EXPR, operand 0 is the value to unsave. By unsave, we
- mean that all _EXPRs such as TARGET_EXPRs, SAVE_EXPRs,
- CALL_EXPRs and RTL_EXPRs, that are protected
- from being evaluated more than once should be reset so that a new
- expand_expr call of this expr will cause those to be re-evaluated.
- This is useful when we want to reuse a tree in different places,
- but where we must re-expand. */
+ mean that all _EXPRs such as TARGET_EXPRs, SAVE_EXPRs, CALL_EXPRs,
+ that are protected from being evaluated more than once should be
+ reset so that a new expand_expr call of this expr will cause those
+ to be re-evaluated. This is useful when we want to reuse a tree in
+ different places, 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. The
- third operand is the "alternate RTL expression" for the result, if
- any; if the second argument is the DECL_RTL for a VAR_DECL, but
- with an invalid memory address replaced by a valid one, then the
- third operand will be the original DECL_RTL. Any temporaries
- created during the building of the RTL_EXPR can be reused once the
- RTL_EXPR has been expanded, with the exception of the
- RTL_EXPR_RTL. */
-DEFTREECODE (RTL_EXPR, "rtl_expr", 'e', 3)
-
/* & in C. Value is the address at which the operand's value resides.
Operand may have any mode. Result mode is Pmode. */
DEFTREECODE (ADDR_EXPR, "addr_expr", 'e', 1)
recalculated.) */
#define SAVE_EXPR_PERSISTENT_P(NODE) TREE_ASM_WRITTEN (SAVE_EXPR_CHECK (NODE))
-/* In a RTL_EXPR node. */
-#define RTL_EXPR_SEQUENCE(NODE) TREE_RTL_OPERAND_CHECK (NODE, RTL_EXPR, 0)
-#define RTL_EXPR_RTL(NODE) TREE_RTL_OPERAND_CHECK (NODE, RTL_EXPR, 1)
-#define RTL_EXPR_ALT_RTL(NODE) TREE_RTL_OPERAND_CHECK (NODE, RTL_EXPR, 2)
-
/* In a WITH_CLEANUP_EXPR node. */
#define WITH_CLEANUP_EXPR_RTL(NODE) \
TREE_RTL_OPERAND_CHECK (NODE, WITH_CLEANUP_EXPR, 2)
/* In stmt.c */
extern void expand_fixups (rtx);
-extern tree expand_start_stmt_expr (int);
-extern tree expand_end_stmt_expr (tree);
extern void expand_expr_stmt (tree);
extern void expand_expr_stmt_value (tree, int, int);
extern int warn_if_unused_value (tree, location_t);
extern void expand_decl_init (tree);
-extern void clear_last_expr (void);
extern void expand_label (tree);
extern void expand_goto (tree);
extern void expand_asm (tree, int);
extern void preserve_temp_slots (rtx);
extern void preserve_rtl_expr_temps (tree);
extern int aggregate_value_p (tree, tree);
-extern void free_temps_for_rtl_expr (tree);
extern void push_function_context (void);
extern void pop_function_context (void);
extern void push_function_context_to (tree);
extern void check_max_integer_computation_mode (tree);
/* In emit-rtl.c */
-extern void start_sequence_for_rtl_expr (tree);
extern rtx emit_line_note (location_t);
/* In calls.c */