Commit 53d4257f by Jan Hubicka Committed by Jan Hubicka

calls.c (ECF_LIBCALL_BLOCK): New constant.

	* calls.c (ECF_LIBCALL_BLOCK): New constant.
	(emit_call_1, initialize_argument_information,
	precompute_arguments, expand_call,
	emit_library_call_value_1): Use ECF_LIBCALL_BLOCK
	instead of ECF_PURE | ECF_CONST. Honnor LCT_CONST/LCT_PURE.

From-SVN: r48279
parent affb9cdd
Sun Dec 23 00:49:37 CET 2001 Jan Hubicka <jh@suse.cz>
* calls.c (ECF_LIBCALL_BLOCK): New constant.
(emit_call_1, initialize_argument_information,
precompute_arguments, expand_call,
emit_library_call_value_1): Use ECF_LIBCALL_BLOCK
instead of ECF_PURE | ECF_CONST. Honnor LCT_CONST/LCT_PURE.
2001-12-22 Joseph S. Myers <jsm28@cam.ac.uk> 2001-12-22 Joseph S. Myers <jsm28@cam.ac.uk>
* config.gcc (extra_headers): Move settings to math-68881.h and * config.gcc (extra_headers): Move settings to math-68881.h and
......
...@@ -176,6 +176,8 @@ static int calls_function_1 PARAMS ((tree, int)); ...@@ -176,6 +176,8 @@ static int calls_function_1 PARAMS ((tree, int));
#define ECF_SP_DEPRESSED 1024 #define ECF_SP_DEPRESSED 1024
/* Nonzero if this call is known to always return. */ /* Nonzero if this call is known to always return. */
#define ECF_ALWAYS_RETURN 2048 #define ECF_ALWAYS_RETURN 2048
/* Create libcall block around the call. */
#define ECF_LIBCALL_BLOCK 4096
static void emit_call_1 PARAMS ((rtx, tree, tree, HOST_WIDE_INT, static void emit_call_1 PARAMS ((rtx, tree, tree, HOST_WIDE_INT,
HOST_WIDE_INT, HOST_WIDE_INT, rtx, HOST_WIDE_INT, HOST_WIDE_INT, rtx,
...@@ -808,14 +810,14 @@ flags_from_decl_or_type (exp) ...@@ -808,14 +810,14 @@ flags_from_decl_or_type (exp)
/* The function exp may have the `pure' attribute. */ /* The function exp may have the `pure' attribute. */
if (DECL_P (exp) && DECL_IS_PURE (exp)) if (DECL_P (exp) && DECL_IS_PURE (exp))
flags |= ECF_PURE; flags |= ECF_PURE | ECF_LIBCALL_BLOCK;
if (TREE_NOTHROW (exp)) if (TREE_NOTHROW (exp))
flags |= ECF_NOTHROW; flags |= ECF_NOTHROW;
} }
if (TREE_READONLY (exp) && ! TREE_THIS_VOLATILE (exp)) if (TREE_READONLY (exp) && ! TREE_THIS_VOLATILE (exp))
flags |= ECF_CONST; flags |= ECF_CONST | ECF_LIBCALL_BLOCK;
if (TREE_THIS_VOLATILE (exp)) if (TREE_THIS_VOLATILE (exp))
flags |= ECF_NORETURN; flags |= ECF_NORETURN;
...@@ -825,7 +827,7 @@ flags_from_decl_or_type (exp) ...@@ -825,7 +827,7 @@ flags_from_decl_or_type (exp)
if (TREE_CODE (type) == FUNCTION_TYPE && TYPE_RETURNS_STACK_DEPRESSED (type)) if (TREE_CODE (type) == FUNCTION_TYPE && TYPE_RETURNS_STACK_DEPRESSED (type))
{ {
flags |= ECF_SP_DEPRESSED; flags |= ECF_SP_DEPRESSED;
flags &= ~(ECF_PURE | ECF_CONST); flags &= ~(ECF_PURE | ECF_CONST | ECF_LIBCALL_BLOCK);
} }
return flags; return flags;
...@@ -1264,7 +1266,7 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args, ...@@ -1264,7 +1266,7 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args,
copy = assign_temp (type, 0, 1, 0); copy = assign_temp (type, 0, 1, 0);
store_expr (args[i].tree_value, copy, 0); store_expr (args[i].tree_value, copy, 0);
*ecf_flags &= ~(ECF_CONST | ECF_PURE); *ecf_flags &= ~(ECF_CONST | ECF_PURE | ECF_LIBCALL_BLOCK);
args[i].tree_value = build1 (ADDR_EXPR, args[i].tree_value = build1 (ADDR_EXPR,
build_pointer_type (type), build_pointer_type (type),
...@@ -1323,7 +1325,7 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args, ...@@ -1323,7 +1325,7 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args,
/* If this is an addressable type, we cannot pre-evaluate it. Thus, /* If this is an addressable type, we cannot pre-evaluate it. Thus,
we cannot consider this function call constant. */ we cannot consider this function call constant. */
if (TREE_ADDRESSABLE (type)) if (TREE_ADDRESSABLE (type))
*ecf_flags &= ~(ECF_CONST | ECF_PURE); *ecf_flags &= ~ECF_LIBCALL_BLOCK;
/* Compute the stack-size of this argument. */ /* Compute the stack-size of this argument. */
if (args[i].reg == 0 || args[i].partial != 0 if (args[i].reg == 0 || args[i].partial != 0
...@@ -1494,7 +1496,7 @@ precompute_arguments (flags, num_actuals, args) ...@@ -1494,7 +1496,7 @@ precompute_arguments (flags, num_actuals, args)
worse code) */ worse code) */
for (i = 0; i < num_actuals; i++) for (i = 0; i < num_actuals; i++)
if ((flags & (ECF_CONST | ECF_PURE)) if ((flags & ECF_LIBCALL_BLOCK)
|| calls_function (args[i].tree_value, !ACCUMULATE_OUTGOING_ARGS)) || calls_function (args[i].tree_value, !ACCUMULATE_OUTGOING_ARGS))
{ {
enum machine_mode mode; enum machine_mode mode;
...@@ -2240,7 +2242,7 @@ expand_call (exp, target, ignore) ...@@ -2240,7 +2242,7 @@ expand_call (exp, target, ignore)
if (aggregate_value_p (exp)) if (aggregate_value_p (exp))
{ {
/* This call returns a big structure. */ /* This call returns a big structure. */
flags &= ~(ECF_CONST | ECF_PURE); flags &= ~(ECF_CONST | ECF_PURE | ECF_LIBCALL_BLOCK);
#ifdef PCC_STATIC_STRUCT_RETURN #ifdef PCC_STATIC_STRUCT_RETURN
{ {
...@@ -2387,7 +2389,7 @@ expand_call (exp, target, ignore) ...@@ -2387,7 +2389,7 @@ expand_call (exp, target, ignore)
do this eventually, but it is too complicated to keep track of do this eventually, but it is too complicated to keep track of
what insns go in the cse'able block and which don't. */ what insns go in the cse'able block and which don't. */
flags &= ~(ECF_CONST | ECF_PURE); flags &= ~ECF_LIBCALL_BLOCK;
must_preallocate = 1; must_preallocate = 1;
} }
...@@ -2670,7 +2672,7 @@ expand_call (exp, target, ignore) ...@@ -2670,7 +2672,7 @@ expand_call (exp, target, ignore)
/* When calling a const function, we must pop the stack args right away, /* When calling a const function, we must pop the stack args right away,
so that the pop is deleted or moved with the call. */ so that the pop is deleted or moved with the call. */
if (flags & (ECF_CONST | ECF_PURE)) if (pass && (flags & ECF_LIBCALL_BLOCK))
NO_DEFER_POP; NO_DEFER_POP;
/* Push the temporary stack slot level so that we can free any /* Push the temporary stack slot level so that we can free any
...@@ -2687,7 +2689,7 @@ expand_call (exp, target, ignore) ...@@ -2687,7 +2689,7 @@ expand_call (exp, target, ignore)
/* Now we are about to start emitting insns that can be deleted /* Now we are about to start emitting insns that can be deleted
if a libcall is deleted. */ if a libcall is deleted. */
if (flags & (ECF_CONST | ECF_PURE | ECF_MALLOC)) if (pass && (flags & (ECF_LIBCALL_BLOCK | ECF_MALLOC)))
start_sequence (); start_sequence ();
adjusted_args_size = args_size; adjusted_args_size = args_size;
...@@ -2903,7 +2905,7 @@ expand_call (exp, target, ignore) ...@@ -2903,7 +2905,7 @@ expand_call (exp, target, ignore)
/* When the stack adjustment is pending, we get better code /* When the stack adjustment is pending, we get better code
by combining the adjustments. */ by combining the adjustments. */
if (pending_stack_adjust if (pending_stack_adjust
&& ! (flags & (ECF_CONST | ECF_PURE)) && ! (flags & ECF_LIBCALL_BLOCK)
&& ! inhibit_defer_pop) && ! inhibit_defer_pop)
{ {
pending_stack_adjust pending_stack_adjust
...@@ -2935,6 +2937,9 @@ expand_call (exp, target, ignore) ...@@ -2935,6 +2937,9 @@ expand_call (exp, target, ignore)
valreg = hard_function_value (TREE_TYPE (exp), fndecl, (pass == 0)); valreg = hard_function_value (TREE_TYPE (exp), fndecl, (pass == 0));
} }
if (valreg == 0 || GET_CODE (valreg) == PARALLEL)
flags &= ~ECF_LIBCALL_BLOCK;
/* Precompute all register parameters. It isn't safe to compute anything /* Precompute all register parameters. It isn't safe to compute anything
once we have started filling any specific hard regs. */ once we have started filling any specific hard regs. */
precompute_register_parameters (num_actuals, args, &reg_parm_seen); precompute_register_parameters (num_actuals, args, &reg_parm_seen);
...@@ -3064,9 +3069,7 @@ expand_call (exp, target, ignore) ...@@ -3064,9 +3069,7 @@ expand_call (exp, target, ignore)
Test valreg so we don't crash; may safely ignore `const' Test valreg so we don't crash; may safely ignore `const'
if return type is void. Disable for PARALLEL return values, because if return type is void. Disable for PARALLEL return values, because
we have no way to move such values into a pseudo register. */ we have no way to move such values into a pseudo register. */
if (pass if (pass && (flags & ECF_LIBCALL_BLOCK))
&& (flags & (ECF_CONST | ECF_PURE))
&& valreg != 0 && GET_CODE (valreg) != PARALLEL)
{ {
rtx note = 0; rtx note = 0;
rtx temp = gen_reg_rtx (GET_MODE (valreg)); rtx temp = gen_reg_rtx (GET_MODE (valreg));
...@@ -3095,15 +3098,7 @@ expand_call (exp, target, ignore) ...@@ -3095,15 +3098,7 @@ expand_call (exp, target, ignore)
valreg = temp; valreg = temp;
} }
else if (flags & (ECF_CONST | ECF_PURE)) else if (pass && (flags & ECF_MALLOC))
{
/* Otherwise, just write out the sequence without a note. */
rtx insns = get_insns ();
end_sequence ();
emit_insns (insns);
}
else if (flags & ECF_MALLOC)
{ {
rtx temp = gen_reg_rtx (GET_MODE (valreg)); rtx temp = gen_reg_rtx (GET_MODE (valreg));
rtx last, insns; rtx last, insns;
...@@ -3502,15 +3497,18 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p) ...@@ -3502,15 +3497,18 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
switch (fn_type) switch (fn_type)
{ {
case LCT_NORMAL: case LCT_NORMAL:
break;
case LCT_CONST: case LCT_CONST:
flags |= ECF_CONST;
break;
case LCT_PURE: case LCT_PURE:
/* Nothing to do here. */ flags |= ECF_PURE;
break; break;
case LCT_CONST_MAKE_BLOCK: case LCT_CONST_MAKE_BLOCK:
flags |= ECF_CONST; flags |= ECF_CONST | ECF_LIBCALL_BLOCK;
break; break;
case LCT_PURE_MAKE_BLOCK: case LCT_PURE_MAKE_BLOCK:
flags |= ECF_PURE; flags |= ECF_PURE | ECF_LIBCALL_BLOCK;
break; break;
case LCT_NORETURN: case LCT_NORETURN:
flags |= ECF_NORETURN; flags |= ECF_NORETURN;
...@@ -3553,7 +3551,7 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p) ...@@ -3553,7 +3551,7 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
#endif #endif
/* This call returns a big structure. */ /* This call returns a big structure. */
flags &= ~(ECF_CONST | ECF_PURE); flags &= ~(ECF_CONST | ECF_PURE | ECF_LIBCALL_BLOCK);
} }
/* ??? Unfinished: must pass the memory address as an argument. */ /* ??? Unfinished: must pass the memory address as an argument. */
...@@ -3581,7 +3579,7 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p) ...@@ -3581,7 +3579,7 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
/* Now we are about to start emitting insns that can be deleted /* Now we are about to start emitting insns that can be deleted
if a libcall is deleted. */ if a libcall is deleted. */
if (flags & (ECF_CONST | ECF_PURE)) if (flags & ECF_LIBCALL_BLOCK)
start_sequence (); start_sequence ();
push_temp_slots (); push_temp_slots ();
...@@ -4023,6 +4021,8 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p) ...@@ -4023,6 +4021,8 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
NO_DEFER_POP; NO_DEFER_POP;
valreg = (mem_value == 0 && outmode != VOIDmode valreg = (mem_value == 0 && outmode != VOIDmode
? hard_libcall_value (outmode) : NULL_RTX); ? hard_libcall_value (outmode) : NULL_RTX);
if (valreg == 0 || GET_CODE (valreg) == PARALLEL)
flags &= ~ECF_LIBCALL_BLOCK;
/* Stack must be properly aligned now. */ /* Stack must be properly aligned now. */
if (stack_pointer_delta & (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT - 1)) if (stack_pointer_delta & (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT - 1))
...@@ -4076,8 +4076,7 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p) ...@@ -4076,8 +4076,7 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
Test valreg so we don't crash; may safely ignore `const' Test valreg so we don't crash; may safely ignore `const'
if return type is void. Disable for PARALLEL return values, because if return type is void. Disable for PARALLEL return values, because
we have no way to move such values into a pseudo register. */ we have no way to move such values into a pseudo register. */
if ((flags & (ECF_CONST | ECF_PURE)) if (flags & ECF_LIBCALL_BLOCK)
&& valreg != 0 && GET_CODE (valreg) != PARALLEL)
{ {
rtx note = 0; rtx note = 0;
rtx temp = gen_reg_rtx (GET_MODE (valreg)); rtx temp = gen_reg_rtx (GET_MODE (valreg));
...@@ -4103,14 +4102,6 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p) ...@@ -4103,14 +4102,6 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
valreg = temp; valreg = temp;
} }
else if (flags & (ECF_CONST | ECF_PURE))
{
/* Otherwise, just write out the sequence without a note. */
rtx insns = get_insns ();
end_sequence ();
emit_insns (insns);
}
pop_temp_slots (); pop_temp_slots ();
/* Copy the value to the right place. */ /* Copy the value to the right place. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment