optabs.c (prepare_cmp_insn): Changed LCT_PURE_MAKE_BLOCK to LCT_PURE and LCT_CONST_MAKE_BLOCK to LCT_CONST...
2008-05-14 Kenneth Zadeck <zadeck@naturalbridge.com> * optabs.c (prepare_cmp_insn): Changed LCT_PURE_MAKE_BLOCK to LCT_PURE and LCT_CONST_MAKE_BLOCK to LCT_CONST in calls to emit_library_call_value. * builtins.c (expand_builtin_powi, expand_builtin_memcmp): Ditto. * tree.h (ECF_LIBCALL_BLOCK): Removed. * calls.c (initialize_argument_information, precompute_arguments, expand_call, emit_library_call_value_1): Remove ECF_LIBCALL_BLOCK. (precompute_arguments): Removed flags parameter. * rtl.h (LCT_CONST_MAKE_BLOCK, LCT_PURE_MAKE_BLOCK): Removed. From-SVN: r135299
This commit is contained in:
parent
f403a4a270
commit
84b8030f0e
@ -1,3 +1,15 @@
|
||||
2008-05-14 Kenneth Zadeck <zadeck@naturalbridge.com>
|
||||
|
||||
* optabs.c (prepare_cmp_insn): Changed LCT_PURE_MAKE_BLOCK to
|
||||
LCT_PURE and LCT_CONST_MAKE_BLOCK to LCT_CONST in calls to
|
||||
emit_library_call_value.
|
||||
* builtins.c (expand_builtin_powi, expand_builtin_memcmp): Ditto.
|
||||
* tree.h (ECF_LIBCALL_BLOCK): Removed.
|
||||
* calls.c (initialize_argument_information, precompute_arguments,
|
||||
expand_call, emit_library_call_value_1): Remove ECF_LIBCALL_BLOCK.
|
||||
(precompute_arguments): Removed flags parameter.
|
||||
* rtl.h (LCT_CONST_MAKE_BLOCK, LCT_PURE_MAKE_BLOCK): Removed.
|
||||
|
||||
2008-05-14 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
* tree-ssa-dse.c (dse_possible_dead_store_p): Remove dead code.
|
||||
|
@ -3082,7 +3082,7 @@ expand_builtin_powi (tree exp, rtx target, rtx subtarget)
|
||||
op1 = convert_to_mode (mode2, op1, 0);
|
||||
|
||||
target = emit_library_call_value (optab_libfunc (powi_optab, mode),
|
||||
target, LCT_CONST_MAKE_BLOCK, mode, 2,
|
||||
target, LCT_CONST, mode, 2,
|
||||
op0, mode, op1, mode2);
|
||||
|
||||
return target;
|
||||
@ -4147,7 +4147,7 @@ expand_builtin_memcmp (tree exp, rtx target, enum machine_mode mode)
|
||||
if (insn)
|
||||
emit_insn (insn);
|
||||
else
|
||||
emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
|
||||
emit_library_call_value (memcmp_libfunc, result, LCT_PURE,
|
||||
TYPE_MODE (integer_type_node), 3,
|
||||
XEXP (arg1_rtx, 0), Pmode,
|
||||
XEXP (arg2_rtx, 0), Pmode,
|
||||
|
176
gcc/calls.c
176
gcc/calls.c
@ -129,7 +129,7 @@ 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 void precompute_arguments (int, struct arg_data *);
|
||||
static int compute_argument_block_size (int, struct args_size *, tree, int);
|
||||
static void initialize_argument_information (int, struct arg_data *,
|
||||
struct args_size *, int,
|
||||
@ -1040,7 +1040,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
|
||||
{
|
||||
@ -1075,8 +1074,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. */
|
||||
@ -1140,11 +1137,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
|
||||
@ -1265,7 +1257,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 +1271,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. */
|
||||
@ -2076,8 +2067,7 @@ expand_call (tree exp, rtx target, int ignore)
|
||||
if (aggregate_value_p (exp, 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
|
||||
{
|
||||
@ -2238,15 +2228,7 @@ expand_call (tree exp, rtx target, int ignore)
|
||||
&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,
|
||||
@ -2377,18 +2359,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)
|
||||
@ -2626,7 +2603,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
|
||||
@ -2826,65 +2802,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;
|
||||
@ -3346,12 +3264,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 +3303,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
|
||||
@ -3421,11 +3332,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,16 +3393,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);
|
||||
}
|
||||
flags &= ~ECF_LIBCALL_BLOCK;
|
||||
|
||||
/* If this was a CONST function, it is now PURE since it now
|
||||
reads memory. */
|
||||
if (flags & ECF_CONST)
|
||||
@ -3886,49 +3782,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. */
|
||||
@ -4012,12 +3865,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,
|
||||
|
@ -4127,7 +4127,7 @@ prepare_cmp_insn (rtx *px, rtx *py, enum rtx_code *pcomparison, rtx size,
|
||||
size = convert_to_mode (TYPE_MODE (length_type), size,
|
||||
TYPE_UNSIGNED (length_type));
|
||||
|
||||
result = emit_library_call_value (libfunc, 0, LCT_PURE_MAKE_BLOCK,
|
||||
result = emit_library_call_value (libfunc, 0, LCT_PURE,
|
||||
result_mode, 3,
|
||||
XEXP (x, 0), Pmode,
|
||||
XEXP (y, 0), Pmode,
|
||||
@ -4169,7 +4169,7 @@ prepare_cmp_insn (rtx *px, rtx *py, enum rtx_code *pcomparison, rtx size,
|
||||
libfunc = ulibfunc;
|
||||
}
|
||||
|
||||
result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK,
|
||||
result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
|
||||
targetm.libgcc_cmp_return_mode (),
|
||||
2, x, mode, y, mode);
|
||||
|
||||
|
@ -2218,11 +2218,9 @@ enum libcall_type
|
||||
LCT_NORMAL = 0,
|
||||
LCT_CONST = 1,
|
||||
LCT_PURE = 2,
|
||||
LCT_CONST_MAKE_BLOCK = 3,
|
||||
LCT_PURE_MAKE_BLOCK = 4,
|
||||
LCT_NORETURN = 5,
|
||||
LCT_THROW = 6,
|
||||
LCT_RETURNS_TWICE = 7
|
||||
LCT_NORETURN = 3,
|
||||
LCT_THROW = 4,
|
||||
LCT_RETURNS_TWICE = 5
|
||||
};
|
||||
|
||||
extern void emit_library_call (rtx, enum libcall_type, enum machine_mode, int,
|
||||
|
@ -4970,11 +4970,9 @@ extern tree build_duplicate_type (tree);
|
||||
#define ECF_RETURNS_TWICE (1 << 7)
|
||||
/* Nonzero if this call replaces the current stack frame. */
|
||||
#define ECF_SIBCALL (1 << 8)
|
||||
/* Create libcall block around the call. */
|
||||
#define ECF_LIBCALL_BLOCK (1 << 9)
|
||||
/* Function does not read or write memory (but may have side effects, so
|
||||
it does not necessarily fit ECF_CONST). */
|
||||
#define ECF_NOVOPS (1 << 10)
|
||||
#define ECF_NOVOPS (1 << 9)
|
||||
|
||||
extern int flags_from_decl_or_type (const_tree);
|
||||
extern int call_expr_flags (const_tree);
|
||||
|
Loading…
Reference in New Issue
Block a user