[m-rev.] diff: compress var name arrays

Zoltan Somogyi zs at cs.mu.OZ.AU
Tue May 4 17:22:28 AEST 2004


Reduce the size of .c and .o files with debugging enabled by compressing
tables of variable numbers. Previously, in the array indexed by variable
numbers whose entries gave each variable's name, the number we used to
identify a variable was its HLDS variable number. Variables whose names
weren't needed, or which didn't have names, or which were optimized away,
still had an entry in this array, which took up space in the .c and .o files
and at runtime.

This diff eliminates these unused array elements by identifying each variable
not via its HLDS variable number, but via a unique id number taken from a dense
set. This id number is used nowhere else, but this is OK.

This change reduces the sizes of .c files with debugging enabled by about 1.5%.

compiler/stack_layout.m:
	Implement the change described above.

	Bring most of this module up to date with our coding standards:
	use state variable syntax where appropriate. (Updating the rest 
	would cause unnecessary conflicts with another workspace.)

	Use 3-tuples instead of pairs of pairs.

trace/mercury_trace_internals.c:
	Implement a new command, var_name_stats, that displays statistics
	about the amount of space occupied by variable name arrays and the
	string tables they point into.

trace/mercury_trace_tables.[ch]:
	Provide the function implementing the new mdb command.

doc/user_guide.texi:
doc/mdb_categories:
	Document the new command.

tests/debugger/completion.inp:
tests/debugger/mdb_command_test.{inp}:
	Update these test cases to account for the new mdb command.
	(tests/debugger/completion.exp will be updated later.)

Zoltan.

cvs server: Diffing .
cvs server: Diffing analysis
cvs server: Diffing bindist
cvs server: Diffing boehm_gc
cvs server: Diffing boehm_gc/Mac_files
cvs server: Diffing boehm_gc/cord
cvs server: Diffing boehm_gc/cord/private
cvs server: Diffing boehm_gc/doc
cvs server: Diffing boehm_gc/include
cvs server: Diffing boehm_gc/include/private
cvs server: Diffing boehm_gc/tests
cvs server: Diffing browser
cvs server: Diffing bytecode
cvs server: Diffing compiler
Index: compiler/stack_layout.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/stack_layout.m,v
retrieving revision 1.86
diff -u -b -r1.86 stack_layout.m
--- compiler/stack_layout.m	3 May 2004 09:41:10 -0000	1.86
+++ compiler/stack_layout.m	4 May 2004 07:15:37 -0000
@@ -53,6 +53,7 @@
 :- implementation.
 
 :- import_module backend_libs__rtti.
+:- import_module hlds__goal_util.
 :- import_module hlds__hlds_data.
 :- import_module hlds__hlds_goal.
 :- import_module hlds__hlds_pred.
@@ -73,7 +74,7 @@
 :- import_module parse_tree__prog_util.
 
 :- import_module std_util, bool, char, string, int, require.
-:- import_module map, term, set, varset.
+:- import_module map, term, set, counter, varset.
 
 %---------------------------------------------------------------------------%
 
@@ -102,7 +103,7 @@
 	LayoutInfo0 = stack_layout_info(ModuleInfo0,
 		AgcLayout, TraceLayout, ProcIdLayout,
 		StaticCodeAddr, [], [], [], LayoutLabels0, [],
-		StringTable0, LabelTables0, map__init, StaticCellInfo0),
+		StringTable0, LabelTables0, StaticCellInfo0),
 	stack_layout__lookup_string_in_table("", _, LayoutInfo0, LayoutInfo1),
 	stack_layout__lookup_string_in_table("<too many variables>", _,
 		LayoutInfo1, LayoutInfo2),
@@ -292,7 +293,8 @@
 		VarSet, VarTypes, InternalMap, MaybeTableIoDecl, IsBeingTraced,
 		NeedsAllNames) },
 	{ map__to_assoc_list(InternalMap, Internals) },
-	stack_layout__set_cur_proc_named_vars(map__init),
+	{ compute_var_number_map(HeadVars, VarSet, Internals, MaybeGoal,
+		VarNumMap) },
 
 	{ code_util__extract_proc_label_from_label(EntryLabel, ProcLabel) },
 	stack_layout__get_procid_stack_layout(ProcIdLayout0),
@@ -323,9 +325,8 @@
 
 	{ ProcLayoutName = proc_layout(ProcLabel, Kind) },
 
-	list__foldl2(stack_layout__construct_internal_layout(ProcLayoutName),
-		Internals, [], InternalLayouts),
-	stack_layout__get_cur_proc_named_vars(NamedVars),
+	list__map_foldl(stack_layout__construct_internal_layout(ProcLayoutName,
+		VarNumMap), Internals, InternalLayouts),
 	stack_layout__get_label_tables(LabelTables0),
 	{ list__foldl(stack_layout__update_label_table, InternalLayouts,
 		LabelTables0, LabelTables) },
@@ -333,8 +334,8 @@
 	stack_layout__construct_proc_layout(RttiProcLabel, EntryLabel,
 		ProcLabel, Detism, StackSlots, SuccipLoc, EvalMethod,
 		MaybeCallLabel, MaxTraceReg, HeadVars, MaybeGoal, InstMap,
-		TraceSlotInfo, VarSet, VarTypes, NamedVars, MaybeTableIoDecl,
-		Kind, NeedsAllNames).
+		TraceSlotInfo, VarSet, VarTypes, MaybeTableIoDecl,
+		Kind, NeedsAllNames, VarNumMap).
 
 %---------------------------------------------------------------------------%
 
