[m-dev.] for review: better names for lambda goals

Thomas Charles CONWAY conway at cs.mu.oz.au
Wed Aug 27 09:25:38 AEST 1997


Fergus Henderson, you write:
> Thomas Charles CONWAY, you wrote:
> > Profiling code with lots of lambda goals was painful, because the names
> > of the predicates contained no information about which piece of the source
> > they correspond to. This change corrects this problem by enabling the
> > profiler to produce output such as:
> > 
> > ... 0.00     0.00 <pred/func goal from lp:'pivot', line 362> [10] 
> > ... 0.00     0.00 <pred/func goal from lp:'pivot', line 356> [11] 
> > ... 0.00     0.00 <pred/func goal from lp:'simplex', line 262> [12] 
> 
> I would prefer
> 		
> 	... 0.00     0.00 <pred goal from lp:'simplex', line 262> [12] 
> 	... 0.00     0.00 <func goal from lp:'pivot', line 356> [11] 
> 
> This is easily done, I think.  See below.
> 
> > profiler/demangle.m:
> > 	demangle the names for lambda goals.
> 
> You also need to change util/mdemangle.c.
> 

Both done. See revised diff below.

-- 
ZZ:wq!
^X^C
Thomas Conway               				      conway at cs.mu.oz.au
AD DEUM ET VINUM	  			      Every sword has two edges.

cvs diff: Diffing .
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/lambda.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/lambda.m,v
retrieving revision 1.30
diff -u -r1.30 lambda.m
--- lambda.m	1997/07/27 15:00:44	1.30
+++ lambda.m	1997/08/25 05:36:50
@@ -41,11 +41,11 @@
 :- pred lambda__process_pred(pred_id, module_info, module_info).
 :- mode lambda__process_pred(in, in, out) is det.
 
-:- pred lambda__transform_lambda(pred_or_func, list(var), list(mode), 
+:- pred lambda__transform_lambda(pred_or_func, string, list(var), list(mode), 
 		determinism, set(var), hlds_goal, unification,
 		varset, map(var, type), tvarset, map(tvar, var), module_info,
 		unify_rhs, unification, module_info).
-:- mode lambda__transform_lambda(in, in, in, in, in, in, in, in, in, in, in,
+:- mode lambda__transform_lambda(in, in, in, in, in, in, in, in, in, in, in, in,
 		in, out, out, out) is det.
 
 	% Permute the list of variables so that inputs come before outputs.
@@ -69,6 +69,8 @@
 			map(var, type),		% from the proc_info
 			tvarset,		% from the proc_info
 			map(tvar, var),		% from the proc_info (typeinfos)
+			pred_or_func,
+			string,			% pred/func name
 			module_info
 		).
 
@@ -115,6 +117,8 @@
 lambda__process_proc_2(ProcInfo0, PredInfo0, ModuleInfo0,
 				ProcInfo, PredInfo, ModuleInfo) :-
 	% grab the appropriate fields from the pred_info and proc_info
+	pred_info_name(PredInfo0, PredName),
+	pred_info_get_is_pred_or_func(PredInfo0, PredOrFunc),
 	pred_info_typevarset(PredInfo0, TypeVarSet0),
 	proc_info_variables(ProcInfo0, VarSet0),
 	proc_info_vartypes(ProcInfo0, VarTypes0),
@@ -123,9 +127,11 @@
 
 	% process the goal
 	Info0 = lambda_info(VarSet0, VarTypes0, TypeVarSet0, TVarMap0, 
+		PredOrFunc, PredName,
 		ModuleInfo0),
 	lambda__process_goal(Goal0, Goal, Info0, Info),
 	Info = lambda_info(VarSet, VarTypes, TypeVarSet, TVarMap, 
+		_, _,
 		ModuleInfo),
 
 	% set the new values of the fields in proc_info and pred_info
@@ -219,16 +225,18 @@
 lambda__process_lambda(PredOrFunc, Vars, Modes, Det, OrigNonLocals0, LambdaGoal,
 		Unification0, Functor, Unification, LambdaInfo0, LambdaInfo) :-
 	LambdaInfo0 = lambda_info(VarSet, VarTypes, TVarSet, TVarMap, 
-			ModuleInfo0),
-	lambda__transform_lambda(PredOrFunc, Vars, Modes, Det, OrigNonLocals0, 
-		LambdaGoal, Unification0, VarSet, VarTypes, TVarSet, TVarMap, 
-		ModuleInfo0, Functor, Unification, ModuleInfo),
+			POF, PredName, ModuleInfo0),
+	lambda__transform_lambda(PredOrFunc, PredName, Vars, Modes, Det,
+		OrigNonLocals0, LambdaGoal, Unification0, VarSet, VarTypes,
+		TVarSet, TVarMap, ModuleInfo0, Functor,
+		Unification, ModuleInfo),
 	LambdaInfo = lambda_info(VarSet, VarTypes, TVarSet, TVarMap, 
-		ModuleInfo).
+			POF, PredName, ModuleInfo).
 
