[m-rev.] diff: more reductions in the size of generated .c files

Zoltan Somogyi zs at cs.mu.OZ.AU
Wed Apr 7 08:36:05 AEST 2004


This diff builds on the diff I posted last week with the same objective,
and it emits macros defined by the diff to the runtime I just committed.
I intend to commit this diff to the compiler together with the previous one
late tomorrow or on friday, unless someone says they have good reason not to
do a cvs update in the workspaces by then.

Zoltan.

Generate even more compact output. These changes reduce the sizes of the C
files generated from modules.m and make_hlds.m by about a further 15% in debug
grades. The size of parse_tree.modules.c, originally about 25 Mb, is now down
to 6.5 Mb, less than twice the size of parse_tree.modules.o (which is about
3.5 Mb). Even more dramatically, they reduce the size of parse_tree.modules.c
and hlds.make_hlds.c by around 40% in non-debug grades, though the reduction
is still larger in debug grades than in non-debug grades when expressed in
bytes instead of as a percentage.

compiler/layout_out.m:
	Declare more than one layout structure at a time when possible.

compiler/llds_out.m:
	Declare and initialize more than one label at a time when possible.
	Even when declaring or initializing only one, get the macro definition
	to supply the mercury__ prefix.

	Use shorter macros to refer to stackvars and framevars.

	When referring to tagged pointers, use macros that supply the MR_mktag
	and MR_mkbody macros in the most common cases.

	When possible, emit calls in no-profiling forms, since these are
	shorter.

diff -u SAVE/layout_out.m ./layout_out.m
--- SAVE/layout_out.m	2004-04-06 16:16:20.000000000 +1000
+++ ./layout_out.m	2004-04-06 20:52:49.000000000 +1000
@@ -32,24 +32,23 @@
 	% Given a Mercury representation of a layout structure, output its
 	% definition in the appropriate C global variable.
 :- pred output_layout_data_defn(layout_data::in, decl_set::in, decl_set::out,
-	io__state::di, io__state::uo) is det.
+	io::di, io::uo) is det.
 
 	% Given the name of a layout structure, output the declaration
 	% of the C global variable which will hold it.
-:- pred output_layout_name_decl(layout_name::in, io__state::di, io__state::uo)
-	is det.
+:- pred output_layout_name_decl(layout_name::in, io::di, io::uo) is det.
 
 	% Given the name of a layout structure, output the declaration
 	% of the C global variable which will hold it, if it has
 	% not already been declared.
 :- pred output_maybe_layout_name_decl(layout_name::in,
-	decl_set::in, decl_set::out, io__state::di, io__state::uo) is det.
+	decl_set::in, decl_set::out, io::di, io::uo) is det.
 
 	% Given a Mercury representation of a layout structure, output the
 	% declaration of the C global variable which will hold it, if it has
 	% not already been declared.
 :- pred output_maybe_layout_data_decl(layout_data::in,
-	decl_set::in, decl_set::out, io__state::di, io__state::uo) is det.
+	decl_set::in, decl_set::out, io::di, io::uo) is det.
 
 	% Given a reference to a layout structure, output the storage class
 	% (e.g. static), type and name of the global variable that will
@@ -57,12 +56,11 @@
 	% of that variable (this influences e.g. whether we output "extern"
 	% or not).
 :- pred output_layout_name_storage_type_name(layout_name::in, bool::in,
-	io__state::di, io__state::uo) is det.
+	io::di, io::uo) is det.
 
 	% Given a reference to a layout structure, output the name of the
 	% global variable that will hold it.
-:- pred output_layout_name(layout_name::in,
-	io__state::di, io__state::uo) is det.
+:- pred output_layout_name(layout_name::in, io::di, io::uo) is det.
 
 	% Given a reference to a layout structure, return a bool that is true
 	% iff the layout structure contains code addresses.
@@ -79,8 +77,7 @@
 :- func proc_label_user_or_compiler(proc_label) = proc_layout_user_or_compiler.
 
 	% Output a value of C type MR_PredFunc corrresponding to the argument.
-:- pred output_pred_or_func(pred_or_func::in,
-	io__state::di, io__state::uo) is det.
+:- pred output_pred_or_func(pred_or_func::in, io::di, io::uo) is det.
 
 %-----------------------------------------------------------------------------%
 
@@ -174,7 +171,7 @@
 	LayoutName = table_gen_info(RttiProcLabel).
 
 :- pred output_layout_decl(layout_name::in, decl_set::in, decl_set::out,
-	io__state::di, io__state::uo) is det.
+	io::di, io::uo) is det.
 
 output_layout_decl(LayoutName, !DeclSet, !IO) :-
 	( decl_set_is_member(data_addr(layout_addr(LayoutName)), !.DeclSet) ->
@@ -442,27 +439,91 @@
 
 %-----------------------------------------------------------------------------%
 
+:- type rval_or_num_or_none
+	--->	rval(rval)
+	;	num(int)
+	;	none.
+
+:- pred output_rval_or_num_or_none(rval_or_num_or_none::in,
+	io::di, io::uo) is det.
+
+output_rval_or_num_or_none(rval(Rval), !IO) :-
+	io__write_string(", ", !IO),
+	output_rval_as_addr(Rval, !IO).
+output_rval_or_num_or_none(num(Num), !IO) :-
+	io__write_string(", ", !IO),
+	io__write_int(Num, !IO).
+output_rval_or_num_or_none(none, !IO).
+
 :- pred output_label_layout_data_defn(label::in, layout_name::in,
 	maybe(trace_port)::in, maybe(bool)::in, maybe(int)::in,
 	maybe(label_var_info)::in, decl_set::in, decl_set::out,
-	io__state::di, io__state::uo) is det.
+	io::di, io::uo) is det.
 
 output_label_layout_data_defn(Label, ProcLayoutAddr, MaybePort, MaybeIsHidden,
 		MaybeGoalPath, MaybeVarInfo, !DeclSet, !IO) :-
 	output_layout_decl(ProcLayoutAddr, !DeclSet, !IO),
 	(
+		MaybeIsHidden = yes(yes),
+		HiddenChars = "T"
+	;
+		MaybeIsHidden = yes(no),
+		HiddenChars = ""
+	;
+		MaybeIsHidden = no,
+		% The value of the hidden field shouldn't matter here.
+		HiddenChars = ""
+	),
+	(
 		MaybeVarInfo = yes(VarInfo0),
-		VarInfo0 = label_var_info(_,
+		VarInfo0 = label_var_info(EncodedVarCount1,
 			LocnsTypes0, VarNums0, TypeParams0),
 		output_rval_decls(LocnsTypes0, !DeclSet, !IO),
 		output_rval_decls(VarNums0, !DeclSet, !IO),
 		output_rval_decls(TypeParams0, !DeclSet, !IO),
 		LabelVars = label_has_var_info,
-		Macro = "MR_DEF_LL"
+		(
+			LocnsTypes0 = const(data_addr_const(LTDataAddr, no)),
+			LTDataAddr = data_addr(_, common(LTCellNum, _)),
+			VarNums0 = const(data_addr_const(VNDataAddr, no)),
+			VNDataAddr = data_addr(_, common(VNCellNum, _))
+		->
+			(
+				TypeParams0 =
+					const(data_addr_const(TPDataAddr, no)),
+				TPDataAddr = data_addr(_, common(TPCellNum, _))
+			->
+				CommonChars = "CCC",
+				LocnsTypes1 = num(LTCellNum),
+				VarNums1 = num(VNCellNum),
+				TypeParams1 = num(TPCellNum)
+			;
+				TypeParams0 = const(int_const(0))
+			->
+				CommonChars = "CC0",
+				LocnsTypes1 = num(LTCellNum),
+				VarNums1 = num(VNCellNum),
+				TypeParams1 = none
+			;
+				CommonChars = "",
+				LocnsTypes1 = rval(LocnsTypes0),
+				VarNums1 = rval(VarNums0),
+				TypeParams1 = rval(TypeParams0)
+			)
+		;
+			CommonChars = "",
+			LocnsTypes1 = rval(LocnsTypes0),
+			VarNums1 = rval(VarNums0),
+			TypeParams1 = rval(TypeParams0)
+		),
+		Macro = "MR_DEF_LL" ++ HiddenChars ++ CommonChars,
+		MaybeVarInfoTuple = yes({EncodedVarCount1,
+			LocnsTypes1, VarNums1, TypeParams1})
 	;
 		MaybeVarInfo = no,
 		LabelVars = label_has_no_var_info,
-		Macro = "MR_DEF_LLNVI"
+		Macro = "MR_DEF_LLNVI" ++ HiddenChars,
+		MaybeVarInfoTuple = no
 	),
 	LayoutName = label_layout(Label, LabelVars),
 	io__write_string("\n", !IO),
@@ -482,18 +543,6 @@
 	),
 	io__write_string(", ", !IO),
 	(
-		MaybeIsHidden = yes(yes),
-		io__write_string("MR_TRUE", !IO)
-	;
-		MaybeIsHidden = yes(no),
-		io__write_string("MR_FALSE", !IO)
-	;
-		MaybeIsHidden = no,
-		% the value we write here shouldn't matter
-		io__write_string("MR_FALSE", !IO)
-	),
-	io__write_string(", ", !IO),
-	(
 		MaybeGoalPath = yes(GoalPath),
 		io__write_int(GoalPath, !IO)
 	;
@@ -501,23 +550,15 @@
 		io__write_string("0", !IO)
 	),
 	(
-		MaybeVarInfo = yes(VarInfo),
+		MaybeVarInfoTuple = yes({EncodedVarCount,
+			LocnsTypes, VarNums, TypeParams}),
 		io__write_string(", ", !IO),
-		VarInfo = label_var_info(EncodedVarCount, LocnsTypes, VarNums,
-			TypeParams),
 		io__write_int(EncodedVarCount, !IO),
-		io__write_string(", ", !IO),
-		output_rval_as_addr(LocnsTypes, !IO),
-		io__write_string(",", !IO),
-		output_rval_as_addr(VarNums, !IO),
-		( TypeParams = const(int_const(0)) ->
-			io__write_string(", 0", !IO)
-		;
-			io__write_string(",\n\t", !IO),
-			output_rval_as_addr(TypeParams, !IO)
-		)
+		output_rval_or_num_or_none(LocnsTypes, !IO),
+		output_rval_or_num_or_none(VarNums, !IO),
+		output_rval_or_num_or_none(TypeParams, !IO)
 	;
-		MaybeVarInfo = no
+		MaybeVarInfoTuple = no
 	),
 	io__write_string(");\n", !IO),
 	decl_set_insert(data_addr(layout_addr(LayoutName)), !DeclSet).
