aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2004-07-02 17:15:50 -0700
committerRichard Henderson <rth@gcc.gnu.org>2004-07-02 17:15:50 -0700
commit82c8274320fcfdf2ce27d26c017a4d9d9cafa4b1 (patch)
tree1c3ed35626f7a5ec145a2aaec1364cd9a760a955 /gcc/expr.c
parenta7e4cdca852a596dffe4e7cd2a1b0bd887c5ebec (diff)
downloadgcc-82c8274320fcfdf2ce27d26c017a4d9d9cafa4b1.zip
gcc-82c8274320fcfdf2ce27d26c017a4d9d9cafa4b1.tar.gz
gcc-82c8274320fcfdf2ce27d26c017a4d9d9cafa4b1.tar.bz2
c-decl.c (grokdeclarator): Don't frob current_function_decl around variable_size.
* c-decl.c (grokdeclarator): Don't frob current_function_decl around variable_size. (set_decl_nonlocal): Remove. (store_parm_decls): Add stmts for pending sizes. * calls.c (calls_function, calls_function_1): Remove. (precompute_arguments): Don't call it. * cfgexpand.c (set_save_expr_context): Remove. (tree_expand_cfg): Don't call it. * dwarf2out.c (add_bound_info): Don't handle SAVE_EXPR. (dwarf2out_finish): Likewise. * expr.c (emit_block_move): Adjust addresses to BLKmode. (store_constructor): Don't pre-evaluate SAVE_EXPR. (safe_from_p): Don't queue SAVE_EXPRs. (expand_expr_real_1 <case SAVE_EXPR>): Rewrite to expect, or build plain VAR_DECLs. * fold-const.c (twoval_comparison_p): Don't look at SAVE_EXPR_RTL. (fold): Likewise. (fold_checksum_tree): Don't special-case SAVE_EXPR. * function.c (free_after_compilation): Don't clear x_save_expr_regs. (put_var_into_stack): Don't handle SAVE_EXPR. (gen_mem_addressof): Likewise. * function.h (struct function): Remove x_save_expr_regs. (save_expr_regs): Remove. * gengtype.c (adjust_field_tree_exp): Don't special-case SAVE_EXPR. * print-tree.c (print_node): Don't dump SAVE_EXPR_NOPLACEHOLDER. * stor-layout.c (variable_size): Don't set it. (force_type_save_exprs, force_type_save_exprs_1): Remove. * tree-inline.c (remap_save_expr): Remove fn argument. Update all callers. Don't set SAVE_EXPR_CONTEXT. * tree-inline.h (remap_save_expr): Update decl. * tree.c (save_expr): Update build size. (first_rtl_op): Don't handle SAVE_EXPR. (unsave_expr_1, contains_placeholder_p): Likewise. (decl_function_context): Likewise. * tree.def (SAVE_EXPR): Remove args 1 and 2. * tree.h (SAVE_EXPR_CONTEXT, SAVE_EXPR_RTL): Remove. (SAVE_EXPR_NOPLACEHOLDER, SAVE_EXPR_PERSISTENT_P): Remove. cp/ * tree.c (cp_unsave_r): Update remap_save_expr call. java/ * jcf-write.c (generate_bytecode_insns <case SAVE_EXPR>): Rewrite. From-SVN: r84036
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c222
1 files changed, 44 insertions, 178 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index df35422..d3951fe 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -1349,11 +1349,6 @@ emit_block_move (rtx x, rtx y, rtx size, enum block_op_methods method)
align = MIN (MEM_ALIGN (x), MEM_ALIGN (y));
- if (GET_MODE (x) != BLKmode)
- abort ();
- if (GET_MODE (y) != BLKmode)
- abort ();
-
x = protect_from_queue (x, 1);
y = protect_from_queue (y, 0);
size = protect_from_queue (size, 0);
@@ -1365,6 +1360,11 @@ emit_block_move (rtx x, rtx y, rtx size, enum block_op_methods method)
if (size == 0)
abort ();
+ /* Make sure we've got BLKmode addresses; store_one_arg can decide that
+ block copy is more efficient for other large modes, e.g. DCmode. */
+ x = adjust_address (x, BLKmode, 0);
+ y = adjust_address (y, BLKmode, 0);
+
/* Set MEM_SIZE as appropriate for this block copy. The main place this
can be incorrect is coming from __builtin_memcpy. */
if (GET_CODE (size) == CONST_INT)
@@ -5090,14 +5090,6 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
= gen_reg_rtx (promote_mode (domain, DECL_MODE (index),
&unsignedp, 0));
SET_DECL_RTL (index, index_r);
- if (TREE_CODE (value) == SAVE_EXPR
- && SAVE_EXPR_RTL (value) == 0)
- {
- /* Make sure value gets expanded once before the
- loop. */
- expand_expr (value, const0_rtx, VOIDmode, 0);
- emit_queue ();
- }
store_expr (lo_index, index_r, 0);
/* Build the head of the loop. */
@@ -5986,7 +5978,6 @@ safe_from_p (rtx x, tree exp, int top_p)
{
rtx exp_rtl = 0;
int i, nops;
- static tree save_expr_list;
if (x == 0
/* If EXP has varying size, we MUST use a target since we currently
@@ -6018,30 +6009,6 @@ safe_from_p (rtx x, tree exp, int top_p)
return 0;
}
- /* A SAVE_EXPR might appear many times in the expression passed to the
- top-level safe_from_p call, and if it has a complex subexpression,
- examining it multiple times could result in a combinatorial explosion.
- E.g. on an Alpha running at least 200MHz, a Fortran testcase compiled
- with optimization took about 28 minutes to compile -- even though it was
- only a few lines long. So we mark each SAVE_EXPR we see with TREE_PRIVATE
- and turn that off when we are done. We keep a list of the SAVE_EXPRs
- we have processed. Note that the only test of top_p was above. */
-
- if (top_p)
- {
- int rtn;
- tree t;
-
- save_expr_list = 0;
-
- rtn = safe_from_p (x, exp, 0);
-
- for (t = save_expr_list; t != 0; t = TREE_CHAIN (t))
- TREE_PRIVATE (TREE_PURPOSE (t)) = 0;
-
- return rtn;
- }
-
/* Now look at our tree code and possibly recurse. */
switch (TREE_CODE_CLASS (TREE_CODE (exp)))
{
@@ -6139,28 +6106,8 @@ safe_from_p (rtx x, tree exp, int top_p)
break;
case CLEANUP_POINT_EXPR:
- return safe_from_p (x, TREE_OPERAND (exp, 0), 0);
-
case SAVE_EXPR:
- exp_rtl = SAVE_EXPR_RTL (exp);
- if (exp_rtl)
- break;
-
- /* If we've already scanned this, don't do it again. Otherwise,
- show we've scanned it and record for clearing the flag if we're
- going on. */
- if (TREE_PRIVATE (exp))
- return 1;
-
- TREE_PRIVATE (exp) = 1;
- if (! safe_from_p (x, TREE_OPERAND (exp, 0), 0))
- {
- TREE_PRIVATE (exp) = 0;
- return 0;
- }
-
- save_expr_list = tree_cons (exp, NULL_TREE, save_expr_list);
- return 1;
+ return safe_from_p (x, TREE_OPERAND (exp, 0), 0);
case BIND_EXPR:
/* The only operand we look at is operand 1. The rest aren't
@@ -6841,88 +6788,30 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
return temp;
case SAVE_EXPR:
- context = decl_function_context (exp);
-
- /* If this SAVE_EXPR was at global context, assume we are an
- initialization function and move it into our context. */
- if (context == 0)
- SAVE_EXPR_CONTEXT (exp) = current_function_decl;
-
- if (context == current_function_decl)
- context = 0;
-
- /* If this is non-local, handle it. */
- if (context)
- {
- /* The following call just exists to abort if the context is
- not of a containing function. */
- find_function_data (context);
-
- temp = SAVE_EXPR_RTL (exp);
- if (temp && REG_P (temp))
- {
- put_var_into_stack (exp, /*rescan=*/true);
- temp = SAVE_EXPR_RTL (exp);
- }
- if (temp == 0 || !MEM_P (temp))
- abort ();
- return
- replace_equiv_address (temp,
- fix_lexical_addr (XEXP (temp, 0), exp));
- }
- if (SAVE_EXPR_RTL (exp) == 0)
- {
- if (mode == VOIDmode)
- temp = const0_rtx;
- else
- temp = assign_temp (build_qualified_type (type,
- (TYPE_QUALS (type)
- | TYPE_QUAL_CONST)),
- 3, 0, 0);
-
- SAVE_EXPR_RTL (exp) = temp;
- if (!optimize && REG_P (temp))
- save_expr_regs = gen_rtx_EXPR_LIST (VOIDmode, temp,
- save_expr_regs);
-
- /* If the mode of TEMP does not match that of the expression, it
- must be a promoted value. We pass store_expr a SUBREG of the
- wanted mode but mark it so that we know that it was already
- extended. */
-
- if (REG_P (temp) && GET_MODE (temp) != mode)
- {
- temp = gen_lowpart_SUBREG (mode, SAVE_EXPR_RTL (exp));
- promote_mode (type, mode, &unsignedp, 0);
- SUBREG_PROMOTED_VAR_P (temp) = 1;
- SUBREG_PROMOTED_UNSIGNED_SET (temp, unsignedp);
- }
-
- if (temp == const0_rtx)
- expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, 0);
- else
- store_expr (TREE_OPERAND (exp, 0), temp,
- modifier == EXPAND_STACK_PARM ? 2 : 0);
+ {
+ tree val = TREE_OPERAND (exp, 0);
+ rtx ret = expand_expr_real_1 (val, target, tmode, modifier, alt_rtl);
- TREE_USED (exp) = 1;
- }
+ if (TREE_CODE (val) != VAR_DECL || !DECL_ARTIFICIAL (val))
+ {
+ /* We can indeed still hit this case, typically via builtin
+ expanders calling save_expr immediately before expanding
+ something. Assume this means that we only have to deal
+ with non-BLKmode values. */
+ if (GET_MODE (ret) == BLKmode)
+ abort ();
- /* If the mode of SAVE_EXPR_RTL does not match that of the expression, it
- must be a promoted value. We return a SUBREG of the wanted mode,
- but mark it so that we know that it was already extended. */
+ val = build_decl (VAR_DECL, NULL, TREE_TYPE (exp));
+ DECL_ARTIFICIAL (val) = 1;
+ TREE_OPERAND (exp, 0) = val;
- if (REG_P (SAVE_EXPR_RTL (exp))
- && GET_MODE (SAVE_EXPR_RTL (exp)) != mode)
- {
- /* Compute the signedness and make the proper SUBREG. */
- promote_mode (type, mode, &unsignedp, 0);
- temp = gen_lowpart_SUBREG (mode, SAVE_EXPR_RTL (exp));
- SUBREG_PROMOTED_VAR_P (temp) = 1;
- SUBREG_PROMOTED_UNSIGNED_SET (temp, unsignedp);
- return temp;
- }
+ if (!CONSTANT_P (ret))
+ ret = copy_to_reg (ret);
+ SET_DECL_RTL (val, ret);
+ }
- return SAVE_EXPR_RTL (exp);
+ return ret;
+ }
case UNSAVE_EXPR:
{
@@ -7301,25 +7190,13 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
&& (offset != 0
|| (code == ARRAY_RANGE_REF && mode == BLKmode)))
{
- /* If the operand is a SAVE_EXPR, we can deal with this by
- forcing the SAVE_EXPR into memory. */
- if (TREE_CODE (TREE_OPERAND (exp, 0)) == SAVE_EXPR)
- {
- put_var_into_stack (TREE_OPERAND (exp, 0),
- /*rescan=*/true);
- op0 = SAVE_EXPR_RTL (TREE_OPERAND (exp, 0));
- }
- else
- {
- tree nt
- = build_qualified_type (TREE_TYPE (tem),
- (TYPE_QUALS (TREE_TYPE (tem))
- | TYPE_QUAL_CONST));
- rtx memloc = assign_temp (nt, 1, 1, 1);
+ tree nt = build_qualified_type (TREE_TYPE (tem),
+ (TYPE_QUALS (TREE_TYPE (tem))
+ | TYPE_QUAL_CONST));
+ rtx memloc = assign_temp (nt, 1, 1, 1);
- emit_move_insn (memloc, op0);
- op0 = memloc;
- }
+ emit_move_insn (memloc, op0);
+ op0 = memloc;
}
if (offset != 0)
@@ -9045,31 +8922,20 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
|| GET_CODE (op0) == CONCAT || GET_CODE (op0) == ADDRESSOF
|| GET_CODE (op0) == PARALLEL || GET_CODE (op0) == LO_SUM)
{
- /* If the operand is a SAVE_EXPR, we can deal with this by
- forcing the SAVE_EXPR into memory. */
- if (TREE_CODE (TREE_OPERAND (exp, 0)) == SAVE_EXPR)
- {
- put_var_into_stack (TREE_OPERAND (exp, 0),
- /*rescan=*/true);
- op0 = SAVE_EXPR_RTL (TREE_OPERAND (exp, 0));
- }
+ /* If this object is in a register, it can't be BLKmode. */
+ tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
+ rtx memloc = assign_temp (inner_type, 1, 1, 1);
+
+ if (GET_CODE (op0) == PARALLEL)
+ /* Handle calls that pass values in multiple
+ non-contiguous locations. The Irix 6 ABI has examples
+ of this. */
+ emit_group_store (memloc, op0, inner_type,
+ int_size_in_bytes (inner_type));
else
- {
- /* If this object is in a register, it can't be BLKmode. */
- tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
- rtx memloc = assign_temp (inner_type, 1, 1, 1);
-
- if (GET_CODE (op0) == PARALLEL)
- /* Handle calls that pass values in multiple
- non-contiguous locations. The Irix 6 ABI has examples
- of this. */
- emit_group_store (memloc, op0, inner_type,
- int_size_in_bytes (inner_type));
- else
- emit_move_insn (memloc, op0);
+ emit_move_insn (memloc, op0);
- op0 = memloc;
- }
+ op0 = memloc;
}
if (!MEM_P (op0))