-lambda__transform_lambda(PredOrFunc, Vars, Modes, Detism, OrigNonLocals0, 
-		LambdaGoal, Unification0, VarSet, VarTypes, TVarSet, TVarMap, 
-		ModuleInfo0, Functor, Unification, ModuleInfo) :-
+lambda__transform_lambda(PredOrFunc, OrigPredName, Vars, Modes, Detism,
+		OrigNonLocals0, LambdaGoal, Unification0, VarSet, VarTypes,
+		TVarSet, TVarMap, ModuleInfo0, Functor,
+		Unification, ModuleInfo) :-
 	(
 		Unification0 = construct(Var0, _, _, UniModes0)
 	->
@@ -308,10 +316,10 @@
 		module_info_name(ModuleInfo0, ModuleName),
 		module_info_next_lambda_count(ModuleInfo0, LambdaCount,
 					ModuleInfo1),
-		string__int_to_string(LambdaCount, LambdaCountStr),
-		string__append("__LambdaGoal__", LambdaCountStr, PName0),
-		string__append(ModuleName, PName0, PName),
-		PredName = qualified(ModuleName, PName),
+		goal_info_get_context(LambdaGoalInfo, OrigContext),
+		term__context_line(OrigContext, OrigLine),
+		make_lambda_name(ModuleName, PredOrFunc, OrigPredName,
+			OrigLine, LambdaCount, PredName),
 		goal_info_get_context(LambdaGoalInfo, LambdaContext),
 		% the TVarSet is a superset of what it really ought be,
 		% but that shouldn't matter
@@ -369,6 +377,21 @@
 	Functor = functor(cons(PredName, NumArgVars), ArgVars),
 	ConsId = pred_const(PredId, ProcId),
 	Unification = construct(Var, ConsId, ArgVars, UniModes).
+
+:- pred make_lambda_name(string, pred_or_func, string, int, int, sym_name).
+:- mode make_lambda_name(in, in, in, in, in, out) is det.
+
+make_lambda_name(ModuleName, PredOrFunc, PredName, Line, Counter, SymName) :-
+	(
+		PredOrFunc = predicate,
+		PFS = "pred"
+	;
+		PredOrFunc = function,
+		PFS = "func"
+	),
+	string__format("IntroducedFrom__%s__%s__%d__%d",
+		[s(PFS), s(PredName), i(Line), i(Counter)], Name),
+		SymName = qualified(ModuleName, Name).
 
 :- pred lambda__uni_modes_to_modes(list(uni_mode), list(mode)).
 :- mode lambda__uni_modes_to_modes(in, out) is det.
Index: compiler/polymorphism.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/polymorphism.m,v
retrieving revision 1.115
diff -u -r1.115 polymorphism.m
--- polymorphism.m	1997/08/09 05:01:28	1.115
+++ polymorphism.m	1997/08/25 05:33:58
@@ -287,6 +287,7 @@
 			map(tvar, var),		% specifies the type_info var
 						% for each of the pred's type
 						% parameters
+			string,			% pred name
 			module_info
 		).
 