@@ -559,7 +600,7 @@
 
 :- pred output_proc_layout_data_defn(proc_label::in,
 	proc_layout_stack_traversal::in, maybe_proc_id_and_exec_trace::in,
-	decl_set::in, decl_set::out, io__state::di, io__state::uo) is det.
+	decl_set::in, decl_set::out, io::di, io::uo) is det.
 
 output_proc_layout_data_defn(ProcLabel, Traversal, MaybeRest, !DeclSet, !IO) :-
 	Kind = maybe_proc_layout_and_exec_trace_kind(MaybeRest, ProcLabel),
@@ -622,7 +663,7 @@
 
 :- pred output_proc_layout_data_defn_start(proc_label::in,
 	proc_layout_kind::in, proc_layout_stack_traversal::in,
-	io__state::di, io__state::uo) is det.
+	io::di, io::uo) is det.
 
 output_proc_layout_data_defn_start(ProcLabel, Kind, Traversal) -->
 	io__write_string("\n"),
@@ -631,13 +672,13 @@
 	io__write_string(" = {\n"),
 	output_layout_traversal_group(Traversal).
 
-:- pred output_proc_layout_data_defn_end(io__state::di, io__state::uo) is det.
+:- pred output_proc_layout_data_defn_end(io::di, io::uo) is det.
 
 output_proc_layout_data_defn_end -->
 	io__write_string("};\n").
 
 :- pred output_layout_traversal_decls(proc_layout_stack_traversal::in,
-	decl_set::in, decl_set::out, io__state::di, io__state::uo) is det.
+	decl_set::in, decl_set::out, io::di, io::uo) is det.
 
 output_layout_traversal_decls(Traversal, !DeclSet, !IO) :-
 	Traversal = proc_layout_stack_traversal(MaybeEntryLabel,
@@ -650,7 +691,7 @@
 	).
 
 :- pred output_layout_traversal_group(proc_layout_stack_traversal::in,
-	io__state::di, io__state::uo) is det.
+	io::di, io::uo) is det.
 
 output_layout_traversal_group(Traversal, !IO) :-
 	Traversal = proc_layout_stack_traversal(MaybeEntryLabel,
@@ -690,22 +731,21 @@
 detism_to_c_detism(cc_nondet) =	  "MR_DETISM_CCNON".
 detism_to_c_detism(cc_multidet) = "MR_DETISM_CCMULTI".
 
-:- pred output_layout_proc_id_group(proc_label::in,
-	io__state::di, io__state::uo) is det.
+:- pred output_layout_proc_id_group(proc_label::in, io::di, io::uo) is det.
 
 output_layout_proc_id_group(ProcLabel) -->
 	io__write_string("\t{\n"),
 	output_proc_id(ProcLabel),
 	io__write_string("\t},\n").
 
-:- pred output_layout_no_proc_id_group(io__state::di, io__state::uo) is det.
+:- pred output_layout_no_proc_id_group(io::di, io::uo) is det.
 
 output_layout_no_proc_id_group -->
 	io__write_string("\t-1\n").
 
 :- pred output_layout_exec_trace_decls(proc_label::in,
 	proc_layout_exec_trace::in, decl_set::in, decl_set::out,
-	io__state::di, io__state::uo) is det.
+	io::di, io::uo) is det.
 
 output_layout_exec_trace_decls(ProcLabel, ExecTrace, !DeclSet, !IO) :-
 	ExecTrace = proc_layout_exec_trace(CallLabelLayout, MaybeProcBody,
@@ -730,7 +770,7 @@
 	).
 
 :- pred output_layout_exec_trace_group(proc_label::in,
-	proc_layout_exec_trace::in, io__state::di, io__state::uo) is det.
+	proc_layout_exec_trace::in, io::di, io::uo) is det.
 
 output_layout_exec_trace_group(ProcLabel, ExecTrace) -->
 	{ ExecTrace = proc_layout_exec_trace(CallLabelLayout, MaybeProcBody,
@@ -792,8 +832,7 @@
 	write_maybe_slot_num(MaybeCallTableSlot),
 	io__write_string("\n\t}\n").
 
-:- pred write_maybe_slot_num(maybe(int)::in, io__state::di, io__state::uo)
-	is det.
+:- pred write_maybe_slot_num(maybe(int)::in, io::di, io::uo) is det.
 
 write_maybe_slot_num(yes(SlotNum)) -->
 	io__write_int(SlotNum).
@@ -826,7 +865,7 @@
 	).
 
 :- pred output_proc_layout_head_var_nums(proc_label::in, list(int)::in,
-	decl_set::in, decl_set::out, io__state::di, io__state::uo) is det.
+	decl_set::in, decl_set::out, io::di, io::uo) is det.
 
 output_proc_layout_head_var_nums(ProcLabel, HeadVarNums, !DeclSet) -->
 	io__write_string("\n"),
@@ -846,7 +885,7 @@
 		!DeclSet) }.
 
 :- pred output_proc_layout_var_names(proc_label::in, list(int)::in, int::in,
-	decl_set::in, decl_set::out, io__state::di, io__state::uo) is det.
+	decl_set::in, decl_set::out, io::di, io::uo) is det.
 
 output_proc_layout_var_names(ProcLabel, VarNames, MaxVarNum,
 		!DeclSet) -->
@@ -869,7 +908,7 @@
 		layout_addr(proc_layout_var_names(ProcLabel))),
 		!DeclSet) }.
 
