aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2001-12-23 01:10:43 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2001-12-23 00:10:43 +0000
commit53d4257f7fd9c8446aae11c3c84de7133773a73c (patch)
treea2d23ff5b37a44891d171b8de241e12bd3b9bf95 /gcc
parentaffb9cddc0541f27279d5a1c6350f106f574375c (diff)
downloadgcc-53d4257f7fd9c8446aae11c3c84de7133773a73c.zip
gcc-53d4257f7fd9c8446aae11c3c84de7133773a73c.tar.gz
gcc-53d4257f7fd9c8446aae11c3c84de7133773a73c.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/calls.c67
2 files changed, 37 insertions, 38 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 94f0e7b..238e583 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+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>
* config.gcc (extra_headers): Move settings to math-68881.h and
diff --git a/gcc/calls.c b/gcc/calls.c
index 5c4fd8d..2049bd2 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -176,6 +176,8 @@ static int calls_function_1 PARAMS ((tree, int));
#define ECF_SP_DEPRESSED 1024
/* Nonzero if this call is known to always return. */
#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,
HOST_WIDE_INT, HOST_WIDE_INT, rtx,
@@ -808,14 +810,14 @@ flags_from_decl_or_type (exp)
/* The function exp may have the `pure' attribute. */
if (DECL_P (exp) && DECL_IS_PURE (exp))
- flags |= ECF_PURE;
+ flags |= ECF_PURE | ECF_LIBCALL_BLOCK;
if (TREE_NOTHROW (exp))
flags |= ECF_NOTHROW;
}
if (TREE_READONLY (exp) && ! TREE_THIS_VOLATILE (exp))
- flags |= ECF_CONST;
+ flags |= ECF_CONST | ECF_LIBCALL_BLOCK;
if (TREE_THIS_VOLATILE (exp))
flags |= ECF_NORETURN;
@@ -825,7 +827,7 @@ flags_from_decl_or_type (exp)
if (TREE_CODE (type) == FUNCTION_TYPE && TYPE_RETURNS_STACK_DEPRESSED (type))
{
flags |= ECF_SP_DEPRESSED;
- flags &= ~(ECF_PURE | ECF_CONST);
+ flags &= ~(ECF_PURE | ECF_CONST | ECF_LIBCALL_BLOCK);
}
return flags;
@@ -1264,7 +1266,7 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args,
copy = assign_temp (type, 0, 1, 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,
build_pointer_type (type),
@@ -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,
we cannot consider this function call constant. */
if (TREE_ADDRESSABLE (type))
- *ecf_flags &= ~(ECF_CONST | ECF_PURE);
+ *ecf_flags &= ~ECF_LIBCALL_BLOCK;
/* Compute the stack-size of this argument. */
if (args[i].reg == 0 || args[i].partial != 0
@@ -1494,7 +1496,7 @@ precompute_arguments (flags, num_actuals, args)
worse code) */
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))
{
enum machine_mode mode;
@@ -2240,7 +2242,7 @@ expand_call (exp, target, ignore)
if (aggregate_value_p (exp))
{
/* This call returns a big structure. */
- flags &= ~(ECF_CONST | ECF_PURE);
+ flags &= ~(ECF_CONST | ECF_PURE | ECF_LIBCALL_BLOCK);
#ifdef PCC_STATIC_STRUCT_RETURN
{
@@ -2387,7 +2389,7 @@ expand_call (exp, target, ignore)
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_CONST | ECF_PURE);
+ flags &= ~ECF_LIBCALL_BLOCK;
must_preallocate = 1;
}
@@ -2670,7 +2672,7 @@ expand_call (exp, target, ignore)
/* 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 (flags & (ECF_CONST | ECF_PURE))
+ if (pass && (flags & ECF_LIBCALL_BLOCK))
NO_DEFER_POP;
/* Push the temporary stack slot level so that we can free any
@@ -2687,7 +2689,7 @@ expand_call (exp, target, ignore)
/* Now we are about to start emitting insns that can be deleted
if a libcall is deleted. */
- if (flags & (ECF_CONST | ECF_PURE | ECF_MALLOC))
+ if (pass && (flags & (ECF_LIBCALL_BLOCK | ECF_MALLOC)))
start_sequence ();
adjusted_args_size = args_size;
@@ -2903,7 +2905,7 @@ expand_call (exp, target, ignore)
/* When the stack adjustment is pending, we get better code
by combining the adjustments. */
if (pending_stack_adjust
- && ! (flags & (ECF_CONST | ECF_PURE))
+ && ! (flags & ECF_LIBCALL_BLOCK)
&& ! inhibit_defer_pop)
{
pending_stack_adjust
@@ -2935,6 +2937,9 @@ expand_call (exp, target, ignore)
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
once we have started filling any specific hard regs. */
precompute_register_parameters (num_actuals, args, &reg_parm_seen);
@@ -3064,9 +3069,7 @@ expand_call (exp, target, ignore)
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_CONST | ECF_PURE))
- && valreg != 0 && GET_CODE (valreg) != PARALLEL)
+ if (pass && (flags & ECF_LIBCALL_BLOCK))
{
rtx note = 0;
rtx temp = gen_reg_rtx (GET_MODE (valreg));
@@ -3095,15 +3098,7 @@ expand_call (exp, target, ignore)
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);
- }
- else if (flags & ECF_MALLOC)
+ else if (pass && (flags & ECF_MALLOC))
{
rtx temp = gen_reg_rtx (GET_MODE (valreg));
rtx last, insns;
@@ -3502,15 +3497,18 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
switch (fn_type)
{
case LCT_NORMAL:
+ break;
case LCT_CONST:
+ flags |= ECF_CONST;
+ break;
case LCT_PURE:
- /* Nothing to do here. */
+ flags |= ECF_PURE;
break;
case LCT_CONST_MAKE_BLOCK:
- flags |= ECF_CONST;
+ flags |= ECF_CONST | ECF_LIBCALL_BLOCK;
break;
case LCT_PURE_MAKE_BLOCK:
- flags |= ECF_PURE;
+ flags |= ECF_PURE | ECF_LIBCALL_BLOCK;
break;
case LCT_NORETURN:
flags |= ECF_NORETURN;
@@ -3553,7 +3551,7 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
#endif
/* 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. */
@@ -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
if a libcall is deleted. */
- if (flags & (ECF_CONST | ECF_PURE))
+ if (flags & ECF_LIBCALL_BLOCK)
start_sequence ();
push_temp_slots ();
@@ -4023,6 +4021,8 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
NO_DEFER_POP;
valreg = (mem_value == 0 && outmode != VOIDmode
? hard_libcall_value (outmode) : NULL_RTX);
+ if (valreg == 0 || GET_CODE (valreg) == PARALLEL)
+ flags &= ~ECF_LIBCALL_BLOCK;
/* Stack must be properly aligned now. */
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)
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_CONST | ECF_PURE))
- && valreg != 0 && GET_CODE (valreg) != PARALLEL)
+ if (flags & ECF_LIBCALL_BLOCK)
{
rtx note = 0;
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)
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 ();
/* Copy the value to the right place. */