[m-rev.] for review: dupproc.m

Zoltan Somogyi zs at cs.mu.OZ.AU
Mon Jul 4 15:51:26 AEST 2005


For review by anyone.

Add a new LLDS optimization we discussed on thursday: elimination of procedures
whose code is an exact copy of the code of another mode of the same predicate.
This happens with in,out vs di,uo and also possibly with in,out vs any,any.
The new optimization reduces the compiler's code size by 0.6%.

compiler/dupproc.m:
	A new module implementing the new optimization.

compiler/ll_backend.m:
	Add dupproc.m as a new submodule.

compiler/notes/compiler_design.html:
	Mention the new module.

compiler/options.m:
	Add an option, --optimize-proc-dups, enabling the new optimization.
	Make --opt-space imply the new option.

doc/user_guide.texi:
	Document the new option.

compiler/mercury_compile.m:
	Invoke the new optimization when compiling by predicates.

	Move the imports of library modules to their own section.

compiler/handle_options.m:
	Make --optimize-proc-dups imply compiling by predicates.

The rest of these changes are cosmetic only.

compiler/llds.m:
	Delete an obsolete form of constant we haven't used in a long time.

compiler/exprn_aux.m:
compiler/jumpopt.m:
compiler/llds_out.m:
compiler/opt_debug.m:
compiler/opt_util.m:
	Conform to the change in llds.m.

compiler/dependency_graph.m:
	Clean up some comments.

compiler/dupelim.m:
	Fix some variable names.

compiler/hlds_module.m:
compiler/hlds_pred.m:
	Minor cleanups.

cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/dependency_graph.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/dependency_graph.m,v
retrieving revision 1.77
diff -u -b -r1.77 dependency_graph.m
--- compiler/dependency_graph.m	23 May 2005 03:15:34 -0000	1.77
+++ compiler/dependency_graph.m	3 Jul 2005 01:39:10 -0000
@@ -44,12 +44,19 @@
 	bool::in, dependency_info(pred_id)::out) is det.
 
 	% Output a form of the static call graph to a file, in a format
-	% suitable for use in .dependency_info files.
+	% suitable for use in .dependency_info files. After the heading,
+	% the format of each line is
+	%
+	%	CallerModeDecl \t CalleeModeDecl
+	%
 :- pred dependency_graph__write_dependency_graph(module_info::in,
 	module_info::out, io::di, io::uo) is det.
 
 	% Output a form of the static call graph to a file for use by the
-	% profiler.
+	% profiler. There is no heading, and the format of each line is
+	%
+	%	CallerLabel \t CalleeLabel
+	%
 :- pred dependency_graph__write_prof_dependency_graph(module_info::in,
 	module_info::out, io::di, io::uo) is det.
 
@@ -57,6 +64,7 @@
 	% of the dependency graph, a list of the higher SCCs in the module
 	% and a module_info, find out which members of the SCC can be
 	% called from outside the SCC.
+	%
 :- pred dependency_graph__get_scc_entry_points(list(pred_proc_id)::in,
 	dependency_ordering::in, module_info::in, list(pred_proc_id)::out)
 	is det.
@@ -70,6 +78,7 @@
 	% dead_proc_elim.m should be be run before this is called
 	% to avoid missing some opportunities for merging where
 	% a procedure is called from a dead procedure.
+	%
 :- pred module_info_ensure_aditi_dependency_info(module_info::in,
 	module_info::out) is det.
 
@@ -130,40 +139,39 @@
 
 %-----------------------------------------------------------------------------%
 
-	% Ensure that the dependency graph has been built by building
-	% it if necessary.
-
 module_info_ensure_dependency_info(!ModuleInfo) :-
 	module_info_get_maybe_dependency_info(!.ModuleInfo, MaybeDepInfo),
