[tree-ssa][rfc] -finstrument-functions at tree level

Richard Henderson rth@twiddle.net
Thu Dec 11 01:50:00 GMT 2003


Even after looking at this and preserving apparently intended
semantics, I don't see that those semantics are useful.  Given

	void a() { }
	void noinline b() { a(); }
	void c() { b(); }

is __cyg_profile_func_start(a, c) really meaningful?  I'm not
sure that it is.  I would sorta expect that inlined functions
don't get noticed by this hook at all.

Thoughts?


r~


        * builtins.c (expand_builtin_profile_func): New.
        (expand_builtin): Use it.
        * builtins.def (BUILT_IN_PROFILE_FUNC_ENTER): New.
        (BUILT_IN_PROFILE_FUNC_EXIT): New.
        * function.c (expand_function_start, expand_function_end): Don't
        do function instrumentation here.
        * gimplify.c (gimplify_function_tree): Do it here.

        * c-opts.c (c_common_post_options): Don't ever use rtl inlining.
fortran/
        * options.c (gfc_post_options): Don't ever use rtl inlining.
java/
        * lang.c (java_post_options): Don't ever use rtl inlining.

Index: builtins.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/builtins.c,v
retrieving revision 1.152.2.42
diff -u -p -r1.152.2.42 builtins.c
--- builtins.c	1 Dec 2003 19:38:21 -0000	1.152.2.42
+++ builtins.c	11 Dec 2003 01:20:01 -0000
@@ -4916,6 +4916,32 @@ expand_builtin_sprintf (tree arglist, rt
 
   return 0;
 }
+
+/* Expand a call to either the entry or exit function profiler.  */
+
+static rtx
+expand_builtin_profile_func (bool exitp)
+{
+  rtx this, which;
+
+  this = DECL_RTL (current_function_decl);
+  if (GET_CODE (this) == MEM)
+    this = XEXP (this, 0);
+  else
+    abort ();
+
+  if (exitp)
+    which = profile_function_exit_libfunc;
+  else
+    which = profile_function_entry_libfunc;
+
+  emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
+		     expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
+						 0, hard_frame_pointer_rtx),
+		     Pmode);
+
+  return const0_rtx;
+}
 
 /* Expand an expression EXP that calls a built-in function,
    with result going to TARGET if that's convenient
@@ -5457,6 +5483,10 @@ expand_builtin (tree exp, rtx target, rt
       expand_builtin_prefetch (arglist);
       return const0_rtx;
 
+    case BUILT_IN_PROFILE_FUNC_ENTER:
+      return expand_builtin_profile_func (false);
+    case BUILT_IN_PROFILE_FUNC_EXIT:
+      return expand_builtin_profile_func (true);
 
     default:	/* just do library call, if unknown builtin */
       if (!DECL_ASSEMBLER_NAME_SET_P (fndecl))
