for review: big step towards a usable debugger, round 3 (part 2 of 3)

Zoltan Somogyi zs at cs.mu.OZ.AU
Wed Apr 8 18:49:22 AEST 1998


ws4 has the code from the previous proposal,
es2 has the code from the current proposal.

--- ws4/compiler/code_gen.m	Tue Apr  7 16:37:37 1998
+++ ws2/compiler/code_gen.m	Wed Apr  8 11:28:16 1998
@@ -256,48 +256,47 @@
 %---------------------------------------------------------------------------%
 
 	% Generate_category_code generates code for an entire procedure.
-	% Its algorithm has three main stages:
+	% Its algorithm has three or four main stages:
 	%
 	%	- generate code for the body goal
-	%	- generate code for the prologue
-	%	- generate code for the epilogue
+	%	- generate code for the procedure entry
+	%	- generate code for the procedure exit
+	%	- generate code for the procedure fail (if needed)
+	%
+	% The first three tasks are forwarded to other procedures.
+	% The fourth task, if needed, is done by generate_category_code.
 	%
 	% The only caller of generate_category_code, generate_proc_code,
 	% has set up the code generator state to reflect what the machine
 	% state will be on entry to the procedure. Ensuring that the
-	% machine state at exit/fail will conform to the expectation
-	% of the caller is the job of the epilogue.
+	% machine state at exit will conform to the expectation
+	% of the caller is the job of code_gen__generate_exit.
 	%
-	% The reason why we generate the prologue after the body is that
+	% The reason why we generate the entry code after the body is that
 	% information such as the total number of stack slots needed,
-	% which is needed when creating the prologue, cannot be conveniently
-	% obtained before generating the body, since the code generator
-	% may allocate temporary variables to hold values such as saved
-	% heap and trail pointers.
+	% which is needed in the procedure entry prologue, cannot be
+	% conveniently obtained before generating the body, since the
+	% code generator may allocate temporary variables to hold values
+	% such as saved heap and trail pointers.
 	%
-	% Code_gen__generate_prologue cannot depend on the code generator
+	% Code_gen__generate_entry cannot depend on the code generator
 	% state, since when it is invoked this state is not appropriate
-	% for the prologue. Nor can it change the code generator state,
-	% since that would confuse code_gen__generate_epilogue.
+	% for the procedure entry. Nor can it change the code generator state,
+	% since that would confuse code_gen__generate_exit.
 	%
 	% Generating CALL trace events is done by generate_category_code,
 	% since only on entry to generate_category_code is the code generator
 	% state set up right. Generating EXIT trace events is done by
-	% code_gen__generate_exit, since the epilogue takes care of the
-	% successes of all procedures of all three code models.
-	% Generating FAIL trace events is done by generate_category_code,
-	% since this requires modifying how we generate code for the body
-	% of the procedure (failures must now branch to a different place).
-	% Since FAIL trace events are part of the failure continuation,
-	% generate_category_code takes care of the failure continuation
-	% as well. (Det procedures of course have no failure continuation.
-	% Nondet procedures have a failure continuation, but in the absence
-	% of tracing this continuation needs no code. Only semidet procedures
-	% need code for the failure continuation at all times.)
-	% code_gen__generate_epilogue.
-	%
-	% Procedures defined by nondet pragma C codes are a special case.
-	% Pragma_c_gen__generate_pragma_c_code handles XXX
+	% code_gen__generate_exit. Generating FAIL trace events is done
+	% by generate_category_code, since this requires modifying how
+	% we generate code for the body of the procedure (failures must
+	% now branch to a different place). Since FAIL trace events are
+	% part of the failure continuation, generate_category_code takes
+	% care of the failure continuation as well. (Model_det procedures
+	% of course have no failure continuation. Model_non procedures have
+	% a failure continuation, but in the absence of tracing this
+	% continuation needs no code. Only model_semi procedures need code
+	% for the failure continuation at all times.)
 
 :- pred generate_category_code(code_model, hlds_goal, proc_info, code_tree,
 	maybe(label), frame_info, code_info, code_info).