-:- pred output_layout_no_exec_trace_group(io__state::di, io__state::uo) is det.
+:- pred output_layout_no_exec_trace_group(io::di, io::uo) is det.
 
 output_layout_no_exec_trace_group -->
 	io__write_string("\t0\n").
@@ -878,7 +917,7 @@
 
 :- pred output_closure_proc_id_data_defn(proc_label::in, int::in,
 	proc_label::in, module_name::in, string::in, int::in, string::in,
-	decl_set::in, decl_set::out, io__state::di, io__state::uo) is det.
+	decl_set::in, decl_set::out, io::di, io::uo) is det.
 
 output_closure_proc_id_data_defn(CallerProcLabel, SeqNo, ClosureProcLabel,
 		ModuleName, FileName, LineNumber, GoalPath,
@@ -902,7 +941,7 @@
 	{ decl_set_insert(data_addr(layout_addr(LayoutName)),
 		!DeclSet) }.
 
-:- pred output_proc_id(proc_label::in, io__state::di, io__state::uo) is det.
+:- pred output_proc_id(proc_label::in, io::di, io::uo) is det.
 
 output_proc_id(ProcLabel) -->
 	(
@@ -955,7 +994,7 @@
 :- pred output_module_layout_data_defn(module_name::in, int::in,
 	string_with_0s::in, list(layout_name)::in, list(file_layout_data)::in,
 	trace_level::in, int::in, decl_set::in, decl_set::out,
-	io__state::di, io__state::uo) is det.
+	io::di, io::uo) is det.
 
 output_module_layout_data_defn(ModuleName, StringTableSize, StringTable,
 		ProcLayoutNames, FileLayouts, TraceLevel, SuppressedEvents,
@@ -999,7 +1038,7 @@
 
 :- pred output_module_layout_proc_vector_defn(module_name::in,
 	list(layout_name)::in, layout_name::out, decl_set::in, decl_set::out,
-	io__state::di, io__state::uo) is det.
+	io::di, io::uo) is det.
 
 output_module_layout_proc_vector_defn(ModuleName, ProcLayoutNames,
 		VectorName, !DeclSet, !IO) :-
@@ -1013,12 +1052,24 @@
 			% place a dummy value in the array.
 		io__write_string("\tNULL\n", !IO)
 	;
-		list__foldl(output_layout_name_in_vector(
-			"(const MR_Proc_Layout *)\n\t&"), ProcLayoutNames, !IO)
+		list__foldl(output_proc_layout_name_in_vector, ProcLayoutNames,
+			!IO)
 	),
 	io__write_string("};\n", !IO),
 	decl_set_insert(data_addr(layout_addr(VectorName)), !DeclSet).
 
+:- pred output_proc_layout_name_in_vector(layout_name::in, io::di, io::uo)
+	is det.
+
+output_proc_layout_name_in_vector(LayoutName, !IO) :-
+	( LayoutName = proc_layout(Label, _) ->
+		io__write_string("MR_PROC_LAYOUT1(", !IO),
+		output_proc_label(Label, no, !IO),
+		io__write_string(")\n", !IO)
+	;
+		error("output_proc_layout_name_in_vector: not proc layout")
+	).
+
 %-----------------------------------------------------------------------------%
 
 	% The string table cannot be zero size; it must contain at least an
@@ -1026,7 +1077,7 @@
 
 :- pred output_module_string_table(module_name::in,
 	int::in, string_with_0s::in, decl_set::in, decl_set::out,
-	io__state::di, io__state::uo) is det.
+	io::di, io::uo) is det.
 
 output_module_string_table(ModuleName, StringTableSize, StringTable,
 		!DeclSet) -->
@@ -1047,7 +1098,7 @@
 % characters minimizes maximum total stack requirements.
 
 :- pred output_module_string_table_chars_driver(int::in, int::in,
-	string_with_0s::in, io__state::di, io__state::uo) is det.
+	string_with_0s::in, io::di, io::uo) is det.
 
 output_module_string_table_chars_driver(CurIndex, MaxIndex, StringWithNulls) -->
 	( { CurIndex < MaxIndex } ->
@@ -1061,7 +1112,7 @@
 	).
 
 :- pred output_module_string_table_chars(int::in, int::in, string_with_0s::in,
-	io__state::di, io__state::uo) is det.
+	io::di, io::uo) is det.
 
 output_module_string_table_chars(CurIndex, MaxIndex, StringWithNulls) -->
 	( { CurIndex mod 10 = 0 } ->
@@ -1086,7 +1137,7 @@
 
 :- pred output_file_layout_vector_data_defn(module_name::in,
 	list(layout_name)::in, layout_name::out, decl_set::in, decl_set::out,
-	io__state::di, io__state::uo) is det.
+	io::di, io::uo) is det.
 
 output_file_layout_vector_data_defn(ModuleName, FileLayoutNames, VectorName,
 		!DeclSet, !IO) :-
@@ -1108,7 +1159,7 @@
 
 :- pred output_file_layout_data_defns(module_name::in, int::in,
 	list(file_layout_data)::in, list(layout_name)::out,
-	decl_set::in, decl_set::out, io__state::di, io__state::uo) is det.
+	decl_set::in, decl_set::out, io::di, io::uo) is det.
 
 output_file_layout_data_defns(_, _, [], [], !DeclSet) --> [].
 output_file_layout_data_defns(ModuleName, FileNum, [FileLayout | FileLayouts],
@@ -1120,7 +1171,7 @@
 
 :- pred output_file_layout_data_defn(module_name::in, int::in,
 	file_layout_data::in, layout_name::out,
-	decl_set::in, decl_set::out, io__state::di, io__state::uo) is det.
+	decl_set::in, decl_set::out, io::di, io::uo) is det.
 
 output_file_layout_data_defn(ModuleName, FileNum, FileLayout, FileLayoutName,
 		!DeclSet, !IO) :-
@@ -1151,7 +1202,7 @@
 
 :- pred output_file_layout_line_number_vector_defn(module_name::in, int::in,
 	list(int)::in, layout_name::out, decl_set::in, decl_set::out,
-	io__state::di, io__state::uo) is det.
+	io::di, io::uo) is det.
 
 output_file_layout_line_number_vector_defn(ModuleName, FileNum, LineNumbers,
 		LayoutName, !DeclSet, !IO) :-
@@ -1171,7 +1222,7 @@
 
 :- pred output_file_layout_label_layout_vector_defn(module_name::in, int::in,
 	list(data_addr)::in, layout_name::out, decl_set::in, decl_set::out,
-	io__state::di, io__state::uo) is det.
+	io::di, io::uo) is det.
 
 output_file_layout_label_layout_vector_defn(ModuleName, FileNum, LabelAddrs,
 		LayoutName, !DeclSet, !IO) :-
@@ -1184,12 +1235,71 @@
 			% place a dummy value in the array.
 		io__write_string("\tNULL\n", !IO)
 	;
-		list__foldl(output_data_addr_in_vector(
-			"(const MR_Label_Layout *)\n\t&"), LabelAddrs, !IO)
+		list__map(project_label_layout, LabelAddrs, Labels),
+		output_label_layout_addrs_in_vector(Labels, !IO)
 	),
 	io__write_string("};\n", !IO),
 	decl_set_insert(data_addr(layout_addr(LayoutName)), !DeclSet).
 