Index: builtins.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/builtins.def,v
retrieving revision 1.29.2.23
diff -u -p -r1.29.2.23 builtins.def
--- builtins.def	28 Sep 2003 06:06:02 -0000	1.29.2.23
+++ builtins.def	11 Dec 2003 01:20:02 -0000
@@ -553,3 +553,9 @@ DEF_GCC_BUILTIN        (BUILT_IN_VA_END,
 DEF_GCC_BUILTIN        (BUILT_IN_VA_START, "va_start", BT_FN_VOID_VALIST_REF_VAR, ATTR_NULL)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN__EXIT, "_exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LIST)
 DEF_C99_BUILTIN        (BUILT_IN__EXIT2, "_Exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LIST)
+
+/* Profiling hooks.  */
+DEF_GCC_BUILTIN (BUILT_IN_PROFILE_FUNC_ENTER, "profile_func_enter",
+		 BT_FN_VOID, ATTR_NULL)
+DEF_GCC_BUILTIN (BUILT_IN_PROFILE_FUNC_EXIT, "profile_func_exit", 
+		 BT_FN_VOID, ATTR_NULL)
Index: c-opts.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-opts.c,v
retrieving revision 1.7.2.23
diff -u -p -r1.7.2.23 c-opts.c
--- c-opts.c	13 Nov 2003 02:37:36 -0000	1.7.2.23
+++ c-opts.c	11 Dec 2003 01:20:03 -0000
@@ -1081,17 +1081,13 @@ c_common_post_options (const char **pfil
 
   flag_inline_trees = 1;
 
-  /* Use tree inlining if possible.  Function instrumentation is only
-     done in the RTL level, so we disable tree inlining.  */
-  if (! flag_instrument_function_entry_exit)
+  /* Use tree inlining.  */
+  if (!flag_no_inline)
+    flag_no_inline = 1;
+  if (flag_inline_functions)
     {
-      if (!flag_no_inline)
-	flag_no_inline = 1;
-      if (flag_inline_functions)
-	{
-	  flag_inline_trees = 2;
-	  flag_inline_functions = 0;
-	}
+      flag_inline_trees = 2;
+      flag_inline_functions = 0;
     }
 
   /* -Wextra implies -Wsign-compare, but not if explicitly
Index: function.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.c,v
retrieving revision 1.374.2.34
diff -u -p -r1.374.2.34 function.c
--- function.c	1 Dec 2003 19:38:35 -0000	1.374.2.34
+++ function.c	11 Dec 2003 01:20:09 -0000
@@ -6548,10 +6548,6 @@ expand_function_start (tree subr, int pa
      valid operands of arithmetic insns.  */
   init_recog_no_volatile ();
 
-  current_function_instrument_entry_exit
-    = (flag_instrument_function_entry_exit
-       && ! DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (subr));
-
   current_function_profile
     = (profile_flag
        && ! DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (subr));
@@ -6718,21 +6714,6 @@ expand_function_start (tree subr, int pa
 	}
     }
 
-  if (current_function_instrument_entry_exit)
-    {
-      rtx fun = DECL_RTL (current_function_decl);
-      if (GET_CODE (fun) == MEM)
-	fun = XEXP (fun, 0);
-      else
-	abort ();
-      emit_library_call (profile_function_entry_libfunc, LCT_NORMAL, VOIDmode,
-			 2, fun, Pmode,
-			 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
-						     0,
-						     hard_frame_pointer_rtx),
-			 Pmode);
-    }
-
   if (current_function_profile)
     {
 #ifdef PROFILE_HOOK
@@ -6981,21 +6962,6 @@ expand_function_end (void)
      structure returning.  */
   if (return_label)
     emit_label (return_label);
-
-  if (current_function_instrument_entry_exit)
-    {
-      rtx fun = DECL_RTL (current_function_decl);
-      if (GET_CODE (fun) == MEM)
-	fun = XEXP (fun, 0);
-      else
-	abort ();
-      emit_library_call (profile_function_exit_libfunc, LCT_NORMAL, VOIDmode,
-			 2, fun, Pmode,
-			 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
-						     0,
-						     hard_frame_pointer_rtx),
-			 Pmode);
-    }
 
   /* Let except.c know where it should emit the call to unregister
      the function context for sjlj exceptions.  */
Index: gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/gimplify.c,v
retrieving revision 1.1.2.126
diff -u -p -r1.1.2.126 gimplify.c
--- gimplify.c	8 Dec 2003 10:03:39 -0000	1.1.2.126
+++ gimplify.c	11 Dec 2003 01:20:12 -0000
@@ -3499,5 +3499,32 @@ gimplify_function_tree (tree fndecl)
 
   gimplify_body (&DECL_SAVED_TREE (fndecl), fndecl);
 
+  /* If we're instrumenting function entry/exit, then prepend the call to
+     the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
+     catch the exit hook.  */
+  /* ??? Add some way to ignore exceptions for this TFE.  */
+  if (flag_instrument_function_entry_exit
+      && ! DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl))
+    {
+      tree tf, x, bind;
+
+      tf = build (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
+      TREE_SIDE_EFFECTS (tf) = 1;
+      x = DECL_SAVED_TREE (fndecl);
+      append_to_statement_list (x, &TREE_OPERAND (tf, 0));
+      x = implicit_built_in_decls[BUILT_IN_PROFILE_FUNC_EXIT];
+      x = build_function_call_expr (x, NULL);
+      append_to_statement_list (x, &TREE_OPERAND (tf, 1));
+
+      bind = build (BIND_EXPR, void_type_node, NULL, NULL, NULL);
+      TREE_SIDE_EFFECTS (bind) = 1;
+      x = implicit_built_in_decls[BUILT_IN_PROFILE_FUNC_ENTER];
+      x = build_function_call_expr (x, NULL);
+      append_to_statement_list (x, &BIND_EXPR_BODY (bind));
+      append_to_statement_list (tf, &BIND_EXPR_BODY (bind));
+
+      DECL_SAVED_TREE (fndecl) = bind;
+    }
+
   current_function_decl = oldfn;
 }
Index: fortran/options.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/Attic/options.c,v
retrieving revision 1.1.2.6
diff -u -p -r1.1.2.6 options.c
--- fortran/options.c	30 Nov 2003 13:43:17 -0000	1.1.2.6
+++ fortran/options.c	11 Dec 2003 01:20:18 -0000
@@ -94,17 +94,13 @@ gfc_post_options (const char **pfilename
 
   flag_inline_trees = 1;
 
-  /* Use tree inlining if possible.  Function instrumentation is only
-     done in the RTL level, so we disable tree inlining.  */
-  if (! flag_instrument_function_entry_exit)
+  /* Use tree inlining.  */
+  if (!flag_no_inline)
+    flag_no_inline = 1;
+  if (flag_inline_functions)
     {
-      if (!flag_no_inline)
-	flag_no_inline = 1;
-      if (flag_inline_functions)
-	{
-	  flag_inline_trees = 2;
-	  flag_inline_functions = 0;
-	}
+      flag_inline_trees = 2;
+      flag_inline_functions = 0;
     }
   
   return false;
Index: java/lang.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/lang.c,v
retrieving revision 1.103.2.26
diff -u -p -r1.103.2.26 lang.c
--- java/lang.c	2 Dec 2003 05:20:25 -0000	1.103.2.26
+++ java/lang.c	11 Dec 2003 01:20:19 -0000
@@ -710,17 +710,13 @@ java_post_options (const char **pfilenam
 {
   const char *filename = *pfilename;
 
- /* Use tree inlining if possible.  Function instrumentation is only
-     done in the RTL level, so we disable tree inlining.  */
-  if (! flag_instrument_function_entry_exit)
+  /* Use tree inlining.  */
+  if (!flag_no_inline)
+    flag_no_inline = 1;
+  if (flag_inline_functions)
     {
-      if (!flag_no_inline)
-	flag_no_inline = 1;
-      if (flag_inline_functions)
-	{
-	  flag_inline_trees = 2;
-	  flag_inline_functions = 0;
-	}
+      flag_inline_trees = 2;
+      flag_inline_functions = 0;
     }
 
   /* Open input file.  */



More information about the Gcc-patches mailing list