[m-rev.] for review: deep profiling fixes, determinism algorithm change

Zoltan Somogyi zs at cs.mu.OZ.AU
Tue Aug 13 11:22:58 AEST 2002


For review by anyone.

I am particularly interested in views about whether the change in determinism
analysis should apply to all impure code or just to goals specially marked
by the compiler.

Zoltan.

Fix several bugs in deep profiling. These allow the compiler to bootstrap
again, *including* writing out the profiling data, with sanity checks enabled.
Some test cases still fail, but significantly fewer than before.

These fixes required several improvements in the infrastructure for low
level debugging in the LLDS grades.

compiler/deep_profiling.m:
	Mark calls that have a prepare_for_{normal,ho,...}_call inserted before
	them as impure, to prevent simplify from optimizing them away, e.g. as
	duplicate calls. This is needed because a prepare_for_{...}_call that
	is not followed immediately by the call port code of the callee leaves
	the profiling tree in a state that violates its invariants.

	Mark the redo port code of model_non predicates as needing to be
	preserved, even if determinism analysis would normally cause it to be
	cut by marking the disjunction it is part of (whose two disjuncts are
	the det exit port code and the failure redo port code) as det.

	Fix the generation of goal paths to match what the rest of the compiler
	does. Start number conjuncts, disjuncts and switch arms from 1, not 0,
	and do not reverse goal paths before attaching them to goals; they will
	be reversed when they are converted to strings.

compiler/det_analysis.m:
	If a disjunct has determinism failure but is impure, treat it as being
	able to succeed when computing the max number of solutions of the
	disjunction as a whole, *provided* that some earlier disjuct could
	succeed. The idea is that ( impure failure ; det ) should be treated
	as det, since all backtracking is local within it, while disjunctions
	of the form ( det ; impure failure ) should be treated as multi, since
	we want to be able to backtrack to the second disjunct from *outside*
	the disjunction.

	At the moment, we do this not for all impure goals, but only for the
	impure goals that deep_profiling marks with the preserve_backtrack_into
	feature.

compiler/hlds_goal.m:
	Add the preserve_backtrack_into feature.

	Add utility predicates for handling the features of a goal directly,
	without explicitly dealing with its goal_info.

runtime/mercury_debug.[ch]:
	Add mechanisms for turning the printing of low level debugging messages
	on and off. Without this, enabling low level debugging can generate
	literally gigabytes of debugging output.

	The mechanisms all depend on numbering calls.

	One mechanism allows messages to be printed starting from calls in
	given ranges, by including e.g. -di100-200,300-400 in MERCURY_OPTIONS.

	Another mechanism allows N messages to be printed starting from calls
	to a given procedure or from calls at which next_call_site_dynamic
	has a given value. The value of N (the size of the block of calls)
	can be specified by include -dB<num> in MERCURY_OPTIONS. The name of
	the given procedure (actually the name of its entry label) can be
	specified by including -dj<entrylabel> in MERCURY_OPTIONS. The address
	of the call_site_dynamic structure to watch for is specified with the
	-dW<addr> option in MERCURY_OPTIONS, as before.

runtime/mercury_wrapper.[ch]:
	Add the global variables required to implement the new low level
	debugging functionality, as well as the option processing code required
	to set those global variables.

	Separate the flags controlling the printing of the values of stack
	control registers (sp, curfr etc) and ordinary registers (r1, r2 etc).
	Print ordinary registers only if explicitly requested.

runtime/mercury_engine.h:
	Add the required global flags.

runtime/mercury_deep_profiling.[ch]:
	Add two extra arguments to MR_deep_assert, and print them if an
	assertion fails. This makes it easier to decide what p

runtime/mercury_deep_*_port_body.h:
runtime/mercury_deep_rec_depth_*.h:
library/profiling_builtin.m:
	Pass the extra arguments to MR_deep_assert, and print low level
	debugging messages only if the relevant flag is set.

tools/lmc:
	Add mechanisms to add to the list of C compiler flags the program is
	compiled with by lmc.

cvs diff: Diffing .
cvs diff: Diffing bench
cvs diff: Diffing bench/progs
cvs diff: Diffing bench/progs/compress
cvs diff: Diffing bench/progs/icfp2000
cvs diff: Diffing bench/progs/icfp2001
cvs diff: Diffing bench/progs/nuc
cvs diff: Diffing bench/progs/ray
cvs diff: Diffing bench/progs/tree234
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/deep_profiling.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/deep_profiling.m,v
retrieving revision 1.10
diff -u -b -r1.10 deep_profiling.m
--- compiler/deep_profiling.m	2002/07/22 06:29:27	1.10
+++ compiler/deep_profiling.m	2002/08/12 08:57:49
@@ -808,7 +808,7 @@
 			failure, FailPortCode),
 		generate_call(ModuleInfo, "non_redo_port_code_sr", 2,
 			[MiddleCSD, NewOutermostProcDyn], no,
-			failure, RedoPortCode),
+			failure, RedoPortCode0),
 		NewNonlocals = list_to_set(
 			[TopCSD, MiddleCSD, OldOutermostProcDyn2])
 	;
@@ -823,10 +823,15 @@
 			[TopCSD, MiddleCSD], no, failure, FailPortCode),
 		generate_call(ModuleInfo, "non_redo_port_code_ac", 2,
 			[MiddleCSD, NewOutermostProcDyn], no,
-			failure, RedoPortCode),
+			failure, RedoPortCode0),
 		NewNonlocals = list_to_set([TopCSD, MiddleCSD])
 	),
 
+	RedoPortCode0 = RedoPortExpr - RedoPortGoalInfo0,
+	goal_info_add_feature(RedoPortGoalInfo0,
+		preserve_backtrack_into, RedoPortGoalInfo),
+	RedoPortCode = RedoPortExpr - RedoPortGoalInfo,
+
 	% Even though the procedure has a model_non interface determinism,
 	% the actual determinism of its original body goal may have been
 	% at_most once. However, the exit/redo disjunction we insert into
@@ -997,10 +1002,9 @@
 transform_goal(_, shorthand(_) - _, _, _) -->
 	{ error("transform_goal/6: shorthand should have gone by now") }.
 
