calls.c (special_function_p): New argument fork_or_exec.

* calls.c (special_function_p): New argument fork_or_exec.
	(expand_call): When profile_arc_flag is set and the function
	is in the fork_or_exec group, call __bb_fork_func first.
	* libgcc2.c, _bb module (__bb_fork_func): New function.
	(__bb_exit_func): If fcntl F_SETLKW is available, use it to lock
	output file.
	* config/svr4.h (TARGET_HAS_F_SETLKW): Define.
	* tree.h (special_function_p): Update prototype.

From-SVN: r31636
This commit is contained in:
Joern Rennecke 2000-01-26 23:38:20 +00:00
parent e09d24ffb1
commit fa76d9e04e
1 changed files with 34 additions and 2 deletions

View File

@ -536,16 +536,18 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
space from the stack such as alloca. */
void
special_function_p (fndecl, returns_twice, is_longjmp,
special_function_p (fndecl, returns_twice, is_longjmp, fork_or_exec,
is_malloc, may_be_alloca)
tree fndecl;
int *returns_twice;
int *is_longjmp;
int *fork_or_exec;
int *is_malloc;
int *may_be_alloca;
{
*returns_twice = 0;
*is_longjmp = 0;
*fork_or_exec = 0;
*may_be_alloca = 0;
/* The function decl may have the `malloc' attribute. */
@ -607,6 +609,21 @@ special_function_p (fndecl, returns_twice, is_longjmp,
else if (tname[0] == 'l' && tname[1] == 'o'
&& ! strcmp (tname, "longjmp"))
*is_longjmp = 1;
else if ((tname[0] == 'f' && tname[1] == 'o'
&& ! strcmp (tname, "fork"))
/* Linux specific: __clone. check NAME to insist on the
leading underscores, to avoid polluting the ISO / POSIX
namespace. */
|| (name[0] == '_' && name[1] == '_'
&& ! strcmp (tname, "clone"))
|| (tname[0] == 'e' && tname[1] == 'x' && tname[2] == 'e'
&& tname[3] == 'c' && (tname[4] == 'l' || tname[4] == 'v')
&& (tname[5] == '\0'
|| ((tname[5] == 'p' || tname[5] == 'e')
&& tname[6] == '\0'))))
*fork_or_exec = 1;
/* Do not add any more malloc-like functions to this list,
instead mark them as malloc functions using the malloc attribute.
Note, realloc is not suitable for attribute malloc since
@ -1646,6 +1663,9 @@ expand_call (exp, target, ignore)
int returns_twice;
/* Nonzero if this is a call to `longjmp'. */
int is_longjmp;
/* Nonzero if this is a syscall that makes a new process in the image of
the current one. */
int fork_or_exec;
/* Nonzero if this is a call to an inline function. */
int is_integrable = 0;
/* Nonzero if this is a call to a `const' function.
@ -1903,7 +1923,7 @@ expand_call (exp, target, ignore)
/* See if this is a call to a function that can return more than once
or a call to longjmp or malloc. */
special_function_p (fndecl, &returns_twice, &is_longjmp,
special_function_p (fndecl, &returns_twice, &is_longjmp, &fork_or_exec,
&is_malloc, &may_be_alloca);
if (may_be_alloca)
@ -1928,6 +1948,18 @@ expand_call (exp, target, ignore)
|| (pending_stack_adjust > 0 && may_be_alloca))
do_pending_stack_adjust ();
if (profile_arc_flag && fork_or_exec)
{
/* A fork duplicates the profile information, and an exec discards
it. We can't rely on fork/exec to be paired. So write out the
profile information we have gathered so far, and clear it. */
emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__bb_fork_func"), 0,
VOIDmode, 0);
/* ??? When __clone is called with CLONE_VM set, profiling is
subject to race conditions, just as with multithreaded programs. */
}
/* Push the temporary stack slot level so that we can free any temporaries
we make. */
push_temp_slots ();