summaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r--gcc/builtins.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c
index c7627c053da..7c6cae19f10 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -5081,6 +5081,69 @@ expand_builtin_signbit (tree exp, rtx target)
}
return temp;
}
+
+/* Expand fork or exec calls. TARGET is the desired target of the
+ call. ARGLIST is the list of arguments of the call. FN is the
+ identificator of the actual function. IGNORE is nonzero if the
+ value is to be ignored. */
+
+static rtx
+expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
+{
+ tree id, decl;
+ tree call;
+
+ /* If we are not profiling, just call the function. */
+ if (!profile_arc_flag)
+ return NULL_RTX;
+
+ /* Otherwise call the wrapper. This should be equivalent for the rest of
+ compiler, so the code does not diverge, and the wrapper may run the
+ code neccesary for keeping the profiling sane. */
+
+ switch (DECL_FUNCTION_CODE (fn))
+ {
+ case BUILT_IN_FORK:
+ id = get_identifier ("__gcov_fork");
+ break;
+
+ case BUILT_IN_EXECL:
+ id = get_identifier ("__gcov_execl");
+ break;
+
+ case BUILT_IN_EXECV:
+ id = get_identifier ("__gcov_execv");
+ break;
+
+ case BUILT_IN_EXECLP:
+ id = get_identifier ("__gcov_execlp");
+ break;
+
+ case BUILT_IN_EXECLE:
+ id = get_identifier ("__gcov_execle");
+ break;
+
+ case BUILT_IN_EXECVP:
+ id = get_identifier ("__gcov_execvp");
+ break;
+
+ case BUILT_IN_EXECVE:
+ id = get_identifier ("__gcov_execve");
+ break;
+
+ default:
+ abort ();
+ }
+
+ decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
+ DECL_EXTERNAL (decl) = 1;
+ TREE_PUBLIC (decl) = 1;
+ DECL_ARTIFICIAL (decl) = 1;
+ TREE_NOTHROW (decl) = 1;
+ call = build_function_call_expr (decl, arglist);
+
+ return expand_call (call, target, ignore);
+}
/* Expand an expression EXP that calls a built-in function,
with result going to TARGET if that's convenient
@@ -5653,6 +5716,17 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
expand_builtin_prefetch (arglist);
return const0_rtx;
+ case BUILT_IN_FORK:
+ case BUILT_IN_EXECL:
+ case BUILT_IN_EXECV:
+ case BUILT_IN_EXECLP:
+ case BUILT_IN_EXECLE:
+ case BUILT_IN_EXECVP:
+ case BUILT_IN_EXECVE:
+ target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
+ if (target)
+ return target;
+ break;
default: /* just do library call, if unknown builtin */
if (!DECL_ASSEMBLER_NAME_SET_P (fndecl))