[m-dev.] for review: fix for a bug reported by Warwick

Zoltan Somogyi zs at cs.mu.OZ.AU
Tue Jan 25 14:17:20 AEDT 2000


Warwick should test this out on his real test case, not just the cut-down
one he sent me.

Fix a bug reported by Warwick. When compiling with --use-trail --trace shallow,
the compiler was performing a store_ticket() operation only conditionally on
MR_from_full but was performing the matching discard_ticket() uncondtitionally.

compiler/trace.m:
	Add a predicate to undo the effects of the slot fill code (meaning
	the store_ticket()).

compiler/code_gen.m:
	Use the new pred in trace.m, instead of the incorrect code now in
	code_gen.m itself.

Zoltan.

cvs diff: Diffing .
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/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/code_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/code_gen.m,v
retrieving revision 1.71
diff -u -b -r1.71 code_gen.m
--- code_gen.m	1999/12/14 04:52:31	1.71
+++ code_gen.m	2000/01/25 02:37:33
@@ -362,7 +362,7 @@
 		code_gen__generate_entry(model_det, Goal, ResumePoint,
 			FrameInfo, EntryCode),
 		code_gen__generate_exit(model_det, FrameInfo, TraceSlotInfo,
-			BodyContext, _, ExitCode),
+			BodyContext, _, _, ExitCode),
 		{ Code =
 			tree(EntryCode,
 			tree(TraceCallCode,
@@ -391,7 +391,8 @@
 		code_gen__generate_entry(model_semi, Goal, ResumePoint,
 			FrameInfo, EntryCode),
 		code_gen__generate_exit(model_semi, FrameInfo, TraceSlotInfo,
-			BodyContext, RestoreDeallocCode, ExitCode),
+			BodyContext, RestoreDeallocCode, UndoFillCode,
+			ExitCode),
 
 		code_info__generate_resume_point(ResumePoint, ResumeCode),
 		{ code_info__resume_point_vars(ResumePoint, ResumeVarList) },
@@ -409,7 +410,8 @@
 			tree(ResumeCode,
 			tree(TraceFailCode,
 			tree(RestoreDeallocCode,
-			     FailCode)))))))
+			tree(UndoFillCode,
+			     FailCode))))))))
 		}
 	;
 		{ MaybeTraceCallLabel = no },
@@ -417,7 +419,7 @@
 		code_gen__generate_entry(model_semi, Goal, ResumePoint,
 			FrameInfo, EntryCode),
 		code_gen__generate_exit(model_semi, FrameInfo, TraceSlotInfo,
-			BodyContext, RestoreDeallocCode, ExitCode),
+			BodyContext, RestoreDeallocCode, _, ExitCode),
 		code_info__generate_resume_point(ResumePoint, ResumeCode),
 		{ Code =
 			tree(EntryCode,
@@ -443,7 +445,7 @@
 		code_gen__generate_entry(model_non, Goal, ResumePoint,
 			FrameInfo, EntryCode),
 		code_gen__generate_exit(model_non, FrameInfo, TraceSlotInfo,
-			BodyContext, _, ExitCode),
+			BodyContext, _, UndoFillCode, ExitCode),
 
 		code_info__generate_resume_point(ResumePoint, ResumeCode),
 		{ code_info__resume_point_vars(ResumePoint, ResumeVarList) },
@@ -453,13 +455,6 @@
 			% definition would be better than BodyContext.
 		trace__generate_external_event_code(fail, TraceInfo,
 			BodyContext, _, _, TraceFailCode),
-		{ TraceSlotInfo = trace_slot_info(_, _, yes(_)) ->
-			DiscardTraceTicketCode = node([
-				discard_ticket - "discard retry ticket"
-			])
-		;
-			DiscardTraceTicketCode = empty
-		},
 		{ FailCode = node([
 			goto(do_fail) - "fail after fail trace port"
 		]) },
@@ -470,7 +465,7 @@
 			tree(ExitCode,
 			tree(ResumeCode,
 			tree(TraceFailCode,
-			tree(DiscardTraceTicketCode,
+			tree(UndoFillCode,
 			     FailCode)))))))
 		}
 	;
@@ -479,7 +474,7 @@
 		code_gen__generate_entry(model_non, Goal, ResumePoint,
 			FrameInfo, EntryCode),
 		code_gen__generate_exit(model_non, FrameInfo, TraceSlotInfo,
-			BodyContext, _, ExitCode),
+			BodyContext, _, _, ExitCode),
 		{ Code =
 			tree(EntryCode,
 			tree(BodyCode,
@@ -633,6 +628,8 @@
 	%	a comment to mark epilogue start
 	%	code to place the output arguments where their caller expects
 	%	code to restore registers from some special slots
+	%	code to undo any actions during trace slot filling
+	%		that need to be undone on success
 	%	code to deallocate the stack frame
 	%	code to set r1 to TRUE (for semidet procedures only)
 	%	a jump back to the caller, including livevals information
@@ -642,6 +639,10 @@
 	% frame are also part of the failure epilog, which is handled by
 	% our caller; this is why we return RestoreDeallocCode.
 	%
+	% For a similar reason, we also return FailUndoCode, which contains
+	% the code to undo the actions during trace slot filling that may
+	% need to be done only in the failure epilog.
+	%
 	% At the moment the only special slots are the succip slot, and
 	% the tracing slots (holding the call sequence number, call event
 	% number, call depth, from-full indication, and trail state).
@@ -657,10 +658,10 @@
 
 :- pred code_gen__generate_exit(code_model::in, frame_info::in,
 	trace_slot_info::in, prog_context::in, code_tree::out, code_tree::out,
-	code_info::in, code_info::out) is det.
+	code_tree::out, code_info::in, code_info::out) is det.
 
 code_gen__generate_exit(CodeModel, FrameInfo, TraceSlotInfo, BodyContext,
-		RestoreDeallocCode, ExitCode) -->
+		RestoreDeallocCode, FailureUndoSlotFillCode, ExitCode) -->
 	{ StartComment = node([
 		comment("Start of procedure epilogue") - ""
 	]) },
@@ -676,7 +677,9 @@
 				will_not_call_mercury, no, no, no)
 				- ""
 		]) },