@@ -299,6 +300,7 @@
 	% grab the appropriate fields from the pred_info and proc_info
 	pred_info_arg_types(PredInfo0, ArgTypeVarSet, ArgTypes),
 	pred_info_typevarset(PredInfo0, TypeVarSet0),
+	pred_info_name(PredInfo0, PredName),
 	proc_info_headvars(ProcInfo0, HeadVars0),
 	proc_info_variables(ProcInfo0, VarSet0),
 	proc_info_vartypes(ProcInfo0, VarTypes0),
@@ -321,10 +323,11 @@
 	map__from_corresponding_lists(HeadTypeVars, ExtraHeadVars,
 				TypeInfoMap0),
 	Info0 = poly_info(VarSet1, VarTypes1, TypeVarSet0,
-				TypeInfoMap0, ModuleInfo0),
+				TypeInfoMap0, PredName, ModuleInfo0),
 	polymorphism__process_goal(Goal0, Goal1, Info0, Info1),
 	polymorphism__fixup_quantification(Goal1, Goal, Info1, Info),
-	Info = poly_info(VarSet, VarTypes, TypeVarSet, TypeInfoMap, ModuleInfo),
+	Info = poly_info(VarSet, VarTypes, TypeVarSet, TypeInfoMap, _PredName,
+		ModuleInfo),
 
 	% set the new values of the fields in proc_info and pred_info
 	proc_info_set_headvars(ProcInfo0, HeadVars, ProcInfo1),
@@ -365,7 +368,7 @@
 		{ list__length(ArgVars0, Arity) },
 		{ special_pred_name_arity(SpecialPredId, PredName0,
 						MangledPredName, Arity) },
-		=(poly_info(_, VarTypes, _, _TypeInfoMap, ModuleInfo)),
+		=(poly_info(_, VarTypes, _, _TypeInfoMap, _PN, ModuleInfo)),
 		{ special_pred_get_type(MangledPredName, ArgVars0, MainVar) },
 		{ map__lookup(VarTypes, MainVar, Type) },
 		{ Type \= term__variable(_) },
@@ -401,7 +404,7 @@
 		{ Unification = complicated_unify(UniMode, CanFail) },
 		{ Y = var(YVar) }
 	->
