more trailing changes

Fergus Henderson fjh at kryten.cs.mu.OZ.AU
Mon Aug 25 23:44:52 AEST 1997


Fix code generation for commits and nondet if-then-elses so that
it computes MR_ticket_counter correctly.

compiler/ite_gen.m:
compiler/code_info.m:
	Change the way we do a soft cut when generating code for nondet
	if-then-elses with nondet conditions so that the ticket counter
	is restored correctly on backtracking.

compiler/llds.m:
	Add new instructions `mark_trail_stack(lval)' and
	`discard_tickets_to(rval)' to save/restore the ticket counter.

compiler/code_info.m:
	Save the ticket counter before doing a commit and
	restore it afterwards.

compiler/*.m:
	Various minor changes to handle the new LLDS instructions.

runtime/mercury_trail.h:
	Add new macros to implement the new LLDS instructions.

compiler/livemap.m:
	Change the code in build_livemap_instr for mark_hp and
	store_ticket so that it deletes the target lval from the
	set of live variables, and simplify the code there for reset_ticket.

cvs diff: Diffing .
Index: code_info.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/code_info.m,v
retrieving revision 1.210
diff -u -u -r1.210 code_info.m
--- 1.210	1997/08/24 10:00:21
+++ code_info.m	1997/08/25 13:30:22
@@ -262,7 +262,10 @@
 					% in grades with trailing, it is four.)
 	).
 
-:- type lval_or_ticket  --->	ticket ; lval(lval).
+:- type lval_or_ticket 
+	--->	ticket			% a ticket (trail pointer)
+	;	ticket_counter		% a copy of the ticket counter
+	;	lval(lval).
 
 %---------------------------------------------------------------------------%
 
@@ -1039,12 +1042,21 @@
 :- pred code_info__may_use_nondet_tailcall(bool, code_info, code_info).
 :- mode code_info__may_use_nondet_tailcall(out, in, out) is det.
 
-	% do_soft_cut takes the lval where the address of the
+	% do_soft_cut(NondetFrameLvalAddress, SoftCutCode, SoftCutContCode)
+	% takes the lval where the address of the
 	% failure frame is stored, and it returns code to
-	% set the redoip of that frame to do_fail.
-
-:- pred code_info__do_soft_cut(lval, code_tree, code_info, code_info).
-:- mode code_info__do_soft_cut(in, out, in, out) is det.
+	% prune away the topmost choice point from that frame,
+	% typically by setting the redoip of that frame to do_fail.
+	% Note that the frame need not be the topmost frame -- a soft cut
+	% can prune away a single choice point from the middle.
+	% do_soft_cut also returns some additional code; in the case of
+	% trailing, the redoip will be set to point to that additional code,
+	% not to do_fail; the additional code will do a `discard_ticket'
+	% before branching to the usual failure continuation (e.g. do_fail).
+
+:- pred code_info__do_soft_cut(lval, code_tree, code_tree,
+			code_info, code_info).
+:- mode code_info__do_soft_cut(in, out, out, in, out) is det.
 
 	% `generate_semi_pre_commit' and `generate_semi_commit' should be
 	% called before and after generating the code for the nondet goal
@@ -1084,7 +1096,7 @@
 			lval,		% curfr
 			lval,		% maxfr
 			lval,		% redoip
-			maybe(lval)	% trail pointer
+			maybe(pair(lval, lval)) % ticket counter, trail pointer
 		).
 
 %---------------------------------------------------------------------------%
@@ -1823,7 +1835,7 @@
 
 %---------------------------------------------------------------------------%
 
-code_info__do_soft_cut(TheFrame, Code) -->
+code_info__do_soft_cut(TheFrame, Code, ContCode) -->
 	code_info__top_failure_cont(FailureCont),
 	{ FailureCont = failure_cont(ContInfo, _) },
 	(
@@ -1837,9 +1849,24 @@
 			% set its redoip to do_fail.
 		{ Address = do_fail }
 	),
+	code_info__get_globals(Globals),
+	{ globals__lookup_bool_option(Globals, use_trail, UseTrail) },
+	( { UseTrail = yes } ->
+		code_info__get_next_label(ContLabel),
+		{ ContAddress = label(ContLabel) },
+		{ ContCode = node([
+			label(ContLabel) - "soft cut failure cont entry point",
+			discard_ticket - "pop ticket stack",
+			goto(Address) - "branch to prev failure continuation"
+		]) }
+	;
+		{ ContAddress = Address },
+		{ ContCode = empty }
+	),
 	{ Code = node([
-		assign(redoip(lval(TheFrame)), const(code_addr_const(Address)))
-			- "prune away the `else' case of the if-then-else"
+		assign(redoip(lval(TheFrame)),
+			const(code_addr_const(ContAddress)))
+		- "prune away the `else' case of the if-then-else"
 	]) }.
 
 %---------------------------------------------------------------------------%
@@ -1940,9 +1967,9 @@
 	code_info__get_globals(Globals),
 	{ globals__lookup_bool_option(Globals, use_trail, UseTrail) },
 	( { UseTrail = yes } ->
-		{ NumSlots = 4 },
+		{ NumSlots = 5 },
 		{ SaveMessage =
-		  "push space for curfr, maxfr, redoip, and trail" }
+	"push space for curfr, maxfr, redoip, ticket_counter and trail_ptr" }
 	;
 		{ NumSlots = 3 },
 		{ SaveMessage = "push space for curfr, maxfr, and redoip" }
@@ -1966,13 +1993,15 @@
 		{ MaxfrSlot = stackvar(2) },
 		{ RedoipSlot = stackvar(3) },
 		( { UseTrail = yes } ->
-			{ TrailSlot = stackvar(4) },
-			{ MaybeTrailSlot = yes(TrailSlot) }
+			{ TicketCounterSlot = stackvar(4) },
+			{ TrailPtrSlot = stackvar(5) },
+			{ MaybeTrailSlots = yes(TicketCounterSlot -
+						TrailPtrSlot) }
 		;
-			{ MaybeTrailSlot = no }
+			{ MaybeTrailSlots = no }
 		),
 		{ Slots = commit_slots(CurfrSlot, MaxfrSlot, RedoipSlot,
-			MaybeTrailSlot) },
+			MaybeTrailSlots) },
 		code_info__add_commit_triple
 	;
 		{ PushCode = empty },
@@ -1981,13 +2010,16 @@
 		code_info__acquire_temp_slot(lval(redoip(lval(maxfr))),
 			RedoipSlot),
 		( { UseTrail = yes } ->
-			code_info__acquire_temp_slot(ticket, TrailSlot),
-			{ MaybeTrailSlot = yes(TrailSlot) }
+			code_info__acquire_temp_slot(ticket_counter,
+						TicketCounterSlot),
+			code_info__acquire_temp_slot(ticket, TrailPtrSlot),
+			{ MaybeTrailSlots = yes(TicketCounterSlot -
+						TrailPtrSlot) }
 		;
-			{ MaybeTrailSlot = no }
+			{ MaybeTrailSlots = no }
 		),
 		{ Slots = commit_slots(CurfrSlot, MaxfrSlot, RedoipSlot,
-			MaybeTrailSlot) }
+			MaybeTrailSlots) }
 	),
 	{ SaveCode = node([
 		assign(CurfrSlot, lval(curfr)) -
@@ -1997,9 +2029,12 @@
 		assign(RedoipSlot, lval(redoip(lval(maxfr)))) -
 				"Save the top redoip"
 	]) },
-	{ MaybeTrailSlot = yes(TheTrailSlot) ->
+	{ MaybeTrailSlots = yes(TheTicketCounterSlot - TheTrailPtrSlot) ->
 		MaybeSaveTrailCode = node([
-			store_ticket(TheTrailSlot) - "Save trail state"
+			mark_ticket_stack(TheTicketCounterSlot) -
+				"Save the ticket counter",
+			store_ticket(TheTrailPtrSlot) -
+				"Save the trail pointer"
 		])
 	;
 		MaybeSaveTrailCode = empty
@@ -2014,7 +2049,7 @@
 code_info__undo_pre_commit_saves(Slots, RestoreMaxfr, RestoreRedoip,
 		RestoreCurfr, SuccPopCode, FailPopCode) -->
 	{ Slots = commit_slots(CurfrSlot, MaxfrSlot, RedoipSlot,
-		MaybeTrailSlot) },
+		MaybeTrailSlots) },
 	{ RestoreMaxfr = node([
 		assign(maxfr, lval(MaxfrSlot)) -
 			"Prune away unwanted choice-points"
@@ -2030,10 +2065,26 @@
 	code_info__get_proc_model(CodeModel),
 	( { CodeModel = model_non } ->
 		code_info__rem_commit_triple,
-		( { MaybeTrailSlot = yes(_) } ->
-			{ NumSlots = 4 },
-			{ PopMessage = "pop curfr, maxfr, redoip, and trail" }
+		( { MaybeTrailSlots = yes(TicketCounterSlot - TrailPtrSlot) } ->
+			{ CommitTrail = node([
+				reset_ticket(lval(TrailPtrSlot), commit) -
+				"discard trail entries and restore trail ptr"
+			]) },
+			{ RestoreTrail = node([
+				reset_ticket(lval(TrailPtrSlot), undo) -
+				"apply trail entries and restore trail ptr"
+			]) },
+			{ RestoreTicketCounter = node([
+				discard_tickets_to(lval(TicketCounterSlot)) -
+				"restore the ticket counter"
+			]) },
+			{ NumSlots = 5 },
+			{ PopMessage =
+		     "pop curfr, maxfr, redoip, ticket_counter and trail_ptr" }
 		;
+			{ CommitTrail = empty },
+			{ RestoreTrail = empty },
+			{ RestoreTicketCounter = empty },
 			{ NumSlots = 3 },
 			{ PopMessage = "pop curfr, maxfr, and redoip" }
 		),
@@ -2044,21 +2095,36 @@
 		code_info__release_temp_slot(CurfrSlot),
 		code_info__release_temp_slot(MaxfrSlot),
 		code_info__release_temp_slot(RedoipSlot),
+		( { MaybeTrailSlots = yes(TicketCounterSlot - TrailPtrSlot) } ->
+			{ CommitTrail = node([
+				reset_ticket(lval(TicketCounterSlot), commit) -
+				"discard trail entries and restore trail ptr"
+			]) },
+			{ RestoreTrail = node([
+				reset_ticket(lval(TicketCounterSlot), undo) -
+				"apply trail entries and restore trail ptr"
+			]) },
+			{ RestoreTicketCounter = node([
+				discard_tickets_to(lval(TicketCounterSlot)) -
+				"restore the ticket counter"
+			]) },
+			code_info__release_temp_slot(TicketCounterSlot),
+			code_info__release_temp_slot(TrailPtrSlot)
+		;
+			{ CommitTrail = empty },
+			{ RestoreTrail = empty },
+			{ RestoreTicketCounter = empty }
+		),
 		{ MainPopCode = empty }
 	),
-	code_info__maybe_reset_ticket(MaybeTrailSlot, commit,
-		MaybeCommitTicket),
-	code_info__maybe_reset_ticket(MaybeTrailSlot, undo,
-		MaybeUndoTicket),
-	code_info__maybe_discard_ticket(MaybeTrailSlot, MaybeDiscardTicket),
 	{ SuccPopCode =
 		tree(MainPopCode,
-		tree(MaybeCommitTicket,
-		     MaybeDiscardTicket)) },
+		tree(CommitTrail,
+		     RestoreTicketCounter)) },
 	{ FailPopCode =
 		tree(MainPopCode,
-		tree(MaybeUndoTicket,
-		     MaybeDiscardTicket)) }.
+		tree(RestoreTrail,
+		     RestoreTicketCounter)) }.
 
 
 :- pred code_info__clone_resume_maps(resume_maps, resume_maps,
@@ -2867,7 +2933,10 @@
 code_info__get_live_value_type(lval(stackvar(_)), unwanted).
 code_info__get_live_value_type(lval(framevar(_)), unwanted).
 code_info__get_live_value_type(lval(mem_ref(_)), unwanted).		% XXX
-code_info__get_live_value_type(ticket, unwanted).
+code_info__get_live_value_type(ticket, unwanted). % XXX we may need to
+					% modify this, if the GC is going
+					% to garbage-collect the trail.
+code_info__get_live_value_type(ticket_counter, unwanted).
 
 %---------------------------------------------------------------------------%
 %---------------------------------------------------------------------------%
Index: dupelim.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/dupelim.m,v
retrieving revision 1.21
diff -u -u -r1.21 dupelim.m
--- 1.21	1997/08/24 03:18:29
+++ dupelim.m	1997/08/25 10:58:44
@@ -181,6 +181,12 @@
 		reset_ticket(Rval, Reason)) :-
 	dupelim__replace_labels_rval(Rval0, Replmap, Rval).
 dupelim__replace_labels_instr(discard_ticket, _, discard_ticket).
+dupelim__replace_labels_instr(mark_ticket_stack(Lval0), Replmap, 
+		mark_ticket_stack(Lval)) :-
+	dupelim__replace_labels_lval(Lval0, Replmap, Lval).
+dupelim__replace_labels_instr(discard_tickets_to(Rval0), Replmap, 
+		discard_tickets_to(Rval)) :-
+	dupelim__replace_labels_rval(Rval0, Replmap, Rval).
 dupelim__replace_labels_instr(incr_sp(Size, Msg), _, incr_sp(Size, Msg)).
 dupelim__replace_labels_instr(decr_sp(Size), _, decr_sp(Size)).
 dupelim__replace_labels_instr(pragma_c(A,B,C,D,E), _, pragma_c(A,B,C,D,E)).
Index: frameopt.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/frameopt.m,v
retrieving revision 1.62
diff -u -u -r1.62 frameopt.m
--- 1.62	1997/08/24 01:29:39
+++ frameopt.m	1997/08/25 11:01:05
@@ -683,6 +683,8 @@
 possible_targets(store_ticket(_), []).
 possible_targets(reset_ticket(_, _), []).
 possible_targets(discard_ticket, []).
+possible_targets(mark_ticket_stack(_), []).
+possible_targets(discard_tickets_to(_), []).
 possible_targets(incr_sp(_, _), []).
 possible_targets(decr_sp(_), []).
 possible_targets(pragma_c(_, _, _, _, _), []).
@@ -1293,6 +1295,8 @@
 substitute_labels_instr(store_ticket(Lval), _, store_ticket(Lval)).
 substitute_labels_instr(reset_ticket(Rval, Rsn), _, reset_ticket(Rval, Rsn)).
 substitute_labels_instr(discard_ticket, _, discard_ticket).
+substitute_labels_instr(mark_ticket_stack(Lval), _, mark_ticket_stack(Lval)).
+substitute_labels_instr(discard_tickets_to(Rval), _, discard_tickets_to(Rval)).
 substitute_labels_instr(incr_sp(Size, Name), _, incr_sp(Size, Name)).
 substitute_labels_instr(decr_sp(Size), _, decr_sp(Size)).
 substitute_labels_instr(pragma_c(Decl, In, Code, Out, Context), _,
Index: ite_gen.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/ite_gen.m,v
retrieving revision 1.46
diff -u -u -r1.46 ite_gen.m
--- 1.46	1997/08/24 01:29:40
+++ ite_gen.m	1997/08/25 12:58:44
@@ -220,7 +220,7 @@
 
 	code_info__pop_failure_cont,
 	( { MaybeMaxfrLval = yes(MaxfrLval) } ->
-		code_info__do_soft_cut(MaxfrLval, SoftCutCode),
+		code_info__do_soft_cut(MaxfrLval, SoftCutCode, SoftCutContCode),
 		code_info__unset_failure_cont(FlushCode)
 			% XXX why call unset_failure_cont here?
 			% We're going to call it from branch_end at the
@@ -228,6 +228,7 @@
 			% one really necessary?
 	;
 		{ SoftCutCode = empty },
+		{ SoftCutContCode = empty },
 		{ FlushCode = empty }
 	),
 
@@ -280,12 +281,13 @@
 		 tree(ThenCode,
 		 tree(ThenSaveCode,
 		 tree(JumpToEndCode,
+		 tree(SoftCutContCode,
 		 tree(RestoreContCode,
 		 tree(RestoreHPCode,
 		 tree(RestoreTicketCode,
 		 tree(ElseCode,
 		 tree(ElseSaveCode,
-		      EndLabelCode)))))))))))))))))
+		      EndLabelCode))))))))))))))))))
 	},
 	code_info__remake_with_store_map(StoreMap).
 
Index: livemap.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/livemap.m,v
retrieving revision 1.26
diff -u -u -r1.26 livemap.m
--- 1.26	1997/08/24 01:29:42
+++ livemap.m	1997/08/25 11:13:53
@@ -244,12 +244,12 @@
 		Livemap = Livemap0,
 		Ccode = Ccode0
 	;
-		Uinstr0 = incr_hp(Lval, _, Rval),
+		Uinstr0 = incr_hp(Lval, _Tag, Rval),
 
 		% Make dead the variable assigned, but make any variables
 		% needed to access it live. Make the variables in the size
 		% expression live as well.
-		% The use of the size expression occurs after the assignment
+		% The use of the size rval occurs after the assignment
 		% to lval, but the two should never have any variables in
 		% common. This is why doing the deletion first works.
 
@@ -261,8 +261,9 @@
 		Ccode = Ccode0
 	;
 		Uinstr0 = mark_hp(Lval),
+		set__delete(Livevals0, Lval, Livevals1),
 		opt_util__lval_access_rvals(Lval, Rvals),
-		livemap__make_live_in_rvals(Rvals, Livevals0, Livevals),
+		livemap__make_live_in_rvals(Rvals, Livevals1, Livevals),
 		Livemap = Livemap0,
 		Instrs = Instrs0,
 		Ccode = Ccode0
@@ -274,14 +275,15 @@
 		Ccode = Ccode0
 	;
 		Uinstr0 = store_ticket(Lval),
+		set__delete(Livevals0, Lval, Livevals1),
 		opt_util__lval_access_rvals(Lval, Rvals),
-		livemap__make_live_in_rvals(Rvals, Livevals0, Livevals),
+		livemap__make_live_in_rvals(Rvals, Livevals1, Livevals),
 		Livemap = Livemap0,
 		Instrs = Instrs0,
 		Ccode = Ccode0
 	;
 		Uinstr0 = reset_ticket(Rval, _Reason),
-		livemap__make_live_in_rvals([Rval], Livevals0, Livevals),
+		livemap__make_live_in_rval(Rval, Livevals0, Livevals),
 		Livemap = Livemap0,
 		Instrs = Instrs0,
 		Ccode = Ccode0
@@ -292,6 +294,20 @@
 		Instrs = Instrs0,
 		Ccode = Ccode0
 	;
+		Uinstr0 = mark_ticket_stack(Lval),
+		set__delete(Livevals0, Lval, Livevals1),
+		opt_util__lval_access_rvals(Lval, Rvals),
+		livemap__make_live_in_rvals(Rvals, Livevals1, Livevals),
+		Livemap = Livemap0,
+		Instrs = Instrs0,
+		Ccode = Ccode0
+	;
+		Uinstr0 = discard_tickets_to(Rval),
+		livemap__make_live_in_rval(Rval, Livevals0, Livevals),
+		Livemap = Livemap0,
+		Instrs = Instrs0,
+		Ccode = Ccode0
+	;
 		Uinstr0 = incr_sp(_, _),
 		Livevals = Livevals0,
 		Livemap = Livemap0,
@@ -304,6 +320,7 @@
 		Instrs = Instrs0,
 		Ccode = Ccode0
 	;
+		% XXX we shouldn't just give up here
 		Uinstr0 = pragma_c(_, _, _, _, _),
 		Livemap = Livemap0,
 		Livevals = Livevals0,
Index: llds.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/llds.m,v
retrieving revision 1.209
diff -u -u -r1.209 llds.m
--- 1.209	1997/08/24 01:29:43
+++ llds.m	1997/08/25 09:53:08
@@ -123,7 +123,8 @@
 			% The third argument is the live value info for the
 			% values live on return. The last gives the model
 			% of the called procedure, and if it is nondet,
-			% says whether tail recursion is applicable to the call.
+			% says whether tail recursion elimination is
+			% potentially applicable to the call.
 
 	;	mkframe(string, int, code_addr)
 			% mkframe(Comment, SlotCount, FailureContinuation)
@@ -140,8 +141,9 @@
 	;	goto(code_addr)
 			% goto(Target)
 			% Branch to the specified address.
-			% Note that jumps to do_fail, etc., can get
-			% optimized into the invocations of macros fail(), etc..
+			% Note that jumps to do_fail, do_redo, etc., can get
+			% optimized into the invocations of macros
+			% fail(), redo(), etc..
 
 	;	computed_goto(rval, list(label))
 			% Evaluate rval, which should be an integer,
@@ -173,24 +175,39 @@
 			% was allocated since that call to mark_hp.
 
 	;	store_ticket(lval)
-			% Get a trail ticket from the constraint solver,
-			% (conceptually) push it onto the ticket stack
-			% [actually just increment the ticket counter]
-			% and store its address in the lval.
+			% Allocate a new "ticket" and store it in the lval.
 
 	;	reset_ticket(rval, reset_trail_reason)
-			% Reset the ticket stack so that the specified
-			% rval is now at the top of the ticket stack.
-			% (i.e. reset the trail back to the specified rval.)
-			% If undo_reason is `undo' (or `exception'), restore
-			% any global state to the state it was in when
-			% the ticket pointed to by the specified rval
-			% was obtained with store_ticket().
+			% The rval must specify a ticket allocated with
+			% `store_ticket' and not yet invalidated or
+			% deallocated.
+			% If undo_reason is `undo' or `exception', restore
+			% any mutable global state to the state it was in when
+			% the ticket was obtained with store_ticket();
+			% invalidates any tickets allocated after this one.
 			% If undo_reason is `commit', leave the state
-			% unchanged, just discard the trail entries.
+			% unchanged, just discard the trail entries and
+			% any associated baggage; invalidates this
+			% ticket as well as any tickets allocated after this
+			% one.
+			% Any invalidated ticket is useless and should
+			% be deallocated with either `discard_ticket'
+			% or `discard_tickets_to'.
 
 	;	discard_ticket
-			% Pop the top ticket off the ticket stack.
+			% Deallocates the most-recently allocated ticket.
+
+	;	mark_ticket_stack(lval)
+			% Tell the trail sub-system to store a ticket counter
+			% (for later use in discard_tickets_upto)
+			% in the specified lval.
+
+	;	discard_tickets_to(rval)
+			% The rval must be a ticket counter obtained via
+			% `mark_ticket_stack' and not yet invalidated.
+			% Deallocates any trail tickets allocated after
+			% the corresponding call to mark_ticket_stack.
+			% Invalidates any later ticket counters.
 
 	;	incr_sp(int, string)
 			% Increment the det stack pointer. The string is
Index: llds_common.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/llds_common.m,v
retrieving revision 1.9
diff -u -u -r1.9 llds_common.m
--- 1.9	1997/08/24 01:29:45
+++ llds_common.m	1997/08/25 11:18:10
@@ -234,6 +234,14 @@
 		Instr = Instr0,
 		Info = Info0
 	;
+		Instr0 = mark_ticket_stack(_),
+		Instr = Instr0,
+		Info = Info0
+	;
+		Instr0 = discard_tickets_to(_),
+		Instr = Instr0,
+		Info = Info0
+	;
 		Instr0 = incr_sp(_, _),
 		Instr = Instr0,
 		Info = Info0
Index: llds_out.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/llds_out.m,v
retrieving revision 1.54
diff -u -u -r1.54 llds_out.m
--- 1.54	1997/08/24 01:29:47
+++ llds_out.m	1997/08/25 12:47:46
@@ -780,6 +780,10 @@
 output_instruction_decls(reset_ticket(Rval, _Reason), DeclSet0, DeclSet) -->
 	output_rval_decls(Rval, "", "", 0, _, DeclSet0, DeclSet).
 output_instruction_decls(discard_ticket, DeclSet, DeclSet) --> [].
+output_instruction_decls(mark_ticket_stack(Lval), DeclSet0, DeclSet) -->
+	output_lval_decls(Lval, "", "", 0, _, DeclSet0, DeclSet).
+output_instruction_decls(discard_tickets_to(Rval), DeclSet0, DeclSet) -->
+	output_rval_decls(Rval, "", "", 0, _, DeclSet0, DeclSet).
 output_instruction_decls(incr_sp(_, _), DeclSet, DeclSet) --> [].
 output_instruction_decls(decr_sp(_), DeclSet, DeclSet) --> [].
 output_instruction_decls(pragma_c(_Decls, Inputs, _C_Code, Outputs, _Context),
@@ -1007,6 +1011,16 @@
 
 output_instruction(discard_ticket, _) -->
 	io__write_string("\tMR_discard_ticket();\n").
+
+output_instruction(mark_ticket_stack(Lval), _) -->
+	io__write_string("\tMR_mark_ticket_stack("),
+	output_lval_as_word(Lval),
+	io__write_string(");\n").
+
+output_instruction(discard_tickets_to(Rval), _) -->
+	io__write_string("\tMR_discard_tickets_to("),
+	output_rval_as_type(Rval, word),
+	io__write_string(");\n").
 
 output_instruction(incr_sp(N, Msg), _) -->
 	io__write_string("\tincr_sp_push_msg("),
Index: middle_rec.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/middle_rec.m,v
retrieving revision 1.65
diff -u -u -r1.65 middle_rec.m
--- 1.65	1997/08/24 01:29:48
+++ middle_rec.m	1997/08/25 11:23:15
@@ -408,6 +408,10 @@
 middle_rec__find_used_registers_instr(reset_ticket(Rval, _Rsn), Used0, Used) :-
 	middle_rec__find_used_registers_rval(Rval, Used0, Used).
 middle_rec__find_used_registers_instr(discard_ticket, Used, Used).
+middle_rec__find_used_registers_instr(mark_ticket_stack(Lval), Used0, Used) :-
+	middle_rec__find_used_registers_lval(Lval, Used0, Used).
+middle_rec__find_used_registers_instr(discard_tickets_to(Rval), Used0, Used) :-
+	middle_rec__find_used_registers_rval(Rval, Used0, Used).
 middle_rec__find_used_registers_instr(incr_sp(_, _), Used, Used).
 middle_rec__find_used_registers_instr(decr_sp(_), Used, Used).
 middle_rec__find_used_registers_instr(pragma_c(_, Ins, _, Outs, _),
Index: opt_debug.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/opt_debug.m,v
retrieving revision 1.71
diff -u -u -r1.71 opt_debug.m
--- 1.71	1997/08/24 01:29:50
+++ opt_debug.m	1997/08/25 11:25:22
@@ -322,6 +322,12 @@
 	opt_debug__dump_vn(Vn, Vn_str),
 	string__append_list(["reset_ticket(", Vn_str, ", _)"], Str).
 opt_debug__dump_vninstr(vn_discard_ticket, "discard_ticket").
+opt_debug__dump_vninstr(vn_mark_ticket_stack(Vnlval), Str) :-
+	opt_debug__dump_vnlval(Vnlval, V_str),
+	string__append_list(["mark_ticket_stack(", V_str, ")"], Str).
+opt_debug__dump_vninstr(vn_discard_tickets_to(Vn), Str) :-
+	opt_debug__dump_vn(Vn, Vn_str),
+	string__append_list(["discard_tickets_to(", Vn_str, ", _)"], Str).
 opt_debug__dump_vninstr(vn_incr_sp(N, _), Str) :-
 	string__int_to_string(N, N_str),
 	string__append_list(["incr_sp(", N_str, ")"], Str).
@@ -852,6 +858,12 @@
 	opt_debug__dump_rval(Rval, R_str),
 	string__append_list(["reset_ticket(", R_str, ", _)"], Str).
 opt_debug__dump_instr(discard_ticket, "discard_ticket").
+opt_debug__dump_instr(mark_ticket_stack(Lval), Str) :-
+	opt_debug__dump_lval(Lval, L_str),
+	string__append_list(["mark_ticket_stack(", L_str, ")"], Str).
+opt_debug__dump_instr(discard_tickets_to(Rval), Str) :-
+	opt_debug__dump_rval(Rval, R_str),
+	string__append_list(["discard_tickets_to(", R_str, ")"], Str).
 opt_debug__dump_instr(incr_sp(Size, _), Str) :-
 	string__int_to_string(Size, S_str),
 	string__append_list(["incr_sp(", S_str, ")"], Str).
Index: opt_util.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/opt_util.m,v
retrieving revision 1.83
diff -u -u -r1.83 opt_util.m
--- 1.83	1997/08/24 01:29:52
+++ opt_util.m	1997/08/25 11:31:42
@@ -865,6 +865,22 @@
 		Uinstr0 = discard_ticket,
 		opt_util__block_refers_stackvars(Instrs0, Need)
 	;
+		Uinstr0 = mark_ticket_stack(Lval),
+		opt_util__lval_refers_stackvars(Lval, Use),
+		( Use = yes ->
+			Need = yes
+		;
+			opt_util__block_refers_stackvars(Instrs0, Need)
+		)
+	;
+		Uinstr0 = discard_tickets_to(Rval),
+		opt_util__rval_refers_stackvars(Rval, Use),
+		( Use = yes ->
+			Need = yes
+		;
+			opt_util__block_refers_stackvars(Instrs0, Need)
+		)
+	;
 		% handled specially
 		Uinstr0 = incr_sp(_, _),
 		Need = no
@@ -969,6 +985,8 @@
 opt_util__can_instr_branch_away(store_ticket(_), no).
 opt_util__can_instr_branch_away(reset_ticket(_, _), no).
 opt_util__can_instr_branch_away(discard_ticket, no).
+opt_util__can_instr_branch_away(mark_ticket_stack(_), no).
+opt_util__can_instr_branch_away(discard_tickets_to(_), no).
 opt_util__can_instr_branch_away(incr_sp(_, _), no).
 opt_util__can_instr_branch_away(decr_sp(_), no).
 opt_util__can_instr_branch_away(pragma_c(_, _, _, _, _), no).
@@ -992,6 +1010,8 @@
 opt_util__can_instr_fall_through(store_ticket(_), yes).
 opt_util__can_instr_fall_through(reset_ticket(_, _), yes).
 opt_util__can_instr_fall_through(discard_ticket, yes).
+opt_util__can_instr_fall_through(mark_ticket_stack(_), yes).
+opt_util__can_instr_fall_through(discard_tickets_to(_), yes).
 opt_util__can_instr_fall_through(incr_sp(_, _), yes).
 opt_util__can_instr_fall_through(decr_sp(_), yes).
 opt_util__can_instr_fall_through(pragma_c(_, _, _, _, _), yes).
@@ -1031,6 +1051,8 @@
 opt_util__can_use_livevals(store_ticket(_), no).
 opt_util__can_use_livevals(reset_ticket(_, _), no).
 opt_util__can_use_livevals(discard_ticket, no).
+opt_util__can_use_livevals(mark_ticket_stack(_), no).
+opt_util__can_use_livevals(discard_tickets_to(_), no).
 opt_util__can_use_livevals(incr_sp(_, _), no).
 opt_util__can_use_livevals(decr_sp(_), no).
 opt_util__can_use_livevals(pragma_c(_, _, _, _, _), no).
@@ -1087,6 +1109,8 @@
 opt_util__instr_labels_2(store_ticket(_), [], []).
 opt_util__instr_labels_2(reset_ticket(_, _), [], []).
 opt_util__instr_labels_2(discard_ticket, [], []).
+opt_util__instr_labels_2(mark_ticket_stack(_), [], []).
+opt_util__instr_labels_2(discard_tickets_to(_), [], []).
 opt_util__instr_labels_2(incr_sp(_, _), [], []).
 opt_util__instr_labels_2(decr_sp(_), [], []).
 opt_util__instr_labels_2(pragma_c(_, _, _, _, _), [], []).
@@ -1115,6 +1139,8 @@
 opt_util__instr_rvals_and_lvals(store_ticket(Lval), [], [Lval]).
 opt_util__instr_rvals_and_lvals(reset_ticket(Rval, _Reason), [Rval], []).
 opt_util__instr_rvals_and_lvals(discard_ticket, [], []).
+opt_util__instr_rvals_and_lvals(mark_ticket_stack(Lval), [], [Lval]).
+opt_util__instr_rvals_and_lvals(discard_tickets_to(Rval), [Rval], []).
 opt_util__instr_rvals_and_lvals(incr_sp(_, _), [], []).
 opt_util__instr_rvals_and_lvals(decr_sp(_), [], []).
 opt_util__instr_rvals_and_lvals(pragma_c(_, In, _, Out, _), Rvals, Lvals) :-
@@ -1208,6 +1234,10 @@
 opt_util__count_temps_instr(reset_ticket(Rval, _Reason), R0, R, F0, F) :-
 	opt_util__count_temps_rval(Rval, R0, R, F0, F).
 opt_util__count_temps_instr(discard_ticket, R, R, F, F).
+opt_util__count_temps_instr(mark_ticket_stack(Lval), R0, R, F0, F) :-
+	opt_util__count_temps_lval(Lval, R0, R, F0, F).
+opt_util__count_temps_instr(discard_tickets_to(Rval), R0, R, F0, F) :-
+	opt_util__count_temps_rval(Rval, R0, R, F0, F).
 opt_util__count_temps_instr(incr_sp(_, _), R, R, F, F).
 opt_util__count_temps_instr(decr_sp(_), R, R, F, F).
 opt_util__count_temps_instr(pragma_c(_, _, _, _, _), R, R, F, F).
Index: value_number.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/value_number.m,v
retrieving revision 1.84
diff -u -u -r1.84 value_number.m
--- 1.84	1997/08/24 01:29:56
+++ value_number.m	1997/08/25 11:35:46
@@ -1080,9 +1080,11 @@
 value_number__boundary_instr(incr_hp(_, _, _), no).
 value_number__boundary_instr(mark_hp(_), no).
 value_number__boundary_instr(restore_hp(_), no).
-value_number__boundary_instr(store_ticket(_), yes).
+value_number__boundary_instr(store_ticket(_), yes). % XXX is it safe to use no?
 value_number__boundary_instr(reset_ticket(_, _), yes).
-value_number__boundary_instr(discard_ticket, yes).
+value_number__boundary_instr(discard_ticket, yes). % XXX
+value_number__boundary_instr(mark_ticket_stack(_), yes). % XXX
+value_number__boundary_instr(discard_tickets_to(_), yes). % XXX
 value_number__boundary_instr(incr_sp(_, _), yes).
 value_number__boundary_instr(decr_sp(_), yes).
 value_number__boundary_instr(pragma_c(_, _, _, _, _), yes).
Index: vn_block.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/vn_block.m,v
retrieving revision 1.47
diff -u -u -r1.47 vn_block.m
--- 1.47	1997/08/24 01:29:58
+++ vn_block.m	1997/08/25 13:00:11
@@ -327,6 +327,20 @@
 	vn_block__new_ctrl_node(vn_discard_ticket, Livemap,
 		Params, VnTables0, VnTables,
 		Liveset0, Liveset, Tuple0, Tuple).
+vn_block__handle_instr(mark_ticket_stack(Lval),
+		Livemap, Params, VnTables0, VnTables, Liveset0, Liveset,
+		SeenIncr, SeenIncr, Tuple0, Tuple) :-
+	vn_util__lval_to_vnlval(Lval, Vnlval, VnTables0, VnTables1),
+	vn_block__new_ctrl_node(vn_mark_ticket_stack(Vnlval), Livemap,
+		Params, VnTables1, VnTables,
+		Liveset0, Liveset, Tuple0, Tuple).
+vn_block__handle_instr(discard_tickets_to(Rval),
+		Livemap, Params, VnTables0, VnTables, Liveset0, Liveset,
+		SeenIncr, SeenIncr, Tuple0, Tuple) :-
+	vn_util__rval_to_vn(Rval, Vn, VnTables0, VnTables1),
+	vn_block__new_ctrl_node(vn_discard_tickets_to(Vn), Livemap,
+		Params, VnTables1, VnTables,
+		Liveset0, Liveset, Tuple0, Tuple).
 vn_block__handle_instr(incr_sp(N, Msg),
 		Livemap, Params, VnTables0, VnTables, Liveset0, Liveset,
 		SeenIncr, SeenIncr, Tuple0, Tuple) :-
@@ -457,6 +471,27 @@
 		LabelNo = LabelNo0,
 		Parallels = []
 	;
+		VnInstr = vn_mark_ticket_stack(Vnlval),
+		( vn_table__search_desired_value(Vnlval, Vn_prime, VnTables0) ->
+			Vn = Vn_prime,
+			VnTables1 = VnTables0
+		;
+			vn_table__record_first_vnlval(Vnlval, Vn, 
+				VnTables0, VnTables1)
+		),
+		vn_table__set_desired_value(Vnlval, Vn, VnTables1, VnTables),
+		set__insert(Liveset0, Vnlval, Liveset),
+		FlushEntry = FlushEntry0,
+		LabelNo = LabelNo0,
+		Parallels = []
+	;
+		VnInstr = vn_discard_tickets_to(_),
+		VnTables = VnTables0,
+		Liveset = Liveset0,
+		FlushEntry = FlushEntry0,
+		LabelNo = LabelNo0,
+		Parallels = []
+	;
 		VnInstr = vn_incr_sp(_, _),
 		VnTables = VnTables0,
 		Liveset = Liveset0,
@@ -847,6 +882,8 @@
 vn_block__is_ctrl_instr(store_ticket(_), yes).
 vn_block__is_ctrl_instr(reset_ticket(_, _), yes).
 vn_block__is_ctrl_instr(discard_ticket, yes).
+vn_block__is_ctrl_instr(mark_ticket_stack(_), yes).
+vn_block__is_ctrl_instr(discard_tickets_to(_), yes).
 vn_block__is_ctrl_instr(incr_sp(_, _), yes).
 vn_block__is_ctrl_instr(decr_sp(_), yes).
 vn_block__is_ctrl_instr(pragma_c(_, _, _, _, _), no).
Index: vn_cost.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/vn_cost.m,v
retrieving revision 1.27
diff -u -u -r1.27 vn_cost.m
--- 1.27	1997/08/24 01:29:59
+++ vn_cost.m	1997/08/25 11:41:43
@@ -167,6 +167,14 @@
 		Uinstr = discard_ticket,
 		Cost = 0
 	;
+		Uinstr = mark_ticket_stack(Lval),
+		vn_cost__lval_cost(Lval, Params, LvalCost),
+		Cost = LvalCost
+	;
+		Uinstr = discard_tickets_to(Rval),
+		vn_cost__rval_cost(Rval, Params, RvalCost),
+		Cost = RvalCost
+	;
 		Uinstr = incr_sp(_, _),
 		Cost = 0
 	;
Index: vn_filter.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/vn_filter.m,v
retrieving revision 1.10
diff -u -u -r1.10 vn_filter.m
--- 1.10	1997/08/24 01:30:01
+++ vn_filter.m	1997/08/25 13:08:57
@@ -122,6 +122,8 @@
 vn_filter__user_instr(store_ticket(_), no).
 vn_filter__user_instr(reset_ticket(Rval, _Reason), yes(Rval)).
 vn_filter__user_instr(discard_ticket, no).
+vn_filter__user_instr(mark_ticket_stack(_), no).
+vn_filter__user_instr(discard_tickets_to(Rval), yes(Rval)).
 vn_filter__user_instr(incr_sp(_, _), no).
 vn_filter__user_instr(decr_sp(_), no).
 vn_filter__user_instr(pragma_c(_, _, _, _, _), _):-
@@ -172,6 +174,11 @@
 	vn_filter__replace_in_rval(Rval0, Temp, Defn, Rval).
 vn_filter__replace_in_user_instr(discard_ticket, _, _, _) :-
 	error("non-user instruction in vn_filter__replace_in_user_instr").
+vn_filter__replace_in_user_instr(mark_ticket_stack(_), _, _, _) :-
+	error("non-user instruction in vn_filter__replace_in_user_instr").
+vn_filter__replace_in_user_instr(discard_tickets_to(Rval0), Temp, Defn,
+		discard_tickets_to(Rval)) :-
+	vn_filter__replace_in_rval(Rval0, Temp, Defn, Rval).
 vn_filter__replace_in_user_instr(incr_sp(_, _), _, _, _) :-
 	error("non-user instruction in vn_filter__replace_in_user_instr").
 vn_filter__replace_in_user_instr(decr_sp(_), _, _, _) :-
@@ -202,6 +209,8 @@
 vn_filter__defining_instr(store_ticket(Lval), yes(Lval)).
 vn_filter__defining_instr(reset_ticket(_, _), no).
 vn_filter__defining_instr(discard_ticket, no).
+vn_filter__defining_instr(mark_ticket_stack(Lval), yes(Lval)).
+vn_filter__defining_instr(discard_tickets_to(_), no).
 vn_filter__defining_instr(incr_sp(_, _), no).
 vn_filter__defining_instr(decr_sp(_), no).
 vn_filter__defining_instr(pragma_c(_, _, _, _, _), _):-
@@ -249,6 +258,11 @@
 vn_filter__replace_in_defining_instr(reset_ticket(_, _), _, _, _) :-
 	error("non-def instruction in vn_filter__replace_in_defining_instr").
 vn_filter__replace_in_defining_instr(discard_ticket, _, _, _) :-
+	error("non-def instruction in vn_filter__replace_in_defining_instr").
+vn_filter__replace_in_defining_instr(mark_ticket_stack(Lval0), Temp, Defn,
+		mark_ticket_stack(Lval)) :-
+	vn_filter__replace_in_lval(Lval0, Temp, Defn, Lval).
+vn_filter__replace_in_defining_instr(discard_tickets_to(_), _, _, _) :-
 	error("non-def instruction in vn_filter__replace_in_defining_instr").
 vn_filter__replace_in_defining_instr(incr_sp(_, _), _, _, _) :-
 	error("non-def instruction in vn_filter__replace_in_defining_instr").
Index: vn_flush.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/vn_flush.m,v
retrieving revision 1.42
diff -u -u -r1.42 vn_flush.m
--- 1.42	1997/08/24 01:30:03
+++ vn_flush.m	1997/08/25 11:45:47
@@ -261,6 +261,22 @@
 		Templocs = Templocs0,
 		Instrs = [discard_ticket - ""]
 	;
+		Vn_instr = vn_mark_ticket_stack(Vnlval),
+		vn_flush__access_path(Vnlval, [src_ctrl(N)], [], Lval,
+			VnTables0, VnTables1, Templocs0, Templocs, Params,
+			FlushInstrs),
+		vn_table__lookup_assigned_vn(vn_origlval(Vnlval), OldVn,
+			"vn_flush__ctrl_node", VnTables1),
+		vn_table__set_current_value(Vnlval, OldVn, VnTables1, VnTables),
+		Instr = mark_ticket_stack(Lval) - "",
+		list__append(FlushInstrs, [Instr], Instrs)
+	;
+		Vn_instr = vn_discard_tickets_to(Vn),
+		vn_flush__vn(Vn, [src_ctrl(N)], [], Rval, VnTables0, VnTables,
+			Templocs0, Templocs, Params, FlushInstrs),
+		Instr = discard_tickets_to(Rval) - "",
+		list__append(FlushInstrs, [Instr], Instrs)
+	;
 		Vn_instr = vn_incr_sp(Incr, Msg),
 		VnTables = VnTables0,
 		Templocs = Templocs0,
Index: vn_order.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/vn_order.m,v
retrieving revision 1.41
diff -u -u -r1.41 vn_order.m
--- 1.41	1997/08/24 01:30:05
+++ vn_order.m	1997/08/25 11:46:26
@@ -380,6 +380,17 @@
 			Predmap1 = Predmap0,
 			VnTables1 = VnTables0
 		;
+			Vn_instr = vn_mark_ticket_stack(Vnlval),
+			vn_util__vnlval_access_vns(Vnlval, Vns),
+			vn_order__find_all_links(Vns, node_ctrl(Ctrl),
+				VnTables0, VnTables1,
+				Succmap0, Succmap1, Predmap0, Predmap1)
+		;
+			Vn_instr = vn_discard_tickets_to(Vn),
+			vn_order__find_links(Vn, node_ctrl(Ctrl),
+				VnTables0, VnTables1,
+				Succmap0, Succmap1, Predmap0, Predmap1)
+		;
 			Vn_instr = vn_incr_sp(_, _),
 			Succmap1 = Succmap0,
 			Predmap1 = Predmap0,
Index: vn_type.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/vn_type.m,v
retrieving revision 1.33
diff -u -u -r1.33 vn_type.m
--- 1.33	1997/08/24 01:30:06
+++ vn_type.m	1997/08/25 11:47:30
@@ -79,6 +79,8 @@
 			;	vn_store_ticket(vnlval)
 			;	vn_reset_ticket(vn, reset_trail_reason)
 			;	vn_discard_ticket
+			;	vn_mark_ticket_stack(vnlval)
+			;	vn_discard_tickets_to(vn)
 			;	vn_incr_sp(int, string)
 			;	vn_decr_sp(int).
 
Index: vn_util.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/vn_util.m,v
retrieving revision 1.56
diff -u -u -r1.56 vn_util.m
--- 1.56	1997/08/24 01:30:08
+++ vn_util.m	1997/08/25 11:48:21
@@ -1257,6 +1257,15 @@
 			VnInstr = vn_discard_ticket,
 			VnTables1 = VnTables0
 		;
+			VnInstr = vn_mark_ticket_stack(Vnlval),
+			vn_util__vnlval_access_vns(Vnlval, Vns),
+			vn_util__record_use_list(Vns, src_ctrl(Ctrl),
+				VnTables0, VnTables1)
+		;
+			VnInstr = vn_discard_tickets_to(Vn),
+			vn_util__record_use(Vn, src_ctrl(Ctrl),
+				VnTables0, VnTables1)
+		;
 			VnInstr = vn_incr_sp(_, _),
 			VnTables1 = VnTables0
 		;
Index: vn_verify.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/vn_verify.m,v
retrieving revision 1.12
diff -u -u -r1.12 vn_verify.m
--- 1.12	1997/08/24 01:30:09
+++ vn_verify.m	1997/08/25 11:49:08
@@ -355,6 +355,16 @@
 		NoDeref = NoDeref0,
 		Tested = Tested0
 	;
+		Instr = mark_ticket_stack(Lval),
+		vn_verify__tags_lval(Lval, NoDeref0),
+		NoDeref = NoDeref0,
+		Tested = Tested0
+	;
+		Instr = discard_tickets_to(Rval),
+		vn_verify__tags_rval(Rval, NoDeref0),
+		NoDeref = NoDeref0,
+		Tested = Tested0
+	;
 		Instr = incr_sp(_, _),
 		NoDeref = NoDeref0,
 		Tested = Tested0
cvs diff: Diffing notes
-- 
Fergus Henderson <fjh at cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3         |     -- the last words of T. S. Garp.



More information about the developers mailing list