@@ -322,11 +321,12 @@
 
 		code_info__get_maybe_trace_info(MaybeTraceInfo),
 		( { MaybeTraceInfo = yes(TraceInfo) } ->
-			{ trace__fail_vars(ProcInfo, ResumeVars) },
+			code_info__get_module_info(ModuleInfo),
+			{ trace__fail_vars(ModuleInfo, ProcInfo, ResumeVars) },
 				% Protect these vars from being forgotten,
 				% so they will be around for the exit trace.
 			code_info__push_resume_point_vars(ResumeVars),
-			trace__generate_event_code(call, TraceInfo,
+			trace__generate_external_event_code(call, TraceInfo,
 				TraceCallLabel, _TypeInfos, TraceCallCode),
 			{ MaybeTraceCallLabel = yes(TraceCallLabel) }
 		;
@@ -357,11 +357,12 @@
 		goto(succip) - "Return from procedure call"
 	]) },
 	( { MaybeTraceInfo = yes(TraceInfo) } ->
-		{ trace__fail_vars(ProcInfo, ResumeVars) },
+		code_info__get_module_info(ModuleInfo),
+		{ trace__fail_vars(ModuleInfo, ProcInfo, ResumeVars) },
 		code_info__make_known_failure_cont(ResumeVars, orig_and_stack,
 			no, SetupCode),
 		code_info__push_resume_point_vars(ResumeVars),
-		trace__generate_event_code(call, TraceInfo,
+		trace__generate_external_event_code(call, TraceInfo,
 			TraceCallLabel, _TypeInfos, TraceCallCode),
 		{ MaybeTraceCallLabel = yes(TraceCallLabel) },
 		code_gen__generate_goal(model_semi, Goal, BodyCode),
@@ -372,7 +373,8 @@
 		code_info__pop_resume_point_vars,
 		code_info__restore_failure_cont(ResumeCode),
 		code_info__set_forward_live_vars(ResumeVars),
-		trace__generate_event_code(fail, TraceInfo, TraceFailCode),
+		trace__generate_external_event_code(fail, TraceInfo, _, _,
+			TraceFailCode),
 		{ Code =
 			tree(EntryCode,
 			tree(SetupCode,
@@ -409,11 +411,12 @@
 		% we must arrange the tracing of failure out of this proc
 	code_info__get_maybe_trace_info(MaybeTraceInfo),
 	( { MaybeTraceInfo = yes(TraceInfo) } ->
-		{ trace__fail_vars(ProcInfo, ResumeVars) },
+		code_info__get_module_info(ModuleInfo),
+		{ trace__fail_vars(ModuleInfo, ProcInfo, ResumeVars) },
 		code_info__make_known_failure_cont(ResumeVars, orig_and_stack,
 			yes, SetupCode),
 		code_info__push_resume_point_vars(ResumeVars),
-		trace__generate_event_code(call, TraceInfo,
+		trace__generate_external_event_code(call, TraceInfo,
 			TraceCallLabel, _TypeInfos, TraceCallCode),
 		{ MaybeTraceCallLabel = yes(TraceCallLabel) },
 		code_gen__generate_goal(model_non, Goal, BodyCode),
@@ -424,7 +427,8 @@
 		code_info__pop_resume_point_vars,
 		code_info__restore_failure_cont(RestoreCode),
 		code_info__set_forward_live_vars(ResumeVars),
-		trace__generate_event_code(fail, TraceInfo, TraceFailCode),
+		trace__generate_external_event_code(fail, TraceInfo, _, _,
+			TraceFailCode),
 		code_info__generate_failure(FailCode),
 		{ Code =
 			tree(PrologCode,
@@ -462,7 +466,8 @@
 	%	code to fill in some special slots in the stack frame
 	%	a comment to mark prologue end
 	%
-	% At the moment the only special slot is the succip slot.
+	% At the moment the only special slots are the succip slot, and
+	% the slots holding the call number and call depth for tracing.
 	%
 	% Not all frames will have all these components. For example, the code
 	% to allocate a stack frame will be missing if the procedure doesn't
@@ -583,7 +588,7 @@
 
 	% Generate the success epilogue for a procedure.
 	%
-	% The epilogue will contain
+	% The success epilogue will contain
 	%
 	%	a comment to mark epilogue start
 	%	code to place the output arguments where their caller expects
@@ -593,13 +598,9 @@
 	%	a jump back to the caller, including livevals information
 	%	a comment to mark epilogue end
 	%
-	% The failure continuation will contain
-	%
-	%	code that sets up the failure resumption point
-	%	code to restore registers from some special slots
-	%	code to deallocate the stack frame
-	%	code to set r1 to FALSE
-	%	a jump back to the caller, including livevals information
+	% The parts of this that restore registers and deallocate the stack
+	% frame are also part of the failure epilog, which is handled by
+	% our caller; this is why return RestoreDeallocCode.
 	%
 	% At the moment the only special slots are the succip slot, and
 	% the slots holding the call number and call depth for tracing.
@@ -608,7 +609,7 @@
 	% nondet procedures we don't deallocate the stack frame before
 	% success.
 	%
-	% Epilogs for procedures defined by nondet pragma C codes do not
+	% Epilogues for procedures defined by nondet pragma C codes do not
 	% follow the rules above. For such procedures, the normal functions
 	% of the epilogue are handled when traversing the pragma C code goal;
 	% we need only #undef a macro defined by the procedure prologue.
@@ -634,7 +635,7 @@
 				will_not_call_mercury, no)
 				- ""
 		]) },
-		{ RestoreDeallocCode = empty }, % XXX
+		{ RestoreDeallocCode = empty },	% always empty for nondet code
 		{ EpilogCode =
 			tree(StartComment,
 			tree(UndefCode,
@@ -676,7 +677,7 @@
 
 		code_info__get_maybe_trace_info(MaybeTraceInfo),
 		( { MaybeTraceInfo = yes(TraceInfo) } ->
-			trace__generate_event_code(exit, TraceInfo,
+			trace__generate_external_event_code(exit, TraceInfo,
 				_, TypeInfoDatas, TraceExitCode),
 			{ assoc_list__values(TypeInfoDatas, TypeInfoLvals) }
 		;
@@ -1201,8 +1202,8 @@
 	(
 		Instrn0 = livevals(LiveVals0),
 		Instrns0 \= [goto(succip) - _ | _]
-		% XXX we should also test for tailcalls
-		% once we start generating them directly
+		% XXX We should also test for tailcalls
+		% if we ever start generating them directly.
 	->
 		set__insert(LiveVals0, stackvar(StackLoc), LiveVals1),
 		Instrn = livevals(LiveVals1)
--- ws4/compiler/continuation_info.m	Tue Apr  7 16:37:38 1998
+++ ws2/compiler/continuation_info.m	Wed Apr  1 14:12:12 1998
@@ -26,15 +26,16 @@
 %
 % 	- After we finish generating code for a procedure, we record
 %	  all the static information about the procedure (some of which
-%	  is available only after code generation), and the info about
-%	  internal labels accumulated in the code generator state,
+%	  is available only after code generation), together with the
+%	  info about internal labels accumulated in the code generator state,
 %	  in the continuation_info structure (which is part of HLDS).
 %
 % 	- If agc_stack_layouts is set, we make a pass over the
 % 	  optimized code recorded in the final LLDS instructions.
 %	  In this pass, we collect information from call instructions
 %	  about the internal labels to which calls can return.
-%	  This info will also go straight into the HLDS.
+%	  This info will also go straight into the continuation_info
+%	  in the HLDS.
 %
 % stack_layout.m converts the information collected in this module into
 % stack_layout tables.
@@ -63,10 +64,14 @@
 :- type proc_layout_info
 	--->	proc_layout_info(
 			proc_label,	% the proc label
-			determinism,	% which stack is used
+			determinism,	% determines which stack is used
 			int,		% number of stack slots
 			maybe(int),	% location of succip on stack
-			maybe(label),	% name of the label of the call event
+			maybe(label),	% if generate_trace is set,
+					% this contains the label associated
+					% with the call event, whose stack
+					% layout says which variables were
+					% live and where on entry
 			proc_label_layout_info
 					% info for each internal label,
 					% needed for basic_stack_layouts
@@ -212,21 +220,7 @@
 
 		% Process the continuation label info.
 	list__foldl(continuation_info__process_continuation, Calls,
-		Internals0, Internals1),
-
-		% Add empty entries for the labels that do not have real info,
-		% since if continuation_info__process_instructions is invoked
-		% then MR_USE_STACK_LAYOUTS will be defined, and this demands
-		% a stack layout data structure for every label, even if it
-		% is not used. When this aspect of the runtime is fixed,
-		% we will be able to remove this step.
-	GetAllInternalLabels = lambda([Instr::in, Label::out] is semidet, (
-		Instr = label(Label) - _Comment,
-		Label = local(_, _)
-	)),
-	list__filter_map(GetAllInternalLabels, Instructions, Labels),
-	list__foldl(continuation_info__ensure_label_is_present, Labels,
-		Internals1, Internals),
+		Internals0, Internals),
 
 	ProcLayoutInfo = proc_layout_info(A, B, C, D, E, Internals),
 	map__det_update(ContInfo0, PredProcId, ProcLayoutInfo, ContInfo).
diff -u ws4/compiler/dense_switch.m ws2/compiler/dense_switch.m
--- ws4/compiler/dense_switch.m	Tue Apr  7 16:37:39 1998
+++ ws2/compiler/dense_switch.m	Sat Mar 28 15:03:46 1998
@@ -236,18 +236,9 @@
 	->
 		{ Comment = "case of dense switch" },
 		% We need to save the expression cache, etc.,
-		% and restore them when we've finished
+		% and restore them when we've finished.
 		code_info__grab_code_info(CodeInfoAtStart),
-		code_info__get_maybe_trace_info(MaybeTraceInfo),
-		( { MaybeTraceInfo = yes(TraceInfo) } ->
-			{ Goal = _ - GoalInfo },
-			{ goal_info_get_goal_path(GoalInfo, Path) },
-			{ goal_info_get_pre_deaths(GoalInfo, PreDeaths) },
-			trace__generate_event_code(switch(Path, PreDeaths),
-				TraceInfo, TraceCode)
-		;
-			{ TraceCode = empty }
-		),
+		trace__maybe_generate_internal_event_code(Goal, TraceCode),
 		code_gen__generate_goal(CodeModel, Goal, GoalCode),
 		code_info__generate_branch_end(CodeModel, StoreMap, SaveCode),
 		{ Code =
diff -u ws4/compiler/disj_gen.m ws2/compiler/disj_gen.m
--- ws4/compiler/disj_gen.m	Tue Apr  7 16:37:39 1998
+++ ws2/compiler/disj_gen.m	Sat Mar 28 15:02:25 1998
@@ -75,7 +75,7 @@
 		% disjunct that might allocate some heap space.
 	{ MaybeHpSlot = no },
 
-		% Generate all the disjuncts
+		% Generate all the disjuncts.
 	code_info__get_next_label(EndLabel),
 	disj_gen__generate_pruned_disjuncts(Goals, StoreMap, EndLabel,
 		ReclaimHeap, MaybeHpSlot, MaybeTicketSlot, no, GoalsCode),
@@ -125,7 +125,7 @@
 		code_info__make_known_failure_cont(ResumeVars, ResumeLocs, no,
 			ModContCode),
 			% The next line is to enable Goal to pass the
-			% pre_goal_update sanity check
+			% pre_goal_update sanity check.
 		{ goal_info_set_resume_point(GoalInfo0, no_resume_point,
 			GoalInfo) },
 		{ Goal = GoalExpr0 - GoalInfo },
@@ -133,11 +133,11 @@
 		( { First = no } ->
 				% Reset the heap pointer to recover memory
 				% allocated by the previous disjunct(s),
-				% if necessary
+				% if necessary.
 			code_info__maybe_restore_hp(MaybeHpSlot0,
 				RestoreHPCode),
 
-				% Reset the solver state if necessary
+				% Reset the solver state if necessary.
 			code_info__maybe_reset_ticket(MaybeTicketSlot, undo,
 				RestoreTicketCode)
 		;
@@ -146,7 +146,7 @@
 		),
 
 			% Save hp if it needs to be saved and hasn't been
-			% saved previously
+			% saved previously.
 		(
 			{ ReclaimHeap = yes },
 			{ code_util__goal_may_allocate_heap(Goal) },
@@ -161,21 +161,13 @@
 
 		code_info__grab_code_info(CodeInfo),
 
-			% generate the disjunct as a semi-deterministic goal
+			% Generate the disjunct as a semi-deterministic goal.
 		{ CodeModel = model_semi ->
 			true
 		;
 			error("pruned disj non-last goal is not semidet")
 		},
-		code_info__get_maybe_trace_info(MaybeTraceInfo),
-		( { MaybeTraceInfo = yes(TraceInfo) } ->
-			{ goal_info_get_goal_path(GoalInfo, Path) },
-			{ goal_info_get_pre_deaths(GoalInfo, PreDeaths) },
-			trace__generate_event_code(disj(Path, PreDeaths),
-				TraceInfo, TraceCode)
-		;
-			{ TraceCode = empty }
-		),
+		trace__maybe_generate_internal_event_code(Goal, TraceCode),
 		code_gen__generate_goal(CodeModel, Goal, GoalCode),
 		code_info__generate_branch_end(CodeModel, StoreMap, SaveCode),
 
@@ -204,26 +196,18 @@
 			      RestCode)))))))))
 		}
 	;
-		% Emit code for the last disjunct
+		% Emit code for the last disjunct.
 
-			% Restore the heap pointer if necessary
+			% Restore the heap pointer if necessary.
 		code_info__maybe_restore_and_discard_hp(MaybeHpSlot0,
 			RestoreHPCode),
 
-			% Restore the solver state if necessary
+			% Restore the solver state if necessary.
 		code_info__maybe_reset_and_discard_ticket(MaybeTicketSlot, 
 			undo, RestorePopTicketCode),
 
-			% Generate the goal
-		code_info__get_maybe_trace_info(MaybeTraceInfo),
-		( { MaybeTraceInfo = yes(TraceInfo) } ->
-			{ goal_info_get_goal_path(GoalInfo0, Path0) },
-			{ goal_info_get_pre_deaths(GoalInfo0, PreDeaths0) },
-			trace__generate_event_code(disj(Path0, PreDeaths0),
-				TraceInfo, TraceCode)
-		;
-			{ TraceCode = empty }
-		),
+			% Generate the goal.
+		trace__maybe_generate_internal_event_code(Goal0, TraceCode),
 		code_gen__generate_goal(CodeModel, Goal0, GoalCode),
 		code_info__generate_branch_end(CodeModel, StoreMap, SaveCode),
 
@@ -309,7 +293,7 @@
 		code_info__make_known_failure_cont(ResumeVars, ResumeLocs, yes,
 			ModContCode),
 			% The next line is to enable Goal to pass the
-			% pre_goal_update sanity check
+			% pre_goal_update sanity check.
 		{ goal_info_set_resume_point(GoalInfo0, no_resume_point,
 			GoalInfo) },
 		{ Goal = GoalExpr0 - GoalInfo },
@@ -317,11 +301,11 @@
 		( { First = no } ->
 				% Reset the heap pointer to recover memory
 				% allocated by the previous disjunct(s),
-				% if necessary
+				% if necessary.
 			code_info__maybe_restore_hp(MaybeHpSlot,
 				RestoreHPCode),
 
-				% Reset the solver state if necessary
+				% Reset the solver state if necessary.
 			code_info__maybe_reset_ticket(MaybeTicketSlot, undo,
 				RestoreTicketCode)
 		;
@@ -331,21 +315,12 @@
 
 		code_info__grab_code_info(CodeInfo),
 
-		code_info__get_maybe_trace_info(MaybeTraceInfo),
-		( { MaybeTraceInfo = yes(TraceInfo) } ->
-			{ goal_info_get_goal_path(GoalInfo, Path) },
-			{ goal_info_get_pre_deaths(GoalInfo, PreDeaths) },
-			trace__generate_event_code(disj(Path, PreDeaths),
-				TraceInfo, TraceCode)
-		;
-			{ TraceCode = empty }
-		),
-
+		trace__maybe_generate_internal_event_code(Goal, TraceCode),
 		code_gen__generate_goal(model_non, Goal, GoalCode),
 		code_info__generate_branch_end(model_non, StoreMap, SaveCode),
 
-			% make sure every variable in the resume set is in its
-			% stack slot
+			% Make sure every variable in the resume set is in its
+			% stack slot.
 		code_info__flush_resume_vars_to_stack(FlushResumeVarsCode),
 
 		{ BranchCode = node([
@@ -356,9 +331,9 @@
 		code_info__slap_code_info(CodeInfo),
 		code_info__pop_resume_point_vars,
 
-			% make sure that the redoip of the top nondet frame
+			% Make sure that the redoip of the top nondet frame
 			% points to the right label, and set up the start of
-			% the next disjunct
+			% the next disjunct.
 		code_info__restore_failure_cont(RestoreContCode),
 
 		disj_gen__generate_non_disjuncts(Goals, StoreMap, EndLabel,
@@ -376,7 +351,7 @@
 			      RestCode)))))))))
 		}
 	;