-		=(poly_info(_, VarTypes, _, TypeInfoMap, ModuleInfo)),
+		=(poly_info(_, VarTypes, _, TypeInfoMap, _PName, ModuleInfo)),
 		{ map__lookup(VarTypes, XVar, Type) },
 		( { Type = term__variable(TypeVar) } ->
 			% Convert polymorphic unifications into calls to
@@ -485,8 +488,8 @@
 		{ goal_info_get_nonlocals(GoalInfo0, OrigNonLocals) },
 		polymorphism__process_goal(LambdaGoal0, LambdaGoal1),
 		polymorphism__fixup_quantification(LambdaGoal1, LambdaGoal),
-		polymorphism__process_lambda(PredOrFunc, Vars, Modes, Det,
-				OrigNonLocals, LambdaGoal, Unification,
+		polymorphism__process_lambda(PredOrFunc, Vars, Modes,
+				Det, OrigNonLocals, LambdaGoal, Unification,
 				Y1, Unification1),
 		{ Goal = unify(XVar, Y1, Mode, Unification1, Context)
 				- GoalInfo }
@@ -534,7 +537,7 @@
 	% so that the c_code can refer to the type_info variable
 	% for type T as `TypeInfo_for_T'.
 	%
-	=(poly_info(_, _, _, _, ModuleInfo)),
+	=(poly_info(_, _, _, _, _, ModuleInfo)),
 	{ module_info_pred_info(ModuleInfo, PredId, PredInfo) },
 	{ pred_info_arg_types(PredInfo, PredTypeVarSet, PredArgTypes) },
 	{ term__vars_list(PredArgTypes, PredTypeVars0) },
@@ -610,7 +613,7 @@
 polymorphism__process_call(PredId, _ProcId, ArgVars0, ArgVars,
 				ExtraVars, ExtraGoals, Info0, Info) :-
 	Info0 = poly_info(VarSet0, VarTypes0, TypeVarSet0,
-				TypeInfoMap0, ModuleInfo),
+				TypeInfoMap0, PredName, ModuleInfo),
 	module_info_pred_info(ModuleInfo, PredId, PredInfo),
 	pred_info_arg_types(PredInfo, PredTypeVarSet, PredArgTypes0),
 		% rename apart
@@ -642,7 +645,7 @@
 				VarTypes),
 		list__append(ExtraVars, ArgVars0, ArgVars),
 		Info = poly_info(VarSet, VarTypes, TypeVarSet,
-				TypeInfoMap, ModuleInfo)
+				TypeInfoMap, PredName, ModuleInfo)
 	).
 
 :- pred polymorphism__fixup_quantification(hlds_goal, hlds_goal,
@@ -658,7 +661,7 @@
 
 polymorphism__fixup_quantification(Goal0, Goal, Info0, Info) :-
 	Info0 = poly_info(VarSet0, VarTypes0, TypeVarSet, TypeVarMap,
-			ModuleInfo),
+			PredName, ModuleInfo),
 	( map__is_empty(TypeVarMap) ->
 		Info = Info0,
 		Goal = Goal0
@@ -682,11 +685,11 @@
 		implicitly_quantify_goal(Goal0, VarSet0, VarTypes0,
 			OutsideVars, Goal, VarSet, VarTypes, _Warnings),
 		Info = poly_info(VarSet, VarTypes, TypeVarSet, TypeVarMap,
-				ModuleInfo)
+				PredName, ModuleInfo)
 	).
 
-:- pred polymorphism__process_lambda(pred_or_func, list(var), list(mode),
-		determinism, set(var), hlds_goal, unification,
+:- pred polymorphism__process_lambda(pred_or_func, list(var),
+		list(mode), determinism, set(var), hlds_goal, unification,
 		unify_rhs, unification, poly_info, poly_info).
 :- mode polymorphism__process_lambda(in, in, in, in, in, in, in, out, out,
 		in, out) is det.
@@ -694,11 +697,14 @@
 polymorphism__process_lambda(PredOrFunc, Vars, Modes, Det, OrigNonLocals,
 		LambdaGoal, Unification0, Functor, Unification,
 		PolyInfo0, PolyInfo) :-
-	PolyInfo0 = poly_info(VarSet, VarTypes, TVarSet, TVarMap, ModuleInfo0),
-	lambda__transform_lambda(PredOrFunc, Vars, Modes, Det, OrigNonLocals,
-		LambdaGoal, Unification0, VarSet, VarTypes, TVarSet, TVarMap,
-		ModuleInfo0, Functor, Unification, ModuleInfo),
-	PolyInfo = poly_info(VarSet, VarTypes, TVarSet, TVarMap, ModuleInfo).
+	PolyInfo0 = poly_info(VarSet, VarTypes, TVarSet, TVarMap, PredName,
+			ModuleInfo0),
+	lambda__transform_lambda(PredOrFunc, PredName, Vars, Modes, Det,
+		OrigNonLocals, LambdaGoal, Unification0, VarSet, VarTypes,
+		TVarSet, TVarMap, ModuleInfo0, Functor,
+		Unification, ModuleInfo),
+	PolyInfo = poly_info(VarSet, VarTypes, TVarSet, TVarMap, PredName,
+			ModuleInfo).
 
 %---------------------------------------------------------------------------%
 
@@ -1238,14 +1244,14 @@
 :- mode polymorphism__get_module_info(out, in, out) is det.
 
 polymorphism__get_module_info(ModuleInfo, PolyInfo, PolyInfo) :-
-	PolyInfo = poly_info(_, _, _, _, ModuleInfo).
+	PolyInfo = poly_info(_, _, _, _, _, ModuleInfo).
 
 :- pred polymorphism__set_module_info(module_info, poly_info, poly_info).
 :- mode polymorphism__set_module_info(in, in, out) is det.
 
 polymorphism__set_module_info(ModuleInfo, PolyInfo0, PolyInfo) :-
-	PolyInfo0 = poly_info(A, B, C, D, _),
-	PolyInfo = poly_info(A, B, C, D, ModuleInfo).
+	PolyInfo0 = poly_info(A, B, C, D, E, _),
+	PolyInfo = poly_info(A, B, C, D, E, ModuleInfo).
 
 %---------------------------------------------------------------------------%
 %---------------------------------------------------------------------------%
cvs diff: Diffing compiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/Togl-1.2
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing library
cvs diff: Diffing lp_solve
cvs diff: Diffing lp_solve/lp_examples
cvs diff: Diffing profiler
Index: profiler/demangle.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/profiler/demangle.m,v
retrieving revision 1.1
diff -u -r1.1 demangle.m
--- demangle.m	1997/07/26 11:41:48	1.1
+++ demangle.m	1997/08/26 22:46:05
@@ -29,7 +29,8 @@
 :- implementation.
 :- import_module int, list, char, std_util, bool, require.
 
-:- type pred_category ---> index ; unify ; compare ; ordinary.
+:- type pred_category ---> index ; unify ; compare ; ordinary ;
+		lambda(int, string).
 :- type data_category ---> common ; info ; layout ; functors.
 
 demangle(MangledName, Name) :-
@@ -113,17 +114,17 @@
 	% skip past the prefix.
 	%
 	( remove_prefix("__Unify__") ->
-		{ Category = unify }
+		{ Category0 = unify }
 	; remove_prefix("__Compare__") ->
-		{ Category = compare },
+		{ Category0 = compare },
 		% there should only be one mode for compare/3 preds
 		{ ModeNum0 = 0 }
 	; remove_prefix("__Index__") ->
-		{ Category = index },
+		{ Category0 = index },
 		% there should only be one mode for index/2 preds
 		{ ModeNum0 = 0 }
 	;	
-		{ Category = ordinary }
+		{ Category0 = ordinary }
 	),
 
 	%
@@ -173,29 +174,53 @@
 	% Separate the module name from the type name for the compiler
 	% generated predicates.
 	%
-	( { Category \= ordinary } ->
+	( { Category0 \= ordinary } ->
 		remove_prefix("_"),
 		remove_maybe_module_prefix(MaybeModule),
 		{ MaybeModule \= yes("") }
 	;
 		remove_maybe_module_prefix(MaybeModule)
 	),
-		
+
 	%
 	% Make sure special predicates with unused_args 
 	% are reported correctly.
 	%
 
-	( { UnusedArgs = yes, Category \= ordinary } ->
+	( { UnusedArgs = yes, Category0 \= ordinary } ->
 		remove_trailing_int(Arity)
 	;
 		{ true }
 	),
 
 	%
+	% Now we need to look at the pred name and see if it is an
+	% introduced lambda predicate.
+	%
+
+	=(PredName0),
+
+	( remove_prefix("IntroducedFrom__") ->
+		( remove_prefix("pred__") ->
+			{ LambdaPredOrFunc = "pred" }
+		; remove_prefix("func__") ->
+			{ LambdaPredOrFunc = "func" }
+		;
+			{ fail }
+		),
+		remove_maybe_module_prefix(MPredName),
+		{ MPredName = yes(PredName) },
+		remove_int(Line),
+		{ Category = lambda(Line, LambdaPredOrFunc) }
+	;
+		{ Category = Category0 },
+		{ PredName = PredName0 }
+	),
+
+
+	%
 	% Now, finally, we can construct the demangled symbol name
 	%
-	=(PredName),
 	{ format_proc(Category, MaybeModule, PredOrFunc, PredName,
 		Arity, ModeNum, HigherOrder, UnusedArgs, MaybeInternalLabelNum,
 		Parts, []) },
@@ -229,6 +254,11 @@
 		string__format("%s %s/%d mode %d",
 			[s(PredOrFunc), s(QualifiedName), i(Arity), i(ModeNum)],
 			MainPart)
+	;
+		Category = lambda(Line, LambdaPredOrFunc),
+		string__format("%s goal from %s, line %d",
+			[s(LambdaPredOrFunc), s(QualifiedName), i(Line)],
+				MainPart)
 	},
 	[MainPart],
 	( { HigherOrder = yes } ->
cvs diff: Diffing runtime
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/diff
cvs diff: Diffing scripts
cvs diff: Diffing tools
cvs diff: Diffing trial
cvs diff: Diffing util
Index: util/mdemangle.c
===================================================================
RCS file: /home/staff/zs/imp/mercury/util/mdemangle.c,v
retrieving revision 1.20
diff -u -r1.20 mdemangle.c
--- mdemangle.c	1997/07/27 15:09:58	1.20
+++ mdemangle.c	1997/08/26 23:21:42
@@ -93,6 +93,10 @@
 	/* we call it `mindex' rather than `index' to
 	   avoid a naming conflict with strchr's alter ego index() */
 
+	static const char introduced[]  = "IntroducedFrom__";
+	static const char pred[]  = "pred__";
+	static const char func[]  = "func__";
+
 	static const char ua_suffix[] = "__ua"; /* added by unused_args.m */
 	static const char ua_suffix2[] = "__uab"; /* added by unused_args.m */
 	static const char ho_suffix[] = "__ho"; /* added by higher_order.m */
@@ -114,7 +118,10 @@
 	bool unused_args = FALSE; /* does this proc have any unused arguments */
 	bool higher_order = FALSE; /* has this proc been specialized */
 	int internal = -1;
-	enum { ORDINARY, UNIFY, COMPARE, INDEX } category;
+	int lambda_line = 0;
+	char *lambda_pred_name;
+	const char *lambda_kind;
+	enum { ORDINARY, UNIFY, COMPARE, INDEX, LAMBDA } category;
 	enum { COMMON, INFO, LAYOUT, FUNCTORS } data_category;
 
 	/*
@@ -284,6 +291,28 @@
 		}
 	}
 
+	if (category == ORDINARY && strip_prefix(&start, introduced)) {
+		category = LAMBDA;
+		if (strip_prefix(&start, pred)) {
+			lambda_kind = "pred";
+		} else if (strip_prefix(&start, func)) {
+			lambda_kind = "func";
+		} else {
+			goto wrong_format;
+		}
+		lambda_pred_name = start;
+		if (!cut_at_double_underscore(&start, end)) {
+			goto wrong_format;
+		}
+		lambda_line = 0;
+		while (start < end && isdigit(*start)) {
+			lambda_line = lambda_line * 10 + (*start - '0');
+			start++;
+		}
+	}
+
+			
+
 	/*
 	** Now, finally, we can print the demangled symbol name
 	*/
@@ -300,6 +329,10 @@
 	case INDEX:
 		printf("index/2 predicate for type '%s:%s'/%d",
 			type_module, start, arity);
+		break;
+	case LAMBDA:
+		printf("%s goal from '%s' line %d",
+			lambda_kind, lambda_pred_name, lambda_line);
 		break;
 	default:
 		printf("%s '%s'/%d mode %d",



More information about the developers mailing list