-transform_goal(Path0, Goal0 - Info0, GoalAndInfo, AddedImpurity) -->
+transform_goal(Path, Goal0 - Info0, GoalAndInfo, AddedImpurity) -->
 	{ Goal0 = foreign_proc(Attrs, _, _, _, _, _, _) },
 	( { may_call_mercury(Attrs, may_call_mercury) } ->
-		{ reverse(Path0, Path) },
 		wrap_foreign_code(Path, Goal0 - Info0, GoalAndInfo),
 		{ AddedImpurity = yes }
 	;
@@ -1011,18 +1015,16 @@
 transform_goal(_Path, Goal - Info, Goal - Info, no) -->
 	{ Goal = unify(_, _, _, _, _) }.
 
-transform_goal(Path0, Goal0 - Info0, GoalAndInfo, yes) -->
+transform_goal(Path, Goal0 - Info0, GoalAndInfo, yes) -->
 	{ Goal0 = call(_, _, _, BuiltinState, _, _) },
 	( { BuiltinState \= inline_builtin } ->
-		{ reverse(Path0, Path) },
 		wrap_call(Path, Goal0 - Info0, GoalAndInfo)
 	;
 		{ GoalAndInfo = Goal0 - Info0 }
 	).
 
-transform_goal(Path0, Goal0 - Info0, GoalAndInfo, yes) -->
+transform_goal(Path, Goal0 - Info0, GoalAndInfo, yes) -->
 	{ Goal0 = generic_call(_, _, _, _) },
-	{ reverse(Path0, Path) },
 	wrap_call(Path, Goal0 - Info0, GoalAndInfo).
 
 :- pred transform_conj(int::in, goal_path::in,
@@ -1031,8 +1033,9 @@
 
 transform_conj(_, _, [], [], no) --> [].
 transform_conj(N, Path, [Goal0 | Goals0], [Goal | Goals], AddedImpurity) -->
-	transform_goal([conj(N) | Path], Goal0, Goal, AddedImpurityFirst),
-	transform_conj(N + 1, Path, Goals0, Goals, AddedImpurityLater),
+	{ N1 = N + 1 },
+	transform_goal([conj(N1) | Path], Goal0, Goal, AddedImpurityFirst),
+	transform_conj(N1, Path, Goals0, Goals, AddedImpurityLater),
 	{ bool__or(AddedImpurityFirst, AddedImpurityLater, AddedImpurity) }.
 
 :- pred transform_disj(int::in, goal_path::in,
@@ -1041,8 +1044,9 @@
 
 transform_disj(_, _, [], [], no) --> [].
 transform_disj(N, Path, [Goal0 | Goals0], [Goal | Goals], AddedImpurity) -->
-	transform_goal([disj(N) | Path], Goal0, Goal, AddedImpurityFirst),
-	transform_disj(N + 1, Path, Goals0, Goals, AddedImpurityLater),
+	{ N1 = N + 1 },
+	transform_goal([disj(N1) | Path], Goal0, Goal, AddedImpurityFirst),
+	transform_disj(N1, Path, Goals0, Goals, AddedImpurityLater),
 	{ bool__or(AddedImpurityFirst, AddedImpurityLater, AddedImpurity) }.
 
 :- pred transform_switch(int::in, int::in, goal_path::in,
@@ -1052,9 +1056,10 @@
 transform_switch(_, _, _, [], [], no) --> [].
 transform_switch(NumCases, N, Path, [case(Id, Goal0) | Goals0],
 		[case(Id, Goal) | Goals], AddedImpurity) -->
-	transform_goal([switch(NumCases, N) | Path], Goal0, Goal,
+	{ N1 = N + 1 },
+	transform_goal([switch(NumCases, N1) | Path], Goal0, Goal,
 		AddedImpurityFirst),
-	transform_switch(NumCases, N + 1, Path, Goals0, Goals,
+	transform_switch(NumCases, N1, Path, Goals0, Goals,
 		AddedImpurityLater),
 	{ bool__or(AddedImpurityFirst, AddedImpurityLater, AddedImpurity) }.
 
@@ -1068,6 +1073,16 @@
 	goal_info_remove_feature(GoalInfo0, tailcall, GoalInfo1),
 	goal_info_add_feature(GoalInfo1, impure, GoalInfo),
 
+	% We need to make the call itself impure. If we didn't do so,
+	% then simplify could eliminate the goal (e.g. if it was a duplicate
+	% call). The result would be a prepare_for_{...}_call whose execution
+	% is not followed by the execution of the call port code of the callee.
+	% This would leave the MR_csd_callee_ptr field NULL, which violates
+	% invariants of the deep profiling tree (which allows this field to be
+	% NULL only temporarily, between the prepare_for_{...}_call and the
+	% call port code).
+	Goal1 = GoalExpr - GoalInfo,
+
 	SiteNumCounter0 = DeepInfo0 ^ site_num_counter,
 	counter__allocate(SiteNum, SiteNumCounter0, SiteNumCounter),
 	varset__new_named_var(DeepInfo0 ^ vars, "SiteNum", SiteNumVar, Vars1),
@@ -1118,14 +1133,14 @@
 		),
 		CallSite = normal_call(RttiProcLabel, TypeSubst,
 			FileName, LineNumber, GoalPath),
-		Goal1 = Goal0,
+		Goal2 = Goal1,
 		DeepInfo3 = DeepInfo1
 	;
 		CallKind = special(_PredProcId, TypeInfoVar),
 		generate_call(ModuleInfo, "prepare_for_special_call", 2,
 			[SiteNumVar, TypeInfoVar], [], PrepareGoal),
 		CallSite = special_call(FileName, LineNumber, GoalPath),
-		Goal1 = Goal0,
+		Goal2 = Goal1,
 		DeepInfo3 = DeepInfo1
 	;
 		CallKind = generic(Generic),
@@ -1166,12 +1181,13 @@
 			use_zeroing_for_ho_cycles, UseZeroing),
 		( UseZeroing = yes ->
 			transform_higher_order_call(Globals, GoalCodeModel,
-				Goal0, Goal1, DeepInfo2, DeepInfo3)
+				Goal1, Goal2, DeepInfo2, DeepInfo3)
 		;
-			Goal1 = Goal0,
+			Goal2 = Goal1,
 			DeepInfo3 = DeepInfo2
 		)
 	),
+
 	DeepInfo4 = DeepInfo3 ^ call_sites :=
 		(DeepInfo3 ^ call_sites ++ [CallSite]),
 	(
@@ -1203,7 +1219,7 @@
 		( CodeModel = model_det ->
 			list__condense([
 				CallGoals,
-				[SiteNumVarGoal, PrepareGoal, Goal1],
+				[SiteNumVarGoal, PrepareGoal, Goal2],
 				ExitGoals
 			], Goals),
 			Goal = conj(Goals) - GoalInfo
@@ -1229,7 +1245,7 @@
 					conj([
 						SiteNumVarGoal,
 						PrepareGoal,
-						Goal1 |
+						Goal2 |
 						ExitGoals
 					]) - WrappedGoalGoalInfo,
 					conj(
@@ -1243,7 +1259,7 @@
 		Goal = conj([
 			SiteNumVarGoal,
 			PrepareGoal,
-			Goal1
+			Goal2
 		]) - GoalInfo,
 		DeepInfo = DeepInfo4
 	).
Index: compiler/det_analysis.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/det_analysis.m,v
retrieving revision 1.157
diff -u -b -r1.157 det_analysis.m
--- compiler/det_analysis.m	2002/07/30 04:29:41	1.157
+++ compiler/det_analysis.m	2002/08/11 01:53:33
@@ -839,11 +839,21 @@
 	determinism_components(Detism, CanFail, MaxSolns).
 det_infer_disj([Goal0 | Goals0], InstMap0, SolnContext, DetInfo, CanFail0,
 		MaxSolns0, [Goal | Goals1], Detism, Msgs) :-
-	det_infer_goal(Goal0, InstMap0, SolnContext, DetInfo,
-			Goal, Detism1, Msgs1),
+	det_infer_goal(Goal0, InstMap0, SolnContext, DetInfo, Goal, Detism1,
+		Msgs1),
 	determinism_components(Detism1, CanFail1, MaxSolns1),
+	Goal = _ - GoalInfo,
+	(
+		MaxSolns0 \= at_most_zero,
+		MaxSolns1 = at_most_zero,
+		goal_info_has_feature(GoalInfo, preserve_backtrack_into)
+	->
+		AdjMaxSolns1 = at_most_one
+	;
+		AdjMaxSolns1 = MaxSolns1
+	),
 	det_disjunction_canfail(CanFail0, CanFail1, CanFail2),
-	det_disjunction_maxsoln(MaxSolns0, MaxSolns1, MaxSolns2),
+	det_disjunction_maxsoln(MaxSolns0, AdjMaxSolns1, MaxSolns2),
 	% if we're in a single-solution context,
 	% convert `at_most_many' to `at_most_many_cc'
 	( SolnContext = first_soln, MaxSolns2 = at_most_many ->
Index: compiler/hlds_goal.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_goal.m,v
retrieving revision 1.97
diff -u -b -r1.97 hlds_goal.m
--- compiler/hlds_goal.m	2002/07/22 06:29:31	1.97
+++ compiler/hlds_goal.m	2002/08/12 11:49:32
@@ -687,6 +687,15 @@
 :- pred goal_get_nonlocals(hlds_goal, set(prog_var)).
 :- mode goal_get_nonlocals(in, out) is det.
 
+:- pred goal_add_feature(hlds_goal, goal_feature, hlds_goal).
+:- mode goal_add_feature(in, in, out) is det.
+
+:- pred goal_remove_feature(hlds_goal, goal_feature, hlds_goal).
+:- mode goal_remove_feature(in, in, out) is det.
+
+:- pred goal_has_feature(hlds_goal, goal_feature).
+:- mode goal_has_feature(in, in) is semidet.
+
 :- type goal_feature
 	--->	constraint	% This is included if the goal is
 				% a constraint.  See constraint.m
@@ -715,6 +724,8 @@
 				% determinism analysis say that the
 				% nondeterminism inside the some() should be
 				% exposed to the environment outside.
+	;	preserve_backtrack_into
+				% This
 	;	tailcall.	% This goal represents a tail call. This marker
 				% is used by deep profiling.
 
@@ -1274,6 +1285,15 @@
 
 goal_get_nonlocals(_Goal - GoalInfo, NonLocals) :-
 	goal_info_get_nonlocals(GoalInfo, NonLocals).
+
+goal_add_feature(Goal - GoalInfo0, Feature, Goal - GoalInfo) :-
+	goal_info_add_feature(GoalInfo0, Feature, GoalInfo).
+
+goal_remove_feature(Goal - GoalInfo0, Feature, Goal - GoalInfo) :-
+	goal_info_remove_feature(GoalInfo0, Feature, GoalInfo).
+
+goal_has_feature(_Goal - GoalInfo, Feature) :-
+	goal_info_has_feature(GoalInfo, Feature).
 
 %-----------------------------------------------------------------------------%
 %
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/aditi
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/stream
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing java
cvs diff: Diffing java/library
cvs diff: Diffing java/runtime
cvs diff: Diffing library
Index: library/profiling_builtin.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/profiling_builtin.m,v
retrieving revision 1.10
diff -u -b -r1.10 profiling_builtin.m
--- library/profiling_builtin.m	2002/08/09 05:26:43	1.10
+++ library/profiling_builtin.m	2002/08/12 13:18:17
@@ -290,9 +290,9 @@
 
 	MR_enter_instrumentation();
 	csd = MR_current_call_site_dynamic;
-	MR_deep_assert(csd != NULL);
+	MR_deep_assert(csd, NULL, csd != NULL);
 	pd = csd->MR_csd_callee_ptr;
-	MR_deep_assert(pd != NULL);
+	MR_deep_assert(csd, NULL, pd != NULL);
 
 	child_csd = pd->MR_pd_call_site_ptr_ptrs[N];
 
@@ -331,9 +331,9 @@
 
 	MR_enter_instrumentation();
 	csd = MR_current_call_site_dynamic;
-	MR_deep_assert(csd != NULL);
+	MR_deep_assert(csd, NULL, csd != NULL);
 	pd = csd->MR_csd_callee_ptr;
-	MR_deep_assert(pd != NULL);
+	MR_deep_assert(csd, NULL, pd != NULL);
 
 	type_info = (MR_TypeInfo) TypeInfo;
 	type_ctor_info = MR_TYPEINFO_GET_TYPE_CTOR_INFO(type_info);
@@ -381,9 +381,9 @@
 	MR_enter_instrumentation();
 	closure = (MR_Closure *) Closure;
 	csd = MR_current_call_site_dynamic;
-	MR_deep_assert(csd != NULL);
+	MR_deep_assert(csd, NULL, csd != NULL);
 	pd = csd->MR_csd_callee_ptr;
-	MR_deep_assert(pd != NULL);
+	MR_deep_assert(csd, NULL, pd != NULL);
 
   #ifdef MR_DEEP_PROFILING_KEY_USES_ID
 	void_key = (void *) (closure->MR_closure_layout);
@@ -432,9 +432,9 @@
 
 	MR_enter_instrumentation();
 	csd = MR_current_call_site_dynamic;
-	MR_deep_assert(csd != NULL);
+	MR_deep_assert(csd, NULL, csd != NULL);
 	pd = csd->MR_csd_callee_ptr;
-	MR_deep_assert(pd != NULL);
+	MR_deep_assert(csd, NULL, pd != NULL);
 
 	void_key = (void *)
 		MR_typeclass_info_class_method(TypeClassInfo, MethodNum);
@@ -473,9 +473,9 @@
 
 	MR_enter_instrumentation();
 	csd = MR_current_call_site_dynamic;
-	MR_deep_assert(csd != NULL);
+	MR_deep_assert(csd, NULL, csd != NULL);
 	pd = csd->MR_csd_callee_ptr;
-	MR_deep_assert(pd != NULL);
+	MR_deep_assert(csd, NULL, pd != NULL);
 
 	MR_current_callback_site = (MR_CallSiteDynList **)
 		&(pd->MR_pd_call_site_ptr_ptrs[CSN]);
@@ -505,9 +505,9 @@
   #endif
 
 	csd = MR_current_call_site_dynamic;
-	MR_deep_assert(csd != NULL);
+	MR_deep_assert(csd, NULL, csd != NULL);
 	pd = csd->MR_csd_callee_ptr;
-	MR_deep_assert(pd != NULL);
+	MR_deep_assert(csd, NULL, pd != NULL);
 
 	child_csd = pd->MR_pd_call_site_ptr_ptrs[CSN];
 
@@ -544,9 +544,9 @@
 
 	MR_enter_instrumentation();
 	csd = MR_current_call_site_dynamic;
-	MR_deep_assert(csd != NULL);
+	MR_deep_assert(csd, NULL, csd != NULL);
 	pd = csd->MR_csd_callee_ptr;
-	MR_deep_assert(pd != NULL);
+	MR_deep_assert(csd, NULL, pd != NULL);
 	ps = pd->MR_pd_proc_static;
 
 	Count = ps->MR_ps_activation_count;
@@ -572,9 +572,9 @@
 
 	MR_enter_instrumentation();
 	csd = MR_current_call_site_dynamic;
-	MR_deep_assert(csd != NULL);
+	MR_deep_assert(csd, NULL, csd != NULL);
 	pd = csd->MR_csd_callee_ptr;
-	MR_deep_assert(pd != NULL);
+	MR_deep_assert(csd, NULL, pd != NULL);
 	ps = pd->MR_pd_proc_static;
 
 	Ptr = (MR_Word) ps->MR_ps_outermost_activation_ptr;
@@ -598,9 +598,9 @@
 
 	MR_enter_instrumentation();
 	csd = MR_current_call_site_dynamic;
-	MR_deep_assert(csd != NULL);
+	MR_deep_assert(csd, NULL, csd != NULL);
 	pd = csd->MR_csd_callee_ptr;
-	MR_deep_assert(pd != NULL);
+	MR_deep_assert(csd, NULL, pd != NULL);
 	ps = pd->MR_pd_proc_static;
 
 	ps->MR_ps_activation_count = 0;
@@ -624,9 +624,9 @@
 
 	MR_enter_instrumentation();
 	csd = MR_current_call_site_dynamic;
-	MR_deep_assert(csd != NULL);
+	MR_deep_assert(csd, NULL, csd != NULL);
 	pd = csd->MR_csd_callee_ptr;
-	MR_deep_assert(pd != NULL);
+	MR_deep_assert(csd, NULL, pd != NULL);
 	ps = pd->MR_pd_proc_static;
 
 	ps->MR_ps_outermost_activation_ptr = NULL;
@@ -649,9 +649,9 @@
 
 	MR_enter_instrumentation();
 	csd = MR_current_call_site_dynamic;
-	MR_deep_assert(csd != NULL);
+	MR_deep_assert(csd, NULL, csd != NULL);
 	pd = csd->MR_csd_callee_ptr;
-	MR_deep_assert(pd != NULL);
+	MR_deep_assert(csd, NULL, pd != NULL);
 	ps = pd->MR_pd_proc_static;
 
 	ps->MR_ps_activation_count = Count;
@@ -675,9 +675,9 @@
 
 	MR_enter_instrumentation();
 	csd = MR_current_call_site_dynamic;
-	MR_deep_assert(csd != NULL);
+	MR_deep_assert(csd, NULL, csd != NULL);
 	pd = csd->MR_csd_callee_ptr;
-	MR_deep_assert(pd != NULL);
+	MR_deep_assert(csd, NULL, pd != NULL);
 	ps = pd->MR_pd_proc_static;
 
 	ps->MR_ps_outermost_activation_ptr = (MR_ProcDynamic *) Ptr;
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
Index: runtime/mercury_debug.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_debug.c,v
retrieving revision 1.11
diff -u -b -r1.11 mercury_debug.c
--- runtime/mercury_debug.c	2002/08/07 03:18:55	1.11
+++ runtime/mercury_debug.c	2002/08/12 08:13:25
@@ -16,7 +16,18 @@
 
 /*--------------------------------------------------------------------*/
 
+#ifdef	MR_DEEP_PROFILING
+static void	MR_check_watch_csd_start(MR_Code *proc);
+static MR_bool	MR_csds_are_different(MR_CallSiteDynamic *csd1,
+			MR_CallSiteDynamic *csd2);
+static void	MR_assign_csd(MR_CallSiteDynamic *csd1,
+			MR_CallSiteDynamic *csd2);
+#endif
+
+static void	MR_count_call(MR_Code *proc);
 static void	MR_print_ordinary_regs(void);
+static void	MR_do_watches(void);
+static MR_bool	MR_proc_matches_name(MR_Code *proc, const char *name);
 static void	MR_printdetslot_as_label(const MR_Integer offset);
 
 #ifdef	MR_LOWLEVEL_ADDR_DEBUG
@@ -36,6 +47,10 @@
 {
 	MR_restore_transient_registers();
 
+	if (MR_lld_print_enabled == 0) {
+		return;
+	}
+
 	printf("\nnew choice point for procedure %s\n", predname);
 	printf("new  fr: "); MR_printnondstack(MR_curfr);
 	printf("prev fr: "); MR_printnondstack(MR_prevfr_slot(MR_curfr));
@@ -53,6 +68,12 @@
 {
 	MR_restore_transient_registers();
 
+	MR_do_watches();
+
+	if (MR_lld_print_enabled == 0) {
+		return;
+	}
+
 	printf("\nsucceeding from procedure\n");
 	printf("curr fr: "); MR_printnondstack(MR_curfr);
 	printf("succ fr: "); MR_printnondstack(MR_succfr_slot(MR_curfr));
@@ -68,6 +89,12 @@
 {
 	MR_restore_transient_registers();
 
+	MR_do_watches();
+
+	if (MR_lld_print_enabled == 0) {
+		return;
+	}
+
 	printf("\nsucceeding from procedure\n");
 	printf("curr fr: "); MR_printnondstack(MR_curfr);
 	printf("succ fr: "); MR_printnondstack(MR_succfr_slot(MR_curfr));
@@ -83,6 +110,12 @@
 {
 	MR_restore_transient_registers();
 
+	MR_do_watches();
+
+	if (MR_lld_print_enabled == 0) {
+		return;
+	}
+
 	printf("\nfailing from procedure\n");
 	printf("curr fr: "); MR_printnondstack(MR_curfr);
 	printf("fail fr: "); MR_printnondstack(MR_prevfr_slot(MR_curfr));
@@ -95,6 +128,12 @@
 {
 	MR_restore_transient_registers();
 
+	MR_do_watches();
+
+	if (MR_lld_print_enabled == 0) {
+		return;
+	}
+
 	printf("\nredo from procedure\n");
 	printf("curr fr: "); MR_printnondstack(MR_curfr);
 	printf("redo fr: "); MR_printnondstack(MR_maxfr);
@@ -104,10 +143,25 @@
 void 
 MR_call_msg(/* const */ MR_Code *proc, /* const */ MR_Code *succ_cont)
 {
-	printf("\ncalling      "); MR_printlabel(stdout, proc);
-	printf("continuation "); MR_printlabel(stdout, succ_cont);
-	if (MR_sregdebug) {
-		MR_printregs("registers at call");
+	MR_count_call(proc);
+
+#ifdef	MR_DEEP_PROFILING
+	MR_check_watch_csd_start(proc);
+#endif	/* MR_DEEP_PROFILING */
+
+	MR_do_watches();
+
+	if (MR_lld_print_enabled == 0) {
+		return;
+	}
+
+	printf("\ncall %lu: ", MR_lld_cur_call);
+	MR_printlabel(stdout, proc);
+	printf("cont ");
+	MR_printlabel(stdout, succ_cont);
+
+	if (MR_anyregdebug) {
+		MR_printregs("at call:");
 	}
 
 #ifdef	MR_DEEP_PROFILING
@@ -120,10 +174,25 @@
 {
 	MR_restore_transient_registers();
 
-	printf("\ntail calling "); MR_printlabel(stdout, proc);
-	printf("continuation "); MR_printlabel(stdout, MR_succip);
-	if (MR_sregdebug) {
-		MR_printregs("registers at tailcall");
+	MR_count_call(proc);
+
+#ifdef	MR_DEEP_PROFILING
+	MR_check_watch_csd_start(proc);
+#endif	/* MR_DEEP_PROFILING */
+
+	MR_do_watches();
+
+	if (MR_lld_print_enabled == 0) {
+		return;
+	}
+
+	printf("\ntail call %lu: ", MR_lld_cur_call);
+	MR_printlabel(stdout, proc);
+	printf("cont ");
+	MR_printlabel(stdout, MR_succip);
+
+	if (MR_anyregdebug) {
+		MR_printregs("at tailcall:");
 	}
 
 #ifdef	MR_DEEP_PROFILING
@@ -134,9 +203,15 @@
 void 
 MR_proceed_msg(void)
 {
+	MR_do_watches();
+
+	if (MR_lld_print_enabled == 0) {
+		return;
+	}
+
 	printf("\nreturning from determinate procedure\n");
-	if (MR_sregdebug) {
-		MR_printregs("registers at proceed");
+	if (MR_anyregdebug) {
+		MR_printregs("at proceed:");
 	}
 
 #ifdef	MR_DEEP_PROFILING
@@ -147,6 +222,10 @@
 void 
 MR_cr1_msg(MR_Word val0, const MR_Word *addr)
 {
+	if (MR_lld_print_enabled == 0) {
+		return;
+	}
+
 	printf("put value %9lx at ", (long) (MR_Integer) val0);
 	MR_printheap(addr);
 }
@@ -154,6 +233,10 @@
 void 
 MR_cr2_msg(MR_Word val0, MR_Word val1, const MR_Word *addr)
 {
+	if (MR_lld_print_enabled == 0) {
+		return;
+	}
+
 	printf("put values %9lx,%9lx at ",	
 		(long) (MR_Integer) val0, (long) (MR_Integer) val1);
 	MR_printheap(addr);
@@ -162,6 +245,10 @@
 void 
 MR_incr_hp_debug_msg(MR_Word val, const MR_Word *addr)
 {
+	if (MR_lld_print_enabled == 0) {
+		return;
+	}
+
 #ifdef MR_CONSERVATIVE_GC
 	printf("allocated %ld words at %p\n", (long) val, addr);
 #else
@@ -173,6 +260,10 @@
 void 
 MR_incr_sp_msg(MR_Word val, const MR_Word *addr)
 {
+	if (MR_lld_print_enabled == 0) {
+		return;
+	}
+
 	printf("increment sp by %ld from ", (long) (MR_Integer) val);
 	MR_printdetstack(addr);
 }
@@ -180,6 +271,10 @@
 void 
 MR_decr_sp_msg(MR_Word val, const MR_Word *addr)
 {
+	if (MR_lld_print_enabled == 0) {
+		return;
+	}
+
 	printf("decrement sp by %ld from ", (long) (MR_Integer) val);
 	MR_printdetstack(addr);
 }
@@ -191,6 +286,10 @@
 void 
 MR_goto_msg(/* const */ MR_Code *addr)
 {
+	if (MR_lld_print_enabled == 0) {
+		return;
+	}
+
 	printf("\ngoto ");
 	MR_printlabel(stdout, addr);
 }
@@ -201,6 +300,10 @@
 	int	i;
 	MR_Integer	x;
 
+	if (MR_lld_print_enabled == 0) {
+		return;
+	}
+
 	for(i=1; i<=8; i++) {
 		x = (MR_Integer) MR_get_reg(i);
 #ifndef MR_CONSERVATIVE_GC
@@ -224,6 +327,58 @@
 
 /* debugging printing tools */
 
+static void
+MR_count_call(MR_Code *proc)
+{
+	MR_lld_cur_call++;
+	if (MR_lld_print_region_enabled == 0) {
+		if (MR_lld_cur_call == MR_lld_print_min) {
+			MR_lld_print_region_enabled = 1;
+			printf("entering printed region\n");
+			printf("min %lu, max %lu, more <%s>\n",
+				MR_lld_print_min, MR_lld_print_max,
+				MR_lld_print_more_min_max);
+		}
+	} else {
+		if (MR_lld_cur_call == MR_lld_print_max) {
+			MR_lld_print_region_enabled = 0;
+			MR_setup_call_intervals(&MR_lld_print_more_min_max,
+				&MR_lld_print_min, &MR_lld_print_max);
+			printf("leaving printed region\n");
+			printf("min %lu, max %lu, more <%s>\n",
+				MR_lld_print_min, MR_lld_print_max,
+				MR_lld_print_more_min_max);
+		
+		}
+	}
+
+	if (MR_proc_matches_name(proc, MR_lld_start_name)) {
+		MR_lld_print_name_enabled = 1;
+		MR_lld_start_until = MR_lld_cur_call + MR_lld_start_block;
+		printf("entering printed name block %s\n", MR_lld_start_name);
+	} else if (MR_lld_cur_call == MR_lld_start_until) {
+		MR_lld_print_name_enabled = 0;
+		printf("leaving printed name block\n");
+	}
+
+#ifdef	MR_DEEP_PROFILING
+	if (MR_watch_csd_addr == MR_next_call_site_dynamic
+		&& MR_watch_csd_addr != NULL)
+	{
+		MR_lld_print_csd_enabled = 1;
+		MR_lld_csd_until = MR_lld_cur_call + MR_lld_start_block;
+		MR_watch_csd_started = MR_TRUE;
+		printf("entering printed csd block %p\n", MR_watch_csd_addr);
+	} else if (MR_lld_cur_call == MR_lld_csd_until) {
+		MR_lld_print_csd_enabled = 0;
+		printf("leaving printed csd block\n");
+	}
+#endif
+
+	MR_lld_print_enabled = MR_lld_print_region_enabled
+		+ MR_lld_print_name_enabled + MR_lld_print_csd_enabled;
+}
+
 void 
 MR_printint(MR_Word n)
 {
@@ -309,26 +464,16 @@
 
 	printf("\n%s\n", msg);
 
+	if (MR_sregdebug) {
 	printf("%-9s", "succip:");  MR_printlabel(stdout, MR_succip);
 	printf("%-9s", "curfr:");   MR_printnondstack(MR_curfr);
 	printf("%-9s", "maxfr:");   MR_printnondstack(MR_maxfr);
 	printf("%-9s", "hp:");      MR_printheap(MR_hp);
 	printf("%-9s", "sp:");      MR_printdetstack(MR_sp);
-
-	MR_print_ordinary_regs();
-
-	if (MR_watch_addr != NULL) {
-		printf("watch addr %p: 0x%lx %ld\n", MR_watch_addr,
-			(long) *MR_watch_addr, (long) *MR_watch_addr);
 	}
 
-	if (MR_watch_csd_addr != NULL) {
-		if (MR_watch_csd_ignore == 0) {
-			MR_print_deep_prof_var(stdout, "watch_csd",
-				(MR_CallSiteDynamic *) MR_watch_csd_addr);
-		} else {
-			MR_watch_csd_ignore--;
-		}
+	if (MR_ordregdebug) {
+		MR_print_ordinary_regs();
 	}
 }
 
@@ -353,6 +498,164 @@
 
 		printf("%ld %lx\n", (long) value, (long) value);
 	}
+}
+
+#ifdef	MR_DEEP_PROFILING
+
+static struct MR_CallSiteDynamic_Struct	MR_watched_csd_last_value =
+{
+	/* MR_csd_callee_ptr */ NULL,
+	{ 
+  #ifdef MR_DEEP_PROFILING_PORT_COUNTS
+    #ifdef MR_DEEP_PROFILING_EXPLICIT_CALL_COUNTS
+	/* MR_own_calls */ 0,
+    #else
+	/* calls are computed from the other fields */
+    #endif
+	/* MR_own_exits */ 0,
+	/* MR_own_fails */ 0,
+	/* MR_own_redos */ 0,
+  #endif
+  #ifdef MR_DEEP_PROFILING_TIMING
+	/* MR_own_quanta */ 0,
+  #endif
+  #ifdef MR_DEEP_PROFILING_MEMORY
+	/* MR_own_allocs */ 0,
+	/* MR_own_words */ 0,
+  #endif
+	},
+	/* MR_csd_depth_count */ 0
+};
+
+static void
+MR_check_watch_csd_start(MR_Code *proc)
+{
+#if 0
+	if (MR_watch_csd_start_name == NULL) {
+		return;
+	}
+
+	if (MR_proc_matches_name(proc, MR_watch_csd_start_name)) {
+		if (MR_watch_csd_addr == MR_next_call_site_dynamic) {
+			/*
+			** Optimize future checks and make
+			** MR_watch_csd_addr static.
+			*/
+			MR_watch_csd_started = MR_TRUE;
+			MR_watch_csd_start_name = NULL;
+		}
+	}
+#endif
+}
+
+static MR_bool
+MR_csds_are_different(MR_CallSiteDynamic *csd1, MR_CallSiteDynamic *csd2)
+{
+	MR_ProfilingMetrics *pm1;
+	MR_ProfilingMetrics *pm2;
+
+	if (csd1->MR_csd_callee_ptr != csd2->MR_csd_callee_ptr)
+		return MR_TRUE;
+
+	pm1 = &csd1->MR_csd_own;
+	pm2 = &csd2->MR_csd_own;
+
+  #ifdef MR_DEEP_PROFILING_PORT_COUNTS
+    #ifdef MR_DEEP_PROFILING_EXPLICIT_CALL_COUNTS
+	if (pm1->MR_own_calls != pm2->MR_own_calls)
+		return MR_TRUE;
+    #endif
+	if (pm1->MR_own_exits != pm2->MR_own_exits)
+		return MR_TRUE;
+	if (pm1->MR_own_fails != pm2->MR_own_fails)
+		return MR_TRUE;
+	if (pm1->MR_own_redos != pm2->MR_own_redos)
+		return MR_TRUE;
+  #endif
+  #ifdef MR_DEEP_PROFILING_TIMING
+	if (pm1->MR_own_quanta != pm2->MR_own_quanta)
+		return MR_TRUE;
+  #endif
+  #ifdef MR_DEEP_PROFILING_MEMORY
+	if (pm1->MR_own_allocs != pm2->MR_own_allocs)
+		return MR_TRUE;
+	if (pm1->MR_own_words != pm2->MR_own_words)
+		return MR_TRUE;
+  #endif
+
+	if (csd1->MR_csd_depth_count != csd2->MR_csd_depth_count)
+		return MR_TRUE;
+
+	return MR_FALSE;
+};
+
+static void
+MR_assign_csd(MR_CallSiteDynamic *csd1, MR_CallSiteDynamic *csd2)
+{
+	csd1->MR_csd_callee_ptr = csd2->MR_csd_callee_ptr;
+
+  #ifdef MR_DEEP_PROFILING_PORT_COUNTS
+    #ifdef MR_DEEP_PROFILING_EXPLICIT_CALL_COUNTS
+	csd1->MR_csd_own.MR_own_calls = csd2->MR_csd_own.MR_own_calls;
+    #endif
+	csd1->MR_csd_own.MR_own_exits = csd2->MR_csd_own.MR_own_exits;
+	csd1->MR_csd_own.MR_own_fails = csd2->MR_csd_own.MR_own_fails;
+	csd1->MR_csd_own.MR_own_redos = csd2->MR_csd_own.MR_own_redos;
+  #endif
+  #ifdef MR_DEEP_PROFILING_TIMING
+	/* MR_own_quanta */ 0,
+	csd1->MR_csd_own.MR_own_quanta = csd2->MR_csd_own.MR_own_quanta;
+  #endif
+  #ifdef MR_DEEP_PROFILING_MEMORY
+	csd1->MR_csd_own.MR_own_allocs = csd2->MR_csd_own.MR_own_allocs;
+	csd1->MR_csd_own.MR_own_words = csd2->MR_csd_own.MR_own_words;
+  #endif
+
+	csd1->MR_csd_depth_count = csd2->MR_csd_depth_count;
+};
+
+#endif	/* MR_DEEP_PROFILING */
+
+static void
+MR_do_watches(void)
+{
+	if (MR_watch_addr != NULL) {
+		printf("watch addr %p: 0x%lx %ld\n", MR_watch_addr,
+			(long) *MR_watch_addr, (long) *MR_watch_addr);
+	}
+
+#ifdef	MR_DEEP_PROFILING
+	if (MR_watch_csd_addr != NULL) {
+		if (MR_watch_csd_started) {
+			if (MR_csds_are_different(&MR_watched_csd_last_value,
+				MR_watch_csd_addr))
+			{
+				MR_assign_csd(&MR_watched_csd_last_value,
+					MR_watch_csd_addr);
+				printf("current call: %lu\n", MR_lld_cur_call);
+				MR_print_deep_prof_var(stdout, "watch_csd",
+					MR_watch_csd_addr);
+			}
+		}
+	}
+#endif	/* MR_DEEP_PROFILING */
+}
+
+static MR_bool
+MR_proc_matches_name(MR_Code *proc, const char *name)
+{
+#ifdef	MR_NEED_ENTRY_LABEL_ARRAY
+	MR_Entry	*entry;
+
+	entry = MR_prev_entry_by_addr(proc);
+	if (entry != NULL && entry->e_addr == proc && entry->e_name != NULL) {
+		if (MR_streq(entry->e_name, name)) {
+			return MR_TRUE;
+		}
+	}
+
+#endif	/* MR_NEED_ENTRY_LABEL_ARRAY */
+	return MR_FALSE;
 }
 
 #endif /* defined(MR_DEBUG_GOTOS) */
Index: runtime/mercury_debug.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_debug.h,v
retrieving revision 1.14
diff -u -b -r1.14 mercury_debug.h
--- runtime/mercury_debug.h	2002/08/09 05:26:48	1.14
+++ runtime/mercury_debug.h	2002/08/11 13:58:37
@@ -137,9 +137,9 @@
 #define	MR_print_deep_prof_vars(fp, msg)				\
 	do {								\
 		fprintf(fp, "%s\n", msg);				\
-		MR_print_deep_prof_var(fp, "current_call_site_dynamic", \
+		MR_print_deep_prof_var(fp, "curcsd", 			\
 			MR_current_call_site_dynamic);			\
-		MR_print_deep_prof_var(fp, "next_call_site_dynamic",	\
+		MR_print_deep_prof_var(fp, "nextcsd",			\
 			MR_next_call_site_dynamic);			\
 	} while (0)
 
Index: runtime/mercury_deep_call_port_body.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_deep_call_port_body.h,v
retrieving revision 1.3
diff -u -b -r1.3 mercury_deep_call_port_body.h
--- runtime/mercury_deep_call_port_body.h	2002/08/07 03:18:55	1.3
+++ runtime/mercury_deep_call_port_body.h	2002/08/12 05:06:04
@@ -40,7 +40,7 @@
 	MR_enter_instrumentation();
 
   #ifdef MR_DEEP_PROFILING_LOWLEVEL_DEBUG
-	if (MR_calldebug) {
+	if (MR_calldebug && MR_lld_print_enabled) {
 		MR_print_deep_prof_vars(stdout, MR_PROCNAME);
 	}
   #endif
@@ -71,7 +71,7 @@
 
   #if defined(MR_VERSION_AC)
     #ifdef MR_USE_ACTIVATION_COUNTS
-	MR_deep_assert(ps->MR_ps_activation_count == 0
+	MR_deep_assert(csd, ps, ps->MR_ps_activation_count == 0
 		|| ps->MR_ps_outermost_activation_ptr != NULL);
 
       #ifdef MR_DEEP_PROFILING_STATISTICS
Index: runtime/mercury_deep_leave_port_body.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_deep_leave_port_body.h,v
retrieving revision 1.2
diff -u -b -r1.2 mercury_deep_leave_port_body.h
--- runtime/mercury_deep_leave_port_body.h	2001/05/31 06:00:11	1.2
+++ runtime/mercury_deep_leave_port_body.h	2002/08/12 05:06:28
@@ -1,5 +1,5 @@
 /*
-** Copyright (C) 2001 The University of Melbourne.
+** Copyright (C) 2001-2002 The University of Melbourne.
 ** This file may only be copied under the terms of the GNU Library General
 ** Public License - see the file COPYING.LIB in the Mercury distribution.
 */
@@ -12,7 +12,7 @@
 ** MR_PROCNAME:			The name of the procedure whose body this is.
 ** MR_FAIL_PORT or MR_EXIT_PORT:
 ** 				Says which field to increment and whether the
-**				procedure is has detism det or failure.
+**				procedure has detism det or failure.
 ** MR_VERSION_AC or MR_VERSION_SR:
 ** 				Says whether the procedure whose body this is
 **				is intended for use with or without
@@ -35,7 +35,7 @@
 	MR_enter_instrumentation();
 
 	csd = (MR_CallSiteDynamic *) MiddleCSD;
-	MR_deep_assert(csd == MR_current_call_site_dynamic);
+	MR_deep_assert(csd, NULL, csd == MR_current_call_site_dynamic);
 
   #ifdef MR_DEEP_PROFILING_PORT_COUNTS
 	/* increment exit/fail count */
@@ -48,15 +48,15 @@
     #endif
   #endif
 
-	MR_deep_assert(csd->MR_csd_callee_ptr != NULL);
+	MR_deep_assert(csd, NULL, csd->MR_csd_callee_ptr != NULL);
 	ps = csd->MR_csd_callee_ptr->MR_pd_proc_static;
-	MR_deep_assert(ps != NULL);
+	MR_deep_assert(csd, ps, ps != NULL);
 
   #if defined(MR_VERSION_AC)
     #ifdef MR_USE_ACTIVATION_COUNTS
 	/* decrement activation count */
 	ps->MR_ps_activation_count--;
-	MR_deep_assert(ps->MR_ps_activation_count >= 0);
+	MR_deep_assert(csd, ps, ps->MR_ps_activation_count >= 0);
     #else
 	MR_fatal_error(MR_PROCNAME ": MR_USE_ACTIVATION_COUNTS not enabled");
     #endif
Index: runtime/mercury_deep_profiling.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_deep_profiling.c,v
retrieving revision 1.8
diff -u -b -r1.8 mercury_deep_profiling.c
--- runtime/mercury_deep_profiling.c	2002/02/18 07:01:15	1.8
+++ runtime/mercury_deep_profiling.c	2002/08/12 05:12:39
@@ -119,12 +119,27 @@
 #endif	/* MR_DEEP_PROFILING_STATISTICS */
 
 void
-MR_deep_assert_failed(const char *cond, const char *filename, int linenumber)
+MR_deep_assert_failed(const MR_CallSiteDynamic *csd, const MR_ProcStatic *ps,
+	const char *cond, const char *filename, int linenumber)
 {
 	char	buf[1024];
+	char	bufcsd[1024];
+	char	bufps[1024];
 
-	sprintf(buf, "Deep profiling assertion failed, %s:%d\n%s\n",
-		filename, linenumber, cond);
+	if (csd != NULL) {
+		sprintf(bufcsd, ", csd %p\n", csd);
+	} else {
+		strcpy(bufcsd, "");
+	}
+
+	if (ps != NULL) {
+		sprintf(bufps, ", ps %p\n", ps);
+	} else {
+		strcpy(bufps, "");
+	}
+
+	sprintf(buf, "Deep profiling assertion failed, %s:%d\n%s%s%s\n",
+		filename, linenumber, cond, bufcsd, bufps);
 	MR_fatal_error(buf);
 }
 
@@ -354,7 +369,8 @@
 
 	MR_write_out_proc_static(fp,
 		(MR_ProcStatic *) &MR_main_parent_proc_static);
-	MR_deep_assert(MR_address_of_write_out_proc_statics != NULL);
+	MR_deep_assert(NULL, NULL,
+		MR_address_of_write_out_proc_statics != NULL);
 	(*MR_address_of_write_out_proc_statics)(fp);
 
 	if (fseek(fp, 0L, SEEK_SET) != 0) {
@@ -745,7 +761,7 @@
 	MR_deep_num_csd_nodes++;
 #endif
 
-	MR_deep_assert(csd->MR_csd_callee_ptr != NULL);
+	MR_deep_assert(csd, NULL, csd->MR_csd_callee_ptr != NULL);
 
 #ifdef MR_DEEP_PROFILING_DEBUG
 	fprintf(debug_fp, "call_site_dynamic %p: callee proc_dynamic %p\n",
@@ -1017,7 +1033,7 @@
 	fprintf(debug_fp, "num: %ld\n", num);
 #endif
 
-	MR_deep_assert((int) num >= 0);
+	MR_deep_assert(NULL, NULL, (int) num >= 0);
 
 	i = 0;
 	do {
@@ -1043,7 +1059,7 @@
 	fprintf(debug_fp, "fixed_size_int: %ld\n", num);
 #endif
 
-	MR_deep_assert((int) num >= 0);
+	MR_deep_assert(NULL, NULL, (int) num >= 0);
 
 	for (i = 0; i < MR_FIXED_SIZE_INT_BYTES; i++) {
 		putc(num & ((1 << 8) - 1), fp);
Index: runtime/mercury_deep_profiling.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_deep_profiling.h,v
retrieving revision 1.8
diff -u -b -r1.8 mercury_deep_profiling.h
--- runtime/mercury_deep_profiling.h	2002/08/09 05:26:48	1.8
+++ runtime/mercury_deep_profiling.h	2002/08/12 05:12:27
@@ -301,15 +301,15 @@
 	} while (0)
 
 #ifdef	MR_DEEP_CHECKS
-  #define MR_deep_assert(cond)						\
+  #define MR_deep_assert(csd, ps, cond)					\
  	do {								\
 		if (!(cond)) {						\
-			MR_deep_assert_failed(MR_STRINGIFY(cond),	\
+			MR_deep_assert_failed(csd, ps, MR_STRINGIFY(cond),\
 				__FILE__, __LINE__);			\
 		}							\
 	} while (0)
 #else
-  #define MR_deep_assert(cond)						\
+  #define MR_deep_assert(csd, ps, cond)					\
   	((void) 0)
 #endif
 
@@ -347,7 +347,8 @@
 
 #endif	/* MR_DEEP_PROFILING_STATISTICS */
 
-extern	void	MR_deep_assert_failed(const char *cond,
+extern	void	MR_deep_assert_failed(const MR_CallSiteDynamic *csd,
+			const MR_ProcStatic *ps, const char *cond,
 			const char *filename, int linenumber);
 extern	void	MR_setup_callback(void *entry);
 extern	void	MR_write_out_proc_static(FILE *fp, const MR_ProcStatic *ptr);
Index: runtime/mercury_deep_rec_depth_actions.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_deep_rec_depth_actions.h,v
retrieving revision 1.2
diff -u -b -r1.2 mercury_deep_rec_depth_actions.h
--- runtime/mercury_deep_rec_depth_actions.h	2001/06/05 04:57:09	1.2
+++ runtime/mercury_deep_rec_depth_actions.h	2002/08/12 05:07:43
@@ -23,7 +23,7 @@
 	do {								\
 		MR_CallSiteDynamic	*inner_csd;			\
 									\
-		MR_deep_assert(csn <= ps->MR_ps_num_call_sites);	\
+		MR_deep_assert(NULL, ps, csn <= ps->MR_ps_num_call_sites);\
 		inner_csd = pd->MR_pd_call_site_ptr_ptrs[csn];		\
 									\
 		if (inner_csd != NULL) {				\
@@ -37,7 +37,7 @@
 	do {								\
 		MR_CallSiteDynamic	*inner_csd;			\
 									\
-		MR_deep_assert(csn <= ps->MR_ps_num_call_sites);	\
+		MR_deep_assert(NULL, ps, csn <= ps->MR_ps_num_call_sites);\
 		inner_csd = pd->MR_pd_call_site_ptr_ptrs[csn];		\
 									\
 		if (inner_csd != NULL) {				\
@@ -48,7 +48,7 @@
 			inner_csd->MR_csd_own.inc_field += inner_count;	\
 			inner_csd->MR_csd_depth_count = outer_count;	\
 		} else {						\
-			MR_deep_assert(outer_count == 0);		\
+			MR_deep_assert(inner_csd, ps, outer_count == 0);\
 		}							\
 	} while (0)
 
Index: runtime/mercury_deep_rec_depth_body.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_deep_rec_depth_body.h,v
retrieving revision 1.2
diff -u -b -r1.2 mercury_deep_rec_depth_body.h
--- runtime/mercury_deep_rec_depth_body.h	2001/06/05 04:57:09	1.2
+++ runtime/mercury_deep_rec_depth_body.h	2002/08/12 05:07:53
@@ -33,11 +33,11 @@
 
 	MR_enter_instrumentation();
 	csd = (MR_CallSiteDynamic *) CSD;
-	MR_deep_assert(csd == MR_current_call_site_dynamic);
+	MR_deep_assert(csd, NULL, csd == MR_current_call_site_dynamic);
 	pd = csd->MR_csd_callee_ptr;
-	MR_deep_assert(pd != NULL);
+	MR_deep_assert(csd, NULL, pd != NULL);
 	ps = pd->MR_pd_proc_static;
-	MR_deep_assert(ps != NULL);
+	MR_deep_assert(csd, ps, ps != NULL);
 
 	MR_REC_DEPTH_BODY
 
Index: runtime/mercury_deep_redo_port_body.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_deep_redo_port_body.h,v
retrieving revision 1.2
diff -u -b -r1.2 mercury_deep_redo_port_body.h
--- runtime/mercury_deep_redo_port_body.h	2001/05/31 06:00:12	1.2
+++ runtime/mercury_deep_redo_port_body.h	2002/08/12 05:06:41
@@ -38,9 +38,9 @@
   #endif
 
 	pd = csd->MR_csd_callee_ptr;
-	MR_deep_assert(pd != NULL);
+	MR_deep_assert(csd, NULL, pd != NULL);
 	ps = pd->MR_pd_proc_static;
-	MR_deep_assert(ps != NULL);
+	MR_deep_assert(csd, ps, ps != NULL);
 
   #if defined(MR_VERSION_AC)
     #ifdef MR_USE_ACTIVATION_COUNTS
Index: runtime/mercury_engine.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_engine.h,v
retrieving revision 1.25
diff -u -b -r1.25 mercury_engine.h
--- runtime/mercury_engine.h	2002/08/02 08:13:34	1.25
+++ runtime/mercury_engine.h	2002/08/11 15:15:42
@@ -51,8 +51,10 @@
 #define	MR_TABLESTACKFLAG	12
 #define	MR_UNBUFFLAG		13
 #define	MR_AGC_FLAG 		14
-#define	MR_DETAILFLAG		15
-#define	MR_MAXFLAG		16
+#define	MR_ORDINARYREGFLAG	15
+#define	MR_ANYREGFLAG 		16
+#define	MR_DETAILFLAG		17
+#define	MR_MAXFLAG		18
 /* MR_DETAILFLAG should be the last real flag */
 
 #define	MR_progdebug		MR_debugflag[MR_PROGFLAG]
@@ -69,8 +71,10 @@
 #define	MR_hashdebug		MR_debugflag[MR_TABLEHASHFLAG]
 #define	MR_tablestackdebug	MR_debugflag[MR_TABLESTACKFLAG]
 #define	MR_unbufdebug		MR_debugflag[MR_UNBUFFLAG]
-#define	MR_detaildebug		MR_debugflag[MR_DETAILFLAG]
 #define	MR_agc_debug		MR_debugflag[MR_AGC_FLAG]
+#define	MR_ordregdebug		MR_debugflag[MR_ORDINARYREGFLAG]
+#define	MR_anyregdebug		MR_debugflag[MR_ANYREGFLAG]
+#define	MR_detaildebug		MR_debugflag[MR_DETAILFLAG]
 
 	/* 
 	** MR_setjmp and MR_longjmp are wrappers around setjmp and longjmp 
Index: runtime/mercury_wrapper.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_wrapper.c,v
retrieving revision 1.107
diff -u -b -r1.107 mercury_wrapper.c
--- runtime/mercury_wrapper.c	2002/08/02 08:13:34	1.107
+++ runtime/mercury_wrapper.c	2002/08/12 08:12:12
@@ -110,8 +110,26 @@
 
 MR_bool		MR_check_space = MR_FALSE;
 MR_Word		*MR_watch_addr = NULL;
-MR_Word		*MR_watch_csd_addr = NULL;
-int		MR_watch_csd_ignore = 0;
+MR_CallSiteDynamic
+		*MR_watch_csd_addr = NULL;
+MR_bool		MR_watch_csd_started = MR_FALSE;
+char		*MR_watch_csd_start_name = NULL;
+
+unsigned long	MR_lld_cur_call = 0;
+int		MR_lld_print_enabled = 1;
+int		MR_lld_print_name_enabled = 0;
+int		MR_lld_print_csd_enabled = 0;
+int		MR_lld_print_region_enabled = 0;
+
+char		*MR_lld_start_name = NULL;
+unsigned	MR_lld_start_block = 100;
+unsigned long	MR_lld_start_until = (unsigned long) -1;
+
+unsigned long	MR_lld_csd_until = (unsigned long) -1;
+
+unsigned long	MR_lld_print_min = (unsigned long) -1;
+unsigned long	MR_lld_print_max = 0;
+char		*MR_lld_print_more_min_max = NULL;
 
 static	MR_bool	benchmark_all_solns = MR_FALSE;
 static	MR_bool	use_own_timer = MR_FALSE;
@@ -952,6 +970,12 @@
 #endif
 			} else if (MR_streq(MR_optarg, "b")) {
 				MR_nondstackdebug = MR_TRUE;
+			} else if (MR_streq(MR_optarg, "B")) {
+				if (sscanf(MR_optarg+1, "%u",
+					&MR_lld_start_block) != 1)
+				{
+					usage();
+				}
 			} else if (MR_streq(MR_optarg, "c")) {
 				MR_calldebug    = MR_TRUE;
 			} else if (MR_streq(MR_optarg, "d")) {
@@ -972,20 +996,30 @@
 				MR_heapdebug    = MR_TRUE;
 			} else if (MR_streq(MR_optarg, "H")) {
 				MR_hashdebug    = MR_TRUE;
+			} else if (MR_optarg[0] == 'i') {
+				MR_lld_print_more_min_max =
+					strdup(MR_optarg + 1);
+				MR_setup_call_intervals(
+					&MR_lld_print_more_min_max,
+					&MR_lld_print_min, &MR_lld_print_max);
 			} else if (MR_optarg[0] == 'I') {
-				int	ignore;
-
-				if (sscanf(MR_optarg+1, "%u", &ignore) != 1) {
-					usage();
-				}
-
-				MR_watch_csd_ignore = ignore;
+				MR_watch_csd_start_name = strdup(MR_optarg+1);
+			} else if (MR_optarg[0] == 'j') {
+				MR_lld_start_name = strdup(MR_optarg+1);
 			} else if (MR_streq(MR_optarg, "m")) {
 				MR_memdebug     = MR_TRUE;
+			} else if (MR_streq(MR_optarg, "o")) {
+				MR_ordregdebug    = MR_TRUE;
 			} else if (MR_streq(MR_optarg, "p")) {
 				MR_progdebug    = MR_TRUE;
+			} else if (MR_streq(MR_optarg, "P")) {
+				MR_calldebug      = MR_TRUE;
+				MR_gotodebug      = MR_TRUE;
+				MR_finaldebug     = MR_TRUE;
 			} else if (MR_streq(MR_optarg, "r")) {
 				MR_sregdebug    = MR_TRUE;
+			} else if (MR_streq(MR_optarg, "R")) {
+				MR_anyregdebug    = MR_TRUE;
 			} else if (MR_streq(MR_optarg, "s")) {
 				MR_detstackdebug  = MR_TRUE;
 			} else if (MR_streq(MR_optarg, "S")) {
@@ -1015,11 +1049,19 @@
 					}
 				}
 
+				MR_anyregdebug = MR_TRUE;
 				if (MR_optarg[0] == 'w') {
 					MR_watch_addr = (MR_Word *) addr;
 				} else {
-					MR_watch_csd_addr = (MR_Word *) addr;
+					MR_watch_csd_addr =
+						(MR_CallSiteDynamic *) addr;
 				}
+
+				/*
+				** The watch code is called only from the
+				** debug messages controlled by MR_calldebug.
+				*/
+				MR_calldebug = MR_TRUE;
 			} else {
 				usage();
 			}
@@ -1109,6 +1151,10 @@
 		} /* end switch */
 	} /* end while */
 
+	if (MR_lld_print_min > 0 || MR_lld_start_name != NULL) {
+		MR_lld_print_enabled = 0;
+	}
+
 	if (MR_optind != argc) {
 		printf("The MERCURY_OPTIONS environment variable contains "
 			"the word `%s'\n"
@@ -1131,6 +1177,66 @@
 	fflush(stdout);
 	exit(1);
 } /* end usage() */
+
+void
+MR_setup_call_intervals(char **more_str_ptr,
+	unsigned long *min_ptr, unsigned long *max_ptr)
+{
+	char	*more_str;
+	int	n;
+
+	more_str = *more_str_ptr;
+	if (more_str == NULL || more_str[0] == '\0') {
+		goto end;
+	}
+
+	n = 0;
+	while (MR_isdigit(more_str[0])) {
+		n = n * 10 + more_str[0] - '0';
+		more_str++;
+	}
+
+	if (n == 0) {
+		goto end;
+	}
+
+	*min_ptr = n;
+	if (more_str[0] == '-' && more_str[1] == '\0') {
+		*max_ptr = (unsigned long) -1;
+		*more_str_ptr = NULL;
+		return;
+	}
+
+	if (more_str[0] != '-') {
+		goto end;
+	}
+
+	more_str++;
+
+	n = 0;
+	while (MR_isdigit(more_str[0])) {
+		n = n * 10 + more_str[0] - '0';
+		more_str++;
+	}
+
+	if (n == 0) {
+		goto end;
+	}
+
+	*max_ptr = n;
+	if (more_str[0] == ',') {
+		more_str++;
+	}
+
+	*more_str_ptr = more_str;
+	return;
+
+end:
+	*more_str_ptr = NULL;
+	*min_ptr = (unsigned long) -1;
+	*max_ptr = 0;
+	return;
+}
 
 /*---------------------------------------------------------------------------*/
 
Index: runtime/mercury_wrapper.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_wrapper.h,v
retrieving revision 1.52
diff -u -b -r1.52 mercury_wrapper.h
--- runtime/mercury_wrapper.h	2002/03/06 14:35:01	1.52
+++ runtime/mercury_wrapper.h	2002/08/12 08:03:20
@@ -229,8 +229,24 @@
 /* low level debugging */
 extern	MR_bool		MR_check_space;
 extern	MR_Word		*MR_watch_addr;
-extern	MR_Word		*MR_watch_csd_addr;
-extern	int		MR_watch_csd_ignore;
+extern	MR_CallSiteDynamic
+			*MR_watch_csd_addr;
+extern	MR_bool		MR_watch_csd_started;
+extern	char		*MR_watch_csd_start_name;
+
+extern	unsigned long	MR_lld_cur_call;
+extern	int		MR_lld_print_enabled;
+extern	int		MR_lld_print_name_enabled;
+extern	int		MR_lld_print_csd_enabled;
+extern	int		MR_lld_print_region_enabled;
+
+extern	char		*MR_lld_start_name;
+extern	unsigned	MR_lld_start_block;
+extern	unsigned long	MR_lld_start_until;
+extern	unsigned long	MR_lld_csd_until;
+extern	unsigned long	MR_lld_print_min;
+extern	unsigned long	MR_lld_print_max;
+extern	char		*MR_lld_print_more_min_max;
 
 /* timing */
 extern	int		MR_time_at_start;
@@ -264,5 +280,8 @@
 
 /* This is used by compiler/mlds_to_gcc.m. */
 const char *MR_make_argv(const char *, char **, char ***, int *);
+
+void		MR_setup_call_intervals(char **more_str_ptr,
+			unsigned long *min_ptr, unsigned long *max_ptr);
 
 #endif /* not MERCURY_WRAPPER_H */
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
Index: tools/lmc
===================================================================
RCS file: /home/mercury1/repository/mercury/tools/lmc,v
retrieving revision 1.8
diff -u -b -r1.8 lmc
--- tools/lmc	2002/08/07 13:12:11	1.8
+++ tools/lmc	2002/08/10 13:57:54
@@ -57,6 +57,18 @@
 	CDEBUG_FLAGS=""
 fi
 
+if test "$MMC_LOWLEVEL_DEBUG" != ""
+then
+	CDEBUG_FLAGS="$CDEBUG_FLAGS --cflags -DMR_LOWLEVEL_DEBUG"
+else
+	CDEBUG_FLAGS=""
+fi
+
+if test "$ADDED_CFLAGS" != ""
+then
+	CDEBUG_FLAGS="$CDEBUG_FLAGS --cflags \"$ADDED_CFLAGS\""
+fi
+
 C_FLAGS="--c-include-directory $WORKSPACE/trace --c-include-directory $WORKSPACE/library --c-include-directory $WORKSPACE/library/Mercury/mihs --c-include-directory $WORKSPACE/runtime --c-include-directory $WORKSPACE/boehm_gc --c-include-directory $WORKSPACE/boehm_gc/include"
 
 if test "$MMC_UNDER_GDB" != ""
cvs diff: Diffing trace
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list