-		% Emit code for the last disjunct
+		% Emit code for the last disjunct.
 
 		{ Goals = [] ->
 			true
@@ -384,24 +359,15 @@
 			error("disj_gen__generate_non_disjuncts: last disjunct followed by others")
 		},
 
-			% Restore the heap pointer if necessary
+			% Restore the heap pointer if necessary.
 		code_info__maybe_restore_and_discard_hp(MaybeHpSlot,
 			RestoreHPCode),
 
-			% Restore the solver state if necessary
+			% Restore the solver state if necessary.
 		code_info__maybe_reset_and_discard_ticket(MaybeTicketSlot,
 			undo, RestorePopTicketCode),
 
-		code_info__get_maybe_trace_info(MaybeTraceInfo),
-		( { MaybeTraceInfo = yes(TraceInfo) } ->
-			{ goal_info_get_goal_path(GoalInfo0, Path0) },
-			{ goal_info_get_pre_deaths(GoalInfo0, PreDeaths0) },
-			trace__generate_event_code(disj(Path0, PreDeaths0),
-				TraceInfo, TraceCode)
-		;
-			{ TraceCode = empty }
-		),
-
+		trace__maybe_generate_internal_event_code(Goal0, TraceCode),
 		code_gen__generate_goal(model_non, Goal0, GoalCode),
 		code_info__generate_branch_end(model_non, StoreMap, SaveCode),
 
diff -u ws4/compiler/handle_options.m ws2/compiler/handle_options.m
--- ws4/compiler/handle_options.m	Tue Apr  7 16:37:39 1998
+++ ws2/compiler/handle_options.m	Tue Mar 31 16:50:37 1998
@@ -262,8 +262,8 @@
 	% --generate-trace requires 
 	% 	- disabling optimizations that would change 
 	% 	  the trace being generated
-	%	- enabling excess_assign to exclude junk vars from the trace
-	%	  (and to ensure consistent paths across optimization levels)
+	%	- enabling some low level optimizations to ensure consistent
+	%	  paths across optimization levels)
 	% 	- enabling stack layouts
 	% 	- enabling typeinfo liveness
 	globals__io_lookup_bool_option(generate_trace, Trace),
@@ -286,13 +286,20 @@
 			% removes a source of variability in the goal paths
 			% reported by tracing.
 		globals__io_set_option(excess_assign, bool(yes)),