-	( MaybeDepInfo = yes(_) ->
-		true
+	(
+		MaybeDepInfo = yes(_)
 	;
+		MaybeDepInfo = no,
 		dependency_graph__build_dependency_graph(!.ModuleInfo, no,
 			DepInfo),
 		module_info_set_dependency_info(DepInfo, !ModuleInfo)
 	).
 
+dependency_graph__build_pred_dependency_graph(ModuleInfo, Imported, DepInfo) :-
+	dependency_graph__build_dependency_graph(ModuleInfo, Imported,
+		DepInfo).
+
 	% Traverse the module structure, calling `dependency_graph__add_arcs'
 	% for each procedure body.
 
-dependency_graph__build_pred_dependency_graph(ModuleInfo, Imported, DepInfo) :-
-	dependency_graph__build_dependency_graph(ModuleInfo, Imported, DepInfo).
-
 :- pred dependency_graph__build_dependency_graph(module_info::in, bool::in,
 	dependency_info(T)::out) is det <= dependency_node(T).
 
-dependency_graph__build_dependency_graph(ModuleInfo, Imported, DepInfo) :-
+dependency_graph__build_dependency_graph(ModuleInfo, Imported, !:DepInfo) :-
 	module_info_predids(ModuleInfo, PredIds),
 	relation__init(DepGraph0),
 	dependency_graph__add_nodes(PredIds, ModuleInfo, Imported,
 		DepGraph0, DepGraph1),
 	dependency_graph__add_arcs(PredIds, ModuleInfo, Imported,
 		DepGraph1, DepGraph),
-	hlds_dependency_info_init(DepInfo0),
-	hlds_dependency_info_set_dependency_graph(DepGraph, DepInfo0, DepInfo1),
+	hlds_dependency_info_init(!:DepInfo),
+	hlds_dependency_info_set_dependency_graph(DepGraph, !DepInfo),
 	relation__atsort(DepGraph, DepOrd0),
 	dependency_graph__sets_to_lists(DepOrd0, [], DepOrd),
-	hlds_dependency_info_set_dependency_ordering(DepOrd, DepInfo1, DepInfo).
+	hlds_dependency_info_set_dependency_ordering(DepOrd, !DepInfo).
 
 :- pred dependency_graph__sets_to_lists(list(set(T))::in, list(list(T))::in,
 	list(list(T))::out) is det.
@@ -307,8 +315,8 @@
 		IncludeImported = no,
 		proc_info_goal(ProcInfo0, Goal),
 
-		relation__lookup_element(!.DepGraph,
-			proc(PredId, ProcId), Caller),
+		relation__lookup_element(!.DepGraph, proc(PredId, ProcId),
+			Caller),
 		dependency_graph__add_arcs_in_goal(Goal, Caller, !DepGraph)
 	;
 		IncludeImported = yes,
@@ -432,12 +440,10 @@
 		Unify = simple_test(_, _)
 	;
 		Unify = construct(_, Cons, _, _, _, _, _),
-		dependency_graph__add_arcs_in_cons(Cons, Caller,
-			!DepGraph)
+		dependency_graph__add_arcs_in_cons(Cons, Caller, !DepGraph)
 	;
 		Unify = deconstruct(_, Cons, _, _, _, _),
-		dependency_graph__add_arcs_in_cons(Cons, Caller,
-			!DepGraph)
+		dependency_graph__add_arcs_in_cons(Cons, Caller, !DepGraph)
 	;
 		Unify = complicated_unify(_, _, _)
 	).
@@ -498,9 +504,8 @@
 		!DepGraph) :-
 	PredProcId = unshroud_pred_proc_id(ShroudedPredProcId),
 	(
-			% If the node isn't in the relation, then
-			% we didn't insert it because is was imported,
-			% and we don't consider it.
+		% If the node isn't in the relation, then we didn't insert it
+		% because it was imported, and we don't consider it.
 		relation__search_element(!.DepGraph,
 			dependency_node(PredProcId), Callee)
 	->
@@ -524,9 +529,6 @@
 		_Caller, !DepGraph).
 
 %-----------------------------------------------------------------------------%
-%-----------------------------------------------------------------------------%
-
-%-----------------------------------------------------------------------------%
 
 :- pred dependency_graph__write_dependency_ordering(
 	list(list(pred_proc_id))::in, module_info::in, int::in,
@@ -565,21 +567,12 @@
 
 %-----------------------------------------------------------------------------%
 
-% dependency_graph__write_prof_dependency_graph:
-%	Output the static call graph of the current module in the form of
-%		CallerLabel (\t) CalleeLabel
-%
 dependency_graph__write_prof_dependency_graph(!ModuleInfo, !IO) :-
 	module_info_ensure_dependency_info(!ModuleInfo),
 	module_info_dependency_info(!.ModuleInfo, DepInfo),
 	write_graph(DepInfo, write_empty_node,
 		write_prof_dep_graph_link(!.ModuleInfo), !IO).
 
-% dependency_graph__write_dependency_graph:
-%	Output the static call graph of the current module in the form of
-%		CallerModeDecl (\t) CalleeModeDecl
-%	with a heading.
-%
 dependency_graph__write_dependency_graph(!ModuleInfo, !IO) :-
 	module_info_ensure_dependency_info(!ModuleInfo),
 	module_info_dependency_info(!.ModuleInfo, DepInfo),
@@ -659,10 +652,8 @@
 
 %-----------------------------------------------------------------------------%
 
-% dependency_graph__output_label:
-%	Prints out the label corresponding to PredId and ProcId.
-%
-
+	% Print out the label corresponding to the given pred_id and proc_id.
+	%
 :- pred dependency_graph__output_label(module_info::in,
 	pred_id::in, proc_id::in, io::di, io::uo) is det.
 
@@ -689,14 +680,12 @@
 	;
 		% Is the predicate called from a higher SCC?
 		module_info_dependency_info(ModuleInfo, DepInfo),
-		hlds_dependency_info_get_dependency_graph(DepInfo,
-			DepGraph),
+		hlds_dependency_info_get_dependency_graph(DepInfo, DepGraph),
 
 		relation__lookup_element(DepGraph, PredProcId, PredProcIdKey),
 		relation__lookup_to(DepGraph, PredProcIdKey, CallingKeys),
 		set__member(CallingKey, CallingKeys),
-		relation__lookup_key(DepGraph, CallingKey,
-			CallingPred),
+		relation__lookup_key(DepGraph, CallingKey, CallingPred),
 		list__member(HigherSCC, HigherSCCs),
 		list__member(CallingPred, HigherSCC)
 	).
@@ -708,9 +697,10 @@
 	module_info_dependency_info(!.ModuleInfo, DepInfo0),
 	hlds_dependency_info_get_maybe_aditi_dependency_ordering(DepInfo0,
 		MaybeAditiInfo),
-	( MaybeAditiInfo = yes(_) ->
-		true
+	(
+		MaybeAditiInfo = yes(_)
 	;
+		MaybeAditiInfo = no,
 		hlds_dependency_info_get_dependency_ordering(DepInfo0,
 			DepOrdering),
 		aditi_scc_info_init(!.ModuleInfo, AditiInfo0),
@@ -749,8 +739,7 @@
 
 dependency_graph__process_aditi_pred_proc_id(SCCid, PredProcId, !Info) :-
 	aditi_scc_info_get_module_info(ModuleInfo, !Info),
-	module_info_pred_proc_info(ModuleInfo, PredProcId,
-		PredInfo, ProcInfo),
+	module_info_pred_proc_info(ModuleInfo, PredProcId, PredInfo, ProcInfo),
 	dependency_graph__process_aditi_proc_info(SCCid, PredInfo, ProcInfo,
 		!Info).
 
@@ -900,6 +889,7 @@
 		MergedSCCs0, NoMergeSCCs, SCCRel, SCCPreds, !Ordering).
 
 	% Find the SCCs called from a given SCC.
+	%
 :- pred dependency_graph__get_called_scc_ids(scc_id::in, relation(scc_id)::in,
 	set(scc_id)::out) is det.
 
@@ -910,8 +900,9 @@
 	list__map(relation__lookup_key(SCCRel), CalledSCCKeyList, CalledSCCs),
 	set__list_to_set(CalledSCCs, CalledSCCSet).
 
-	% Go over the list of SCCs finding all those which
-	% can be merged into a given SCC.
+	% Go over the list of SCCs finding all those which can be merged
+	% into a given SCC.
+	%
 :- pred dependency_graph__do_merge_aditi_sccs(scc_id::in, set(scc_id)::in,
 	set(scc_id)::in, list(scc_id)::in, list(scc_id)::out,
 	scc_pred_map::in, relation(scc_id)::in,
@@ -1089,6 +1080,7 @@
 
 	% An SCC cannot be merged into its parents if one of its
 	% procedures is called as an aggregate query.
+	%
 :- pred handle_higher_order_args(list(prog_var)::in, bool::in, scc_id::in,
 	multi_map(prog_var, pred_proc_id)::in, map(pred_proc_id, scc_id)::in,
 	relation(scc_id)::in, relation(scc_id)::out,
@@ -1136,8 +1128,8 @@
 	multi_map(prog_var, pred_proc_id)::out,
 	aditi_scc_info::in, aditi_scc_info::out) is det.
 
-aditi_scc_info_add_closure(Var, PredProcId, Map0, Map, Info, Info) :-
-	AditiPreds = Info ^ aditi_scc_local_procs,
+aditi_scc_info_add_closure(Var, PredProcId, Map0, Map, !Info) :-
+	AditiPreds = !.Info ^ aditi_scc_local_procs,
 	( set__member(PredProcId, AditiPreds) ->
 		multi_map__set(Map0, Var, PredProcId, Map)
 	;
Index: compiler/dupelim.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/dupelim.m,v
retrieving revision 1.64
diff -u -b -r1.64 dupelim.m
--- compiler/dupelim.m	16 Jun 2005 05:19:56 -0000	1.64
+++ compiler/dupelim.m	3 Jul 2005 03:36:20 -0000
@@ -495,10 +495,10 @@
 		standardize_rval(Rval1L, RvalL),
 		Rval = unop(Unop, RvalL)
 	;
-		Rval1 = binop(Binnop, Rval1L, Rval1R),
+		Rval1 = binop(Binop, Rval1L, Rval1R),
 		standardize_rval(Rval1L, RvalL),
 		standardize_rval(Rval1R, RvalR),
-		Rval = binop(Binnop, RvalL, RvalR)
+		Rval = binop(Binop, RvalL, RvalR)
 	;
 		Rval1 = mem_addr(_),
 		Rval = Rval1
Index: compiler/dupproc.m
===================================================================
RCS file: compiler/dupproc.m
diff -N compiler/dupproc.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ compiler/dupproc.m	3 Jul 2005 05:54:40 -0000
@@ -0,0 +1,420 @@
+%-----------------------------------------------------------------------------%
+% Copyright (C) 2005 The University of Melbourne.
+% This file may only be copied under the terms of the GNU General
+% Public License - see the file COPYING in the Mercury distribution.
+%-----------------------------------------------------------------------------%
+%
+% File: dupproc.m.
+% Author: zs.
+%
+% The job of this module is to eliminate duplicate procedure bodies. These
+% can arise when a predicate has several modes that differ only in details that
+% don't matter for code generation, such as in/out vs di/uo, or (in some cases)
+% in/out, vs any/any.
+%
+
+%-----------------------------------------------------------------------------%
+
+:- module ll_backend__dupproc.
+
+:- interface.
+
+% :- import_module hlds__hlds_pred.
+:- import_module ll_backend__llds.
+:- import_module mdbcomp__prim_data.
+
+:- import_module assoc_list.
+:- import_module list.
+:- import_module map.
+
+:- pred eliminate_duplicate_procs(assoc_list(proc_label, c_procedure)::in,
+	list(c_procedure)::out,
+	map(proc_label, proc_label)::in, 
+	map(proc_label, proc_label)::out) is det.
+
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module ll_backend__opt_util.
+
+:- import_module require.
+:- import_module std_util.
+
+eliminate_duplicate_procs(IdProcs, Procs, !DupProcMap) :-
+	(
+		IdProcs = [],
+		Procs = []
+	;
+		IdProcs = [_Id - Proc],
+		Procs = [Proc]
+	;
+		IdProcs = [Id1 - Proc1 | IdProcsTail],
+		IdProcsTail = [_ | _],
+		standardize_proc(Proc1, StdProc1, !.DupProcMap),
+		eliminate_dup_procs([Id1 - StdProc1], IdProcsTail,
+			FinalIdProcsTail, !DupProcMap),
+		assoc_list__values(FinalIdProcsTail, FinalProcsTail),
+		Procs = [Proc1 | FinalProcsTail]
+	).
+
+:- pred eliminate_dup_procs(assoc_list(proc_label, c_procedure)::in,
+	assoc_list(proc_label, c_procedure)::in,
+	assoc_list(proc_label, c_procedure)::out,
+	map(proc_label, proc_label)::in, 
+	map(proc_label, proc_label)::out) is det.
+
+eliminate_dup_procs(_ModelStdProcs, [], [], !DupProcMap).
+eliminate_dup_procs(ModelStdProcs0, [Id - Proc0 | IdProcs0],
+		[Id - Proc | IdProcs], !DupProcMap) :-
+	(
+		Proc0 ^ cproc_may_alter_rtti = may_alter_rtti,
+		find_matching_model_proc(ModelStdProcs0, Id, Proc0,
+			!.DupProcMap, MatchingId)
+	->
+		redirect_proc(Proc0, MatchingId, Proc),
+		map__det_insert(!.DupProcMap, Id, MatchingId, !:DupProcMap),
+		ModelStdProcs = ModelStdProcs0
+	;
+		Proc = Proc0,
+		standardize_proc(Proc0, StdProc0, !.DupProcMap),
+		% Since the number of procedures per predicate is tiny,
+		% the quadratic behavior here is not a problem.
+		list__append(ModelStdProcs0, [Id - StdProc0], ModelStdProcs)
+	),
+	eliminate_dup_procs(ModelStdProcs, IdProcs0, IdProcs, !DupProcMap).
+
+:- pred find_matching_model_proc(assoc_list(proc_label, c_procedure)::in,
+	proc_label::in, c_procedure::in, map(proc_label, proc_label)::in,
+	proc_label::out) is semidet.
+
+find_matching_model_proc([ModelId - ModelStdProc | ModelIdProcs], Id, Proc,
+		DupProcMap, MatchingId) :-
+	map__det_insert(DupProcMap, Id, ModelId, AugDupProcMap),
+	standardize_proc(Proc, StdProc, AugDupProcMap),
+	StdInstrs = StdProc ^ cproc_code,
+	ModelStdInstrs = ModelStdProc ^ cproc_code,
+	( StdInstrs = ModelStdInstrs ->
+		MatchingId = ModelId
+	;
+		find_matching_model_proc(ModelIdProcs, Id, Proc, DupProcMap,
+			MatchingId)
+	).
+
+:- pred redirect_proc(c_procedure::in, proc_label::in, c_procedure::out)
+	is det.
+
+redirect_proc(Proc0, Target, Proc) :-
+	Instrs0 = Proc0 ^ cproc_code,
+	get_prologue(Instrs0, LabelInstr, _Comments, _LaterInstrs),
+	Redirect = goto(label(entry(local, Target))) -
+		"Redirect to procedure with identical body",
+	Instrs = [LabelInstr, Redirect],
+	Proc = Proc0 ^ cproc_code := Instrs.
+
+%-----------------------------------------------------------------------------%
+
+:- pred standardize_proc(c_procedure::in, c_procedure::out,
+	map(proc_label, proc_label)::in) is det.
+
+standardize_proc(CProc, StdCProc, DupProcMap) :-
+	Instrs = CProc ^ cproc_code,
+	standardize_instrs(Instrs, StdInstrs, DupProcMap),
+	StdCProc = CProc ^ cproc_code := StdInstrs.
+
+:- pred standardize_instrs(list(instruction)::in, list(instruction)::out,
+	map(proc_label, proc_label)::in) is det.
+
+standardize_instrs([], [], _).
+standardize_instrs([Instr - _ | Instrs], [StdInstr - "" | StdInstrs],
+		DupProcMap) :-
+	standardize_instr(Instr, StdInstr, DupProcMap),
+	standardize_instrs(Instrs, StdInstrs, DupProcMap).
+
+:- pred standardize_instr(instr::in, instr::out,
+	map(proc_label, proc_label)::in) is det.
+
+standardize_instr(Instr, StdInstr, DupProcMap) :-
+	(
+		Instr = comment(_),
+		StdInstr = comment("")
+	;
+		Instr = livevals(_),
+		StdInstr = Instr
+	;
+		Instr = block(NumIntTemps, NumFloatTemps, Instrs),
+		standardize_instrs(Instrs, StdInstrs, DupProcMap),
+		StdInstr = block(NumIntTemps, NumFloatTemps, StdInstrs)
+	;
+		Instr = assign(Lval, Rval),
+		standardize_rval(Rval, StdRval, DupProcMap),
+		StdInstr = assign(Lval, StdRval)
+	;
+		Instr = call(Target, Cont, LiveInfo, Context, GoalPath, Model),
+		standardize_code_addr(Target, StdTarget, DupProcMap),
+		standardize_code_addr(Cont, StdCont, DupProcMap),
+		StdInstr = call(StdTarget, StdCont, LiveInfo, Context,
+			GoalPath, Model)
+	;
+		Instr = mkframe(FrameInfo, MaybeCodeAddr),
+		(
+			FrameInfo = temp_frame(_),
+			StdFrameInfo = FrameInfo
+		;
+			FrameInfo = ordinary_frame(_, NumSlots, MaybePragma),
+			StdFrameInfo = ordinary_frame("", NumSlots,
+				MaybePragma)
+		),
+		standardize_maybe_code_addr(MaybeCodeAddr, MaybeStdCodeAddr,
+			DupProcMap),
+		StdInstr = mkframe(StdFrameInfo, MaybeStdCodeAddr)
+	;
+		Instr = label(Label),
+		standardize_label(Label, StdLabel, DupProcMap),
+		StdInstr = label(StdLabel)
+	;
+		Instr = goto(Target),
+		standardize_code_addr(Target, StdTarget, DupProcMap),
+		StdInstr = goto(StdTarget)
+	;
+		Instr = computed_goto(Rval, Targets),
+		standardize_labels(Targets, StdTargets, DupProcMap),
+		StdInstr = computed_goto(Rval, StdTargets)
+	;
+		Instr = c_code(_, _),
+		StdInstr = Instr
+	;
+		Instr = if_val(Rval, Target),
+		standardize_rval(Rval, StdRval, DupProcMap),
+		standardize_code_addr(Target, StdTarget, DupProcMap),
+		StdInstr = if_val(StdRval, StdTarget)
+	;
+		Instr = incr_hp(_, _, _, _, _),
+		StdInstr = Instr
+	;
+		Instr = mark_hp(_),
+		StdInstr = Instr
+	;
+		Instr = restore_hp(_),
+		StdInstr = Instr
+	;
+		Instr = free_heap(_),
+		StdInstr = Instr
+	;
+		Instr = store_ticket(_),
+		StdInstr = Instr
+	;
+		Instr = reset_ticket(_, _),
+		StdInstr = Instr
+	;
+		Instr = discard_ticket,
+		StdInstr = Instr
+	;
+		Instr = prune_ticket,
+		StdInstr = Instr
+	;
+		Instr = mark_ticket_stack(_),
+		StdInstr = Instr
+	;
+		Instr = prune_tickets_to(_),
+		StdInstr = Instr
+	;
+		Instr = incr_sp(NumSlots, _),
+		StdInstr = incr_sp(NumSlots, "")
+	;
+		Instr = decr_sp(_),
+		StdInstr = Instr
+	;
+		Instr = fork(Child, Parent, NumSlots),
+		standardize_label(Child, StdChild, DupProcMap),
+		standardize_label(Parent, StdParent, DupProcMap),
+		StdInstr = fork(StdChild, StdParent, NumSlots)
+	;
+		Instr = init_sync_term(_, _),
+		StdInstr = Instr
+	;
+		Instr = join_and_terminate(_),
+		StdInstr = Instr
+	;
+		Instr = join_and_continue(Lval, Label),
+		standardize_label(Label, StdLabel, DupProcMap),
+		StdInstr = join_and_continue(Lval, StdLabel)
+	;
+		Instr = pragma_c(_, _, _, _, _, _, _, _, _),
+		% The labels occurring in pragma_c instructions cannot be
+		% substituted.
+		StdInstr = Instr
+	).
+
+	% Compute the standard form of a proc_label.
+	%
+:- pred standardize_proc_label(proc_label::in, proc_label::out,
+	map(proc_label, proc_label)::in) is det.
+
+standardize_proc_label(ProcLabel, StdProcLabel, DupProcMap) :-
+	( map__search(DupProcMap, ProcLabel, FoundProcLabel) ->
+		StdProcLabel = FoundProcLabel
+	;
+		StdProcLabel = ProcLabel
+	).
+
+	% Compute the standard form of a label.
+	%
+:- pred standardize_label(label::in, label::out,
+	map(proc_label, proc_label)::in) is det.
+
+standardize_label(Label, StdLabel, DupProcMap) :-
+	(
+		Label = internal(Num, ProcLabel),
+		standardize_proc_label(ProcLabel, StdProcLabel, DupProcMap),
+		StdLabel = internal(Num, StdProcLabel)
+	;
+		Label = entry(Type, ProcLabel),
+		standardize_proc_label(ProcLabel, StdProcLabel, DupProcMap),
+		StdLabel = entry(Type, StdProcLabel)
+	).
+
+	% Compute the standard form of a list(label).
+	%
+:- pred standardize_labels(list(label)::in, list(label)::out,
+	map(proc_label, proc_label)::in) is det.
+
+standardize_labels([], [], _DupProcMap).
+standardize_labels([Label | Labels], [StdLabel | StdLabels], DupProcMap) :-
+	standardize_label(Label, StdLabel, DupProcMap),
+	standardize_labels(Labels, StdLabels, DupProcMap).
+
+	% Compute the standard form of a code_addr.
+	%
+:- pred standardize_code_addr(code_addr::in, code_addr::out,
+	map(proc_label, proc_label)::in) is det.
+
+standardize_code_addr(CodeAddr, StdCodeAddr, DupProcMap) :-
+	(
+		CodeAddr = label(Label),
+		standardize_label(Label, StdLabel, DupProcMap),
+		StdCodeAddr = label(StdLabel)
+	;
+		CodeAddr = imported(ProcLabel),
+		standardize_proc_label(ProcLabel, StdProcLabel, DupProcMap),
+		StdCodeAddr = imported(StdProcLabel)
+	;
+		CodeAddr = succip,
+		StdCodeAddr = CodeAddr
+	;
+		CodeAddr = do_succeed(_),
+		StdCodeAddr = CodeAddr
+	;
+		CodeAddr = do_redo,
+		StdCodeAddr = CodeAddr
+	;
+		CodeAddr = do_fail,
+		StdCodeAddr = CodeAddr
+	;
+		CodeAddr = do_trace_redo_fail_shallow,
+		StdCodeAddr = CodeAddr
+	;
+		CodeAddr = do_trace_redo_fail_deep,
+		StdCodeAddr = CodeAddr
+	;
+		CodeAddr = do_call_closure,
+		StdCodeAddr = CodeAddr
+	;
+		CodeAddr = do_call_class_method,
+		StdCodeAddr = CodeAddr
+	;
+		CodeAddr = do_not_reached,
+		StdCodeAddr = CodeAddr
+	).
+
+	% Compute the standard form of a maybe(code_addr).
+	%
+:- pred standardize_maybe_code_addr(maybe(code_addr)::in,
+	maybe(code_addr)::out, map(proc_label, proc_label)::in) is det.
+
+standardize_maybe_code_addr(MaybeCodeAddr, MaybeStdCodeAddr, DupProcMap) :-
+	(
+		MaybeCodeAddr = no,
+		MaybeStdCodeAddr = no
+	;
+		MaybeCodeAddr = yes(CodeAddr),
+		standardize_code_addr(CodeAddr, StdCodeAddr, DupProcMap),
+		MaybeStdCodeAddr = yes(StdCodeAddr)
+	).
+
+	% Compute the standard form of a list(code_addr).
+	%
+:- pred standardize_code_addrs(list(code_addr)::in, list(code_addr)::out,
+	map(proc_label, proc_label)::in) is det.
+
+standardize_code_addrs([], [], _DupProcMap).
+standardize_code_addrs([CodeAddr | CodeAddrs], [StdCodeAddr |
+		StdCodeAddrs], DupProcMap) :-
+	standardize_code_addr(CodeAddr, StdCodeAddr, DupProcMap),
+	standardize_code_addrs(CodeAddrs, StdCodeAddrs, DupProcMap).
+
+	% Compute the standard form of an rval.
+	%
+:- pred standardize_rval(rval::in, rval::out, map(proc_label, proc_label)::in)
+	is det.
+
+standardize_rval(Rval, StdRval, DupProcMap) :-
+	(
+		Rval = lval(_),
+		StdRval = Rval
+	;
+		Rval = var(_),
+		error("var in standardize_rval")
+	;
+		Rval = mkword(_, _),
+		StdRval = Rval
+	;
+		Rval = const(Const),
+		standardize_rval_const(Const, StdConst, DupProcMap),
+		StdRval = const(StdConst)
+	;
+		Rval = unop(Unop, RvalL),
+		standardize_rval(RvalL, StdRvalL, DupProcMap),
+		StdRval = unop(Unop, StdRvalL)
+	;
+		Rval = binop(Binop, RvalL, RvalR),
+		standardize_rval(RvalL, StdRvalL, DupProcMap),
+		standardize_rval(RvalR, StdRvalR, DupProcMap),
+		StdRval = binop(Binop, StdRvalL, StdRvalR)
+	;
+		Rval = mem_addr(_),
+		StdRval = Rval
+	).
+
+	% Compute the standard form of an rval constant.
+	%
+:- pred standardize_rval_const(rval_const::in, rval_const::out,
+	map(proc_label, proc_label)::in) is det.
+
+standardize_rval_const(Const, StdConst, DupProcMap) :-
+	(
+		Const = true,
+		StdConst = Const
+	;
+		Const = false,
+		StdConst = Const
+	;
+		Const = int_const(_),
+		StdConst = Const
+	;
+		Const = float_const(_),
+		StdConst = Const
+	;
+		Const = string_const(_),
+		StdConst = Const
+	;
+		Const = multi_string_const(_, _),
+		StdConst = Const
+	;
+		Const = code_addr_const(CodeAddr),
+		standardize_code_addr(CodeAddr, StdCodeAddr, DupProcMap),
+		StdConst = code_addr_const(StdCodeAddr)
+	;
+		Const = data_addr_const(_, _),
+		StdConst = Const
+	).
Index: compiler/exprn_aux.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/exprn_aux.m,v
retrieving revision 1.56
diff -u -b -r1.56 exprn_aux.m
--- compiler/exprn_aux.m	4 May 2005 07:42:42 -0000	1.56
+++ compiler/exprn_aux.m	3 Jul 2005 03:20:39 -0000
@@ -149,8 +149,6 @@
 exprn_aux__const_is_constant(code_addr_const(CodeAddr), ExprnOpts, IsConst) :-
 	exprn_aux__addr_is_constant(CodeAddr, ExprnOpts, IsConst).
 exprn_aux__const_is_constant(data_addr_const(_, _), _, yes).
-exprn_aux__const_is_constant(label_entry(Label), ExprnOpts, IsConst) :-
-	exprn_aux__addr_is_constant(label(Label), ExprnOpts, IsConst).
 
 :- pred exprn_aux__addr_is_constant(code_addr::in, exprn_opts::in, bool::out)
 	is det.
Index: compiler/handle_options.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/handle_options.m,v
retrieving revision 1.231
diff -u -b -r1.231 handle_options.m
--- compiler/handle_options.m	15 Jun 2005 08:16:18 -0000	1.231
+++ compiler/handle_options.m	3 Jul 2005 05:51:52 -0000
@@ -1557,7 +1557,10 @@
 		% --optimize-frames requires --optimize-labels and
 		% --optimize-jumps
 	option_implies(optimize_frames, optimize_labels, bool(yes)),
-	option_implies(optimize_frames, optimize_jumps, bool(yes)).
+	option_implies(optimize_frames, optimize_jumps, bool(yes)),
+
+		% --optimize-proc-dups is implemented only with --trad-passes.
+	option_implies(optimize_proc_dups, trad_passes, bool(yes)).
 
 % option_implies(SourceBoolOption, ImpliedOption, ImpliedOptionValue, IO0, IO).
 % If the SourceBoolOption is set to yes, then the ImpliedOption is set
Index: compiler/hlds_module.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_module.m,v
retrieving revision 1.114
diff -u -b -r1.114 hlds_module.m
--- compiler/hlds_module.m	26 May 2005 00:17:00 -0000	1.114
+++ compiler/hlds_module.m	3 Jul 2005 01:07:14 -0000
@@ -670,7 +670,6 @@
 
 		maybe_complexity_proc_map	:: maybe(pair(int,
 							complexity_proc_map)),
-
 		complexity_proc_infos		:: list(complexity_proc_info),
 						% Information about the
 						% procedures we are performing
@@ -680,6 +679,7 @@
 						% Information for the
 						% inter-module analysis
 						% framework.
+
 		aditi_top_down_procs		:: list(aditi_top_down_proc),
 						% List of top-down procedures
 						% which could be called from
@@ -912,41 +912,41 @@
 	module_info_get_predicate_table(MI, PredTable),
 	predicate_table_get_predids(PredTable, PredIds).
 
-module_info_reverse_predids(MI0, MI) :-
-	module_info_get_predicate_table(MI0, PredTable0),
+module_info_reverse_predids(!MI) :-
+	module_info_get_predicate_table(!.MI, PredTable0),
 	predicate_table_reverse_predids(PredTable0, PredTable),
-	module_info_set_predicate_table(PredTable, MI0, MI).
+	module_info_set_predicate_table(PredTable, !MI).
 
-module_info_remove_predid(PredId, MI0, MI) :-
-	module_info_get_predicate_table(MI0, PredTable0),
+module_info_remove_predid(PredId, !MI) :-
+	module_info_get_predicate_table(!.MI, PredTable0),
 	predicate_table_remove_predid(PredId, PredTable0, PredTable),
-	module_info_set_predicate_table(PredTable, MI0, MI).
+	module_info_set_predicate_table(PredTable, !MI).
 
-module_info_remove_predicate(PredId, MI0, MI) :-
-	module_info_get_predicate_table(MI0, PredTable0),
+module_info_remove_predicate(PredId, !MI) :-
+	module_info_get_predicate_table(!.MI, PredTable0),
 	predicate_table_remove_predicate(PredId, PredTable0, PredTable),
-	module_info_set_predicate_table(PredTable, MI0, MI).
+	module_info_set_predicate_table(PredTable, !MI).
 
-module_info_set_preds(Preds, MI0, MI) :-
-	module_info_get_predicate_table(MI0, PredTable0),
+module_info_set_preds(Preds, !MI) :-
+	module_info_get_predicate_table(!.MI, PredTable0),
 	predicate_table_set_preds(Preds, PredTable0, PredTable),
-	module_info_set_predicate_table(PredTable, MI0, MI).
+	module_info_set_predicate_table(PredTable, !MI).
 
-module_info_set_pred_info(PredId, PredInfo, MI0, MI) :-
-	module_info_preds(MI0, Preds0),
+module_info_set_pred_info(PredId, PredInfo, !MI) :-
+	module_info_preds(!.MI, Preds0),
 	map__set(Preds0, PredId, PredInfo, Preds),
-	module_info_set_preds(Preds, MI0, MI).
+	module_info_set_preds(Preds, !MI).
 
 module_info_set_pred_proc_info(proc(PredId, ProcId), PredInfo, ProcInfo,
-		MI0, MI) :-
+		!MI) :-
 	module_info_set_pred_proc_info(PredId, ProcId,
-		PredInfo, ProcInfo, MI0, MI).
+		PredInfo, ProcInfo, !MI).
 
-module_info_set_pred_proc_info(PredId, ProcId, PredInfo0, ProcInfo, MI0, MI) :-
+module_info_set_pred_proc_info(PredId, ProcId, PredInfo0, ProcInfo, !MI) :-
 	pred_info_procedures(PredInfo0, Procs0),
 	map__set(Procs0, ProcId, ProcInfo, Procs),
 	pred_info_set_procedures(Procs, PredInfo0, PredInfo),
-	module_info_set_pred_info(PredId, PredInfo, MI0, MI).
+	module_info_set_pred_info(PredId, PredInfo, !MI).
 
 module_info_typeids(MI, TypeCtors) :-
 	module_info_types(MI, Types),
@@ -967,9 +967,11 @@
 
 module_info_dependency_info(MI, DepInfo) :-
 	module_info_get_maybe_dependency_info(MI, MaybeDepInfo),
-	( MaybeDepInfo = yes(DepInfoPrime) ->
+	(
+		MaybeDepInfo = yes(DepInfoPrime),
 		DepInfo = DepInfoPrime
 	;
+		MaybeDepInfo = no,
 		error("Attempted to access invalid dependency_info")
 	).
 
@@ -977,25 +979,27 @@
 	module_info_dependency_info(MI, DepInfo),
 	hlds_dependency_info_get_maybe_aditi_dependency_ordering(DepInfo,
 		MaybeOrdering),
-	( MaybeOrdering = yes(OrderingPrime) ->
+	(
+		MaybeOrdering = yes(OrderingPrime),
 		AditiOrdering = OrderingPrime
 	;
+		MaybeOrdering = no,
 		error("Attempted to access invalid aditi_dependency_ordering")
 	).
 
-module_info_set_dependency_info(DependencyInfo, MI0, MI) :-
-	module_info_set_maybe_dependency_info(yes(DependencyInfo), MI0, MI).
+module_info_set_dependency_info(DependencyInfo, !MI) :-
+	module_info_set_maybe_dependency_info(yes(DependencyInfo), !MI).
 
-module_info_clobber_dependency_info(MI0, MI) :-
-	module_info_set_maybe_dependency_info(no, MI0, MI).
+module_info_clobber_dependency_info(!MI) :-
+	module_info_set_maybe_dependency_info(no, !MI).
 
-module_info_incr_errors(MI0, MI) :-
-	module_info_num_errors(MI0, Errs0),
+module_info_incr_errors(!MI) :-
+	module_info_num_errors(!.MI, Errs0),
 	Errs = Errs0 + 1,
-	module_info_set_num_errors(Errs, MI0, MI).
+	module_info_set_num_errors(Errs, !MI).
 
-module_info_next_lambda_count(Context, Count, MI0, MI) :-
-	module_info_get_lambdas_per_context(MI0, ContextCounter0),
+module_info_next_lambda_count(Context, Count, !MI) :-
+	module_info_get_lambdas_per_context(!.MI, ContextCounter0),
 	(
 		map.insert(ContextCounter0, Context, counter.init(2), 
 			FoundContextCounter)
@@ -1005,14 +1009,15 @@
 	;
 		map.lookup(ContextCounter0, Context, Counter0),
 		counter.allocate(Count, Counter0, Counter),
-		map.det_update(ContextCounter0, Context, Counter, ContextCounter)
+		map.det_update(ContextCounter0, Context, Counter,
+			ContextCounter)
 	),
-	module_info_set_lambdas_per_context(ContextCounter, MI0, MI).
+	module_info_set_lambdas_per_context(ContextCounter, !MI).
 
-module_info_next_model_non_pragma_count(Count, MI0, MI) :-
-	module_info_get_model_non_pragma_counter(MI0, Counter0),
+module_info_next_model_non_pragma_count(Count, !MI) :-
+	module_info_get_model_non_pragma_counter(!.MI, Counter0),
 	counter__allocate(Count, Counter0, Counter),
-	module_info_set_model_non_pragma_counter(Counter, MI0, MI).
+	module_info_set_model_non_pragma_counter(Counter, !MI).
 
 	% After we have finished constructing the symbol tables,
 	% we balance all the binary trees, to improve performance
@@ -1188,16 +1193,16 @@
 	% module+name+arity, for both functions and predicates.
 
 	% Initialize the predicate table
-
+	%
 :- pred predicate_table_init(predicate_table::out) is det.
 
 	% Balance all the binary trees in the predicate table
-
+	%
 :- pred predicate_table_optimize(predicate_table::in, predicate_table::out)
 	is det.
 
 	% Get the pred_id->pred_info map.
-
+	%
 :- pred predicate_table_get_preds(predicate_table::in, pred_table::out) is det.
 
 	% Restrict the predicate table to the list of predicates.
@@ -1205,7 +1210,7 @@
 	% to restrict the table to is significantly smaller then the
 	% predicate_table size, as rather than removing entries from
 	% the table it builds a new table from scratch.
-
+	%
 :- pred predicate_table_restrict(partial_qualifier_info::in,
 	list(pred_id)::in, predicate_table::in, predicate_table::out) is det.
 
@@ -1213,17 +1218,17 @@
 	% NB You shouldn't modify the keys in this table, only
 	% use predicate_table_insert, predicate_table_remove_predid and
 	% predicate_table_remove_predicate.
-
+	%
 :- pred predicate_table_set_preds(pred_table::in,
 	predicate_table::in, predicate_table::out) is det.
 
 	% Get a list of all the valid predids in the predicate_table.
-
+	%
 :- pred predicate_table_get_predids(predicate_table::in, list(pred_id)::out)
 	is det.
 
 	% Remove a pred_id from the valid list.
-
+	%
 :- pred predicate_table_remove_predid(pred_id::in,
 	predicate_table::in, predicate_table::out) is det.
 :- pred predicate_table_remove_predicate(pred_id::in,
@@ -1232,7 +1237,7 @@
 	% Search the table for (a) predicates or functions
 	% (b) predicates only or (c) functions only
 	% matching this (possibly module-qualified) sym_name.
-
+	%
 :- pred predicate_table_search_sym(predicate_table::in, is_fully_qualified::in,
 	sym_name::in, list(pred_id)::out) is semidet.
 
@@ -1245,7 +1250,7 @@
 	% Search the table for (a) predicates or functions
 	% (b) predicates only or (c) functions only matching this
 	% (possibly module-qualified) sym_name & arity.
-
+	%
 :- pred predicate_table_search_sym_arity(predicate_table::in,
 	is_fully_qualified::in, sym_name::in, arity::in, list(pred_id)::out)
 	is semidet.
@@ -1259,9 +1264,8 @@
 	is semidet.
 
 	% Search the table for (a) predicates or functions
-	% (b) predicates only or (c) functions only
-	% matching this name.
-
+	% (b) predicates only or (c) functions only matching this name.
+	%
 :- pred predicate_table_search_name(predicate_table::in, string::in,
 	list(pred_id)::out) is semidet.
 
@@ -1277,7 +1281,7 @@
 	% When searching for functions, the arity used
 	% is the arity of the function, not the arity N+1 predicate
 	% that it gets converted to.
-
+	%
 :- pred predicate_table_search_name_arity(predicate_table::in, string::in,
 	arity::in, list(pred_id)::out) is semidet.
 
@@ -1331,7 +1335,7 @@
 	% to, i.e. the arity of the function plus one.
 	% NB.  This is opposite to what happens with the search
 	% predicates declared above!!
-
+	%
 :- pred predicate_table_search_pf_m_n_a(predicate_table::in,
 	is_fully_qualified::in, pred_or_func::in, module_name::in, string::in,
 	arity::in, list(pred_id)::out) is semidet.
@@ -1343,7 +1347,7 @@
 	% to, i.e. the arity of the function plus one.
 	% NB.  This is opposite to what happens with the search
 	% predicates declared above!!
-
+	%
 :- pred predicate_table_search_pf_name_arity(predicate_table::in,
 	pred_or_func::in, string::in, arity::in, list(pred_id)::out)
 	is semidet.
@@ -1355,14 +1359,14 @@
 	% to, i.e. the arity of the function plus one.
 	% NB.  This is opposite to what happens with the search
 	% predicates declared above!!
-
+	%
 :- pred predicate_table_search_pf_sym_arity(predicate_table::in,
 	is_fully_qualified::in, pred_or_func::in, sym_name::in, arity::in,
 	list(pred_id)::out) is semidet.
 
 	% Search the table for predicates or functions matching
 	% this pred_or_func category and sym_name.
-
+	%
 :- pred predicate_table_search_pf_sym(predicate_table::in,
 	is_fully_qualified::in, pred_or_func::in, sym_name::in,
 	list(pred_id)::out) is semidet.
@@ -1373,6 +1377,7 @@
 	% Insert PredInfo into PredTable0 and assign it a new pred_id.
 	% You should check beforehand that the pred doesn't already
 	% occur in the table.
+	%
 :- pred predicate_table_insert(pred_info::in, need_qualifier::in,
 	partial_qualifier_info::in, pred_id::out,
 	predicate_table::in, predicate_table::out) is det.
@@ -1382,6 +1387,7 @@
 	% the predicate symbol table.  This is useful for creating
 	% compiler-generated predicates which will only ever be accessed
 	% via fully-qualified names.
+	%
 :- pred predicate_table_insert(pred_info::in, pred_id::out,
 	predicate_table::in, predicate_table::out) is det.
 
@@ -1394,19 +1400,21 @@
 :- pred predicate_arity(module_info::in, pred_id::in, arity::out) is det.
 
 	% Get the pred_id and proc_id matching a higher-order term with
-	% the given argument types, aborting with an error if none is
-	% found.
+	% the given argument types, aborting with an error if none is found.
+	%
 :- pred get_pred_id_and_proc_id(is_fully_qualified::in, sym_name::in,
 	pred_or_func::in, tvarset::in, list(type)::in, module_info::in,
 	pred_id::out, proc_id::out) is det.
 
 	% Get the pred_id matching a higher-order term with
 	% the given argument types, failing if none is found.
+	%
 :- pred get_pred_id(is_fully_qualified::in, sym_name::in, pred_or_func::in,
 	tvarset::in, list(type)::in, module_info::in, pred_id::out) is semidet.
 
 	% Given a pred_id, return the single proc_id, aborting
 	% if there are no modes or more than one mode.
+	%
 :- pred get_proc_id(module_info::in, pred_id::in, proc_id::out) is det.
 
 :- type mode_no
@@ -1561,10 +1569,10 @@
 	module_name_arity_index::in, module_name_arity_index::out) is det.
 
 predicate_table_remove_from_index(Module, Name, Arity, PredId,
-		N0, N, NA0, NA, MNA0, MNA) :-
-	do_remove_from_index(Name, PredId, N0, N),
-	do_remove_from_index(Name / Arity, PredId, NA0, NA),
-	do_remove_from_m_n_a_index(Module, Name, Arity, PredId, MNA0, MNA).
+		!N, !NA, !MNA) :-
+	do_remove_from_index(Name, PredId, !N),
+	do_remove_from_index(Name / Arity, PredId, !NA),
+	do_remove_from_m_n_a_index(Module, Name, Arity, PredId, !MNA).
 
 :- pred do_remove_from_index(T::in, pred_id::in,
 	map(T, list(pred_id))::in, map(T, list(pred_id))::out) is det.
@@ -1572,9 +1580,11 @@
 do_remove_from_index(T, PredId, Index0, Index) :-
 	( map__search(Index0, T, NamePredIds0) ->
 		list__delete_all(NamePredIds0, PredId, NamePredIds),
-		( NamePredIds = [] ->
+		(
+			NamePredIds = [],
 			map__delete(Index0, T, Index)
 		;
+			NamePredIds = [_ | _],
 			map__det_update(Index0, T, NamePredIds, Index)
 		)
 	;
@@ -1619,7 +1629,7 @@
 		qualified(Module, Name), PredIdList) :-
 	predicate_table_search_module_name(PredicateTable, IsFullyQualified,
 		Module, Name, PredIdList),
-	PredIdList \= [].
+	PredIdList = [_ | _].
 
 predicate_table_search_pred_sym(PredicateTable, may_be_partially_qualified,
 		unqualified(Name), PredIdList) :-
@@ -1628,7 +1638,7 @@
 		qualified(Module, Name), PredIdList) :-
 	predicate_table_search_pred_module_name(PredicateTable,
 		IsFullyQualified, Module, Name, PredIdList),
-	PredIdList \= [].
+	PredIdList = [_ | _].
 
 predicate_table_search_func_sym(PredicateTable, may_be_partially_qualified,
 		unqualified(Name), PredIdList) :-
@@ -1637,7 +1647,7 @@
 		qualified(Module, Name), PredIdList) :-
 	predicate_table_search_func_module_name(PredicateTable,
 		IsFullyQualified, Module, Name, PredIdList),
-	PredIdList \= [].
+	PredIdList = [_ | _].
 
 	% Given a list of predicates, and a module name, find all the
 	% predicates which came from that module.
@@ -1693,7 +1703,7 @@
 		FuncPredIds = []
 	),
 	list__append(FuncPredIds, PredPredIds, PredIds),
-	PredIds \= [].
+	PredIds = [_ | _].
 
 predicate_table_search_pred_name(PredicateTable, PredName, PredIds) :-
 	map__search(PredicateTable ^ pred_name_index, PredName, PredIds).
@@ -1726,7 +1736,7 @@
 		FuncPredIds = []
 	),
 	list__append(FuncPredIds, PredPredIds, PredIds),
-	PredIds \= [].
+	PredIds = [_ | _].
 
 :- pred predicate_table_search_pred_module_name(predicate_table::in,
 	is_fully_qualified::in, module_name::in, string::in,
@@ -1774,7 +1784,7 @@
 		FuncPredIds = []
 	),
 	list__append(FuncPredIds, PredPredIds, PredIds),
-	PredIds \= [].
+	PredIds = [_ | _].
 
 predicate_table_search_pred_name_arity(PredicateTable, PredName, Arity,
 		PredIds) :-
@@ -1807,7 +1817,7 @@
 		FuncPredIds = []
 	),
 	list__append(FuncPredIds, PredPredIds, PredIds),
-	PredIds \= [].
+	PredIds = [_ | _].
 
 predicate_table_search_pred_m_n_a(PredicateTable, IsFullyQualified,
 		Module, PredName, Arity, PredIds) :-
@@ -2014,7 +2024,8 @@
 		PredId, AccessibilityTable0, AccessibilityTable,
 		N_Index0, N_Index, NA_Index0, NA_Index,
 		MNA_Index0, MNA_Index) :-
-	( NeedQual = may_be_unqualified ->
+	(
+		NeedQual = may_be_unqualified,
 			% insert the unqualified name into the name index
 		multi_map__set(N_Index0, Name, PredId, N_Index),
 
@@ -2025,11 +2036,13 @@
 
 		AccessibleByUnqualifiedName = yes
 	;
+		NeedQual = must_be_qualified,
 		N_Index = N_Index0,
 		NA_Index = NA_Index0,
 		AccessibleByUnqualifiedName = no
 	),
-	( MaybeQualInfo = yes(QualInfo) ->
+	(
+		MaybeQualInfo = yes(QualInfo),
 
 			% insert partially module-qualified versions
 			% of the name into the module:name/arity index
@@ -2042,6 +2055,7 @@
 
 		AccessibleByPartiallyQualifiedNames = yes
 	;
+		MaybeQualInfo = no,
 		MNA_Index1 = MNA_Index0,
 		AccessibleByPartiallyQualifiedNames = no
 	),
@@ -2122,7 +2136,8 @@
 		Arity = pred_info_orig_arity(PredInfo),
 		PredOrFuncStr = prog_out__pred_or_func_to_str(PredOrFunc),
 		string__int_to_string(Arity, ArityString),
-		( ProcIds = [] ->
+		(
+			ProcIds = [],
 			string__append_list([
 				"cannot take address of ", PredOrFuncStr,
 				"\n`", Name, "/", ArityString,
@@ -2131,6 +2146,7 @@
 				"bailing out.)"],
 				Message)
 		;