+:- pred project_label_layout(data_addr::in, label::out) is det.
+
+project_label_layout(DataAddr, Label) :-
+	(
+		DataAddr = layout_addr(LayoutName),
+		LayoutName = label_layout(LabelPrime, _)
+	->
+		Label = LabelPrime
+	;
+		error("project_label_layout: not label layout")
+	).
+
+:- pred output_label_layout_addrs_in_vector(list(label)::in, io::di, io::uo)
+	is det.
+
+output_label_layout_addrs_in_vector([], !IO).
+output_label_layout_addrs_in_vector([Label | Labels], !IO) :-
+	(
+		Label = local(LabelNum, ProcLabel),
+		groupable_labels(ProcLabel, 1, N, [LabelNum], RevLabelNums,
+			Labels, RemainingLabels),
+		N > 1
+	->
+		list__reverse(RevLabelNums, LabelNums),
+		io__write_string("MR_LABEL_LAYOUT", !IO),
+		io__write_int(list__length(LabelNums), !IO),
+		io__write_string("(", !IO),
+		output_proc_label(ProcLabel, no, !IO),
+		io__write_string(",", !IO),
+		io__write_list(LabelNums, ",", io__write_int, !IO),
+		io__write_string(")\n", !IO),
+		output_label_layout_addrs_in_vector(RemainingLabels, !IO)
+	;
+		io__write_string("MR_LABEL_LAYOUT(", !IO),
+		output_label(Label, !IO),
+		io__write_string("),\n", !IO),
+		output_label_layout_addrs_in_vector(Labels, !IO)
+	).
+
+:- pred groupable_labels(proc_label::in, int::in, int::out,
+	list(int)::in, list(int)::out, list(label)::in, list(label)::out)
+	is det.
+
+groupable_labels(ProcLabel, !Count, !RevLabelsNums, !Labels) :-
+	(
+		% There must be a macro of the form MR_LABEL_LAYOUT<n>
+		% for every <n> up to MaxChunkSize.
+		!.Labels = [Label | !:Labels],
+		MaxChunkSize = 9,
+		!.Count < MaxChunkSize,	% leave room for the one we're adding
+		Label = local(LabelNum, ProcLabel)
+	->
+		!:Count = !.Count + 1,
+		!:RevLabelsNums = [LabelNum | !.RevLabelsNums],
+		groupable_labels(ProcLabel, !Count, !RevLabelsNums, !Labels)
+	;
+		true
+	).
+
 %-----------------------------------------------------------------------------%
 
 :- pred line_no_label_to_label_layout_addr(pair(int, layout_name)::in,
@@ -1198,15 +1308,14 @@
 line_no_label_to_label_layout_addr(LineNo - LabelLayout, LineNo, DataAddr) :-
 	DataAddr = layout_addr(LabelLayout).
 
-:- pred quote_and_write_string(string::in, io__state::di, io__state::uo)
-	is det.
+:- pred quote_and_write_string(string::in, io::di, io::uo) is det.
 
 quote_and_write_string(String) -->
 	io__write_string(""""),
 	c_util__output_quoted_string(String),
 	io__write_string("""").
 
-:- pred output_number_in_vector(int::in, io__state::di, io__state::uo) is det.
+:- pred output_number_in_vector(int::in, io::di, io::uo) is det.
 
 output_number_in_vector(Num) -->
 	io__write_string("\t"),
@@ -1214,7 +1323,7 @@
 	io__write_string(",\n").
 
 :- pred output_layout_name_in_vector(string::in, layout_name::in,
-	io__state::di, io__state::uo) is det.
+	io::di, io::uo) is det.
 
 output_layout_name_in_vector(Prefix, Name) -->
 	io__write_string("\t"),
@@ -1223,7 +1332,7 @@
 	io__write_string(",\n").
 
 :- pred output_data_addr_in_vector(string::in, data_addr::in,
-	io__state::di, io__state::uo) is det.
+	io::di, io::uo) is det.
 
 output_data_addr_in_vector(Prefix, DataAddr) -->
 	io__write_string("\t"),
@@ -1235,7 +1344,7 @@
 
 :- pred output_proc_static_data_defn(rtti_proc_label::in, string::in,
 	int::in, bool::in, list(call_site_static_data)::in,
-	decl_set::in, decl_set::out, io__state::di, io__state::uo) is det.
+	decl_set::in, decl_set::out, io::di, io::uo) is det.
 
 output_proc_static_data_defn(RttiProcLabel, FileName, LineNumber,
 		IsInInterface, CallSites, !DeclSet, !IO) :-
@@ -1272,7 +1381,7 @@
 
 :- pred output_call_site_static_array(rtti_proc_label::in,
 	list(call_site_static_data)::in, decl_set::in, decl_set::out,
-	io__state::di, io__state::uo) is det.
+	io::di, io::uo) is det.
 
 output_call_site_static_array(RttiProcLabel, CallSites, !DeclSet, !IO) :-
 	LayoutName = proc_static_call_sites(RttiProcLabel),
@@ -1284,7 +1393,7 @@
 	decl_set_insert(data_addr(layout_addr(LayoutName)), !DeclSet).
 
 :- pred output_call_site_static(call_site_static_data::in, int::in, int::out,
-	io__state::di, io__state::uo) is det.
+	io::di, io::uo) is det.
 
 output_call_site_static(CallSiteStatic, Index, Index + 1, !IO) :-
 	io__write_string("\t{ /* ", !IO),