@@ -436,15 +437,15 @@
 	proc_label::in, determinism::in, int::in, maybe(int)::in,
 	eval_method::in, maybe(label)::in, int::in, list(prog_var)::in,
 	maybe(hlds_goal)::in, instmap::in, trace_slot_info::in, prog_varset::in,
-	vartypes::in, map(int, string)::in, maybe(proc_table_info)::in,
-	proc_layout_kind::in, bool::in, stack_layout_info::in,
-	stack_layout_info::out) is det.
+	vartypes::in, maybe(proc_table_info)::in,
+	proc_layout_kind::in, bool::in, var_num_map::in,
+	stack_layout_info::in, stack_layout_info::out) is det.
 
 stack_layout__construct_proc_layout(RttiProcLabel, EntryLabel, ProcLabel,
 		Detism, StackSlots, MaybeSuccipLoc, EvalMethod, MaybeCallLabel,
 		MaxTraceReg, HeadVars, MaybeGoal, InstMap, TraceSlotInfo,
-		VarSet, VarTypes, UsedVarNames, MaybeTableInfo, Kind,
-		NeedsAllNames) -->
+		VarSet, VarTypes, MaybeTableInfo, Kind,
+		NeedsAllNames, VarNumMap) -->
 	{
 		MaybeSuccipLoc = yes(Location)
 	->
@@ -503,8 +504,8 @@
 		{ Kind = proc_layout_exec_trace(_) },
 		stack_layout__construct_trace_layout(RttiProcLabel, EvalMethod,
 			MaybeCallLabel, MaxTraceReg, HeadVars, MaybeGoal,
-			InstMap, TraceSlotInfo, VarSet, VarTypes, UsedVarNames,
-			MaybeTableInfo, NeedsAllNames, ExecTrace),
+			InstMap, TraceSlotInfo, VarSet, VarTypes,
+			MaybeTableInfo, NeedsAllNames, VarNumMap, ExecTrace),
 		{ MaybeRest = proc_id_and_exec_trace(ExecTrace) }
 	),
 