+			ProcIds = [_ | _],
 			string__append_list([
 				"sorry, not implemented: ",
 				"taking address of ", PredOrFuncStr,
Index: compiler/hlds_pred.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_pred.m,v
retrieving revision 1.164
diff -u -b -r1.164 hlds_pred.m
--- compiler/hlds_pred.m	7 Jun 2005 02:59:55 -0000	1.164
+++ compiler/hlds_pred.m	3 Jul 2005 01:11:17 -0000
@@ -105,16 +105,15 @@
 	% to be used to initialize the relevant fields in in call(...) goals
 	% before we do type- and mode-checks, or when those check find that
 	% there was no predicate matching the call.
-
+	%
 :- func invalid_pred_id = pred_id.
 :- func invalid_proc_id = proc_id.
 
 :- pred hlds_pred__next_pred_id(pred_id::in, pred_id::out) is det.
 
-	% For semidet complicated unifications with mode (in, in),
-	% these are defined to have the same proc_id (0).  This
-	% returns that proc_id.
-
+	% For semidet complicated unifications with mode (in, in), these are
+	% defined to have the same proc_id (0).  This returns that proc_id.
+	%
 :- pred hlds_pred__in_in_unification_proc_id(proc_id::out) is det.
 
 :- type pred_info.
@@ -927,8 +926,9 @@
 :- func pred_info_module(pred_info) =  module_name.
 :- func pred_info_name(pred_info) = string.
 
-	% pred_info_orig_arity returns the arity of the predicate
+	% Pred_info_orig_arity returns the arity of the predicate
 	% *not* counting inserted type_info arguments for polymorphic preds.
+	%
 :- func pred_info_orig_arity(pred_info) = arity.
 
 	% N-ary functions are converted into N+1-ary predicates.
Index: compiler/jumpopt.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/jumpopt.m,v
retrieving revision 1.76
diff -u -b -r1.76 jumpopt.m
--- compiler/jumpopt.m	16 Jun 2005 03:44:42 -0000	1.76
+++ compiler/jumpopt.m	3 Jul 2005 03:22:27 -0000
@@ -1025,9 +1025,6 @@
 jumpopt__short_labels_const(_, string_const(S), string_const(S)).
 jumpopt__short_labels_const(_, multi_string_const(L, S),
         multi_string_const(L, S)).
-jumpopt__short_labels_const(Instrmap, label_entry(Label0),
-        label_entry(Label)) :-
-    jumpopt__short_label(Instrmap, Label0, Label).
 jumpopt__short_labels_const(Instrmap, code_addr_const(CodeAddr0),
         code_addr_const(CodeAddr)) :-
     ( CodeAddr0 = label(Label0) ->
Index: compiler/ll_backend.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ll_backend.m,v
retrieving revision 1.9
diff -u -b -r1.9 ll_backend.m
--- compiler/ll_backend.m	5 Apr 2005 08:34:05 -0000	1.9
+++ compiler/ll_backend.m	3 Jul 2005 01:53:07 -0000
@@ -70,6 +70,7 @@
 :- include_module optimize.
    :- include_module jumpopt.
    :- include_module dupelim.
+   :- include_module dupproc.
    :- include_module frameopt.
    :- include_module delay_slot.
    :- include_module labelopt.
Index: compiler/llds.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/llds.m,v
retrieving revision 1.311
diff -u -b -r1.311 llds.m
--- compiler/llds.m	24 Mar 2005 13:33:33 -0000	1.311
+++ compiler/llds.m	3 Jul 2005 03:22:18 -0000
@@ -747,11 +747,10 @@
 
 	% An lval represents a data location or register that can be used
 	% as the target of an assignment.
-:- type lval --->
-
+:- type lval
 	/* virtual machine registers */
 
-		reg(reg_type, int)
+	--->	reg(reg_type, int)
 				% One of the general-purpose virtual machine
 				% registers (either an int or float reg).
 
@@ -891,11 +890,9 @@
 			% whose real length is given by the integer,
 			% and not the location of the first NULL
 	;	code_addr_const(code_addr)
-	;	data_addr_const(data_addr, maybe(int))
+	;	data_addr_const(data_addr, maybe(int)).
 			% if the second arg is yes(Offset), then increment the
 			% address of the first by Offset words
-	;	label_entry(label).
-			% the address of the label (uses MR_ENTRY macro).
 
 :- type data_addr
 	--->	data_addr(module_name, data_name)
@@ -1149,7 +1146,6 @@
 llds__const_type(multi_string_const(_, _), string).
 llds__const_type(code_addr_const(_), code_ptr).
 llds__const_type(data_addr_const(_, _), data_ptr).
-llds__const_type(label_entry(_), code_ptr).
 
 llds__unop_return_type(mktag, word).
 llds__unop_return_type(tag, word).
Index: compiler/llds_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/llds_out.m,v
retrieving revision 1.249
diff -u -b -r1.249 llds_out.m
--- compiler/llds_out.m	10 Jun 2005 06:38:28 -0000	1.249
+++ compiler/llds_out.m	3 Jul 2005 03:22:39 -0000
@@ -4806,10 +4806,6 @@
 		io__write_int(Offset, !IO),
 		io__write_string(")", !IO)
 	).
-output_rval_const(label_entry(Label), !IO) :-
-	io__write_string("MR_ENTRY_AP(", !IO),
-	output_label(Label, no, !IO),
-	io__write_string(")", !IO).
 
 :- pred output_type_ctor_addr(module_name::in, string::in, int::in,
 	io::di, io::uo) is det.
Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mercury_compile.m,v
retrieving revision 1.334
diff -u -b -r1.334 mercury_compile.m
--- compiler/mercury_compile.m	17 Jun 2005 10:13:52 -0000	1.334
+++ compiler/mercury_compile.m	3 Jul 2005 16:37:44 -0000
@@ -42,7 +42,6 @@
     %
 
     % semantic analysis
-:- import_module libs__handle_options.
 :- import_module parse_tree__prog_foreign.
 :- import_module parse_tree__prog_io.
 :- import_module parse_tree__prog_out.
@@ -72,7 +71,6 @@
 :- import_module transform_hlds__complexity.
 :- import_module transform_hlds__lambda.
 :- import_module transform_hlds__closure_analysis.
-:- import_module backend_libs__type_ctor_info.
 :- import_module transform_hlds__termination.
 :- import_module transform_hlds__term_constr_main.
 :- import_module transform_hlds__exception_analysis.
@@ -109,10 +107,7 @@
 :- import_module ll_backend__continuation_info.
 :- import_module ll_backend__stack_layout.
 :- import_module ll_backend__global_data.
-:- import_module backend_libs__foreign.
-:- import_module backend_libs__export.
-:- import_module backend_libs__base_typeclass_info.
-:- import_module backend_libs__type_class_info.
+:- import_module ll_backend__dupproc.
 
     % the Aditi-RL back-end
 :- import_module aditi_backend__rl_gen.
@@ -143,9 +138,6 @@
 :- import_module aditi_backend__rl.
 :- import_module aditi_backend__rl_dump.
 :- import_module aditi_backend__rl_file.
-:- import_module backend_libs__compile_target_code.
-:- import_module backend_libs__name_mangle.
-:- import_module backend_libs__rtti.
 :- import_module check_hlds__goal_path.
 :- import_module hlds__arg_info.
 :- import_module hlds__hlds_data.
@@ -153,10 +145,6 @@
 :- import_module hlds__hlds_out.
 :- import_module hlds__hlds_pred.
 :- import_module hlds__passes_aux.
-:- import_module libs__globals.
-:- import_module libs__options.
-:- import_module libs__timestamp.
-:- import_module libs__trace_params.
 :- import_module ll_backend__layout.
 :- import_module ll_backend__llds.
 :- import_module make.
@@ -176,6 +164,22 @@
 :- import_module analysis.
 :- import_module transform_hlds__mmc_analysis.
 
+    % compiler library modules
+:- import_module backend_libs__base_typeclass_info.
+:- import_module backend_libs__compile_target_code.
+:- import_module backend_libs__export.
+:- import_module backend_libs__foreign.
+:- import_module backend_libs__name_mangle.
+:- import_module backend_libs__proc_label.
+:- import_module backend_libs__rtti.
+:- import_module backend_libs__type_class_info.
+:- import_module backend_libs__type_ctor_info.
+:- import_module libs__globals.
+:- import_module libs__handle_options.
+:- import_module libs__options.
+:- import_module libs__timestamp.
+:- import_module libs__trace_params.
+
     % library modules
 :- import_module assoc_list.
 :- import_module benchmarking.
@@ -2529,16 +2533,30 @@
 
 mercury_compile__backend_pass_by_preds(!HLDS, !GlobalData, LLDS, !IO) :-
     module_info_predids(!.HLDS, PredIds),
-    mercury_compile__backend_pass_by_preds_2(PredIds, !HLDS, !GlobalData,
-        LLDS, !IO).
+    globals__io_lookup_bool_option(optimize_proc_dups, ProcDups, !IO),
+    (
+        ProcDups = no,
+        OrderedPredIds = PredIds,
+        MaybeDupProcMap = no
+    ;
+        ProcDups = yes,
+        dependency_graph__build_pred_dependency_graph(!.HLDS, no, DepInfo),
+        hlds_dependency_info_get_dependency_ordering(DepInfo, PredSCCs),
+        list__condense(PredSCCs, OrderedPredIds),
+        MaybeDupProcMap = yes(map.init)
+    ),
+    mercury_compile__backend_pass_by_preds_2(OrderedPredIds, !HLDS,
+        !GlobalData, MaybeDupProcMap, LLDS, !IO).
 
 :- pred mercury_compile__backend_pass_by_preds_2(list(pred_id)::in,
     module_info::in, module_info::out, global_data::in, global_data::out,
+    maybe(map(mdbcomp__prim_data__proc_label,
+        mdbcomp__prim_data__proc_label))::in,
     list(c_procedure)::out, io::di, io::uo) is det.
 
-mercury_compile__backend_pass_by_preds_2([], !HLDS, !GlobalData, [], !IO).
+mercury_compile__backend_pass_by_preds_2([], !HLDS, !GlobalData, _, [], !IO).
 mercury_compile__backend_pass_by_preds_2([PredId | PredIds], !HLDS,
-        !GlobalData, Code, !IO) :-
+        !GlobalData, !.MaybeDupProcMap, Code, !IO) :-
     module_info_preds(!.HLDS, PredTable),
     map__lookup(PredTable, PredId, PredInfo),
     ProcIds = pred_info_non_imported_procids(PredInfo),
@@ -2547,7 +2565,7 @@
         ; hlds_pred__pred_info_is_aditi_relation(PredInfo)
         )
     ->