@@ -1328,7 +1437,7 @@
 	io__write_string(""" },\n", !IO).
 
 :- pred output_call_site_static_decl(call_site_static_data::in,
-	decl_set::in, decl_set::out, io__state::di, io__state::uo) is det.
+	decl_set::in, decl_set::out, io::di, io::uo) is det.
 
 output_call_site_static_decl(CallSiteStatic, !DeclSet, !IO) :-
 	(
@@ -1349,7 +1458,7 @@
 
 :- pred output_table_io_decl(rtti_proc_label::in, proc_layout_kind::in,
 	int::in, rval::in, rval::in, decl_set::in, decl_set::out,
-	io__state::di, io__state::uo) is det.
+	io::di, io::uo) is det.
 
 output_table_io_decl(RttiProcLabel, ProcLayoutKind, NumPTIs,
 		PTIVectorRval, TypeParamsRval, !DeclSet, !IO) :-
@@ -1374,7 +1483,7 @@
 
 :- pred output_table_gen(rtti_proc_label::in, int::in, int::in,
 	list(table_trie_step)::in, rval::in, rval::in,
-	decl_set::in, decl_set::out, io__state::di, io__state::uo) is det.
+	decl_set::in, decl_set::out, io::di, io::uo) is det.
 
 output_table_gen(RttiProcLabel, NumInputs, NumOutputs, Steps,
 		PTIVectorRval, TypeParamsRval, !DeclSet, !IO) :-
@@ -1403,7 +1512,7 @@
 
 :- pred output_table_gen_steps_table(rtti_proc_label::in,
 	list(table_trie_step)::in, list(maybe(int))::out,
-	decl_set::in, decl_set::out, io__state::di, io__state::uo) is det.
+	decl_set::in, decl_set::out, io::di, io::uo) is det.
 
 output_table_gen_steps_table(RttiProcLabel, Steps, MaybeEnumParams,
 		!DeclSet, !IO) :-
@@ -1416,7 +1525,7 @@
 	decl_set_insert(data_addr(layout_addr(LayoutName)), !DeclSet).
 
 :- pred output_table_gen_steps(list(table_trie_step)::in,
-	list(maybe(int))::out, io__state::di, io__state::uo) is det.
+	list(maybe(int))::out, io::di, io::uo) is det.
 
 output_table_gen_steps([], [], !IO).
 output_table_gen_steps([Step | Steps], [MaybeEnumParam | MaybeEnumParams],
@@ -1457,7 +1566,7 @@
 
 :- pred output_table_gen_enum_params_table(rtti_proc_label::in,
 	list(maybe(int))::in, decl_set::in, decl_set::out,
-	io__state::di, io__state::uo) is det.
+	io::di, io::uo) is det.
 
 output_table_gen_enum_params_table(RttiProcLabel, MaybeEnumParams,
 		!DeclSet, !IO) :-
@@ -1470,7 +1579,7 @@
 	decl_set_insert(data_addr(layout_addr(LayoutName)), !DeclSet).
 
 :- pred output_table_gen_enum_params(list(maybe(int))::in,
-	io__state::di, io__state::uo) is det.
+	io::di, io::uo) is det.
 
 output_table_gen_enum_params([], !IO).
 output_table_gen_enum_params([MaybeEnumParam | MaybeEnumParams], !IO) :-
diff -u SAVE/llds_out.m ./llds_out.m
--- SAVE/llds_out.m	2004-04-06 16:16:20.000000000 +1000
+++ ./llds_out.m	2004-04-07 02:45:54.000000000 +1000
@@ -418,8 +418,7 @@
 	multi_map__to_assoc_list(CommonMap, CommonAssocList),
 	list__foldl2(output_common_decl_group, CommonAssocList, !DeclSet, !IO),
 	output_rtti_data_decl_list(RttiDatas, !DeclSet, !IO),
-	list__foldl2(output_c_label_decl(StackLayoutLabels), Labels,
-		!DeclSet, !IO),
+	output_c_label_decls(StackLayoutLabels, Labels, !DeclSet, !IO),
 	list__foldl2(output_comp_gen_c_var, Vars, !DeclSet, !IO),
 	list__reverse(CommonDatas0, CommonDatas),
 	list__foldl2(output_common_data_defn, CommonDatas, !DeclSet, !IO),
@@ -949,7 +948,7 @@
 	io__write_string(ModuleName, !IO),
 	io__write_string(")\n", !IO),
 	gather_c_module_labels(Procedures, Labels),
-	list__foldl(output_c_label_init(StackLayoutLabels), Labels, !IO),
+	output_c_label_inits(StackLayoutLabels, Labels, !IO),
 	io__write_string("MR_BEGIN_CODE\n", !IO),
 	io__write_string("\n", !IO),
 	globals__io_lookup_bool_option(auto_comments, PrintComments, !IO),
@@ -1064,6 +1063,127 @@
 			"foreign code other than C")
 	).
 
+:- pred output_c_label_decls(map(label, data_addr)::in, list(label)::in,
+	decl_set::in, decl_set::out, io__state::di, io__state::uo) is det.
+
+output_c_label_decls(StackLayoutLabels, Labels, !DeclSet, !IO) :-
+	group_c_labels_with_layouts(StackLayoutLabels, Labels,
+		multi_map__init, DeclLLMap, multi_map__init, LocalLabels,
+		[], RevAddrsToDecl, [], RevOtherLabels),
+	multi_map__to_assoc_list(DeclLLMap, DeclLLList),
+	list__foldl2(output_label_layout_decls, DeclLLList, !DeclSet, !IO),
+	multi_map__to_assoc_list(LocalLabels, LocalLabelList),
+	list__foldl2(output_local_label_decls, LocalLabelList, !DeclSet, !IO),
+	list__reverse(RevAddrsToDecl, AddrsToDecl),
+	list__foldl2(output_stack_layout_decl, AddrsToDecl, !DeclSet, !IO),
+	list__reverse(RevOtherLabels, OtherLabels),
+	list__foldl2(output_c_label_decl(StackLayoutLabels), OtherLabels,
+		!DeclSet, !IO).
+
+:- pred group_c_labels_with_layouts(map(label, data_addr)::in, list(label)::in,
+	multi_map(proc_label, int)::in, multi_map(proc_label, int)::out,
+	multi_map(proc_label, int)::in, multi_map(proc_label, int)::out,
+	list(data_addr)::in, list(data_addr)::out,
+	list(label)::in, list(label)::out) is det.
+
+group_c_labels_with_layouts(_StackLayoutLabels, [],
+		!DeclLLMap, !OtherLocalMap, !RevAddrsToDecl, !RevOthers).
+group_c_labels_with_layouts(StackLayoutLabels, [Label | Labels],
+		!DeclLLMap, !OtherLocalMap, !RevAddrsToDecl, !RevOthers) :-
+	( Label = local(LabelNum, ProcLabel) ->
+		( map__search(StackLayoutLabels, Label, DataAddr) ->
+			(
+				DataAddr = layout_addr(LayoutName),
+				LayoutName = label_layout(Label, LabelVars),
+				LabelVars = label_has_var_info
+			->
+				multi_map__set(!.DeclLLMap, ProcLabel,
+					LabelNum, !:DeclLLMap)
+			;
+				multi_map__set(!.OtherLocalMap, ProcLabel,
+					LabelNum, !:OtherLocalMap),
+				!:RevAddrsToDecl = [DataAddr
+					| !.RevAddrsToDecl]
+			)
+		;
+			multi_map__set(!.OtherLocalMap, ProcLabel, LabelNum,
+				!:OtherLocalMap)
+		)
+	;
+		!:RevOthers = [Label | !.RevOthers]
+	),
+	group_c_labels_with_layouts(StackLayoutLabels, Labels,
+		!DeclLLMap, !OtherLocalMap, !RevAddrsToDecl, !RevOthers).
+
+:- pred output_label_layout_decls(pair(proc_label, list(int))::in,
+	decl_set::in, decl_set::out, io__state::di, io__state::uo) is det.
+
+output_label_layout_decls(ProcLabel - LabelNums0, !DeclSet, !IO) :-
+	% There must be a macro of the form MR_DECL_LL<n> for every <n>
+	% up to MaxChunkSize.
+	list__reverse(LabelNums0, LabelNums),
+	MaxChunkSize = 10,
+	list__chunk(LabelNums, MaxChunkSize, LabelNumChunks),
+	list__foldl2(output_label_layout_decl_group(ProcLabel), LabelNumChunks,
+		!DeclSet, !IO).
+
+:- pred output_label_layout_decl_group(proc_label::in, list(int)::in,
+	decl_set::in, decl_set::out, io__state::di, io__state::uo) is det.
+
+output_label_layout_decl_group(ProcLabel, LabelNums, !DeclSet, !IO) :-
+	io__write_string("MR_DECL_LL", !IO),
+	io__write_int(list__length(LabelNums), !IO),
+	io__write_string("(", !IO),
+	output_proc_label(ProcLabel, no, !IO),
+	io__write_string(", ", !IO),
+	io__write_list(LabelNums, ",", io__write_int, !IO),
+	io__write_string(")\n", !IO).
+
+:- pred output_local_label_decls(pair(proc_label, list(int))::in,
+	decl_set::in, decl_set::out, io__state::di, io__state::uo) is det.
+
+output_local_label_decls(ProcLabel - LabelNums0, !DeclSet, !IO) :-
+	% There must be a macro of the form MR_decl_label<n> for every <n>
+	% up to MaxChunkSize.
+	list__reverse(LabelNums0, LabelNums),
+	MaxChunkSize = 8,
+	list__chunk(LabelNums, MaxChunkSize, LabelNumChunks),
+	list__foldl2(output_local_label_decl_group(ProcLabel), LabelNumChunks,
+		!DeclSet, !IO),
+	list__foldl(insert_var_info_label_layout_decl(ProcLabel), LabelNums,
+		!DeclSet),
+	list__foldl(insert_code_addr_decl(ProcLabel), LabelNums, !DeclSet).
+
+:- pred output_local_label_decl_group(proc_label::in, list(int)::in,
+	decl_set::in, decl_set::out, io__state::di, io__state::uo) is det.
+
+output_local_label_decl_group(ProcLabel, LabelNums, !DeclSet, !IO) :-
+	io__write_string("MR_decl_label", !IO),
+	io__write_int(list__length(LabelNums), !IO),
+	io__write_string("(", !IO),
+	output_proc_label(ProcLabel, no, !IO),
+	io__write_string(", ", !IO),
+	io__write_list(LabelNums, ",", io__write_int, !IO),
+	io__write_string(")\n", !IO),
+	list__foldl(insert_code_addr_decl(ProcLabel), LabelNums, !DeclSet).
+
+:- pred insert_var_info_label_layout_decl(proc_label::in, int::in,
+	decl_set::in, decl_set::out) is det.
+
+insert_var_info_label_layout_decl(ProcLabel, LabelNum, !DeclSet) :-
+	Label = local(LabelNum, ProcLabel),
+	LayoutName = label_layout(Label, label_has_var_info),
+	DataAddr = layout_addr(LayoutName),
+	DeclId = data_addr(DataAddr),
+	decl_set_insert(DeclId, !DeclSet).
+
+:- pred insert_code_addr_decl(proc_label::in, int::in,
+	decl_set::in, decl_set::out) is det.
+
+insert_code_addr_decl(ProcLabel, LabelNum, !DeclSet) :-
+	DeclId = code_addr(label(local(LabelNum, ProcLabel))),
+	decl_set_insert(DeclId, !DeclSet).
+
 :- pred output_c_label_decl(map(label, data_addr)::in, label::in,
 	decl_set::in, decl_set::out, io__state::di, io__state::uo) is det.
 
@@ -1108,7 +1228,7 @@
 		%
 		(
 			Label = exported(_),
-			DeclMacro = "MR_define_extern_entry("
+			DeclMacro = "MR_def_extern_entry("
 		;
 			Label = local(_),
 			% The code for procedures local to a Mercury module
@@ -1119,21 +1239,21 @@
 			globals__io_lookup_bool_option(split_c_files,
 				SplitFiles, !IO),
 			( SplitFiles = no ->
-				DeclMacro = "MR_declare_static("
+				DeclMacro = "MR_decl_static("
 			;
-				DeclMacro = "MR_define_extern_entry("
+				DeclMacro = "MR_def_extern_entry("
 			)
 		;
 			Label = c_local(_),
-			DeclMacro = "MR_declare_local("
+			DeclMacro = "MR_decl_local("
 		;
 			Label = local(_, _),
-			DeclMacro = "MR_declare_label("
+			DeclMacro = "MR_decl_label("
 		),
 		io__write_string(DeclMacro, !IO),
 		io__write_string("", !IO),
-		output_label(Label, !IO),
-		io__write_string(");\n", !IO)
+		output_label(Label, no, !IO),
+		io__write_string(")\n", !IO)
 	;
 		AlreadyDeclaredLabel = yes
 	),
@@ -1145,8 +1265,67 @@
 output_stack_layout_decl(DataAddr, !DeclSet, !IO) :-
 	output_data_addr_decls(DataAddr, !DeclSet, !IO).
 
+:- pred output_c_label_inits(map(label, data_addr)::in, list(label)::in,
+	io::di, io::uo) is det.
+
+output_c_label_inits(StackLayoutLabels, Labels, !IO) :-
+	group_c_labels(StackLayoutLabels, Labels, multi_map__init, NoLayoutMap,
+		multi_map__init, LayoutMap, [], RevOtherLabels),
+	list__reverse(RevOtherLabels, OtherLabels),
+	list__foldl(output_c_label_init(StackLayoutLabels), OtherLabels, !IO),
+	multi_map__to_assoc_list(NoLayoutMap, NoLayoutList),
+	multi_map__to_assoc_list(LayoutMap, LayoutList),
+	list__foldl(output_c_label_init_group(""), NoLayoutList, !IO),
+	list__foldl(output_c_label_init_group("_sl"), LayoutList, !IO).
+
+:- pred group_c_labels(map(label, data_addr)::in, list(label)::in,
+	multi_map(proc_label, int)::in, multi_map(proc_label, int)::out,
+	multi_map(proc_label, int)::in, multi_map(proc_label, int)::out,
+	list(label)::in, list(label)::out) is det.
+
+group_c_labels(_StackLayoutLabels, [], !NoLayoutMap, !LayoutMap, !RevOthers).
+group_c_labels(StackLayoutLabels, [Label | Labels], !NoLayoutMap, !LayoutMap,
+		!RevOthers) :-
+	( Label = local(LabelNum, ProcLabel) ->
+		( map__search(StackLayoutLabels, Label, _DataAddr) ->
+			multi_map__set(!.LayoutMap, ProcLabel, LabelNum,
+				!:LayoutMap)
+		;
+			multi_map__set(!.NoLayoutMap, ProcLabel, LabelNum,
+				!:NoLayoutMap)
+		)
+	;
+		!:RevOthers = [Label | !.RevOthers]
+	),
+	group_c_labels(StackLayoutLabels, Labels, !NoLayoutMap, !LayoutMap,
+		!RevOthers).
+
+:- pred output_c_label_init_group(string::in,
+	pair(proc_label, list(int))::in, io::di, io::uo) is det.
+
+output_c_label_init_group(Suffix, ProcLabel - LabelNums, !IO) :-
+	% There must be macros of the form MR_init_label<n> and
+	% MR_init_label_sl<n> for every <n> up to MaxChunkSize.
+	MaxChunkSize = 8,
+	list__chunk(LabelNums, MaxChunkSize, LabelNumChunks),
+	list__foldl(output_c_label_init_chunk(Suffix, ProcLabel),
+		LabelNumChunks, !IO).
+
+:- pred output_c_label_init_chunk(string::in,
+	proc_label::in, list(int)::in, io::di, io::uo) is det.
+
+output_c_label_init_chunk(Suffix, ProcLabel, LabelNums, !IO) :-
+	io__write_string("\tMR_init_label", !IO),
+	io__write_string(Suffix, !IO),
+	io__write_int(list__length(LabelNums), !IO),
+	io__write_string("(", !IO),
+	output_proc_label(ProcLabel, no, !IO),
+	io__write_string(",", !IO),
+	io__write_list(LabelNums, ",", io__write_int, !IO),
+	io__write_string(")\n", !IO).
+
 :- pred output_c_label_init(map(label, data_addr)::in, label::in,
-	io__state::di, io__state::uo) is det.
+	io::di, io::uo) is det.
 
 output_c_label_init(StackLayoutLabels, Label, !IO) :-
 	( map__search(StackLayoutLabels, Label, DataAddr) ->
@@ -1167,21 +1346,22 @@
 		InitProcLayout = no
 	),
 	(
-		Label = exported(_),
-		TabInitMacro = "\tMR_init_entry"
+		Label = exported(ProcLabel),
+		TabInitMacro = "\tMR_init_entry1"
 	;
-		Label = local(_),
-		TabInitMacro = "\tMR_init_entry"
+		Label = local(ProcLabel),
+		TabInitMacro = "\tMR_init_entry1"
 	;
-		Label = c_local(_),
-		TabInitMacro = "\tMR_init_local"
+		Label = c_local(ProcLabel),
+		TabInitMacro = "\tMR_init_local1"
 	;
 		Label = local(_, _),
-		TabInitMacro = "\tMR_init_label"
+		% These should have been separated out by group_c_labels.
+		error("output_c_label_init: local/2")
 	),
 	io__write_string(TabInitMacro, !IO),
 	io__write_string(SuffixOpen, !IO),
-	output_label(Label, !IO),
+	output_proc_label(ProcLabel, no, !IO),
 	io__write_string(");\n", !IO),
 	( InitProcLayout = yes ->
 		io__write_string("\tMR_INIT_PROC_LAYOUT_ADDR(", !IO),
@@ -1699,33 +1879,76 @@
 
 output_instruction(incr_hp(Lval, MaybeTag, MaybeOffset, Rval, TypeMsg),
 		ProfInfo, !IO) :-
+	globals__io_lookup_bool_option(profile_memory, ProfMem, !IO),
 	(
-		MaybeTag = no,
-		io__write_string("\tMR_offset_incr_hp_msg(", !IO),
-		output_lval_as_word(Lval, !IO)
-	;
-		MaybeTag = yes(Tag),
-		io__write_string("\tMR_tag_offset_incr_hp_msg(", !IO),
-		output_lval_as_word(Lval, !IO),
+		ProfMem = yes,
+		(
+			MaybeTag = no,
+			io__write_string("\tMR_offset_incr_hp_msg(", !IO),
+			output_lval_as_word(Lval, !IO)
+		;
+			MaybeTag = yes(Tag),
+			io__write_string("\tMR_tag_offset_incr_hp_msg(", !IO),
+			output_lval_as_word(Lval, !IO),
+			io__write_string(", ", !IO),
+			output_tag(Tag, !IO)
+		),
 		io__write_string(", ", !IO),
-		output_tag(Tag, !IO)
-	),
-	io__write_string(", ", !IO),
-	(
-		MaybeOffset = no,
-		io__write_string("0, ", !IO)
+		(
+			MaybeOffset = no,
+			io__write_string("0, ", !IO)
+		;
+			MaybeOffset = yes(Offset),
+			io__write_int(Offset, !IO),
+			io__write_string(", ", !IO)
+		),
+		output_rval_as_type(Rval, word, !IO),
+		io__write_string(", ", !IO),
+		ProfInfo = CallerLabel - _,
+		output_label(CallerLabel, !IO),
+		io__write_string(", """, !IO),
+		c_util__output_quoted_string(TypeMsg, !IO),
+		io__write_string(""");\n", !IO)
 	;
-		MaybeOffset = yes(Offset),
-		io__write_int(Offset, !IO),
-		io__write_string(", ", !IO)
-	),
-	output_rval_as_type(Rval, word, !IO),
-	io__write_string(", ", !IO),
-	ProfInfo = CallerLabel - _,
-	output_label(CallerLabel, !IO),
-	io__write_string(", """, !IO),
-	c_util__output_quoted_string(TypeMsg, !IO),
-	io__write_string(""");\n", !IO).
+		ProfMem = no,
+		(
+			MaybeTag = no,
+			(
+				MaybeOffset = yes(_),
+				io__write_string("\tMR_offset_incr_hp(", !IO)
+			;
+				MaybeOffset = no,
+				io__write_string("\tMR_alloc_heap(", !IO)
+			),
+			output_lval_as_word(Lval, !IO)
+		;
+			MaybeTag = yes(Tag),
+			(
+				MaybeOffset = yes(_),
+				io__write_string("\tMR_tag_offset_incr_hp(",
+					!IO),
+				output_lval_as_word(Lval, !IO),
+				io__write_string(", ", !IO),
+				output_tag(Tag, !IO)
+			;
+				MaybeOffset = no,
+				io__write_string("\tMR_tag_alloc_heap(", !IO),
+				output_lval_as_word(Lval, !IO),
+				io__write_string(", ", !IO),
+				io__write_int(Tag, !IO)
+			)
+		),
+		io__write_string(", ", !IO),
+		(
+			MaybeOffset = yes(Offset),
+			io__write_int(Offset, !IO),
+			io__write_string(", ", !IO)
+		;
+			MaybeOffset = no
+		),
+		output_rval_as_type(Rval, word, !IO),
+		io__write_string(");\n", !IO)
+	).
 
 output_instruction(mark_hp(Lval), _, !IO) :-
 	io__write_string("\tMR_mark_hp(", !IO),
@@ -1770,15 +1993,20 @@
 	output_rval_as_type(Rval, word, !IO),
 	io__write_string(");\n", !IO).
 
-output_instruction(incr_sp(N, Msg), _, !IO) :-
-	io__write_string("\tMR_incr_sp_push_msg(", !IO),
+output_instruction(incr_sp(N, _Msg), _, !IO) :-
+	io__write_string("\tMR_incr_sp(", !IO),
 	io__write_int(N, !IO),
-	io__write_string(", """, !IO),
-	c_util__output_quoted_string(Msg, !IO),
-	io__write_string(""");\n", !IO).
+	io__write_string(");\n", !IO).
+	% Use the code below instead of the code above if you want to run
+	% tools/framesize on the output of the compiler.
+	% io__write_string("\tMR_incr_sp_push_msg(", !IO),
+	% io__write_int(N, !IO),
+	% io__write_string(", """, !IO),
+	% c_util__output_quoted_string(Msg, !IO),
+	% io__write_string(""");\n", !IO).
 
 output_instruction(decr_sp(N), _, !IO) :-
-	io__write_string("\tMR_decr_sp_pop_msg(", !IO),
+	io__write_string("\tMR_decr_sp(", !IO),
 	io__write_int(N, !IO),
 	io__write_string(");\n", !IO).
 
@@ -2781,8 +3009,8 @@
 output_code_addr_decls(label(Label), !IO) :-
 	output_label_as_code_addr_decls(Label, !IO).
 output_code_addr_decls(imported(ProcLabel), !IO) :-
-	io__write_string("MR_declare_entry(", !IO),
-	output_proc_label(ProcLabel, !IO),
+	io__write_string("MR_decl_entry(", !IO),
+	output_proc_label(ProcLabel, no, !IO),
 	io__write_string(");\n", !IO).
 output_code_addr_decls(succip, !IO).
 output_code_addr_decls(do_succeed(_), !IO).
@@ -2834,8 +3062,8 @@
 	( SplitFiles = no ->
 		true
 	;
-		io__write_string("MR_declare_entry(", !IO),
-		output_label(local(ProcLabel), !IO),
+		io__write_string("MR_decl_entry(", !IO),
+		output_label(local(ProcLabel), no, !IO),
 		io__write_string(");\n", !IO)
 	).
 output_label_as_code_addr_decls(c_local(_), !IO).
@@ -2998,25 +3226,55 @@
 output_goto(label(Label), CallerLabel, !IO) :-
 	(
 		Label = exported(_),
-		io__write_string("MR_tailcall(", !IO),
-		output_label_as_code_addr(Label, !IO),
-		io__write_string(",\n\t\t", !IO),
-		output_label_as_code_addr(CallerLabel, !IO),
-		io__write_string(");\n", !IO)
+		globals__io_lookup_bool_option(profile_calls, ProfileCalls,
+			!IO),
+		(
+			ProfileCalls = yes,
+			io__write_string("MR_tailcall(", !IO),
+			output_label_as_code_addr(Label, !IO),
+			io__write_string(",\n\t\t", !IO),
+			output_label_as_code_addr(CallerLabel, !IO),
+			io__write_string(");\n", !IO)
+		;
+			ProfileCalls = no,
+			io__write_string("MR_noprof_tailcall(", !IO),
+			output_label_as_code_addr(Label, !IO),
+			io__write_string(");\n", !IO)
+		)
 	;
 		Label = local(_),
-		io__write_string("MR_tailcall(", !IO),
-		output_label_as_code_addr(Label, !IO),
-		io__write_string(",\n\t\t", !IO),
-		output_label_as_code_addr(CallerLabel, !IO),
-		io__write_string(");\n", !IO)
+		globals__io_lookup_bool_option(profile_calls, ProfileCalls,
+			!IO),
+		(
+			ProfileCalls = yes,
+			io__write_string("MR_tailcall(", !IO),
+			output_label_as_code_addr(Label, !IO),
+			io__write_string(",\n\t\t", !IO),
+			output_label_as_code_addr(CallerLabel, !IO),
+			io__write_string(");\n", !IO)
+		;
+			ProfileCalls = no,
+			io__write_string("MR_noprof_tailcall(", !IO),
+			output_label_as_code_addr(Label, !IO),
+			io__write_string(");\n", !IO)
+		)
 	;
 		Label = c_local(_),
-		io__write_string("MR_localtailcall(", !IO),
-		output_label(Label, !IO),
-		io__write_string(",\n\t\t", !IO),
-		output_label_as_code_addr(CallerLabel, !IO),
-		io__write_string(");\n", !IO)
+		globals__io_lookup_bool_option(profile_calls, ProfileCalls,
+			!IO),
+		(
+			ProfileCalls = yes,
+			io__write_string("MR_localtailcall(", !IO),
+			output_label(Label, !IO),
+			io__write_string(",\n\t\t", !IO),
+			output_label_as_code_addr(CallerLabel, !IO),
+			io__write_string(");\n", !IO)
+		;
+			ProfileCalls = no,
+			io__write_string("MR_noprof_localtailcall(", !IO),
+			output_label(Label, !IO),
+			io__write_string(");\n", !IO)
+		)
 	;
 		Label = local(_, _),
 		io__write_string("MR_GOTO_LABEL(", !IO),
@@ -3024,11 +3282,20 @@
 		io__write_string(");\n", !IO)
 	).
 output_goto(imported(ProcLabel), CallerLabel, !IO) :-
-	io__write_string("MR_tailcall(MR_ENTRY(", !IO),
-	output_proc_label(ProcLabel, !IO),
-	io__write_string("),\n\t\t", !IO),
-	output_label_as_code_addr(CallerLabel, !IO),
-	io__write_string(");\n", !IO).
+	globals__io_lookup_bool_option(profile_calls, ProfileCalls, !IO),
+	(
+		ProfileCalls = yes,
+		io__write_string("MR_tailcall(MR_ENTRY(", !IO),
+		output_proc_label(ProcLabel, !IO),
+		io__write_string("),\n\t\t", !IO),
+		output_label_as_code_addr(CallerLabel, !IO),
+		io__write_string(");\n", !IO)
+	;
+		ProfileCalls = no,
+		io__write_string("MR_noprof_tailcall(MR_ENTRY(", !IO),
+		output_proc_label(ProcLabel, !IO),
+		io__write_string("));\n", !IO)
+	).
 output_goto(succip, _, !IO) :-
 	io__write_string("MR_proceed();\n", !IO).
 output_goto(do_succeed(Last), _, !IO) :-
@@ -3114,8 +3381,15 @@
 		io__write_string(");\n\t", !IO),
 		io__write_string("MR_noprof_", !IO)
 	;
-		ProfileCall = yes,
-		io__write_string("MR_", !IO)
+		globals__io_lookup_bool_option(profile_calls, ProfileCall,
+			!IO),
+		(
+			ProfileCall = yes,
+			io__write_string("MR_", !IO)
+		;
+			ProfileCall = no,
+			io__write_string("MR_noprof_", !IO)
+		)
 	),
 	(
 		Target = label(Label),
@@ -3335,35 +3609,44 @@
 	% visible to the other C files for that Mercury module.
 	globals__io_lookup_bool_option(split_c_files, SplitFiles, !IO),
 	( SplitFiles = no ->
-		io__write_string("MR_define_static(", !IO),
-		output_label(local(ProcLabel), !IO),
-		io__write_string(");\n", !IO)
-	;
-		io__write_string("MR_define_entry(", !IO),
-		output_label(local(ProcLabel), !IO),
-		io__write_string(");\n", !IO)
+		io__write_string("MR_def_static(", !IO),
+		output_proc_label(ProcLabel, no, !IO),
+		io__write_string(")\n", !IO)
+	;
+		io__write_string("MR_def_entry(", !IO),
+		output_proc_label(ProcLabel, no, !IO),
+		io__write_string(")\n", !IO)
 	).
 output_label_defn(c_local(ProcLabel), !IO) :-
-	io__write_string("MR_define_local(", !IO),
-	output_label(c_local(ProcLabel), !IO),
-	io__write_string(");\n", !IO).
+	io__write_string("MR_def_local(", !IO),
+	output_proc_label(ProcLabel, no, !IO),
+	io__write_string(")\n", !IO).
 output_label_defn(local(Num, ProcLabel), !IO) :-
-	io__write_string("MR_define_label(", !IO),
-	output_label(local(Num, ProcLabel), !IO),
-	io__write_string(");\n", !IO).
-
-% Note that the suffixes _l and _iN used to be interpreted by mod2c,
-% which generated different code depending on the suffix.
-% We don't generate the _l suffix anymore, since it interferes
-% with referring to a label both as local(_) and c_local(_).
+	io__write_string("MR_def_label(", !IO),
+	output_proc_label(ProcLabel, no, !IO),
+	io__write_string(",", !IO),
+	io__write_int(Num, !IO),
+	io__write_string(")\n", !IO).
+
+% Entry labels, i.e. those bound to any functor other than local/2,
+% should generate the same code, regardless of whether we refer to them
+% via exported/1, local/1 or c_local/1, because we may refer to an entry label
+% via different function symbols in different circumstances.
 % For example, the entry label of a recursive unification predicate
-% is referred to as local(_) in type_info structures and as c_local(_)
-% in the recursive call.
+% is referred to as local/1 in type_info structures and as c_local/1
+% in the recursive call, since the c_local/1 is special cased in some
+% circumstances, leading to better code.
 
 output_label(Label, !IO) :-
 	LabelStr = llds_out__label_to_c_string(Label, yes),
 	io__write_string(LabelStr, !IO).
 
+:- pred output_label(label::in, bool::in, io::di, io::uo) is det.
+
+output_label(Label, AddPrefix, !IO) :-
+	LabelStr = llds_out__label_to_c_string(Label, AddPrefix),
+	io__write_string(LabelStr, !IO).
+
 llds_out__label_to_c_string(exported(ProcLabel), AddPrefix) =
 	proc_label_to_c_string(ProcLabel, AddPrefix).
 llds_out__label_to_c_string(local(ProcLabel), AddPrefix) =
@@ -3649,28 +3932,40 @@
 		io__write_int(CellNum, !IO),
 		io__write_string(")", !IO)
 	;
-		io__write_string("MR_mkword(", !IO),
-		output_tag(Tag, !IO),
+		Exprn = unop(mkbody, const(int_const(Body)))
+	->
+		io__write_string("MR_tbmkword(", !IO),
+		io__write_int(Tag, !IO),
+		io__write_string(", ", !IO),
+		io__write_int(Body, !IO),
+		io__write_string(")", !IO)
+	;
+		io__write_string("MR_tmkword(", !IO),
+		io__write_int(Tag, !IO),
 		io__write_string(", ", !IO),
 		output_rval_as_type(Exprn, data_ptr, !IO),
 		io__write_string(")", !IO)
 	).
 output_rval(lval(Lval), !IO) :-
 	% if a field is used as an rval, then we need to use
-	% the MR_const_field() macro, not the MR_field() macro,
-	% to avoid warnings about discarding const,
-	% and similarly for MR_mask_field.
-	( Lval = field(MaybeTag, Rval, FieldNum) ->
+	% the MR_const_field() macro or its variants, not the MR_field() macro
+	% or its variants, to avoid warnings about discarding const.
+	( Lval = field(MaybeTag, Rval, FieldNumRval) ->
 		( MaybeTag = yes(Tag) ->
-			io__write_string("MR_const_field(", !IO),
-			output_tag(Tag, !IO),
+			io__write_string("MR_const_tfield(", !IO),
+			io__write_int(Tag, !IO),
 			io__write_string(", ", !IO)
 		;
 			io__write_string("MR_const_mask_field(", !IO)
 		),
 		output_rval(Rval, !IO),
 		io__write_string(", ", !IO),
-		output_rval(FieldNum, !IO),
+		( FieldNumRval = const(int_const(FieldNum)) ->
+			% Avoid emitting the (MR_Integer) cast.
+			io__write_int(FieldNum, !IO)
+		;
+			output_rval(FieldNumRval, !IO)
+		),
 		io__write_string(")", !IO)
 	;
 		output_lval(Lval, !IO)
@@ -3693,8 +3988,8 @@
 	;
 		MemRef = heap_ref(Rval, Tag, FieldNum),
 		output_llds_type_cast(data_ptr, !IO),
-		io__write_string("&MR_field(", !IO),
-		output_tag(Tag, !IO),
+		io__write_string("&MR_tfield(", !IO),
+		io__write_int(Tag, !IO),
 		io__write_string(", ", !IO),
 		output_rval(Rval, !IO),
 		io__write_string(", ", !IO),
@@ -3876,7 +4171,7 @@
 	;
 		true
 	},
-	io__write_string("MR_stackvar("),
+	io__write_string("MR_sv("),
 	io__write_int(N),
 	io__write_string(")").
 output_lval(framevar(N)) -->
@@ -3885,7 +4180,7 @@
 	;
 		true
 	},
-	io__write_string("MR_framevar("),
+	io__write_string("MR_fv("),
 	io__write_int(N),
 	io__write_string(")").
 output_lval(succip) -->
@@ -3918,17 +4213,22 @@
 	io__write_string("MR_succip_slot("),
 	output_rval(Rval),
 	io__write_string(")").
-output_lval(field(MaybeTag, Rval, FieldNum)) -->
+output_lval(field(MaybeTag, Rval, FieldNumRval)) -->
 	( { MaybeTag = yes(Tag) } ->
-		io__write_string("MR_field("),
-		output_tag(Tag),
+		io__write_string("MR_tfield("),
+		io__write_int(Tag),
 		io__write_string(", ")
 	;
 		io__write_string("MR_mask_field(")
 	),
 	output_rval(Rval),
 	io__write_string(", "),
-	output_rval(FieldNum),
+	( { FieldNumRval = const(int_const(FieldNum)) } ->
+		% Avoid emitting the (MR_Integer) cast.
+		io__write_int(FieldNum)
+	;
+		output_rval(FieldNumRval)
+	),
 	io__write_string(")").
 output_lval(lvar(_)) -->
 	{ error("Illegal to output an lvar") }.
--------------------------------------------------------------------------
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