@@ -528,17 +529,17 @@
 :- pred stack_layout__construct_trace_layout(rtti_proc_label::in,
 	eval_method::in, maybe(label)::in, int::in, list(prog_var)::in,
 	maybe(hlds_goal)::in, instmap::in, trace_slot_info::in, prog_varset::in,
-	vartypes::in, map(int, string)::in, maybe(proc_table_info)::in,
-	bool::in, proc_layout_exec_trace::out,
+	vartypes::in, maybe(proc_table_info)::in, bool::in,
+	var_num_map::in, proc_layout_exec_trace::out,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
 stack_layout__construct_trace_layout(RttiProcLabel, EvalMethod, MaybeCallLabel,
 		MaxTraceReg, HeadVars, MaybeGoal, InstMap, TraceSlotInfo,
-		VarSet, VarTypes, UsedVarNameMap, MaybeTableInfo,
-		NeedsAllNames, ExecTrace, !Info) :-
-	stack_layout__construct_var_name_vector(VarSet, UsedVarNameMap,
+		_VarSet, VarTypes, MaybeTableInfo, NeedsAllNames, VarNumMap,
+		ExecTrace, !Info) :-
+	stack_layout__construct_var_name_vector(VarNumMap,
 		NeedsAllNames, MaxVarNum, VarNameVector, !Info),
-	list__map(term__var_to_int, HeadVars, HeadVarNumVector),
+	list__map(convert_var_to_int(VarNumMap), HeadVars, HeadVarNumVector),
 	(
 		MaybeGoal = no,
 		MaybeProcRepRval = no
@@ -585,29 +586,37 @@
 		MaybeTrailSlots, MaybeMaxfrSlot, EvalMethod,
 		MaybeCallTableSlot).
 
-:- pred stack_layout__construct_var_name_vector(prog_varset::in,
-	map(int, string)::in, bool::in, int::out, list(int)::out,
+:- pred stack_layout__construct_var_name_vector(var_num_map::in,
+	bool::in, int::out, list(int)::out,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
-stack_layout__construct_var_name_vector(VarSet, UsedVarNameMap, NeedsAllNames,
-		Count, Offsets, !Info) :-
+stack_layout__construct_var_name_vector(VarNumMap, NeedsAllNames, MaxVarNum,
+		Offsets, !Info) :-
+	map__values(VarNumMap, VarNames0),
 	(
 		NeedsAllNames = yes,
-		varset__var_name_list(VarSet, VarNameList),
-		list__map(stack_layout__convert_var_name_to_int,
-			VarNameList, VarNames)
+		VarNames = VarNames0
 	;
 		NeedsAllNames = no,
-		map__to_assoc_list(UsedVarNameMap, VarNames)
+		list__filter(var_has_name, VarNames0, VarNames)
 	),
-	( VarNames = [FirstVar - _ | _] ->
-		stack_layout__construct_var_name_rvals(VarNames, 1,
-			FirstVar, Count, Offsets, !Info)
-	;
-		Count = 0,
+	list__sort(VarNames, SortedVarNames),
+	( SortedVarNames = [FirstVarNum - _ | _] ->
+		MaxVarNum0 = FirstVarNum,
+		stack_layout__construct_var_name_rvals(SortedVarNames, 1,
+			MaxVarNum0, MaxVarNum, Offsets, !Info)
+	;
+			% Since variable numbers start at 1, MaxVarNum = 0
+			% implies an empty array.
+		MaxVarNum = 0,
 		Offsets = []
 	).
 
+:- pred var_has_name(pair(int, string)::in) is semidet.
+
+var_has_name(_VarNum - VarName) :-
+	VarName \= "".
+
 :- pred stack_layout__construct_var_name_rvals(assoc_list(int, string)::in,
 	int::in, int::in, int::out, list(int)::out,
 	stack_layout_info::in, stack_layout_info::out) is det.
@@ -628,17 +637,116 @@
 
 %---------------------------------------------------------------------------%
 
+% A var_num_map maps each variable that occurs in any of a procedure's layout
+% structures to a number that uniquely identifies that variable, and to its
+% name.
+%
+% The integer returned by term__var_to_int are a dense set when we consider
+% all the original variables of a procedure. However, it can become less dense
+% when an optimization removes all references to a variable, and becomes less
+% dense still when we consider only variables that occur in a layout structure.
+% This is why we allocate our own id numbers.
+
+:- type var_num_map	== map(prog_var, pair(int, string)).
+
+:- pred compute_var_number_map(list(prog_var)::in, prog_varset::in,
+	assoc_list(label, internal_layout_info)::in, maybe(hlds_goal)::in,
+	var_num_map::out) is det.
+
+compute_var_number_map(HeadVars, VarSet, Internals, MaybeGoal, VarNumMap) :-
+	VarNumMap0 = map__init,
+	Counter0 = counter__init(1),	% to match term__var_supply_init
+	(
+		MaybeGoal = yes(Goal),
+		goal_util__goal_vars(Goal, GoalVarSet),
+		set__to_sorted_list(GoalVarSet, GoalVars),
+		list__foldl2(add_var_to_var_number_map(VarSet), GoalVars,
+			VarNumMap0, VarNumMap1, Counter0, Counter1)
+	;
+		MaybeGoal = no,
+		VarNumMap1 = VarNumMap0,
+		Counter1 = Counter0
+	),
+	list__foldl2(add_var_to_var_number_map(VarSet), HeadVars,
+		VarNumMap1, VarNumMap2, Counter1, Counter2),
+	list__foldl2(internal_var_number_map, Internals, VarNumMap2, VarNumMap,
+		Counter2, _Counter).
+
+:- pred internal_var_number_map(pair(label, internal_layout_info)::in,
+	var_num_map::in, var_num_map::out, counter::in, counter::out) is det.
+
+internal_var_number_map(_Label - Internal, !VarNumMap, !Counter) :-
+	Internal = internal_layout_info(MaybeTrace, MaybeResume, MaybeReturn),
+	(
+		MaybeTrace = yes(Trace),
+		Trace = trace_port_layout_info(_, _, _, _, TraceLayout),
+		label_layout_var_number_map(TraceLayout, !VarNumMap, !Counter)
+	;
+		MaybeTrace = no
+	),
+	(
+		MaybeResume = yes(ResumeLayout),
+		label_layout_var_number_map(ResumeLayout, !VarNumMap, !Counter)
+	;
+		MaybeResume = no
+	),
+	(
+		MaybeReturn = yes(Return),
+		Return = return_layout_info(_, ReturnLayout),
+		label_layout_var_number_map(ReturnLayout, !VarNumMap, !Counter)
+	;
+		MaybeReturn = no
+	).
+
+:- pred label_layout_var_number_map(layout_label_info::in,
+	var_num_map::in, var_num_map::out, counter::in, counter::out) is det.
+
+label_layout_var_number_map(LabelLayout, !VarNumMap, !Counter) :-
+	LabelLayout = layout_label_info(VarInfoSet, _),
+	VarInfos = set__to_sorted_list(VarInfoSet),
+	FindVar = (pred(VarInfo::in, Var - Name::out) is semidet :-
+		VarInfo = var_info(_, LiveValueType),
+		LiveValueType = var(Var, Name, _, _)
+	),
+	list__filter_map(FindVar, VarInfos, VarsNames),
+	list__foldl2(add_named_var_to_var_number_map, VarsNames,
+		!VarNumMap, !Counter).
+
+:- pred add_var_to_var_number_map(prog_varset::in, prog_var::in,
+	var_num_map::in, var_num_map::out, counter::in, counter::out) is det.
+
+add_var_to_var_number_map(VarSet, Var, !VarNumMap, !Counter) :-
+	( varset__search_name(VarSet, Var, VarName) ->
+		Name = VarName
+	;
+		Name = ""
+	),
+	add_named_var_to_var_number_map(Var - Name, !VarNumMap, !Counter).
+
+:- pred add_named_var_to_var_number_map(pair(prog_var, string)::in,
+	var_num_map::in, var_num_map::out, counter::in, counter::out) is det.
+
+add_named_var_to_var_number_map(Var - Name, !VarNumMap, !Counter) :-
+	( map__search(!.VarNumMap, Var, _) ->
+		% Name shouldn't differ from the name recorded in !.VarNumMap.
+		true
+	;
+		counter__allocate(VarNum, !Counter),
+		map__det_insert(!.VarNumMap, Var, VarNum - Name, !:VarNumMap)
+	).
+
+%---------------------------------------------------------------------------%
+
 	% Construct the layout describing a single internal label
 	% for accurate GC and/or execution tracing.
 
 :- pred stack_layout__construct_internal_layout(layout_name::in,
-	pair(label, internal_layout_info)::in,
-	list({label, label_vars, internal_layout_info})::in,
-	list({label, label_vars, internal_layout_info})::out,
+	var_num_map::in, pair(label, internal_layout_info)::in,
+	{label, label_vars, internal_layout_info}::out,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
-stack_layout__construct_internal_layout(ProcLayoutName, Label - Internal,
-		!LabelLayouts, !Info) :-
+stack_layout__construct_internal_layout(ProcLayoutName, VarNumMap,
+		Label - Internal, LabelLayout, !Info) :-
 	Internal = internal_layout_info(Trace, Resume, Return),
 	(
 		Trace = no,
@@ -752,9 +860,9 @@
 			TypeVarMap0),
 		map__union(set__intersect, TypeVarMap0, ReturnTypeVarMap,
 			TypeVarMap),
-		stack_layout__construct_livelval_rvals(LiveVarSet, TypeVarMap,
-			EncodedLength, LiveValRval, NamesRval, TypeParamRval,
-			!Info),
+		stack_layout__construct_livelval_rvals(LiveVarSet, VarNumMap,
+			TypeVarMap, EncodedLength, LiveValRval, NamesRval,
+			TypeParamRval, !Info),
 		VarInfo = label_var_info(EncodedLength, LiveValRval, NamesRval,
 			TypeParamRval),
 		MaybeVarInfo = yes(VarInfo),
@@ -767,19 +875,20 @@
 	LayoutName = label_layout(Label, LabelVars),
 	stack_layout__add_internal_layout_data(CData, Label, LayoutName,
 		!Info),
-	!:LabelLayouts = [{Label, LabelVars, Internal} | !.LabelLayouts].
+	LabelLayout = {Label, LabelVars, Internal}.
 
 %---------------------------------------------------------------------------%
 
 :- pred stack_layout__construct_livelval_rvals(set(var_info)::in,
-	map(tvar, set(layout_locn))::in, int::out, rval::out, rval::out,
-	rval::out, stack_layout_info::in, stack_layout_info::out) is det.
+	var_num_map::in, map(tvar, set(layout_locn))::in, int::out,
+	rval::out, rval::out, rval::out,
+	stack_layout_info::in, stack_layout_info::out) is det.
 
-stack_layout__construct_livelval_rvals(LiveLvalSet, TVarLocnMap, EncodedLength,
-		LiveValRval, NamesRval, TypeParamRval, !Info) :-
+stack_layout__construct_livelval_rvals(LiveLvalSet, VarNumMap, TVarLocnMap,
+		EncodedLength, LiveValRval, NamesRval, TypeParamRval, !Info) :-
 	set__to_sorted_list(LiveLvalSet, LiveLvals),
 	stack_layout__sort_livevals(LiveLvals, SortedLiveLvals),
-	stack_layout__construct_liveval_arrays(SortedLiveLvals,
+	stack_layout__construct_liveval_arrays(SortedLiveLvals, VarNumMap,
 		EncodedLength, LiveValRval, NamesRval, !Info),
 	StaticCellInfo0 = !.Info ^ static_cell_info,
 	stack_layout__construct_tvar_vector(TVarLocnMap,
@@ -936,13 +1045,13 @@
 	% and a corresponding vector of variable names.
 
 :- pred stack_layout__construct_liveval_arrays(list(var_info)::in,
-	int::out, rval::out, rval::out,
+	var_num_map::in, int::out, rval::out, rval::out,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
-stack_layout__construct_liveval_arrays(VarInfos, EncodedLength,
+stack_layout__construct_liveval_arrays(VarInfos, VarNumMap, EncodedLength,
 		TypeLocnVector, NumVector, !Info) :-
 	int__pow(2, stack_layout__short_count_bits, BytesLimit),
-	stack_layout__construct_liveval_array_infos(VarInfos,
+	stack_layout__construct_liveval_array_infos(VarInfos, VarNumMap,
 		0, BytesLimit, IntArrayInfo, ByteArrayInfo, !Info),
 
 	list__length(IntArrayInfo, IntArrayLength),
@@ -1000,17 +1109,18 @@
 associate_type(LldsType, Rval, Rval - LldsType).
 
 :- pred stack_layout__construct_liveval_array_infos(list(var_info)::in,
-	int::in, int::in,
+	var_num_map::in, int::in, int::in,
 	list(liveval_array_info)::out, list(liveval_array_info)::out,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
-stack_layout__construct_liveval_array_infos([], _, _, [], [], !Info).
-stack_layout__construct_liveval_array_infos([VarInfo | VarInfos],
+stack_layout__construct_liveval_array_infos([], _, _, _, [], [], !Info).
+stack_layout__construct_liveval_array_infos([VarInfo | VarInfos], VarNumMap,
 		BytesSoFar, BytesLimit, IntVars, ByteVars, !Info) :-
 	VarInfo = var_info(Locn, LiveValueType),
 	stack_layout__represent_live_value_type(LiveValueType, TypeRval,
 		TypeRvalType, !Info),
-	stack_layout__construct_liveval_num_rval(VarInfo, VarNumRval, !Info),
+	stack_layout__construct_liveval_num_rval(VarNumMap, VarInfo,
+		VarNumRval, !Info),
 	(
 		BytesSoFar < BytesLimit,
 		stack_layout__represent_locn_as_byte(Locn, LocnByteRval)
@@ -1018,48 +1128,37 @@
 		Var = live_array_info(LocnByteRval, TypeRval, TypeRvalType,
 			VarNumRval),
 		stack_layout__construct_liveval_array_infos(VarInfos,
-			BytesSoFar + 1, BytesLimit, IntVars, ByteVars0, !Info),
+			VarNumMap, BytesSoFar + 1, BytesLimit,
+			IntVars, ByteVars0, !Info),
 		ByteVars = [Var | ByteVars0]
 	;
 		stack_layout__represent_locn_as_int_rval(Locn, LocnRval),
 		Var = live_array_info(LocnRval, TypeRval, TypeRvalType,
 			VarNumRval),
 		stack_layout__construct_liveval_array_infos(VarInfos,
-			BytesSoFar, BytesLimit, IntVars0, ByteVars, !Info),
+			VarNumMap, BytesSoFar, BytesLimit,
+			IntVars0, ByteVars, !Info),
 		IntVars = [Var | IntVars0]
 	).
 
-:- pred stack_layout__construct_liveval_num_rval(var_info::in, rval::out,
+:- pred stack_layout__construct_liveval_num_rval(var_num_map::in,
+	var_info::in, rval::out,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
-stack_layout__construct_liveval_num_rval(var_info(_, LiveValueType),
+stack_layout__construct_liveval_num_rval(VarNumMap, var_info(_, LiveValueType),
 		VarNumRval, !Info) :-
-	( LiveValueType = var(Var, Name, _, _) ->
-		stack_layout__convert_var_to_int(Var, VarNum),
-		VarNumRval = const(int_const(VarNum)),
-		stack_layout__get_cur_proc_named_vars(NamedVars0, !Info),
-		( map__insert(NamedVars0, VarNum, Name, NamedVars) ->
-			stack_layout__set_cur_proc_named_vars(NamedVars,
-				!Info)
-		;
-			% The variable has been put into the map already at
-			% another label.
-			true
-		)
+	( LiveValueType = var(Var, _, _, _) ->
+		stack_layout__convert_var_to_int(VarNumMap, Var, VarNum),
+		VarNumRval = const(int_const(VarNum))
 	;
 		VarNumRval = const(int_const(0))
 	).
 
-:- pred stack_layout__convert_var_name_to_int(pair(prog_var, string)::in,
-	pair(int, string)::out) is det.
-
-stack_layout__convert_var_name_to_int(Var - Name, VarNum - Name) :-
-	stack_layout__convert_var_to_int(Var, VarNum).
+:- pred stack_layout__convert_var_to_int(var_num_map::in, prog_var::in,
+	int::out) is det.
 
-:- pred stack_layout__convert_var_to_int(prog_var::in, int::out) is det.
-
-stack_layout__convert_var_to_int(Var, VarNum) :-
-	term__var_to_int(Var, VarNum0),
+stack_layout__convert_var_to_int(VarNumMap, Var, VarNum) :-
+	map__lookup(VarNumMap, Var, VarNum0 - _),
 		% The variable number has to fit into two bytes.
 		% We reserve the largest such number (Limit)
 		% to mean that the variable number is too large
@@ -1531,12 +1630,6 @@
 					   % contributes labels to this module
 					   % to a table describing those
 					   % labels.
-		cur_proc_named_vars	:: map(int, string),
-					   % Maps the number of each variable
-					   % in the current procedure whose
-					   % name is of interest in an internal
-					   % label's layout structure to the
-					   % name of that variable.
 		static_cell_info	:: static_cell_info
 	).
 
@@ -1573,9 +1666,6 @@
 :- pred stack_layout__get_label_tables(map(string, label_table)::out,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
-:- pred stack_layout__get_cur_proc_named_vars(map(int, string)::out,
-	stack_layout_info::in, stack_layout_info::out) is det.
-
 :- pred stack_layout__get_static_cell_info(static_cell_info::out,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
@@ -1590,7 +1680,6 @@
 stack_layout__get_label_set(LI ^ label_set, LI, LI).
 stack_layout__get_string_table(LI ^ string_table, LI, LI).
 stack_layout__get_label_tables(LI ^ label_tables, LI, LI).
-stack_layout__get_cur_proc_named_vars(LI ^ cur_proc_named_vars, LI, LI).
 stack_layout__get_static_cell_info(LI ^ static_cell_info, LI, LI).
 
 :- pred stack_layout__add_table_data(layout_data::in,
@@ -1637,16 +1726,11 @@
 :- pred stack_layout__set_label_tables(map(string, label_table)::in,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
-:- pred stack_layout__set_cur_proc_named_vars(map(int, string)::in,
-	stack_layout_info::in, stack_layout_info::out) is det.
-
 :- pred stack_layout__set_static_cell_info(static_cell_info::in,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
 stack_layout__set_string_table(ST, LI0, LI0 ^ string_table := ST).
 stack_layout__set_label_tables(LT, LI0, LI0 ^ label_tables := LT).
-stack_layout__set_cur_proc_named_vars(NV, LI0,
-	LI0 ^ cur_proc_named_vars := NV).
 stack_layout__set_static_cell_info(SCI, LI0,
 	LI0 ^ static_cell_info := SCI).
 
cvs server: Diffing compiler/notes
cvs server: Diffing debian
cvs server: Diffing deep_profiler
cvs server: Diffing deep_profiler/notes
cvs server: Diffing doc
Index: doc/mdb_categories
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/mdb_categories,v
retrieving revision 1.19
diff -u -b -r1.19 mdb_categories
--- doc/mdb_categories	12 Mar 2004 06:02:02 -0000	1.19
+++ doc/mdb_categories	4 May 2004 07:15:37 -0000
@@ -70,7 +70,8 @@
              `flag', `subgoal', `consumer', `gen_stack', `cut_stack,
              `pneg_stack', `mm_stacks', `nondet_stack', `stack_regs',
              `all_regs', `debug_vars', `proc_stats', `label_stats',
-             `print_optionals', `unhide_events', `dd_dd', `table',
-             `type_ctor', `class_decl', `all_type_ctors' and `all_class_decls'.
+             `var_name_stats', `print_optionals', `unhide_events', `dd_dd',
+             `table', `type_ctor', `class_decl', `all_type_ctors' and
+             `all_class_decls'.
 
 end
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.383
diff -u -b -r1.383 user_guide.texi
--- doc/user_guide.texi	18 Mar 2004 03:42:10 -0000	1.383
+++ doc/user_guide.texi	4 May 2004 07:15:40 -0000
@@ -3315,6 +3315,16 @@
 Prints statistics about label layout structures in the program
 to the file @var{filename}.
 @sp 1
+ at item var_name_stats
+ at kindex var_name_stats (mdb command)
+Prints statistics about the memory requirements of variable names
+in the layout structures in the program.
+ at sp 1
+ at item var_name_stats @var{filename}
+Prints statistics about the memory requirements of variable names
+in the layout structures in the program
+to the file @var{filename}.
+ at sp 1
 @item print_optionals
 @kindex print_optionals (mdb command)
 Reports whether optionally-printed values such as typeinfos
cvs server: Diffing extras
cvs server: Diffing extras/aditi
cvs server: Diffing extras/cgi
cvs server: Diffing extras/complex_numbers
cvs server: Diffing extras/complex_numbers/samples
cvs server: Diffing extras/complex_numbers/tests
cvs server: Diffing extras/concurrency
cvs server: Diffing extras/curs
cvs server: Diffing extras/curs/samples
cvs server: Diffing extras/curses
cvs server: Diffing extras/curses/sample
cvs server: Diffing extras/dynamic_linking
cvs server: Diffing extras/error
cvs server: Diffing extras/graphics
cvs server: Diffing extras/graphics/mercury_opengl
cvs server: Diffing extras/graphics/mercury_tcltk
cvs server: Diffing extras/graphics/samples
cvs server: Diffing extras/graphics/samples/calc
cvs server: Diffing extras/graphics/samples/maze
cvs server: Diffing extras/graphics/samples/pent
cvs server: Diffing extras/lazy_evaluation
cvs server: Diffing extras/lex
cvs server: Diffing extras/lex/samples
cvs server: Diffing extras/lex/tests
cvs server: Diffing extras/logged_output
cvs server: Diffing extras/moose
cvs server: Diffing extras/moose/samples
cvs server: Diffing extras/moose/tests
cvs server: Diffing extras/morphine
cvs server: Diffing extras/morphine/non-regression-tests
cvs server: Diffing extras/morphine/scripts
cvs server: Diffing extras/morphine/source
cvs server: Diffing extras/odbc
cvs server: Diffing extras/posix
cvs server: Diffing extras/quickcheck
cvs server: Diffing extras/quickcheck/tutes
cvs server: Diffing extras/references
cvs server: Diffing extras/references/samples
cvs server: Diffing extras/references/tests
cvs server: Diffing extras/stream
cvs server: Diffing extras/trailed_update
cvs server: Diffing extras/trailed_update/samples
cvs server: Diffing extras/trailed_update/tests
cvs server: Diffing extras/xml
cvs server: Diffing extras/xml/samples
cvs server: Diffing java
cvs server: Diffing java/runtime
cvs server: Diffing library
cvs server: Diffing profiler
cvs server: Diffing robdd
cvs server: Diffing runtime
cvs server: Diffing runtime/GETOPT
cvs server: Diffing runtime/machdeps
cvs server: Diffing samples
cvs server: Diffing samples/c_interface
cvs server: Diffing samples/c_interface/c_calls_mercury
cvs server: Diffing samples/c_interface/cplusplus_calls_mercury
cvs server: Diffing samples/c_interface/mercury_calls_c
cvs server: Diffing samples/c_interface/mercury_calls_cplusplus
cvs server: Diffing samples/c_interface/mercury_calls_fortran
cvs server: Diffing samples/c_interface/simpler_c_calls_mercury
cvs server: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs server: Diffing samples/diff
cvs server: Diffing samples/muz
cvs server: Diffing samples/rot13
cvs server: Diffing samples/solutions
cvs server: Diffing samples/tests
cvs server: Diffing samples/tests/c_interface
cvs server: Diffing samples/tests/c_interface/c_calls_mercury
cvs server: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs server: Diffing samples/tests/c_interface/mercury_calls_c
cvs server: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs server: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs server: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs server: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs server: Diffing samples/tests/diff
cvs server: Diffing samples/tests/muz
cvs server: Diffing samples/tests/rot13
cvs server: Diffing samples/tests/solutions
cvs server: Diffing samples/tests/toplevel
cvs server: Diffing scripts
cvs server: Diffing tests
cvs server: Diffing tests/benchmarks
cvs server: Diffing tests/debugger
Index: tests/debugger/completion.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/completion.inp,v
retrieving revision 1.7
diff -u -b -r1.7 completion.inp
--- tests/debugger/completion.inp	16 Mar 2004 05:08:13 -0000	1.7
+++ tests/debugger/completion.inp	4 May 2004 07:15:41 -0000
@@ -1,6 +1,6 @@
 echo on
 register --quiet
- at h@e at v@a@
+ at h@e at v@a at s@
 p --f@@D@
 sta@ @
 proc at e@complet at .@1
Index: tests/debugger/mdb_command_test.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/mdb_command_test.inp,v
retrieving revision 1.26
diff -u -b -r1.26 mdb_command_test.inp
--- tests/debugger/mdb_command_test.inp	12 Mar 2004 06:02:13 -0000	1.26
+++ tests/debugger/mdb_command_test.inp	4 May 2004 07:15:41 -0000
@@ -58,6 +58,7 @@
 debug_vars           xyzzy xyzzy xyzzy xyzzy xyzzy
 proc_stats           xyzzy xyzzy xyzzy xyzzy xyzzy
 label_stats          xyzzy xyzzy xyzzy xyzzy xyzzy
+var_name_stats       xyzzy xyzzy xyzzy xyzzy xyzzy
 print_optionals      xyzzy xyzzy xyzzy xyzzy xyzzy
 unhide_events        xyzzy xyzzy xyzzy xyzzy xyzzy
 dd_dd                xyzzy xyzzy xyzzy xyzzy xyzzy
cvs server: Diffing tests/debugger/declarative
cvs server: Diffing tests/dppd
cvs server: Diffing tests/general
cvs server: Diffing tests/general/accumulator
cvs server: Diffing tests/general/string_format
cvs server: Diffing tests/general/structure_reuse
cvs server: Diffing tests/grade_subdirs
cvs server: Diffing tests/hard_coded
cvs server: Diffing tests/hard_coded/exceptions
cvs server: Diffing tests/hard_coded/purity
cvs server: Diffing tests/hard_coded/sub-modules
cvs server: Diffing tests/hard_coded/typeclasses
cvs server: Diffing tests/invalid
cvs server: Diffing tests/invalid/purity
cvs server: Diffing tests/misc_tests
cvs server: Diffing tests/mmc_make
cvs server: Diffing tests/mmc_make/lib
cvs server: Diffing tests/recompilation
cvs server: Diffing tests/tabling
cvs server: Diffing tests/term
cvs server: Diffing tests/valid
cvs server: Diffing tests/warnings
cvs server: Diffing tools
cvs server: Diffing trace
Index: trace/mercury_trace_internal.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_internal.c,v
retrieving revision 1.169
diff -u -b -r1.169 mercury_trace_internal.c
--- trace/mercury_trace_internal.c	12 Mar 2004 06:02:18 -0000	1.169
+++ trace/mercury_trace_internal.c	4 May 2004 07:15:44 -0000
@@ -447,6 +447,7 @@
 static	MR_TraceCmdFunc	MR_trace_cmd_table_io;
 static	MR_TraceCmdFunc	MR_trace_cmd_proc_stats;
 static	MR_TraceCmdFunc	MR_trace_cmd_label_stats;
+static	MR_TraceCmdFunc	MR_trace_cmd_var_name_stats;
 static	MR_TraceCmdFunc	MR_trace_cmd_proc_body;
 static	MR_TraceCmdFunc	MR_trace_cmd_print_optionals;
 static	MR_TraceCmdFunc	MR_trace_cmd_unhide_events;
@@ -3779,6 +3780,34 @@
 }
 
 static MR_Next
+MR_trace_cmd_var_name_stats(char **words, int word_count,
+	MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info,
+	MR_Event_Details *event_details, MR_Code **jumpaddr)
+{
+	if (word_count == 1) {
+		MR_var_name_stats(MR_mdb_out);
+	} else if (word_count == 2) {
+		FILE	*fp;
+
+		fp = fopen(words[1], "w");
+		if (fp == NULL) {
+			fflush(MR_mdb_out);
+			fprintf(MR_mdb_err,
+				"mdb: error opening `%s': %s.\n",
+				words[1], strerror(errno));
+			return KEEP_INTERACTING;
+		}
+
+		MR_var_name_stats(fp);
+		(void) fclose(fp);
+	} else {
+		MR_trace_usage("developer", "var_name_stats");
+	}
+
+	return KEEP_INTERACTING;
+}
+
+static MR_Next
 MR_trace_cmd_print_optionals(char **words, int word_count,
 	MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info,
 	MR_Event_Details *event_details, MR_Code **jumpaddr)
@@ -6989,6 +7018,8 @@
 	{ "developer", "proc_stats", MR_trace_cmd_proc_stats,
 		NULL, MR_trace_filename_completer },
 	{ "developer", "label_stats", MR_trace_cmd_label_stats,
+		NULL, MR_trace_filename_completer },
+	{ "developer", "var_name_stats", MR_trace_cmd_var_name_stats,
 		NULL, MR_trace_filename_completer },
 	{ "developer", "print_optionals", MR_trace_cmd_print_optionals,
 		MR_trace_on_off_args, MR_trace_null_completer },
Index: trace/mercury_trace_tables.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_tables.c,v
retrieving revision 1.26
diff -u -b -r1.26 mercury_trace_tables.c
--- trace/mercury_trace_tables.c	12 Feb 2004 01:35:22 -0000	1.26
+++ trace/mercury_trace_tables.c	4 May 2004 07:15:44 -0000
@@ -1007,7 +1007,9 @@
 	const MR_Module_Layout		*module_layout;
 	const MR_Module_File_Layout	*file_layout;
 	const MR_Label_Layout		*label_layout;
-	int				module_num, file_num, label_num;
+	int				module_num;
+	int				file_num;
+	int				label_num;
 	MR_Trace_Port			port;
 	int				total;
 	int				histogram[MR_PORT_NUM_PORTS];
@@ -1052,4 +1054,76 @@
 			((float) 100 * histogram[port]) / total);
 	}
 	fprintf(fp, "%s %10d\n", "all ", total);
+}
+
+void
+MR_var_name_stats(FILE *fp)
+{
+	const MR_Module_Layout		*module_layout;
+	const MR_Proc_Layout		*proc_layout;
+	const MR_uint_least32_t		*var_names;
+	int				module_num;
+	int				proc_num;
+	int				var_num;
+	int				num_var_nums;
+	int				total_string_table_bytes;
+	int				total_var_num_table_entries;
+	int				total_used_var_num_table_entries;
+	int				total_unused_var_num_table_entries;
+	int				total_num_procs;
+
+	total_string_table_bytes = 0;
+	total_var_num_table_entries = 0;
+	total_used_var_num_table_entries = 0;
+	total_num_procs = 0;
+
+	for (module_num = 0; module_num < MR_module_info_next; module_num++) {
+		module_layout = MR_module_infos[module_num];
+
+		total_string_table_bytes +=
+			module_layout->MR_ml_string_table_size;
+
+		for (proc_num = 0;
+			proc_num < module_layout->MR_ml_proc_count;
+			proc_num++)
+		{
+			proc_layout = module_layout->MR_ml_procs[proc_num];
+			total_num_procs += 1;
+
+			if (! MR_PROC_LAYOUT_HAS_EXEC_TRACE(proc_layout)) {
+				continue;
+			}
+
+			var_names = proc_layout->MR_sle_used_var_names;
+			num_var_nums =
+				proc_layout->MR_sle_max_named_var_num + 1;
+
+			total_var_num_table_entries += num_var_nums;
+			for (var_num = 0; var_num < num_var_nums; var_num++) {
+				if (var_names[var_num] != 0) {
+					total_used_var_num_table_entries++;
+				}
+			}
+		}
+	}
+
+	fprintf(fp, "%d modules, %d bytes in string tables, average %.2f\n",
+		MR_module_info_next, total_string_table_bytes,
+		(float) total_string_table_bytes / MR_module_info_next);
+	fprintf(fp, "%d procedures, %d var numbers, average %.2f\n",
+		total_num_procs, total_var_num_table_entries,
+		(float) total_var_num_table_entries / total_num_procs);
+	fprintf(fp, "%d procedures, %d used var numbers, average %.2f\n",
+		total_num_procs, total_used_var_num_table_entries,
+		(float) total_used_var_num_table_entries / total_num_procs);
+	fprintf(fp, "%d var numbers, %d used, average %.2f%%\n",
+		total_var_num_table_entries,
+		total_used_var_num_table_entries,
+		(float) 100 * total_used_var_num_table_entries /
+			total_var_num_table_entries);
+	total_unused_var_num_table_entries =
+		total_var_num_table_entries - total_used_var_num_table_entries;
+	fprintf(fp, "%d unused var numbers, %d bytes\n",
+		total_unused_var_num_table_entries,
+		4 * total_unused_var_num_table_entries);
 }
Index: trace/mercury_trace_tables.h
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_tables.h,v
retrieving revision 1.13
diff -u -b -r1.13 mercury_trace_tables.h
--- trace/mercury_trace_tables.h	15 Nov 2002 04:50:49 -0000	1.13
+++ trace/mercury_trace_tables.h	4 May 2004 07:15:44 -0000
@@ -164,6 +164,14 @@
 
 extern	void	MR_label_layout_stats(FILE *fp);
 
+/*
+** MR_var_name_stats(fp):
+**	Prints statistics about the space occupied by the variable names
+**	in the layout structures of the program.
+*/
+
+extern	void	MR_var_name_stats(FILE *fp);
+
 /* A Readline completer for module names. */
 extern  MR_Completer_List *MR_trace_module_completer(const char *, size_t);
 
cvs server: Diffing util
cvs server: Diffing vim
cvs server: Diffing vim/after
cvs server: Diffing vim/ftplugin
cvs server: Diffing vim/syntax
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list