-        Code1 = []
+        ProcList = []
     ;
         globals__io_lookup_bool_option(verbose, Verbose, !IO),
         (
@@ -2576,7 +2594,7 @@
             copy(Globals1, Globals1Unique),
             globals__io_set_globals(Globals1Unique, !IO),
             mercury_compile__backend_pass_by_preds_3(ProcIds, PredId, PredInfo,
-                !HLDS, !GlobalData, Code1, !IO),
+                !HLDS, !GlobalData, IdProcList, !IO),
             module_info_globals(!.HLDS, Globals2),
             globals__set_trace_level(TraceLevel, Globals2, Globals),
             module_info_set_globals(Globals, !HLDS),
@@ -2584,22 +2602,33 @@
             globals__io_set_globals(GlobalsUnique, !IO)
         ;
             mercury_compile__backend_pass_by_preds_3(ProcIds, PredId, PredInfo,
-                !HLDS, !GlobalData, Code1, !IO)
+                !HLDS, !GlobalData, IdProcList, !IO)
+        ),
+        (
+            !.MaybeDupProcMap = no,
+            assoc_list__values(IdProcList, ProcList)
+        ;
+            !.MaybeDupProcMap = yes(DupProcMap0),
+            eliminate_duplicate_procs(IdProcList, ProcList,
+                DupProcMap0, DupProcMap),
+            !:MaybeDupProcMap = yes(DupProcMap)
         )
     ),
     mercury_compile__backend_pass_by_preds_2(PredIds, !HLDS, !GlobalData,
-        Code2, !IO),
-    list__append(Code1, Code2, Code).
+        !.MaybeDupProcMap, TailPredsCode, !IO),
+    list__append(ProcList, TailPredsCode, Code).
 
 :- pred mercury_compile__backend_pass_by_preds_3(list(proc_id)::in,
     pred_id::in, pred_info::in, module_info::in, module_info::out,
-    global_data::in, global_data::out, list(c_procedure)::out,
+    global_data::in, global_data::out,
+    assoc_list(mdbcomp__prim_data__proc_label, c_procedure)::out,
     io::di, io::uo) is det.
 
 mercury_compile__backend_pass_by_preds_3([], _, _, !HLDS, !GlobalData, [],
         !IO).
 mercury_compile__backend_pass_by_preds_3([ProcId | ProcIds], PredId, PredInfo,
-        !HLDS, !GlobalData, [Proc | Procs], !IO) :-
+        !HLDS, !GlobalData, [ProcLabel - Proc | Procs], !IO) :-
+    ProcLabel = make_proc_label(!.HLDS, PredId, ProcId),
     pred_info_procedures(PredInfo, ProcTable),
     map__lookup(ProcTable, ProcId, ProcInfo),
     mercury_compile__backend_pass_by_preds_4(PredInfo, ProcInfo, _,
Index: compiler/opt_debug.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/opt_debug.m,v
retrieving revision 1.150
diff -u -b -r1.150 opt_debug.m
--- compiler/opt_debug.m	31 Mar 2005 04:44:21 -0000	1.150
+++ compiler/opt_debug.m	3 Jul 2005 03:22:48 -0000
@@ -314,9 +314,6 @@
 			["data_addr_const(", DataAddr_str, ", ",
 			Offset_str, ")"], Str)
 	).
