[m-rev.] diff: frameopt for model_non predicates

Zoltan Somogyi zs at cs.mu.OZ.AU
Mon May 24 09:12:51 AEST 2004


Perform frame optimization on nondet predicates. The need for this was revealed
by benchmarking in Uppsala, which initially showed Mercury to take three to
five times as long as XSB on some tabling benchmarks. One major contributor
was the fact that the predicate returning answers out of answer table
was creating and destroying a nondet stack frame for every answer it returned.

To make this change easier, make the representation of labels more reader
friendly, classifying them primarily on whether they represent entry or
internal labels, and only secondarily on the scope in which they represent
valid references to the label.

compiler/frameopt.m:
	Add a predicate to perform frame optimization on model_non predicates.
	This optimization involves separating the steps of creating the frame
	(done once) and setting the redoip (potentially done on every
	iteration).

compiler/optimize.m:
	Invoke this new predicate. Reorder the arguments of predicates in this
	file, and the top level predicates of the optimizations it invokes,
	to allow the use of state variable notation.

compiler/mercury_stacks.h:
	Provide macros for creating nondet stack frames that do not fill in the
	redoip slot.

compiler/llds.m:
	Make the setting of redoip optional in mkframe operations.

	Make the representation of labels more reader friendly.

compiler/layout_out.m:
	Change the representation of label layouts to enforce the invariant
	that these can refer only to internal labels. (The layout structures
	of entry labels are proc layout structures, whose design enforces the
	relevant invariant already.)

compiler/jumpopt.m:
	Add an optimization that improves code that matches a new pattern:

	% Attempt to transform code such as
	%
	%       if (Cond) L1
	%       goto L2
	%
	% into
	%
	%       if (! Cond) L2
	%       <code at L1>
	%
	% when we know the code at L1 and don't know the code at L2.

	The new frame optimization creates instances of this pattern, usually
	with L2 being do_fail.

