[m-rev.] for review: reduce the size of procedure representation bytecode

Ian MacLarty maclarty at cs.mu.OZ.AU
Fri Apr 8 15:04:05 AEST 2005


For review by anyone.

I haven't checked the combined saving yet, though I expect that will be the sum
of the two individual savings, since the optimizations are independent.

Estimated hours taken: 15
Branches: main

Reduce the size of the bytecode representations of procedures (generated with
the `--trace rep' option) by applying two optimizations.  

The first optimization is to store strings in the existing global string table
and just keep the offsets in the bytecode representation.  This reduces the
size of the procedure representation bytecode for mercury_compile by 15.46% and
the total size of the executable by 2.34%.

The second optimization is to use a single byte to store variable numbers
where the biggest variable number in a procedure is less than or equal to 255.
An extra byte is stored at the beginning of the procedure to indicate whether
variable numbers are stored as bytes or shorts.  This optimization reduces the
size of the procedure representation bytecode for mercury_compile by 11.34% and
the total size of the executable by 1.75%.

browser/declarative_execution.m:
	Pass the label_layout for a call to any predicates than need to
	look up strings in the bytecode.  The global string table is accessable
	via the label_layout.

	Pass the representation used for variable numbers (byte or short) to
	any predicates that need to look up variable numbers in the bytecode.

compiler/c_util.m:
	Escape (') characters in the C representation of the string table.

compiler/prog_rep.m:
	Update the global string table when converting a string to bytecode.

	Determine the maximum variable number in a procedure and use a byte
	to represent the variable numbers if this is less than 256.
	
compiler/stack_layout.m:
	Export the predicate that adds a string to the global string table.
	Export an abstract version of the stack_layout_info type that the
	above predicate operates on.

	Pass the stack_layout_info to the predicate that constructs the
	bytecodes for a procedure, so it can update the global string
	table.

mdbcomp/program_representation.m:
	Add a predicate to convert the byte indicating whether bytes or shorts
	are used to represent variable numbers to a Mercury value.

trace/mercury_trace_internal.c:
	Pass the label layout when reading a procedure from the bytecode, so
	that strings can be looked up in the global string table.

Index: browser/declarative_execution.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/declarative_execution.m,v
retrieving revision 1.40
diff -u -r1.40 declarative_execution.m
--- browser/declarative_execution.m	31 Mar 2005 04:44:18 -0000	1.40
+++ browser/declarative_execution.m	8 Apr 2005 04:47:07 -0000
@@ -650,12 +650,13 @@
 :- pragma promise_pure(call_node_maybe_proc_rep/2).
 
 call_node_maybe_proc_rep(CallNode, MaybeProcRep) :-
-	( call_node_bytecode_layout(CallNode ^ call_label, ProcLayout) ->
+	Label = CallNode ^ call_label,
+	( call_node_bytecode_layout(Label, ProcLayout) ->
 		( semipure have_cached_proc_rep(ProcLayout, ProcRep) ->
 			MaybeProcRep = yes(ProcRep)
 		;
 			lookup_proc_bytecode(ProcLayout, ByteCode),
-			read_proc_rep(ByteCode, ProcRep),
+			read_proc_rep(ByteCode, Label, ProcRep),
 			impure cache_proc_rep(ProcLayout, ProcRep),
 			MaybeProcRep = yes(ProcRep)
 		)
@@ -1613,17 +1614,18 @@
 	[can_pass_as_mercury_type, stable]).
 :- pragma foreign_type("Java", bytecode, "java.lang.Object", []). %stub only
 
-:- pred read_proc_rep(bytecode::in, proc_rep::out) is det.
-:- pragma export(read_proc_rep(in, out), "MR_DD_trace_read_rep").
+:- pred read_proc_rep(bytecode::in, label_layout::in, proc_rep::out) is det.
+:- pragma export(read_proc_rep(in, in, out), "MR_DD_trace_read_rep").
 
-read_proc_rep(Bytecode, ProcRep) :-
+read_proc_rep(Bytecode, Label, ProcRep) :-
 	some [!Pos] (
 		!:Pos = 0,
 		read_int32(Bytecode, !Pos, Limit),
-		read_string(Bytecode, !Pos, FileName),
+		read_var_num_rep(Bytecode, !Pos, VarNumRep),
+		read_string(Bytecode, Label, !Pos, FileName),
 		Info = read_proc_rep_info(Limit, FileName),
-		read_vars(Bytecode, !Pos, HeadVars),
-		read_goal(Bytecode, !Pos, Info, Goal),
+		read_vars(VarNumRep, Bytecode, !Pos, HeadVars),
+		read_goal(VarNumRep, Bytecode, Label, !Pos, Info, Goal),
 		ProcRep = proc_rep(HeadVars, Goal),
 		require(unify(!.Pos, Limit), "read_proc_rep: limit mismatch")
 	).
@@ -1634,65 +1636,72 @@
 			filename	:: string
 		).
 
-:- pred read_goal(bytecode::in, int::in, int::out, read_proc_rep_info::in,
-	goal_rep::out) is det.
+:- pred read_goal(var_num_rep::in, bytecode::in, label_layout::in, int::in, 
+	int::out, read_proc_rep_info::in, goal_rep::out) is det.
 
-read_goal(Bytecode, !Pos, Info, Goal) :-
+read_goal(VarNumRep, Bytecode, Label, !Pos, Info, Goal) :-
 	read_byte(Bytecode, !Pos, GoalTypeByte),
 	( byte_to_goal_type(GoalTypeByte) = GoalType ->
 		(
 			GoalType = goal_conj,
-			read_goals(Bytecode, !Pos, Info, Goals),
+			read_goals(VarNumRep, Bytecode, Label, !Pos, Info, 	
+				Goals),
 			Goal = conj_rep(Goals)
 		;
 			GoalType = goal_disj,
-			read_goals(Bytecode, !Pos, Info, Goals),
+			read_goals(VarNumRep, Bytecode, Label, !Pos, Info, 
+				Goals),
 			Goal = disj_rep(Goals)
 		;
 			GoalType = goal_neg,
-			read_goal(Bytecode, !Pos, Info, SubGoal),
+			read_goal(VarNumRep, Bytecode, Label, !Pos, Info, 
+				SubGoal),
 			Goal = negation_rep(SubGoal)
 		;
 			GoalType = goal_ite,
-			read_goal(Bytecode, !Pos, Info, Cond),
-			read_goal(Bytecode, !Pos, Info, Then),
-			read_goal(Bytecode, !Pos, Info, Else),
+			read_goal(VarNumRep, Bytecode, Label, !Pos, Info, 
+				Cond),
+			read_goal(VarNumRep, Bytecode, Label, !Pos, Info, 
+				Then),
+			read_goal(VarNumRep, Bytecode, Label, !Pos, Info, 
+				Else),
 			Goal = ite_rep(Cond, Then, Else)
 		;
 			GoalType = goal_switch,
-			read_goals(Bytecode, !Pos, Info, Goals),
+			read_goals(VarNumRep, Bytecode, Label, !Pos, Info, 
+				Goals),
 			Goal = switch_rep(Goals)
 		;
 			GoalType = goal_assign,
-			read_var(Bytecode, !Pos, Target),
-			read_var(Bytecode, !Pos, Source),
+			read_var(VarNumRep, Bytecode, !Pos, Target),
+			read_var(VarNumRep, Bytecode, !Pos, Source),
 			AtomicGoal = unify_assign_rep(Target, Source),
-			read_atomic_info(Bytecode, !Pos, Info, AtomicGoal,
-				Goal)
+			read_atomic_info(VarNumRep, Bytecode, Label, !Pos,
+				Info, AtomicGoal, Goal)
 		;
 			GoalType = goal_construct,
-			read_var(Bytecode, !Pos, Var),
-			read_cons_id(Bytecode, !Pos, ConsId),
-			read_vars(Bytecode, !Pos, ArgVars),
+			read_var(VarNumRep, Bytecode, !Pos, Var),
+			read_cons_id(Bytecode, Label, !Pos, ConsId),
+			read_vars(VarNumRep, Bytecode, !Pos, ArgVars),
 			AtomicGoal = unify_construct_rep(Var, ConsId, ArgVars),
-			read_atomic_info(Bytecode, !Pos, Info, AtomicGoal,
-				Goal)
+			read_atomic_info(VarNumRep, Bytecode, Label, !Pos,
+				Info, AtomicGoal, Goal)
 		;
 			GoalType = goal_deconstruct,
-			read_var(Bytecode, !Pos, Var),
-			read_cons_id(Bytecode, !Pos, ConsId),
-			read_vars(Bytecode, !Pos, ArgVars),
+			read_var(VarNumRep, Bytecode, !Pos, Var),
+			read_cons_id(Bytecode, Label, !Pos, ConsId),
+			read_vars(VarNumRep, Bytecode, !Pos, ArgVars),
 			AtomicGoal = unify_deconstruct_rep(Var, ConsId,
 				ArgVars),
-			read_atomic_info(Bytecode, !Pos, Info, AtomicGoal,
-				Goal)
+			read_atomic_info(VarNumRep, Bytecode, Label, !Pos,
+				Info, AtomicGoal, Goal)
 		;
 			GoalType = goal_simple_test,
-			read_var(Bytecode, !Pos, Var1),
-			read_var(Bytecode, !Pos, Var2),
+			read_var(VarNumRep, Bytecode, !Pos, Var1),
+			read_var(VarNumRep, Bytecode, !Pos, Var2),
 			AtomicGoal = unify_simple_test_rep(Var1, Var2),
-			read_atomic_info(Bytecode, !Pos, Info, AtomicGoal,
-				Goal)
+			read_atomic_info(VarNumRep, Bytecode, Label, !Pos,
+				Info, AtomicGoal, Goal)
 		;
 			GoalType = goal_scope,
 			read_byte(Bytecode, !Pos, MaybeCutByte),
@@ -1703,121 +1712,132 @@
 			;
 				error("read_goal: bad maybe_cut")
 			),
-			read_goal(Bytecode, !Pos, Info, SubGoal),
+			read_goal(VarNumRep, Bytecode, Label, !Pos, Info, 
+				SubGoal),
 			Goal = scope_rep(SubGoal, MaybeCut)
 		;
 			GoalType = goal_ho_call,
-			read_var(Bytecode, !Pos, Var),
-			read_vars(Bytecode, !Pos, Args),
+			read_var(VarNumRep, Bytecode, !Pos, Var),
+			read_vars(VarNumRep, Bytecode, !Pos, Args),
 			AtomicGoal = higher_order_call_rep(Var, Args),
-			read_atomic_info(Bytecode, !Pos, Info, AtomicGoal,
-				Goal)
+			read_atomic_info(VarNumRep, Bytecode, Label, !Pos,
+				Info, AtomicGoal, Goal)
 		;
 			GoalType = goal_method_call,
-			read_var(Bytecode, !Pos, Var),
+			read_var(VarNumRep, Bytecode, !Pos, Var),
 			read_method_num(Bytecode, !Pos, MethodNum),
-			read_vars(Bytecode, !Pos, Args),
+			read_vars(VarNumRep, Bytecode, !Pos, Args),
 			AtomicGoal = method_call_rep(Var, MethodNum, Args),
-			read_atomic_info(Bytecode, !Pos, Info, AtomicGoal,
-				Goal)
+			read_atomic_info(VarNumRep, Bytecode, Label, !Pos,
+				Info, AtomicGoal, Goal)
 		;
 			GoalType = goal_unsafe_cast,
-			read_var(Bytecode, !Pos, OutputVar),
-			read_var(Bytecode, !Pos, InputVar),
+			read_var(VarNumRep, Bytecode, !Pos, OutputVar),
+			read_var(VarNumRep, Bytecode, !Pos, InputVar),
 			AtomicGoal = unsafe_cast_rep(OutputVar, InputVar),
-			read_atomic_info(Bytecode, !Pos, Info, AtomicGoal,
-				Goal)
+			read_atomic_info(VarNumRep, Bytecode, Label, !Pos,
+				Info, AtomicGoal, Goal)
 		;
 			GoalType = goal_plain_call,
-			read_string(Bytecode, !Pos, ModuleName),
-			read_string(Bytecode, !Pos, PredName),
-			read_vars(Bytecode, !Pos, Args),
+			read_string(Bytecode, Label, !Pos, ModuleName),
+			read_string(Bytecode, Label, !Pos, PredName),
+			read_vars(VarNumRep, Bytecode, !Pos, Args),
 			AtomicGoal = plain_call_rep(ModuleName, PredName,
 				Args),
-			read_atomic_info(Bytecode, !Pos, Info, AtomicGoal,
-				Goal)
+			read_atomic_info(VarNumRep, Bytecode, Label, !Pos,
+				Info, AtomicGoal, Goal)
 		;
 			GoalType = goal_builtin_call,
-			read_string(Bytecode, !Pos, ModuleName),
-			read_string(Bytecode, !Pos, PredName),
-			read_vars(Bytecode, !Pos, Args),
+			read_string(Bytecode, Label, !Pos, ModuleName),
+			read_string(Bytecode, Label, !Pos, PredName),
+			read_vars(VarNumRep, Bytecode, !Pos, Args),
 			AtomicGoal = builtin_call_rep(ModuleName, PredName,
 				Args),
-			read_atomic_info(Bytecode, !Pos, Info, AtomicGoal,
-				Goal)
+			read_atomic_info(VarNumRep, Bytecode, Label, !Pos,
+				Info, AtomicGoal, Goal)
 		;
 			GoalType = goal_foreign,
-			read_vars(Bytecode, !Pos, Args),
+			read_vars(VarNumRep, Bytecode, !Pos, Args),
 			AtomicGoal = pragma_foreign_code_rep(Args),
-			read_atomic_info(Bytecode, !Pos, Info, AtomicGoal,
-				Goal)
+			read_atomic_info(VarNumRep, Bytecode, Label, !Pos,
+				Info, AtomicGoal, Goal)
 		)
 	;
 		error("read_goal: invalid goal type")
 	).
 
-:- pred read_atomic_info(bytecode::in, int::in, int::out,
-	read_proc_rep_info::in, atomic_goal_rep::in, goal_rep::out) is det.
+:- pred read_atomic_info(var_num_rep::in, bytecode::in, label_layout::in, 
+	int::in, int::out, read_proc_rep_info::in, atomic_goal_rep::in,
+	goal_rep::out) is det.
 
-read_atomic_info(Bytecode, !Pos, Info, AtomicGoal, Goal) :-
+read_atomic_info(VarNumRep, Bytecode, Label, !Pos, Info, AtomicGoal, Goal) :-
 	read_byte(Bytecode, !Pos, DetismByte),
 	( determinism_representation(DetismPrime, DetismByte) ->
 		Detism = DetismPrime
 	;
 		error("read_atomic_info: bad detism")
 	),
-	read_string(Bytecode, !Pos, FileName0),
+	read_string(Bytecode, Label, !Pos, FileName0),
 	( FileName0 = "" ->
 		FileName = Info ^ filename
 	;
 		FileName = FileName0
 	),
 	read_lineno(Bytecode, !Pos, LineNo),
-	read_vars(Bytecode, !Pos, BoundVars),
+	read_vars(VarNumRep, Bytecode, !Pos, BoundVars),
 	Goal = atomic_goal_rep(Detism, FileName, LineNo, BoundVars,
 		AtomicGoal).
 
-:- pred read_goals(bytecode::in, int::in, int::out, read_proc_rep_info::in,
-	list(goal_rep)::out) is det.
+:- pred read_goals(var_num_rep::in, bytecode::in, label_layout::in, int::in, 
+	int::out, read_proc_rep_info::in, list(goal_rep)::out) is det.
 
-read_goals(Bytecode, !Pos, Info, Goals) :-
+read_goals(VarNumRep, Bytecode, Label, !Pos, Info, Goals) :-
 	read_length(Bytecode, !Pos, Len),
-	read_goals_2(Bytecode, !Pos, Info, Len, Goals).
+	read_goals_2(VarNumRep, Bytecode, Label, !Pos, Info, Len, Goals).
 
-:- pred read_goals_2(bytecode::in, int::in, int::out,
-	read_proc_rep_info::in, int::in, list(goal_rep)::out) is det.
+:- pred read_goals_2(var_num_rep::in, bytecode::in, label_layout::in, int::in, 
+	int::out, read_proc_rep_info::in, int::in, list(goal_rep)::out) is det.
 
-read_goals_2(Bytecode, !Pos, Info, N, Goals) :-
+read_goals_2(VarNumRep, Bytecode, Label, !Pos, Info, N, Goals) :-
 	( N > 0 ->
-		read_goal(Bytecode, !Pos, Info, Head),
-		read_goals_2(Bytecode, !Pos, Info, N - 1, Tail),
+		read_goal(VarNumRep, Bytecode, Label, !Pos, Info, Head),
+		read_goals_2(VarNumRep, Bytecode, Label, !Pos, Info, N - 1, 
+			Tail),
 		Goals = [Head | Tail]
 	;
 		Goals = []
 	).
 
-:- pred read_vars(bytecode::in, int::in, int::out, list(var_rep)::out) is det.
+:- pred read_vars(var_num_rep::in, bytecode::in, int::in, int::out, 
+	list(var_rep)::out) is det.
 
-read_vars(Bytecode, !Pos, Vars) :-
+read_vars(VarNumRep, Bytecode, !Pos, Vars) :-
 	read_length(Bytecode, !Pos, Len),
-	read_vars_2(Bytecode, Len, !Pos, Vars).
+	read_vars_2(VarNumRep, Bytecode, Len, !Pos, Vars).
 
-:- pred read_vars_2(bytecode::in, int::in, int::in, int::out,
+:- pred read_vars_2(var_num_rep::in, bytecode::in, int::in, int::in, int::out,
 	list(var_rep)::out) is det.
 
-read_vars_2(Bytecode, N, !Pos, Vars) :-
+read_vars_2(VarNumRep, Bytecode, N, !Pos, Vars) :-
 	( N > 0 ->
-		read_var(Bytecode, !Pos, Head),
-		read_vars_2(Bytecode, N - 1, !Pos, Tail),
+		read_var(VarNumRep, Bytecode, !Pos, Head),
+		read_vars_2(VarNumRep, Bytecode, N - 1, !Pos, Tail),
 		Vars = [Head | Tail]
 	;
 		Vars = []
 	).
 
-:- pred read_var(bytecode::in, int::in, int::out, var_rep::out) is det.
+:- pred read_var(var_num_rep::in, bytecode::in, int::in, int::out,
+	var_rep::out) is det.
 
-read_var(Bytecode, !Pos, Var) :-
-	read_short(Bytecode, !Pos, Var).
+read_var(VarNumRep, Bytecode, !Pos, Var) :-
+	(
+		VarNumRep = byte,
+		read_byte(Bytecode, !Pos, Var)
+	;
+		VarNumRep = short,
+		read_short(Bytecode, !Pos, Var)
+	).
 
 :- pred read_length(bytecode::in, int::in, int::out, var_rep::out) is det.
 
@@ -1834,10 +1854,11 @@
 read_method_num(Bytecode, !Pos, MethodNum) :-
 	read_short(Bytecode, !Pos, MethodNum).
 
-:- pred read_cons_id(bytecode::in, int::in, int::out, cons_id_rep::out) is det.
+:- pred read_cons_id(bytecode::in, label_layout::in, int::in, int::out, 
+	cons_id_rep::out) is det.
 
-read_cons_id(Bytecode, !Pos, ConsId) :-
-	read_string(Bytecode, !Pos, ConsId).
+read_cons_id(Bytecode, Label, !Pos, ConsId) :-
+	read_string(Bytecode, Label, !Pos, ConsId).
 
 %-----------------------------------------------------------------------------%
 
@@ -1872,14 +1893,35 @@
 	Pos = Pos0 + 4;
 ").
 
-:- pred read_string(bytecode::in, int::in, int::out, string::out) is det.
+:- pred read_string(bytecode::in, label_layout::in, int::in, int::out, 
+	string::out) is det.
 
 :- pragma foreign_proc("C",
-	read_string(Bytecode::in, Pos0::in, Pos::out, Value::out),
+	read_string(Bytecode::in, Label::in, Pos0::in, Pos::out, Value::out),
 	[will_not_call_mercury, thread_safe, promise_pure],
 "
-	MR_make_aligned_string(Value, (char *) &Bytecode[Pos0]);
-	Pos = Pos0 + strlen(Value) + 1;
+	int		offset;
+	const char	*str;
+	
+	offset = (Bytecode[Pos0] << 24) + (Bytecode[Pos0+1] << 16) +
+		(Bytecode[Pos0+2] << 8) + Bytecode[Pos0+3];
+	Pos = Pos0 + 4;
+	str = Label->MR_sll_entry->MR_sle_module_layout->MR_ml_string_table 
+		+ offset;
+	MR_make_aligned_string(Value, str);
 ").
+
+:- pred read_var_num_rep(bytecode::in, int::in, int::out, var_num_rep::out) 
+	is det.
+
+read_var_num_rep(Bytecode, !Pos, VarNumRep) :-
+	read_byte(Bytecode, !Pos, Byte),
+	(
+		var_num_rep_byte(VarNumRep0, Byte)
+	->
+		VarNumRep = VarNumRep0
+	;
+		error("read_var_num_rep: unknown var_num_rep")
+	).
 
 %-----------------------------------------------------------------------------%
Index: compiler/c_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/c_util.m,v
retrieving revision 1.24
diff -u -r1.24 c_util.m
--- compiler/c_util.m	24 Mar 2005 02:00:14 -0000	1.24
+++ compiler/c_util.m	6 Apr 2005 04:07:16 -0000
@@ -274,6 +274,7 @@
 :- pred c_util__escape_special_char(char::in, char::out) is semidet.
 
 c_util__escape_special_char('"', '"').
+c_util__escape_special_char('''', '''').
 c_util__escape_special_char('\\', '\\').
 c_util__escape_special_char('\n', 'n').
 c_util__escape_special_char('\t', 't').
Index: compiler/prog_rep.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_rep.m,v
retrieving revision 1.34
diff -u -r1.34 prog_rep.m
--- compiler/prog_rep.m	31 Mar 2005 04:44:21 -0000	1.34
+++ compiler/prog_rep.m	7 Apr 2005 03:50:42 -0000
@@ -22,6 +22,7 @@
 :- import_module hlds__hlds_module.
 :- import_module hlds__hlds_pred.
 :- import_module hlds__instmap.
+:- import_module ll_backend__stack_layout.
 :- import_module parse_tree__prog_data.
 
 :- import_module list.
@@ -40,8 +41,9 @@
 
 :- type var_num_map	== map(prog_var, pair(int, string)).
 
-:- func prog_rep__represent_proc(list(prog_var), hlds_goal, instmap, vartypes,
-	var_num_map, module_info) = list(int).
+:- pred prog_rep__represent_proc(list(prog_var)::in, hlds_goal::in, 
+	instmap::in, vartypes::in, var_num_map::in, module_info::in,
+	stack_layout_info::in, stack_layout_info::out, list(int)::out) is det.
 
 :- implementation.
 
@@ -68,57 +70,88 @@
 			filename	:: string,
 			vartypes	:: vartypes,
 			var_num_map	:: var_num_map,
+			var_num_rep	:: var_num_rep,
 			module_info	:: module_info
 		).
 
 prog_rep__represent_proc(HeadVars, Goal, InstMap0, VarTypes, VarNumMap,
-		ModuleInfo) = ProcRepBytes :-
+		ModuleInfo, !StackInfo, ProcRepBytes) :-
 	Goal = _ - GoalInfo,
 	goal_info_get_context(GoalInfo, Context),
 	term__context_file(Context, FileName),
-	Info = info(FileName, VarTypes, VarNumMap, ModuleInfo),
+	MaxVarNum = map.foldl(max_var_num, VarNumMap, 0),
+	(
+		MaxVarNum =< 255
+	->
+		VarNumRep = byte
+	;
+		VarNumRep = short
+	),
+	Info = info(FileName, VarTypes, VarNumMap, VarNumRep, ModuleInfo),
+	var_num_rep_byte(VarNumRep, VarNumRepByte),
 
-	ProcRepBytes0 = string_to_byte_list(FileName) ++
+	string_to_byte_list(FileName, !StackInfo, FileNameBytes),
+ 	goal_to_byte_list(Goal, InstMap0, Info, !StackInfo, GoalBytes),
+	ProcRepBytes0 = [VarNumRepByte] ++ FileNameBytes ++
 		vars_to_byte_list(Info, HeadVars) ++
-		goal_to_byte_list(Goal, InstMap0, Info),
+		GoalBytes,
 	int32_to_byte_list(list__length(ProcRepBytes0) + 4, LimitBytes),
 	ProcRepBytes = LimitBytes ++ ProcRepBytes0.
 
 %---------------------------------------------------------------------------%
 
-:- func goal_to_byte_list(hlds_goal, instmap, prog_rep__info) = list(int).
+:- func max_var_num(prog_var, pair(int, string), int) = int.
+
+max_var_num(_, VarNum1 - _, VarNum2) = Max :-
+	(
+		VarNum1 > VarNum2
+	->
+		Max = VarNum1
+	;
+		Max = VarNum2
+	).
+
+%---------------------------------------------------------------------------%
 
-goal_to_byte_list(GoalExpr - GoalInfo, InstMap0, Info) =
-	goal_expr_to_byte_list(GoalExpr, GoalInfo, InstMap0, Info).
+:- pred goal_to_byte_list(hlds_goal::in, instmap::in, prog_rep__info::in,
+	stack_layout_info::in, stack_layout_info::out, list(int)::out) is det.
 
-:- func goal_expr_to_byte_list(hlds_goal_expr, hlds_goal_info, instmap,
-	prog_rep__info) = list(int).
+goal_to_byte_list(GoalExpr - GoalInfo, InstMap0, Info, !StackInfo, Bytes) :-
+	goal_expr_to_byte_list(GoalExpr, GoalInfo, InstMap0, Info, !StackInfo, 
+		Bytes).
+
+:- pred goal_expr_to_byte_list(hlds_goal_expr::in, hlds_goal_info::in, 
+	instmap::in, prog_rep__info::in, 
+	stack_layout_info::in, stack_layout_info::out, list(int)::out) is det.
 
-goal_expr_to_byte_list(conj(Goals), _, InstMap0, Info) = Bytes :-
+goal_expr_to_byte_list(conj(Goals), _, InstMap0, Info, !StackInfo, Bytes) :-
+	conj_to_byte_list(Goals, InstMap0, Info, !StackInfo, ConjBytes),
 	Bytes = [goal_type_to_byte(goal_conj)] ++
-		length_to_byte_list(Goals) ++
-		conj_to_byte_list(Goals, InstMap0, Info).
-goal_expr_to_byte_list(par_conj(_), _, _, _) = _ :-
+		length_to_byte_list(Goals) ++ ConjBytes.
+goal_expr_to_byte_list(par_conj(_), _, _, _, !StackInfo, _) :-
 	sorry("prog_rep", "parallel conjunctions and declarative debugging").
-goal_expr_to_byte_list(disj(Goals), _, InstMap0, Info) = Bytes :-
+goal_expr_to_byte_list(disj(Goals), _, InstMap0, Info, !StackInfo, Bytes) :-
+	disj_to_byte_list(Goals, InstMap0, Info, !StackInfo, DisjBytes),
 	Bytes = [goal_type_to_byte(goal_disj)] ++
-		length_to_byte_list(Goals) ++
-		disj_to_byte_list(Goals, InstMap0, Info).
-goal_expr_to_byte_list(not(Goal), _GoalInfo, InstMap0, Info) = Bytes :-
-	Bytes = [goal_type_to_byte(goal_neg)] ++
-		goal_to_byte_list(Goal, InstMap0, Info).
-goal_expr_to_byte_list(if_then_else(_, Cond, Then, Else), _, InstMap0, Info)
-		= Bytes :-
+		length_to_byte_list(Goals) ++ DisjBytes.
+goal_expr_to_byte_list(not(Goal), _GoalInfo, InstMap0, Info, !StackInfo, Bytes)
+		:-
+	goal_to_byte_list(Goal, InstMap0, Info, !StackInfo, GoalBytes),
+	Bytes = [goal_type_to_byte(goal_neg)] ++ GoalBytes.
+goal_expr_to_byte_list(if_then_else(_, Cond, Then, Else), _, InstMap0, Info,
+		!StackInfo, Bytes) :- 
 	Cond = _ - CondGoalInfo,
 	goal_info_get_instmap_delta(CondGoalInfo, InstMapDelta),
 	instmap__apply_instmap_delta(InstMap0, InstMapDelta, InstMap1),
+	goal_to_byte_list(Cond, InstMap0, Info, !StackInfo, CondBytes),
+	goal_to_byte_list(Then, InstMap1, Info, !StackInfo, ThenBytes),
+	goal_to_byte_list(Else, InstMap0, Info, !StackInfo, ElseBytes),
 	Bytes = [goal_type_to_byte(goal_ite)] ++
-		goal_to_byte_list(Cond, InstMap0, Info) ++
-		goal_to_byte_list(Then, InstMap1, Info) ++
-		goal_to_byte_list(Else, InstMap0, Info).
-goal_expr_to_byte_list(unify(_, _, _, Uni, _), GoalInfo, InstMap0, Info)
-		= Bytes :-
-	AtomicBytes = atomic_goal_info_to_byte_list(GoalInfo, InstMap0, Info),
+		CondBytes ++ ThenBytes ++ ElseBytes.
+goal_expr_to_byte_list(unify(_, _, _, Uni, _), GoalInfo, InstMap0, Info, 
+		!StackInfo, Bytes) :-
+	atomic_goal_info_to_byte_list(GoalInfo, InstMap0, Info, !StackInfo, 
+		AtomicBytes),
 	(
 		Uni = assign(Target, Source),
 		Bytes = [goal_type_to_byte(goal_assign)] ++
@@ -127,16 +160,18 @@
 			AtomicBytes
 	;
 		Uni = construct(Var, ConsId, Args, _, _, _, _),
+		cons_id_to_byte_list(ConsId, !StackInfo, ConsIdBytes),
 		Bytes = [goal_type_to_byte(goal_construct)] ++
 			var_to_byte_list(Info, Var) ++
-			cons_id_to_byte_list(ConsId) ++
+			ConsIdBytes ++
 			vars_to_byte_list(Info, Args) ++
 			AtomicBytes
 	;
 		Uni = deconstruct(Var, ConsId, Args, _, _, _),
+		cons_id_to_byte_list(ConsId, !StackInfo, ConsIdBytes),
 		Bytes = [goal_type_to_byte(goal_deconstruct)] ++
 			var_to_byte_list(Info, Var) ++
-			cons_id_to_byte_list(ConsId) ++
+			ConsIdBytes ++
 			vars_to_byte_list(Info, Args) ++
 			AtomicBytes
 	;
@@ -149,11 +184,13 @@
 		Uni = complicated_unify(_, _, _),
 		error("goal_expr_to_byte_list: complicated_unify")
 	).
-goal_expr_to_byte_list(switch(_, _, Cases), _, InstMap0, Info) = Bytes :-
+goal_expr_to_byte_list(switch(_, _, Cases), _, InstMap0, Info, !StackInfo, 
+		Bytes) :-
+	cases_to_byte_list(Cases, InstMap0, Info, !StackInfo, CasesBytes),
 	Bytes = [goal_type_to_byte(goal_switch)] ++
-		length_to_byte_list(Cases) ++
-		cases_to_byte_list(Cases, InstMap0, Info).
-goal_expr_to_byte_list(scope(_, Goal), GoalInfo, InstMap0, Info) = Bytes :-
+		length_to_byte_list(Cases) ++ CasesBytes.
+goal_expr_to_byte_list(scope(_, Goal), GoalInfo, InstMap0, Info, !StackInfo, 
+		Bytes) :-
 	Goal = _ - InnerGoalInfo,
 	goal_info_get_determinism(GoalInfo, OuterDetism),
 	goal_info_get_determinism(InnerGoalInfo, InnerDetism),
@@ -162,12 +199,13 @@
 	;
 		MaybeCut = 1
 	),
+	goal_to_byte_list(Goal, InstMap0, Info, !StackInfo, GoalBytes),
 	Bytes = [goal_type_to_byte(goal_scope)] ++
-		[MaybeCut] ++
-		goal_to_byte_list(Goal, InstMap0, Info).
+		[MaybeCut] ++ GoalBytes.
 goal_expr_to_byte_list(generic_call(GenericCall, Args, _, _),
-		GoalInfo, InstMap0, Info) = Bytes :-
-	AtomicBytes = atomic_goal_info_to_byte_list(GoalInfo, InstMap0, Info),
+		GoalInfo, InstMap0, Info, !StackInfo, Bytes) :-
+	atomic_goal_info_to_byte_list(GoalInfo, InstMap0, Info, !StackInfo, 
+		AtomicBytes),
 	(
 		GenericCall = higher_order(PredVar, _, _, _),
 		Bytes = [goal_type_to_byte(goal_ho_call)] ++
@@ -197,41 +235,46 @@
 			Aditi and declarative debugging")
 	).
 goal_expr_to_byte_list(call(PredId, _, Args, Builtin, _, _),
-		GoalInfo, InstMap0, Info) = Bytes :-
-	AtomicBytes = atomic_goal_info_to_byte_list(GoalInfo, InstMap0, Info),
+		GoalInfo, InstMap0, Info, !StackInfo, Bytes) :-
+	atomic_goal_info_to_byte_list(GoalInfo, InstMap0, Info, !StackInfo,
+		AtomicBytes),
 	module_info_pred_info(Info ^ module_info, PredId, PredInfo),
 	ModuleSymName = pred_info_module(PredInfo),
 	mdbcomp__prim_data__sym_name_to_string(ModuleSymName, ModuleName),
 	PredName = pred_info_name(PredInfo),
+	string_to_byte_list(ModuleName, !StackInfo, ModuleNameBytes),
+	string_to_byte_list(PredName, !StackInfo, PredNameBytes),
 	( Builtin = not_builtin ->
 		Bytes = [goal_type_to_byte(goal_plain_call)] ++
-			string_to_byte_list(ModuleName) ++
-			string_to_byte_list(PredName) ++
+			ModuleNameBytes ++
+			PredNameBytes ++ 
 			vars_to_byte_list(Info, Args) ++
 			AtomicBytes
 	;
 		Bytes = [goal_type_to_byte(goal_builtin_call)] ++
-			string_to_byte_list(ModuleName) ++
-			string_to_byte_list(PredName) ++
+			ModuleNameBytes ++
+			PredNameBytes ++
 			vars_to_byte_list(Info, Args) ++
 			AtomicBytes
 	).
 goal_expr_to_byte_list(foreign_proc(_, _PredId, _, Args, _, _),
-		GoalInfo, InstMap0, Info) = Bytes :-
+		GoalInfo, InstMap0, Info, !StackInfo, Bytes) :-
 	ArgVars = list__map(foreign_arg_var, Args),
+	atomic_goal_info_to_byte_list(GoalInfo, InstMap0, Info, !StackInfo,
+		AtomicBytes),
 	Bytes = [goal_type_to_byte(goal_foreign)] ++
-		vars_to_byte_list(Info, ArgVars) ++
-		atomic_goal_info_to_byte_list(GoalInfo, InstMap0, Info).
-goal_expr_to_byte_list(shorthand(_), _, _, _) = _ :-
+		vars_to_byte_list(Info, ArgVars) ++ AtomicBytes.
+goal_expr_to_byte_list(shorthand(_), _, _, _, !StackInfo, _) :-
 	% these should have been expanded out by now
 	error("goal_expr_to_byte_list: unexpected shorthand").
 
 %---------------------------------------------------------------------------%
 
-:- func atomic_goal_info_to_byte_list(hlds_goal_info, instmap, prog_rep__info)
-	= list(int).
+:- pred atomic_goal_info_to_byte_list(hlds_goal_info::in, instmap::in, 
+	prog_rep__info::in, stack_layout_info::in, stack_layout_info::out, 
+	list(int)::out) is det.
 
-atomic_goal_info_to_byte_list(GoalInfo, InstMap0, Info) = Bytes :-
+atomic_goal_info_to_byte_list(GoalInfo, InstMap0, Info, !StackInfo, Bytes) :-
 	goal_info_get_determinism(GoalInfo, Detism),
 	goal_info_get_context(GoalInfo, Context),
 	term__context_file(Context, FileName0),
@@ -246,15 +289,17 @@
 	instmap_changed_vars(InstMap0, InstMap, Info ^ vartypes,
 		Info ^ module_info, ChangedVars),
 	set__to_sorted_list(ChangedVars, ChangedVarList),
+	string_to_byte_list(FileName, !StackInfo, FileNameBytes),
 	Bytes = [represent_determinism(Detism)] ++
-		string_to_byte_list(FileName) ++
+		FileNameBytes ++
 		lineno_to_byte_list(LineNo) ++
 		vars_to_byte_list(Info, ChangedVarList).
 
-:- func cons_id_to_byte_list(cons_id) = list(int).
+:- pred cons_id_to_byte_list(cons_id::in, 
+	stack_layout_info::in, stack_layout_info::out, list(int)::out) is det.
 
-cons_id_to_byte_list(SymName) =
-	string_to_byte_list(cons_id_to_string(SymName)).
+cons_id_to_byte_list(SymName, !StackInfo, Bytes) :-
+	string_to_byte_list(cons_id_to_string(SymName), !StackInfo, Bytes).
 
 :- func cons_id_to_string(cons_id) = string.
 
@@ -289,35 +334,39 @@
 
 %---------------------------------------------------------------------------%
 
-:- func conj_to_byte_list(hlds_goals, instmap, prog_rep__info) = list(int).
+:- pred conj_to_byte_list(hlds_goals::in, instmap::in, prog_rep__info::in,
+	stack_layout_info::in, stack_layout_info::out, list(int)::out) is det.
 
-conj_to_byte_list([], _, _) = [].
-conj_to_byte_list([Goal | Goals], InstMap0, Info) = Bytes :-
-	GoalBytes = goal_to_byte_list(Goal, InstMap0, Info),
+conj_to_byte_list([], _, _, !StackInfo, []).
+conj_to_byte_list([Goal | Goals], InstMap0, Info, !StackInfo, Bytes) :-
+	goal_to_byte_list(Goal, InstMap0, Info, !StackInfo, GoalBytes),
 	Goal = _ - GoalInfo,
 	goal_info_get_instmap_delta(GoalInfo, InstMapDelta),
 	instmap__apply_instmap_delta(InstMap0, InstMapDelta, InstMap1),
-	GoalsBytes = conj_to_byte_list(Goals, InstMap1, Info),
+	conj_to_byte_list(Goals, InstMap1, Info, !StackInfo, GoalsBytes),
 	Bytes = GoalBytes ++ GoalsBytes.
 
 %---------------------------------------------------------------------------%
 
-:- func disj_to_byte_list(hlds_goals, instmap, prog_rep__info) = list(int).
+:- pred disj_to_byte_list(hlds_goals::in, instmap::in, prog_rep__info::in,
+	stack_layout_info::in, stack_layout_info::out, list(int)::out) is det.
 
-disj_to_byte_list([], _, _) = [].
-disj_to_byte_list([Goal | Goals], InstMap0, Info) = Bytes :-
-	GoalBytes = goal_to_byte_list(Goal, InstMap0, Info),
-	GoalsBytes = disj_to_byte_list(Goals, InstMap0, Info),
+disj_to_byte_list([], _, _, !StackInfo, []).
+disj_to_byte_list([Goal | Goals], InstMap0, Info, !StackInfo, Bytes) :-
+	goal_to_byte_list(Goal, InstMap0, Info, !StackInfo, GoalBytes),
+	disj_to_byte_list(Goals, InstMap0, Info, !StackInfo, GoalsBytes),
 	Bytes = GoalBytes ++ GoalsBytes.
 
 %---------------------------------------------------------------------------%
 
-:- func cases_to_byte_list(list(case), instmap, prog_rep__info) = list(int).
+:- pred cases_to_byte_list(list(case)::in, instmap::in, prog_rep__info::in,
+	stack_layout_info::in, stack_layout_info::out, list(int)::out) is det.
 
-cases_to_byte_list([], _, _) = [].
-cases_to_byte_list([case(_ConsId, Goal) | Cases], InstMap0, Info) = Bytes :-
-	GoalBytes = goal_to_byte_list(Goal, InstMap0, Info),
-	GoalsBytes = cases_to_byte_list(Cases, InstMap0, Info),
+cases_to_byte_list([], _, _, !StackInfo, []).
+cases_to_byte_list([case(_ConsId, Goal) | Cases], InstMap0, Info, !StackInfo,
+		Bytes) :-
+	goal_to_byte_list(Goal, InstMap0, Info, !StackInfo, GoalBytes),
+	cases_to_byte_list(Cases, InstMap0, Info, !StackInfo, GoalsBytes),
 	% XXX
 	% Bytes = cons_id_and_arity_to_byte_list(ConsId)
 	%	++ GoalBytes ++ GoalsBytes.
@@ -336,10 +385,12 @@
 % but we here use them to represent unsigned quantities. This effectively
 % halves their range.
 
-:- func string_to_byte_list(string) = list(int).
+:- pred string_to_byte_list(string::in, 
+	stack_layout_info::in, stack_layout_info::out, list(int)::out) is det.
 
-string_to_byte_list(String) = Bytes :-
-	string_to_byte_list(String, Bytes).
+string_to_byte_list(String, !StackInfo, Bytes) :-
+	stack_layout__lookup_string_in_table(String, Index, !StackInfo),
+	int32_to_byte_list(Index, Bytes).
 
 :- func vars_to_byte_list(prog_rep__info, list(prog_var)) = list(int).
 
@@ -351,7 +402,13 @@
 
 var_to_byte_list(Info, Var) = Bytes :-
 	map__lookup(Info ^ var_num_map, Var, VarNum - _),
-	short_to_byte_list(VarNum, Bytes).
+	(
+		Info ^ var_num_rep = byte,
+		Bytes = [VarNum]
+	;
+		Info ^ var_num_rep = short,
+		short_to_byte_list(VarNum, Bytes)
+	).
 
 :- func length_to_byte_list(list(T)) = list(int).
 
Index: compiler/stack_layout.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/stack_layout.m,v
retrieving revision 1.101
diff -u -r1.101 stack_layout.m
--- compiler/stack_layout.m	1 Apr 2005 02:09:35 -0000	1.101
+++ compiler/stack_layout.m	6 Apr 2005 04:07:16 -0000
@@ -57,6 +57,11 @@
 :- pred stack_layout__represent_determinism_rval(determinism::in,
 	rval::out) is det.
 
+:- type stack_layout_info.
+
+:- pred stack_layout__lookup_string_in_table(string::in, int::out,
+	stack_layout_info::in, stack_layout_info::out) is det.
+
 :- implementation.
 
 :- import_module backend_libs__rtti.
@@ -575,8 +580,9 @@
 		ProcBytes = []
 	;
 		NeedGoalRep = yes,
-		ProcBytes = prog_rep__represent_proc(HeadVars,
-			Goal, InstMap, VarTypes, VarNumMap, ModuleInfo)
+		prog_rep__represent_proc(HeadVars,
+			Goal, InstMap, VarTypes, VarNumMap, ModuleInfo, 
+			!Info, ProcBytes)
 	),
 	(
 		MaybeCallLabel = yes(CallLabelPrime),
@@ -1758,9 +1764,6 @@
 					% in reverse order.
 		int			% Next available offset
 	).
-
-:- pred stack_layout__lookup_string_in_table(string::in, int::out,
-	stack_layout_info::in, stack_layout_info::out) is det.
 
 stack_layout__lookup_string_in_table(String, Offset, !Info) :-
 	StringTable0 = !.Info ^ string_table,
Index: mdbcomp/program_representation.m
===================================================================
RCS file: /home/mercury1/repository/mercury/mdbcomp/program_representation.m,v
retrieving revision 1.4
diff -u -r1.4 program_representation.m
--- mdbcomp/program_representation.m	31 Mar 2005 04:44:27 -0000	1.4
+++ mdbcomp/program_representation.m	6 Apr 2005 04:07:07 -0000
@@ -271,6 +271,17 @@
 
 :- func byte_to_goal_type(int) = bytecode_goal_type is semidet.
 
+	% A variable number is represented in a byte if there are no more than
+	% 255 variables in the procedure.  Otherwise a short is used.
+	%
+:- type var_num_rep
+	--->	byte
+	;	short.
+
+:- pred var_num_rep_byte(var_num_rep, int).
+:- mode var_num_rep_byte(in, out) is det.
+:- mode var_num_rep_byte(out, in) is semidet.
+
 %-----------------------------------------------------------------------------%
 
 :- implementation.
@@ -447,5 +458,10 @@
 goal_type_byte(14, goal_method_call).
 goal_type_byte(15, goal_plain_call).
 goal_type_byte(16, goal_builtin_call).
+
+%-----------------------------------------------------------------------------%
+
+var_num_rep_byte(byte, 0).
+var_num_rep_byte(short, 1).
 
 %-----------------------------------------------------------------------------%
Index: trace/mercury_trace_internal.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_internal.c,v
retrieving revision 1.199
diff -u -r1.199 mercury_trace_internal.c
--- trace/mercury_trace_internal.c	6 Apr 2005 01:11:32 -0000	1.199
+++ trace/mercury_trace_internal.c	6 Apr 2005 04:07:16 -0000
@@ -1401,7 +1401,8 @@
     }
 
     MR_TRACE_CALL_MERCURY(
-        MR_DD_trace_read_rep(entry->MR_sle_body_bytes, &rep);
+        MR_DD_trace_read_rep(entry->MR_sle_body_bytes, 
+            event_info->MR_event_sll, &rep);
     );
 
     (*browser)(ML_proc_rep_type(), rep, caller, format);
@@ -2468,7 +2469,8 @@
                 problem = "current procedure has no body bytecodes";
             } else {
                 MR_TRACE_CALL_MERCURY(
-                    MR_DD_trace_read_rep(entry->MR_sle_body_bytes, &rep);
+                    MR_DD_trace_read_rep(entry->MR_sle_body_bytes, 
+                        event_info->MR_event_sll, &rep);
                 );
 
                 browser_term = MR_type_value_to_browser_term(
--------------------------------------------------------------------------
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