-dump_const(label_entry(Label), Str) :-
-	dump_label(Label, LabelStr),
-	string__append_list(["label_entry(", LabelStr, ")"], Str).
 
 dump_data_addr(data_addr(ModuleName, DataName), Str) :-
 	mdbcomp__prim_data__sym_name_to_string(ModuleName, ModuleName_str),
Index: compiler/opt_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/opt_util.m,v
retrieving revision 1.130
diff -u -b -r1.130 opt_util.m
--- compiler/opt_util.m	16 Jun 2005 05:19:56 -0000	1.130
+++ compiler/opt_util.m	3 Jul 2005 03:22:57 -0000
@@ -1959,7 +1959,6 @@
 	replace_labels_code_addr(Addr0, ReplMap, Addr).
 replace_labels_rval_const(data_addr_const(DataAddr, MaybeOffset), _,
 		data_addr_const(DataAddr, MaybeOffset)).
-replace_labels_rval_const(label_entry(Label), _, label_entry(Label)).
 
 :- pred replace_labels_code_addr(code_addr::in, map(label, label)::in,
 	code_addr::out) is det.
Index: compiler/options.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.461
diff -u -b -r1.461 options.m
--- compiler/options.m	17 Jun 2005 10:13:53 -0000	1.461
+++ compiler/options.m	2 Jul 2005 23:52:24 -0000
@@ -565,6 +565,7 @@
 		;	local_var_access_threshold
 		;	optimize_labels
 		;	optimize_dups