compiler/*.m:
	Minor diffs to conform to the changes above.

Zoltan.

cvs server: Diffing .
cvs server: Diffing analysis
cvs server: Diffing bindist
cvs server: Diffing boehm_gc
cvs server: Diffing boehm_gc/Mac_files
cvs server: Diffing boehm_gc/cord
cvs server: Diffing boehm_gc/cord/private
cvs server: Diffing boehm_gc/doc
cvs server: Diffing boehm_gc/include
cvs server: Diffing boehm_gc/include/private
cvs server: Diffing boehm_gc/tests
cvs server: Diffing browser
cvs server: Diffing bytecode
cvs server: Diffing compiler
Index: compiler/basic_block.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/basic_block.m,v
retrieving revision 1.15
diff -u -b -r1.15 basic_block.m
--- compiler/basic_block.m	11 Nov 2003 03:35:06 -0000	1.15
+++ compiler/basic_block.m	23 May 2004 22:18:04 -0000
@@ -79,7 +79,7 @@
 		RestInstrs = OrigInstrs0
 	;
 		counter__allocate(N, !C),
-		Label = local(N, ProcLabel),
+		Label = internal(N, ProcLabel),
 		LabelInstr = label(Label) - "",
 		RestInstrs = [OrigInstr0 | OrigInstrs0]
 	),
Index: compiler/code_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/code_gen.m,v
retrieving revision 1.125
diff -u -b -r1.125 code_gen.m
--- compiler/code_gen.m	23 May 2004 22:16:43 -0000	1.125
+++ compiler/code_gen.m	23 May 2004 22:18:04 -0000
@@ -848,7 +848,8 @@
 			NondetFrameInfo = ordinary_frame(PushMsg, TotalSlots,
 				yes(Struct)),
 			AllocCode = node([
-				mkframe(NondetFrameInfo, OutsideResumeAddress)
+				mkframe(NondetFrameInfo,
+					yes(OutsideResumeAddress))
 					- "Allocate stack frame",
 				pragma_c([], DefineComponents,
 					will_not_call_mercury, no, no, no, no,
@@ -860,7 +861,8 @@
 			NondetFrameInfo = ordinary_frame(PushMsg, TotalSlots,
 				no),
 			AllocCode = node([
-				mkframe(NondetFrameInfo, OutsideResumeAddress)
+				mkframe(NondetFrameInfo,
+					yes(OutsideResumeAddress))
 					- "Allocate stack frame"
 			]),
 			NondetPragma = no
Index: compiler/code_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/code_info.m,v
retrieving revision 1.288
diff -u -b -r1.288 code_info.m
--- compiler/code_info.m	10 Apr 2004 10:33:00 -0000	1.288
+++ compiler/code_info.m	23 May 2004 22:18:04 -0000
@@ -143,7 +143,7 @@
 	% Get the label layout information created by tracing
 	% during code generation.
 :- pred code_info__get_layout_info(code_info::in,
-	map(label, internal_layout_info)::out) is det.
+	proc_label_layout_info::out) is det.
 
 	% Get the global static data structures that have
 	% been created during code generation for closure layouts.
@@ -202,7 +202,7 @@
 :- pred code_info__set_succip_used(bool::in,
 	code_info::in, code_info::out) is det.
 
-:- pred code_info__set_layout_info(map(label, internal_layout_info)::in,
+:- pred code_info__set_layout_info(proc_label_layout_info::in,
 	code_info::in, code_info::out) is det.
 
 :- pred code_info__get_max_temp_slot_count(code_info::in, int::out) is det.
@@ -315,7 +315,7 @@
 				% by this procedure.
 		store_succip	:: bool,
 				% do we need to store succip?
-		label_info	:: map(label, internal_layout_info),
+		label_info	:: proc_label_layout_info,
 				% Information on which values
 				% are live and where at which labels,
 				% for tracing and/or accurate gc.
@@ -841,7 +841,13 @@
 	code_info__get_layout_info(!.CI, Internals0),
 	Exec = yes(trace_port_layout_info(Context, Port, IsHidden,
 		Path, Layout)),
-	( map__search(Internals0, Label, Internal0) ->
+	(
+		Label = internal(LabelNum, _)
+	;
+		Label = entry(_, _),
+		error("code_info__add_trace_layout_for_label: entry")
+	),
+	( map__search(Internals0, LabelNum, Internal0) ->
 		Internal0 = internal_layout_info(Exec0, Resume, Return),
 		( Exec0 = no ->
 			true
@@ -849,17 +855,23 @@
 			error("adding trace layout for already known label")
 		),
 		Internal = internal_layout_info(Exec, Resume, Return),
-		map__set(Internals0, Label, Internal, Internals)
+		map__det_update(Internals0, LabelNum, Internal, Internals)
 	;
 		Internal = internal_layout_info(Exec, no, no),
-		map__det_insert(Internals0, Label, Internal, Internals)
+		map__det_insert(Internals0, LabelNum, Internal, Internals)
 	),
 	code_info__set_layout_info(Internals, !CI).
 
 code_info__add_resume_layout_for_label(Label, LayoutInfo, !CI) :-
 	code_info__get_layout_info(!.CI, Internals0),
 	Resume = yes(LayoutInfo),
-	( map__search(Internals0, Label, Internal0) ->
+	(
+		Label = internal(LabelNum, _)
+	;
+		Label = entry(_, _),
+		error("code_info__add_trace_layout_for_label: entry")
+	),
+	( map__search(Internals0, LabelNum, Internal0) ->
 		Internal0 = internal_layout_info(Exec, Resume0, Return),
 		( Resume0 = no ->
 			true
@@ -867,10 +879,10 @@
 			error("adding gc layout for already known label")
 		),
 		Internal = internal_layout_info(Exec, Resume, Return),
-		map__set(Internals0, Label, Internal, Internals)
+		map__det_update(Internals0, LabelNum, Internal, Internals)
 	;
 		Internal = internal_layout_info(no, Resume, no),
-		map__det_insert(Internals0, Label, Internal, Internals)
+		map__det_insert(Internals0, LabelNum, Internal, Internals)
 	),
 	code_info__set_layout_info(Internals, !CI).
 
@@ -1999,7 +2011,7 @@
 		Kind = det_stack_proc
 	),
 	Code = node([
-		mkframe(temp_frame(Kind), Redoip)
+		mkframe(temp_frame(Kind), yes(Redoip))
 			- Comment
 	]),
 	code_info__set_created_temp_frame(yes, !CI),
Index: compiler/code_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/code_util.m,v
retrieving revision 1.150
diff -u -b -r1.150 code_util.m
--- compiler/code_util.m	19 May 2004 03:59:06 -0000	1.150
+++ compiler/code_util.m	23 May 2004 22:18:04 -0000
@@ -63,9 +63,6 @@
 :- pred code_util__extract_proc_label_from_code_addr(code_addr::in,
 	proc_label::out) is det.
 
-:- pred code_util__extract_proc_label_from_label(label::in, proc_label::out)
-	is det.
-
 :- pred code_util__arg_loc_to_register(arg_loc::in, lval::out) is det.
 
 :- pred code_util__max_mentioned_reg(list(lval)::in, int::out) is det.
@@ -141,10 +138,11 @@
 		% into a data structure, a label that is usable only
 		% within the current C module won't do.
 		( RttiProcLabel ^ proc_is_exported = yes ->
-			Label = exported(ProcLabel)
+			EntryType = exported
 		;
-			Label = local(ProcLabel)
-		)
+			EntryType = local
+		),
+		Label = entry(EntryType, ProcLabel)
 	;
 		Immed = yes(ProcsPerFunc - proc(CurPredId, CurProcId)),
 		choose_local_label_type(ProcsPerFunc, CurPredId, CurProcId,
@@ -169,39 +167,26 @@
 			ProcId = CurProcId
 		)
 	->
-		Label = c_local(ProcLabel)
+		EntryType = c_local
 	;
-		Label = local(ProcLabel)
-	).
+		EntryType = local
+	),
+	Label = entry(EntryType, ProcLabel).
 
 %-----------------------------------------------------------------------------%
 
 code_util__make_internal_label(ModuleInfo, PredId, ProcId, LabelNum, Label) :-
 	ProcLabel = make_proc_label(ModuleInfo, PredId, ProcId),
-	Label = local(LabelNum, ProcLabel).
+	Label = internal(LabelNum, ProcLabel).
 
 code_util__extract_proc_label_from_code_addr(CodeAddr, ProcLabel) :-
-	( code_util__proc_label_from_code_addr(CodeAddr, ProcLabelPrime) ->
+	( CodeAddr = label(Label) ->
+		ProcLabel = get_proc_label(Label)
+	; CodeAddr = imported(ProcLabelPrime) ->
 		ProcLabel = ProcLabelPrime
 	;
 		error("code_util__extract_label_from_code_addr failed")
 	).
-
-:- pred code_util__proc_label_from_code_addr(code_addr::in,
-	proc_label::out) is semidet.
-
-code_util__proc_label_from_code_addr(CodeAddr, ProcLabel) :-
-	(
-		CodeAddr = label(Label),
-		code_util__extract_proc_label_from_label(Label, ProcLabel)
-	;
-		CodeAddr = imported(ProcLabel)
-	).
-
-code_util__extract_proc_label_from_label(local(_, ProcLabel), ProcLabel).
-code_util__extract_proc_label_from_label(c_local(ProcLabel), ProcLabel).
-code_util__extract_proc_label_from_label(local(ProcLabel), ProcLabel).
-code_util__extract_proc_label_from_label(exported(ProcLabel), ProcLabel).
 
 %-----------------------------------------------------------------------------%
 
Index: compiler/continuation_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/continuation_info.m,v
retrieving revision 1.52
diff -u -b -r1.52 continuation_info.m
--- compiler/continuation_info.m	19 May 2004 03:59:07 -0000	1.52
+++ compiler/continuation_info.m	23 May 2004 22:18:04 -0000
@@ -138,7 +138,7 @@
 	%
 	% Information about the labels internal to a procedure.
 	%
-:- type proc_label_layout_info	==	map(label, internal_layout_info).
+:- type proc_label_layout_info	==	map(int, internal_layout_info).
 
 	%
 	% Information for an internal label.
@@ -430,7 +430,16 @@
 		Internals0, Internals) :-
 	CallInfo = call_info(ReturnLabel, Target, LiveInfoList,
 		Context, MaybeGoalPath),
-	( map__search(Internals0, ReturnLabel, Internal0) ->
+	% We could check not only that the return label is an internal label,
+	% but also that it belongs to the current procedure, but this would be
+	% serious paranoia.
+	(
+		ReturnLabel = internal(ReturnLabelNum, _)
+	;
+		ReturnLabel = entry(_, _),
+		error("continuation_info__process_continuation: bad return")
+	),
+	( map__search(Internals0, ReturnLabelNum, Internal0) ->
 		Internal0 = internal_layout_info(Port0, Resume0, Return0)
 	;
 		Port0 = no,
@@ -470,7 +479,7 @@
 		Return = Return0
 	),
 	Internal = internal_layout_info(Port0, Resume0, Return),
-	map__set(Internals0, ReturnLabel, Internal, Internals).
+	map__set(Internals0, ReturnLabelNum, Internal, Internals).
 
 :- pred continuation_info__convert_return_data(list(liveinfo)::in,
 	set(var_info)::out, map(tvar, set(layout_locn))::out) is det.
Index: compiler/dupelim.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/dupelim.m,v
retrieving revision 1.59
diff -u -b -r1.59 dupelim.m
--- compiler/dupelim.m	11 Nov 2003 03:35:06 -0000	1.59
+++ compiler/dupelim.m	23 May 2004 22:18:04 -0000
@@ -48,8 +48,8 @@
 
 :- import_module list, counter.
 
-:- pred dupelim_main(list(instruction)::in, proc_label::in,
-	counter::in, counter::out, list(instruction)::out) is det.
+:- pred dupelim_main(proc_label::in, counter::in, counter::out,
+	list(instruction)::in, list(instruction)::out) is det.
 
 %-----------------------------------------------------------------------------%
 
@@ -71,7 +71,7 @@
 	% OtherLabels must be nonempty.
 :- type cluster		--->	cluster(label, list(label)).
 
-dupelim_main(Instrs0, ProcLabel, !C, Instrs) :-
+dupelim_main(ProcLabel, !C, Instrs0, Instrs) :-
 	create_basic_blocks(Instrs0, Comments, ProcLabel, !C,
 		LabelSeq0, BlockMap0),
 	map__init(StdMap0),
Index: compiler/exprn_aux.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/exprn_aux.m,v
retrieving revision 1.50
diff -u -b -r1.50 exprn_aux.m
--- compiler/exprn_aux.m	20 Oct 2003 07:29:05 -0000	1.50
+++ compiler/exprn_aux.m	23 May 2004 22:18:04 -0000
@@ -168,12 +168,15 @@
 :- pred exprn_aux__label_is_constant(label::in, bool::in, bool::in, bool::out)
 	is det.
 
-exprn_aux__label_is_constant(exported(_), NonLocalGotos, AsmLabels, IsConst) :-
+exprn_aux__label_is_constant(entry(exported, _), NonLocalGotos, AsmLabels,
+		IsConst) :-
 	globals__imported_is_constant(NonLocalGotos, AsmLabels, IsConst).
-exprn_aux__label_is_constant(local(_), NonLocalGotos, AsmLabels, IsConst) :-
+exprn_aux__label_is_constant(entry(local, _), NonLocalGotos, AsmLabels,
+		IsConst) :-
 	globals__imported_is_constant(NonLocalGotos, AsmLabels, IsConst).
-exprn_aux__label_is_constant(c_local(_), _NonLocalGotos, _AsmLabels, yes).
-exprn_aux__label_is_constant(local(_, _), _NonLocalGotos, _AsmLabels, yes).
+exprn_aux__label_is_constant(entry(c_local, _), _NonLocalGotos, _AsmLabels,
+		yes).
+exprn_aux__label_is_constant(internal(_, _), _NonLocalGotos, _AsmLabels, yes).
 
 %------------------------------------------------------------------------------%
 
Index: compiler/frameopt.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/frameopt.m,v
retrieving revision 1.84
diff -u -b -r1.84 frameopt.m
--- compiler/frameopt.m	12 May 2004 10:05:05 -0000	1.84
+++ compiler/frameopt.m	23 May 2004 22:18:04 -0000
@@ -71,6 +71,9 @@
 % Since the second transformation is a bigger win, we prefer to use it
 % whenever both transformations are possible.
 %
+% For predicates that live on the nondet stack, we attempt to perform
+% only the second transformation.
+%
 % NOTE: This module cannot handle code sequences of the form
 %
 %	label1:
@@ -91,17 +94,52 @@
 :- import_module backend_libs__proc_label.
 :- import_module ll_backend__llds.
 
-:- import_module bool, list, counter.
+:- import_module bool, list, set, counter.
 
-	% The first bool output says whether we performed any modifications.
+	% frameopt_main(ProcLabel, !LabelCounter, !Instrs,
+	%	AnyChange, NewJumps):
+	%
+	% Attempt to update !Instrs using the one of the transformations
+	% described above for procedures that live on the det stack.
+	%
+	% ProcLabel should be the ProcLabel of the procedure whose body
+	% !.Instrs implements, and !.LabelCounter that procedure's label
+	% counter. If frameopt_main allocates any labels, !:LabelCounter
+	% will reflect this.
+	%
+	% AnyChange says whether we performed any modifications.
 	% If yes, then we also introduced some extra labels that should be
-	% deleted. The second says whether we introduced any jumps that
-	% can be profitably be short-circuited.
+	% deleted. NewJumps says whether we introduced any jumps that could
+	% be profitably be short-circuited.
 
-:- pred frameopt_main(list(instruction)::in, proc_label::in,
-	counter::in, counter::out, list(instruction)::out,
+:- pred frameopt_main(proc_label::in, counter::in, counter::out,
+	list(instruction)::in, list(instruction)::out,
 	bool::out, bool::out) is det.
 
+	% frameopt_nondet(ProcLabel, LayoutLabels, MayAlterRtti, !LabelCounter,
+	%	!Instrs, AnyChange):
+	%
+	% Attempt to update !Instrs using the one of the transformations
+	% described above for procedures that live on the nondet stack.
+	%
+	% ProcLabel should be the ProcLabel of the procedure whose body
+	% !.Instrs implements, and !.LabelCounter that procedure's label
+	% counter. If frameopt_main allocates any labels, !:LabelCounter
+	% will reflect this.
+	%
+	% LayoutLabels should be the set of labels in the procedure with layout
+	% structures, while MayAlterRtti should say whether we are allowed to
+	% perform optimizations that may interfere with RTTI.
+	%
+	% AnyChange says whether we performed any modifications.
+	% If yes, then we also introduced some extra labels that should be
+	% deleted, and we introduced some jumps that may be profitably
+	% short-circuited.
+
+:- pred frameopt_nondet(proc_label::in, set(label)::in, may_alter_rtti::in,
+	counter::in, counter::out,
+	list(instruction)::in, list(instruction)::out, bool::out) is det.
+
 %-----------------------------------------------------------------------------%
 
 :- implementation.
@@ -114,11 +152,9 @@
 
 :- import_module int, string, require, std_util, assoc_list, set, map, queue.
 
-frameopt_main(Instrs0, ProcLabel, !C, Instrs, Mod, Jumps) :-
+frameopt_main(ProcLabel, !C, Instrs0, Instrs, Mod, Jumps) :-
 	opt_util__get_prologue(Instrs0, LabelInstr, Comments0, Instrs1),
-	(
-		frameopt__detstack_setup(Instrs1, FrameSize, Msg, _, _, _)
-	->
+	( frameopt__detstack_setup(Instrs1, FrameSize, Msg, _, _, _) ->
 		map__init(BlockMap0),
 		divide_into_basic_blocks([LabelInstr | Instrs1], ProcLabel,
 			BasicInstrs, !C),
@@ -175,6 +211,96 @@
 	list__append(BlockInstrs, RestInstrs, Instrs).
 
 %-----------------------------------------------------------------------------%
+
+frameopt_nondet(ProcLabel, LayoutLabels, MayAlterRtti, !C, Instrs0, Instrs,
+		Mod) :-
+	opt_util__get_prologue(Instrs0, LabelInstr, Comments0, Instrs1),
+	(
+		MayAlterRtti = may_alter_rtti,
+		frameopt__nondetstack_setup(Instrs1, FrameInfo, Redoip,
+			MkframeInstr, Remain),
+		MkframeInstr = MkframeUinstr - MkframeComment,
+		find_succeed_labels(Instrs1, map__init, SuccMap),
+		counter__allocate(KeepFrameLabelNum, !C),
+		KeepFrameLabel = internal(KeepFrameLabelNum, ProcLabel),
+		keep_nondet_frame(Remain, Instrs2, ProcLabel, KeepFrameLabel,
+			MkframeUinstr, SuccMap, LayoutLabels, no, yes)
+	->
+		list__condense([[LabelInstr], Comments0,
+			[mkframe(FrameInfo, no) - MkframeComment,
+			label(KeepFrameLabel) - "tail recursion target",
+			assign(redoip(lval(curfr)),
+				const(code_addr_const(Redoip)))
+				- ""],
+			Instrs2], Instrs),
+		Mod = yes
+	;
+		Instrs = Instrs0,
+		Mod = no
+	).
+
+:- pred frameopt__nondetstack_setup(list(instruction)::in,
+	nondet_frame_info::out, code_addr::out,
+	instruction::out, list(instruction)::out) is semidet.
+
+frameopt__nondetstack_setup(Instrs0, FrameInfo, Redoip,
+		MkframeInstr, Remain) :-
+	Instrs0 = [MkframeInstr | Remain],
+	MkframeInstr = mkframe(FrameInfo, yes(Redoip)) - _,
+	FrameInfo = ordinary_frame(_, _, _).
+
+:- pred find_succeed_labels(list(instruction)::in, tailmap::in, tailmap::out)
+	is det.
+
+find_succeed_labels([], !SuccMap).
+find_succeed_labels([Instr | Instrs], !SuccMap) :-
+	Instr = Uinstr - _,
+	(
+		Uinstr = label(Label),
+		opt_util__skip_comments(Instrs, TailInstrs),
+		opt_util__is_succeed_next(TailInstrs, Between)
+	->
+		map__det_insert(!.SuccMap, Label, Between, !:SuccMap)
+	;
+		true
+	),
+	find_succeed_labels(Instrs, !SuccMap).
+
+:- pred keep_nondet_frame(list(instruction)::in, list(instruction)::out,
+	proc_label::in, label::in, instr::in, tailmap::in, set(label)::in,
+	bool::in, bool::out) is det.
+
+keep_nondet_frame([], [], _, _, _, _, _, !Changed).
+keep_nondet_frame([Instr0 | Instrs0], Instrs, ProcLabel, KeepFrameLabel,
+		PrevInstr, SuccMap, LayoutLabels, !Changed) :-
+	Instr0 = Uinstr0 - Comment,
+	(
+		% Look for nondet style tailcalls which do not need
+		% a runtime check.
+		Uinstr0 = call(label(entry(_, ProcLabel)), label(RetLabel),
+			_, _, _, CallModel),
+		CallModel = nondet(unchecked_tail_call),
+		map__search(SuccMap, RetLabel, BetweenIncl),
+		BetweenIncl = [livevals(_) - _, goto(_) - _],
+		PrevInstr = livevals(Livevals),
+		not set__member(RetLabel, LayoutLabels)
+	->
+		keep_nondet_frame(Instrs0, Instrs1, ProcLabel, KeepFrameLabel,
+			Uinstr0, SuccMap, LayoutLabels, !.Changed, _),
+		!:Changed = yes,
+		NewComment = Comment ++ " (nondet tailcall)",
+		Instrs = [
+			livevals(Livevals) - "",
+			goto(label(KeepFrameLabel)) - NewComment
+			| Instrs1
+		]
+	;
+		keep_nondet_frame(Instrs0, Instrs1, ProcLabel, KeepFrameLabel,
+			Uinstr0, SuccMap, LayoutLabels, !Changed),
+		Instrs = [Instr0 | Instrs1]
+	).
+
+%-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
 :- type block_map	==	map(label, block_info).
@@ -234,7 +360,7 @@
 				Instrs = [Instr0 | Instrs1]
 			;
 				counter__allocate(N, !C),
-				NewLabel = local(N, ProcLabel),
+				NewLabel = internal(N, ProcLabel),
 				NewInstr = label(NewLabel) - "",
 				divide_into_basic_blocks(Instrs0, ProcLabel,
 					Instrs1, !C),
@@ -296,7 +422,7 @@
 				Instrs2 = Instrs1
 			;
 				counter__allocate(N, !C),
-				NewLabel = local(N, ProcLabel),
+				NewLabel = internal(N, ProcLabel),
 				NewInstr = label(NewLabel) - "",
 				Instrs2 = [NewInstr | Instrs1]
 			),
@@ -325,7 +451,7 @@
 					[], no, ordinary(Needs)),
 				MaybeTailInfo = yes(TailInfo - Label),
 				counter__allocate(N, !C),
-				NewLabel = local(N, ProcLabel),
+				NewLabel = internal(N, ProcLabel),
 				NewInstr = label(NewLabel) - "",
 				LabelledBlock = [NewInstr | Teardown],
 				TeardownLabel = NewLabel,
@@ -616,7 +742,7 @@
 		),
 		(
 			LastUinstr = goto(label(GotoLabel)),
-			same_label_ref(FirstLabel, GotoLabel)
+			matching_label_ref(FirstLabel, GotoLabel)
 		->
 			!:KeepFrame = yes
 		;
@@ -640,14 +766,21 @@
 	% is a proper reference to the first label (from the initial label
 	% instruction).
 
-:- pred same_label_ref(label::in, label::in) is semidet.
+:- pred matching_label_ref(label::in, label::in) is semidet.
+
+matching_label_ref(entry(FirstLabelType, ProcLabel),
+		entry(GotoLabelType, ProcLabel)) :-
+	matching_entry_type(FirstLabelType, GotoLabelType).
+
+:- pred matching_entry_type(entry_label_type::in, entry_label_type::in)
+	is semidet.
 
-same_label_ref(exported(ProcLabel), exported(ProcLabel)).
-same_label_ref(exported(ProcLabel), c_local(ProcLabel)).
-same_label_ref(exported(ProcLabel), local(ProcLabel)).
-same_label_ref(local(ProcLabel), c_local(ProcLabel)).
-same_label_ref(local(ProcLabel), local(ProcLabel)).
-same_label_ref(c_local(ProcLabel), c_local(ProcLabel)).
+matching_entry_type(exported, exported).
+matching_entry_type(exported, c_local).
+matching_entry_type(exported, local).
+matching_entry_type(local, c_local).
+matching_entry_type(local, local).
+matching_entry_type(c_local, c_local).
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -694,7 +827,7 @@
 		BlockInfo0 = block_info(Label, OrigInstrs, [_], no,
 			teardown(Succip, Livevals, Goto)),
 		Goto = goto(label(GotoLabel)) - Comment,
-		same_label_ref(FirstLabel, GotoLabel)
+		matching_label_ref(FirstLabel, GotoLabel)
 	->
 		(
 			OrigInstrs = [OrigInstr0 | _],
@@ -1069,7 +1202,7 @@
 				% stack frame, so we must create one.
 
 				counter__allocate(N, !C),
-				NewLabel = local(N, ProcLabel),
+				NewLabel = internal(N, ProcLabel),
 				MaybeFallThrough = yes(NewLabel),
 				MaybeNewLabel = yes(NewLabel),
 				SetupCode = [
@@ -1158,7 +1291,7 @@
 		Label = OldParallel
 	;
 		counter__allocate(N, !C),
-		NewParallel = local(N, ProcLabel),
+		NewParallel = internal(N, ProcLabel),
 		Label = NewParallel,
 		map__det_insert(!.ParMap, Label0, NewParallel, !:ParMap)
 	).
Index: compiler/jumpopt.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/jumpopt.m,v
retrieving revision 1.70
diff -u -b -r1.70 jumpopt.m
--- compiler/jumpopt.m	23 May 2004 22:16:44 -0000	1.70
+++ compiler/jumpopt.m	23 May 2004 22:18:04 -0000
@@ -19,33 +19,36 @@
 
 :- import_module list, set, bool, counter.
 
-	% Take an instruction list and optimize jumps. This includes jumps
-	% implicit in procedure returns.
+	% jumpopt_main(LayoutLabels, MayAlterRtti, ProcLabel, Fulljumpopt,
+	%	Recjump, PessimizeTailCalls, CheckedNondetTailCall,
+	%	!LabelCounter, !Instrs, Mod):
 	%
-	% The second argument gives the set of labels that have layout
-	% structures. This module will not optimize jumps to labels in this
-	% set, since this may interfere with the RTTI recorded for these
-	% labels. The third argument says whether we are allowed to perform
-	% optimizations that may interfere with RTTI.
+	% Take an instruction list and optimize jumps. This includes the jumps
+	% implicit in procedure returns.
 	%
-	% The final four bool inputs should be
+	% LayoutLabels gives the set of labels that have layout structures.
+	% This module will not optimize jumps to labels in this set, since
+	% this may interfere with the RTTI recorded for these labels.
+	% MayAlterRtti says whether we are allowed to perform optimizations
+	% that may interfere with RTTI.
 	%
-	% - the value of the --optimize-fulljumps option,
+	% Fulljumpopt should be the value of the --optimize-fulljumps option.
 	%
-	% - an indication of whether this is the final application of this
-	%   optimization,
+	% Recjump should be an indication of whether this is the final
+	% application of this optimization.
 	%
-	% - the value of the --pessimize-tailcalls option, and
+	% PessimizeTailCalls should be the value of the --pessimize-tailcalls
+	% option.
 	%
-	% - the value of the --checked-nondet-tailcalls option respectively.
+	% CheckedNondetTailCall should be the value of the
+	% --checked-nondet-tailcalls option.
 	%
-	% The bool output says whether the instruction sequence was modified
+	% Mod will say whether the instruction sequence was modified
 	% by the optimization.
 
-:- pred jumpopt_main(list(instruction)::in, set(label)::in, may_alter_rtti::in,
-	proc_label::in, counter::in, counter::out,
-	bool::in, bool::in, bool::in, bool::in,
-	list(instruction)::out, bool::out) is det.
+:- pred jumpopt_main(set(label)::in, may_alter_rtti::in, proc_label::in,
+	bool::in, bool::in, bool::in, bool::in, counter::in, counter::out,
+	list(instruction)::in, list(instruction)::out, bool::out) is det.
 
 %-----------------------------------------------------------------------------%
 
@@ -81,9 +84,9 @@
 % frameopt, which can do a better job of optimizing this block, have
 % been applied.
 
-jumpopt_main(Instrs0, LayoutLabels, MayAlterRtti, ProcLabel, C0, C,
-		Fulljumpopt, Recjump, PessimizeTailCalls,
-		CheckedNondetTailCall, Instrs, Mod) :-
+jumpopt_main(LayoutLabels, MayAlterRtti, ProcLabel, Fulljumpopt, Recjump,
+		PessimizeTailCalls, CheckedNondetTailCall, !C, Instrs0, Instrs,
+		Mod) :-
 	map__init(Instrmap0),
 	map__init(Lvalmap0),
 	map__init(Procmap0),
@@ -111,14 +114,14 @@
 	),
 	(
 		CheckedNondetTailCall = yes,
-		CheckedNondetTailCallInfo0 = yes(ProcLabel - C0),
+		CheckedNondetTailCallInfo0 = yes(ProcLabel - !.C),
 		jumpopt__instr_list(Instrs0, comment(""), Instrmap, Blockmap,
 			Lvalmap, Procmap, Sdprocmap, Forkmap, Succmap,
 			LayoutLabels, Fulljumpopt, MayAlterRtti,
 			CheckedNondetTailCallInfo0, CheckedNondetTailCallInfo,
 			Instrs1),
-		( CheckedNondetTailCallInfo = yes(_ - Cprime) ->
-			C = Cprime
+		( CheckedNondetTailCallInfo = yes(_ - !:C) ->
+			true
 		;
 			error("jumpopt_main: lost the next label number")
 		)
@@ -128,8 +131,7 @@
 		jumpopt__instr_list(Instrs0, comment(""), Instrmap, Blockmap,
 			Lvalmap, Procmap, Sdprocmap, Forkmap, Succmap,
 			LayoutLabels, Fulljumpopt, MayAlterRtti,
-			CheckedNondetTailCallInfo0, _, Instrs1),
-		C = C0
+			CheckedNondetTailCallInfo0, _, Instrs1)
 	),
 	opt_util__filter_out_bad_livevals(Instrs1, Instrs),
 	( Instrs = Instrs0 ->
@@ -180,10 +182,10 @@
 		;
 			true
 		),
-		% put the start of the procedure into Blockmap
-		% only after frameopt and value_number have had a shot at it
+		% Put the start of the procedure into Blockmap only after
+		% frameopt has had a shot at it.
 		(
-			( Label = local(_, _)
+			( Label = internal(_, _)
 			; Recjump = yes
 			)
 		->
@@ -320,7 +322,7 @@
 			not set__member(RetLabel, LayoutLabels)
 		->
 			counter__allocate(LabelNum, Counter0, Counter1),
-			NewLabel = local(LabelNum, ProcLabel),
+			NewLabel = internal(LabelNum, ProcLabel),
 			NewInstrs = [
 				if_val(binop(ne, lval(curfr), lval(maxfr)),
 					label(NewLabel))
@@ -533,6 +535,43 @@
 			% strictly reduces the size of the code.
 			RemainInstrs = [NewInstr | AfterGoto]
 		;
+			% Attempt to transform code such as
+			%
+			%	if (Cond) L1
+			%	goto L2
+			%
+			% into
+			%
+			%	if (! Cond) L2
+			% 	<code at L1>
+			%
+			% when we know the code at L1 and don't know the code
+			% at L2. Here, we just generate
+			%
+			%	if (! Cond) L2
+			% 	goto L1
+			%
+			% and get the code processed again starting after the
+			% if_val, to get the recursive call to replace the goto
+			% to L1 with the code at L1.
+			Fulljumpopt = yes,
+			map__search(Blockmap, TargetLabel, _TargetBlock),
+			opt_util__skip_comments(Instrs0, Instrs1),
+			Instrs1 = [GotoInstr | AfterGoto],
+			GotoInstr = goto(GotoAddr) - GotoComment,
+			\+ (
+				GotoAddr = label(GotoLabel),
+				map__search(Blockmap, GotoLabel, _)
+			)
+		->
+			code_util__neg_rval(Cond, NotCond),
+			NewIfInstr = if_val(NotCond, GotoAddr) - GotoComment,
+			NewInstrs = [NewIfInstr],
+			NewGotoComment = Comment0 ++ " (switched)",
+			NewGotoInstr = goto(label(TargetLabel)) -
+				NewGotoComment,
+			RemainInstrs = [NewGotoInstr | AfterGoto]
+		;
 			map__search(Instrmap, TargetLabel, TargetInstr)
 		->
 			jumpopt__final_dest(Instrmap, TargetLabel, DestLabel,
@@ -609,7 +648,7 @@
 				Shorted),
 			NewInstrs = [assign(Lval, Rval) - Shorted]
 		)
-	; Uinstr0 = mkframe(FrameInfo, label(Label0)) ->
+	; Uinstr0 = mkframe(FrameInfo, yes(label(Label0))) ->
 		jumpopt__short_label(Instrmap, Label0, Label),
 		RemainInstrs = Instrs0,
 		( Label = Label0 ->
@@ -617,7 +656,7 @@
 		;
 			string__append(Comment0, " (some shortcircuits)",
 				Shorted),
-			NewInstrs = [mkframe(FrameInfo, label(Label))
+			NewInstrs = [mkframe(FrameInfo, yes(label(Label)))
 				- Shorted]
 		)
 	;
Index: compiler/labelopt.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/labelopt.m,v
retrieving revision 1.22
diff -u -b -r1.22 labelopt.m
--- compiler/labelopt.m	15 Mar 2003 03:08:54 -0000	1.22
+++ compiler/labelopt.m	23 May 2004 22:18:04 -0000
@@ -23,8 +23,8 @@
 	% If the instruction before the label branches away, we also
 	% remove the instruction block following the label.
 
-:- pred labelopt_main(list(instruction)::in, bool::in, set(label)::in,
-	list(instruction)::out, bool::out) is det.
+:- pred labelopt_main(bool::in, set(label)::in,
+	list(instruction)::in, list(instruction)::out, bool::out) is det.
 
 	% Build up a set showing which labels are referred to.
 	% The input set is the list of labels referred to from outside
@@ -41,11 +41,11 @@
 
 :- import_module std_util.
 
-labelopt_main(Instrs0, Final, LayoutLabelSet, Instrs, Mod) :-
+labelopt_main(Final, LayoutLabelSet, Instrs0, Instrs, Mod) :-
 	labelopt__build_useset(Instrs0, LayoutLabelSet, Useset),
 	labelopt__instr_list(Instrs0, yes, Useset, Instrs1, Mod),
 	( Final = yes, Mod = yes ->
-		labelopt_main(Instrs1, Final, LayoutLabelSet, Instrs, _)
+		labelopt_main(Final, LayoutLabelSet, Instrs1, Instrs, _)
 	;
 		Instrs = Instrs1
 	).
@@ -76,9 +76,13 @@
 	Instr0 = Uinstr0 - _Comment,
 	( Uinstr0 = label(Label) ->
 		(
-			( Label = exported(_)
-			; Label = local(_)
-			; set__member(Label, Useset)
+			(
+				Label = entry(EntryType, _),
+				( EntryType = exported
+				; EntryType = local
+				)
+			;
+				set__member(Label, Useset)
 			)
 		->
 			ReplInstrs = [Instr0],
Index: compiler/layout.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/layout.m,v
retrieving revision 1.13
diff -u -b -r1.13 layout.m
--- compiler/layout.m	19 May 2004 03:59:19 -0000	1.13
+++ compiler/layout.m	23 May 2004 22:18:04 -0000
@@ -45,7 +45,8 @@
 
 :- type layout_data
 	--->	label_layout_data(		% defines MR_Label_Layout
-			label			:: label,
+			proc_label		:: proc_label,
+			label_num		:: int,
 			proc_layout_name	:: layout_name,
 			maybe_port		:: maybe(trace_port),
 			maybe_is_hidden		:: maybe(bool),
@@ -176,7 +177,7 @@
 %-----------------------------------------------------------------------------%
 
 :- type layout_name
-	--->	label_layout(label, label_vars)
+	--->	label_layout(proc_label, int, label_vars)
 	;	proc_layout(rtti_proc_label, proc_layout_kind)
 		% A proc layout structure for stack tracing, accurate gc,
 		% deep profiling and/or execution tracing.
Index: compiler/layout_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/layout_out.m,v
retrieving revision 1.33
diff -u -b -r1.33 layout_out.m
--- compiler/layout_out.m	20 May 2004 22:53:29 -0000	1.33
+++ compiler/layout_out.m	23 May 2004 22:18:04 -0000
@@ -98,10 +98,10 @@
 
 :- import_module int, char, string, require, std_util, list.
 
-output_layout_data_defn(label_layout_data(Label, ProcLayoutAddr,
+output_layout_data_defn(label_layout_data(ProcLabel, LabelNum, ProcLayoutAddr,
 		MaybePort, MaybeIsHidden, MaybeGoalPath, MaybeVarInfo),
 		!DeclSet, !IO) :-
-	output_label_layout_data_defn(Label, ProcLayoutAddr,
+	output_label_layout_data_defn(ProcLabel, LabelNum, ProcLayoutAddr,
 		MaybePort, MaybeIsHidden, MaybeGoalPath, MaybeVarInfo,
 		!DeclSet, !IO).
 output_layout_data_defn(proc_layout_data(ProcLabel, Traversal, MaybeRest),
@@ -148,10 +148,12 @@
 
 :- pred extract_layout_name(layout_data::in, layout_name::out) is det.
 
-extract_layout_name(label_layout_data(Label, _, _, _, _, yes(_)), LayoutName) :-
-	LayoutName = label_layout(Label, label_has_var_info).
-extract_layout_name(label_layout_data(Label, _, _, _, _, no), LayoutName) :-
-	LayoutName = label_layout(Label, label_has_no_var_info).
+extract_layout_name(label_layout_data(ProcLabel, LabelNum, _, _, _, _, yes(_)),
+		LayoutName) :-
+	LayoutName = label_layout(ProcLabel, LabelNum, label_has_var_info).
+extract_layout_name(label_layout_data(ProcLabel, LabelNum, _, _, _, _, no),
+		LayoutName) :-
+	LayoutName = label_layout(ProcLabel, LabelNum, label_has_no_var_info).
 extract_layout_name(proc_layout_data(RttiProcLabel, _, MaybeRest),
 		LayoutName) :-
 	ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
@@ -194,11 +196,12 @@
 		LabelName
 	], Name).
 
-output_layout_name(label_layout(Label, _)) -->
+output_layout_name(label_layout(ProcLabel, LabelNum, _)) -->
 	% This code should be kept in sync with make_label_layout_name/1 above.
 	io__write_string(mercury_data_prefix),
 	io__write_string("_label_layout__"),
-	io__write_string(label_to_c_string(Label, yes)).
+	io__write_string(label_to_c_string(internal(LabelNum, ProcLabel),
+		yes)).
 output_layout_name(proc_layout(RttiProcLabel, _)) -->
 	io__write_string(mercury_data_prefix),
 	io__write_string("_proc_layout__"),
@@ -297,12 +300,13 @@
 	{ ProcLabel = make_proc_label_from_rtti(RttiProcLabel) },
 	output_proc_label(ProcLabel, no).
 
-output_layout_name_storage_type_name(label_layout(Label, LabelVars),
+output_layout_name_storage_type_name(
+		label_layout(ProcLabel, LabelNum, LabelVars),
 		_BeingDefined) -->
 	io__write_string("static const "),
 	io__write_string(label_vars_to_type(LabelVars)),
 	io__write_string(" "),
-	output_layout_name(label_layout(Label, LabelVars)).
+	output_layout_name(label_layout(ProcLabel, LabelNum, LabelVars)).
 output_layout_name_storage_type_name(proc_layout(ProcLabel, Kind),
 		BeingDefined) -->
 	{ ProcIsImported = ProcLabel ^ proc_is_imported },
@@ -415,7 +419,7 @@
 	output_layout_name(table_gen_steps(RttiProcLabel)),
 	io__write_string("[]").
 
-layout_name_would_include_code_addr(label_layout(_, _)) = no.
+layout_name_would_include_code_addr(label_layout(_, _, _)) = no.
 layout_name_would_include_code_addr(proc_layout(_, _)) = no.
 layout_name_would_include_code_addr(proc_layout_exec_trace(_)) = yes.
 layout_name_would_include_code_addr(proc_layout_head_var_nums(_)) = no.
@@ -467,13 +471,13 @@
 	io__write_int(Num, !IO).
 output_rval_or_num_or_none(none, !IO).
 
-:- pred output_label_layout_data_defn(label::in, layout_name::in,
+:- pred output_label_layout_data_defn(proc_label::in, int::in, layout_name::in,
 	maybe(trace_port)::in, maybe(bool)::in, maybe(int)::in,
 	maybe(label_var_info)::in, decl_set::in, decl_set::out,
 	io::di, io::uo) is det.
 
-output_label_layout_data_defn(Label, ProcLayoutAddr, MaybePort, MaybeIsHidden,
-		MaybeGoalPath, MaybeVarInfo, !DeclSet, !IO) :-
+output_label_layout_data_defn(ProcLabel, LabelNum, ProcLayoutAddr, MaybePort,
+		MaybeIsHidden, MaybeGoalPath, MaybeVarInfo, !DeclSet, !IO) :-
 	output_layout_decl(ProcLayoutAddr, !DeclSet, !IO),
 	(
 		MaybeIsHidden = yes(yes),
@@ -544,11 +548,10 @@
 		Macro = "MR_DEF_LLNVI" ++ HiddenChars,
 		MaybeVarInfoTuple = no
 	),
-	LayoutName = label_layout(Label, LabelVars),
+	LayoutName = label_layout(ProcLabel, LabelNum, LabelVars),
 	io__write_string("\n", !IO),
 	io__write_string(Macro, !IO),
 	io__write_string("(", !IO),
-	break_up_local_label(Label, ProcLabel, LabelNum),
 	output_proc_label(ProcLabel, no, !IO),
 	io__write_string(",\n", !IO),
 	io__write_int(LabelNum, !IO),
@@ -822,8 +825,8 @@
 	output_layout_name_storage_type_name(
 		proc_layout_exec_trace(RttiProcLabel), yes, !IO),
 	io__write_string(" = {\nMR_LABEL_LAYOUT_REF(", !IO),
-	( CallLabelLayout = label_layout(CallLabel, _) ->
-		output_label(CallLabel, no, !IO)
+	( CallLabelLayout = label_layout(CallProcLabel, CallLabelNum, _) ->
+		output_label(internal(CallLabelNum, CallProcLabel), no, !IO)
 	;
 		error("output_layout_exec_trace: bad call layout")
 	),
@@ -1290,9 +1293,9 @@
 project_label_layout(DataAddr, Label) :-
 	(
 		DataAddr = layout_addr(LayoutName),
-		LayoutName = label_layout(LabelPrime, _)
+		LayoutName = label_layout(ProcLabel, LabelNum, _)
 	->
-		Label = LabelPrime
+		Label = internal(LabelNum, ProcLabel)
 	;
 		error("project_label_layout: not label layout")
 	).
@@ -1303,7 +1306,7 @@
 output_label_layout_addrs_in_vector([], !IO).
 output_label_layout_addrs_in_vector([Label | Labels], !IO) :-
 	(
-		Label = local(LabelNum, ProcLabel),
+		Label = internal(LabelNum, ProcLabel),
 		groupable_labels(ProcLabel, 1, N, [LabelNum], RevLabelNums,
 			Labels, RemainingLabels),
 		N > 1
@@ -1335,7 +1338,7 @@
 		!.Labels = [Label | !:Labels],
 		MaxChunkSize = 9,
 		!.Count < MaxChunkSize,	% leave room for the one we're adding
-		Label = local(LabelNum, ProcLabel)
+		Label = internal(LabelNum, ProcLabel)
 	->
 		!:Count = !.Count + 1,
 		!:RevLabelsNums = [LabelNum | !.RevLabelsNums],
Index: compiler/llds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds.m,v
retrieving revision 1.304
diff -u -b -r1.304 llds.m
--- compiler/llds.m	23 May 2004 22:16:44 -0000	1.304
+++ compiler/llds.m	23 May 2004 22:18:04 -0000
@@ -255,17 +255,21 @@
 			% tail recursion elimination is potentially applicable
 			% to the call.
 
-	;	mkframe(nondet_frame_info, code_addr)
-			% mkframe(NondetFrameInfo, CodeAddr) creates a nondet
+	;	mkframe(nondet_frame_info, maybe(code_addr))
+			% mkframe(NondetFrameInfo, MaybeAddr) creates a nondet
 			% stack frame. NondetFrameInfo says whether the frame
 			% is an ordinary frame, containing the variables of a
 			% model_non procedure, or a temp frame used only for
 			% its redoip/redofr slots. If the former, it also
 			% gives the details of the size of the variable parts
 			% of the frame (temp frames have no variable sized
-			% parts). CodeAddr is the code address to branch to
-			% when trying to generate the next solution from this
-			% choice point.
+			% parts). If MaybeAddr = yes(CodeAddr), then CodeAddr
+			% is the code address to branch to when trying to
+			% generate the next solution from this choice point.
+			% If MaybeAddr = no, then the field of the choice
+			% point that contains this information is not filled
+			% in by mkframe; it is up to the code following to do
+			% so.
 
 	;	label(label)
 			% Defines a label that can be used as the
@@ -880,14 +884,30 @@
 	--->	r		% general-purpose (integer) regs
 	;	f.		% floating point regs
 
+	% There are two kinds of labels: entry labels and internal labels.
+	% Entry labels are the entry points of procedures; internal labels
+	% are not.
+	%
+	% We have three ways of referring to entry labels. One way is valid
+	% from everywhere in the program (external). Another way is valid
+	% only from within the C file that defines the procedure (local).
+	% The last is valid only from within the BEGIN_MODULE/END_MODULE pair
+	% that contains the procedure definition. The more specialized the
+	% reference, the faster jumping to the label may be, though the
+	% implementations of adjacent entry_label_types may be identical
+	% in some grades.
+	%
+	% It is valid to declare a label using one entry_label_type and to
+	% refer to it using a more specialized entry_label_type.
+
+:- type entry_label_type
+	--->	c_local		% proc entry; internal to a C module
+	;	local		% proc entry; internal to a Mercury module
+	;	exported.	% proc entry; exported from a Mercury module
+
 :- type label
-	--->	local(int, proc_label)	% not proc entry; internal to a
-					% procedure
-	;	c_local(proc_label)	% proc entry; internal to a C module
-	;	local(proc_label)	% proc entry; internal to a Mercury
-					% module
-	;	exported(proc_label).	% proc entry; exported from a Mercury
-					% module
+	--->	internal(int, proc_label)
+	;	entry(entry_label_type, proc_label).
 
 :- type code_addr
 	--->	label(label)		% A label defined in this Mercury
@@ -1034,11 +1054,11 @@
 	).
 
 break_up_local_label(Label, ProcLabel, LabelNum) :-
-	( Label = local(LabelNumPrime, ProcLabelPrime) ->
-		LabelNum = LabelNumPrime,
-		ProcLabel = ProcLabelPrime
+	(
+		Label = internal(LabelNum, ProcLabel)
 	;
-		error("break_up_local_label: bad label")
+		Label = entry(_, _),
+		error("break_up_local_label: entry label")
 	).
 
 llds__wrap_rtti_data(RttiData, rtti_data(RttiData)).
@@ -1160,10 +1180,8 @@
 llds__register_type(r, word).
 llds__register_type(f, float).
 
-get_proc_label(exported(ProcLabel)) = ProcLabel.
-get_proc_label(local(ProcLabel)) = ProcLabel.
-get_proc_label(c_local(ProcLabel)) = ProcLabel.
-get_proc_label(local(_, ProcLabel)) = ProcLabel.
+get_proc_label(entry(_, ProcLabel)) = ProcLabel.
+get_proc_label(internal(_, ProcLabel)) = ProcLabel.
 
 get_defining_module_name(proc(ModuleName, _, _, _, _, _)) = ModuleName.
 get_defining_module_name(special_proc(ModuleName, _, _, _, _, _)) = ModuleName.
Index: compiler/llds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds_out.m,v
retrieving revision 1.232
diff -u -b -r1.232 llds_out.m
--- compiler/llds_out.m	20 May 2004 22:04:43 -0000	1.232
+++ compiler/llds_out.m	23 May 2004 22:18:04 -0000
@@ -463,7 +463,7 @@
 		!OtherLayouts) :-
 	( Layout = proc_layout_data(_, _, _) ->
 		!:ProcLayouts = [Layout | !.ProcLayouts]
-	; Layout = label_layout_data(_, _, _, _, _, _) ->
+	; Layout = label_layout_data(_, _, _, _, _, _, _) ->
 		!:LabelLayouts = [Layout | !.LabelLayouts]
 	;
 		!:OtherLayouts = [Layout | !.OtherLayouts]
@@ -1145,11 +1145,13 @@
 		!DeclLLMap, !OtherLocalMap, !RevAddrsToDecl, !RevOthers).
 group_c_labels_with_layouts(StackLayoutLabels, [Label | Labels],
 		!DeclLLMap, !OtherLocalMap, !RevAddrsToDecl, !RevOthers) :-
-	( Label = local(LabelNum, ProcLabel) ->
+	(
+		Label = internal(LabelNum, ProcLabel),
 		( map__search(StackLayoutLabels, Label, DataAddr) ->
 			(
 				DataAddr = layout_addr(LayoutName),
-				LayoutName = label_layout(Label, LabelVars),
+				LayoutName = label_layout(ProcLabel, LabelNum,
+					LabelVars),
 				LabelVars = label_has_var_info
 			->
 				multi_map__set(!.DeclLLMap, ProcLabel,
@@ -1165,6 +1167,7 @@
 				!:OtherLocalMap)
 		)
 	;
+		Label = entry(_, _),
 		!:RevOthers = [Label | !.RevOthers]
 	),
 	group_c_labels_with_layouts(StackLayoutLabels, Labels,
@@ -1226,8 +1229,7 @@
 	decl_set::in, decl_set::out) is det.
 
 insert_var_info_label_layout_decl(ProcLabel, LabelNum, !DeclSet) :-
-	Label = local(LabelNum, ProcLabel),
-	LayoutName = label_layout(Label, label_has_var_info),
+	LayoutName = label_layout(ProcLabel, LabelNum, label_has_var_info),
 	DataAddr = layout_addr(LayoutName),
 	DeclId = data_addr(DataAddr),
 	decl_set_insert(DeclId, !DeclSet).
@@ -1236,7 +1238,7 @@
 	decl_set::in, decl_set::out) is det.
 
 insert_code_addr_decl(ProcLabel, LabelNum, !DeclSet) :-
-	DeclId = code_addr(label(local(LabelNum, ProcLabel))),
+	DeclId = code_addr(label(internal(LabelNum, ProcLabel))),
 	decl_set_insert(DeclId, !DeclSet).
 
 :- pred output_c_label_decl(map(label, data_addr)::in, label::in,
@@ -1248,9 +1250,10 @@
 	%
 	( map__search(StackLayoutLabels, Label, DataAddr) ->
 		(
-			Label = local(LabelNum, ProcLabel),
+			Label = internal(LabelNum, ProcLabel),
 			DataAddr = layout_addr(LayoutName),
-			LayoutName = label_layout(Label, LabelVars)
+			LayoutName = label_layout(ProcLabel, LabelNum,
+				LabelVars)
 		->
 			(
 				LabelVars = label_has_var_info,
@@ -1282,10 +1285,10 @@
 		% Declare the label itself.
 		%
 		(
-			Label = exported(_),
+			Label = entry(exported, _),
 			DeclMacro = "MR_def_extern_entry("
 		;
-			Label = local(_),
+			Label = entry(local, _),
 			% The code for procedures local to a Mercury module
 			% should normally be visible only within the C file
 			% generated for that module. However, if we generate
@@ -1299,10 +1302,10 @@
 				DeclMacro = "MR_def_extern_entry("
 			)
 		;
-			Label = c_local(_),
+			Label = entry(c_local, _),
 			DeclMacro = "MR_decl_local("
 		;
-			Label = local(_, _),
+			Label = internal(_, _),
 			DeclMacro = "MR_decl_label("
 		),
 		io__write_string(DeclMacro, !IO),
@@ -1341,7 +1344,8 @@
 group_c_labels(_StackLayoutLabels, [], !NoLayoutMap, !LayoutMap, !RevOthers).
 group_c_labels(StackLayoutLabels, [Label | Labels], !NoLayoutMap, !LayoutMap,
 		!RevOthers) :-
-	( Label = local(LabelNum, ProcLabel) ->
+	(
+		Label = internal(LabelNum, ProcLabel),
 		( map__search(StackLayoutLabels, Label, _DataAddr) ->
 			multi_map__set(!.LayoutMap, ProcLabel, LabelNum,
 				!:LayoutMap)
@@ -1350,6 +1354,7 @@
 				!:NoLayoutMap)
 		)
 	;
+		Label = entry(_, _),
 		!:RevOthers = [Label | !.RevOthers]
 	),
 	group_c_labels(StackLayoutLabels, Labels, !NoLayoutMap, !LayoutMap,
@@ -1402,18 +1407,18 @@
 		InitProcLayout = no
 	),
 	(
-		Label = exported(ProcLabel),
+		Label = entry(exported, ProcLabel),
 		TabInitMacro = "\tMR_init_entry1"
 	;
-		Label = local(ProcLabel),
+		Label = entry(local, ProcLabel),
 		TabInitMacro = "\tMR_init_entry1"
 	;
-		Label = c_local(ProcLabel),
+		Label = entry(c_local, ProcLabel),
 		TabInitMacro = "\tMR_init_local1"
 	;
-		Label = local(_, _),
+		Label = internal(_, _),
 		% These should have been separated out by group_c_labels.
-		error("output_c_label_init: local/2")
+		error("output_c_label_init: internal/2")
 	),
 	io__write_string(TabInitMacro, !IO),
 	io__write_string(SuffixOpen, !IO),
@@ -1429,10 +1434,8 @@
 
 :- pred label_is_proc_entry(label::in, bool::out) is det.
 
-label_is_proc_entry(local(_, _), no).
-label_is_proc_entry(c_local(_), yes).
-label_is_proc_entry(local(_), yes).
-label_is_proc_entry(exported(_), yes).
+label_is_proc_entry(internal(_, _), no).
+label_is_proc_entry(entry(_, _), yes).
 
 :- pred output_c_procedure_decls(map(label, data_addr)::in, c_procedure::in,
 	decl_set::in, decl_set::out, io::di, io::uo) is det.
@@ -1492,9 +1495,11 @@
 	error("cannot find caller label").
 llds_out__find_caller_label([Instr0 - _ | Instrs], CallerLabel) :-
 	( Instr0 = label(Label) ->
-		( Label = local(_, _) ->
+		(
+			Label = internal(_, _),
 			error("caller label is internal label")
 		;
+			Label = entry(_, _),
 			CallerLabel = Label
 		)
 	;
@@ -1513,12 +1518,12 @@
 		(
 			Instr = call(_, label(ContLabel), _, _, _, _)
 		;
-			Instr = mkframe(_, label(ContLabel))
+			Instr = mkframe(_, yes(label(ContLabel)))
 		;
 			Instr = join_and_continue(_, ContLabel)
 		;
-			Instr = assign(redoip(lval(_)),
-				const(code_addr_const(label(ContLabel))))
+			Instr = assign(redoip(_), const(Const)),
+			Const = code_addr_const(label(ContLabel))
 		)
 	->
 		bintree_set__insert(!.ContLabelSet, ContLabel, !:ContLabelSet)
@@ -1614,7 +1619,7 @@
 	output_code_addr_decls(Target, !DeclSet, !IO),
 	output_code_addr_decls(ContLabel, !DeclSet, !IO).
 output_instr_decls(_, c_code(_, _), !DeclSet, !IO).
-output_instr_decls(_, mkframe(FrameInfo, FailureContinuation),
+output_instr_decls(_, mkframe(FrameInfo, MaybeFailureContinuation),
 		!DeclSet, !IO) :-
 	(
 		FrameInfo = ordinary_frame(_, _, yes(Struct)),
@@ -1634,11 +1639,13 @@
 		io__write_string("struct ", !IO),
 		io__write_string(StructName, !IO),
 		io__write_string(" {\n", !IO),
-		( MaybeStructFieldsContext = yes(StructFieldsContext) ->
+		(
+			MaybeStructFieldsContext = yes(StructFieldsContext),
 			output_set_line_num(StructFieldsContext, !IO),
 			io__write_string(StructFields, !IO),
 			output_reset_line_num(!IO)
 		;
+			MaybeStructFieldsContext = no,
 			io__write_string(StructFields, !IO)
 		),
 		io__write_string("\n};\n", !IO),
@@ -1646,7 +1653,12 @@
 	;
 		true
 	),
-	output_code_addr_decls(FailureContinuation, !DeclSet, !IO).
+	(
+		MaybeFailureContinuation = yes(FailureContinuation),
+		output_code_addr_decls(FailureContinuation, !DeclSet, !IO)
+	;
+		MaybeFailureContinuation = no
+	).
 output_instr_decls(_, label(_), !DeclSet, !IO).
 output_instr_decls(_, goto(CodeAddr), !DeclSet, !IO) :-
 	output_code_addr_decls(CodeAddr, !DeclSet, !IO).
@@ -1811,8 +1823,9 @@
 	bintree_set__init(ContLabelSet),
 	DummyModule = unqualified("DEBUG"),
 	DummyPredName = "DEBUG",
-	ProfInfo = local(proc(DummyModule, predicate, DummyModule,
-		DummyPredName, 0, hlds_pred__initial_proc_id)) - ContLabelSet,
+	ProcLabel = proc(DummyModule, predicate, DummyModule,
+		DummyPredName, 0, hlds_pred__initial_proc_id),
+	ProfInfo = entry(local, ProcLabel) - ContLabelSet,
 	output_instruction_and_comment(Instr, Comment, PrintComments,
 		ProfInfo, !IO).
 
@@ -1823,8 +1836,9 @@
 	bintree_set__init(ContLabelSet),
 	DummyModule = unqualified("DEBUG"),
 	DummyPredName = "DEBUG",
-	ProfInfo = local(proc(DummyModule, predicate, DummyModule,
-		DummyPredName, 0, hlds_pred__initial_proc_id)) - ContLabelSet,
+	ProcLabel = proc(DummyModule, predicate, DummyModule,
+		DummyPredName, 0, hlds_pred__initial_proc_id),
+	ProfInfo = entry(local, ProcLabel) - ContLabelSet,
 	output_instruction(Instr, ProfInfo, !IO).
 
 :- pred output_instruction(instr::in, pair(label, bintree_set(label))::in,
@@ -1877,10 +1891,13 @@
 	io__write_string("\t", !IO),
 	io__write_string(C_Code_String, !IO).
 
-output_instruction(mkframe(FrameInfo, FailCont), _, !IO) :-
+output_instruction(mkframe(FrameInfo, MaybeFailCont), _, !IO) :-
 	(
 		FrameInfo = ordinary_frame(Msg, Num, MaybeStruct),
-		( MaybeStruct = yes(pragma_c_struct(StructName, _, _)) ->
+		(
+			MaybeStruct = yes(pragma_c_struct(StructName, _, _)),
+			(
+				MaybeFailCont = yes(FailCont),
 			io__write_string("\tMR_mkpragmaframe(""", !IO),
 			c_util__output_quoted_string(Msg, !IO),
 			io__write_string(""", ", !IO),
@@ -1891,6 +1908,21 @@
 			output_code_addr(FailCont, !IO),
 			io__write_string(");\n", !IO)
 		;
+				MaybeFailCont = no,
+				io__write_string(
+					"\tMR_mkpragmaframe_no_redoip(""",
+					!IO),
+				c_util__output_quoted_string(Msg, !IO),
+				io__write_string(""", ", !IO),
+				io__write_int(Num, !IO),
+				io__write_string(", ", !IO),
+				io__write_string(StructName, !IO),
+				io__write_string(");\n", !IO)
+			)
+		;
+			MaybeStruct = no,
+			(
+				MaybeFailCont = yes(FailCont),
 			io__write_string("\tMR_mkframe(""", !IO),
 			c_util__output_quoted_string(Msg, !IO),
 			io__write_string(""", ", !IO),
@@ -1898,18 +1930,39 @@
 			io__write_string(", ", !IO),
 			output_code_addr(FailCont, !IO),
 			io__write_string(");\n", !IO)
+			;
+				MaybeFailCont = no,
+				io__write_string("\tMR_mkframe_no_redoip(""",
+					!IO),
+				c_util__output_quoted_string(Msg, !IO),
+				io__write_string(""", ", !IO),
+				io__write_int(Num, !IO),
+				io__write_string(");\n", !IO)
+			)
 		)
 	;
 		FrameInfo = temp_frame(Kind),
 		(
 			Kind = det_stack_proc,
 			io__write_string("\tMR_mkdettempframe(", !IO),
-			output_code_addr(FailCont, !IO),
+			(
+				MaybeFailCont = yes(FailCont),
+				output_code_addr(FailCont, !IO)
+			;
+				MaybeFailCont = no,
+				error("output_instruction: no failcont")
+			),
 			io__write_string(");\n", !IO)
 		;
 			Kind = nondet_stack_proc,
 			io__write_string("\tMR_mktempframe(", !IO),
-			output_code_addr(FailCont, !IO),
+			(
+				MaybeFailCont = yes(FailCont),
+				output_code_addr(FailCont, !IO)
+			;
+				MaybeFailCont = no,
+				error("output_instruction: no failcont")
+			),
 			io__write_string(");\n", !IO)
 		)
 	).
@@ -3043,16 +3096,16 @@
 
 need_code_addr_decls(label(Label), Need, !IO) :-
 	(
-		Label = exported(_),
+		Label = entry(exported, _),
 		Need = yes
 	;
-		Label = local(_),
+		Label = entry(local, _),
 		Need = yes
 	;
-		Label = c_local(_),
+		Label = entry(c_local, _),
 		Need = no
 	;
-		Label = local(_, _),
+		Label = internal(_, _),
 		Need = no
 	).
 need_code_addr_decls(imported(_), yes, !IO).
@@ -3130,21 +3183,22 @@
 
 :- pred output_label_as_code_addr_decls(label::in, io::di, io::uo) is det.
 
-output_label_as_code_addr_decls(exported(ProcLabel), !IO) :-
+output_label_as_code_addr_decls(entry(exported, ProcLabel), !IO) :-
 	io__write_string("MR_decl_entry(", !IO),
-	output_label(exported(ProcLabel), no, !IO),
+	output_label(entry(exported, ProcLabel), no, !IO),
 	io__write_string(");\n", !IO).
-output_label_as_code_addr_decls(local(ProcLabel), !IO) :-
+output_label_as_code_addr_decls(entry(local, ProcLabel), !IO) :-
 	globals__io_lookup_bool_option(split_c_files, SplitFiles, !IO),
-	( SplitFiles = no ->
-		true
+	(
+		SplitFiles = no
 	;
+		SplitFiles = yes,
 		io__write_string("MR_decl_entry(", !IO),
-		output_label(local(ProcLabel), no, !IO),
+		output_label(entry(local, ProcLabel), no, !IO),
 		io__write_string(");\n", !IO)
 	).
-output_label_as_code_addr_decls(c_local(_), !IO).
-output_label_as_code_addr_decls(local(_, _), !IO).
+output_label_as_code_addr_decls(entry(c_local, _), !IO).
+output_label_as_code_addr_decls(internal(_, _), !IO).
 
 output_data_addr_decls(DataAddr, !DeclSet, !IO) :-
 	output_data_addr_decls(DataAddr, "", "", 0, _, !DeclSet, !IO).
@@ -3299,7 +3353,7 @@
 
 output_goto(label(Label), CallerLabel, !IO) :-
 	(
-		Label = exported(_),
+		Label = entry(exported, _),
 		globals__io_lookup_bool_option(profile_calls, ProfileCalls,
 			!IO),
 		(
@@ -3316,7 +3370,7 @@
 			io__write_string(");\n", !IO)
 		)
 	;
-		Label = local(_),
+		Label = entry(local, _),
 		globals__io_lookup_bool_option(profile_calls, ProfileCalls,
 			!IO),
 		(
@@ -3333,7 +3387,7 @@
 			io__write_string(");\n", !IO)
 		)
 	;
-		Label = c_local(_),
+		Label = entry(c_local, _),
 		globals__io_lookup_bool_option(profile_calls, ProfileCalls,
 			!IO),
 		(
@@ -3350,7 +3404,7 @@
 			io__write_string(");\n", !IO)
 		)
 	;
-		Label = local(_, _),
+		Label = internal(_, _),
 		io__write_string("MR_GOTO_LAB(", !IO),
 		output_label(Label, no, !IO),
 		io__write_string(");\n", !IO)
@@ -3463,9 +3517,7 @@
 	(
 		Target = label(Label),
 		% We really shouldn't be calling internal labels ...
-		( Label = c_local(_)
-		; Label = local(_, _)
-		)
+		label_is_external_to_c_module(Label) = no
 	->
 		(
 			ProfileCall = yes,
@@ -3511,9 +3563,7 @@
 		)
 	;
 		Continuation = label(ContLabel),
-		( ContLabel = c_local(_)
-		; ContLabel = local(_, _)
-		)
+		label_is_external_to_c_module(ContLabel) = no
 	->
 		(
 			ProfileCall = yes,
@@ -3634,12 +3684,12 @@
 
 code_addr_to_string_base(label(Label), BaseStr, yes, Wrapper) :-
 	BaseStr = label_to_c_string(Label, no),
-	IsEntry = label_is_entry(Label),
+	IsExternal = label_is_external_to_c_module(Label),
 	(
-		IsEntry = yes,
+		IsExternal = yes,
 		Wrapper = entry
 	;
-		IsEntry = no,
+		IsExternal = no,
 		Wrapper = label
 	).
 code_addr_to_string_base(imported(ProcLabel), BaseStr, yes, entry) :-
@@ -3766,18 +3816,18 @@
 	label_as_code_addr_to_string(Label, Str),
 	io__write_string(Str, !IO).
 
-:- func label_is_entry(label) = bool.
+:- func label_is_external_to_c_module(label) = bool.
 
-label_is_entry(exported(_)) = yes.
-label_is_entry(local(_)) = yes.
-label_is_entry(c_local(_)) = no.
-label_is_entry(local(_, _)) = no.
+label_is_external_to_c_module(entry(exported, _)) = yes.
+label_is_external_to_c_module(entry(local, _)) = yes.
+label_is_external_to_c_module(entry(c_local, _)) = no.
+label_is_external_to_c_module(internal(_, _)) = no.
 
 :- pred label_as_code_addr_to_string(label::in, string::out) is det.
 
 label_as_code_addr_to_string(Label, Str) :-
 	LabelStr = llds_out__label_to_c_string(Label, no),
-	IsEntry = label_is_entry(Label),
+	IsEntry = label_is_external_to_c_module(Label),
 	(
 		IsEntry = yes,
 		Str = "MR_ENTRY_AP(" ++ LabelStr ++ ")"
@@ -3807,44 +3857,45 @@
 
 :- pred output_label_defn(label::in, io::di, io::uo) is det.
 
-output_label_defn(exported(ProcLabel), !IO) :-
+output_label_defn(entry(exported, ProcLabel), !IO) :-
 	io__write_string("MR_define_entry(", !IO),
-	output_label(exported(ProcLabel), !IO),
+	output_label(entry(exported, ProcLabel), !IO),
 	io__write_string(");\n", !IO).
-output_label_defn(local(ProcLabel), !IO) :-
+output_label_defn(entry(local, ProcLabel), !IO) :-
 	% The code for procedures local to a Mercury module
 	% should normally be visible only within the C file
 	% generated for that module. However, if we generate
 	% multiple C files, the code in each C file must be
 	% visible to the other C files for that Mercury module.
 	globals__io_lookup_bool_option(split_c_files, SplitFiles, !IO),
-	( SplitFiles = no ->
+	(
+		SplitFiles = no,
 		io__write_string("MR_def_static(", !IO),
 		output_proc_label(ProcLabel, no, !IO),
 		io__write_string(")\n", !IO)
 	;
+		SplitFiles = yes,
 		io__write_string("MR_def_entry(", !IO),
 		output_proc_label(ProcLabel, no, !IO),
 		io__write_string(")\n", !IO)
 	).
-output_label_defn(c_local(ProcLabel), !IO) :-
+output_label_defn(entry(c_local, ProcLabel), !IO) :-
 	io__write_string("MR_def_local(", !IO),
 	output_proc_label(ProcLabel, no, !IO),
 	io__write_string(")\n", !IO).
-output_label_defn(local(Num, ProcLabel), !IO) :-
+output_label_defn(internal(Num, ProcLabel), !IO) :-
 	io__write_string("MR_def_label(", !IO),
 	output_proc_label(ProcLabel, no, !IO),
 	io__write_string(",", !IO),
 	io__write_int(Num, !IO),
 	io__write_string(")\n", !IO).
 
-% Entry labels, i.e. those bound to any functor other than local/2,
-% should generate the same code, regardless of whether we refer to them
-% via exported/1, local/1 or c_local/1, because we may refer to an entry label
-% via different function symbols in different circumstances.
+% Entry labels should generate the same code, regardless of the entry label
+% type, because we may refer to an entry label via different entry label types
+% in different circumstances.
 % For example, the entry label of a recursive unification predicate
-% is referred to as local/1 in type_info structures and as c_local/1
-% in the recursive call, since the c_local/1 is special cased in some
+% is referred to as local in type_info structures and as c_local
+% in the recursive call, since the c_local is special cased in some
 % circumstances, leading to better code.
 
 output_label(Label, !IO) :-
@@ -3855,13 +3906,9 @@
 	LabelStr = llds_out__label_to_c_string(Label, AddPrefix),
 	io__write_string(LabelStr, !IO).
 
-llds_out__label_to_c_string(exported(ProcLabel), AddPrefix) =
-	proc_label_to_c_string(ProcLabel, AddPrefix).
-llds_out__label_to_c_string(local(ProcLabel), AddPrefix) =
-	proc_label_to_c_string(ProcLabel, AddPrefix).
-llds_out__label_to_c_string(c_local(ProcLabel), AddPrefix) =
+llds_out__label_to_c_string(entry(_, ProcLabel), AddPrefix) =
 	proc_label_to_c_string(ProcLabel, AddPrefix).
-llds_out__label_to_c_string(local(Num, ProcLabel), AddPrefix) = LabelStr :-
+llds_out__label_to_c_string(internal(Num, ProcLabel), AddPrefix) = LabelStr :-
 	ProcLabelStr = proc_label_to_c_string(ProcLabel, AddPrefix),
 	string__int_to_string(Num, NumStr),
 	string__append("_i", NumStr, NumSuffix),
Index: compiler/opt_debug.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/opt_debug.m,v
retrieving revision 1.140
diff -u -b -r1.140 opt_debug.m
--- compiler/opt_debug.m	19 May 2004 03:59:30 -0000	1.140
+++ compiler/opt_debug.m	23 May 2004 22:18:04 -0000
@@ -503,8 +503,9 @@
 	string__append_list(["tc_instance(", TypesStr, ")"],
 		Str).
 
-opt_debug__dump_layout_name(label_layout(Label, LabelVars), Str) :-
-	opt_debug__dump_label(Label, LabelStr),
+opt_debug__dump_layout_name(label_layout(ProcLabel, LabelNum, LabelVars),
+		Str) :-
+	opt_debug__dump_label(internal(LabelNum, ProcLabel), LabelStr),
 	(
 		LabelVars = label_has_var_info,
 		LabelVarsStr = "label_has_var_info"
@@ -648,15 +649,11 @@
 	opt_debug__dump_code_addrs(Addrs, A2_str),
 	string__append_list([" ", A_str, A2_str], Str).
 
-opt_debug__dump_label(local(N, ProcLabel), Str) :-
+opt_debug__dump_label(internal(N, ProcLabel), Str) :-
 	opt_debug__dump_proclabel(ProcLabel, P_str),
 	string__int_to_string(N, N_str),
 	string__append_list([P_str, "_", N_str], Str).
-opt_debug__dump_label(c_local(ProcLabel), Str) :-
-	opt_debug__dump_proclabel(ProcLabel, Str).
-opt_debug__dump_label(local(ProcLabel), Str) :-
-	opt_debug__dump_proclabel(ProcLabel, Str).
-opt_debug__dump_label(exported(ProcLabel), Str) :-
+opt_debug__dump_label(entry(_, ProcLabel), Str) :-
 	opt_debug__dump_proclabel(ProcLabel, Str).
 
 opt_debug__dump_labels([], "").
@@ -729,8 +726,14 @@
 	opt_debug__dump_code_addr(Proc, P_str),
 	opt_debug__dump_code_addr(Ret, R_str),
 	string__append_list(["call(", P_str, ", ", R_str, ", ...)"], Str).
-opt_debug__dump_instr(mkframe(FrameInfo, Redoip), Str) :-
-	opt_debug__dump_code_addr(Redoip, R_str),
+opt_debug__dump_instr(mkframe(FrameInfo, MaybeRedoip), Str) :-
+	(
+		MaybeRedoip = yes(Redoip),
+		opt_debug__dump_code_addr(Redoip, R_str)
+	;
+		MaybeRedoip = no,
+		R_str = "no_redoip"
+	),
 	(
 		FrameInfo = ordinary_frame(Name, Size, MaybePragma),
 		string__int_to_string(Size, S_str),
Index: compiler/opt_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/opt_util.m,v
retrieving revision 1.123
diff -u -b -r1.123 opt_util.m
--- compiler/opt_util.m	20 Oct 2003 07:29:10 -0000	1.123
+++ compiler/opt_util.m	23 May 2004 22:18:04 -0000
@@ -1169,7 +1169,8 @@
 	opt_util__instr_list_labels(Instrs, Labels, CodeAddrs).
 opt_util__instr_labels_2(assign(_,_), [], []).
 opt_util__instr_labels_2(call(Target, Ret, _, _, _, _), [], [Target, Ret]).
-opt_util__instr_labels_2(mkframe(_, Addr), [], [Addr]).
+opt_util__instr_labels_2(mkframe(_, yes(Addr)), [], [Addr]).
+opt_util__instr_labels_2(mkframe(_, no), [], []).
 opt_util__instr_labels_2(label(_), [], []).
 opt_util__instr_labels_2(goto(Addr), [], [Addr]).
 opt_util__instr_labels_2(computed_goto(_, Labels), Labels, []).
@@ -1381,9 +1382,11 @@
 	list__append(CodeAddrs0, CodeAddrs1, CodeAddrs).
 
 opt_util__livevals_addr(label(Label), Result) :-
-	( Label = local(_, _) ->
+	(
+		Label = internal(_, _),
 		Result = no
 	;
+		Label = entry(_, _),
 		Result = yes
 	).
 opt_util__livevals_addr(imported(_), yes).
@@ -1476,13 +1479,9 @@
 % that uses a temp var without defining it.
 opt_util__count_temps_rval(_, R, R, F, F).
 
-opt_util__format_label(local(_, ProcLabel), Str) :-
-	opt_util__format_proclabel(ProcLabel, Str).
-opt_util__format_label(c_local(ProcLabel), Str) :-
-	opt_util__format_proclabel(ProcLabel, Str).
-opt_util__format_label(local(ProcLabel), Str) :-
+opt_util__format_label(internal(_, ProcLabel), Str) :-
 	opt_util__format_proclabel(ProcLabel, Str).
-opt_util__format_label(exported(ProcLabel), Str) :-
+opt_util__format_label(entry(_, ProcLabel), Str) :-
 	opt_util__format_proclabel(ProcLabel, Str).
 
 :- pred opt_util__format_proclabel(proc_label, string).
@@ -1765,14 +1764,22 @@
 opt_util__replace_labels_instr(call(Target, Return0, LiveInfo, CXT, GP, CM),
 		ReplMap, _, call(Target, Return, LiveInfo, CXT, GP, CM)) :-
 	opt_util__replace_labels_code_addr(Return0, ReplMap, Return).
-opt_util__replace_labels_instr(mkframe(NondetFrameInfo, Redoip0), ReplMap,
-		ReplData, mkframe(NondetFrameInfo, Redoip)) :-
+opt_util__replace_labels_instr(mkframe(NondetFrameInfo, MaybeRedoip0), ReplMap,
+		ReplData, mkframe(NondetFrameInfo, MaybeRedoip)) :-
 	(
 		ReplData = yes,
-		opt_util__replace_labels_code_addr(Redoip0, ReplMap, Redoip)
+		(
+			MaybeRedoip0 = yes(Redoip0),
+			opt_util__replace_labels_code_addr(Redoip0, ReplMap,
+				Redoip),
+			MaybeRedoip = yes(Redoip)
+		;
+			MaybeRedoip0 = no,
+			MaybeRedoip = no
+		)
 	;
 		ReplData = no,
-		Redoip = Redoip0
+		MaybeRedoip = MaybeRedoip0
 	).
 opt_util__replace_labels_instr(label(Label), ReplMap, _, label(Label)) :-
 	( map__search(ReplMap, Label, _) ->
Index: compiler/optimize.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/optimize.m,v
retrieving revision 1.41
diff -u -b -r1.41 optimize.m
--- compiler/optimize.m	30 Jan 2004 06:00:45 -0000	1.41
+++ compiler/optimize.m	23 May 2004 22:18:04 -0000
@@ -55,29 +55,40 @@
 optimize_main(GlobalData, !Procs, !IO) :-
 	list__map_foldl(optimize__proc(GlobalData), !Procs, !IO).
 
-optimize__proc(GlobalData, CProc0, CProc) -->
-	{ CProc0 = c_procedure(Name, Arity, PredProcId, Instrs0,
-		ProcLabel, C0, MayAlterRtti) },
-	optimize__init_opt_debug_info(Name, Arity, PredProcId, Instrs0, C0,
-		OptDebugInfo0),
-	globals__io_lookup_int_option(optimize_repeat, Repeat),
-	{
-		global_data_maybe_get_proc_layout(GlobalData, PredProcId,
-			ProcLayout)
+:- func make_internal_label(proc_label, int) = label.
+
+make_internal_label(ProcLabel, LabelNum) = internal(LabelNum, ProcLabel).
+
+optimize__proc(GlobalData, CProc0, CProc, !IO) :-
+	some [!OptDebugInfo, !C, !Instrs] (
+		CProc0 = c_procedure(Name, Arity, PredProcId, !:Instrs,
+			ProcLabel, !:C, MayAlterRtti),
+		optimize__init_opt_debug_info(Name, Arity, PredProcId,
+			!.Instrs, !.C, !:OptDebugInfo, !IO),
+		globals__io_lookup_int_option(optimize_repeat, Repeat, !IO),
+		(
+			global_data_maybe_get_proc_layout(GlobalData,
+				PredProcId, ProcLayout)
 	->
-		LabelMap = ProcLayout^internal_map,
-		map__sorted_keys(LabelMap, LayoutLabels),
+			LabelMap = ProcLayout ^ internal_map,
+			map__sorted_keys(LabelMap, LayoutLabelNums),
+			LayoutLabels = list__map(make_internal_label(ProcLabel),
+				LayoutLabelNums),
 		set__sorted_list_to_set(LayoutLabels, LayoutLabelSet)
 	;
 		set__init(LayoutLabelSet)
-	},
-	optimize__repeat(Repeat, LayoutLabelSet, Instrs0, ProcLabel,
-		MayAlterRtti, C0, C1, OptDebugInfo0, OptDebugInfo1, Instrs1),
-	optimize__middle(Instrs1, yes, LayoutLabelSet, ProcLabel,
-		MayAlterRtti, C1, C, OptDebugInfo1, OptDebugInfo, Instrs3),
-	optimize__last(Instrs3, LayoutLabelSet, C, OptDebugInfo, Instrs),
-	{ CProc = c_procedure(Name, Arity, PredProcId, Instrs,
-		ProcLabel, C, MayAlterRtti) }.
+		),
+		optimize__initial(LayoutLabelSet, ProcLabel, MayAlterRtti,
+			!C, !OptDebugInfo, !Instrs, !IO),
+		optimize__repeat(Repeat, LayoutLabelSet, ProcLabel,
+			MayAlterRtti, !C, !OptDebugInfo, !Instrs, !IO),
+		optimize__middle(yes, LayoutLabelSet, ProcLabel, MayAlterRtti,
+			!C, !OptDebugInfo, !Instrs, !IO),
+		optimize__last(LayoutLabelSet, !.C, !.OptDebugInfo, !Instrs,
+			!IO),
+		CProc = c_procedure(Name, Arity, PredProcId, !.Instrs,
+			ProcLabel, !.C, MayAlterRtti)
+	).
 
 %-----------------------------------------------------------------------------%
 
@@ -90,7 +101,7 @@
 
 :- pred optimize__init_opt_debug_info(string::in, int::in, pred_proc_id::in,
 	list(instruction)::in, counter::in, opt_debug_info::out,
-	io__state::di, io__state::uo) is det.
+	io::di, io::uo) is det.
 
 optimize__init_opt_debug_info(Name, Arity, PredProcId, Instrs0, Counter,
 		OptDebugInfo, !IO) :-
@@ -116,7 +127,8 @@
 		( Res = ok(FileStream) ->
 			io__set_output_stream(FileStream, OutputStream, !IO),
 			counter__allocate(NextLabel, Counter, _),
-			opt_debug__msg(yes, NextLabel, "before optimization", !IO),
+			opt_debug__msg(yes, NextLabel, "before optimization",
+				!IO),
 			opt_debug__dump_instrs(yes, Instrs0, !IO),
 			io__set_output_stream(OutputStream, _, !IO),
 			io__close_output(FileStream, !IO)
@@ -130,344 +142,384 @@
 
 :- pred optimize__maybe_opt_debug(list(instruction)::in, counter::in,
 	string::in, opt_debug_info::in, opt_debug_info::out,
-	io__state::di, io__state::uo) is det.
+	io::di, io::uo) is det.
 
-optimize__maybe_opt_debug(Instrs, Counter, Msg,
-		OptDebugInfo0, OptDebugInfo) -->
+optimize__maybe_opt_debug(Instrs, Counter, Msg, OptDebugInfo0, OptDebugInfo,
+		!IO) :-
 	(
-		{ OptDebugInfo0 = opt_debug_info(BaseName, OptNum0) },
-		{ OptNum = OptNum0 + 1 },
-		{ string__int_to_string(OptNum0, OptNum0Str) },
-		{ string__int_to_string(OptNum, OptNumStr) },
-		{ string__append_list([BaseName, ".opt", OptNum0Str],
-			OptFileName0) },
-		{ string__append_list([BaseName, ".opt", OptNumStr],
-			OptFileName) },
-		{ string__append_list([BaseName, ".diff", OptNumStr],
-			DiffFileName) },
-		io__open_output(OptFileName, Res),
-		( { Res = ok(FileStream) } ->
-			io__set_output_stream(FileStream, OutputStream),
-			{ counter__allocate(NextLabel, Counter, _) },
-			opt_debug__msg(yes, NextLabel, Msg),
-			opt_debug__dump_instrs(yes, Instrs),
-			io__set_output_stream(OutputStream, _),
-			io__close_output(FileStream)
-		;
-			{ string__append("cannot open ", OptFileName,
-				ErrorMsg) },
-			{ error(ErrorMsg) }
+		OptDebugInfo0 = opt_debug_info(BaseName, OptNum0),
+		OptNum = OptNum0 + 1,
+		string__int_to_string(OptNum0, OptNum0Str),
+		string__int_to_string(OptNum, OptNumStr),
+		string__append_list([BaseName, ".opt", OptNum0Str],
+			OptFileName0),
+		string__append_list([BaseName, ".opt", OptNumStr],
+			OptFileName),
+		string__append_list([BaseName, ".diff", OptNumStr],
+			DiffFileName),
+		io__open_output(OptFileName, Res, !IO),
+		( Res = ok(FileStream) ->
+			io__set_output_stream(FileStream, OutputStream, !IO),
+			counter__allocate(NextLabel, Counter, _),
+			opt_debug__msg(yes, NextLabel, Msg, !IO),
+			opt_debug__dump_instrs(yes, Instrs, !IO),
+			io__set_output_stream(OutputStream, _, !IO),
+			io__close_output(FileStream, !IO)
+		;
+			string__append("cannot open ", OptFileName,
+				ErrorMsg),
+			error(ErrorMsg)
 		),
 		% Although the -u is not fully portable, it is available
 		% on all the systems we intend to use it on, and the main user
 		% of --debug-opt (zs) strongly prefers -u to -c.
-		{ string__append_list(["diff -u ",
+		string__append_list(["diff -u ",
 			OptFileName0, " ", OptFileName,
-			" > ", DiffFileName], DiffCommand) },
-		io__call_system(DiffCommand, _),
-		{ OptDebugInfo = opt_debug_info(BaseName, OptNum) }
+			" > ", DiffFileName], DiffCommand),
+		io__call_system(DiffCommand, _, !IO),
+		OptDebugInfo = opt_debug_info(BaseName, OptNum)
+	;
+		OptDebugInfo0 = no_opt_debug_info,
+		OptDebugInfo = no_opt_debug_info
+	).
+
+%-----------------------------------------------------------------------------%
+
+:- pred optimize__initial(set(label)::in, proc_label::in, may_alter_rtti::in,
+	counter::in, counter::out, opt_debug_info::in, opt_debug_info::out,
+	list(instruction)::in, list(instruction)::out, io::di, io::uo) is det.
+
+optimize__initial(LayoutLabelSet, ProcLabel, MayAlterRtti, !C, !OptDebugInfo,
+		!Instrs, !IO) :-
+	globals__io_lookup_bool_option(very_verbose, VeryVerbose, !IO),
+	opt_util__find_first_label(!.Instrs, Label),
+	opt_util__format_label(Label, LabelStr),
+
+	globals__io_lookup_bool_option(optimize_frames, FrameOpt, !IO),
+	(
+		FrameOpt = yes,
+		(
+			VeryVerbose = yes,
+			io__write_string("% Optimizing nondet frames for ",
+				!IO),
+			io__write_string(LabelStr, !IO),
+			io__write_string("\n", !IO)
+		;
+			VeryVerbose = no
+		),
+		frameopt_nondet(ProcLabel, LayoutLabelSet, MayAlterRtti, !C,
+			!Instrs, _Mod),
+		optimize__maybe_opt_debug(!.Instrs, !.C,
+			"after nondet frame opt", !OptDebugInfo, !IO)
 	;
-		{ OptDebugInfo0 = no_opt_debug_info },
-		{ OptDebugInfo = no_opt_debug_info }
+		FrameOpt = no
 	).
 
 %-----------------------------------------------------------------------------%
 
-:- pred optimize__repeat(int::in, set(label)::in, list(instruction)::in,
-	proc_label::in, may_alter_rtti::in, counter::in, counter::out,
-	opt_debug_info::in, opt_debug_info::out, list(instruction)::out,
-	io__state::di, io__state::uo) is det.
-
-optimize__repeat(Iter0, LayoutLabelSet, Instrs0, ProcLabel, MayAlterRtti,
-		C0, C, OptDebugInfo0, OptDebugInfo, Instrs) -->
-	( { Iter0 > 0 } ->
-		{ Iter1 = Iter0 - 1 },
-		( { Iter1 = 0 } ->
-			{ Final = yes }
-		;
-			{ Final = no }
-		),
-		optimize__repeated(Instrs0, Final, LayoutLabelSet, ProcLabel,
-			MayAlterRtti, C0, C1, OptDebugInfo0, OptDebugInfo1,
-			Instrs1, Mod),
-		( { Mod = yes } ->
-			optimize__repeat(Iter1, LayoutLabelSet, Instrs1,
-				ProcLabel, MayAlterRtti, C1, C,
-				OptDebugInfo1, OptDebugInfo, Instrs)
-		;
-			{ Instrs = Instrs1 },
-			{ C = C1 },
-			{ OptDebugInfo = OptDebugInfo0 }
+:- pred optimize__repeat(int::in, set(label)::in, proc_label::in,
+	may_alter_rtti::in, counter::in, counter::out,
+	opt_debug_info::in, opt_debug_info::out,
+	list(instruction)::in, list(instruction)::out, io::di, io::uo) is det.
+
+optimize__repeat(CurIter, LayoutLabelSet, ProcLabel, MayAlterRtti,
+		!C, !OptDebugInfo, !Instrs, !IO) :-
+	( CurIter > 0 ->
+		NextIter = CurIter - 1,
+		( NextIter = 0 ->
+			Final = yes
+		;
+			Final = no
+		),
+		optimize__repeated(Final, LayoutLabelSet, ProcLabel,
+			MayAlterRtti, !C, !OptDebugInfo,
+			!Instrs, Mod, !IO),
+		(
+			Mod = yes,
+			optimize__repeat(NextIter, LayoutLabelSet, ProcLabel,
+				MayAlterRtti, !C, !OptDebugInfo, !Instrs, !IO)
+		;
+			Mod = no
 		)
 	;
-		{ Instrs = Instrs0 },
-		{ C = C0 },
-		{ OptDebugInfo = OptDebugInfo0 }
+		true
 	).
 
 	% We short-circuit jump sequences before normal peepholing
 	% to create more opportunities for use of the tailcall macro.
 
-:- pred optimize__repeated(list(instruction)::in, bool::in, set(label)::in,
-	proc_label::in, may_alter_rtti::in, counter::in, counter::out,
-	opt_debug_info::in, opt_debug_info::out, list(instruction)::out,
-	bool::out, io__state::di, io__state::uo) is det.
-
-optimize__repeated(Instrs0, Final, LayoutLabelSet, ProcLabel, MayAlterRtti,
-		C0, C, OptDebugInfo0, OptDebugInfo, Instrs, Mod) -->
-	{ opt_util__find_first_label(Instrs0, Label) },
-	{ proc_label_to_c_string(get_proc_label(Label), no) = LabelStr },
-	globals__io_lookup_bool_option(very_verbose, VeryVerbose),
-	globals__io_lookup_bool_option(optimize_jumps, Jumpopt),
-	globals__io_lookup_bool_option(optimize_fulljumps, FullJumpopt),
+:- pred optimize__repeated(bool::in, set(label)::in, proc_label::in,
+	may_alter_rtti::in, counter::in, counter::out,
+	opt_debug_info::in, opt_debug_info::out,
+	list(instruction)::in, list(instruction)::out, bool::out,
+	io::di, io::uo) is det.
+
+optimize__repeated(Final, LayoutLabelSet, ProcLabel, MayAlterRtti,
+		!C, !OptDebugInfo, !Instrs, Mod, !IO) :-
+	InstrsAtStart = !.Instrs,
+	opt_util__find_first_label(!.Instrs, Label),
+	proc_label_to_c_string(get_proc_label(Label), no) = LabelStr,
+	globals__io_lookup_bool_option(very_verbose, VeryVerbose, !IO),
+	globals__io_lookup_bool_option(optimize_jumps, Jumpopt, !IO),
+	globals__io_lookup_bool_option(optimize_fulljumps, FullJumpopt, !IO),
 	globals__io_lookup_bool_option(pessimize_tailcalls,
-		PessimizeTailCalls),
+		PessimizeTailCalls, !IO),
 	globals__io_lookup_bool_option(checked_nondet_tailcalls,
-		CheckedNondetTailCalls),
-	( { Jumpopt = yes } ->
-		( { VeryVerbose = yes } ->
-			io__write_string("% Optimizing jumps for "),
-			io__write_string(LabelStr),
-			io__write_string("\n")
-		;
-			[]
-		),
-		{ jumpopt_main(Instrs0, LayoutLabelSet, MayAlterRtti,
-			ProcLabel, C0, C1, FullJumpopt, Final,
-			PessimizeTailCalls, CheckedNondetTailCalls,
-			Instrs1, Mod1) },
-		optimize__maybe_opt_debug(Instrs1, C1, "after jump opt",
-			OptDebugInfo0, OptDebugInfo1)
-	;
-		{ Instrs1 = Instrs0 },
-		{ C1 = C0 },
-		{ OptDebugInfo1 = OptDebugInfo0 },
-		{ Mod1 = no }
-	),
-	globals__io_lookup_bool_option(optimize_peep, Peephole),
-	( { Peephole = yes } ->
-		( { VeryVerbose = yes } ->
-			io__write_string("% Optimizing locally for "),
-			io__write_string(LabelStr),
-			io__write_string("\n")
-		;
-			[]
-		),
-		globals__io_get_gc_method(GC_Method),
-		{ peephole__optimize(GC_Method, Instrs1, Instrs2, Mod2) },
-		optimize__maybe_opt_debug(Instrs2, C1, "after peephole",
-			OptDebugInfo1, OptDebugInfo2)
-	;
-		{ Instrs2 = Instrs1 },
-		{ OptDebugInfo2 = OptDebugInfo1 },
-		{ Mod2 = no }
-	),
-	globals__io_lookup_bool_option(optimize_labels, LabelElim),
-	( { LabelElim = yes } ->
-		( { VeryVerbose = yes } ->
-			io__write_string("% Optimizing labels for "),
-			io__write_string(LabelStr),
-			io__write_string("\n")
-		;
-			[]
-		),
-		{ labelopt_main(Instrs2, Final, LayoutLabelSet,
-			Instrs3, Mod3) },
-		optimize__maybe_opt_debug(Instrs3, C1, "after label opt",
-			OptDebugInfo2, OptDebugInfo3)
-		;
-		{ Instrs3 = Instrs2 },
-		{ OptDebugInfo3 = OptDebugInfo2 },
-		{ Mod3 = no }
-	),
-	globals__io_lookup_bool_option(optimize_dups, DupElim),
-	( { DupElim = yes } ->
-		( { VeryVerbose = yes } ->
-			io__write_string("% Optimizing duplicates for "),
-			io__write_string(LabelStr),
-			io__write_string("\n")
-		;
-			[]
-		),
-		{ dupelim_main(Instrs3, ProcLabel, C1, C, Instrs) },
-		optimize__maybe_opt_debug(Instrs, C, "after duplicates",
-			OptDebugInfo3, OptDebugInfo)
-	;
-		{ Instrs = Instrs3 },
-		{ OptDebugInfo = OptDebugInfo3 },
-		{ C = C1 }
+		CheckedNondetTailCalls, !IO),
+	(
+		Jumpopt = yes,
+		(
+			VeryVerbose = yes,
+			io__write_string("% Optimizing jumps for ", !IO),
+			io__write_string(LabelStr, !IO),
+			io__write_string("\n", !IO)
+		;
+			VeryVerbose = no
+		),
+		jumpopt_main(LayoutLabelSet, MayAlterRtti, ProcLabel,
+			FullJumpopt, Final, PessimizeTailCalls,
+			CheckedNondetTailCalls, !C, !Instrs, Mod1),
+		optimize__maybe_opt_debug(!.Instrs, !.C, "after jump opt",
+			!OptDebugInfo, !IO)
+	;
+		Jumpopt = no,
+		Mod1 = no
+	),
+	globals__io_lookup_bool_option(optimize_peep, Peephole, !IO),
+	( 
+		Peephole = yes,
+		(
+			VeryVerbose = yes,
+			io__write_string("% Optimizing locally for ", !IO),
+			io__write_string(LabelStr, !IO),
+			io__write_string("\n", !IO)
+		;
+			VeryVerbose = no
+		),
+		globals__io_get_gc_method(GC_Method, !IO),
+		peephole__optimize(GC_Method, !Instrs, Mod2),
+		optimize__maybe_opt_debug(!.Instrs, !.C, "after peephole",
+			!OptDebugInfo, !IO)
+	;
+		Peephole = no,
+		Mod2 = no
+	),
+	globals__io_lookup_bool_option(optimize_labels, LabelElim, !IO),
+	(
+		LabelElim = yes,
+		(
+			VeryVerbose = yes,
+			io__write_string("% Optimizing labels for ", !IO),
+			io__write_string(LabelStr, !IO),
+			io__write_string("\n", !IO)
+		;
+			VeryVerbose = no
+		),
+		labelopt_main(Final, LayoutLabelSet, !Instrs, Mod3),
+		optimize__maybe_opt_debug(!.Instrs, !.C, "after label opt",
+			!OptDebugInfo, !IO)
+	;
+		LabelElim = no,
+		Mod3 = no
+	),
+	globals__io_lookup_bool_option(optimize_dups, DupElim, !IO),
+	(
+		DupElim = yes,
+		(
+			VeryVerbose = yes,
+			io__write_string("% Optimizing duplicates for ", !IO),
+			io__write_string(LabelStr, !IO),
+			io__write_string("\n", !IO)
+		;
+			VeryVerbose = no
+		),
+		dupelim_main(ProcLabel, !C, !Instrs),
+		optimize__maybe_opt_debug(!.Instrs, !.C, "after duplicates",
+			!OptDebugInfo, !IO)
+	;
+		DupElim = no
 	),
-	{ Mod1 = no, Mod2 = no, Mod3 = no, Instrs = Instrs0 ->
+	( Mod1 = no, Mod2 = no, Mod3 = no, !.Instrs = InstrsAtStart ->
 		Mod = no
 	;
 		Mod = yes
-	},
-	globals__io_lookup_bool_option(statistics, Statistics),
-	maybe_report_stats(Statistics).
-
-:- pred optimize__middle(list(instruction)::in, bool::in, set(label)::in,
-	proc_label::in, may_alter_rtti::in, counter::in, counter::out,
-	opt_debug_info::in, opt_debug_info::out, list(instruction)::out,
-	io__state::di, io__state::uo) is det.
-
-optimize__middle(Instrs0, Final, LayoutLabelSet, ProcLabel, MayAlterRtti,
-		C0, C, OptDebugInfo0, OptDebugInfo, Instrs) -->
-	globals__io_lookup_bool_option(very_verbose, VeryVerbose),
-	{ opt_util__find_first_label(Instrs0, Label) },
-	{ opt_util__format_label(Label, LabelStr) },
-
-	globals__io_lookup_bool_option(optimize_frames, FrameOpt),
-	( { FrameOpt = yes } ->
-		( { VeryVerbose = yes } ->
-			io__write_string("% Optimizing frames for "),
-			io__write_string(LabelStr),
-			io__write_string("\n")
-		;
-			[]
-		),
-		{ frameopt_main(Instrs0, ProcLabel, C0, C1, Instrs1,
-			Mod1, Jumps) },
-		optimize__maybe_opt_debug(Instrs1, C1, "after frame opt",
-			OptDebugInfo0, OptDebugInfo1),
-		globals__io_lookup_bool_option(optimize_fulljumps, FullJumpopt),
+	),
+	globals__io_lookup_bool_option(statistics, Statistics, !IO),
+	maybe_report_stats(Statistics, !IO).
+
+:- pred optimize__middle(bool::in, set(label)::in, proc_label::in,
+	may_alter_rtti::in, counter::in, counter::out,
+	opt_debug_info::in, opt_debug_info::out,
+	list(instruction)::in, list(instruction)::out, io::di, io::uo) is det.
+
+optimize__middle(Final, LayoutLabelSet, ProcLabel, MayAlterRtti, !C,
+		!OptDebugInfo, !Instrs, !IO) :-
+	globals__io_lookup_bool_option(very_verbose, VeryVerbose, !IO),
+	opt_util__find_first_label(!.Instrs, Label),
+	opt_util__format_label(Label, LabelStr),
+
+	globals__io_lookup_bool_option(optimize_frames, FrameOpt, !IO),
+	(
+		FrameOpt = yes,
+		(
+			VeryVerbose = yes,
+			io__write_string("% Optimizing frames for ", !IO),
+			io__write_string(LabelStr, !IO),
+			io__write_string("\n", !IO)
+		;
+			VeryVerbose = no
+		),
+		frameopt_main(ProcLabel, !C, !Instrs, Mod1, Jumps),
+		optimize__maybe_opt_debug(!.Instrs, !.C, "after frame opt",
+			!OptDebugInfo, !IO),
+		globals__io_lookup_bool_option(optimize_fulljumps,
+			FullJumpopt, !IO),
 		globals__io_lookup_bool_option(pessimize_tailcalls,
-			PessimizeTailCalls),
+			PessimizeTailCalls, !IO),
 		globals__io_lookup_bool_option(checked_nondet_tailcalls,
-			CheckedNondetTailCalls),
-		( { Jumps = yes, FullJumpopt = yes } ->
-			( { VeryVerbose = yes } ->
-				io__write_string("% Optimizing jumps for "),
-				io__write_string(LabelStr),
-				io__write_string("\n")
-			;
-				[]
-			),
-			{ jumpopt_main(Instrs1, LayoutLabelSet, MayAlterRtti,
-				ProcLabel, C1, C2, FullJumpopt, Final,
-				PessimizeTailCalls, CheckedNondetTailCalls,
-				Instrs2, _Mod2) },
-			optimize__maybe_opt_debug(Instrs2, C2, "after jumps",
-				OptDebugInfo1, OptDebugInfo2)
-		;
-			{ Instrs2 = Instrs1 },
-			{ OptDebugInfo2 = OptDebugInfo1 },
-			{ C2 = C1 }
-		),
-		( { Mod1 = yes } ->
-			( { VeryVerbose = yes } ->
-				io__write_string("% Optimizing labels for "),
-				io__write_string(LabelStr),
-				io__write_string("\n")
-			;
-				[]
-			),
-			{ labelopt_main(Instrs2, Final, LayoutLabelSet,
-				Instrs3, _Mod3) },
-			optimize__maybe_opt_debug(Instrs3, C2, "after labels",
-				OptDebugInfo2, OptDebugInfo3)
+			CheckedNondetTailCalls, !IO),
+		(
+			Jumps = yes,
+			FullJumpopt = yes
+		->
+			(
+				VeryVerbose = yes,
+				io__write_string("% Optimizing jumps for ",
+					!IO),
+				io__write_string(LabelStr, !IO),
+				io__write_string("\n", !IO)
+			;
+				VeryVerbose = no
+			),
+			jumpopt_main(LayoutLabelSet, MayAlterRtti, ProcLabel,
+				FullJumpopt, Final, PessimizeTailCalls,
+				CheckedNondetTailCalls, !C, !Instrs, _Mod2),
+			optimize__maybe_opt_debug(!.Instrs, !.C, "after jumps",
+				!OptDebugInfo, !IO)
 			;
-			{ OptDebugInfo3 = OptDebugInfo2 },
-			{ Instrs3 = Instrs2 }
+			true
+		),
+		(
+			Mod1 = yes,
+			(
+				VeryVerbose = yes,
+				io__write_string("% Optimizing labels for ",
+					!IO),
+				io__write_string(LabelStr, !IO),
+				io__write_string("\n", !IO)
+			;
+				VeryVerbose = no
+			),
+			labelopt_main(Final, LayoutLabelSet, !Instrs, _Mod3),
+			optimize__maybe_opt_debug(!.Instrs, !.C, "after labels",
+				!OptDebugInfo, !IO)
+		;
+			Mod1 = no
 		)
 	;
-		{ Instrs3 = Instrs0 },
-		{ OptDebugInfo3 = OptDebugInfo0 },
-		{ C2 = C0 }
+		FrameOpt = no
 	),
-	globals__io_lookup_bool_option(use_local_vars, UseLocalVars),
+	globals__io_lookup_bool_option(use_local_vars, UseLocalVars, !IO),
 	(
-		{ UseLocalVars = yes },
-		( { VeryVerbose = yes } ->
-			io__write_string("% Optimizing local vars for "),
-			io__write_string(LabelStr),
-			io__write_string("\n")
+		UseLocalVars = yes,
+		(
+			VeryVerbose = yes,
+			io__write_string("% Optimizing local vars for ", !IO),
+			io__write_string(LabelStr, !IO),
+			io__write_string("\n", !IO)
 		;
-			[]
+			VeryVerbose = no
 		),
-		globals__io_lookup_int_option(num_real_r_regs, NumRealRRegs),
+		globals__io_lookup_int_option(num_real_r_regs, NumRealRRegs,
+			!IO),
 		globals__io_lookup_int_option(local_var_access_threshold,
-			AccessThreshold),
-		{ use_local_vars__main(Instrs3, Instrs,
-			ProcLabel, NumRealRRegs, AccessThreshold, C2, C) },
-		optimize__maybe_opt_debug(Instrs, C, "after use_local_vars",
-			OptDebugInfo3, OptDebugInfo)
-	;
-		{ UseLocalVars = no },
-		{ Instrs = Instrs3 },
-		{ OptDebugInfo = OptDebugInfo3 },
-		{ C = C2 }
+			AccessThreshold, !IO),
+		use_local_vars__main(!Instrs, ProcLabel, NumRealRRegs,
+			AccessThreshold, !C),
+		optimize__maybe_opt_debug(!.Instrs, !.C,
+			"after use_local_vars", !OptDebugInfo, !IO)
+	;
+		UseLocalVars = no
 	).
 
-:- pred optimize__last(list(instruction)::in, set(label)::in,
-	counter::in, opt_debug_info::in, list(instruction)::out,
-	io__state::di, io__state::uo) is det.
-
-optimize__last(Instrs0, LayoutLabelSet, C, OptDebugInfo0, Instrs) -->
-	globals__io_lookup_bool_option(very_verbose, VeryVerbose),
-	{ opt_util__find_first_label(Instrs0, Label) },
-	{ opt_util__format_label(Label, LabelStr) },
-
-	globals__io_lookup_bool_option(optimize_reassign, Reassign),
-	globals__io_lookup_bool_option(optimize_delay_slot, DelaySlot),
-	globals__io_lookup_bool_option(use_local_vars, UseLocalVars),
-	( { Reassign = yes ; DelaySlot = yes ; UseLocalVars = yes } ->
+:- pred optimize__last(set(label)::in, counter::in, opt_debug_info::in,
+	list(instruction)::in, list(instruction)::out, io::di, io::uo) is det.
+
+optimize__last(LayoutLabelSet, C, !.OptDebugInfo, !Instrs, !IO) :-
+	globals__io_lookup_bool_option(very_verbose, VeryVerbose, !IO),
+	opt_util__find_first_label(!.Instrs, Label),
+	opt_util__format_label(Label, LabelStr),
+
+	globals__io_lookup_bool_option(optimize_reassign, Reassign, !IO),
+	globals__io_lookup_bool_option(optimize_delay_slot, DelaySlot, !IO),
+	globals__io_lookup_bool_option(use_local_vars, UseLocalVars, !IO),
+	(
+		( Reassign = yes
+		; DelaySlot = yes
+		; UseLocalVars = yes
+		)
+	->
 		% We must get rid of any extra labels added by other passes,
 		% since they can confuse reassign, wrap_blocks and delay_slot.
-		( { VeryVerbose = yes } ->
-			io__write_string("% Optimizing labels for "),
-			io__write_string(LabelStr),
-			io__write_string("\n")
-		;
-			[]
-		),
-		{ labelopt_main(Instrs0, no, LayoutLabelSet, Instrs1, _Mod1) },
-		optimize__maybe_opt_debug(Instrs1, C, "after label opt",
-			OptDebugInfo0, OptDebugInfo1)
-	;
-		{ OptDebugInfo1 = OptDebugInfo0 },
-		{ Instrs1 = Instrs0 }
-	),
-	( { Reassign = yes } ->
-		( { VeryVerbose = yes } ->
-			io__write_string("% Optimizing reassign for "),
-			io__write_string(LabelStr),
-			io__write_string("\n")
-		;
-			[]
-		),
-		{ remove_reassign(Instrs1, Instrs2) },
-		optimize__maybe_opt_debug(Instrs2, C, "after reassign",
-			OptDebugInfo1, OptDebugInfo2)
-	;
-		{ OptDebugInfo2 = OptDebugInfo1 },
-		{ Instrs2 = Instrs1 }
-	),
-	( { DelaySlot = yes } ->
-		( { VeryVerbose = yes } ->
-			io__write_string("% Optimizing delay slot for "),
-			io__write_string(LabelStr),
-			io__write_string("\n")
+		(
+			VeryVerbose = yes,
+			io__write_string("% Optimizing labels for ", !IO),
+			io__write_string(LabelStr, !IO),
+			io__write_string("\n", !IO)
+		;
+			VeryVerbose = no
+		),
+		labelopt_main(no, LayoutLabelSet, !Instrs, _Mod1),
+		optimize__maybe_opt_debug(!.Instrs, C, "after label opt",
+			!OptDebugInfo, !IO)
 		;
-			[]
+		true
 		),
-		{ fill_branch_delay_slot(Instrs2, Instrs3) },
-		optimize__maybe_opt_debug(Instrs3, C, "after delay slots",
-			OptDebugInfo2, OptDebugInfo3)
+	(
+		Reassign = yes,
+		(
+			VeryVerbose = yes,
+			io__write_string("% Optimizing reassign for ", !IO),
+			io__write_string(LabelStr, !IO),
+			io__write_string("\n", !IO)
+		;
+			VeryVerbose = no
+		),
+		remove_reassign(!Instrs),
+		optimize__maybe_opt_debug(!.Instrs, C, "after reassign",
+			!OptDebugInfo, !IO)
 	;
-		{ OptDebugInfo3 = OptDebugInfo2 },
-		{ Instrs3 = Instrs2 }
+		Reassign = no
 	),
-	( { UseLocalVars = yes } ->
-		( { VeryVerbose = yes } ->
-			io__write_string("% Wrapping blocks for "),
-			io__write_string(LabelStr),
-			io__write_string("\n")
+	(
+		DelaySlot = yes,
+		(
+			VeryVerbose = yes,
+			io__write_string("% Optimizing delay slot for ", !IO),
+			io__write_string(LabelStr, !IO),
+			io__write_string("\n", !IO)
+		;
+			VeryVerbose = no
+		),
+		fill_branch_delay_slot(!Instrs),
+		optimize__maybe_opt_debug(!.Instrs, C, "after delay slots",
+			!OptDebugInfo, !IO)
 		;
-			[]
+		DelaySlot = no
 		),
-		{ wrap_blocks(Instrs3, Instrs) },
-		optimize__maybe_opt_debug(Instrs, C, "after wrap blocks",
-			OptDebugInfo3, _OptDebugInfo)
+	(
+		UseLocalVars = yes,
+		(
+			VeryVerbose = yes,
+			io__write_string("% Wrapping blocks for ", !IO),
+			io__write_string(LabelStr, !IO),
+			io__write_string("\n", !IO)
+		;
+			VeryVerbose = no
+		),
+		wrap_blocks(!Instrs),
+		optimize__maybe_opt_debug(!.Instrs, C, "after wrap blocks",
+			!.OptDebugInfo, _OptDebugInfo, !IO)
 	;
-		{ Instrs = Instrs3 }
+		UseLocalVars = no
 	).
Index: compiler/peephole.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/peephole.m,v
retrieving revision 1.80
diff -u -b -r1.80 peephole.m
--- compiler/peephole.m	11 Nov 2003 03:35:08 -0000	1.80
+++ compiler/peephole.m	23 May 2004 22:18:04 -0000
@@ -221,7 +221,7 @@
 	% These two classes of patterns are mutually exclusive because if_val
 	% is not straight-line code.
 
-peephole__match(mkframe(NondetFrameInfo, Redoip1), Comment, _,
+peephole__match(mkframe(NondetFrameInfo, yes(Redoip1)), Comment, _,
 		Instrs0, Instrs) :-
 	(
 		% A mkframe sets curfr to point to the new frame
@@ -236,7 +236,7 @@
 		opt_util__touches_nondet_ctrl(Skipped, no)
 	->
 		list__append(Skipped, Rest, Instrs1),
-		Instrs = [mkframe(NondetFrameInfo, Redoip2) - Comment
+		Instrs = [mkframe(NondetFrameInfo, yes(Redoip2)) - Comment
 			| Instrs1]
 	;
 		opt_util__skip_comments_livevals(Instrs0, Instrs1),
@@ -249,7 +249,7 @@
 			Instrs = [
 				if_val(Test, do_redo)
 					- Comment2,
-				mkframe(NondetFrameInfo, do_fail)
+				mkframe(NondetFrameInfo, yes(do_fail))
 					- Comment
 				| Instrs2
 			]
@@ -262,7 +262,7 @@
 				Instrs = [
 					if_val(Test, do_redo)
 						- Comment2,
-					mkframe(NondetFrameInfo, Redoip1)
+					mkframe(NondetFrameInfo, yes(Redoip1))
 						- Comment
 					| Instrs2
 				]
@@ -270,7 +270,7 @@
 				Target = do_redo
 			->
 				Instrs = [
-					mkframe(NondetFrameInfo, Redoip1)
+					mkframe(NondetFrameInfo, yes(Redoip1))
 						- Comment,
 					if_val(Test, Redoip1)
 						- Comment2
Index: compiler/stack_layout.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/stack_layout.m,v
retrieving revision 1.89
diff -u -b -r1.89 stack_layout.m
--- compiler/stack_layout.m	20 May 2004 22:53:29 -0000	1.89
+++ compiler/stack_layout.m	23 May 2004 22:18:04 -0000
@@ -150,7 +150,7 @@
 
 stack_layout__valid_proc_layout(ProcLayoutInfo) :-
 	EntryLabel = ProcLayoutInfo ^ entry_label,
-	code_util__extract_proc_label_from_label(EntryLabel, ProcLabel),
+	ProcLabel = get_proc_label(EntryLabel),
 	(
 		ProcLabel = proc(_, _, DeclModule, Name, Arity, _),
 		\+ no_type_info_builtin(DeclModule, Name, Arity)
@@ -296,7 +296,7 @@
 	compute_var_number_map(HeadVars, VarSet, Internals, MaybeGoal,
 		VarNumMap),
 
-	code_util__extract_proc_label_from_label(EntryLabel, ProcLabel),
+	ProcLabel = get_proc_label(EntryLabel),
 	stack_layout__get_procid_stack_layout(ProcIdLayout0, !Info),
 	bool__or(ProcIdLayout0, ForceProcIdLayout, ProcIdLayout),
 	(
@@ -318,8 +318,8 @@
 		valid_proc_layout(ProcLayoutInfo)
 	->
 		list__map_foldl(stack_layout__construct_internal_layout(
-			ProcLayoutName, VarNumMap), Internals, InternalLayouts,
-			!Info)
+			ProcLabel, ProcLayoutName, VarNumMap),
+			Internals, InternalLayouts, !Info)
 	;
 		InternalLayouts = []
 	),
@@ -336,10 +336,11 @@
 	% Add the given label layout to the module-wide label tables.
 
 :- pred stack_layout__update_label_table(
-	{label, label_vars, internal_layout_info}::in,
+	{proc_label, int, label_vars, internal_layout_info}::in,
 	map(string, label_table)::in, map(string, label_table)::out) is det.
 
-stack_layout__update_label_table({Label, LabelVars, InternalInfo},
+stack_layout__update_label_table(
+		{ProcLabel, LabelNum, LabelVars, InternalInfo},
 		!LabelTables) :-
 	InternalInfo = internal_layout_info(Port, _, Return),
 	(
@@ -352,28 +353,28 @@
 		;
 			IsReturn = unknown_callee
 		),
-		stack_layout__update_label_table_2(Label, LabelVars,
-			Context, IsReturn, !LabelTables)
+		stack_layout__update_label_table_2(ProcLabel, LabelNum,
+			LabelVars, Context, IsReturn, !LabelTables)
 	;
 		Port = yes(trace_port_layout_info(Context, _, _, _, _)),
 		stack_layout__context_is_valid(Context)
 	->
-		stack_layout__update_label_table_2(Label, LabelVars,
-			Context, not_a_return, !LabelTables)
+		stack_layout__update_label_table_2(ProcLabel, LabelNum,
+			LabelVars, Context, not_a_return, !LabelTables)
 	;
 		true
 	).
 
-:- pred stack_layout__update_label_table_2(label::in, label_vars::in,
-	context::in, is_label_return::in,
+:- pred stack_layout__update_label_table_2(proc_label::in, int::in,
+	label_vars::in, context::in, is_label_return::in,
 	map(string, label_table)::in, map(string, label_table)::out) is det.
 
-stack_layout__update_label_table_2(Label, LabelVars, Context, IsReturn,
-		!LabelTables) :-
+stack_layout__update_label_table_2(ProcLabel, LabelNum, LabelVars, Context,
+		IsReturn, !LabelTables) :-
 	term__context_file(Context, File),
 	term__context_line(Context, Line),
 	( map__search(!.LabelTables, File, LabelTable0) ->
-		LabelLayout = label_layout(Label, LabelVars),
+		LabelLayout = label_layout(ProcLabel, LabelNum, LabelVars),
 		( map__search(LabelTable0, Line, LineInfo0) ->
 			LineInfo = [LabelLayout - IsReturn | LineInfo0],
 			map__det_update(LabelTable0, Line, LineInfo,
@@ -389,7 +390,7 @@
 		)
 	; stack_layout__context_is_valid(Context) ->
 		map__init(LabelTable0),
-		LabelLayout = label_layout(Label, LabelVars),
+		LabelLayout = label_layout(ProcLabel, LabelNum, LabelVars),
 		LineInfo = [LabelLayout - IsReturn],
 		map__det_insert(LabelTable0, Line, LineInfo, LabelTable),
 		map__det_insert(!.LabelTables, File, LabelTable, !:LabelTables)
@@ -576,7 +577,14 @@
 	TraceSlotInfo = trace_slot_info(MaybeFromFullSlot, MaybeIoSeqSlot,
 		MaybeTrailSlots, MaybeMaxfrSlot, MaybeCallTableSlot),
 		% The label associated with an event must have variable info.
-	CallLabelLayout = label_layout(CallLabel, label_has_var_info),
+	(
+		CallLabel = internal(CallLabelNum, CallProcLabel)
+	;
+		CallLabel = entry(_, _),
+		error("stack_layout__construct_trace_layout: entry call label")
+	),
+	CallLabelLayout = label_layout(CallProcLabel, CallLabelNum,
+		label_has_var_info),
 	(
 		MaybeTableInfo = no,
 		MaybeTableName = no
@@ -660,7 +668,7 @@
 :- type var_num_map	== map(prog_var, pair(int, string)).
 
 :- pred compute_var_number_map(list(prog_var)::in, prog_varset::in,
-	assoc_list(label, internal_layout_info)::in, maybe(hlds_goal)::in,
+	assoc_list(int, internal_layout_info)::in, maybe(hlds_goal)::in,
 	var_num_map::out) is det.
 
 compute_var_number_map(HeadVars, VarSet, Internals, MaybeGoal, VarNumMap) :-
@@ -682,7 +690,7 @@
 	list__foldl2(internal_var_number_map, Internals, VarNumMap2, VarNumMap,
 		Counter2, _Counter).
 
-:- pred internal_var_number_map(pair(label, internal_layout_info)::in,
+:- pred internal_var_number_map(pair(int, internal_layout_info)::in,
 	var_num_map::in, var_num_map::out, counter::in, counter::out) is det.
 
 internal_var_number_map(_Label - Internal, !VarNumMap, !Counter) :-
@@ -750,13 +758,13 @@
 	% Construct the layout describing a single internal label
 	% for accurate GC and/or execution tracing.
 
-:- pred stack_layout__construct_internal_layout(layout_name::in,
-	var_num_map::in, pair(label, internal_layout_info)::in,
-	{label, label_vars, internal_layout_info}::out,
+:- pred stack_layout__construct_internal_layout(proc_label::in,
+	layout_name::in, var_num_map::in, pair(int, internal_layout_info)::in,
+	{proc_label, int, label_vars, internal_layout_info}::out,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
-stack_layout__construct_internal_layout(ProcLayoutName, VarNumMap,
-		Label - Internal, LabelLayout, !Info) :-
+stack_layout__construct_internal_layout(ProcLabel, ProcLayoutName, VarNumMap,
+		LabelNum - Internal, LabelLayout, !Info) :-
 	Internal = internal_layout_info(Trace, Resume, Return),
 	(
 		Trace = no,
@@ -879,13 +887,14 @@
 		LabelVars = label_has_var_info
 	),
 
-	LayoutData = label_layout_data(Label, ProcLayoutName,
+	LayoutData = label_layout_data(ProcLabel, LabelNum, ProcLayoutName,
 		MaybePort, MaybeIsHidden, MaybeGoalPath, MaybeVarInfo),
 	CData = layout_data(LayoutData),
-	LayoutName = label_layout(Label, LabelVars),
+	LayoutName = label_layout(ProcLabel, LabelNum, LabelVars),
+	Label = internal(LabelNum, ProcLabel),
 	stack_layout__add_internal_layout_data(CData, Label, LayoutName,
 		!Info),
-	LabelLayout = {Label, LabelVars, Internal}.
+	LabelLayout = {ProcLabel, LabelNum, LabelVars, Internal}.
 
 %---------------------------------------------------------------------------%
 
Index: compiler/trace.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/trace.m,v
retrieving revision 1.64
diff -u -b -r1.64 trace.m
--- compiler/trace.m	3 May 2004 08:47:26 -0000	1.64
+++ compiler/trace.m	23 May 2004 22:18:04 -0000
@@ -889,14 +889,14 @@
 				"from-full flag not stored in expected slot"),
 			Code = node([
 				mkframe(temp_frame(nondet_stack_proc),
-					do_trace_redo_fail_shallow)
+					yes(do_trace_redo_fail_shallow))
 					- "set up shallow redo event"
 			])
 		;
 			MaybeFromFullSlot = no,
 			Code = node([
 				mkframe(temp_frame(nondet_stack_proc),
-					do_trace_redo_fail_deep)
+					yes(do_trace_redo_fail_deep))
 					- "set up deep redo event"
 			])
 		)
Index: compiler/transform_llds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/transform_llds.m,v
retrieving revision 1.12
diff -u -b -r1.12 transform_llds.m
--- compiler/transform_llds.m	5 Apr 2004 05:07:43 -0000	1.12
+++ compiler/transform_llds.m	23 May 2004 22:18:04 -0000
@@ -105,7 +105,7 @@
 	PredName = "ACCURATE_GC_END_LABEL",
 	ProcLabel = proc(ModuleName, predicate, ModuleName, PredName,
 		Arity, ProcId),
-	Instrs = [label(local(ProcLabel)) -
+	Instrs = [label(entry(local, ProcLabel)) -
 		"label to indicate end of previous procedure"],
 	DummyProc = c_procedure(PredName, Arity, proc(PredId, ProcId),
 		Instrs, ProcLabel, counter__init(0), must_not_alter_rtti),
@@ -195,9 +195,9 @@
 
 		Index     = binop((-), Rval, const(int_const(Mid))),
 		Test      = binop((>=), Rval, const(int_const(Mid))),
-		ElseAddr  = label(local(LabelNum, ProcLabel)),
+		ElseAddr  = label(internal(LabelNum, ProcLabel)),
 		IfInstr   = if_val(Test, ElseAddr) - "binary search",
-		ElseInstr = label(local(LabelNum, ProcLabel)) - "",
+		ElseInstr = label(internal(LabelNum, ProcLabel)) - "",
 
 		split_computed_goto(Rval, Start, Comment ++ " then",
 			ThenInstrs, !C, MaxSize, Mid, ProcLabel),
Index: compiler/use_local_vars.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/use_local_vars.m,v
retrieving revision 1.7
diff -u -b -r1.7 use_local_vars.m
--- compiler/use_local_vars.m	11 Nov 2003 03:35:08 -0000	1.7
+++ compiler/use_local_vars.m	23 May 2004 22:18:04 -0000
@@ -161,7 +161,7 @@
 find_live_lvals_at_end_labels(LiveMap, Label, !LiveLvals) :-
 	( map__search(LiveMap, Label, LabelLiveLvals) ->
 		set__union(LabelLiveLvals, !LiveLvals)
-	; Label = local(_, _) ->
+	; Label = internal(_, _) ->
 		error("find_live_lvals_at_end_labels: local label not found")
 	;
 		% Non-local labels can be found only through call instructions,
cvs server: Diffing compiler/notes
cvs server: Diffing debian
cvs server: Diffing deep_profiler
cvs server: Diffing deep_profiler/notes
cvs server: Diffing doc
cvs server: Diffing extras
cvs server: Diffing extras/aditi
cvs server: Diffing extras/cgi
cvs server: Diffing extras/complex_numbers
cvs server: Diffing extras/complex_numbers/samples
cvs server: Diffing extras/complex_numbers/tests
cvs server: Diffing extras/concurrency
cvs server: Diffing extras/curs
cvs server: Diffing extras/curs/samples
cvs server: Diffing extras/curses
cvs server: Diffing extras/curses/sample
cvs server: Diffing extras/dynamic_linking
cvs server: Diffing extras/error
cvs server: Diffing extras/graphics
cvs server: Diffing extras/graphics/mercury_glut
cvs server: Diffing extras/graphics/mercury_opengl
cvs server: Diffing extras/graphics/mercury_tcltk
cvs server: Diffing extras/graphics/samples
cvs server: Diffing extras/graphics/samples/calc
cvs server: Diffing extras/graphics/samples/maze
cvs server: Diffing extras/graphics/samples/pent
cvs server: Diffing extras/lazy_evaluation
cvs server: Diffing extras/lex
cvs server: Diffing extras/lex/samples
cvs server: Diffing extras/lex/tests
cvs server: Diffing extras/logged_output
cvs server: Diffing extras/moose
cvs server: Diffing extras/moose/samples
cvs server: Diffing extras/moose/tests
cvs server: Diffing extras/morphine
cvs server: Diffing extras/morphine/non-regression-tests
cvs server: Diffing extras/morphine/scripts
cvs server: Diffing extras/morphine/source
cvs server: Diffing extras/odbc
cvs server: Diffing extras/posix
cvs server: Diffing extras/quickcheck
cvs server: Diffing extras/quickcheck/tutes
cvs server: Diffing extras/references
cvs server: Diffing extras/references/samples
cvs server: Diffing extras/references/tests
cvs server: Diffing extras/stream
cvs server: Diffing extras/trailed_update
cvs server: Diffing extras/trailed_update/samples
cvs server: Diffing extras/trailed_update/tests
cvs server: Diffing extras/xml
cvs server: Diffing extras/xml/samples
cvs server: Diffing java
cvs server: Diffing java/runtime
cvs server: Diffing library
cvs server: Diffing profiler
cvs server: Diffing robdd
cvs server: Diffing runtime
Index: runtime/mercury_stacks.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_stacks.h,v
retrieving revision 1.45
diff -u -b -r1.45 mercury_stacks.h
--- runtime/mercury_stacks.h	19 May 2004 03:59:51 -0000	1.45
+++ runtime/mercury_stacks.h	23 May 2004 22:18:04 -0000
@@ -185,16 +185,15 @@
 				((void) 0)
 #endif
 
-#define	MR_mkframe(predname, numslots, redoip)				\
+#define	MR_mkframe_basic(predname, numslots)				\
 	do {								\
 		MR_Word	*prevfr;					\
 		MR_Word	*succfr;					\
 									\
 		prevfr = MR_maxfr;					\
 		succfr = MR_curfr;					\
-		MR_maxfr += (MR_NONDET_FIXED_SIZE + numslots);		\
+		MR_maxfr += (MR_NONDET_FIXED_SIZE + (numslots));	\
 		MR_curfr = MR_maxfr;					\
-		MR_redoip_slot(MR_curfr) = redoip;			\
 		MR_prevfr_slot(MR_curfr) = prevfr;			\
 		MR_succip_slot(MR_curfr) = MR_succip;			\
 		MR_succfr_slot(MR_curfr) = succfr;			\
@@ -205,27 +204,30 @@
 		MR_collect_non_frame_stats(numslots);			\
 	} while (0)
 
+#define	MR_mkframe(predname, numslots, redoip)				\
+	do {								\
+		MR_mkframe_basic(predname, numslots);			\
+		MR_redoip_slot(MR_curfr) = redoip;			\
+	} while (0)
+
+#define	MR_mkframe_no_redoip(predname, numslots)			\
+	do {								\
+		MR_mkframe_basic(predname, numslots);			\
+	} while (0)
+
 /* just like mkframe, but also reserves space for a struct     */
 /* with the given tag at the bottom of the nondet stack frame  */
 #define	MR_mkpragmaframe(predname, numslots, structname, redoip)	\
 	do {								\
-		MR_Word	*prevfr;					\
-		MR_Word	*succfr;					\
-									\
-		prevfr = MR_maxfr;					\
-		succfr = MR_curfr;					\
-		MR_maxfr += MR_NONDET_FIXED_SIZE + numslots + 		\
-			MR_bytes_to_words(sizeof(struct structname));	\
-		MR_curfr = MR_maxfr;					\
+		MR_mkframe_basic(predname, numslots +			\
+			MR_bytes_to_words(sizeof(struct structname)));	\
 		MR_redoip_slot(MR_curfr) = redoip;			\
-		MR_prevfr_slot(MR_curfr) = prevfr;			\
-		MR_succip_slot(MR_curfr) = MR_succip;			\
-		MR_succfr_slot(MR_curfr) = succfr;			\
-		MR_redofr_slot(MR_curfr) = MR_curfr;			\
-		MR_maybe_fill_table_detfr_slot();			\
-		MR_debugmkframe(predname);				\
-		MR_nondstack_overflow_check();				\
-		MR_collect_non_frame_stats(numslots);			\
+	} while (0)
+
+#define	MR_mkpragmaframe_no_redoip(predname, numslots, structname)	\
+	do {								\
+		MR_mkframe_basic(predname, numslots +			\
+			MR_bytes_to_words(sizeof(struct structname)));	\
 	} while (0)
 
 #define	MR_mktempframe(redoip)						\
