aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoern Rennecke <amylaar@gcc.gnu.org>2000-01-26 23:38:20 +0000
committerJoern Rennecke <amylaar@gcc.gnu.org>2000-01-26 23:38:20 +0000
commitfa76d9e04ebf753eee8e6dffb45430579c31ebf3 (patch)
tree8b4db574b812ef5991986ffdcd38e0b493de8a3e
parente09d24ffb12aff104ba1f584c420445aac4c1873 (diff)
downloadgcc-fa76d9e04ebf753eee8e6dffb45430579c31ebf3.zip
gcc-fa76d9e04ebf753eee8e6dffb45430579c31ebf3.tar.gz
gcc-fa76d9e04ebf753eee8e6dffb45430579c31ebf3.tar.bz2
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
-rw-r--r--gcc/calls.c36
1 files changed, 34 insertions, 2 deletions
diff --git a/gcc/calls.c b/gcc/calls.c
index 8c13685..84fdd60 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -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 ();