+		;	optimize_proc_dups
 %%% unused:	;	optimize_copyprop
 		;	optimize_frames
 		;	optimize_delay_slot
@@ -1234,6 +1235,7 @@
 	local_var_access_threshold -	int(2),
 	optimize_labels		-	bool(no),
 	optimize_dups		-	bool(no),
+	optimize_proc_dups	-	bool(no),
 %%%	optimize_copyprop	-	bool(no),
 	optimize_frames		-	bool(no),
 	optimize_delay_slot	-	bool(no),
@@ -1960,6 +1962,8 @@
 long_option("optimise-labels",		optimize_labels).
 long_option("optimize-dups",		optimize_dups).
 long_option("optimise-dups",		optimize_dups).
+long_option("optimize-proc-dups",	optimize_proc_dups).
+long_option("optimise-proc-dups",	optimize_proc_dups).
 %%% long_option("optimize-copyprop",	optimize_copyprop).
 %%% long_option("optimise-copyprop",	optimize_copyprop).
 long_option("optimize-frames",		optimize_frames).
@@ -2419,6 +2423,7 @@
 	optimize_dead_procs	-	bool(yes),
 	optimize_labels		-	bool(yes),
 	optimize_dups		-	bool(yes),
+	optimize_proc_dups	-	bool(yes),
 	optimize_fulljumps	-	bool(no),
 	optimize_reassign	-	bool(yes),
 	inline_alloc		-	bool(no),