cvs server: Diffing runtime/GETOPT
cvs server: Diffing runtime/machdeps
cvs server: Diffing samples
cvs server: Diffing samples/c_interface
cvs server: Diffing samples/c_interface/c_calls_mercury
cvs server: Diffing samples/c_interface/cplusplus_calls_mercury
cvs server: Diffing samples/c_interface/mercury_calls_c
cvs server: Diffing samples/c_interface/mercury_calls_cplusplus
cvs server: Diffing samples/c_interface/mercury_calls_fortran
cvs server: Diffing samples/c_interface/simpler_c_calls_mercury
cvs server: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs server: Diffing samples/diff
cvs server: Diffing samples/muz
cvs server: Diffing samples/rot13
cvs server: Diffing samples/solutions
cvs server: Diffing samples/tests
cvs server: Diffing samples/tests/c_interface
cvs server: Diffing samples/tests/c_interface/c_calls_mercury
cvs server: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs server: Diffing samples/tests/c_interface/mercury_calls_c
cvs server: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs server: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs server: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs server: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs server: Diffing samples/tests/diff
cvs server: Diffing samples/tests/muz
cvs server: Diffing samples/tests/rot13
cvs server: Diffing samples/tests/solutions
cvs server: Diffing samples/tests/toplevel
cvs server: Diffing scripts
cvs server: Diffing tests
cvs server: Diffing tests/benchmarks
cvs server: Diffing tests/debugger
cvs server: Diffing tests/debugger/declarative
cvs server: Diffing tests/dppd
cvs server: Diffing tests/general
cvs server: Diffing tests/general/accumulator
cvs server: Diffing tests/general/string_format
cvs server: Diffing tests/general/structure_reuse
cvs server: Diffing tests/grade_subdirs
cvs server: Diffing tests/hard_coded
cvs server: Diffing tests/hard_coded/exceptions
cvs server: Diffing tests/hard_coded/purity
cvs server: Diffing tests/hard_coded/sub-modules
cvs server: Diffing tests/hard_coded/typeclasses
cvs server: Diffing tests/invalid
cvs server: Diffing tests/invalid/purity
cvs server: Diffing tests/misc_tests
cvs server: Diffing tests/mmc_make
cvs server: Diffing tests/mmc_make/lib
cvs server: Diffing tests/recompilation
cvs server: Diffing tests/tabling
cvs server: Diffing tests/term
cvs server: Diffing tests/valid
cvs server: Diffing tests/warnings
cvs server: Diffing tools
cvs server: Diffing trace
cvs server: Diffing util
cvs server: Diffing vim
cvs server: Diffing vim/after
cvs server: Diffing vim/ftplugin
cvs server: 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