-		{ RestoreDeallocCode = empty },	% always empty for nondet code
+		{ RestoreDeallocCode = empty },
+		trace__undo_slot_fill_code(TraceSlotInfo, CodeModel,
+			_SuccessUndoSlotFillCode, FailureUndoSlotFillCode),
 		{ ExitCode =
 			tree(StartComment,
 			tree(UndefCode,
@@ -714,22 +717,10 @@
 				decr_sp(TotalSlots) - "Deallocate stack frame"
 			])
 		},
-		{
-			TraceSlotInfo = trace_slot_info(_, _, yes(_)),
-			CodeModel \= model_non
-		->
-			DiscardTraceTicketCode = node([
-				discard_ticket - "discard retry ticket"
-			])
-		;
-			DiscardTraceTicketCode = empty
-		},
 
-		{ RestoreDeallocCode =
-			tree(RestoreSuccipCode,
-			tree(DeallocCode,
-			     DiscardTraceTicketCode))
-		},
+		{ RestoreDeallocCode = tree(RestoreSuccipCode, DeallocCode) },
+		trace__undo_slot_fill_code(TraceSlotInfo, CodeModel,
+			SuccessUndoSlotFillCode, FailureUndoSlotFillCode),
 
 		code_info__get_maybe_trace_info(MaybeTraceInfo),
 		( { MaybeTraceInfo = yes(TraceInfo) } ->
@@ -771,7 +762,8 @@
 			{ AllSuccessCode =
 				tree(TraceExitCode,
 				tree(RestoreDeallocCode,
-				     SuccessCode))
+				tree(SuccessUndoSlotFillCode,
+				     SuccessCode)))
 			}
 		;
 			{ CodeModel = model_semi },
@@ -784,7 +776,8 @@
 			{ AllSuccessCode =
 				tree(TraceExitCode,
 				tree(RestoreDeallocCode,
-				     SuccessCode))
+				tree(SuccessUndoSlotFillCode,
+				     SuccessCode)))
 			}
 		;
 			{ CodeModel = model_non },
Index: compiler/trace.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/trace.m,v
retrieving revision 1.29
diff -u -b -r1.29 trace.m
--- trace.m	1999/12/16 19:06:52	1.29
+++ trace.m	2000/01/25 02:54:50
@@ -122,6 +122,13 @@
 :- pred trace__generate_slot_fill_code(trace_info::in, code_tree::out,
 	code_info::in, code_info::out) is det.
 
+	% Generate two code sequences to undo whatever effects of the trace
+	% slot fill code need to be undone when we leave from the procedure:
+	% the first is for the success epilog, the second for the failure
+	% epilog.
+:- pred trace__undo_slot_fill_code(trace_slot_info::in, code_model::in,
+	code_tree::out, code_tree::out, code_info::in, code_info::out) is det.
+
 	% If we are doing execution tracing, generate code to prepare for
 	% a call.
 :- pred trace__prepare_for_call(code_tree::out, code_info::in, code_info::out)
@@ -425,6 +432,41 @@
 		pragma_c([], [pragma_c_raw_code(TraceStmt)],
 			will_not_call_mercury, no, no, yes) - ""
 	])
+	}.
+
+trace__undo_slot_fill_code(TraceSlotInfo, CodeModel,
+		SuccessUndoFillCode, FailureUndoFillCode) -->
+	code_info__get_maybe_trace_info(MaybeTraceInfo),
+	{
+		MaybeTraceInfo = yes(TraceInfo),
+		TraceSlotInfo = trace_slot_info(_, _, yes(_))
+	->
+		trace_info_get_trace_type(TraceInfo, TraceType),
+		(
+			TraceType = shallow_trace(CallFromFullSlot),
+			trace__stackref_to_string(CallFromFullSlot,
+				CallFromFullSlotStr),
+			string__append_list(["\tif (", CallFromFullSlotStr,
+				") {\n\t\tMR_discard_ticket();\n\t}"],
+				UndoStmt)
+		;
+			TraceType = deep_trace,
+			UndoStmt = "MR_discard_ticket();"
+		),
+		UndoFillCode = node([
+			pragma_c([], [pragma_c_raw_code(UndoStmt)],
+				will_not_call_mercury, no, no, yes) - ""
+		]),
+		( CodeModel = model_non ->
+			SuccessUndoFillCode = empty,
+			FailureUndoFillCode = UndoFillCode
+		;
+			SuccessUndoFillCode = UndoFillCode,
+			FailureUndoFillCode = UndoFillCode
+		)
+	;
+		SuccessUndoFillCode = empty,
+		FailureUndoFillCode = empty
 	}.
 
 trace__prepare_for_call(TraceCode) -->
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
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/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/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/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing library
cvs diff: Diffing profiler
cvs diff: Diffing runtime
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 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/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing trial
cvs diff: Diffing util
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list