+			% The explicit setting of the following option
+			% removes a source of variability in the goal paths
+			% reported by tracing.
+		globals__io_set_option(follow_code, bool(yes)),
 			% The following option selects a special-case
 			% code generator that cannot (yet) implement tracing.
 		globals__io_set_option(middle_rec, bool(no)),
 			% Tracing inserts C code into the generated LLDS.
 			% Value numbering cannot optimize such LLDS code.
-			% We turn value numbering off now so that we don't
-			% have to discover this fact anew for each procedure.
+			% (If it tried, it would get it wrong due to the
+			% absence of liveness annotations on the introduced
+			% labels.) We turn value numbering off now so that
+			% we don't have to discover this fact anew
+			% for each procedure.
 		globals__io_set_option(optimize_value_number, bool(no)),
 			% The following options cause the info required
 			% by tracing to be generated.
--- ws4/compiler/live_vars.m	Tue Apr  7 16:37:50 1998
+++ ws2/compiler/live_vars.m	Tue Mar 31 20:06:05 1998
@@ -51,7 +51,7 @@
 	module_info_globals(ModuleInfo, Globals),
 	globals__lookup_bool_option(Globals, generate_trace, Trace),
 	( Trace = yes ->
-		trace__fail_vars(ProcInfo0, ResumeVars0),
+		trace__fail_vars(ModuleInfo, ProcInfo0, ResumeVars0),
 		set__insert(LiveSets0, ResumeVars0, LiveSets1)
 	;
 		set__init(ResumeVars0),
--- ws4/compiler/liveness.m	Tue Apr  7 16:37:51 1998
+++ ws2/compiler/liveness.m	Tue Mar 31 20:06:13 1998
@@ -167,7 +167,7 @@
 	module_info_globals(ModuleInfo, Globals),
 	globals__lookup_bool_option(Globals, generate_trace, Trace),
 	( Trace = yes ->
-		trace__fail_vars(ProcInfo0, ResumeVars0)
+		trace__fail_vars(ModuleInfo, ProcInfo0, ResumeVars0)
 	;
 		set__init(ResumeVars0)
 	),
diff -u ws4/compiler/llds_out.m ws2/compiler/llds_out.m
--- ws4/compiler/llds_out.m	Sat Mar 28 16:00:50 1998
+++ ws2/compiler/llds_out.m	Tue Mar 31 11:33:58 1998
@@ -18,13 +18,13 @@
 :- interface.
 
 :- import_module llds, prog_data, hlds_data.
-:- import_module bool, io.
+:- import_module set_bbbtree, bool, io.
 
 	% Given a 'c_file' structure, open the appropriate .c file
 	% and output the code into that file.
 
-:- pred output_c_file(c_file, io__state, io__state).
-:- mode output_c_file(in, di, uo) is det.
+:- pred output_c_file(c_file, set_bbbtree(label), io__state, io__state).
+:- mode output_c_file(in, in, di, uo) is det.
 
 	% Convert an lval to a string description of that lval.
 
@@ -135,16 +135,17 @@
 		;	data_addr(data_addr)
 		;	pragma_c_struct(string).
 
-output_c_file(C_File) -->
+output_c_file(C_File, StackLayoutLabels) -->
 	globals__io_lookup_bool_option(split_c_files, SplitFiles),
 	( { SplitFiles = yes } ->
 		{ C_File = c_file(ModuleName, C_HeaderInfo, C_Modules) },
 		module_name_to_file_name(ModuleName, ".dir", yes, ObjDirName),
 		make_directory(ObjDirName),
 		output_c_file_init(ModuleName, C_Modules),
-		output_c_file_list(C_Modules, 1, ModuleName, C_HeaderInfo)
+		output_c_file_list(C_Modules, 1, ModuleName, C_HeaderInfo,
+			StackLayoutLabels)
 	;
-		output_single_c_file(C_File, no)
+		output_single_c_file(C_File, no, StackLayoutLabels)
 	).
 
 :- pred make_directory(string, io__state, io__state).
@@ -156,15 +157,17 @@
 	io__call_system(Command, _Result).
 
 :- pred output_c_file_list(list(c_module), int, module_name,
-			list(c_header_code), io__state, io__state).
-:- mode output_c_file_list(in, in, in, in, di, uo) is det.
+	list(c_header_code), set_bbbtree(label), io__state, io__state).
+:- mode output_c_file_list(in, in, in, in, in, di, uo) is det.
 
-output_c_file_list([], _, _, _) --> [].
-output_c_file_list([Module|Modules], Num, ModuleName, C_HeaderLines) -->
+output_c_file_list([], _, _, _, _) --> [].
+output_c_file_list([Module|Modules], Num, ModuleName, C_HeaderLines,
+		StackLayoutLabels) -->
 	output_single_c_file(c_file(ModuleName, C_HeaderLines, [Module]),
-		yes(Num)),
+		yes(Num), StackLayoutLabels),
 	{ Num1 is Num + 1 },
-	output_c_file_list(Modules, Num1, ModuleName, C_HeaderLines).
+	output_c_file_list(Modules, Num1, ModuleName, C_HeaderLines,
+		StackLayoutLabels).
 
 :- pred output_c_file_init(module_name, list(c_module), io__state, io__state).
 :- mode output_c_file_init(in, in, di, uo) is det.
@@ -205,11 +208,12 @@
 		io__set_exit_status(1)
 	).
 
-:- pred output_single_c_file(c_file, maybe(int), io__state, io__state).
-:- mode output_single_c_file(in, in, di, uo) is det.
+:- pred output_single_c_file(c_file, maybe(int), set_bbbtree(label),
+	io__state, io__state).
+:- mode output_single_c_file(in, in, in, di, uo) is det.
 
-output_single_c_file(c_file(ModuleName, C_HeaderLines, Modules), SplitFiles) 
-		-->
+output_single_c_file(c_file(ModuleName, C_HeaderLines, Modules), SplitFiles,
+		StackLayoutLabels) -->
 	( { SplitFiles = yes(Num) } ->
 		module_name_to_split_c_file_name(ModuleName, Num, ".c",
 			FileName)
@@ -245,7 +249,7 @@
 		{ gather_c_file_labels(Modules, Labels) },
 		{ set__init(DeclSet0) },
 		output_c_label_decl_list(Labels, DeclSet0, DeclSet),
-		output_c_module_list(Modules, DeclSet),
+		output_c_module_list(Modules, StackLayoutLabels, DeclSet),
 		( { SplitFiles = yes(_) } ->
 			[]
 		;
@@ -424,18 +428,21 @@
 	io__write_string("_bunch_"),
 	io__write_int(Number).
 
-:- pred output_c_module_list(list(c_module), decl_set, io__state, io__state).
-:- mode output_c_module_list(in, in, di, uo) is det.
+:- pred output_c_module_list(list(c_module), set_bbbtree(label), decl_set,
+	io__state, io__state).
+:- mode output_c_module_list(in, in, in, di, uo) is det.
 
-output_c_module_list([], _) --> [].
-output_c_module_list([M | Ms], DeclSet0) -->
-	output_c_module(M, DeclSet0, DeclSet),
-	output_c_module_list(Ms, DeclSet).
+output_c_module_list([], _, _) --> [].
+output_c_module_list([M | Ms], StackLayoutLabels, DeclSet0) -->
+	output_c_module(M, StackLayoutLabels, DeclSet0, DeclSet),
+	output_c_module_list(Ms, StackLayoutLabels, DeclSet).
 
-:- pred output_c_module(c_module, decl_set, decl_set, io__state, io__state).
-:- mode output_c_module(in, in, out, di, uo) is det.
+:- pred output_c_module(c_module, set_bbbtree(label), decl_set, decl_set,
+	io__state, io__state).
+:- mode output_c_module(in, in, in, out, di, uo) is det.
 
-output_c_module(c_module(ModuleName, Procedures), DeclSet0, DeclSet) -->
+output_c_module(c_module(ModuleName, Procedures), StackLayoutLabels,
+		DeclSet0, DeclSet) -->
 	io__write_string("\n"),
 	output_c_procedure_list_decls(Procedures, DeclSet0, DeclSet),
 	io__write_string("\n"),
@@ -443,7 +450,7 @@
 	io__write_string(ModuleName),
 	io__write_string(")\n"),
 	{ gather_c_module_labels(Procedures, Labels) },
-	output_c_label_init_list(Labels),
+	output_c_label_init_list(Labels, StackLayoutLabels),
 	io__write_string("BEGIN_CODE\n"),
 	io__write_string("\n"),
 	globals__io_lookup_bool_option(auto_comments, PrintComments),
@@ -452,7 +459,7 @@
 	io__write_string("END_MODULE\n").
 
 output_c_module(c_data(ModuleName, VarName, ExportedFromModule, ArgVals,
-		_Refs), DeclSet0, DeclSet) -->
+		_Refs), _, DeclSet0, DeclSet) -->
 	io__write_string("\n"),
 	{ DataAddr = data_addr(data_addr(ModuleName, VarName)) },
 	output_cons_arg_decls(ArgVals, "", "", 0, _, DeclSet0, DeclSet1),