@@ -4037,7 +4042,9 @@
 		"--no-optimize-labels",
 		"\tDisable elimination of dead labels and code.",
 		"--optimize-dups",
-		"\tEnable elimination of duplicate code.",
+		"\tEnable elimination of duplicate code within procedures.",
+		"--optimize-proc-dups",
+		"\tEnable elimination of duplicate procedures.",
 %%%		"--optimize-copyprop",
 %%%		"\tEnable the copy propagation optimization.",
 		"--no-optimize-frames",
cvs diff: Diffing compiler/notes
Index: compiler/notes/compiler_design.html
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/notes/compiler_design.html,v
retrieving revision 1.102
diff -u -b -r1.102 compiler_design.html
--- compiler/notes/compiler_design.html	24 Apr 2005 01:47:58 -0000	1.102
+++ compiler/notes/compiler_design.html	3 Jul 2005 05:46:20 -0000
@@ -1115,13 +1115,16 @@
 
 <p>
 
-The various LLDS-to-LLDS optimizations are invoked from optimize.m.
+Most of the various LLDS-to-LLDS optimizations are invoked from optimize.m.
 They are:
 
 <ul>
 <li> optimization of jumps to jumps (jumpopt.m)
 
-<li> elimination of duplicate code sequences (dupelim.m)
+<li> elimination of duplicate code sequences within procedures (dupelim.m)
+
+<li> elimination of duplicate procedure bodies (dupproc.m,
+invoked directly from mercury_compile.m)
 
 <li> optimization of stack frame allocation/deallocation (frameopt.m)
 
@@ -1131,11 +1134,10 @@
 
 <li> peephole optimization (peephole.m)
 
-<li> introduction of local C variables (use_local_vars.m) <br>
+<li> introduction of local C variables (use_local_vars.m)
 
 <li> removal of redundant assignments, i.e. assignments that assign a value
-that the target location already holds (reassign.m) <br>
-
+that the target location already holds (reassign.m)
 
 </ul>
 
cvs diff: Diffing debian
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.440
diff -u -b -r1.440 user_guide.texi
--- doc/user_guide.texi	30 Jun 2005 08:12:04 -0000	1.440
+++ doc/user_guide.texi	4 Jul 2005 05:29:33 -0000
@@ -7253,7 +7253,12 @@
 @sp 1
 @item --optimize-dups
 @findex --optimize-dups
-Enable elimination of duplicate code.
+Enable elimination of duplicate code within procedures.
+
+ at sp 1
+ at item --optimize-proc-dups
+ at findex --optimize-proc-dups
+Enable elimination of duplicate procedures.
 
 @c @sp 1
 @c @item --optimize-copyprop
cvs diff: Diffing extras
cvs diff: Diffing extras/aditi
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/stream
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing mdbcomp
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list