X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcalls.c;h=f6bc970b71b42aa27e15cebda967526f7dce9e69;hb=6a167a57b73f180e3bdb2482a43db877c73f3084;hp=ac8398271252ac6cf748b436865fec9b4fc2cbc5;hpb=9a27561fb113a16c47844119231b5edfa6b13c01;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/calls.c b/gcc/calls.c index ac839827125..f6bc970b71b 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see #include "tm.h" #include "rtl.h" #include "tree.h" +#include "gimple.h" #include "flags.h" #include "expr.h" #include "optabs.h" @@ -41,6 +42,7 @@ along with GCC; see the file COPYING3. If not see #include "cgraph.h" #include "except.h" #include "dbgcnt.h" +#include "tree-flow.h" /* Like PREFERRED_STACK_BOUNDARY but in units of bytes, not bits. */ #define STACK_BYTES (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT) @@ -129,12 +131,12 @@ static int store_one_arg (struct arg_data *, rtx, int, int, int); static void store_unaligned_arguments_into_pseudos (struct arg_data *, int); static int finalize_must_preallocate (int, int, struct arg_data *, struct args_size *); -static void precompute_arguments (int, int, struct arg_data *); -static int compute_argument_block_size (int, struct args_size *, tree, int); +static void precompute_arguments (int, struct arg_data *); +static int compute_argument_block_size (int, struct args_size *, tree, tree, int); static void initialize_argument_information (int, struct arg_data *, struct args_size *, int, tree, tree, - tree, CUMULATIVE_ARGS *, int, + tree, tree, CUMULATIVE_ARGS *, int, rtx *, int *, int *, int *, bool *, bool); static void compute_argument_addresses (struct arg_data *, rtx, int); @@ -377,27 +379,23 @@ emit_call_1 (rtx funexp, tree fntree, tree fndecl ATTRIBUTE_UNUSED, /* If this call can't throw, attach a REG_EH_REGION reg note to that effect. */ if (ecf_flags & ECF_NOTHROW) - REG_NOTES (call_insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, const0_rtx, - REG_NOTES (call_insn)); + add_reg_note (call_insn, REG_EH_REGION, const0_rtx); else { - int rn = lookup_stmt_eh_region (fntree); + int rn = lookup_expr_eh_region (fntree); /* If rn < 0, then either (1) tree-ssa not used or (2) doesn't throw, which we already took care of. */ if (rn > 0) - REG_NOTES (call_insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (rn), - REG_NOTES (call_insn)); + add_reg_note (call_insn, REG_EH_REGION, GEN_INT (rn)); } if (ecf_flags & ECF_NORETURN) - REG_NOTES (call_insn) = gen_rtx_EXPR_LIST (REG_NORETURN, const0_rtx, - REG_NOTES (call_insn)); + add_reg_note (call_insn, REG_NORETURN, const0_rtx); if (ecf_flags & ECF_RETURNS_TWICE) { - REG_NOTES (call_insn) = gen_rtx_EXPR_LIST (REG_SETJMP, const0_rtx, - REG_NOTES (call_insn)); + add_reg_note (call_insn, REG_SETJMP, const0_rtx); cfun->calls_setjmp = 1; } @@ -417,6 +415,10 @@ emit_call_1 (rtx funexp, tree fntree, tree fndecl ATTRIBUTE_UNUSED, rounded_stack_size -= n_popped; rounded_stack_size_rtx = GEN_INT (rounded_stack_size); stack_pointer_delta -= n_popped; + + /* If popup is needed, stack realign must use DRAP */ + if (SUPPORTS_STACK_ALIGNMENT) + crtl->need_drap = true; } if (!ACCUMULATE_OUTGOING_ARGS) @@ -546,7 +548,26 @@ setjmp_call_p (const_tree fndecl) return special_function_p (fndecl, 0) & ECF_RETURNS_TWICE; } + +/* Return true if STMT is an alloca call. */ + +bool +gimple_alloca_call_p (const_gimple stmt) +{ + tree fndecl; + + if (!is_gimple_call (stmt)) + return false; + + fndecl = gimple_call_fndecl (stmt); + if (fndecl && (special_function_p (fndecl, 0) & ECF_MAY_BE_ALLOCA)) + return true; + + return false; +} + /* Return true when exp contains alloca call. */ + bool alloca_call_p (const_tree exp) { @@ -692,7 +713,8 @@ precompute_register_parameters (int num_actuals, struct arg_data *args, || (GET_CODE (args[i].value) == SUBREG && REG_P (SUBREG_REG (args[i].value))))) && args[i].mode != BLKmode - && rtx_cost (args[i].value, SET) > COSTS_N_INSNS (1) + && rtx_cost (args[i].value, SET, optimize_insn_for_speed_p ()) + > COSTS_N_INSNS (1) && ((SMALL_REGISTER_CLASSES && *reg_parm_seen) || optimize)) args[i].value = copy_to_mode_reg (args[i].mode, args[i].value); @@ -815,7 +837,8 @@ store_unaligned_arguments_into_pseudos (struct arg_data *args, int num_actuals) for (i = 0; i < num_actuals; i++) if (args[i].reg != 0 && ! args[i].pass_on_stack && args[i].mode == BLKmode - && (TYPE_ALIGN (TREE_TYPE (args[i].tree_value)) + && MEM_P (args[i].value) + && (MEM_ALIGN (args[i].value) < (unsigned int) MIN (BIGGEST_ALIGNMENT, BITS_PER_WORD))) { int bytes = int_size_in_bytes (TREE_TYPE (args[i].tree_value)); @@ -915,7 +938,7 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, struct args_size *args_size, int n_named_args ATTRIBUTE_UNUSED, tree exp, tree struct_value_addr_value, - tree fndecl, + tree fndecl, tree fntype, CUMULATIVE_ARGS *args_so_far, int reg_parm_stack_space, rtx *old_stack_level, int *old_pending_adj, @@ -1040,7 +1063,6 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, if (*ecf_flags & ECF_CONST) *ecf_flags &= ~(ECF_CONST | ECF_LOOPING_CONST_OR_PURE); - *ecf_flags &= ~ECF_LIBCALL_BLOCK; } else { @@ -1049,10 +1071,10 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, rtx copy; if (!COMPLETE_TYPE_P (type) - || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST - || (flag_stack_check && ! STACK_CHECK_BUILTIN - && (0 < compare_tree_int (TYPE_SIZE_UNIT (type), - STACK_CHECK_MAX_VAR_SIZE)))) + || TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST + || (flag_stack_check == GENERIC_STACK_CHECK + && compare_tree_int (TYPE_SIZE_UNIT (type), + STACK_CHECK_MAX_VAR_SIZE) > 0)) { /* This is a variable-sized object. Make space on the stack for it. */ @@ -1075,8 +1097,6 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, store_expr (args[i].tree_value, copy, 0, false); - *ecf_flags &= ~(ECF_LIBCALL_BLOCK); - /* Just change the const function to pure and then let the next test clear the pure based on callee_copies. */ @@ -1099,7 +1119,9 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, mode = TYPE_MODE (type); unsignedp = TYPE_UNSIGNED (type); - if (targetm.calls.promote_function_args (fndecl ? TREE_TYPE (fndecl) : 0)) + if (targetm.calls.promote_function_args (fndecl + ? TREE_TYPE (fndecl) + : fntype)) mode = promote_mode (type, mode, &unsignedp, 1); args[i].unsignedp = unsignedp; @@ -1140,11 +1162,6 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, || (args[i].pass_on_stack && args[i].reg != 0)) *must_preallocate = 1; - /* If this is an addressable type, we cannot pre-evaluate it. Thus, - we cannot consider this function call constant. */ - if (TREE_ADDRESSABLE (type)) - *ecf_flags &= ~ECF_LIBCALL_BLOCK; - /* Compute the stack-size of this argument. */ if (args[i].reg == 0 || args[i].partial != 0 || reg_parm_stack_space > 0 @@ -1190,6 +1207,7 @@ static int compute_argument_block_size (int reg_parm_stack_space, struct args_size *args_size, tree fndecl ATTRIBUTE_UNUSED, + tree fntype ATTRIBUTE_UNUSED, int preferred_stack_boundary ATTRIBUTE_UNUSED) { int unadjusted_args_size = args_size->constant; @@ -1227,7 +1245,7 @@ compute_argument_block_size (int reg_parm_stack_space, /* The area corresponding to register parameters is not to count in the size of the block we need. So make the adjustment. */ - if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? NULL_TREE : TREE_TYPE (fndecl)))) + if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl)))) args_size->var = size_binop (MINUS_EXPR, args_size->var, ssize_int (reg_parm_stack_space)); @@ -1248,7 +1266,7 @@ compute_argument_block_size (int reg_parm_stack_space, args_size->constant = MAX (args_size->constant, reg_parm_stack_space); - if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? NULL_TREE : TREE_TYPE (fndecl)))) + if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl)))) args_size->constant -= reg_parm_stack_space; } return unadjusted_args_size; @@ -1265,7 +1283,7 @@ compute_argument_block_size (int reg_parm_stack_space, precomputed argument. */ static void -precompute_arguments (int flags, int num_actuals, struct arg_data *args) +precompute_arguments (int num_actuals, struct arg_data *args) { int i; @@ -1279,15 +1297,14 @@ precompute_arguments (int flags, int num_actuals, struct arg_data *args) which have already been stored into the stack. (we have code to avoid such case by saving the outgoing stack arguments, but it results in worse code) */ - if ((flags & ECF_LIBCALL_BLOCK) == 0 && !ACCUMULATE_OUTGOING_ARGS) + if (!ACCUMULATE_OUTGOING_ARGS) return; for (i = 0; i < num_actuals; i++) { enum machine_mode mode; - if ((flags & ECF_LIBCALL_BLOCK) == 0 - && TREE_CODE (args[i].tree_value) != CALL_EXPR) + if (TREE_CODE (args[i].tree_value) != CALL_EXPR) continue; /* If this is an addressable type, we cannot pre-evaluate it. */ @@ -1865,7 +1882,7 @@ shift_return_value (enum machine_mode mode, bool left_p, rtx value) static rtx avoid_likely_spilled_reg (rtx x) { - rtx new; + rtx new_rtx; if (REG_P (x) && HARD_REGISTER_P (x) @@ -1876,10 +1893,10 @@ avoid_likely_spilled_reg (rtx x) and the whole point of this function is to avoid using the hard register directly in such a situation. */ generating_concat_p = 0; - new = gen_reg_rtx (GET_MODE (x)); + new_rtx = gen_reg_rtx (GET_MODE (x)); generating_concat_p = 1; - emit_move_insn (new, x); - return new; + emit_move_insn (new_rtx, x); + return new_rtx; } return x; } @@ -2063,21 +2080,20 @@ expand_call (tree exp, rtx target, int ignore) } #ifdef REG_PARM_STACK_SPACE - reg_parm_stack_space = REG_PARM_STACK_SPACE (fndecl); + reg_parm_stack_space = REG_PARM_STACK_SPACE (!fndecl ? fntype : fndecl); #endif - if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? NULL_TREE : TREE_TYPE (fndecl))) + if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl))) && reg_parm_stack_space > 0 && PUSH_ARGS) must_preallocate = 1; /* Set up a place to return a structure. */ /* Cater to broken compilers. */ - if (aggregate_value_p (exp, fndecl)) + if (aggregate_value_p (exp, (!fndecl ? fntype : fndecl))) { /* This call returns a big structure. */ - flags &= ~(ECF_CONST | ECF_PURE | ECF_LOOPING_CONST_OR_PURE - | ECF_LIBCALL_BLOCK); + flags &= ~(ECF_CONST | ECF_PURE | ECF_LOOPING_CONST_OR_PURE); #ifdef PCC_STATIC_STRUCT_RETURN { @@ -2224,29 +2240,21 @@ expand_call (tree exp, rtx target, int ignore) n_named_args = num_actuals; /* Make a vector to hold all the information about each arg. */ - args = alloca (num_actuals * sizeof (struct arg_data)); + args = XALLOCAVEC (struct arg_data, num_actuals); memset (args, 0, num_actuals * sizeof (struct arg_data)); /* Build up entries in the ARGS array, compute the size of the arguments into ARGS_SIZE, etc. */ initialize_argument_information (num_actuals, args, &args_size, n_named_args, exp, - structure_value_addr_value, fndecl, + structure_value_addr_value, fndecl, fntype, &args_so_far, reg_parm_stack_space, &old_stack_level, &old_pending_adj, &must_preallocate, &flags, &try_tail_call, CALL_FROM_THUNK_P (exp)); if (args_size.var) - { - /* If this function requires a variable-sized argument list, don't - try to make a cse'able block for this call. We may be able to - do this eventually, but it is too complicated to keep track of - what insns go in the cse'able block and which don't. */ - - flags &= ~ECF_LIBCALL_BLOCK; - must_preallocate = 1; - } + must_preallocate = 1; /* Now make final decision about preallocating stack space. */ must_preallocate = finalize_must_preallocate (must_preallocate, @@ -2273,7 +2281,7 @@ expand_call (tree exp, rtx target, int ignore) if (currently_expanding_call++ != 0 || !flag_optimize_sibling_calls || args_size.var - || lookup_stmt_eh_region (exp) >= 0 + || lookup_expr_eh_region (exp) >= 0 || dbg_cnt (tail_call) == false) try_tail_call = 0; @@ -2290,6 +2298,12 @@ expand_call (tree exp, rtx target, int ignore) It does not seem worth the effort since few optimizable sibling calls will return a structure. */ || structure_value_addr != NULL_RTX +#ifdef REG_PARM_STACK_SPACE + /* If outgoing reg parm stack space changes, we can not do sibcall. */ + || (OUTGOING_REG_PARM_STACK_SPACE (funtype) + != OUTGOING_REG_PARM_STACK_SPACE (TREE_TYPE (current_function_decl))) + || (reg_parm_stack_space != REG_PARM_STACK_SPACE (fndecl)) +#endif /* Check whether the target is able to optimize the call into a sibcall. */ || !targetm.function_ok_for_sibcall (fndecl, exp) @@ -2317,11 +2331,12 @@ expand_call (tree exp, rtx target, int ignore) try_tail_call = 0; /* Ensure current function's preferred stack boundary is at least - what we need. We don't have to increase alignment for recursive - functions. */ - if (crtl->preferred_stack_boundary < preferred_stack_boundary - && fndecl != current_function_decl) + what we need. Stack alignment may also increase preferred stack + boundary. */ + if (crtl->preferred_stack_boundary < preferred_stack_boundary) crtl->preferred_stack_boundary = preferred_stack_boundary; + else + preferred_stack_boundary = crtl->preferred_stack_boundary; preferred_unit_stack_boundary = preferred_stack_boundary / BITS_PER_UNIT; @@ -2377,18 +2392,13 @@ expand_call (tree exp, rtx target, int ignore) || pass == 0) do_pending_stack_adjust (); - /* When calling a const function, we must pop the stack args right away, - so that the pop is deleted or moved with the call. */ - if (pass && (flags & ECF_LIBCALL_BLOCK)) - NO_DEFER_POP; - /* Precompute any arguments as needed. */ if (pass) - precompute_arguments (flags, num_actuals, args); + precompute_arguments (num_actuals, args); /* Now we are about to start emitting insns that can be deleted if a libcall is deleted. */ - if (pass && (flags & (ECF_LIBCALL_BLOCK | ECF_MALLOC))) + if (pass && (flags & ECF_MALLOC)) start_sequence (); if (pass == 0 && crtl->stack_protect_guard) @@ -2403,7 +2413,7 @@ expand_call (tree exp, rtx target, int ignore) unadjusted_args_size = compute_argument_block_size (reg_parm_stack_space, &adjusted_args_size, - fndecl, + fndecl, fntype, (pass == 0 ? 0 : preferred_stack_boundary)); @@ -2413,7 +2423,7 @@ expand_call (tree exp, rtx target, int ignore) incoming argument block. */ if (pass == 0) { - argblock = virtual_incoming_args_rtx; + argblock = crtl->args.internal_arg_pointer; argblock #ifdef STACK_GROWS_DOWNWARD = plus_constant (argblock, crtl->args.pretend_args_size); @@ -2479,7 +2489,7 @@ expand_call (tree exp, rtx target, int ignore) /* Since we will be writing into the entire argument area, the map must be allocated for its entire size, not just the part that is the responsibility of the caller. */ - if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? NULL_TREE : TREE_TYPE (fndecl)))) + if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl)))) needed += reg_parm_stack_space; #ifdef ARGS_GROW_DOWNWARD @@ -2578,7 +2588,7 @@ expand_call (tree exp, rtx target, int ignore) { rtx push_size = GEN_INT (adjusted_args_size.constant - + (OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? NULL + + (OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl))) ? 0 : reg_parm_stack_space)); if (old_stack_level == 0) @@ -2626,7 +2636,6 @@ expand_call (tree exp, rtx target, int ignore) /* When the stack adjustment is pending, we get better code by combining the adjustments. */ if (pending_stack_adjust - && ! (flags & ECF_LIBCALL_BLOCK) && ! inhibit_defer_pop) { pending_stack_adjust @@ -2750,7 +2759,7 @@ expand_call (tree exp, rtx target, int ignore) /* If register arguments require space on the stack and stack space was not preallocated, allocate stack space here for arguments passed in registers. */ - if (OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? NULL_TREE : TREE_TYPE (fndecl))) + if (OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl))) && !ACCUMULATE_OUTGOING_ARGS && must_preallocate == 0 && reg_parm_stack_space > 0) anti_adjust_stack (GEN_INT (reg_parm_stack_space)); @@ -2826,65 +2835,7 @@ expand_call (tree exp, rtx target, int ignore) valreg = gen_rtx_REG (TYPE_MODE (TREE_TYPE (exp)), REGNO (valreg)); } - /* If call is cse'able, make appropriate pair of reg-notes around it. - Test valreg so we don't crash; may safely ignore `const' - if return type is void. Disable for PARALLEL return values, because - we have no way to move such values into a pseudo register. */ - if (pass && (flags & ECF_LIBCALL_BLOCK)) - { - rtx insns; - rtx insn; - bool failed = valreg == 0 || GET_CODE (valreg) == PARALLEL; - - insns = get_insns (); - - /* Expansion of block moves possibly introduced a loop that may - not appear inside libcall block. */ - for (insn = insns; insn; insn = NEXT_INSN (insn)) - if (JUMP_P (insn)) - failed = true; - - if (failed) - { - end_sequence (); - emit_insn (insns); - } - else - { - rtx note = 0; - rtx temp = gen_reg_rtx (GET_MODE (valreg)); - - /* Mark the return value as a pointer if needed. */ - if (TREE_CODE (TREE_TYPE (exp)) == POINTER_TYPE) - mark_reg_pointer (temp, - TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)))); - - end_sequence (); - if (flag_unsafe_math_optimizations - && fndecl - && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL - && (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_SQRT - || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_SQRTF - || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_SQRTL)) - note = gen_rtx_fmt_e (SQRT, - GET_MODE (temp), - args[0].initial_value); - else - { - /* Construct an "equal form" for the value which - mentions all the arguments in order as well as - the function name. */ - for (i = 0; i < num_actuals; i++) - note = gen_rtx_EXPR_LIST (VOIDmode, - args[i].initial_value, note); - note = gen_rtx_EXPR_LIST (VOIDmode, funexp, note); - } - emit_libcall_block (insns, temp, valreg, note); - - valreg = temp; - } - } - else if (pass && (flags & ECF_MALLOC)) + if (pass && (flags & ECF_MALLOC)) { rtx temp = gen_reg_rtx (GET_MODE (valreg)); rtx last, insns; @@ -2898,8 +2849,7 @@ expand_call (tree exp, rtx target, int ignore) /* The return value from a malloc-like function can not alias anything else. */ last = get_last_insn (); - REG_NOTES (last) = - gen_rtx_EXPR_LIST (REG_NOALIAS, temp, REG_NOTES (last)); + add_reg_note (last, REG_NOALIAS, temp); /* Write out the sequence. */ insns = get_insns (); @@ -3289,6 +3239,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, /* Todo, choose the correct decl type of orgfun. Sadly this information isn't present here, so we default to native calling abi here. */ tree fndecl ATTRIBUTE_UNUSED = NULL_TREE; /* library calls default to host calling abi ? */ + tree fntype ATTRIBUTE_UNUSED = NULL_TREE; /* library calls default to host calling abi ? */ int inc; int count; rtx argblock = 0; @@ -3318,7 +3269,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, #ifdef REG_PARM_STACK_SPACE /* Define the boundary of the register parm stack space that needs to be save, if any. */ - int low_to_save, high_to_save; + int low_to_save = 0, high_to_save = 0; rtx save_area = 0; /* Place that it is saved. */ #endif @@ -3346,12 +3297,6 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, case LCT_PURE: flags |= ECF_PURE; break; - case LCT_CONST_MAKE_BLOCK: - flags |= ECF_CONST | ECF_LIBCALL_BLOCK; - break; - case LCT_PURE_MAKE_BLOCK: - flags |= ECF_PURE | ECF_LIBCALL_BLOCK; - break; case LCT_NORETURN: flags |= ECF_NORETURN; break; @@ -3391,8 +3336,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, mem_value = assign_temp (tfom, 0, 1, 1); #endif /* This call returns a big structure. */ - flags &= ~(ECF_CONST | ECF_PURE | ECF_LOOPING_CONST_OR_PURE - | ECF_LIBCALL_BLOCK); + flags &= ~(ECF_CONST | ECF_PURE | ECF_LOOPING_CONST_OR_PURE); } } else @@ -3407,7 +3351,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, of the full argument passing conventions to limit complexity here since library functions shouldn't have many args. */ - argvec = alloca ((nargs + 1) * sizeof (struct arg)); + argvec = XALLOCAVEC (struct arg, nargs + 1); memset (argvec, 0, (nargs + 1) * sizeof (struct arg)); #ifdef INIT_CUMULATIVE_LIBCALL_ARGS @@ -3421,11 +3365,6 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, count = 0; - /* Now we are about to start emitting insns that can be deleted - if a libcall is deleted. */ - if (flags & ECF_LIBCALL_BLOCK) - start_sequence (); - push_temp_slots (); /* If there's a structure value address to be passed, @@ -3487,15 +3426,6 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, int must_copy = !reference_callee_copied (&args_so_far, mode, NULL_TREE, 1); - /* loop.c won't look at CALL_INSN_FUNCTION_USAGE of const/pure - functions, so we have to pretend this isn't such a function. */ - if (flags & ECF_LIBCALL_BLOCK) - { - rtx insns = get_insns (); - end_sequence (); - emit_insn (insns); - } - /* If this was a CONST function, it is now PURE since it now reads memory. */ if (flags & ECF_CONST) @@ -3504,7 +3434,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, flags |= ECF_PURE; } - if (GET_MODE (val) == MEM && !must_copy) + if (MEM_P (val) && !must_copy) slot = val; else { @@ -3567,7 +3497,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, args_size.constant = MAX (args_size.constant, reg_parm_stack_space); - if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? NULL_TREE : TREE_TYPE (fndecl)))) + if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl)))) args_size.constant -= reg_parm_stack_space; if (args_size.constant > crtl->outgoing_args_size) @@ -3592,7 +3522,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, /* Since we will be writing into the entire argument area, the map must be allocated for its entire size, not just the part that is the responsibility of the caller. */ - if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? NULL_TREE : TREE_TYPE (fndecl)))) + if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl)))) needed += reg_parm_stack_space; #ifdef ARGS_GROW_DOWNWARD @@ -3885,49 +3815,6 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, /* Now restore inhibit_defer_pop to its actual original value. */ OK_DEFER_POP; - /* If call is cse'able, make appropriate pair of reg-notes around it. - Test valreg so we don't crash; may safely ignore `const' - if return type is void. Disable for PARALLEL return values, because - we have no way to move such values into a pseudo register. */ - if (flags & ECF_LIBCALL_BLOCK) - { - rtx insns; - - if (valreg == 0) - { - insns = get_insns (); - end_sequence (); - emit_insn (insns); - } - else - { - rtx note = 0; - rtx temp; - int i; - - if (GET_CODE (valreg) == PARALLEL) - { - temp = gen_reg_rtx (outmode); - emit_group_store (temp, valreg, NULL_TREE, - GET_MODE_SIZE (outmode)); - valreg = temp; - } - - temp = gen_reg_rtx (GET_MODE (valreg)); - - /* Construct an "equal form" for the value which mentions all the - arguments in order as well as the function name. */ - for (i = 0; i < nargs; i++) - note = gen_rtx_EXPR_LIST (VOIDmode, argvec[i].value, note); - note = gen_rtx_EXPR_LIST (VOIDmode, fun, note); - - insns = get_insns (); - end_sequence (); - emit_libcall_block (insns, temp, valreg, note); - - valreg = temp; - } - } pop_temp_slots (); /* Copy the value to the right place. */ @@ -4011,12 +3898,9 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, with NARGS different arguments, passed as alternating rtx values and machine_modes to convert them to. - FN_TYPE should be LCT_NORMAL for `normal' calls, LCT_CONST for `const' - calls, LCT_PURE for `pure' calls, LCT_CONST_MAKE_BLOCK for `const' calls - which should be enclosed in REG_LIBCALL/REG_RETVAL notes, - LCT_PURE_MAKE_BLOCK for `purep' calls which should be enclosed in - REG_LIBCALL/REG_RETVAL notes with extra (use (memory (scratch)), - or other LCT_ value for other types of library calls. */ + FN_TYPE should be LCT_NORMAL for `normal' calls, LCT_CONST for + `const' calls, LCT_PURE for `pure' calls, or other LCT_ value for + other types of library calls. */ void emit_library_call (rtx orgfun, enum libcall_type fn_type,