From: Richard Henderson Date: Sat, 3 Jul 2004 00:15:50 +0000 (-0700) Subject: c-decl.c (grokdeclarator): Don't frob current_function_decl around variable_size. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=82c8274320fcfdf2ce27d26c017a4d9d9cafa4b1;p=gcc.git 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 ): 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 ): Rewrite. From-SVN: r84036 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 479cec5166e..bce517a67d1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,43 @@ +2004-07-02 Richard Henderson + + * 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 ): 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. + 2004-07-03 Joseph S. Myers * doc/bugreport.texi, doc/configterms.texi, doc/contrib.texi, diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 00bb5872da0..329c86222a4 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -3990,20 +3990,7 @@ grokdeclarator (tree declarator, tree declspecs, } if (size_varies) - { - /* We must be able to distinguish the - SAVE_EXPR_CONTEXT for the variably-sized type - so that we can set it correctly in - set_save_expr_context. The convention is - that all SAVE_EXPRs that need to be reset - have NULL_TREE for their SAVE_EXPR_CONTEXT. */ - tree cfd = current_function_decl; - if (decl_context == PARM) - current_function_decl = NULL_TREE; - itype = variable_size (itype); - if (decl_context == PARM) - current_function_decl = cfd; - } + itype = variable_size (itype); itype = build_index_type (itype); } } @@ -6065,25 +6052,6 @@ store_parm_decls_oldstyle (tree fndecl, tree arg_info) } } -/* A subroutine of store_parm_decls called via walk_tree. Mark all - decls non-local. */ - -static tree -set_decl_nonlocal (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) -{ - tree t = *tp; - - if (DECL_P (t)) - { - DECL_NONLOCAL (t) = 1; - *walk_subtrees = 0; - } - else if (TYPE_P (t)) - *walk_subtrees = 0; - - return NULL; -} - /* Store the parameter declarations into the current function declaration. This is called after parsing the parameter declarations, before digesting the body of the function. @@ -6096,9 +6064,6 @@ store_parm_decls (void) { tree fndecl = current_function_decl; - /* The function containing FNDECL, if any. */ - tree context = decl_function_context (fndecl); - /* The argument information block for FNDECL. */ tree arg_info = DECL_ARGUMENTS (fndecl); @@ -6129,27 +6094,14 @@ store_parm_decls (void) /* Begin the statement tree for this function. */ DECL_SAVED_TREE (fndecl) = push_stmt_list (); - /* If this is a nested function, save away the sizes of any - variable-size types so that we can expand them when generating - RTL. */ - if (context) - { - tree t; - - DECL_LANG_SPECIFIC (fndecl)->pending_sizes - = nreverse (get_pending_sizes ()); - for (t = DECL_LANG_SPECIFIC (fndecl)->pending_sizes; - t; - t = TREE_CHAIN (t)) - { - /* We will have a nonlocal use of whatever variables are - buried inside here. */ - walk_tree (&TREE_OPERAND (TREE_VALUE (t), 0), - set_decl_nonlocal, NULL, NULL); - - SAVE_EXPR_CONTEXT (TREE_VALUE (t)) = context; - } - } + /* ??? Insert the contents of the pending sizes list into the function + to be evaluated. This just changes mis-behaviour until assign_parms + phase ordering problems are resolved. */ + { + tree t; + for (t = nreverse (get_pending_sizes ()); t ; t = TREE_CHAIN (t)) + add_stmt (TREE_VALUE (t)); + } /* Even though we're inside a function body, we still don't want to call expand_expr to calculate the size of a variable-sized array. diff --git a/gcc/calls.c b/gcc/calls.c index 11d8b26e848..328488e4ed3 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -117,9 +117,6 @@ static sbitmap stored_args_map; argument list for the constructor call. */ int stack_arg_under_construction; -static int calls_function (tree, int); -static int calls_function_1 (tree, int); - static void emit_call_1 (rtx, tree, tree, tree, HOST_WIDE_INT, HOST_WIDE_INT, HOST_WIDE_INT, rtx, rtx, int, rtx, int, CUMULATIVE_ARGS *); @@ -155,123 +152,6 @@ static rtx save_fixed_argument_area (int, rtx, int *, int *); static void restore_fixed_argument_area (rtx, rtx, int, int); #endif -/* If WHICH is 1, return 1 if EXP contains a call to the built-in function - `alloca'. - - If WHICH is 0, return 1 if EXP contains a call to any function. - Actually, we only need return 1 if evaluating EXP would require pushing - arguments on the stack, but that is too difficult to compute, so we just - assume any function call might require the stack. */ - -static tree calls_function_save_exprs; - -static int -calls_function (tree exp, int which) -{ - int val; - - calls_function_save_exprs = 0; - val = calls_function_1 (exp, which); - calls_function_save_exprs = 0; - return val; -} - -/* Recursive function to do the work of above function. */ - -static int -calls_function_1 (tree exp, int which) -{ - int i; - enum tree_code code = TREE_CODE (exp); - int class = TREE_CODE_CLASS (code); - int length = first_rtl_op (code); - - /* If this code is language-specific, we don't know what it will do. */ - if ((int) code >= NUM_TREE_CODES) - return 1; - - switch (code) - { - case CALL_EXPR: - if (which == 0) - return 1; - else if ((TREE_CODE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0)))) - == FUNCTION_TYPE) - && (TYPE_RETURNS_STACK_DEPRESSED - (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0)))))) - return 1; - else if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR - && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) - == FUNCTION_DECL) - && (special_function_p (TREE_OPERAND (TREE_OPERAND (exp, 0), 0), - 0) - & ECF_MAY_BE_ALLOCA)) - return 1; - - break; - - case CONSTRUCTOR: - { - tree tem; - - for (tem = CONSTRUCTOR_ELTS (exp); tem != 0; tem = TREE_CHAIN (tem)) - if (calls_function_1 (TREE_VALUE (tem), which)) - return 1; - } - - return 0; - - case SAVE_EXPR: - if (SAVE_EXPR_RTL (exp) != 0) - return 0; - if (value_member (exp, calls_function_save_exprs)) - return 0; - calls_function_save_exprs = tree_cons (NULL_TREE, exp, - calls_function_save_exprs); - return (TREE_OPERAND (exp, 0) != 0 - && calls_function_1 (TREE_OPERAND (exp, 0), which)); - - case BLOCK: - { - tree local; - tree subblock; - - for (local = BLOCK_VARS (exp); local; local = TREE_CHAIN (local)) - if (DECL_INITIAL (local) != 0 - && calls_function_1 (DECL_INITIAL (local), which)) - return 1; - - for (subblock = BLOCK_SUBBLOCKS (exp); - subblock; - subblock = TREE_CHAIN (subblock)) - if (calls_function_1 (subblock, which)) - return 1; - } - return 0; - - case TREE_LIST: - for (; exp != 0; exp = TREE_CHAIN (exp)) - if (calls_function_1 (TREE_VALUE (exp), which)) - return 1; - return 0; - - default: - break; - } - - /* Only expressions and blocks can contain calls. - Blocks were handled above. */ - if (! IS_EXPR_CODE_CLASS (class)) - return 0; - - for (i = 0; i < length; i++) - if (TREE_OPERAND (exp, i) != 0 - && calls_function_1 (TREE_OPERAND (exp, i), which)) - return 1; - - return 0; -} - /* Force FUNEXP into a form suitable for the address of a CALL, and return that as an rtx. Also load the static chain register if FNDECL is a nested function. @@ -1372,58 +1252,50 @@ precompute_arguments (int flags, int num_actuals, struct arg_data *args) int i; /* If this is a libcall, then precompute all arguments so that we do not - get extraneous instructions emitted as part of the libcall sequence. - - If this target defines ACCUMULATE_OUTGOING_ARGS to true, then we must - precompute all arguments that contain function calls. Otherwise, - computing arguments for a subcall may clobber arguments for this call. - - If this target defines ACCUMULATE_OUTGOING_ARGS to false, then we only - need to precompute arguments that change the stack pointer, such as calls - to alloca, and calls that do not pop all of their arguments. */ - + get extraneous instructions emitted as part of the libcall sequence. */ + if ((flags & ECF_LIBCALL_BLOCK) == 0) + return; + for (i = 0; i < num_actuals; i++) - if ((flags & ECF_LIBCALL_BLOCK) - || calls_function (args[i].tree_value, !ACCUMULATE_OUTGOING_ARGS)) - { - enum machine_mode mode; + { + enum machine_mode mode; - /* If this is an addressable type, we cannot pre-evaluate it. */ - if (TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value))) - abort (); + /* If this is an addressable type, we cannot pre-evaluate it. */ + if (TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value))) + abort (); - args[i].value - = expand_expr (args[i].tree_value, NULL_RTX, VOIDmode, 0); + args[i].value + = expand_expr (args[i].tree_value, NULL_RTX, VOIDmode, 0); - /* ANSI doesn't require a sequence point here, - but PCC has one, so this will avoid some problems. */ - emit_queue (); + /* ANSI doesn't require a sequence point here, + but PCC has one, so this will avoid some problems. */ + emit_queue (); - args[i].initial_value = args[i].value - = protect_from_queue (args[i].value, 0); + args[i].initial_value = args[i].value + = protect_from_queue (args[i].value, 0); - mode = TYPE_MODE (TREE_TYPE (args[i].tree_value)); - if (mode != args[i].mode) - { - args[i].value - = convert_modes (args[i].mode, mode, - args[i].value, args[i].unsignedp); + mode = TYPE_MODE (TREE_TYPE (args[i].tree_value)); + if (mode != args[i].mode) + { + args[i].value + = convert_modes (args[i].mode, mode, + args[i].value, args[i].unsignedp); #if defined(PROMOTE_FUNCTION_MODE) && !defined(PROMOTE_MODE) - /* CSE will replace this only if it contains args[i].value - pseudo, so convert it down to the declared mode using - a SUBREG. */ - if (REG_P (args[i].value) - && GET_MODE_CLASS (args[i].mode) == MODE_INT) - { - args[i].initial_value - = gen_lowpart_SUBREG (mode, args[i].value); - SUBREG_PROMOTED_VAR_P (args[i].initial_value) = 1; - SUBREG_PROMOTED_UNSIGNED_SET (args[i].initial_value, - args[i].unsignedp); - } + /* CSE will replace this only if it contains args[i].value + pseudo, so convert it down to the declared mode using + a SUBREG. */ + if (REG_P (args[i].value) + && GET_MODE_CLASS (args[i].mode) == MODE_INT) + { + args[i].initial_value + = gen_lowpart_SUBREG (mode, args[i].value); + SUBREG_PROMOTED_VAR_P (args[i].initial_value) = 1; + SUBREG_PROMOTED_UNSIGNED_SET (args[i].initial_value, + args[i].unsignedp); + } #endif - } - } + } + } } /* Given the current state of MUST_PREALLOCATE and information about diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 05b3bc803a3..01b58a1d7b1 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -360,26 +360,6 @@ construct_exit_block (void) update_bb_for_insn (exit_block); } -/* Called to move the SAVE_EXPRs for parameter declarations in a - nested function into the nested function. DATA is really the - nested FUNCTION_DECL. */ - -static tree -set_save_expr_context (tree *tp, - int *walk_subtrees, - void *data) -{ - if (TREE_CODE (*tp) == SAVE_EXPR && !SAVE_EXPR_CONTEXT (*tp)) - SAVE_EXPR_CONTEXT (*tp) = (tree) data; - /* Do not walk back into the SAVE_EXPR_CONTEXT; that will cause - circularity. */ - else if (DECL_P (*tp)) - *walk_subtrees = 0; - - return NULL; -} - - /* Translate the intermediate representation contained in the CFG from GIMPLE trees to RTL. @@ -403,15 +383,6 @@ tree_expand_cfg (void) IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl))); } - /* If the function has a variably modified type, there may be - SAVE_EXPRs in the parameter types. Their context must be set to - refer to this function; they cannot be expanded in the containing - function. */ - if (decl_function_context (current_function_decl) == current_function_decl - && variably_modified_type_p (TREE_TYPE (current_function_decl))) - walk_tree (&TREE_TYPE (current_function_decl), set_save_expr_context, - current_function_decl, NULL); - /* Prepare the rtl middle end to start recording block changes. */ reset_block_changes (); diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8e21875e4c8..dbd0ac78953 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,7 @@ +2004-07-02 Richard Henderson + + * tree.c (cp_unsave_r): Update remap_save_expr call. + 2004-07-02 Mark Mitchell PR c++/16240 diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index fb08095f94c..deee9dc8628 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -2256,7 +2256,7 @@ cp_unsave_r (tree* tp, *tp = (tree) n->value; } else if (TREE_CODE (*tp) == SAVE_EXPR) - remap_save_expr (tp, st, current_function_decl, walk_subtrees); + remap_save_expr (tp, st, walk_subtrees); else { copy_tree_r (tp, walk_subtrees, NULL); diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 2e3d55e5223..2fb962ce63a 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -10249,53 +10249,6 @@ add_bound_info (dw_die_ref subrange_die, enum dwarf_attribute bound_attr, tree b break; case SAVE_EXPR: - /* If optimization is turned on, the SAVE_EXPRs that describe how to - access the upper bound values may be bogus. If they refer to a - register, they may only describe how to get at these values at the - points in the generated code right after they have just been - computed. Worse yet, in the typical case, the upper bound values - will not even *be* computed in the optimized code (though the - number of elements will), so these SAVE_EXPRs are entirely - bogus. In order to compensate for this fact, we check here to see - if optimization is enabled, and if so, we don't add an attribute - for the (unknown and unknowable) upper bound. This should not - cause too much trouble for existing (stupid?) debuggers because - they have to deal with empty upper bounds location descriptions - anyway in order to be able to deal with incomplete array types. - Of course an intelligent debugger (GDB?) should be able to - comprehend that a missing upper bound specification in an array - type used for a storage class `auto' local array variable - indicates that the upper bound is both unknown (at compile- time) - and unknowable (at run-time) due to optimization. - - We assume that a MEM rtx is safe because gcc wouldn't put the - value there unless it was going to be used repeatedly in the - function, i.e. for cleanups. */ - if (SAVE_EXPR_RTL (bound) - && (! optimize || MEM_P (SAVE_EXPR_RTL (bound)))) - { - dw_die_ref ctx = lookup_decl_die (current_function_decl); - dw_die_ref decl_die = new_die (DW_TAG_variable, ctx, bound); - rtx loc = SAVE_EXPR_RTL (bound); - - /* If the RTL for the SAVE_EXPR is memory, handle the case where - it references an outer function's frame. */ - if (MEM_P (loc)) - { - rtx new_addr = fix_lexical_addr (XEXP (loc, 0), bound); - - if (XEXP (loc, 0) != new_addr) - loc = gen_rtx_MEM (GET_MODE (loc), new_addr); - } - - add_AT_flag (decl_die, DW_AT_artificial, 1); - add_type_attribute (decl_die, TREE_TYPE (bound), 1, 0, ctx); - add_AT_location_description (decl_die, DW_AT_location, - loc_descriptor (loc, true)); - add_AT_die_ref (subrange_die, bound_attr, decl_die); - } - - /* Else leave out the attribute. */ break; case VAR_DECL: @@ -10331,15 +10284,6 @@ add_bound_info (dw_die_ref subrange_die, enum dwarf_attribute bound_attr, tree b else ctx = lookup_decl_die (current_function_decl); - /* If we weren't able to find a context, it's most likely the case - that we are processing the return type of the function. So - make a SAVE_EXPR to point to it and have the limbo DIE code - find the proper die. The save_expr function doesn't always - make a SAVE_EXPR, so do it ourselves. */ - if (ctx == 0) - bound = build (SAVE_EXPR, TREE_TYPE (bound), bound, - current_function_decl, NULL_TREE); - decl_die = new_die (DW_TAG_variable, ctx, bound); add_AT_flag (decl_die, DW_AT_artificial, 1); add_type_attribute (decl_die, TREE_TYPE (bound), 1, 0, ctx); @@ -13735,15 +13679,6 @@ dwarf2out_finish (const char *filename) add_child_die (origin->die_parent, die); else if (die == comp_unit_die) ; - /* If this was an expression for a bound involved in a function - return type, it may be a SAVE_EXPR for which we weren't able - to find a DIE previously. So try now. */ - else if (node->created_for - && TREE_CODE (node->created_for) == SAVE_EXPR - && 0 != (origin = (lookup_decl_die - (SAVE_EXPR_CONTEXT - (node->created_for))))) - add_child_die (origin, die); else if (errorcount > 0 || sorrycount > 0) /* It's OK to be confused by errors in the input. */ add_child_die (comp_unit_die, die); diff --git a/gcc/expr.c b/gcc/expr.c index df354228fec..d3951fed769 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)) diff --git a/gcc/fold-const.c b/gcc/fold-const.c index f8408c4d693..bfd17989003 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -2661,7 +2661,7 @@ twoval_comparison_p (tree arg, tree *cval1, tree *cval2, int *save_p) || code == COMPOUND_EXPR)) class = '2'; - else if (class == 'e' && code == SAVE_EXPR && SAVE_EXPR_RTL (arg) == 0 + else if (class == 'e' && code == SAVE_EXPR && ! TREE_SIDE_EFFECTS (TREE_OPERAND (arg, 0))) { /* If we've already found a CVAL1 or CVAL2, this expression is @@ -5971,10 +5971,6 @@ fold (tree expr) if all operands are constant. */ int wins = 1; - /* 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. */ if (kind == 'c') return t; @@ -8985,14 +8981,7 @@ fold_checksum_tree (tree expr, struct md5_ctx *ctx, htab_t ht) return; *slot = expr; code = TREE_CODE (expr); - if (code == SAVE_EXPR && SAVE_EXPR_NOPLACEHOLDER (expr)) - { - /* Allow SAVE_EXPR_NOPLACEHOLDER flag to be modified. */ - memcpy (buf, expr, tree_size (expr)); - expr = (tree) buf; - SAVE_EXPR_NOPLACEHOLDER (expr) = 0; - } - else if (TREE_CODE_CLASS (code) == 'd' && DECL_ASSEMBLER_NAME_SET_P (expr)) + if (TREE_CODE_CLASS (code) == 'd' && DECL_ASSEMBLER_NAME_SET_P (expr)) { /* Allow DECL_ASSEMBLER_NAME to be modified. */ memcpy (buf, expr, tree_size (expr)); @@ -9051,7 +9040,6 @@ fold_checksum_tree (tree expr, struct md5_ctx *ctx, htab_t ht) case 'e': switch (code) { - case SAVE_EXPR: len = 2; break; case GOTO_SUBROUTINE_EXPR: len = 0; break; case WITH_CLEANUP_EXPR: len = 2; break; default: break; diff --git a/gcc/function.c b/gcc/function.c index 1d17c4fa591..b6d37896a8e 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -436,7 +436,6 @@ free_after_compilation (struct function *f) f->x_nonlocal_goto_handler_labels = NULL; f->x_return_label = NULL; f->x_naked_return_label = NULL; - f->x_save_expr_regs = NULL; f->x_stack_slot_list = NULL; f->x_tail_recursion_reentry = NULL; f->x_arg_pointer_save_area = NULL; @@ -1305,9 +1304,7 @@ put_var_into_stack (tree decl, int rescan) context = decl_function_context (decl); /* Get the current rtl used for this object and its original mode. */ - orig_reg = reg = (TREE_CODE (decl) == SAVE_EXPR - ? SAVE_EXPR_RTL (decl) - : DECL_RTL_IF_SET (decl)); + orig_reg = reg = DECL_RTL_IF_SET (decl); /* No need to do anything if decl has no rtx yet since in that case caller is setting TREE_ADDRESSABLE @@ -2824,10 +2821,8 @@ gen_mem_addressof (rtx reg, tree decl, int rescan) if (decl) { tree type = TREE_TYPE (decl); - enum machine_mode decl_mode - = (DECL_P (decl) ? DECL_MODE (decl) : TYPE_MODE (TREE_TYPE (decl))); - rtx decl_rtl = (TREE_CODE (decl) == SAVE_EXPR ? SAVE_EXPR_RTL (decl) - : DECL_RTL_IF_SET (decl)); + enum machine_mode decl_mode = DECL_MODE (decl); + rtx decl_rtl = DECL_RTL_IF_SET (decl); PUT_MODE (reg, decl_mode); diff --git a/gcc/function.h b/gcc/function.h index 7043d0bff3f..4a057625bcf 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -243,10 +243,6 @@ struct function GTY(()) on machines which require execution of the epilogue on all returns. */ rtx x_naked_return_label; - /* List (chain of EXPR_LISTs) of pseudo-regs of SAVE_EXPRs. - So we can mark them all live at the end of the function, if nonopt. */ - rtx x_save_expr_regs; - /* List (chain of EXPR_LISTs) of all stack slots in this function. Made for the sake of unshare_all_rtl. */ rtx x_stack_slot_list; @@ -506,7 +502,6 @@ extern int trampolines_created; #define parm_reg_stack_loc (cfun->x_parm_reg_stack_loc) #define return_label (cfun->x_return_label) #define naked_return_label (cfun->x_naked_return_label) -#define save_expr_regs (cfun->x_save_expr_regs) #define stack_slot_list (cfun->x_stack_slot_list) #define parm_birth_insn (cfun->x_parm_birth_insn) #define frame_offset (cfun->x_frame_offset) diff --git a/gcc/gengtype.c b/gcc/gengtype.c index 99b79901a5f..55a26de0128 100644 --- a/gcc/gengtype.c +++ b/gcc/gengtype.c @@ -650,7 +650,6 @@ adjust_field_tree_exp (type_p t, options_p opt ATTRIBUTE_UNUSED) int first_rtl; int num_rtl; } data[] = { - { "SAVE_EXPR", 2, 1 }, { "GOTO_SUBROUTINE_EXPR", 0, 2 }, { "WITH_CLEANUP_EXPR", 2, 1 }, }; diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 135423a5f64..efa1c0cd2cd 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,7 @@ +2004-07-02 Richard Henderson + + * jcf-write.c (generate_bytecode_insns ): Rewrite. + 2004-07-01 Richard Henderson * class.c (registerClass_libfunc): Remove. diff --git a/gcc/java/jcf-write.c b/gcc/java/jcf-write.c index 42136c6d727..09b39da91a3 100644 --- a/gcc/java/jcf-write.c +++ b/gcc/java/jcf-write.c @@ -2197,35 +2197,24 @@ generate_bytecode_insns (tree exp, int target, struct jcf_partial *state) } break; case SAVE_EXPR: - /* Because the state associated with a SAVE_EXPR tree node must - be a RTL expression, we use it to store the DECL_LOCAL_INDEX - of a temporary variable in a CONST_INT. */ - if (! SAVE_EXPR_RTL (exp)) + /* The first time through, the argument of the SAVE_EXPR will be + something complex. Evaluate it, and replace the argument with + a VAR_DECL that holds the result. */ + arg = TREE_OPERAND (exp, 0); + if (TREE_CODE (arg) != VAR_DECL || DECL_NAME (arg)) { tree type = TREE_TYPE (exp); tree decl = build_decl (VAR_DECL, NULL_TREE, type); - generate_bytecode_insns (TREE_OPERAND (exp, 0), - STACK_TARGET, state); + generate_bytecode_insns (arg, STACK_TARGET, state); localvar_alloc (decl, state); - SAVE_EXPR_RTL (exp) = GEN_INT (DECL_LOCAL_INDEX (decl)); + TREE_OPERAND (exp, 0) = decl; emit_dup (TYPE_IS_WIDE (type) ? 2 : 1, 0, state); emit_store (decl, state); } else { - /* The following code avoids creating a temporary DECL just - to pass to emit_load. This code could be factored with - the similar implementation in emit_load_or_store. */ tree type = TREE_TYPE (exp); - int kind = adjust_typed_op (type, 4); - int index = (int) INTVAL (SAVE_EXPR_RTL (exp)); - if (index <= 3) - { - RESERVE (1); /* [ilfda]load_[0123] */ - OP1 (OPCODE_iload + 5 + 4*kind + index); - } - else /* [ilfda]load */ - maybe_wide (OPCODE_iload + kind, index, state); + emit_load (arg, state); NOTE_PUSH (TYPE_IS_WIDE (type) ? 2 : 1); } break; diff --git a/gcc/print-tree.c b/gcc/print-tree.c index 055f8f36097..320879775c3 100644 --- a/gcc/print-tree.c +++ b/gcc/print-tree.c @@ -578,8 +578,6 @@ print_node (FILE *file, const char *prefix, tree node, int indent) case 's': if (TREE_CODE (node) == BIT_FIELD_REF && BIT_FIELD_REF_UNSIGNED (node)) fputs (" unsigned", file); - else if (TREE_CODE (node) == SAVE_EXPR && SAVE_EXPR_NOPLACEHOLDER (node)) - fputs (" noplaceholder", file); if (TREE_CODE (node) == BIND_EXPR) { print_node (file, "vars", TREE_OPERAND (node, 0), indent + 4); diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 94bc46fb564..cf97159b5c5 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -66,7 +66,6 @@ static void place_union_field (record_layout_info, tree); static int excess_unit_span (HOST_WIDE_INT, HOST_WIDE_INT, HOST_WIDE_INT, HOST_WIDE_INT, tree); #endif -static void force_type_save_exprs_1 (tree); extern void debug_rli (record_layout_info); /* SAVE_EXPRs for sizes of types and decls, waiting to be expanded. */ @@ -146,8 +145,6 @@ variable_size (tree size) not wish to do that here; the array-size is the same in both places. */ save = skip_simple_arithmetic (size); - if (TREE_CODE (save) == SAVE_EXPR) - SAVE_EXPR_PERSISTENT_P (save) = 1; if (cfun && cfun->x_dont_save_pending_sizes_p) /* The front-end doesn't want us to keep a list of the expressions @@ -168,60 +165,6 @@ variable_size (tree size) return size; } - -/* Given a type T, force elaboration of any SAVE_EXPRs used in the definition - of that type. */ - -void -force_type_save_exprs (tree t) -{ - tree field; - - switch (TREE_CODE (t)) - { - case ERROR_MARK: - return; - - case ARRAY_TYPE: - case SET_TYPE: - case VECTOR_TYPE: - /* It's probably overly-conservative to force elaboration of bounds and - also the sizes, but it's better to be safe than sorry. */ - force_type_save_exprs_1 (TYPE_MIN_VALUE (TYPE_DOMAIN (t))); - force_type_save_exprs_1 (TYPE_MAX_VALUE (TYPE_DOMAIN (t))); - break; - - case RECORD_TYPE: - case UNION_TYPE: - case QUAL_UNION_TYPE: - for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field)) - if (TREE_CODE (field) == FIELD_DECL) - { - force_type_save_exprs (TREE_TYPE (field)); - force_type_save_exprs_1 (DECL_FIELD_OFFSET (field)); - } - break; - - default: - break; - } - - force_type_save_exprs_1 (TYPE_SIZE (t)); - force_type_save_exprs_1 (TYPE_SIZE_UNIT (t)); -} - -/* Utility routine of above, to verify that SIZE has been elaborated and - do so it it is a SAVE_EXPR and has not been. */ - -static void -force_type_save_exprs_1 (tree size) -{ - if (size - && (size = skip_simple_arithmetic (size)) - && TREE_CODE (size) == SAVE_EXPR - && !SAVE_EXPR_RTL (size)) - expand_expr (size, NULL_RTX, VOIDmode, 0); -} #ifndef MAX_FIXED_MODE_SIZE #define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (DImode) diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index aa579c34186..d2d0fd4bab8 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -528,8 +528,7 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data) else if (TREE_CODE (*tp) == STATEMENT_LIST) copy_statement_list (tp); else if (TREE_CODE (*tp) == SAVE_EXPR) - remap_save_expr (tp, id->decl_map, VARRAY_TREE (id->fns, 0), - walk_subtrees); + remap_save_expr (tp, id->decl_map, walk_subtrees); else if (TREE_CODE (*tp) == UNSAVE_EXPR) /* UNSAVE_EXPRs should not be generated until expansion time. */ abort (); @@ -2318,11 +2317,10 @@ copy_tree_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) /* The SAVE_EXPR pointed to by TP is being copied. If ST contains information indicating to what new SAVE_EXPR this one should be mapped, - use that one. Otherwise, create a new node and enter it in ST. FN is the - function into which the copy will be placed. */ + use that one. Otherwise, create a new node and enter it in ST. */ void -remap_save_expr (tree *tp, void *st_, tree fn, int *walk_subtrees) +remap_save_expr (tree *tp, void *st_, int *walk_subtrees) { splay_tree st = (splay_tree) st_; splay_tree_node n; @@ -2336,11 +2334,6 @@ remap_save_expr (tree *tp, void *st_, tree fn, int *walk_subtrees) { t = copy_node (*tp); - /* The SAVE_EXPR is now part of the function into which we - are inlining this body. */ - SAVE_EXPR_CONTEXT (t) = fn; - /* And we haven't evaluated it yet. */ - SAVE_EXPR_RTL (t) = NULL_RTX; /* Remember this SAVE_EXPR. */ splay_tree_insert (st, (splay_tree_key) *tp, (splay_tree_value) t); /* Make sure we don't remap an already-remapped SAVE_EXPR. */ @@ -2412,7 +2405,7 @@ unsave_r (tree *tp, int *walk_subtrees, void *data) else if (TREE_CODE (*tp) == BIND_EXPR) copy_bind_expr (tp, walk_subtrees, id); else if (TREE_CODE (*tp) == SAVE_EXPR) - remap_save_expr (tp, st, current_function_decl, walk_subtrees); + remap_save_expr (tp, st, walk_subtrees); else { copy_tree_r (tp, walk_subtrees, NULL); diff --git a/gcc/tree-inline.h b/gcc/tree-inline.h index 142f5569f58..4619e314bef 100644 --- a/gcc/tree-inline.h +++ b/gcc/tree-inline.h @@ -29,7 +29,7 @@ bool tree_inlinable_function_p (tree); tree copy_tree_r (tree*, int*, void*); void clone_body (tree, tree, void*); tree save_body (tree, tree *); -void remap_save_expr (tree*, void*, tree, int*); +void remap_save_expr (tree*, void*, int*); int estimate_num_insns (tree expr); /* 0 if we should not perform inlining. diff --git a/gcc/tree.c b/gcc/tree.c index 38e94ef70af..bc6d3aec1eb 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -1375,8 +1375,7 @@ save_expr (tree expr) if (contains_placeholder_p (inner)) return t; - t = build3 (SAVE_EXPR, TREE_TYPE (expr), t, current_function_decl, - NULL_TREE); + t = build1 (SAVE_EXPR, TREE_TYPE (expr), t); /* This expression might be placed ahead of a jump to ensure that the value was computed on both sides of the jump. So make sure it isn't @@ -1451,8 +1450,6 @@ first_rtl_op (enum tree_code code) { switch (code) { - case SAVE_EXPR: - return 2; case GOTO_SUBROUTINE_EXPR: return 0; case WITH_CLEANUP_EXPR: @@ -1511,11 +1508,6 @@ unsave_expr_1 (tree expr) { switch (TREE_CODE (expr)) { - case SAVE_EXPR: - if (! SAVE_EXPR_PERSISTENT_P (expr)) - SAVE_EXPR_RTL (expr) = 0; - break; - case TARGET_EXPR: /* Don't mess with a TARGET_EXPR that hasn't been expanded. It's OK for this to happen if it was part of a subtree that @@ -1640,7 +1632,6 @@ bool contains_placeholder_p (tree exp) { enum tree_code code; - int result; if (!exp) return 0; @@ -1678,19 +1669,6 @@ contains_placeholder_p (tree exp) || CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1)) || CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 2))); - case SAVE_EXPR: - /* If we already know this doesn't have a placeholder, don't - check again. */ - if (SAVE_EXPR_NOPLACEHOLDER (exp) || SAVE_EXPR_RTL (exp) != 0) - return 0; - - SAVE_EXPR_NOPLACEHOLDER (exp) = 1; - result = CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0)); - if (result) - SAVE_EXPR_NOPLACEHOLDER (exp) = 0; - - return result; - default: break; } @@ -4781,9 +4759,6 @@ decl_function_context (tree decl) if (TREE_CODE (decl) == ERROR_MARK) return 0; - if (TREE_CODE (decl) == SAVE_EXPR) - context = SAVE_EXPR_CONTEXT (decl); - /* C++ virtual functions use DECL_CONTEXT for the class of the vtable where we look up the function at runtime. Such functions always take a first argument of type 'pointer to real context'. diff --git a/gcc/tree.def b/gcc/tree.def index bf80871793a..bb49981a133 100644 --- a/gcc/tree.def +++ b/gcc/tree.def @@ -723,10 +723,9 @@ DEFTREECODE (NON_LVALUE_EXPR, "non_lvalue_expr", '1', 1) DEFTREECODE (VIEW_CONVERT_EXPR, "view_convert_expr", '1', 1) /* Represents something we computed once and will use multiple times. - First operand is that expression. Second is the function decl - in which the SAVE_EXPR was created. The third operand is the RTL, - nonzero only after the expression has been computed. */ -DEFTREECODE (SAVE_EXPR, "save_expr", 'e', 3) + First operand is that expression. After it is evaluated once, it + will be replaced by the temporary variable that holds the value. */ +DEFTREECODE (SAVE_EXPR, "save_expr", 'e', 1) /* 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, diff --git a/gcc/tree.h b/gcc/tree.h index b91ac6c19d0..eff90686c73 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -282,8 +282,6 @@ struct tree_common GTY(()) all decls BIT_FIELD_REF_UNSIGNED in BIT_FIELD_REF - SAVE_EXPR_NOPLACEHOLDER in - SAVE_EXPR asm_written_flag: @@ -1030,19 +1028,6 @@ struct tree_vec GTY(()) && VOID_TYPE_P (TREE_TYPE (NODE)) \ && integer_zerop (TREE_OPERAND (NODE, 0))) -/* In a SAVE_EXPR node. */ -#define SAVE_EXPR_CONTEXT(NODE) TREE_OPERAND_CHECK_CODE (NODE, SAVE_EXPR, 1) -#define SAVE_EXPR_RTL(NODE) TREE_RTL_OPERAND_CHECK (NODE, SAVE_EXPR, 2) - -#define SAVE_EXPR_NOPLACEHOLDER(NODE) \ - (SAVE_EXPR_CHECK (NODE)->common.unsigned_flag) - -/* Nonzero if the SAVE_EXPRs value should be kept, even if it occurs - both in normal code and in a handler. (Normally, in a handler, all - SAVE_EXPRs are unsaved, meaning that their values are - recalculated.) */ -#define SAVE_EXPR_PERSISTENT_P(NODE) TREE_ASM_WRITTEN (SAVE_EXPR_CHECK (NODE)) - /* In a WITH_CLEANUP_EXPR node. */ #define WITH_CLEANUP_EXPR_RTL(NODE) \ TREE_RTL_OPERAND_CHECK (NODE, WITH_CLEANUP_EXPR, 2) @@ -3210,11 +3195,6 @@ extern tree substitute_placeholder_in_expr (tree, tree); extern tree variable_size (tree); -/* Given a type T, force elaboration of any SAVE_EXPRs used in the definition - of that type. */ - -extern void force_type_save_exprs (tree); - /* stabilize_reference (EXP) returns a reference equivalent to EXP but it can be used multiple times and only evaluate the subexpressions once. */