@@ -471,7 +478,7 @@
 		0, _),
 	{ set__insert(DeclSet1, DataAddr, DeclSet) }.
 
-output_c_module(c_code(C_Code, Context), DeclSet, DeclSet) -->
+output_c_module(c_code(C_Code, Context), _, DeclSet, DeclSet) -->
 	globals__io_lookup_bool_option(auto_comments, PrintComments),
 	( { PrintComments = yes } ->
 		io__write_string("/* "),
@@ -485,7 +492,7 @@
 	io__write_string("\n"),
 	output_reset_line_num.
 
-output_c_module(c_export(PragmaExports), DeclSet, DeclSet) -->
+output_c_module(c_export(PragmaExports), _, DeclSet, DeclSet) -->
 	output_exported_c_functions(PragmaExports).
 
 	% output_c_header_include_lines reverses the list of c header lines
@@ -522,6 +529,7 @@
 
 :- pred output_exported_c_functions(list(string), io__state, io__state).
 :- mode output_exported_c_functions(in, di, uo) is det.
+
 output_exported_c_functions([]) --> [].
 output_exported_c_functions([F | Fs]) -->
 	io__write_string(F),
@@ -568,36 +576,53 @@
 	output_label(Label),
 	io__write_string(");\n").
 
-:- pred output_c_label_init_list(list(label), io__state, io__state).
-:- mode output_c_label_init_list(in, di, uo) is det.
+:- pred output_c_label_init_list(list(label), set_bbbtree(label),
+	io__state, io__state).
+:- mode output_c_label_init_list(in, in, di, uo) is det.
 
-output_c_label_init_list([]) --> [].
-output_c_label_init_list([Label | Labels]) -->
-	output_c_label_init(Label),
-	output_c_label_init_list(Labels).
+output_c_label_init_list([], _) --> [].
+output_c_label_init_list([Label | Labels], StackLayoutLabels) -->
+	output_c_label_init(Label, StackLayoutLabels),
+	output_c_label_init_list(Labels, StackLayoutLabels).
 
-:- pred output_c_label_init(label, io__state, io__state).
-:- mode output_c_label_init(in, di, uo) is det.
+:- pred output_c_label_init(label, set_bbbtree(label), io__state, io__state).
+:- mode output_c_label_init(in, in, di, uo) is det.
 
-output_c_label_init(Label) -->
+output_c_label_init(Label, StackLayoutLabels) -->
 	(
 		{ Label = exported(_) },
-		io__write_string("\tinit_entry("),
+		( { set_bbbtree__member(Label, StackLayoutLabels) } ->
+			io__write_string("\tinit_entry_sl(")
+		;
+			io__write_string("\tinit_entry(")
+		),
 		output_label(Label),
 		io__write_string(");\n")
 	;
 		{ Label = local(_) },
-		io__write_string("\tinit_entry("),
+		( { set_bbbtree__member(Label, StackLayoutLabels) } ->
+			io__write_string("\tinit_entry_sl(")
+		;
+			io__write_string("\tinit_entry(")
+		),
 		output_label(Label),
 		io__write_string(");\n")
 	;
 		{ Label = c_local(_) },
-		io__write_string("\tinit_local("),
+		( { set_bbbtree__member(Label, StackLayoutLabels) } ->
+			io__write_string("\tinit_local_sl(")
+		;
+			io__write_string("\tinit_local(")
+		),
 		output_label(Label),
 		io__write_string(");\n")
 	;
 		{ Label = local(_, _) },
-		io__write_string("\tinit_label("),
+		( { set_bbbtree__member(Label, StackLayoutLabels) } ->
+			io__write_string("\tinit_label_sl(")
+		;
+			io__write_string("\tinit_label(")
+		),
 		output_label(Label),
 		io__write_string(");\n")
 	).
diff -u ws4/compiler/mercury_compile.m ws2/compiler/mercury_compile.m
--- ws4/compiler/mercury_compile.m	Tue Apr  7 16:37:51 1998
+++ ws2/compiler/mercury_compile.m	Thu Apr  2 13:09:45 1998
@@ -26,7 +26,7 @@
 
 	% library modules
 :- import_module int, list, map, set, std_util, dir, require, string, bool.
-:- import_module library, getopt, term, varset.
+:- import_module library, getopt, term, set_bbbtree, varset.
 
 	% the main compiler passes (in order of execution)
 :- import_module handle_options, prog_io, prog_out, modules, module_qual.
@@ -1664,10 +1664,12 @@
 	{ base_type_info__generate_llds(HLDS0, BaseTypeInfos) },
 	{ base_type_layout__generate_llds(HLDS0, HLDS1, BaseTypeLayouts) },
 	{ BasicStackLayout = yes ->
-		stack_layout__generate_llds(HLDS1, HLDS, StackLayouts),
+		stack_layout__generate_llds(HLDS1, HLDS,
+			StackLayouts, StackLayoutLabelMap),
 		list__append(StackLayouts, BaseTypeLayouts, StaticData0)
 	;
 		HLDS = HLDS1,
+		set_bbbtree__init(StackLayoutLabelMap),
 		StaticData0 = BaseTypeLayouts
 	},
 
@@ -1677,7 +1679,8 @@
 	{ list__append(BaseTypeInfos, StaticData, AllData) },
 	mercury_compile__chunk_llds(HLDS, LLDS1, AllData, CommonData,
 		LLDS2, NumChunks),
-	mercury_compile__output_llds(ModuleName, LLDS2, Verbose, Stats),
+	mercury_compile__output_llds(ModuleName, LLDS2, StackLayoutLabelMap,
+		Verbose, Stats),
 
 	export__produce_header_file(HLDS, ModuleName),
 
@@ -1791,18 +1794,19 @@
 	Num1 is Num + 1,
 	mercury_compile__combine_chunks_2(Chunks, ModName, Num1, Modules).
 
-:- pred mercury_compile__output_llds(module_name, c_file, bool, bool,
-	io__state, io__state).
-:- mode mercury_compile__output_llds(in, in, in, in, di, uo) is det.
+:- pred mercury_compile__output_llds(module_name, c_file, set_bbbtree(label),
+	bool, bool, io__state, io__state).
+:- mode mercury_compile__output_llds(in, in, in, in, in, di, uo) is det.
 
-mercury_compile__output_llds(ModuleName, LLDS, Verbose, Stats) -->
+mercury_compile__output_llds(ModuleName, LLDS, StackLayoutLabels,
+		Verbose, Stats) -->
 	maybe_write_string(Verbose,
 		"% Writing output to `"),
 	module_name_to_file_name(ModuleName, ".c", yes, FileName),
 	maybe_write_string(Verbose, FileName),
 	maybe_write_string(Verbose, "'..."),
 	maybe_flush_output(Verbose),
-	output_c_file(LLDS),
+	output_c_file(LLDS, StackLayoutLabels),
 	maybe_write_string(Verbose, " done.\n"),
 	maybe_flush_output(Verbose),
 	maybe_report_stats(Stats).
diff -u ws4/compiler/pragma_c_gen.m ws2/compiler/pragma_c_gen.m
--- ws4/compiler/pragma_c_gen.m	Tue Apr  7 16:38:01 1998
+++ ws2/compiler/pragma_c_gen.m	Sat Mar 28 15:23:48 1998
@@ -532,17 +532,10 @@
 	code_info__maybe_save_ticket(UseTrail, SaveTicketCode, MaybeTicketSlot),
 	code_info__maybe_reset_ticket(MaybeTicketSlot, undo, RestoreTicketCode),
 
-	code_info__get_maybe_trace_info(MaybeTraceInfo),
-	( { MaybeTraceInfo = yes(TraceInfo) } ->
-		{ set__init(Empty) },
-		trace__generate_event_code(disj([disj(1)], Empty), TraceInfo,
-			FirstTraceCode),
-		trace__generate_event_code(disj([disj(2)], Empty), TraceInfo,
-			LaterTraceCode)
-	;
-		{ FirstTraceCode = empty },
-		{ LaterTraceCode = empty }
-	),
+	trace__maybe_generate_pragma_event_code(nondet_pragma_first,
+		FirstTraceCode),
+	trace__maybe_generate_pragma_event_code(nondet_pragma_later,
+		LaterTraceCode),
 
 	{ FirstDisjunctCode =
 		tree(SaveHeapCode,
diff -u ws4/compiler/stack_layout.m ws2/compiler/stack_layout.m
--- ws4/compiler/stack_layout.m	Tue Apr  7 16:38:01 1998
+++ ws2/compiler/stack_layout.m	Wed Apr  1 13:53:06 1998
@@ -87,20 +87,27 @@
 % 	live data names	 	(Word *) - pointer to vector of String
 %	type parameters		(Word *) - pointer to vector of MR_Live_Lval
 %
+% The internal label number field is just for the convenience of those
+% implementors who are debugging stack layout dependent code. It holds
+% either the label number, or -1 indicating the entry label.
+%
 % The live data pair vector will have an entry for each live variable.
 % The entry will give the location of the variable and its type. (It also
 % has room for its instantiation state, but this is not filled in yet.)
 %
-% The live data name vector pointer may be NULL. If it is not, the vector
-% will have an entry for each live variable, with each entry being either
-% NULL or giving the name of the variable.
+% The live data name vector pointer will be NULL. If it is not, the vector
+% will have an entry for each live variable, with each entry giving the name
+% of the variable (it is either a pointer to a string, or a NULL pointer,
+% which means that the variable has no name).
 %
 % The number of type parameters is never stored as it is not needed --
 % the type parameter vector will simply be indexed by the type variable's
 % variable number stored within pseudo-typeinfos inside the elements
 % of the live data pairs vectors. Since we allocate type variable numbers
 % sequentially, the type parameter vector will usually be dense. However,
-% in some cases, XXX
+% after all variables whose types include e.g. type variable 2 have gone
+% out of scope, variables whose types include type variable 3 may still
+% be around.
 %
 % We need detailed information about the variables that are live at an
 % internal label in two kinds of circumstances. Stack layout information
@@ -133,17 +140,17 @@
 :- interface.
 
 :- import_module hlds_module, llds.
-:- import_module list.
+:- import_module list, set_bbbtree.
 
-:- pred stack_layout__generate_llds(module_info, module_info, list(c_module)).
-:- mode stack_layout__generate_llds(in, out, out) is det.
+:- pred stack_layout__generate_llds(module_info::in, module_info::out,
+	list(c_module)::out, set_bbbtree(label)::out) is det.
 
 :- implementation.
 
 :- import_module globals, options, continuation_info, llds_out.
 :- import_module hlds_data, hlds_pred, base_type_layout, prog_data, prog_out.
-:- import_module assoc_list, bool, string, int, map, std_util, require.
-:- import_module term, set.
+:- import_module assoc_list, bool, string, int, require.
+:- import_module map, std_util, term, set.
 
 :- type stack_layout_info 	--->	
 	stack_layout_info(
@@ -152,7 +159,9 @@
 		bool,		% generate agc layout info?
 		bool,		% generate tracing layout info?
 		bool,		% generate procedure id layout info?
-		list(c_module)	% generated data
+		list(c_module),	% generated data
+		set_bbbtree(label)
+				% the set of labels with stack layouts
 	).
 
 %---------------------------------------------------------------------------%
@@ -160,7 +169,8 @@
 	% Process all the continuation information stored in the HLDS,
 	% converting it into LLDS data structures.
 
-stack_layout__generate_llds(ModuleInfo0, ModuleInfo, CModules) :-
+stack_layout__generate_llds(ModuleInfo0, ModuleInfo, CModules,
+		StackLayoutLabels) :-
 	module_info_get_continuation_info(ModuleInfo0, ContinuationInfo),
 	continuation_info__get_all_proc_layouts(ContinuationInfo,
 		ProcLayoutList),
@@ -172,13 +182,15 @@
 	globals__lookup_bool_option(Globals, trace_stack_layout, TraceLayout),
 	globals__lookup_bool_option(Globals, procid_stack_layout,
 		ProcInfoLayout),
+	set_bbbtree__init(StackLayoutLabels0),
 
 	LayoutInfo0 = stack_layout_info(ModuleName, CellCount, AgcLayout,
-		TraceLayout, ProcInfoLayout, []),
+		TraceLayout, ProcInfoLayout, [], StackLayoutLabels0),
 	list__foldl(stack_layout__construct_layouts, ProcLayoutList,
 		LayoutInfo0, LayoutInfo),
 
 	stack_layout__get_cmodules(CModules, LayoutInfo, _),
+	stack_layout__get_label_set(StackLayoutLabels, LayoutInfo, _),
 	stack_layout__get_cell_number(FinalCellCount, LayoutInfo, _),
 	module_info_set_cell_count(ModuleInfo0, FinalCellCount, ModuleInfo).
 
@@ -216,9 +228,31 @@
 		Location = Location0
 	;
 			% Use a dummy location of -1 if there is
-			% no succip on the stack. The runtime system
-			% might be able to work around this, depending
-			% upon what it is using the stack layouts for.
+			% no succip on the stack.
+			%
+			% This case can arise in two circumstances.
+			% First, procedures that use the nondet stack
+			% have a special slot for the succip, so the
+			% succip is not stored in a general purpose
+			% slot. Second, procedures that use the det stack
+			% but which do not call other procedures
+			% do not save the succip on the stack.
+			%
+			% The tracing system does not care about the
+			% location of the saved succip. The accurate
+			% garbage collector does. It should know from
+			% the determinism that the procedure uses the
+			% nondet stack, which takes care of the first
+			% possibility above. Procedures that do not call
+			% other procedures do not establish resumption
+			% points and thus agc is not interested in them.
+			% As far as stack dumps go, calling error counts
+			% as a call, so any procedure that may call error
+			% (directly or indirectly) will have its saved succip
+			% location recorded, so the stack dump will work.
+			%
+			% Future uses of stack layouts will have to have
+			% similar constraints.
 		Location = -1
 	},
 	{ determinism_components(Detism, _, at_most_many) ->
@@ -264,7 +298,7 @@
 
 	{ CModule = c_data(ModuleName, stack_layout(Label), yes,
 		MaybeRvals, []) },
-	stack_layout__add_cmodule(CModule).
+	stack_layout__add_cmodule(CModule, Label).
 
 %---------------------------------------------------------------------------%
 
@@ -331,7 +365,7 @@
 	{ LayoutRvals = [yes(EntryAddrRval), yes(LabelNumRval) | AgcRvals] },
 	{ CModule = c_data(ModuleName, stack_layout(Label), yes,
 		LayoutRvals, []) },
-	stack_layout__add_cmodule(CModule).
+	stack_layout__add_cmodule(CModule, Label).
 
 	% Construct the rvals required for accurate GC or for tracing.
 
@@ -620,60 +654,68 @@
 	stack_layout_info::in, stack_layout_info::out) is det.
 
 stack_layout__get_module_name(ModuleName, LayoutInfo, LayoutInfo) :-
-	LayoutInfo = stack_layout_info(ModuleName, _, _, _, _, _).
+	LayoutInfo = stack_layout_info(ModuleName, _, _, _, _, _, _).
 
 :- pred stack_layout__get_next_cell_number(int::out,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
 stack_layout__get_next_cell_number(CNum0, LayoutInfo0, LayoutInfo) :-
-	LayoutInfo0 = stack_layout_info(A, CNum0, C, D, E, F),
+	LayoutInfo0 = stack_layout_info(A, CNum0, C, D, E, F, G),
 	CNum is CNum0 + 1,
-	LayoutInfo = stack_layout_info(A, CNum, C, D, E, F).
+	LayoutInfo = stack_layout_info(A, CNum, C, D, E, F, G).
 
 :- pred stack_layout__get_cell_number(int::out,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
 stack_layout__get_cell_number(CNum, LayoutInfo, LayoutInfo) :-
-	LayoutInfo = stack_layout_info(_, CNum, _, _, _, _).
-
-:- pred stack_layout__get_cmodules(list(c_module)::out,
-	stack_layout_info::in, stack_layout_info::out) is det.
-
-stack_layout__get_cmodules(CModules, LayoutInfo, LayoutInfo) :-
-	LayoutInfo = stack_layout_info(_, _, _, _, _, CModules).
+	LayoutInfo = stack_layout_info(_, CNum, _, _, _, _, _).
 
 :- pred stack_layout__get_agc_stack_layout(bool::out,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
 stack_layout__get_agc_stack_layout(AgcStackLayout, LayoutInfo, LayoutInfo) :-
-	LayoutInfo = stack_layout_info(_, _, AgcStackLayout, _, _, _).
+	LayoutInfo = stack_layout_info(_, _, AgcStackLayout, _, _, _, _).
 
 :- pred stack_layout__get_trace_stack_layout(bool::out,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
 stack_layout__get_trace_stack_layout(TraceStackLayout, LayoutInfo,
 		LayoutInfo) :-
-	LayoutInfo = stack_layout_info(_, _, _, TraceStackLayout, _, _).
+	LayoutInfo = stack_layout_info(_, _, _, TraceStackLayout, _, _, _).
 
 :- pred stack_layout__get_procid_stack_layout(bool::out,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
 stack_layout__get_procid_stack_layout(ProcIdStackLayout, LayoutInfo,
 		LayoutInfo) :-
-	LayoutInfo = stack_layout_info(_, _, _, _, ProcIdStackLayout, _).
+	LayoutInfo = stack_layout_info(_, _, _, _, ProcIdStackLayout, _, _).
 
-:- pred stack_layout__add_cmodule(c_module::in,
+:- pred stack_layout__get_cmodules(list(c_module)::out,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
-stack_layout__add_cmodule(CModule, LayoutInfo0, LayoutInfo) :-
-	LayoutInfo0 = stack_layout_info(A, B, C, D, E, CModules0),
+stack_layout__get_cmodules(CModules, LayoutInfo, LayoutInfo) :-
+	LayoutInfo = stack_layout_info(_, _, _, _, _, CModules, _).
+
+:- pred stack_layout__get_label_set(set_bbbtree(label)::out,
+	stack_layout_info::in, stack_layout_info::out) is det.
+
+stack_layout__get_label_set(StackLayoutLabels, LayoutInfo, LayoutInfo) :-
+	LayoutInfo = stack_layout_info(_, _, _, _, _, _, StackLayoutLabels).
+
+:- pred stack_layout__add_cmodule(c_module::in, label::in,
+	stack_layout_info::in, stack_layout_info::out) is det.
+
+stack_layout__add_cmodule(CModule, Label, LayoutInfo0, LayoutInfo) :-
+	LayoutInfo0 = stack_layout_info(A, B, C, D, E, CModules0,
+		StackLayoutLabels0),
 	CModules = [CModule | CModules0],
-	LayoutInfo = stack_layout_info(A, B, C, D, E, CModules).
+	set_bbbtree__insert(StackLayoutLabels0, Label, StackLayoutLabels),
+	LayoutInfo = stack_layout_info(A, B, C, D, E, CModules,
+		StackLayoutLabels).
 
 :- pred stack_layout__set_cell_number(int::in,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
 stack_layout__set_cell_number(CNum, LayoutInfo0, LayoutInfo) :-
-	LayoutInfo0 = stack_layout_info(A, _, C, D, E, F),
-	LayoutInfo = stack_layout_info(A, CNum, C, D, E, F).
-
+	LayoutInfo0 = stack_layout_info(A, _, C, D, E, F, G),
+	LayoutInfo = stack_layout_info(A, CNum, C, D, E, F, G).
diff -u ws4/compiler/string_switch.m ws2/compiler/string_switch.m
--- ws4/compiler/string_switch.m	Tue Apr  7 16:38:02 1998
+++ ws2/compiler/string_switch.m	Sat Mar 28 15:05:48 1998
@@ -303,28 +303,16 @@
 		{ LabelCode = node([
 			label(Label) - Comment
 		]) },
-		code_info__get_maybe_trace_info(MaybeTraceInfo),
-		( { MaybeTraceInfo = yes(TraceInfo) } ->
-			{ Goal = _ - GoalInfo },
-			{ goal_info_get_goal_path(GoalInfo, Path) },
-			{ goal_info_get_pre_deaths(GoalInfo, PreDeaths) },
-			trace__generate_event_code(switch(Path, PreDeaths),
-				TraceInfo, TraceCode)
-		;
-			{ TraceCode = empty }
-		),
+		code_info__grab_code_info(CodeInfo),
+		trace__maybe_generate_internal_event_code(Goal, TraceCode),
+		code_gen__generate_goal(CodeModel, Goal, GoalCode),
+		code_info__generate_branch_end(CodeModel, StoreMap, SaveCode),
 		(
 			{ string_switch__this_is_last_case(Slot, TblSize,
 				HashSlotMap) }
 		->
-			code_gen__generate_goal(CodeModel, Goal, GoalCode),
-			code_info__generate_branch_end(CodeModel, StoreMap,
-				SaveCode)
+			[]
 		;
-			code_info__grab_code_info(CodeInfo),
-			code_gen__generate_goal(CodeModel, Goal, GoalCode),
-			code_info__generate_branch_end(CodeModel, StoreMap,
-				SaveCode),
 			code_info__slap_code_info(CodeInfo)
 		),
 		{ FinishCode = node([
diff -u ws4/compiler/switch_gen.m ws2/compiler/switch_gen.m
--- ws4/compiler/switch_gen.m	Tue Apr  7 16:38:02 1998
+++ ws2/compiler/switch_gen.m	Sat Mar 28 15:41:34 1998
@@ -307,22 +307,13 @@
 
 switch_gen__generate_cases([case(_, _, Cons, Goal) | Cases], Var, CodeModel,
 		CanFail, StoreMap, EndLabel, CasesCode) -->
-	code_info__get_maybe_trace_info(MaybeTraceInfo),
-	( { MaybeTraceInfo = yes(TraceInfo) } ->
-		{ Goal = _ - GoalInfo },
-		{ goal_info_get_goal_path(GoalInfo, Path) },
-		{ goal_info_get_pre_deaths(GoalInfo, PreDeaths) },
-		trace__generate_event_code(switch(Path, PreDeaths), TraceInfo,
-			TraceCode)
-	;
-		{ TraceCode = empty }
-	),
 	code_info__grab_code_info(CodeInfo0),
 	(
 		{ Cases = [_|_] ; CanFail = can_fail }
 	->
 		unify_gen__generate_tag_test(Var, Cons, branch_on_failure,
 			NextLabel, TestCode),
+		trace__maybe_generate_internal_event_code(Goal, TraceCode),
 		code_gen__generate_goal(CodeModel, Goal, GoalCode),
 		code_info__generate_branch_end(CodeModel, StoreMap, SaveCode),
 		{ ElseCode = node([
@@ -341,6 +332,7 @@
 		code_info__grab_code_info(CodeInfo1),
 		code_info__slap_code_info(CodeInfo0)
 	;
+		trace__maybe_generate_internal_event_code(Goal, TraceCode),
 		code_gen__generate_goal(CodeModel, Goal, GoalCode),
 		code_info__generate_branch_end(CodeModel, StoreMap, SaveCode),
 		{ ThisCaseCode =
diff -u ws4/compiler/tag_switch.m ws2/compiler/tag_switch.m
--- ws4/compiler/tag_switch.m	Tue Apr  7 16:38:28 1998
+++ ws2/compiler/tag_switch.m	Sat Mar 28 15:11:24 1998
@@ -659,18 +659,8 @@
 	->
 		% There is no secondary tag, so there is no switch on it
 		( { GoalList = [-1 - Goal] } ->
-			code_info__get_maybe_trace_info(MaybeTraceInfo),
-			( { MaybeTraceInfo = yes(TraceInfo) } ->
-				{ Goal = _ - GoalInfo },
-				{ goal_info_get_goal_path(GoalInfo, Path) },
-				{ goal_info_get_pre_deaths(GoalInfo,
-					PreDeaths) },
-				trace__generate_event_code(
-					switch(Path, PreDeaths),
-					TraceInfo, TraceCode)
-			;
-				{ TraceCode = empty }
-			),
+			trace__maybe_generate_internal_event_code(Goal,
+				TraceCode),
 			code_gen__generate_goal(CodeModel, Goal, GoalCode),
 			code_info__generate_branch_end(CodeModel, StoreMap,
 				SaveCode),
@@ -806,16 +796,6 @@
 tag_switch__generate_secondary_try_me_else_chain([Case0 | Cases0], StagRval,
 		CodeModel, CanFail, StoreMap, EndLabel, FailLabel, Code) -->
 	{ Case0 = Secondary - Goal },
-	code_info__get_maybe_trace_info(MaybeTraceInfo),
-	( { MaybeTraceInfo = yes(TraceInfo) } ->
-		{ Goal = _ - GoalInfo },
-		{ goal_info_get_goal_path(GoalInfo, Path) },
-		{ goal_info_get_pre_deaths(GoalInfo, PreDeaths) },
-		trace__generate_event_code(switch(Path, PreDeaths),
-			TraceInfo, TraceCode)
-	;
-		{ TraceCode = empty }
-	),
 	( { Cases0 = [_|_] ; CanFail = can_fail } ->
 		code_info__grab_code_info(CodeInfo),
 		code_info__get_next_label(ElseLabel),
@@ -825,6 +805,7 @@
 				label(ElseLabel))
 				- "test remote sec tag only"
 		]) },
+		trace__maybe_generate_internal_event_code(Goal, TraceCode),
 		code_gen__generate_goal(CodeModel, Goal, GoalCode),
 		code_info__generate_branch_end(CodeModel, StoreMap, SaveCode),
 		{ GotoLabelCode = node([
@@ -854,6 +835,7 @@
 			{ Code = tree(ThisCode, FailCode) }
 		)
 	;
+		trace__maybe_generate_internal_event_code(Goal, TraceCode),
 		code_gen__generate_goal(CodeModel, Goal, GoalCode),
 		code_info__generate_branch_end(CodeModel, StoreMap, SaveCode),
 		{ GotoCode = node([
@@ -884,16 +866,6 @@
 		CodeModel, CanFail, StoreMap, EndLabel, FailLabel,
 		PrevTests0, PrevCases0, Code) -->
 	{ Case0 = Secondary - Goal },
-	code_info__get_maybe_trace_info(MaybeTraceInfo),
-	( { MaybeTraceInfo = yes(TraceInfo) } ->
-		{ Goal = _ - GoalInfo },
-		{ goal_info_get_goal_path(GoalInfo, Path) },
-		{ goal_info_get_pre_deaths(GoalInfo, PreDeaths) },
-		trace__generate_event_code(switch(Path, PreDeaths),
-			TraceInfo, TraceCode)
-	;
-		{ TraceCode = empty }
-	),
 	( { Cases0 = [_|_] ; CanFail = can_fail } ->
 		code_info__grab_code_info(CodeInfo),
 		code_info__get_next_label(ThisStagLabel),
@@ -907,6 +879,7 @@
 			label(ThisStagLabel) -
 				"handle next secondary tag"
 		]) },
+		trace__maybe_generate_internal_event_code(Goal, TraceCode),
 		code_gen__generate_goal(CodeModel, Goal, GoalCode),
 		code_info__generate_branch_end(CodeModel, StoreMap, SaveCode),
 		{ GotoCode = node([
@@ -936,6 +909,7 @@
 			{ Code = tree(PrevTests, tree(FailCode, PrevCases)) }
 		)
 	;
+		trace__maybe_generate_internal_event_code(Goal, TraceCode),
 		code_gen__generate_goal(CodeModel, Goal, GoalCode),
 		code_info__generate_branch_end(CodeModel, StoreMap, SaveCode),
 		{ GotoCode = node([
@@ -981,29 +955,15 @@
 				label(NewLabel) -
 					"start of case in secondary tag switch"
 			]) },
-			code_info__get_maybe_trace_info(MaybeTraceInfo),
-			( { MaybeTraceInfo = yes(TraceInfo) } ->
-				{ Goal = _ - GoalInfo },
-				{ goal_info_get_goal_path(GoalInfo, Path) },
-				{ goal_info_get_pre_deaths(GoalInfo,
-					PreDeaths) },
-				trace__generate_event_code(
-					switch(Path, PreDeaths),
-					TraceInfo, TraceCode)
-			;
-				{ TraceCode = empty }
-			),
+			code_info__grab_code_info(CodeInfo),
+			trace__maybe_generate_internal_event_code(Goal,
+				TraceCode),
+			code_gen__generate_goal(CodeModel, Goal, GoalCode),
+			code_info__generate_branch_end(CodeModel, StoreMap,
+				SaveCode),
 			( { CaseList1 = [] } ->
-				code_gen__generate_goal(CodeModel, Goal,
-					GoalCode),
-				code_info__generate_branch_end(CodeModel,
-					StoreMap, SaveCode)
+				[]
 			;
-				code_info__grab_code_info(CodeInfo),
-				code_gen__generate_goal(CodeModel, Goal,
-					GoalCode),
-				code_info__generate_branch_end(CodeModel,
-					StoreMap, SaveCode),
 				code_info__slap_code_info(CodeInfo)
 			),
 			{ GotoCode = node([
@@ -1067,18 +1027,8 @@
 			),
 			{ MaybeFinalCodeInfo = MaybeFinalCodeInfo0 }
 		; { StagGoals = [CurSec - Goal] } ->
-			code_info__get_maybe_trace_info(MaybeTraceInfo),
-			( { MaybeTraceInfo = yes(TraceInfo) } ->
-				{ Goal = _ - GoalInfo },
-				{ goal_info_get_goal_path(GoalInfo, Path) },
-				{ goal_info_get_pre_deaths(GoalInfo,
-					PreDeaths) },
-				trace__generate_event_code(
-					switch(Path, PreDeaths),
-					TraceInfo, TraceCode)
-			;
-				{ TraceCode = empty }
-			),
+			trace__maybe_generate_internal_event_code(Goal,
+				TraceCode),
 			code_gen__generate_goal(CodeModel, Goal, GoalCode),
 			code_info__generate_branch_end(CodeModel, StoreMap,
 				SaveCode),



More information about the developers mailing list