[m-dev.] for review: improve profiling of HO and method calls

Fergus Henderson fjh at cs.mu.OZ.AU
Sat Sep 9 01:43:50 AEDT 2000


Tom, could you please review this one?

----------

Estimated hours taken: 3

Improve profiling of higher-order code and code using class methods,
by ensuring that `do_call_closure' and `do_call_class_method' do not
appear in the profile, but that the time spent in them is instead
credited to their caller.

runtime/mercury_calls.h:
	Add `noprof_' version of call(), for use by the code generated
	by compiler/llds_out.m.

compiler/llds_out.m:
	Output `noprof_' prefix (and skip caller argument) for calls
	and tailcalls to do_call_closure and do_call_class_method.
	This ensures that we handle calls _to_ those procedures
	as described above.

runtime/mercury_ho_call.c:
	Change calls to the closure procedure or the class method
	procedure, so that they pass MR_prof_current_proc rather
	than the do_call_closure or do_call_class_method label
	that would normally be expected.  
	This ensures that we handle calls _from_ those procedures
	as described above.
	
Workspace: /home/pgrad/fjh/ws/hg
Index: compiler/llds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds_out.m,v
retrieving revision 1.150
diff -u -d -r1.150 llds_out.m
--- compiler/llds_out.m	2000/08/14 09:08:44	1.150
+++ compiler/llds_out.m	2000/09/08 14:25:50
@@ -3069,14 +3069,12 @@
 	io__write_string("GOTO(ENTRY(MR_do_trace_redo_fail_shallow));\n").
 output_goto(do_trace_redo_fail_deep, _) -->
 	io__write_string("GOTO(ENTRY(MR_do_trace_redo_fail_deep));\n").
-output_goto(do_call_closure, CallerLabel) -->
-	io__write_string("tailcall(ENTRY(mercury__do_call_closure),\n\t\t"),
-	output_label_as_code_addr(CallerLabel),
-	io__write_string(");\n").
+output_goto(do_call_closure, _CallerLabel) -->
+	% see comment in output_call for why we use `noprof_' here
+	io__write_string("noprof_tailcall(ENTRY(mercury__do_call_closure));\n").
 output_goto(do_call_class_method, CallerLabel) -->
-	io__write_string("tailcall(ENTRY(mercury__do_call_class_method),\n\t\t"),
-	output_label_as_code_addr(CallerLabel),
-	io__write_string(");\n").
+	% see comment in output_call for why we use `noprof_' here
+	io__write_string("noprof_tailcall(ENTRY(mercury__do_call_class_method));\n").
 output_goto(do_det_aditi_call, CallerLabel) -->
 	io__write_string("tailcall(ENTRY(do_det_aditi_call),\n\t\t"),
 	output_label_as_code_addr(CallerLabel),
@@ -3123,7 +3121,24 @@
 :- mode output_call(in, in, in, di, uo) is det.
 
 output_call(Target, Continuation, CallerLabel) -->
+	% For profiling, we ignore calls to do_call_closure
+	% and do_call_class_method, because in general they
+	% lead to cycles in the call graph that screw up the
+	% profile.  By generating a `noprof_call' rather than
+	% a `call', we ensure that time spent inside those
+	% routines is credited to the caller, rather than to
+	% do_call_closure or do_call_class_method itself.
 	(
+		{ Target = do_call_closure
+		; Target = do_call_class_method
+		}
+	->
+		{ ProfileCall = no },
+		io__write_string("noprof_")
+	;
+		{ ProfileCall = yes }
+	},
+	(
 		{ Target = label(Label) },
 		% We really shouldn't be calling internal labels ...
 		{ Label = c_local(_) ; Label = local(_, _) }
@@ -3146,8 +3161,12 @@
 		io__write_string(",\n\t\t"),
 		output_code_addr(Continuation)
 	),
-	io__write_string(",\n\t\t"),
-	output_label_as_code_addr(CallerLabel),
+	( { ProfileCall = yes } ->
+		io__write_string(",\n\t\t"),
+		output_label_as_code_addr(CallerLabel)
+	;
+		[]
+	),
 	io__write_string(");\n").
 
 output_code_addr(label(Label)) -->
Index: runtime/mercury_calls.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_calls.h,v
retrieving revision 1.6
diff -u -d -r1.6 mercury_calls.h
--- runtime/mercury_calls.h	2000/08/03 06:18:35	1.6
+++ runtime/mercury_calls.h	2000/09/08 14:16:37
@@ -113,6 +113,12 @@
 			GOTO(proc);				\
 		} while (0)
 
+#define	noprof_tailcall(proc)					\
+		do {						\
+			debugtailcall(proc);			\
+			GOTO(proc);				\
+		} while (0)
+
 #define	proceed()						\
 		do {						\
 			debugproceed();				\
Index: runtime/mercury_ho_call.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_ho_call.c,v
retrieving revision 1.35
diff -u -d -r1.35 mercury_ho_call.c
--- runtime/mercury_ho_call.c	2000/08/03 06:18:44	1.35
+++ runtime/mercury_ho_call.c	2000/09/08 14:37:07
@@ -86,6 +86,11 @@
 	init_entry_ai(mercury__compare_3_3);
 BEGIN_CODE
 
+/*
+** Note: this routine gets ignored for profiling.
+** That means it should be called using noprof_call()
+** rather than call().
+*/
 Define_entry(mercury__do_call_closure);
 {
 	MR_Closure	*closure;
@@ -119,8 +124,13 @@
 
 	restore_registers();
 
+	/*
+	** Note that we pass MR_prof_current_proc rather than
+	** LABEL(do_call_closure), so that the call gets recorded
+	** as having come from our caller.
+	*/
 	tailcall(closure->MR_closure_code,
-		LABEL(mercury__do_call_closure));
+		MR_prof_current_proc);
 }
 
 	/*
@@ -131,6 +141,12 @@
 	** r5+:input args
 	*/
 
+/*
+** Note: this routine gets ignored for profiling.
+** That means it should be called using noprof_call()
+** rather than call().  See comment in output_call in
+** compiler/llds_out for explanation.
+*/
 Define_entry(mercury__do_call_class_method);
 {
 	MR_Code 	*destination;
@@ -167,7 +183,12 @@
 
 	restore_registers();
 
-	tailcall(destination, LABEL(mercury__do_call_class_method));
+	/*
+	** Note that we pass MR_prof_current_proc rather than
+	** LABEL(do_call_class_method), so that the call gets recorded
+	** as having come from our caller.
+	*/
+	tailcall(destination, MR_prof_current_proc);
 }
 
 /*

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3        |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list