[m-dev.] for review: --target option, IL grades and copy-in/copy-out for MLDS

Tyson Dowd trd at cs.mu.OZ.AU
Mon Sep 4 23:58:29 AEDT 2000


Hi,

This is really two changes, but the smaller one (add new options and
grades to cater for a non-C backend) adds the options that control the
larger one (copy-in/copy-out).  If there are issues with this diff I'm
prepared to split it.

Fergus did this work, but any mistakes are probably the result of my
merging or separating the diffs.

Someone other than Fergus should review this.  I think Pete is likely to
be directly affected if this change goes awry, so perhaps he could do
the honours?

===================================================================


Estimated hours taken: 24	(by fjh)

Add new options and grades for the IL back-end.

Implement an option to handle output parameters for nondeterministic
procedures by passing the outputs (by value) to the continuation,
rather than using pass-by-reference.  This is needed for IL
because IL does not allow managed pointers (which we used to
implement pass-by-refernece) to be stored as fields of environment
structs.

Also add an option to return outputs by value in det/semidet code.
This is not yet tested, since none of our target languages support
returning multiple values.

(Note that the IL backend is not activated by these changes -- it
hasn't been checked in).

compiler/globals.m:
	Use field names for the globals structure.
	Add new `target' field to the globals.

compiler/options.m:
compiler/handle_options.m:
        Add new options `--target', `--target-only', `--il', and `--il-only'.
        Add new grades `il' and `ilc'.
	Change `--compile-to-c' from a boolean option to an abbreviation
	for `--target c --target-only', and move it from the "Output options"
	section to the "Compilation model options" section.

        Comment out the documentation for `--generate-prolog' and
        `--prolog-dialect', since those options are not yet implemented.

        Document the `--infer-all' option.

compiler/mercury_compile.m:
        Check the `target_code_only' option rather than `compile_to_c',
        since the latter is just an abbreviation now, not a real option.

compiler/ml_call_gen.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_unify_gen.m:
        Use the `--det-copy-out' option to decide whether to pass output
        arguments by reference, or whether to just return multiple values.
        Use the `--nondet-copy-out' option to decide whether to pass output
        arguments by reference, or whether to just pass them to the
        continuation.

compiler/mlds.m:
        Change the mlds__cont_type so that it includes a list of
        the continuation's argument types (if any).

compiler/mlds_to_c.m:
        Update to reflect the change to mlds.m.

doc/user_guide.texi:
        Update the documentation to reflect the above changes.


scripts/parse_grade_options.sh-subr:
	Add new options `--target' and `--il'.

scripts/init_grade_options.sh-subr
        Add new grades `il' and `ilc'.

scripts/final_grade_options.sh-subr
        Make `--target il' imply `--high-level-code'.



Index: compiler/globals.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/globals.m,v
retrieving revision 1.34
diff -u -r1.34 globals.m
--- compiler/globals.m	1999/06/01 09:43:44	1.34
+++ compiler/globals.m	2000/09/04 03:17:06
@@ -21,6 +21,13 @@
 
 :- type globals.
 
+:- type compilation_target
+	--->	c	% Generate C code
+	;	il	% Generate IL assembler code
+			% IL is the Microsoft COM+ 2.0 Intermediate Language
+	;	java.	% Generate Java
+			% (this target is not yet implemented)
+
 :- type gc_method
 	--->	none
 	;	conservative
@@ -47,6 +54,7 @@
 	;	shallow
 	;	deep.
 
+:- pred convert_target(string::in, compilation_target::out) is semidet.
 :- pred convert_gc_method(string::in, gc_method::out) is semidet.
 :- pred convert_tags_method(string::in, tags_method::out) is semidet.
 :- pred convert_prolog_dialect(string::in, prolog_dialect::out) is semidet.
@@ -58,11 +66,12 @@
 
 	% Access predicates for the `globals' structure.
 
-:- pred globals__init(option_table::di, gc_method::di, tags_method::di,
-	prolog_dialect::di, termination_norm::di, trace_level::di,
-	globals::uo) is det.
+:- pred globals__init(option_table::di, compilation_target::di, gc_method::di,
+	tags_method::di, prolog_dialect::di, termination_norm::di,
+	trace_level::di, globals::uo) is det.
 
 :- pred globals__get_options(globals::in, option_table::out) is det.
+:- pred globals__get_target(globals::in, compilation_target::out) is det.
 :- pred globals__get_gc_method(globals::in, gc_method::out) is det.
 :- pred globals__get_tags_method(globals::in, tags_method::out) is det.
 :- pred globals__get_prolog_dialect(globals::in, prolog_dialect::out) is det.
@@ -106,9 +115,13 @@
 
 	% Access predicates for storing a `globals' structure in the
 	% io__state using io__set_globals and io__get_globals.
+
+:- pred globals__io_init(option_table::di, compilation_target::in,
+	gc_method::in, tags_method::in, prolog_dialect::in,
+	termination_norm::in, trace_level::in,
+	io__state::di, io__state::uo) is det.
 
-:- pred globals__io_init(option_table::di, gc_method::in, tags_method::in,
-	prolog_dialect::in, termination_norm::in, trace_level::in,
+:- pred globals__io_get_target(compilation_target::out,
 	io__state::di, io__state::uo) is det.
 
 :- pred globals__io_get_gc_method(gc_method::out,
@@ -164,6 +177,13 @@
 :- import_module exprn_aux.
 :- import_module map, std_util, io, require.
 
+convert_target("java", java).
+convert_target("Java", java).
+convert_target("il", il).
+convert_target("IL", il).
+convert_target("c", c).
+convert_target("C", c).
+
 convert_gc_method("none", none).
 convert_gc_method("conservative", conservative).
 convert_gc_method("accurate", accurate).
@@ -202,33 +222,32 @@
 
 :- type globals
 	--->	globals(
-			option_table,
-			gc_method,
-			tags_method,
-			prolog_dialect,
-			termination_norm,
-			trace_level
+			options :: option_table,
+			target :: compilation_target,
+			gc_method :: gc_method,
+			tags_method :: tags_method,
+			prolog_dialect :: prolog_dialect,
+			termination_norm :: termination_norm,
+			trace_level :: trace_level
 		).
 
-globals__init(Options, GC_Method, TagsMethod,
+globals__init(Options, Target, GC_Method, TagsMethod,
 		PrologDialect, TerminationNorm, TraceLevel,
-	globals(Options, GC_Method, TagsMethod,
+	globals(Options, Target, GC_Method, TagsMethod,
 		PrologDialect, TerminationNorm, TraceLevel)).
 
-globals__get_options(globals(Options, _, _, _, _, _), Options).
-globals__get_gc_method(globals(_, GC_Method, _, _, _, _), GC_Method).
-globals__get_tags_method(globals(_, _, TagsMethod, _, _, _), TagsMethod).
-globals__get_prolog_dialect(globals(_, _, _, PrologDialect, _, _),
-	PrologDialect).
-globals__get_termination_norm(globals(_, _, _, _, TerminationNorm, _),
-	TerminationNorm).
-globals__get_trace_level(globals(_, _, _, _, _, TraceLevel), TraceLevel).
+globals__get_options(Globals, Globals^options).
+globals__get_target(Globals, Globals^target).
+globals__get_gc_method(Globals, Globals^gc_method).
+globals__get_tags_method(Globals, Globals^tags_method).
+globals__get_prolog_dialect(Globals, Globals^prolog_dialect).
+globals__get_termination_norm(Globals, Globals^termination_norm).
+globals__get_trace_level(Globals, Globals^trace_level).
 
-globals__set_options(globals(_, B, C, D, E, F), Options,
-	globals(Options, B, C, D, E, F)).
+globals__set_options(Globals, Options, Globals^options := Options).
 
-globals__set_trace_level(globals(A, B, C, D, E, _), TraceLevel,
-	globals(A, B, C, D, E, TraceLevel)).
+globals__set_trace_level(Globals, TraceLevel,
+	Globals^trace_level := TraceLevel).
 
 globals__lookup_option(Globals, Option, OptionData) :-
 	globals__get_options(Globals, OptionTable),
@@ -306,16 +325,21 @@
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
-globals__io_init(Options, GC_Method, TagsMethod,
+globals__io_init(Options, Target, GC_Method, TagsMethod,
 		PrologDialect, TerminationNorm, TraceLevel) -->
+	{ copy(Target, Target1) },
 	{ copy(GC_Method, GC_Method1) },
 	{ copy(TagsMethod, TagsMethod1) },
 	{ copy(PrologDialect, PrologDialect1) },
 	{ copy(TerminationNorm, TerminationNorm1) },
 	{ copy(TraceLevel, TraceLevel1) },
-	{ globals__init(Options, GC_Method1, TagsMethod1,
+	{ globals__init(Options, Target1, GC_Method1, TagsMethod1,
 		PrologDialect1, TerminationNorm1, TraceLevel1, Globals) },
 	globals__io_set_globals(Globals).
+
+globals__io_get_target(Target) -->
+	globals__io_get_globals(Globals),
+	{ globals__get_target(Globals, Target) }.
 
 globals__io_get_gc_method(GC_Method) -->
 	globals__io_get_globals(Globals),
Index: compiler/handle_options.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/handle_options.m,v
retrieving revision 1.88
diff -u -r1.88 handle_options.m
--- compiler/handle_options.m	2000/01/10 05:26:18	1.88
+++ compiler/handle_options.m	2000/09/04 03:17:06
@@ -80,14 +80,18 @@
 			ConvertToGoedel),
 		globals__io_lookup_bool_option(typecheck_only, TypecheckOnly),
 		globals__io_lookup_bool_option(errorcheck_only, ErrorcheckOnly),
-		globals__io_lookup_bool_option(compile_to_c, CompileToC),
+		globals__io_lookup_bool_option(target_code_only,
+			TargetCodeOnly),
+		globals__io_get_target(Target),
+		{ GenerateIL = (if Target = il then yes else no) },
 		globals__io_lookup_bool_option(compile_only, CompileOnly),
 		globals__io_lookup_bool_option(aditi_only, AditiOnly),
 		{ bool__or_list([GenerateDependencies, MakeInterface,
 			MakePrivateInterface, MakeShortInterface,
 			MakeOptimizationInt, MakeTransOptInt,
 			ConvertToMercury, ConvertToGoedel, TypecheckOnly,
-			ErrorcheckOnly, CompileToC, CompileOnly, AditiOnly],
+			ErrorcheckOnly, TargetCodeOnly, GenerateIL,
+			CompileOnly, AditiOnly],
 			NotLink) },
 		{ bool__not(NotLink, Link) }
 	).
@@ -114,93 +118,103 @@
 
 postprocess_options(error(ErrorMessage), yes(ErrorMessage)) --> [].
 postprocess_options(ok(OptionTable), Error) -->
-    { map__lookup(OptionTable, gc, GC_Method0) },
+    { map__lookup(OptionTable, target, Target0) },
     (
-        { GC_Method0 = string(GC_MethodStr) },
-        { convert_gc_method(GC_MethodStr, GC_Method) }
+        { Target0 = string(TargetStr) },
+        { convert_target(TargetStr, Target) }
     ->
-        { map__lookup(OptionTable, tags, TagsMethod0) },
+        { map__lookup(OptionTable, gc, GC_Method0) },
         (
-            { TagsMethod0 = string(TagsMethodStr) },
-            { convert_tags_method(TagsMethodStr, TagsMethod) }
+            { GC_Method0 = string(GC_MethodStr) },
+            { convert_gc_method(GC_MethodStr, GC_Method) }
         ->
-            { map__lookup(OptionTable, prolog_dialect, PrologDialect0) },
+            { map__lookup(OptionTable, tags, TagsMethod0) },
             (
-                { PrologDialect0 = string(PrologDialectStr) },
-                { convert_prolog_dialect(PrologDialectStr, PrologDialect) }
+                { TagsMethod0 = string(TagsMethodStr) },
+                { convert_tags_method(TagsMethodStr, TagsMethod) }
             ->
-                { map__lookup(OptionTable,
-                    fact_table_hash_percent_full, PercentFull) },
+                { map__lookup(OptionTable, prolog_dialect, PrologDialect0) },
                 (
-                    { PercentFull = int(Percent) },
-                    { Percent >= 1 },
-                    { Percent =< 100 }
+                    { PrologDialect0 = string(PrologDialectStr) },
+                    { convert_prolog_dialect(PrologDialectStr, PrologDialect) }
                 ->
-                    { map__lookup(OptionTable, termination_norm,
-                        TermNorm0) },
+                    { map__lookup(OptionTable,
+                        fact_table_hash_percent_full, PercentFull) },
                     (
-                        { TermNorm0 = string(TermNormStr) },
-                        { convert_termination_norm(TermNormStr, TermNorm) }
+                        { PercentFull = int(Percent) },
+                        { Percent >= 1 },
+                        { Percent =< 100 }
                     ->
-                        { map__lookup(OptionTable, trace, Trace) },
-                        { map__lookup(OptionTable, require_tracing,
-                            RequireTracingOpt) },
+                        { map__lookup(OptionTable, termination_norm,
+                            TermNorm0) },
                         (
-                            { Trace = string(TraceStr) },
-                            { RequireTracingOpt = bool(RequireTracing) },
-                            { convert_trace_level(TraceStr, RequireTracing,
-                                TraceLevel) }
+                            { TermNorm0 = string(TermNormStr) },
+                            { convert_termination_norm(TermNormStr, TermNorm) }
                         ->
-                            { map__lookup(OptionTable, dump_hlds_alias,
-                                DumpAliasOption) },
+                            { map__lookup(OptionTable, trace, Trace) },
+                            { map__lookup(OptionTable, require_tracing,
+                                RequireTracingOpt) },
                             (
-                                { DumpAliasOption = string(DumpAlias) },
-                                { DumpAlias = "" }
+                                { Trace = string(TraceStr) },
+                                { RequireTracingOpt = bool(RequireTracing) },
+                                { convert_trace_level(TraceStr, RequireTracing,
+                                    TraceLevel) }
                             ->
-                                postprocess_options_2(OptionTable,
-                                    GC_Method, TagsMethod, PrologDialect,
-				    TermNorm, TraceLevel, Error)
+                                { map__lookup(OptionTable, dump_hlds_alias,
+                                    DumpAliasOption) },
+                                (
+                                    { DumpAliasOption = string(DumpAlias) },
+                                    { DumpAlias = "" }
+                                ->
+                                    postprocess_options_2(OptionTable,
+                                        Target, GC_Method, TagsMethod,
+				        PrologDialect, TermNorm, TraceLevel,
+					Error)
+                                ;
+                                    { DumpAliasOption = string(DumpAlias) },
+                                    { convert_dump_alias(DumpAlias,
+                                        DumpOptions) }
+                                ->
+                                    { map__set(OptionTable, dump_hlds_options,
+                                        string(DumpOptions), NewOptionTable) },
+                                    postprocess_options_2(NewOptionTable,
+                                        Target, GC_Method, TagsMethod,
+				        PrologDialect, TermNorm, TraceLevel,
+					Error)
+                                ;
+                                    { Error = yes("Invalid argument to option `--hlds-dump-alias'.") }
+                                )
                             ;
-                                { DumpAliasOption = string(DumpAlias) },
-                                { convert_dump_alias(DumpAlias,
-                                    DumpOptions) }
-                            ->
-                                { map__set(OptionTable, dump_hlds_options,
-                                    string(DumpOptions), NewOptionTable) },
-                                postprocess_options_2(NewOptionTable,
-                                    GC_Method, TagsMethod, PrologDialect,
-				    TermNorm, TraceLevel, Error)
-                            ;
-                                { Error = yes("Invalid argument to option `--hlds-dump-alias'.") }
+                                { Error = yes("Invalid argument to option `--trace'\n\t(must be `minimum', `shallow', `deep', or `default').") }
                             )
                         ;
-                            { Error = yes("Invalid argument to option `--trace'\n\t(must be `minimum', `shallow', `deep', or `default').") }
+                            { Error = yes("Invalid argument to option `--termination-norm'\n\t(must be `simple', `total' or  `num-data-elems').") }
                         )
                     ;
-                        { Error = yes("Invalid argument to option `--termination-norm'\n\t(must be `simple', `total' or  `num-data-elems').") }
+                        { Error = yes("Invalid argument to option `--fact-table-hash-percent-full'\n\t(must be an integer between 1 and 100)") }
                     )
                 ;
-                    { Error = yes("Invalid argument to option `--fact-table-hash-percent-full'\n\t(must be an integer between 1 and 100)") }
+                    { Error = yes("Invalid prolog-dialect option (must be `sicstus', `nu', or `default')") }
                 )
             ;
-                { Error = yes("Invalid prolog-dialect option (must be `sicstus', `nu', or `default')") }
+                { Error = yes("Invalid tags option (must be `none', `low' or `high')") }
             )
         ;
-            { Error = yes("Invalid tags option (must be `none', `low' or `high')") }
-        )
+            { Error = yes("Invalid GC option (must be `none', `conservative' or `accurate')") }
+	)
     ;
-        { Error = yes("Invalid GC option (must be `none', `conservative' or `accurate')") }
+        { Error = yes("Invalid target option (must be `c' or `il')") }
     ).
 
-:- pred postprocess_options_2(option_table, gc_method, tags_method,
-	prolog_dialect, termination_norm, trace_level, maybe(string),
-	io__state, io__state).
-:- mode postprocess_options_2(in, in, in, in, in, in, out, di, uo) is det.
+:- pred postprocess_options_2(option_table, compilation_target, gc_method,
+	tags_method, prolog_dialect, termination_norm, trace_level,
+	maybe(string), io__state, io__state).
+:- mode postprocess_options_2(in, in, in, in, in, in, in, out, di, uo) is det.
 
-postprocess_options_2(OptionTable, GC_Method, TagsMethod, PrologDialect,
-		TermNorm, TraceLevel, Error) -->
+postprocess_options_2(OptionTable, Target, GC_Method, TagsMethod,
+		PrologDialect, TermNorm, TraceLevel, Error) -->
 	{ unsafe_promise_unique(OptionTable, OptionTable1) }, % XXX
-	globals__io_init(OptionTable1, GC_Method, TagsMethod,
+	globals__io_init(OptionTable1, Target, GC_Method, TagsMethod,
 		PrologDialect, TermNorm, TraceLevel),
 
 	% --gc conservative implies --no-reclaim-heap-*
@@ -250,6 +264,22 @@
 
 	globals__io_set_option(num_tag_bits, int(NumTagBits)),
 
+	% Generating IL implies high-level code, turning off nested functions,
+	% using copy-out for nondet output arguments,
+	% using zero tags, boxing enums, disabling no_tag_types and no
+	% static ground terms.
+	( { Target = il } ->
+		globals__io_set_option(highlevel_code, bool(yes)),
+		globals__io_set_option(gcc_nested_functions, bool(no)),
+		globals__io_set_option(nondet_copy_out, bool(yes)),
+		globals__io_set_option(num_tag_bits, int(0)),
+		globals__io_set_option(unboxed_enums, bool(no)),
+		globals__io_set_option(unboxed_no_tag_types, bool(no)),
+		globals__io_set_option(static_ground_terms, bool(no))
+	;
+		[]
+	),
+
 	% --high-level-code disables the use of low-level gcc extensions
 	option_implies(highlevel_code, gcc_non_local_gotos, bool(no)),
 	option_implies(highlevel_code, gcc_global_registers, bool(no)),
@@ -664,77 +694,105 @@
 :- mode grade_component_table(out, in, out) is multi.
 :- mode grade_component_table(out, out, out) is multi.
 
-	% GCC-hack components
+	% Base components
+	% These specify the basic compilation model we use,
+	% including the choice of back-end and the use of gcc extensions.
 grade_component_table("none", gcc_ext, [
 		asm_labels		- bool(no),
 		gcc_non_local_gotos	- bool(no),
 		gcc_global_registers	- bool(no),
 		highlevel_code		- bool(no),
 		gcc_nested_functions	- bool(no),
-		highlevel_data		- bool(no)]).
+		highlevel_data		- bool(no),
+		target			- string("c")]).
 grade_component_table("reg", gcc_ext, [
 		asm_labels		- bool(no),
 		gcc_non_local_gotos	- bool(no),
 		gcc_global_registers	- bool(yes),
 		highlevel_code		- bool(no),
 		gcc_nested_functions	- bool(no),
-		highlevel_data		- bool(no)]).
+		highlevel_data		- bool(no),
+		target			- string("c")]).
 grade_component_table("jump", gcc_ext, [
 		asm_labels		- bool(no),
 		gcc_non_local_gotos	- bool(yes),
 		gcc_global_registers	- bool(no),
 		highlevel_code		- bool(no),
 		gcc_nested_functions	- bool(no),
-		highlevel_data		- bool(no)]).
+		highlevel_data		- bool(no),
+		target			- string("c")]).
 grade_component_table("asm_jump", gcc_ext, [
 		asm_labels		- bool(yes),
 		gcc_non_local_gotos	- bool(yes),
 		gcc_global_registers	- bool(no),
 		highlevel_code		- bool(no),
 		gcc_nested_functions	- bool(no),
-		highlevel_data		- bool(no)]).
+		highlevel_data		- bool(no),
+		target			- string("c")]).
 grade_component_table("fast", gcc_ext, [
 		asm_labels		- bool(no),
 		gcc_non_local_gotos	- bool(yes),
 		gcc_global_registers	- bool(yes),
 		highlevel_code		- bool(no),
 		gcc_nested_functions	- bool(no),
-		highlevel_data		- bool(no)]).
+		highlevel_data		- bool(no),
+		target			- string("c")]).
 grade_component_table("asm_fast", gcc_ext, [
 		asm_labels		- bool(yes),
 		gcc_non_local_gotos	- bool(yes),
 		gcc_global_registers	- bool(yes),
 		highlevel_code		- bool(no),
 		gcc_nested_functions	- bool(no),
-		highlevel_data		- bool(no)]).
+		highlevel_data		- bool(no),
+		target			- string("c")]).
 grade_component_table("hl", gcc_ext, [
 		asm_labels		- bool(no),
 		gcc_non_local_gotos	- bool(no),
 		gcc_global_registers	- bool(no),
 		highlevel_code		- bool(yes),
 		gcc_nested_functions	- bool(no),
-		highlevel_data		- bool(yes)]).
+		highlevel_data		- bool(yes),
+		target			- string("c")]).
 grade_component_table("hlc", gcc_ext, [
 		asm_labels		- bool(no),
 		gcc_non_local_gotos	- bool(no),
 		gcc_global_registers	- bool(no),
 		highlevel_code		- bool(yes),
 		gcc_nested_functions	- bool(no),
-		highlevel_data		- bool(no)]).
+		highlevel_data		- bool(no),
+		target			- string("c")]).
 grade_component_table("hl_nest", gcc_ext, [
 		asm_labels		- bool(no),
 		gcc_non_local_gotos	- bool(no),
 		gcc_global_registers	- bool(no),
 		highlevel_code		- bool(yes),
 		gcc_nested_functions	- bool(yes),
-		highlevel_data		- bool(yes)]).
+		highlevel_data		- bool(yes),
+		target			- string("c")]).
 grade_component_table("hlc_nest", gcc_ext, [
 		asm_labels		- bool(no),
 		gcc_non_local_gotos	- bool(no),
 		gcc_global_registers	- bool(no),
 		highlevel_code		- bool(yes),
 		gcc_nested_functions	- bool(yes),
-		highlevel_data		- bool(no)]).
+		highlevel_data		- bool(no),
+		target			- string("c")]).
+grade_component_table("il", gcc_ext, [
+		asm_labels		- bool(no),
+		gcc_non_local_gotos	- bool(no),
+		gcc_global_registers	- bool(no),
+		highlevel_code		- bool(yes),
+		gcc_nested_functions	- bool(no),
+		highlevel_data		- bool(yes),
+		target			- string("il")]).
+grade_component_table("ilc", gcc_ext, [
+		asm_labels		- bool(no),
+		gcc_non_local_gotos	- bool(no),
+		gcc_global_registers	- bool(no),
+		highlevel_code		- bool(yes),
+		gcc_nested_functions	- bool(no),
+		highlevel_data		- bool(no),
+		target			- string("il")]).
 
 	% Parallelism/multithreading components.
 grade_component_table("par", par, [parallel - bool(yes)]).
Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mercury_compile.m,v
retrieving revision 1.172
diff -u -r1.172 mercury_compile.m
--- compiler/mercury_compile.m	2000/08/31 03:00:18	1.172
+++ compiler/mercury_compile.m	2000/09/04 05:00:59
@@ -67,6 +67,7 @@
 :- import_module ml_optimize.			% MLDS -> MLDS
 :- import_module mlds_to_c.			% MLDS -> C
 
+
 	% miscellaneous compiler modules
 :- import_module prog_data, hlds_module, hlds_pred, hlds_out, llds, rl.
 :- import_module mercury_to_mercury, mercury_to_goedel.
@@ -439,6 +440,8 @@
 		mercury_compile__middle_pass(ModuleName, HLDS25, HLDS50),
 		globals__io_lookup_bool_option(highlevel_code, HighLevelCode),
 		globals__io_lookup_bool_option(aditi_only, AditiOnly),
+		globals__io_lookup_bool_option(target_code_only, 
+				TargetCodeOnly),
 
 		% magic sets can report errors.
 		{ module_info_num_errors(HLDS50, NumErrors) },
@@ -450,9 +453,9 @@
 		    ; { HighLevelCode = yes } ->
 			mercury_compile__mlds_backend(HLDS50, MLDS),
 			mercury_compile__mlds_to_high_level_c(MLDS),
-			globals__io_lookup_bool_option(compile_to_c, 
-				CompileToC),
-			( { CompileToC = no } ->
+			( { TargetCodeOnly = yes } ->
+				[]
+			;
 				module_name_to_file_name(ModuleName, ".c", no,
 					C_File),
 				object_extension(Obj),
@@ -460,8 +463,6 @@
 					O_File),
 				mercury_compile__single_c_to_obj(
 					C_File, O_File, _CompileOK)
-			;
-			    []
 			)
 		    ;
 			mercury_compile__backend_pass(HLDS50, HLDS70,
@@ -477,6 +478,21 @@
 	    []
 	).
 
+	% return `yes' iff this module defines the main/2 entry point.
+:- func mercury_compile__mlds_has_main(mlds) = bool.
+mercury_compile__mlds_has_main(MLDS) =
+	(
+		MLDS = mlds(_, _, _, Defns),
+		list__member(Defn, Defns),
+		Defn = mlds__defn(Name, _, _, _),
+		Name = function(FuncName, _, _, _), 
+		FuncName = pred(predicate, _, "main", 2)
+	->
+		yes
+	;
+		no
+	).
+
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
@@ -2195,8 +2211,8 @@
 	%
 	% Finally we invoke the C compiler to compile it.
 	%
-	globals__io_lookup_bool_option(compile_to_c, CompileToC),
-	( { CompileToC = no } ->
+	globals__io_lookup_bool_option(target_code_only, TargetCodeOnly),
+	( { TargetCodeOnly = no } ->
 		mercury_compile__c_to_obj(ModuleName, NumChunks, CompileOK),
 		{ bool__not(CompileOK, CompileErrors) }
 	;
@@ -2390,6 +2406,7 @@
 
 	{ MLDS = MLDS40 },
 	mercury_compile__maybe_dump_mlds(MLDS, "99", "final").
+
 
 :- pred mercury_compile__mlds_gen_rtti_data(module_info, mlds, mlds).
 :- mode mercury_compile__mlds_gen_rtti_data(in, in, out) is det.
Index: compiler/ml_call_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_call_gen.m,v
retrieving revision 1.14
diff -u -r1.14 ml_call_gen.m
--- compiler/ml_call_gen.m	2000/06/05 02:47:07	1.14
+++ compiler/ml_call_gen.m	2000/09/04 00:41:56
@@ -83,6 +83,12 @@
 :- mode ml_gen_box_or_unbox_lval(in, in, in, in, in, out, out, out, out,
 		in, out) is det.
 
+	% XXX document this
+:- pred ml_gen_cont_params(list(mlds__type), mlds__func_params,
+		ml_gen_info, ml_gen_info).
+:- mode ml_gen_cont_params(in, out, in, out) is det.
+
+
 %-----------------------------------------------------------------------------%
 
 :- implementation.
@@ -90,6 +96,7 @@
 :- import_module hlds_module.
 :- import_module builtin_ops.
 :- import_module type_util, mode_util.
+:- import_module options, globals.
 
 :- import_module bool, int, string, std_util, term, varset, require, map.
 
@@ -130,7 +137,7 @@
 	%
 	% insert the `closure_arg' parameter
 	%
-	{ ClosureArgType = mlds__generic_env_ptr_type },
+	{ ClosureArgType = mlds__generic_type },
 	{ ClosureArg = data(var("closure_arg")) - ClosureArgType },
 	{ Params0 = mlds__func_params(ArgParams0, RetParam) },
 	{ Params = mlds__func_params([ClosureArg | ArgParams0], RetParam) },
@@ -190,8 +197,9 @@
 	ml_gen_var_list(ArgVars, ArgLvals),
 	ml_variable_types(ArgVars, ActualArgTypes),
 	ml_gen_arg_list(ArgNames, ArgLvals, ActualArgTypes, BoxedArgTypes,
-		ArgModes, Context, InputRvals, OutputLvals, ConvArgDecls,
-		ConvOutputStatements),
+		ArgModes, CodeModel, Context,
+		InputRvals, OutputLvals, OutputTypes,
+		ConvArgDecls, ConvOutputStatements),
 	{ ClosureRval = unop(unbox(ClosureArgType), lval(ClosureLval)) },
 
 	%
@@ -204,7 +212,7 @@
 	%
 	{ ObjectRval = no },
 	{ DoGenCall = ml_gen_mlds_call(Signature, ObjectRval, FuncRval,
-		[ClosureRval | InputRvals], OutputLvals,
+		[ClosureRval | InputRvals], OutputLvals, OutputTypes,
 		CodeModel, Context) },
 
 	( { ConvArgDecls = [], ConvOutputStatements = [] } ->
@@ -300,8 +308,9 @@
 	% to pass as the function call's arguments and return values
 	%
 	ml_gen_arg_list(ArgNames, ArgLvals, ActualArgTypes, PredArgTypes,
-		ArgModes, Context, InputRvals, OutputLvals, ConvArgDecls,
-		ConvOutputStatements),
+		ArgModes, CodeModel, Context,
+		InputRvals, OutputLvals, OutputTypes,
+		ConvArgDecls, ConvOutputStatements),
 
 	%
 	% Construct a closure to generate the call
@@ -312,7 +321,7 @@
 	%
 	{ ObjectRval = no },
 	{ DoGenCall = ml_gen_mlds_call(Signature, ObjectRval, FuncRval,
-		InputRvals, OutputLvals, CodeModel, Context) },
+		InputRvals, OutputLvals, OutputTypes, CodeModel, Context) },
 
 	( { ConvArgDecls = [], ConvOutputStatements = [] } ->
 		DoGenCall(MLDS_Decls, MLDS_Statements)
@@ -346,42 +355,58 @@
 
 	%
 	% This generates a call in the specified code model.
-	% This is a lower-level routine called by both ml_gen_call_parts
+	% This is a lower-level routine called by both ml_gen_call
 	% and ml_gen_generic_call.
 	%
 :- pred ml_gen_mlds_call(mlds__func_signature, maybe(mlds__rval), mlds__rval,
-		list(mlds__rval), list(mlds__lval), code_model, prog_context,
-		mlds__defns, mlds__statements, ml_gen_info, ml_gen_info).
-:- mode ml_gen_mlds_call(in, in, in, in, in, in, in, out, out, in, out) is det.
+		list(mlds__rval), list(mlds__lval), list(mlds__type),
+		code_model, prog_context, mlds__defns, mlds__statements,
+		ml_gen_info, ml_gen_info).
+:- mode ml_gen_mlds_call(in, in, in, in, in, in, in, in, out, out, in, out)
+		is det.
 
 ml_gen_mlds_call(Signature, ObjectRval, FuncRval, ArgRvals0, RetLvals0,
-		CodeModel, Context, MLDS_Decls, MLDS_Statements) -->
+		RetTypes0, CodeModel, Context, MLDS_Decls, MLDS_Statements) -->
 	%
-	% append the extra argument or return val for this code_model
+	% append the extra arguments or return val for this code_model
 	%
 	(
 		{ CodeModel = model_non },
-		% pass the current success continuation
-		ml_gen_info_current_success_cont(Cont),
-		{ Cont = success_cont(FuncPtrRval, EnvPtrRval) },
+		% create a new success continuation, if necessary
+		ml_gen_success_cont(RetTypes0, RetLvals0, Context,
+			Cont, ContDecls),
+		% append the success continuation to the ordinary arguments
+		{ Cont = success_cont(FuncPtrRval, EnvPtrRval, _, _) },
 		ml_gen_info_use_gcc_nested_functions(UseNestedFuncs),
 		( { UseNestedFuncs = yes } ->
 			{ ArgRvals = list__append(ArgRvals0, [FuncPtrRval]) }
 		;
 			{ ArgRvals = list__append(ArgRvals0,
 				[FuncPtrRval, EnvPtrRval]) }
+		),
+		% for --nondet-copy-out, the output arguments will be
+		% passed to the continuation rather than being returned
+		ml_gen_info_get_globals(Globals),
+		{ globals__lookup_bool_option(Globals, nondet_copy_out,
+			NondetCopyOut) },
+		( { NondetCopyOut = yes } ->
+			{ RetLvals = [] }
+		;
+			{ RetLvals = RetLvals0 }
 		),
-		{ RetLvals = RetLvals0 }
+		{ MLDS_Decls = ContDecls }
 	;
 		{ CodeModel = model_semi },
 		% return a bool indicating whether or not it succeeded
 		ml_success_lval(Success),
 		{ ArgRvals = ArgRvals0 },
-		{ RetLvals = list__append([Success], RetLvals0) }
+		{ RetLvals = list__append([Success], RetLvals0) },
+		{ MLDS_Decls = [] }
 	;
 		{ CodeModel = model_det },
 		{ ArgRvals = ArgRvals0 },
-		{ RetLvals = RetLvals0 }
+		{ RetLvals = RetLvals0 },
+		{ MLDS_Decls = [] }
 	),
 
 	%
@@ -392,9 +417,103 @@
 			CallOrTailcall) },
 	{ MLDS_Statement = mlds__statement(MLDS_Stmt,
 			mlds__make_context(Context)) },
-	{ MLDS_Statements = [MLDS_Statement] },
-	{ MLDS_Decls = [] }.
+	{ MLDS_Statements = [MLDS_Statement] }.
 
+:- pred ml_gen_success_cont(list(mlds__type), list(mlds__lval), prog_context,
+		success_cont, mlds__defns, ml_gen_info, ml_gen_info).
+:- mode ml_gen_success_cont(in, in, in, out, out, in, out) is det.
+
+ml_gen_success_cont(OutputArgTypes, OutputArgLvals, Context,
+		Cont, ContDecls) -->
+	ml_gen_info_current_success_cont(CurrentCont),
+	{ CurrentCont = success_cont(_FuncPtrRval, _EnvPtrRval,
+		CurrentContArgTypes, CurrentContArgLvals) },
+	(
+		%
+		% As an optimization, check if the parameters expected by
+		% the current continuation are the same as the ones
+		% expected by the new continuation that we're generating;
+		% if so, we can just use the current continuation rather
+		% than creating a new one.
+		%
+		{ CurrentContArgTypes = OutputArgTypes },
+		{ CurrentContArgLvals = OutputArgLvals }
+	->
+		{ Cont = CurrentCont },
+		{ ContDecls = [] }
+	;
+		% 
+		% Create a new continuation function
+		% that just copies the outputs to locals
+		% and then calls the original current continuation
+		%
+		ml_gen_cont_params(OutputArgTypes, Params),
+		ml_gen_new_func_label(yes(Params),
+			ContFuncLabel, ContFuncLabelRval),
+		/* push nesting level */
+		ml_gen_copy_args_to_locals(OutputArgLvals, Context,
+			CopyDecls, CopyStatements),
+		ml_gen_call_current_success_cont(Context, CallCont),
+		{ CopyStatement = ml_gen_block(CopyDecls,
+			list__append(CopyStatements, [CallCont]), Context) },
+		/* pop nesting level */
+		ml_gen_label_func(ContFuncLabel, Params, Context,
+			CopyStatement, ContFuncDefn),
+		{ ContDecls = [ContFuncDefn] },
+
+		ml_get_env_ptr(EnvPtrRval),
+		{ NewSuccessCont = success_cont(ContFuncLabelRval,
+			EnvPtrRval, OutputArgTypes, OutputArgLvals) },
+		ml_gen_info_push_success_cont(NewSuccessCont),
+		{ Cont = NewSuccessCont }
+	).
+
+ml_gen_cont_params(OutputArgTypes, Params) -->
+	ml_gen_cont_params_2(OutputArgTypes, 1, Args0),
+	ml_gen_info_use_gcc_nested_functions(UseNestedFuncs),
+	( { UseNestedFuncs = yes } ->
+		{ Args = Args0 }
+	;
+		ml_declare_env_ptr_arg(EnvPtrArg),
+		{ Args = list__append(Args0, [EnvPtrArg]) }
+	),
+	{ Params = mlds__func_params(Args, []) }.
+
+:- pred ml_gen_cont_params_2(list(mlds__type), int, mlds__arguments,
+		ml_gen_info, ml_gen_info).
+:- mode ml_gen_cont_params_2(in, in, out, in, out) is det.
+
+ml_gen_cont_params_2([], _, []) --> [].
+ml_gen_cont_params_2([Type | Types], ArgNum, [Argument | Arguments]) -->
+	{ ArgName = ml_gen_arg_name(ArgNum) },
+	{ Argument = data(var(ArgName)) - Type },
+	ml_gen_cont_params_2(Types, ArgNum + 1, Arguments).
+
+:- pred ml_gen_copy_args_to_locals(list(mlds__lval), prog_context,
+		mlds__defns, mlds__statements, ml_gen_info, ml_gen_info).
+:- mode ml_gen_copy_args_to_locals(in, in, out, out, in, out) is det.
+
+ml_gen_copy_args_to_locals(ArgLvals, Context, CopyDecls, CopyStatements) -->
+	{ CopyDecls = [] },
+	ml_gen_copy_args_to_locals_2(ArgLvals, 1, Context, CopyStatements).
+
+:- pred ml_gen_copy_args_to_locals_2(list(mlds__lval), int, prog_context,
+		mlds__statements, ml_gen_info, ml_gen_info).
+:- mode ml_gen_copy_args_to_locals_2(in, in, in, out, in, out) is det.
+
+ml_gen_copy_args_to_locals_2([], _, _, []) --> [].
+ml_gen_copy_args_to_locals_2([LocalLval | LocalLvals], ArgNum, Context,
+		[Statement | Statements]) -->
+	{ ArgName = ml_gen_arg_name(ArgNum) },
+	ml_qualify_var(ArgName, ArgLval),
+	{ Statement = ml_gen_assign(LocalLval, lval(ArgLval), Context) },
+	ml_gen_copy_args_to_locals_2(LocalLvals, ArgNum + 1, Context,
+		Statements).
+
+:- func ml_gen_arg_name(int) = string.
+ml_gen_arg_name(ArgNum) = ArgName :-
+	string__format("arg%d", [i(ArgNum)], ArgName).
+
 %
 % Generate an rval containing the address of the specified procedure
 %
@@ -413,14 +532,15 @@
 % Generate rvals and lvals for the arguments of a procedure call
 %
 :- pred ml_gen_arg_list(list(var_name), list(mlds__lval), list(prog_type),
-		list(prog_type), list(mode), prog_context, list(mlds__rval),
-		list(mlds__lval), mlds__defns, mlds__statements,
-		ml_gen_info, ml_gen_info).
-:- mode ml_gen_arg_list(in, in, in, in, in, in, out, out, out, out,
+		list(prog_type), list(mode), code_model, prog_context,
+		list(mlds__rval), list(mlds__lval), list(mlds__type),
+		mlds__defns, mlds__statements, ml_gen_info, ml_gen_info).
+:- mode ml_gen_arg_list(in, in, in, in, in, in, in, out, out, out, out, out,
 		in, out) is det.
 
-ml_gen_arg_list(VarNames, VarLvals, CallerTypes, CalleeTypes, Modes, Context,
-		InputRvals, OutputLvals, ConvDecls, ConvOutputStatements) -->
+ml_gen_arg_list(VarNames, VarLvals, CallerTypes, CalleeTypes, Modes, CodeModel,
+		Context, InputRvals, OutputLvals, OutputTypes,
+		ConvDecls, ConvOutputStatements) -->
 	(
 		{ VarNames = [] },
 		{ VarLvals = [] },
@@ -430,6 +550,7 @@
 	->
 		{ InputRvals = [] },
 		{ OutputLvals = [] },
+		{ OutputTypes = [] },
 		{ ConvDecls = [] },
 		{ ConvOutputStatements = [] }
 	;
@@ -440,17 +561,20 @@
 		{ Modes = [Mode | Modes1] }
 	->
 		ml_gen_arg_list(VarNames1, VarLvals1,
-			CallerTypes1, CalleeTypes1, Modes1, Context,
-			InputRvals1, OutputLvals1,
+			CallerTypes1, CalleeTypes1, Modes1, CodeModel, Context,
+			InputRvals1, OutputLvals1, OutputTypes1,
 			ConvDecls1, ConvOutputStatements1),
 		=(MLDSGenInfo),
 		{ ml_gen_info_get_module_info(MLDSGenInfo, ModuleInfo) },
-		( { type_util__is_dummy_argument_type(CalleeType) } ->
+		(
+			{ type_util__is_dummy_argument_type(CalleeType) }
+		->
 			%
 			% exclude arguments of type io__state etc.
 			%
 			{ InputRvals = InputRvals1 },
 			{ OutputLvals = OutputLvals1 },
+			{ OutputTypes = OutputTypes1 },
 			{ ConvDecls = ConvDecls1 },
 			{ ConvOutputStatements = ConvOutputStatements1 }
 		; { mode_to_arg_mode(ModuleInfo, Mode, CalleeType, top_in) } ->
@@ -472,6 +596,7 @@
 				VarRval, ArgRval),
 			{ InputRvals = [ArgRval | InputRvals1] },
 			{ OutputLvals = OutputLvals1 },
+			{ OutputTypes = OutputTypes1 },
 			{ ConvDecls = ConvDecls1 },
 			{ ConvOutputStatements = ConvOutputStatements1 }
 		;
@@ -486,25 +611,28 @@
 				ConvDecls1) },
 			{ ConvOutputStatements = list__append(
 				ThisArgConvOutput, ConvOutputStatements1) },
+			ml_gen_info_get_globals(Globals),
+			{ CopyOut = get_copy_out_option(Globals, CodeModel) },
 			(
-		/************
 				%
 				% if the target language allows multiple
 				% return values, then use them
 				%
-				{ UseMultipleOutputs = yes }
+				{ CopyOut = yes }
 			->
-				{ InputRvals = InputLvals1 },
+				{ InputRvals = InputRvals1 },
 				{ OutputLvals = [ArgLval | OutputLvals1] },
+				ml_gen_type(CalleeType, OutputType),
+				{ OutputTypes = [OutputType | OutputTypes1] }
 			;
-		************/
 				%
 				% otherwise use the traditional C style
 				% of passing the address of the output value
 				%
 				{ InputRvals = [ml_gen_mem_addr(ArgLval)
 					| InputRvals1] },
-				{ OutputLvals = OutputLvals1 }
+				{ OutputLvals = OutputLvals1 },
+				{ OutputTypes = OutputTypes1 }
 			)
 		)
 	;
Index: compiler/ml_code_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_code_gen.m,v
retrieving revision 1.58
diff -u -r1.58 ml_code_gen.m
--- compiler/ml_code_gen.m	2000/08/24 10:01:48	1.58
+++ compiler/ml_code_gen.m	2000/09/04 00:41:57
@@ -943,25 +943,36 @@
 
 	MLDSGenInfo0 = ml_gen_info_init(ModuleInfo, PredId, ProcId),
 	MLDS_Params = ml_gen_proc_params(ModuleInfo, PredId, ProcId),
+
 	( CodeModel = model_non ->
 		% set up the initial success continuation
-		ml_initial_cont(InitialCont, MLDSGenInfo0, MLDSGenInfo1),
-		ml_gen_info_push_success_cont(InitialCont,
-			MLDSGenInfo1, MLDSGenInfo2)
+		ml_set_up_initial_succ_cont(ModuleInfo, NondetCopiedOutputVars,
+			MLDSGenInfo0, MLDSGenInfo2)
 	;
+		NondetCopiedOutputVars = [],
 		MLDSGenInfo2 = MLDSGenInfo0
 	),
 
 	% This would generate all the local variables at the top of the
 	% function:
-	%	proc_info_varset(ProcInfo, VarSet),
-	%	proc_info_vartypes(ProcInfo, VarTypes),
 	%	MLDS_LocalVars = ml_gen_all_local_var_decls(Goal, VarSet,
 	% 		VarTypes, HeadVars, ModuleInfo),
 	% But instead we now generate them locally for each goal.
-	% We just declare the `succeeded' var here.
+	% We just declare the `succeeded' var here,
+	% plus, if --nondet-copy-out is enabled,
+	% locals for the output arguments.
 	MLDS_Context = mlds__make_context(Context),
-	MLDS_LocalVars = [ml_gen_succeeded_var_decl(MLDS_Context)],
+	( NondetCopiedOutputVars = [] ->
+		% optimize common case
+		OutputVarLocals = []
+	;
+		proc_info_varset(ProcInfo, VarSet),
+		proc_info_vartypes(ProcInfo, VarTypes),
+		OutputVarLocals = ml_gen_local_var_decls(VarSet, VarTypes,
+			MLDS_Context, ModuleInfo, NondetCopiedOutputVars)
+	),
+	MLDS_LocalVars = [ml_gen_succeeded_var_decl(MLDS_Context) |
+			OutputVarLocals],
 	ml_gen_proc_body(CodeModel, HeadVars, ArgTypes, Goal,
 			MLDS_Decls0, MLDS_Statements,
 			MLDSGenInfo2, MLDSGenInfo),
@@ -971,6 +982,30 @@
 	MLDS_ProcDefnBody = mlds__function(yes(proc(PredId, ProcId)),
 			MLDS_Params, yes(MLDS_Statement)).
 
+:- pred ml_set_up_initial_succ_cont(module_info, list(prog_var),
+		ml_gen_info, ml_gen_info).
+:- mode ml_set_up_initial_succ_cont(in, out, in, out) is det.
+
+ml_set_up_initial_succ_cont(ModuleInfo, NondetCopiedOutputVars) -->
+	{ module_info_globals(ModuleInfo, Globals) },
+	{ globals__lookup_bool_option(Globals, nondet_copy_out,
+		NondetCopyOut) },
+	( { NondetCopyOut = yes } ->
+		% for --nondet-copy-out, we generate local variables
+		% for the output variables and then pass them to the
+		% continuation, rather than passing them by reference.
+		=(MLDSGenInfo0),
+		{ ml_gen_info_get_output_vars(MLDSGenInfo0,
+			NondetCopiedOutputVars) },
+		ml_gen_info_set_output_vars([])
+	;
+		{ NondetCopiedOutputVars = [] }
+	),
+	ml_gen_var_list(NondetCopiedOutputVars, OutputVarLvals),
+	ml_variable_types(NondetCopiedOutputVars, OutputVarTypes),
+	ml_initial_cont(OutputVarLvals, OutputVarTypes, InitialCont),
+	ml_gen_info_push_success_cont(InitialCont).
+
 	% Generate MLDS definitions for all the local variables in a function.
 	%
 	% Note that this function generates all the local variables at the
@@ -1360,15 +1395,26 @@
 		%			succeeded = TRUE;
 		%			MR_DO_COMMIT(ref);
 		%		}
+		%	#ifdef NONDET_COPY_OUT
+		%		<local var decls>
+		%	#endif
 		%		MR_TRY_COMMIT(ref, {
 		%			<Goal && success()>
 		%			succeeded = FALSE;
 		%		}, {
+		%	#ifdef NONDET_COPY_OUT
+		%			<copy local vars to output args>
+		%	#endif
 		%			succeeded = TRUE;
 		%		})
 
+		ml_gen_maybe_make_locals_for_output_args(GoalInfo,
+			LocalVarDecls, CopyLocalsToOutputArgs,
+			OrigVarLvalMap),
+
 		% generate the `success()' function
-		ml_gen_new_func_label(SuccessFuncLabel, SuccessFuncLabelRval),
+		ml_gen_new_func_label(no, SuccessFuncLabel, 
+			SuccessFuncLabelRval),
 		/* push nesting level */
 		{ MLDS_Context = mlds__make_context(Context) },
 		ml_gen_info_new_commit_label(CommitLabelNum),
@@ -1386,7 +1432,7 @@
 
 		ml_get_env_ptr(EnvPtrRval),
 		{ SuccessCont = success_cont(SuccessFuncLabelRval,
-			EnvPtrRval) },
+			EnvPtrRval, [], []) },
 		ml_gen_info_push_success_cont(SuccessCont),
 		ml_gen_goal(model_non, Goal, GoalStatement),
 		ml_gen_info_pop_success_cont,
@@ -1395,12 +1441,15 @@
 		{ TryCommitStmt = try_commit(CommitRefLval,
 			ml_gen_block([], [GoalStatement, SetSuccessFalse],
 				Context),
-			SetSuccessTrue) },
+			ml_gen_block([], list__append(CopyLocalsToOutputArgs,
+				[SetSuccessTrue]), Context)) },
 		{ TryCommitStatement = mlds__statement(TryCommitStmt,
 			MLDS_Context) },
+
+		{ MLDS_Decls = [CommitRefDecl, SuccessFunc | LocalVarDecls] },
+		{ MLDS_Statements = [TryCommitStatement] },
 
-		{ MLDS_Decls = [CommitRefDecl, SuccessFunc] },
-		{ MLDS_Statements = [TryCommitStatement] }
+		ml_gen_info_set_var_lvals(OrigVarLvalMap)
 
 	; { GoalCodeModel = model_non, CodeModel = model_det } ->
 
@@ -1411,12 +1460,23 @@
 		%		void success() {
 		%			MR_DO_COMMIT(ref);
 		%		}
+		%	#ifdef NONDET_COPY_OUT
+		%		<local var decls>
+		%	#endif
 		%		MR_TRY_COMMIT(ref, {
+		%	#ifdef NONDET_COPY_OUT
+		%			<copy local vars to output args>
+		%	#endif
 		%			<Goal && success()>
 		%		}, {})
 
+		ml_gen_maybe_make_locals_for_output_args(GoalInfo,
+			LocalVarDecls, CopyLocalsToOutputArgs,
+			OrigVarLvalMap),
+
 		% generate the `success()' function
-		ml_gen_new_func_label(SuccessFuncLabel, SuccessFuncLabelRval),
+		ml_gen_new_func_label(no,
+			SuccessFuncLabel, SuccessFuncLabelRval),
 		/* push nesting level */
 		{ MLDS_Context = mlds__make_context(Context) },
 		ml_gen_info_new_commit_label(CommitLabelNum),
@@ -1434,23 +1494,117 @@
 
 		ml_get_env_ptr(EnvPtrRval),
 		{ SuccessCont = success_cont(SuccessFuncLabelRval,
-			EnvPtrRval) },
+			EnvPtrRval, [], []) },
 		ml_gen_info_push_success_cont(SuccessCont),
 		ml_gen_goal(model_non, Goal, GoalStatement),
 		ml_gen_info_pop_success_cont,
 
 		{ TryCommitStmt = try_commit(CommitRefLval, GoalStatement,
-			ml_gen_block([], [], Context)) },
+			ml_gen_block([], CopyLocalsToOutputArgs, Context)) },
 		{ TryCommitStatement = mlds__statement(TryCommitStmt,
 			MLDS_Context) },
 
-		{ MLDS_Decls = [CommitRefDecl, SuccessFunc] },
-		{ MLDS_Statements = [TryCommitStatement] }
+		{ MLDS_Decls = [CommitRefDecl, SuccessFunc | LocalVarDecls] },
+		{ MLDS_Statements = [TryCommitStatement] },
+
+		ml_gen_info_set_var_lvals(OrigVarLvalMap)
 	;
 		% no commit required
 		ml_gen_goal(CodeModel, Goal, MLDS_Decls, MLDS_Statements)
 	).
 
+	%
+	% In commits, you have model_non code called from a model_det or
+	% model_semi context.  With --nondet-copy-out, when generating code
+	% for commits, if the context is a model_det or model_semi procedure
+	% with output arguments passed by reference, then we need to introduce
+	% local variables corresponding to those output arguments,
+	% and at the end of the commit we'll copy the local variables into
+	% the output arguments.
+	%
+:- pred ml_gen_maybe_make_locals_for_output_args(hlds_goal_info, mlds__defns,
+		mlds__statements, map(prog_var, mlds__lval),
+		ml_gen_info, ml_gen_info).
+:- mode ml_gen_maybe_make_locals_for_output_args(in, out, out, out, in, out)
+		is det.
+
+ml_gen_maybe_make_locals_for_output_args(GoalInfo,
+		LocalVarDecls, CopyLocalsToOutputArgs, OrigVarLvalMap) -->
+	=(MLDSGenInfo0),
+	{ ml_gen_info_get_var_lvals(MLDSGenInfo0, OrigVarLvalMap) },
+	ml_gen_info_get_globals(Globals),
+	{ globals__lookup_bool_option(Globals, nondet_copy_out,
+		NondetCopyOut) },
+	( { NondetCopyOut = yes } ->
+		{ goal_info_get_context(GoalInfo, Context) },
+		{ goal_info_get_nonlocals(GoalInfo, NonLocals) },
+		{ ml_gen_info_get_output_vars(MLDSGenInfo0, OutputVars) },
+		{ VarsToCopy = set__intersect(set__list_to_set(OutputVars),
+			NonLocals) },
+		ml_gen_make_locals_for_output_args(
+			set__to_sorted_list(VarsToCopy), Context,
+			LocalVarDecls, CopyLocalsToOutputArgs)
+	;
+		{ LocalVarDecls = [] },
+		{ CopyLocalsToOutputArgs = [] }
+	).
+
+:- pred ml_gen_make_locals_for_output_args(list(prog_var), prog_context,
+		mlds__defns, mlds__statements, ml_gen_info, ml_gen_info).
+:- mode ml_gen_make_locals_for_output_args(in, in, out, out, in, out) is det.
+
+ml_gen_make_locals_for_output_args([], _, [], []) --> [].
+ml_gen_make_locals_for_output_args([Var | Vars], Context,
+		LocalDefns, Assigns) -->
+	ml_gen_make_locals_for_output_args(Vars, Context,
+		LocalDefns0, Assigns0),
+	ml_variable_type(Var, Type),
+	( { type_util__is_dummy_argument_type(Type) } ->
+		{ LocalDefns = LocalDefns0 },
+		{ Assigns = Assigns0 }
+	;
+		ml_gen_make_local_for_output_arg(Var, Type, Context,
+			LocalDefn, Assign),
+		{ LocalDefns = [LocalDefn | LocalDefns0] },
+		{ Assigns = [Assign | Assigns0] }
+	).
+
+:- pred ml_gen_make_local_for_output_arg(prog_var, prog_type, prog_context,
+		mlds__defn, mlds__statement, ml_gen_info, ml_gen_info).
+:- mode ml_gen_make_local_for_output_arg(in, in, in, out, out, in, out) is det.
+
+ml_gen_make_local_for_output_arg(OutputVar, Type, Context,
+		LocalVarDefn, Assign) -->
+	%
+	% Look up the name of the output variable
+	%
+	=(MLDSGenInfo),
+	{ ml_gen_info_get_varset(MLDSGenInfo, VarSet) },
+	{ ml_gen_info_get_module_info(MLDSGenInfo, ModuleInfo) },
+	{ OutputVarName = ml_gen_var_name(VarSet, OutputVar) },
+
+	%
+	% Generate a declaration for a corresponding local variable.
+	%
+	{ string__append("local_", OutputVarName, LocalVarName) },
+	{ LocalVarDefn = ml_gen_var_decl(LocalVarName, Type,
+		mlds__make_context(Context), ModuleInfo) },
+
+	%
+	% Generate code to assign from the local var to the output var
+	%
+	ml_gen_var(OutputVar, OutputVarLval),
+	ml_qualify_var(LocalVarName, LocalVarLval),
+	{ Assign = ml_gen_assign(OutputVarLval, lval(LocalVarLval), Context) },
+
+	%
+	% Update the lval for this variable so that any references to it
+	% inside the commit refer to the local variable rather than
+	% to the output argument.
+	% (Note that we reset all the var lvals at the end of the commit.)
+	%
+	ml_gen_info_set_var_lval(OutputVar, LocalVarLval).
+
 	% Generate the declaration for the `commit' variable.
 	%
 :- func ml_gen_commit_var_decl(mlds__context, mlds__var_name) = mlds__defn.
@@ -1717,8 +1871,19 @@
 			raw_target_code("\t\tif (MR_succeeded) {\n")],
 			AssignOutputsList
 	]) },
+	=(MLDSGenInfo),
+	{ ml_gen_info_get_module_info(MLDSGenInfo, ModuleInfo) },
+	{ module_info_globals(ModuleInfo, Globals) },
+	{ globals__lookup_string_option(Globals, target, Target) },
 	( { CodeModel = model_non } ->
-		ml_gen_call_current_success_cont(Context, CallCont)
+		(
+			{ Target = "il" }
+		->
+			ml_gen_call_current_success_cont_indirectly(Context,
+				CallCont)
+		;
+			ml_gen_call_current_success_cont(Context, CallCont)
+		)
 	;
 		{ error("ml_gen_nondet_pragma_c_code: unexpected code model") }
 	),
@@ -2391,7 +2556,7 @@
 		{ CondVarDecl = ml_gen_cond_var_decl(CondVar, MLDS_Context) },
 
 		% generate the `then_func'
-		ml_gen_new_func_label(ThenFuncLabel, ThenFuncLabelRval),
+		ml_gen_new_func_label(no, ThenFuncLabel, ThenFuncLabelRval),
 		/* push nesting level */
 		{ Then = _ - ThenGoalInfo },
 		{ goal_info_get_context(ThenGoalInfo, ThenContext) },
@@ -2408,7 +2573,8 @@
 		ml_gen_set_cond_var(CondVar, const(false), Context,
 			SetCondFalse),
 		ml_get_env_ptr(EnvPtrRval),
-		{ SuccessCont = success_cont(ThenFuncLabelRval, EnvPtrRval) },
+		{ SuccessCont = success_cont(ThenFuncLabelRval, EnvPtrRval,
+			[], []) },
 		ml_gen_info_push_success_cont(SuccessCont),
 		ml_gen_goal(model_non, Cond, CondDecls, CondStatements),
 		ml_gen_info_pop_success_cont,
Index: compiler/ml_code_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_code_util.m,v
retrieving revision 1.19
diff -u -r1.19 ml_code_util.m
--- compiler/ml_code_util.m	2000/08/24 10:01:49	1.19
+++ compiler/ml_code_util.m	2000/09/04 00:41:57
@@ -20,6 +20,7 @@
 :- import_module rtti.
 :- import_module mlds.
 :- import_module llds. % XXX for `code_model'.
+:- import_module globals.
 
 :- import_module bool, int, list, map, std_util.
 
@@ -120,6 +121,13 @@
 :- func ml_gen_params(module_info, list(string), list(prog_type),
 		list(mode), code_model) = mlds__func_params.
 
+	% Given a list of variables and their corresponding modes,
+	% return a list containing only those variables which have
+	% an output mode.
+	%
+:- func select_output_vars(module_info, list(Var), list(mode),
+		map(Var, prog_type)) = list(Var).
+
 %-----------------------------------------------------------------------------%
 %
 % Routines for generating labels and entity names.
@@ -141,11 +149,14 @@
 		= mlds__entity_name.
 
 	% Allocate a new function label and return an rval containing
-	% the function's address.
-	%
-:- pred ml_gen_new_func_label(ml_label_func, mlds__rval,
-		ml_gen_info, ml_gen_info).
-:- mode ml_gen_new_func_label(out, out, in, out) is det.
+	% the function's address.  If parameters are not given, we
+	% assume it's a continuation function, and give it the
+	% appropriate arguments (depending on whether we are doing
+	% nested functions or not).
+	%
+:- pred ml_gen_new_func_label(maybe(mlds__func_params), ml_label_func,
+	mlds__rval, ml_gen_info, ml_gen_info).
+:- mode ml_gen_new_func_label(in, out, out, in, out) is det.
 
 	% Generate the mlds__pred_label and module name
 	% for a given procedure.
@@ -316,7 +327,7 @@
 		mlds__statement, ml_gen_info, ml_gen_info).
 :- mode ml_gen_set_cond_var(in, in, in, out, in, out) is det.
 
-	% Return rvals for the success continuation that was
+	% Return the success continuation that was
 	% passed as the current function's argument(s).
 	% The success continuation consists of two parts, the
 	% `cont' argument, and the `cont_env' argument.
@@ -326,9 +337,11 @@
 	% of local variables in the containing procedure) for the continuation
 	% function.  (If we're using gcc nested function, the `cont_env'
 	% is not used.)
+	% XXX need to update this documentation
 	%
-:- pred ml_initial_cont(success_cont, ml_gen_info, ml_gen_info).
-:- mode ml_initial_cont(out, in, out) is det.
+:- pred ml_initial_cont(list(mlds__lval), list(prog_type), success_cont,
+			ml_gen_info, ml_gen_info).
+:- mode ml_initial_cont(in, in, out, in, out) is det.
 
 	% Generate code to call the current success continuation.
 	% This is used for generating success when in a model_non context.
@@ -337,6 +350,15 @@
 			ml_gen_info, ml_gen_info).
 :- mode ml_gen_call_current_success_cont(in, out, in, out) is det.
 
+	% Generate code to call the current success continuation, using
+	% a local function as a proxy.
+	% This is used for generating success when in a model_non context
+	% from within pragma C code (currently only in IL).
+	%
+:- pred ml_gen_call_current_success_cont_indirectly(prog_context, 
+		mlds__statement, ml_gen_info, ml_gen_info).
+:- mode ml_gen_call_current_success_cont_indirectly(in, out, in, out) is det.
+
 %-----------------------------------------------------------------------------%
 %
 % Routines for dealing with the environment pointer
@@ -376,7 +398,16 @@
 :- func ml_base_typeclass_info_method_offset = int.
 
 %-----------------------------------------------------------------------------%
+%
+% Miscellaneous routines
+%
+
+	% Get the value of the appropriate --det-copy-out or --nondet-copy-out
+	% option, depending on the code model.
+:- func get_copy_out_option(globals, code_model) = bool.
+
 %-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 %
 % The `ml_gen_info' ADT.
 %
@@ -415,6 +446,12 @@
 :- pred ml_gen_info_get_output_vars(ml_gen_info, list(prog_var)).
 :- mode ml_gen_info_get_output_vars(in, out) is det.
 
+:- pred ml_gen_info_set_output_vars(list(prog_var), ml_gen_info, ml_gen_info).
+:- mode ml_gen_info_set_output_vars(in, in, out) is det.
+
+:- pred ml_gen_info_get_globals(globals, ml_gen_info, ml_gen_info).
+:- mode ml_gen_info_get_globals(out, in, out) is det.
+
 :- pred ml_gen_info_use_gcc_nested_functions(bool, ml_gen_info, ml_gen_info).
 :- mode ml_gen_info_use_gcc_nested_functions(out, in, out) is det.
 
@@ -470,15 +507,21 @@
 	% holding the address of the) function that a nondet procedure
 	% should call if it succeeds, and possibly also the
 	% (rval for the variable holding) the environment pointer
-	% for that function.
+	% for that function, and possibly also the (list of rvals
+	% for the) arguments to the continuation.
 	%
 :- type success_cont 
 	--->	success_cont(
 			mlds__rval,	% function pointer
-			mlds__rval	% environment pointer
+			mlds__rval,	% environment pointer
 				% note that if we're using nested
 				% functions then the environment
 				% pointer will not be used
+			list(mlds__type), % argument types, if any
+			list(mlds__lval)  % arguments, if any
+				% The arguments will only be non-empty if the
+				% --nondet-copy-out option is enabled.
+				% They do not include the environment pointer.
 		).
 
 	%
@@ -486,8 +529,7 @@
 	% The following routines provide access to that stack.
 	%
 
-:- pred ml_gen_info_push_success_cont(success_cont,
-			ml_gen_info, ml_gen_info).
+:- pred ml_gen_info_push_success_cont(success_cont, ml_gen_info, ml_gen_info).
 :- mode ml_gen_info_push_success_cont(in, in, out) is det.
 
 :- pred ml_gen_info_pop_success_cont(ml_gen_info, ml_gen_info).
@@ -515,6 +557,11 @@
 :- pred ml_gen_info_get_var_lvals(ml_gen_info, map(prog_var, mlds__lval)).
 :- mode ml_gen_info_get_var_lvals(in, out) is det.
 
+	% Set the partial mapping from variables to lvals.
+:- pred ml_gen_info_set_var_lvals(map(prog_var, mlds__lval),
+		ml_gen_info, ml_gen_info).
+:- mode ml_gen_info_set_var_lvals(in, in, out) is det.
+
 	%
 	% The ml_gen_info contains a list of extra definitions
 	% of functions or global constants which should be inserted
@@ -540,6 +587,7 @@
 
 :- implementation.
 
+:- import_module ml_call_gen.
 :- import_module prog_util, type_util, mode_util, special_pred.
 :- import_module code_util. % XXX for `code_util__compiler_generated'.
 :- import_module globals, options.
@@ -657,7 +705,7 @@
 		{ FirstCodeModel = model_non },
 
 		% generate the `succ_func'
-		ml_gen_new_func_label(RestFuncLabel, RestFuncLabelRval),
+		ml_gen_new_func_label(no, RestFuncLabel, RestFuncLabelRval),
 		/* push nesting level */
 		DoGenRest(RestDecls, RestStatements),
 		{ RestStatement = ml_gen_block(RestDecls, RestStatements,
@@ -668,7 +716,7 @@
 
 		ml_get_env_ptr(EnvPtrRval),
 		{ SuccessCont = success_cont(RestFuncLabelRval,
-			EnvPtrRval) },
+			EnvPtrRval, [], []) },
 		ml_gen_info_push_success_cont(SuccessCont),
 		DoGenFirst(FirstDecls, FirstStatements),
 		ml_gen_info_pop_success_cont,
@@ -795,21 +843,28 @@
 
 ml_gen_params_base(ModuleInfo, HeadVarNames, HeadTypes, HeadModes,
 		CodeModel) = FuncParams :-
+	module_info_globals(ModuleInfo, Globals),
+	CopyOut = get_copy_out_option(Globals, CodeModel),
+	ml_gen_arg_decls(ModuleInfo, HeadVarNames, HeadTypes, HeadModes,
+		CopyOut, FuncArgs0, RetTypes0),
 	( CodeModel = model_semi ->
-		RetTypes = [mlds__native_bool_type]
-	;
+		RetTypes = [mlds__native_bool_type | RetTypes0]
+	; CodeModel = model_non, CopyOut = yes ->
 		RetTypes = []
+	;
+		RetTypes = RetTypes0
 	),
-	ml_gen_arg_decls(ModuleInfo, HeadVarNames, HeadTypes, HeadModes,
-		FuncArgs0),
 	( CodeModel = model_non ->
-		ContType = mlds__cont_type,
+		( CopyOut = yes ->
+			ContType = mlds__cont_type(RetTypes0)
+		;
+			ContType = mlds__cont_type([])
+		),
 		ContName = data(var("cont")),
 		ContArg = ContName - ContType,
 		ContEnvType = mlds__generic_env_ptr_type,
 		ContEnvName = data(var("cont_env_ptr")),
 		ContEnvArg = ContEnvName - ContEnvType,
-		module_info_globals(ModuleInfo, Globals),
 		globals__lookup_bool_option(Globals, gcc_nested_functions,
 			NestedFunctions),
 		(
@@ -826,29 +881,52 @@
 	FuncParams = mlds__func_params(FuncArgs, RetTypes).
 
 	% Given the argument variable names, and corresponding lists of their
-	% types and modes, generate the MLDS argument list declaration.
+	% types and modes, generate the MLDS argument declarations
+	% and return types.
 	%
 :- pred ml_gen_arg_decls(module_info, list(mlds__var_name), list(prog_type),
-		list(arg_mode), mlds__arguments).
-:- mode ml_gen_arg_decls(in, in, in, in, out) is det.
+		list(arg_mode), bool, mlds__arguments, mlds__return_types).
+:- mode ml_gen_arg_decls(in, in, in, in, in, out, out) is det.
 
-ml_gen_arg_decls(ModuleInfo, HeadVars, HeadTypes, HeadModes, FuncArgs) :-
+ml_gen_arg_decls(ModuleInfo, HeadVars, HeadTypes, HeadModes, CopyOut,
+		FuncArgs, RetTypes) :-
 	(
 		HeadVars = [], HeadTypes = [], HeadModes = []
 	->
-		FuncArgs = []
+		FuncArgs = [], RetTypes = []
 	;	
 		HeadVars = [Var | Vars],
 		HeadTypes = [Type | Types],
 		HeadModes = [Mode | Modes]
 	->
-		ml_gen_arg_decls(ModuleInfo, Vars, Types, Modes, FuncArgs0),
-		% exclude types such as io__state, etc.
-		( type_util__is_dummy_argument_type(Type) ->
+		ml_gen_arg_decls(ModuleInfo, Vars, Types, Modes, CopyOut,
+			FuncArgs0, RetTypes0),
+		(
+			%
+			% exclude types such as io__state, etc.
+			%
+			type_util__is_dummy_argument_type(Type)
+		->
+			FuncArgs = FuncArgs0,
+			RetTypes = RetTypes0
+		;
+			%
+			% for by-value outputs, generate a return type
+			%
+			Mode = top_out,
+			CopyOut = yes
+		->
+			RetType = mercury_type_to_mlds_type(ModuleInfo, Type),
+			RetTypes = [RetType | RetTypes0],
 			FuncArgs = FuncArgs0
 		;
+			%
+			% for inputs and by-reference outputs,
+			% generate argument
+			%
 			ml_gen_arg_decl(ModuleInfo, Var, Type, Mode, FuncArg),
-			FuncArgs = [FuncArg | FuncArgs0]
+			FuncArgs = [FuncArg | FuncArgs0],
+			RetTypes = RetTypes0
 		)
 	;
 		error("ml_gen_arg_decls: length mismatch")
@@ -905,7 +983,7 @@
 	% Allocate a new function label and return an rval containing
 	% the function's address.
 	%
-ml_gen_new_func_label(FuncLabel, FuncLabelRval) -->
+ml_gen_new_func_label(MaybeParams, FuncLabel, FuncLabelRval) -->
 	ml_gen_info_new_func_label(FuncLabel),
 	=(Info),
 	{ ml_gen_info_get_module_info(Info, ModuleInfo) },
@@ -914,13 +992,16 @@
 	{ ml_gen_pred_label(ModuleInfo, PredId, ProcId,
 		PredLabel, PredModule) },
 	{ ml_gen_info_use_gcc_nested_functions(UseNestedFuncs, Info, _) },
-	{ UseNestedFuncs = yes ->
-		ArgTypes = []
+	{ MaybeParams = yes(Params) ->
+		Signature = mlds__get_func_signature(Params)
 	;
-		ArgTypes = [mlds__generic_env_ptr_type]
+		( UseNestedFuncs = yes ->
+			ArgTypes = []
+		;
+			ArgTypes = [mlds__generic_env_ptr_type]
+		),
+		Signature = mlds__func_signature(ArgTypes, [])
 	},
-	{ Signature = mlds__func_signature(ArgTypes, []) },
-
 	{ ProcLabel = qual(PredModule, PredLabel - ProcId) },
 	{ FuncLabelRval = const(code_addr_const(internal(ProcLabel,
 		FuncLabel, Signature))) }.
@@ -1039,6 +1120,7 @@
 		% The variable won't have been declared, so
 		% we need to generate a dummy lval for this variable.
 		%
+		{ dummy_call },
 		{ mercury_private_builtin_module(PrivateBuiltin) },
 		{ MLDS_Module = mercury_module_name_to_mlds(PrivateBuiltin) },
 		{ Lval = var(qual(MLDS_Module, "dummy_var")) }
@@ -1059,6 +1141,9 @@
 		)
 	).
 
+:- pred dummy_call is det.
+dummy_call.
+
 	% Lookup the types of a list of variables.
 	%
 ml_variable_types([], []) --> [].
@@ -1273,31 +1358,55 @@
 	% function.  (If we're using gcc nested function, the `cont_env'
 	% is not used.)
 	%
-ml_initial_cont(Cont) -->
+ml_initial_cont(OutputVarLvals0, OutputVarTypes0, Cont) -->
 	ml_qualify_var("cont", ContLval),
 	ml_qualify_var("cont_env_ptr", ContEnvLval),
-	{ Cont = success_cont(lval(ContLval), lval(ContEnvLval)) }.
+	{ ml_skip_dummy_argument_types(OutputVarTypes0, OutputVarLvals0,
+		OutputVarTypes, OutputVarLvals) },
+	list__map_foldl(ml_gen_type, OutputVarTypes, MLDS_OutputVarTypes),
+	{ Cont = success_cont(lval(ContLval), lval(ContEnvLval),
+		MLDS_OutputVarTypes, OutputVarLvals) }.
+
+:- pred ml_skip_dummy_argument_types(list(prog_type), list(T),
+		list(prog_type), list(T)).
+:- mode ml_skip_dummy_argument_types(in, in, out, out) is det.
+
+ml_skip_dummy_argument_types([], [], [], []).
+ml_skip_dummy_argument_types([Type | Types0], [Var | Vars0],
+		Types, Vars) :-
+	ml_skip_dummy_argument_types(Types0, Vars0, Types1, Vars1),
+	( type_util__is_dummy_argument_type(Type) ->
+		Types = Types1,
+		Vars = Vars1
+	;
+		Types = [Type | Types1],
+		Vars = [Var | Vars1]
+	).
+ml_skip_dummy_argument_types([_|_], [], _, _) :-
+	error("ml_skip_dummy_argument_types: length mismatch").
+ml_skip_dummy_argument_types([], [_|_], _, _) :-
+	error("ml_skip_dummy_argument_types: length mismatch").
 
 	% Generate code to call the current success continuation.
 	% This is used for generating success when in a model_non context.
 	%
 ml_gen_call_current_success_cont(Context, MLDS_Statement) -->
 	ml_gen_info_current_success_cont(SuccCont),
-	{ SuccCont = success_cont(FuncRval, EnvPtrRval) },
+	{ SuccCont = success_cont(FuncRval, EnvPtrRval,
+		ArgTypes0, ArgLvals0) },
+	{ ArgRvals0 = list__map(func(Lval) = lval(Lval), ArgLvals0) },
 	ml_gen_info_use_gcc_nested_functions(UseNestedFuncs),
 	( { UseNestedFuncs = yes } ->
-		{ ArgTypes = [] }
+		{ ArgTypes = ArgTypes0 },
+		{ ArgRvals = ArgRvals0 }
 	;
-		{ ArgTypes = [mlds__generic_env_ptr_type] }
+		{ ArgTypes = list__append(ArgTypes0,
+			[mlds__generic_env_ptr_type]) },
+		{ ArgRvals = list__append(ArgRvals0, [EnvPtrRval]) }
 	),
 	{ RetTypes = [] },
 	{ Signature = mlds__func_signature(ArgTypes, RetTypes) },
 	{ ObjectRval = no },
-	( { UseNestedFuncs = yes } ->
-		{ ArgRvals = [] }
-	;
-		{ ArgRvals = [EnvPtrRval] }
-	),
 	{ RetLvals = [] },
 	{ CallOrTailcall = call },
 	{ MLDS_Stmt = call(Signature, FuncRval, ObjectRval, ArgRvals, RetLvals,
@@ -1305,6 +1414,87 @@
 	{ MLDS_Statement = mlds__statement(MLDS_Stmt,
 			mlds__make_context(Context)) }.
 
+	% XXX this code is quite similar to some of the existing code
+	% for calling continuations when doing copy-in/copy-out.
+	% Sharing code should be investigated.
+
+ml_gen_call_current_success_cont_indirectly(Context, MLDS_Statement) -->
+
+		% We generate a call to the success continuation, just
+		% as usual.
+	ml_gen_info_current_success_cont(SuccCont),
+	{ SuccCont = success_cont(ContinuationFuncRval, EnvPtrRval,
+		ArgTypes0, ArgLvals0) },
+	{ ArgRvals0 = list__map(func(Lval) = lval(Lval), ArgLvals0) },
+	ml_gen_info_use_gcc_nested_functions(UseNestedFuncs),
+	( { UseNestedFuncs = yes } ->
+		{ ArgTypes = ArgTypes0 },
+		{ ArgRvals = ArgRvals0 }
+	;
+		{ ArgTypes = list__append(ArgTypes0,
+			[mlds__generic_env_ptr_type]) },
+		{ ArgRvals = list__append(ArgRvals0, [EnvPtrRval]) }
+	),
+	{ RetTypes = [] },
+	{ Signature = mlds__func_signature(ArgTypes, RetTypes) },
+	{ ObjectRval = no },
+	{ RetLvals = [] },
+	{ CallOrTailcall = call },
+
+	{ MLDS_Context = mlds__make_context(Context) },
+	=(MLDSGenInfo),
+	{ ml_gen_info_get_module_name(MLDSGenInfo, PredModule) },
+	{ MLDS_Module = mercury_module_name_to_mlds(PredModule) },
+
+		% We generate a nested function that does the real call
+		% to the continuation.
+		%
+		% All we do is change the call rvals to be the input
+		% variables, and the func rval to be the input variable
+		% for the continuation.
+	ml_gen_cont_params(ArgTypes0, InnerFuncParams0),
+	{ InnerFuncParams0 = func_params(InnerArgs0, Rets) },
+	{ InnerArgRvals = list__filter_map(
+		(func(data(var(VarName)) - _Type) 
+		= lval(var(qual(MLDS_Module, VarName))) is semidet), 
+			InnerArgs0) },
+		% XXX is the ArgTypes0 right?
+	{ InnerFuncArgType = mlds__cont_type(ArgTypes0) },
+	{ InnerFuncRval = lval(var(qual(MLDS_Module, "passed_cont"))) },
+	{ InnerFuncParams = func_params(
+		[data(var("passed_cont")) - InnerFuncArgType | InnerArgs0],
+			Rets) },
+
+	{ InnerMLDS_Stmt = call(Signature, InnerFuncRval, ObjectRval, 
+			InnerArgRvals, RetLvals, CallOrTailcall) },
+	{ InnerMLDS_Statement = statement(InnerMLDS_Stmt, MLDS_Context) },
+
+	ml_gen_label_func(1, InnerFuncParams, Context, 
+		InnerMLDS_Statement, Defn),
+
+	{ ProxySignature = mlds__func_signature([InnerFuncArgType | ArgTypes],
+		RetTypes) },
+	{ ProxyArgRvals = [ContinuationFuncRval | ArgRvals] },
+
+	{ Defn = mlds__defn(function(PredLabel, ProcId, yes(SeqNum), _), _, _, 
+		function(_, _, yes(_)))
+	->
+		% We call the proxy function.
+		QualProcLabel = qual(MLDS_Module, PredLabel - ProcId),
+		ProxyFuncRval = const(code_addr_const(
+			internal(QualProcLabel, SeqNum, ProxySignature))),
+
+	
+		% Put it inside a block where we call it.
+		MLDS_Stmt = call(ProxySignature, ProxyFuncRval, ObjectRval,
+			ProxyArgRvals, RetLvals, CallOrTailcall),
+		MLDS_Statement = mlds__statement(
+			block([Defn], [statement(MLDS_Stmt, MLDS_Context)]), 
+			MLDS_Context)
+	;
+		error("success continuation generated was not a function")
+	}.
+
 %-----------------------------------------------------------------------------%
 %
 % Routines for dealing with the environment pointer
@@ -1333,9 +1523,10 @@
 % The `ml_gen_info' type holds information used during MLDS code generation
 % for a given procedure.
 %
-% Only the `func_label', `commit_label', `cond_var', `success_cont_stack',
-% and `extra_defns' fields are mutable; the others are set when the 
-% `ml_gen_info' is created and then never modified.
+% Only the `func_label', `commit_label', `cond_var', `conv_var',
+% `var_lvals', `success_cont_stack', and `extra_defns' fields are mutable;
+% the others are set when the % ml_gen_info' is created and then never
+% modified.
 % 
 
 :- type ml_gen_info
@@ -1374,15 +1565,13 @@
 
 ml_gen_info_init(ModuleInfo, PredId, ProcId) = MLDSGenInfo :-
 	module_info_pred_proc_info(ModuleInfo, PredId, ProcId,
-			PredInfo, ProcInfo),
+			_PredInfo, ProcInfo),
 	proc_info_headvars(ProcInfo, HeadVars),
 	proc_info_varset(ProcInfo, VarSet),
 	proc_info_vartypes(ProcInfo, VarTypes),
 	proc_info_argmodes(ProcInfo, HeadModes),
-	pred_info_arg_types(PredInfo, ArgTypes),
-	map__from_corresponding_lists(HeadVars, ArgTypes, HeadVarTypes),
 	OutputVars = select_output_vars(ModuleInfo, HeadVars, HeadModes,
-		HeadVarTypes, VarTypes),
+		VarTypes),
 
 	FuncLabelCounter = 0,
 	CommitLabelCounter = 0,
@@ -1419,14 +1608,18 @@
 ml_gen_info_get_varset(Info, Info^varset).
 ml_gen_info_get_var_types(Info, Info^var_types).
 ml_gen_info_get_output_vars(Info, Info^output_vars).
+ml_gen_info_set_output_vars(OutputVars, Info, Info^output_vars := OutputVars).
 
 ml_gen_info_use_gcc_nested_functions(UseNestedFuncs) -->
-	=(Info),
-	{ ml_gen_info_get_module_info(Info, ModuleInfo) },
-	{ module_info_globals(ModuleInfo, Globals) },
+	ml_gen_info_get_globals(Globals),
 	{ globals__lookup_bool_option(Globals, gcc_nested_functions,
 		UseNestedFuncs) }.
 
+ml_gen_info_get_globals(Globals) -->
+	=(Info),
+	{ ml_gen_info_get_module_info(Info, ModuleInfo) },
+	{ module_info_globals(ModuleInfo, Globals) }.
+
 ml_gen_info_new_func_label(Label, Info, Info^func_label := Label) :-
 	Label = Info^func_label + 1.
 
@@ -1455,11 +1648,12 @@
 ml_gen_info_current_success_cont(SuccCont, Info, Info) :-
 	stack__top_det(Info^success_cont_stack, SuccCont).
 
-ml_gen_info_get_var_lvals(Info, Info^var_lvals).
-
 ml_gen_info_set_var_lval(Var, Lval, Info,
 		Info^var_lvals := map__set(Info^var_lvals, Var, Lval)).
 
+ml_gen_info_get_var_lvals(Info, Info^var_lvals).
+ml_gen_info_set_var_lvals(VarLvals, Info, Info^var_lvals := VarLvals).
+
 ml_gen_info_add_extra_defn(ExtraDefn, Info,
 	Info^extra_defns := [ExtraDefn | Info^extra_defns]).
 
@@ -1471,11 +1665,7 @@
 	% return a list containing only those variables which have
 	% an output mode.
 	%
-:- func select_output_vars(module_info, list(prog_var), list(mode),
-		vartypes, vartypes) = list(prog_var).
-
-select_output_vars(ModuleInfo, HeadVars, HeadModes, HeadVarTypes, VarTypes)
-		= OutputVars :-
+select_output_vars(ModuleInfo, HeadVars, HeadModes, VarTypes) = OutputVars :-
 	( HeadVars = [], HeadModes = [] ->
 		OutputVars = []
 	; HeadVars = [Var|Vars], HeadModes = [Mode|Modes] ->
@@ -1484,11 +1674,11 @@
 			\+ mode_to_arg_mode(ModuleInfo, Mode, VarType, top_in)
 		->
 			OutputVars1 = select_output_vars(ModuleInfo,
-					Vars, Modes, HeadVarTypes, VarTypes),
+					Vars, Modes, VarTypes),
 			OutputVars = [Var | OutputVars1]
 		;
 			OutputVars = select_output_vars(ModuleInfo,
-					Vars, Modes, HeadVarTypes, VarTypes)
+					Vars, Modes, VarTypes)
 		)
 	;
 		error("select_output_vars: length mismatch")
@@ -1530,6 +1720,22 @@
 	%	more information about the layout of base_typeclass_infos.)
 	% Hence the offset is 4.
 ml_base_typeclass_info_method_offset = 4.
+
+%-----------------------------------------------------------------------------%
+%
+% Miscellaneous routines
+%
+
+	% Get the value of the appropriate --det-copy-out or --nondet-copy-out
+	% option, depending on the code model.
+get_copy_out_option(Globals, CodeModel) = CopyOut :-
+	( CodeModel = model_non ->
+		globals__lookup_bool_option(Globals,
+			nondet_copy_out, CopyOut)
+	;	
+		globals__lookup_bool_option(Globals,
+			det_copy_out, CopyOut)
+	).
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
Index: compiler/ml_unify_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_unify_gen.m,v
retrieving revision 1.14
diff -u -r1.14 ml_unify_gen.m
--- compiler/ml_unify_gen.m	2000/06/06 05:45:22	1.14
+++ compiler/ml_unify_gen.m	2000/09/04 00:41:59
@@ -80,7 +80,7 @@
 :- import_module code_util. % XXX needed for `code_util__cons_id_to_tag'.
 :- import_module globals, options.
 
-:- import_module bool, int, string, list, require, std_util, term, varset.
+:- import_module bool, int, string, list, map, require, std_util, term, varset.
 
 %-----------------------------------------------------------------------------%
 
@@ -409,12 +409,12 @@
 	% (we do this just to match the structure used
 	% by the LLDS closure representation)
 	%
-	{ ClosureLayoutRval = const(int_const(0)) },
 	{ mercury_private_builtin_module(PrivateBuiltinModule) },
 	{ MLDS_PrivateBuiltinModule = mercury_module_name_to_mlds(
 		PrivateBuiltinModule) },
 	{ ClosureLayoutType = mlds__class_type(qual(MLDS_PrivateBuiltinModule,
-			"closure_layout"), 0, mlds__struct) },
+			"closure_layout"), 0, mlds__class) },
+	{ ClosureLayoutRval = const(null(ClosureLayoutType)) },
 
 	%
 	% Generate a wrapper function which just unboxes the
@@ -467,7 +467,8 @@
 	% The generated function will be of the following form:
 	%
 	%	foo_wrapper(void *closure_arg,
-	%			MR_Box arg1, MR_Box *arg2, ..., MR_Box argn)
+	%			MR_Box wrapper_arg1, MR_Box *wrapper_arg2,
+	%			..., MR_Box wrapper_argn)
 	%	{
 	%		FooClosure *closure;
 	%		...
@@ -483,10 +484,11 @@
 	%	    CONJ(code_model, 
 	%		/* call function, boxing/unboxing inputs if needed */
 	%		foo(closure->f1, unbox(closure->f2), ...,
-	%			unbox(arg1), &unboxed_arg2, arg3, ...);
+	%			unbox(wrapper_arg1), &conv_arg2,
+	%			wrapper_arg3, ...);
 	%	    ,
 	%		/* box output arguments */
-	%		*arg2 = box(unboxed_arg2);
+	%		*wrapper_arg2 = box(conv_arg2);
 	%		...
 	%	    )
 	%	}
@@ -497,19 +499,21 @@
 	% #if MODEL_DET
 	%		/* call function, boxing/unboxing inputs if needed */
 	%		foo(closure->f1, unbox(closure->f2), ...,
-	%			unbox(arg1), &unboxed_arg2, arg3, ...);
+	%			unbox(wrapper_arg1), &conv_arg2,
+	%			wrapper_arg3, ...);
 	%
 	%		/* box output arguments */
-	%		*arg2 = box(unboxed_arg2);
+	%		*wrapper_arg2 = box(conv_arg2);
 	%		...
 	% #elif MODEL_SEMI
 	%		/* call function, boxing/unboxing inputs if needed */
 	%		succeeded = foo(closure->f1, unbox(closure->f2), ...,
-	%			unbox(arg1), &unboxed_arg2, arg3, ...);
+	%			unbox(wrapper_arg1), &conv_arg2,
+	%			wrapper_arg3, ...);
 	%		
 	%		if (succeeded) {
 	%			/* box output arguments */
-	%			*arg2 = box(unboxed_arg2);
+	%			*wrapper_arg2 = box(conv_arg2);
 	%			...
 	%		}
 	%
@@ -518,14 +522,15 @@
 	% #else /* MODEL_NON */
 	%		foo_1() {
 	%			/* box output arguments */
-	%			*arg2 = box(unboxed_arg2);
+	%			*wrapper_arg2 = box(conv_arg2);
 	%			...
 	%			(*succ_cont)();
 	%		}
 	%			
 	%		/* call function, boxing/unboxing inputs if needed */
 	%		foo(closure->f1, unbox(closure->f2), ...,
-	%			unbox(arg1), &unboxed_arg2, arg3, ...,
+	%			unbox(wrapper_arg1), &conv_arg2,
+	%			wrapper_arg3, ...,
 	%			foo_1);
 	% #endif
 	%
@@ -558,7 +563,8 @@
 	%
 	% compute the parameters for the wrapper function
 	%	(void *closure_arg,
-	%	MR_Box arg1, MR_Box *arg2, ..., MR_Box argn)
+	%	MR_Box wrapper_arg1, MR_Box *wrapper_arg2, ...,
+	%	MR_Box wrapper_argn)
 	%
 
 	% first generate the declarations for the boxed arguments
@@ -580,11 +586,17 @@
 		WrapperBoxedArgTypes, WrapperArgModes, CodeModel) },
 
 	% then insert the `closure_arg' parameter
-	{ ClosureArg = data(var("closure_arg")) - mlds__generic_env_ptr_type },
+	{ ClosureArg = data(var("closure_arg")) - mlds__generic_type },
 	{ WrapperParams0 = mlds__func_params(WrapperArgs0, WrapperRetType) },
 	{ WrapperParams = mlds__func_params([ClosureArg | WrapperArgs0],
 		WrapperRetType) },
 
+	% also compute the lvals for the parameters,
+	% and local declarations for any --copy-out output parameters
+	ml_gen_wrapper_arg_lvals(WrapperHeadVarNames, WrapperBoxedArgTypes,
+		WrapperArgModes, CodeModel, Context,
+		WrapperHeadVarDecls, WrapperHeadVarLvals),
+
 	%
 	% generate code to declare and initialize the closure pointer.
 	% XXX we should use a struct type for the closure, but
@@ -602,7 +614,7 @@
 	{ ClosureArgName = "closure_arg" },
 	{ MLDS_Context = mlds__make_context(Context) },
 	{ ClosureDecl = ml_gen_mlds_var_decl(var(ClosureName),
-		mlds__generic_env_ptr_type, MLDS_Context) },
+		mlds__generic_type, MLDS_Context) },
 	ml_qualify_var(ClosureName, ClosureLval),
 	ml_qualify_var(ClosureArgName, ClosureArgLval),
 	{ InitClosure = ml_gen_assign(ClosureLval, lval(ClosureArgLval),
@@ -614,7 +626,22 @@
 	% this is needed by ml_gen_call which we call below
 	%
 	( { CodeModel = model_non } ->
-		ml_initial_cont(InitialCont),
+		{ module_info_globals(ModuleInfo, Globals) },
+		{ globals__lookup_bool_option(Globals, nondet_copy_out,
+			NondetCopyOut) },
+		( { NondetCopyOut = yes } ->
+			{ map__from_corresponding_lists(WrapperHeadVarLvals,
+				WrapperBoxedArgTypes, WrapperBoxedVarTypes) },
+			{ WrapperOutputLvals = select_output_vars(ModuleInfo,
+				WrapperHeadVarLvals, WrapperArgModes,
+				WrapperBoxedVarTypes) },
+			{ WrapperOutputTypes = map__apply_to_list(
+				WrapperOutputLvals, WrapperBoxedVarTypes) },
+			ml_initial_cont(WrapperOutputLvals, WrapperOutputTypes,
+				InitialCont)
+		;
+			ml_initial_cont([], [], InitialCont)
+		),
 		ml_gen_info_push_success_cont(InitialCont)
 	;
 		[]
@@ -632,13 +659,11 @@
 	%		MR_field(MR_mktag(0), closure, 4),
 	%		...
 	% #endif
-	%		unbox(arg1), &unboxed_arg2, arg3, ...
+	%		unbox(wrapper_arg1), &conv_arg2, wrapper_arg3, ...
 	%	);
 	%
 	ml_gen_closure_field_lvals(ClosureLval, Offset, 1, NumClosureArgs,
 		ClosureArgLvals),
-	ml_gen_wrapper_arg_lvals(WrapperHeadVarNames, WrapperBoxedArgTypes,
-		WrapperArgModes, WrapperHeadVarLvals),
 	{ CallLvals = list__append(ClosureArgLvals, WrapperHeadVarLvals) },
 	ml_gen_call(PredId, ProcId, ProcHeadVarNames, CallLvals,
 		ProcBoxedArgTypes, CodeModel, Context, Decls0, Statements0),
@@ -653,17 +678,23 @@
 	%
 	( { CodeModel = model_semi } ->
 		{ SucceededVarDecl = ml_gen_succeeded_var_decl(MLDS_Context) },
-		{ Decls = [SucceededVarDecl | Decls1] },
+		{ Decls2 = [SucceededVarDecl | Decls1] },
 		ml_gen_test_success(Succeeded),
 		{ ReturnStmt = return([Succeeded]) },
 		{ ReturnStatement = mlds__statement(ReturnStmt, MLDS_Context) },
 		{ Statements = list__append(Statements1, [ReturnStatement]) }
 	;
-		{ Decls = Decls1 },
+		{ Decls2 = Decls1 },
 		{ Statements = Statements1 }
 	),
 
 	%
+	% Insert the local declarations of the wrapper's output arguments,
+	% if any (this is needed for `--nondet-copy-out')
+	%
+	{ Decls = list__append(WrapperHeadVarDecls, Decls2) },
+
+	%
 	% if the wrapper function was model_non, then
 	% pop the success continuation that we pushed
 	%
@@ -677,7 +708,8 @@
 	% Put it all together
 	%
 	{ WrapperFuncBody = ml_gen_block(Decls, Statements, Context) },
-	ml_gen_new_func_label(WrapperFuncName, WrapperFuncRval),
+	ml_gen_new_func_label(yes(WrapperParams), WrapperFuncName,
+		WrapperFuncRval),
 	ml_gen_label_func(WrapperFuncName, WrapperParams, Context,
 		WrapperFuncBody, WrapperFunc),
 	{ WrapperFuncType = mlds__func_type(WrapperParams) },
@@ -693,37 +725,70 @@
 		Names = [Name | Names1]
 	).
 
-	% ml_gen_wrapper_arg_lvals(HeadVarNames, ArgModes, HeadVarLvals):
+	% ml_gen_wrapper_arg_lvals(HeadVarNames, Types, ArgModes, CodeModel,
+	%		LocalVarDefns, HeadVarLvals):
 	%	Generate lvals for the specified head variables
 	%	passed in the specified modes.
+	%	Also generate local definitions for output variables,
+	%	if those output variables will be copied out,
+	%	rather than passed by reference.
 	%
 :- pred ml_gen_wrapper_arg_lvals(list(var_name), list(prog_type), list(mode),
-		list(mlds__lval), ml_gen_info, ml_gen_info).
-:- mode ml_gen_wrapper_arg_lvals(in, in, in, out, in, out) is det.
+		code_model, prog_context, list(mlds__defn), list(mlds__lval),
+		ml_gen_info, ml_gen_info).
+:- mode ml_gen_wrapper_arg_lvals(in, in, in, in, in, out, out, in, out) is det.
 
-ml_gen_wrapper_arg_lvals(Names, Types, Modes, Lvals) -->
+ml_gen_wrapper_arg_lvals(Names, Types, Modes, CodeModel, Context,
+		Defns, Lvals) -->
 	(
 		{ Names = [], Types = [], Modes = [] }
 	->
-		{ Lvals = [] }
+		{ Lvals = [] },
+		{ Defns = [] }
 	;
-		{ Names = [Name|Names1] },
-		{ Types = [Type|Types1] },
-		{ Modes = [Mode|Modes1] }
+		{ Names = [Name | Names1] },
+		{ Types = [Type | Types1] },
+		{ Modes = [Mode | Modes1] }
 	->
+		ml_gen_wrapper_arg_lvals(Names1, Types1, Modes1,
+			CodeModel, Context, Defns1, Lvals1),
 		ml_qualify_var(Name, VarLval),
 		=(Info),
 		{ ml_gen_info_get_module_info(Info, ModuleInfo) },
 		( { mode_to_arg_mode(ModuleInfo, Mode, Type, top_in) } ->
-			{ Lval = VarLval }
+			{ Lval = VarLval },
+			{ Defns = Defns1 }
 		;
-			% output arguments are passed by reference,
-			% so we need to dereference them
-			ml_gen_type(Type, MLDS_Type),
-			{ Lval = mem_ref(lval(VarLval), MLDS_Type) }
+			%
+			% handle output variables
+			%
+			ml_gen_info_get_globals(Globals),
+			{ CopyOut = get_copy_out_option(Globals, CodeModel) },
+			( { CopyOut = yes } ->
+				%
+				% output arguments are copied out,
+				% so we need to generate a local declaration
+				% for them here
+				%
+				{ Lval = VarLval },
+				( { type_util__is_dummy_argument_type(Type) } ->
+					{ Defns = Defns1 }
+				;
+					ml_gen_local_for_output_arg(Name, Type,
+						Context, Defn),
+					{ Defns = [Defn | Defns1] }
+				)
+			;
+				%
+				% output arguments are passed by reference,
+				% so we need to dereference them
+				%
+				ml_gen_type(Type, MLDS_Type),
+				{ Lval = mem_ref(lval(VarLval), MLDS_Type) },
+				{ Defns = Defns1 }
+			)
 		),
-		ml_gen_wrapper_arg_lvals(Names1, Types1, Modes1, Lvals1),
-		{ Lvals = [Lval|Lvals1] }
+		{ Lvals = [Lval | Lvals1] }
 	;
 		{ error("ml_gen_wrapper_arg_lvals: length mismatch") }
 	).
@@ -744,7 +809,7 @@
 		{ FieldId = offset(const(int_const(ArgNum + Offset))) },
 			% XXX these types might not be right
 		{ FieldLval = field(yes(0), lval(ClosureLval), FieldId,
-			mlds__generic_type, mlds__generic_env_ptr_type) },
+			mlds__generic_type, mlds__generic_type) },
 		%
 		% recursively handle the remaining fields
 		%
@@ -752,6 +817,19 @@
 			NumClosureArgs, ClosureArgLvals0),
 		{ ClosureArgLvals = [FieldLval | ClosureArgLvals0] }
 	).
+
+:- pred ml_gen_local_for_output_arg(var_name, prog_type, prog_context,
+		mlds__defn, ml_gen_info, ml_gen_info).
+:- mode ml_gen_local_for_output_arg(in, in, in, out, in, out) is det.
+
+ml_gen_local_for_output_arg(VarName, Type, Context, LocalVarDefn) -->
+	%
+	% Generate a declaration for a corresponding local variable.
+	%
+	=(MLDSGenInfo),
+	{ ml_gen_info_get_module_info(MLDSGenInfo, ModuleInfo) },
+	{ LocalVarDefn = ml_gen_var_decl(VarName, Type,
+		mlds__make_context(Context), ModuleInfo) }.
 
 %-----------------------------------------------------------------------------%
 		
Index: compiler/mlds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds.m,v
retrieving revision 1.32
diff -u -r1.32 mlds.m
--- compiler/mlds.m	2000/08/24 10:01:50	1.32
+++ compiler/mlds.m	2000/09/04 00:42:01
@@ -66,17 +66,23 @@
 % MLDS function signatures are determined by the HLDS procedure's
 % argument types, modes, and determinism.
 % Procedures arguments with type `io__state' or `store(_)' are not passed.
+% Procedure arguments with top_unused modes are not passed.
 % Procedures arguments with top_in modes are passed as input.
-% Procedures arguments with top_out modes may be returned by value
-% or alternatively may be passed by reference.
-% Procedure arguments with top_unused modes should not be passed
-% (except possibly in the case where they are polymorphically typed,
-% and even then, depending on how polymorphism is handled).]
+% Procedures arguments with top_out modes are normally passed by reference.
+% However, several alternative approaches are also supported (see below).
+%
 % Procedures with determinism model_det need no special handling.
 % Procedures with determinism model_semi must return a boolean.
 % Procedures with determinism model_non get passed a continuation;
 % if the procedure succeeds, it must call the continuation, and if
 % it fails, it must return.
+%
+% With the `--copy-out' option, arguments with top_out modes will be returned
+% by value.  This requires the target language to support multiple return
+% values.  The MLDS->target code generator can of course handle that by mapping
+% functions with multiple return values into functions that returns a struct.
+% With the `--nondet-copy-out' option, arguments for nondet procedures with
+% top_out modes will be passed as arguments to the continuation.
 
 % 4. Variables
 %
@@ -414,18 +420,20 @@
 :- type mlds__func_params
 	---> mlds__func_params(
 		mlds__arguments,	% names and types of arguments (inputs)
-		list(mlds__type)	% types of return values (outputs)
+		mlds__return_types	% types of return values (outputs)
 	).
 
 :- type mlds__arguments == assoc_list(mlds__entity_name, mlds__type).
+:- type mlds__arg_types == list(mlds__type).
+:- type mlds__return_types == list(mlds__type).
 
 	% An mlds__func_signature is like an mlds__func_params
 	% except that it only includes the function's type, not
 	% the parameter names.
 :- type mlds__func_signature
 	---> mlds__func_signature(
-		list(mlds__type),	% argument types
-		list(mlds__type)	% return types
+		mlds__arg_types,	% argument types
+		mlds__return_types	% return types
 	).
 
 :- func mlds__get_func_signature(mlds__func_params) = mlds__func_signature.
@@ -479,7 +487,7 @@
 
 		% The type for the continuation functions used
 		% to handle nondeterminism
-	;	mlds__cont_type
+	;	mlds__cont_type(mlds__return_types)
 
 		% The type used for storing information about a commit.
 		% This may be `jmp_buf' or `__label__'.
@@ -894,10 +902,11 @@
 	%
 
 	;	target_code(target_lang, list(target_code_component))
-			% Do whatever is specified by the target_code_compoenents,
-			% which can be any piece of code in the specified
-			% target language (C, assembler, or whatever)
-			% that does not have any non-local flow of control.
+			% Do whatever is specified by the
+			% target_code_components, which can be any piece
+			% of code in the specified target language (C,
+			% assembler, or whatever) that does not have any
+			% non-local flow of control.
 	.
 
 	%
@@ -1081,7 +1090,12 @@
 			% first null character.
 	;	multi_string_const(int, string)
 	;	code_addr_const(mlds__code_addr)
-	;	data_addr_const(mlds__data_addr).
+	;	data_addr_const(mlds__data_addr)
+			% A null value, of the given type.
+			% Usually this will be a pointer (mlds__ptr_type)
+			% but it could be a place holder for a string or
+			% a func_type.
+	;	null(mlds__type).
 
 :- type mlds__code_addr
 	--->	proc(mlds__qualified_proc_label, mlds__func_signature)
Index: compiler/mlds_to_c.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_c.m,v
retrieving revision 1.53
diff -u -r1.53 mlds_to_c.m
--- compiler/mlds_to_c.m	2000/08/31 03:00:22	1.53
+++ compiler/mlds_to_c.m	2000/09/04 00:42:01
@@ -30,6 +30,7 @@
 
 :- implementation.
 
+:- import_module ml_util.
 :- import_module llds.		% XXX needed for C interface types
 :- import_module llds_out.	% XXX needed for llds_out__name_mangle,
 				% llds_out__sym_name_mangle,
@@ -516,7 +517,7 @@
 mlds_output_pragma_export_type(prefix, mercury_type(Type, _)) -->
 	{ export__type_to_type_string(Type, String) },
 	io__write_string(String).
-mlds_output_pragma_export_type(prefix, mlds__cont_type) -->
+mlds_output_pragma_export_type(prefix, mlds__cont_type(_)) -->
 	io__write_string("MR_Word").
 mlds_output_pragma_export_type(prefix, mlds__commit_type) -->
 	io__write_string("MR_Word").
@@ -1198,7 +1199,8 @@
 	; { RetTypes = [RetType] } ->
 		OutputPrefix(RetType)
 	;
-		{ error("mlds_output_func: multiple return types") }
+		io__write_string("\n#error multiple return types\n")
+		% { error("mlds_output_func: multiple return types") }
 	),
 	io__write_char(' '),
 	mlds_output_fully_qualified_name(QualifiedName),
@@ -1513,12 +1515,18 @@
 	io__write_string("void *").
 mlds_output_type_prefix(mlds__pseudo_type_info_type) -->
 	io__write_string("MR_PseudoTypeInfo").
-mlds_output_type_prefix(mlds__cont_type) -->
-	globals__io_lookup_bool_option(gcc_nested_functions, GCC_NestedFuncs),
-	( { GCC_NestedFuncs = yes } ->
-		io__write_string("MR_NestedCont")
+mlds_output_type_prefix(mlds__cont_type(ArgTypes)) -->
+	( { ArgTypes = [] } ->
+		globals__io_lookup_bool_option(gcc_nested_functions,
+			GCC_NestedFuncs),
+		( { GCC_NestedFuncs = yes } ->
+			io__write_string("MR_NestedCont")
+		;
+			io__write_string("MR_Cont")
+		)
 	;
-		io__write_string("MR_Cont")
+		% This case only happens for --nondet-copy-out
+		io__write_string("void (*")
 	).
 mlds_output_type_prefix(mlds__commit_type) -->
 	globals__io_lookup_bool_option(gcc_local_labels, GCC_LocalLabels),
@@ -1610,7 +1618,23 @@
 mlds_output_type_suffix(mlds__generic_type) --> [].
 mlds_output_type_suffix(mlds__generic_env_ptr_type) --> [].
 mlds_output_type_suffix(mlds__pseudo_type_info_type) --> [].
-mlds_output_type_suffix(mlds__cont_type) --> [].
+mlds_output_type_suffix(mlds__cont_type(ArgTypes)) -->
+	( { ArgTypes = [] } ->
+		[]
+	;
+		% This case only happens for --nondet-copy-out
+		io__write_string(")("),
+		io__write_list(ArgTypes, ", ", mlds_output_type),
+		% add the type for the environment parameter, if needed
+		globals__io_lookup_bool_option(gcc_nested_functions,
+			GCC_NestedFuncs),
+		( { GCC_NestedFuncs = no } ->
+			io__write_string(", void *")
+		;
+			[]
+		),
+		io__write_string(")")
+	).
 mlds_output_type_suffix(mlds__commit_type) --> [].
 mlds_output_type_suffix(mlds__rtti_type(_)) --> [].
 
@@ -2149,11 +2173,6 @@
 		%	...
 		%	new_argN_value = argN_tmp_copy;
 		%
-		% The temporaries are needed for the case where
-		% we are e.g. assigning v1, v2 to v2, v1;
-		% they ensure that we don't try to reference the old value of
-		% a parameter after it has already been clobbered by the
-		% new value.
 
 		{ string__append(VarName, "__tmp_copy", TempName) },
 		{ QualTempName = qual(ModuleName, data(var(TempName))) },
@@ -2746,6 +2765,8 @@
 	mlds_output_code_addr(CodeAddr).
 mlds_output_rval_const(data_addr_const(DataAddr)) -->
 	mlds_output_data_addr(DataAddr).
+mlds_output_rval_const(null(_)) -->
+	io__write_string("NULL").
 
 %-----------------------------------------------------------------------------%
 
Index: compiler/options.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.287
diff -u -r1.287 options.m
--- compiler/options.m	2000/08/31 03:00:23	1.287
+++ compiler/options.m	2000/09/04 02:54:47
@@ -88,7 +88,7 @@
 		;	convert_to_goedel
 		;	typecheck_only
 		;	errorcheck_only
-		;	compile_to_c
+		;	target_code_only
 		;	compile_only
 		;	aditi_only
 		;	output_grade_string
@@ -102,8 +102,11 @@
 		;	trace_decl
 		;	stack_trace_higher_order
 		;	generate_bytecode
-		;	generate_prolog
-		;	prolog_dialect
+		;	generate_prolog		% Currently not used
+				% XXX generate_prolog should probably be
+				% in the "Output options" section rather than
+				% in the "Auxiliary output options" section
+		;	prolog_dialect		% Currently not used
 		;	line_numbers
 		;	auto_comments
 		;	show_dependency_graph
@@ -127,6 +130,10 @@
 		;	mode_inference_iteration_limit
 	% Compilation Model options
 		;	grade
+		;	target
+		;	il			% target il
+		;	il_only			% target il + target_code_only
+		;	compile_to_c		% target c + target_code_only
 		;	gcc_non_local_gotos
 		;	gcc_global_registers
 		;	asm_labels
@@ -165,6 +172,8 @@
 		;	highlevel_code
 		;	highlevel_data
 		;	gcc_nested_functions
+		;	det_copy_out
+		;	nondet_copy_out
 		;	unboxed_float
 		;       unboxed_enums
 		;       unboxed_no_tag_types
@@ -338,7 +347,7 @@
 		;	allow_hijacks
 	%	- LLDS
 		;	common_data
-		;	optimize
+		;	optimize	% also used for MLDS->MLDS optimizations
 		;	optimize_peep
 		;	optimize_jumps
 		;	optimize_fulljumps
@@ -366,6 +375,8 @@
 		;	everything_in_one_c_function
 		;	c_optimize
 		;	inline_alloc
+	%	- IL
+	%	(none yet)
 	% Link options
 		;	output_file_name
 		;	link_flags
@@ -378,7 +389,9 @@
 		;	use_search_directories_for_intermod
 		;	filenames_from_stdin
 		;	use_subdirs
-		;	aditi
+		;	aditi		% XXX this should be in the
+					% "Auxiliary output options"
+					% section
 		;	aditi_user
 		;	help.
 
@@ -463,7 +476,7 @@
 	convert_to_goedel 	-	bool(no),
 	typecheck_only		-	bool(no),
 	errorcheck_only		-	bool(no),
-	compile_to_c		-	bool(no),
+	target_code_only	-	bool(no),
 	compile_only		-	bool(no),
 	aditi_only		-	bool(no),
 	output_grade_string	-	bool(no)
@@ -511,6 +524,10 @@
 					% the `mmc' script will pass the
 					% default grade determined
 					% at configuration time
+	target			-	string("c"),
+	il			-	special,
+	il_only			-	special,
+	compile_to_c		-	special,
 	gcc_non_local_gotos	-	bool(yes),
 	gcc_global_registers	-	bool(yes),
 	asm_labels		-	bool(yes),
@@ -563,6 +580,8 @@
 	highlevel_code		-	bool(no),
 	highlevel_data		-	bool(no),
 	gcc_nested_functions	-	bool(no),
+	det_copy_out		-	bool(no),
+	nondet_copy_out		-	bool(no),
 	unboxed_float           -       bool(no),
 	unboxed_enums           -       bool(yes),
 	unboxed_no_tag_types    -       bool(yes)
@@ -755,7 +774,7 @@
 
 	% please keep this in alphabetic order
 short_option('c', 			compile_only).
-short_option('C', 			compile_to_c).
+short_option('C', 			target_code_only).
 short_option('d', 			dump_hlds).
 short_option('D', 			dump_hlds_alias).
 short_option('e', 			errorcheck_only).
@@ -843,8 +862,7 @@
 long_option("convert-to-Goedel", 	convert_to_goedel).
 long_option("typecheck-only",		typecheck_only).
 long_option("errorcheck-only",		errorcheck_only).
-long_option("compile-to-c",		compile_to_c).
-long_option("compile-to-C",		compile_to_c).
+long_option("target-code-only",		target_code_only).
 long_option("compile-only",		compile_only).
 long_option("aditi-only",		aditi_only).
 long_option("output-grade-string",	output_grade_string).
@@ -863,6 +881,7 @@
 long_option("generate-prolog",		generate_prolog).
 long_option("generate-Prolog",		generate_prolog).
 long_option("prolog-dialect",		prolog_dialect).
+long_option("Prolog-dialect",		prolog_dialect).
 long_option("line-numbers",		line_numbers).
 long_option("auto-comments",		auto_comments).
 long_option("show-dependency-graph",	show_dependency_graph).
@@ -891,6 +910,12 @@
 
 % compilation model options
 long_option("grade",			grade).
+long_option("target",			target).
+long_option("il",			il).
+long_option("il-only",			il_only).
+long_option("IL-only",			il_only).
+long_option("compile-to-c",		compile_to_c).
+long_option("compile-to-C",		compile_to_c).
 long_option("gcc-non-local-gotos",	gcc_non_local_gotos).
 long_option("gcc-global-registers",	gcc_global_registers).
 long_option("asm-labels",		asm_labels).
@@ -938,6 +963,8 @@
 long_option("highlevel-data",		highlevel_data).
 long_option("high-level-data",		highlevel_data).
 long_option("gcc-nested-functions",	gcc_nested_functions).
+long_option("det-copy-out",		det_copy_out).
+long_option("nondet-copy-out",		nondet_copy_out).
 long_option("unboxed-float",		unboxed_float).
 long_option("unboxed-enums",		unboxed_enums).
 long_option("unboxed-no-tag-types",	unboxed_no_tag_types).
@@ -1157,6 +1184,14 @@
 		string__append_list(["invalid grade `", Grade, "'"], Msg),
 		Result = error(Msg)
 	).
+special_handler(il, none, OptionTable0, ok(OptionTable)) :-
+	map__set(OptionTable0, target, string("il"), OptionTable).
+special_handler(il_only, none, OptionTable0, ok(OptionTable)) :-
+	map__set(OptionTable0, target, string("il"), OptionTable1),
+	map__set(OptionTable1, target_code_only, bool(yes), OptionTable).
+special_handler(compile_to_c, none, OptionTable0, ok(OptionTable)) :-
+	map__set(OptionTable0, target, string("c"), OptionTable1),
+	map__set(OptionTable1, target_code_only, bool(yes), OptionTable).
 special_handler(profiling, bool(Value), OptionTable0, ok(OptionTable)) :-
 	map__set(OptionTable0, profile_time, bool(Value), OptionTable1),
 	map__set(OptionTable1, profile_calls, bool(Value), OptionTable2),
@@ -1440,6 +1475,7 @@
 	options_help_hlds_hlds_optimization,
 	options_help_hlds_llds_optimization,
 	options_help_llds_llds_optimization,
+	options_help_mlds_mlds_optimization,
 	options_help_rl_rl_optimization,
 	options_help_output_optimization,
 	options_help_object_optimization,
@@ -1594,8 +1630,9 @@
 		"\tand don't generate any code.",
 		"-e, --errorcheck-only",
 		"\tCheck the module for errors, but do not generate any code.",
-		"-C, --compile-to-c",
-		"\tGenerate C code in `<module>.c', but not object code.",
+		"-C, --target-code-only",
+		"\tGenerate target code (i.e. C code in `<module>.c',",
+		"\t\tor IL code in `<module>.il') but not object code.",
 		"-c, --compile-only",
 		"\tGenerate C code in `<module>.c' and object code in `<module>.o'",
 		"\tbut do not attempt to link the named modules.",
@@ -1644,11 +1681,13 @@
 		"--generate-bytecode",
 		"\tOutput a bytecode form of the module for use",
 		"\tby an experimental debugger.",
-		"--generate-prolog",
-		"\tConvert the program to Prolog. Output to file `<module>.pl'",
-		"\tor `<module>.nl' (depending on the dialect).",
-		"--prolog-dialect {sicstus,nu}",
-		"\tTarget the named dialect if generating Prolog code.",
+% --generate-prolog is not documented because it is not yet implemented
+%		"--generate-prolog",
+%		"\tConvert the program to Prolog. Output to file `<module>.pl'",
+%		"\tor `<module>.nl' (depending on the dialect).",
+% --prolog-dialect is not documented because it is not yet used
+%		"--prolog-dialect {sicstus,nu}",
+%		"\tTarget the named dialect if generating Prolog code.",
 		"--no-line-numbers",
 		"\tDo not put source line numbers in the generated code.",
 		"\tThe generated code may be in C (the usual case),",
@@ -1709,6 +1748,8 @@
 		"\tExecute disjunctions strictly left-to-right.",
 		"--fully-strict",
 		"\tDon't optimize away loops or calls to error/1.",
+		"--infer-all",
+		"\tAbbreviation for `--infer-types --infer-modes --infer-det'.",
 		"--infer-types",
 		"\tIf there is no type declaration for a predicate or function,",
 		"\ttry to infer the type, rather than just reporting an error.",
@@ -1779,6 +1820,17 @@
 		"-s <grade>, --grade <grade>",
 		"\tSelect the compilation model. The <grade> should be one of",
 		"\t`none', `reg', `jump', `asm_jump', `fast', `asm_fast', `hlc'",
+		"--target {c, il}",
+		"\tSpecify the target language: C or IL (default: C).",
+		"\tThe IL target implies `--high-level-code' (see below).",
+		"--il",
+		"\tAn abbreviation for `--target il'.",
+		"--il-only",
+		"\tAn abbreviation for `--target il --intermediate-code-only'.",
+		"\tGenerate IL code in `<module>.il', but do not generate object code.",
+		"--compile-to-c",
+		"\tAn abbreviation for `--target c --intermediate-code-only'.",
+		"\tGenerate C code in `<module>.c', but do not generate object code.",
 % These grades (hl, hl_nest, and hlc_nest) are not yet documented, because
 % the --high-level-data option is not yet implemented,
 % and the --gcc-nested-functions option is not yet documented.
@@ -1809,9 +1861,9 @@
 % the --high-level-data option is not yet implemented,
 % and the --gcc-nested-functions option is not yet documented.
 %		"-H, --high-level-code\t\t\t(grades: hl, hlc, hl_nest, hlc_nest)",
-		"-H, --high-level-code\t\t\t(grades: hlc)",
-		"\tUse an alternative back-end that generates high-level C code",
-		"\trather than the very low-level C code that is generated by our",
+		"-H, --high-level-code\t\t\t(grades: hlc, ilc)",
+		"\tUse an alternative back-end that generates high-level code",
+		"\trather than the very low-level code that is generated by our",
 		"\toriginal back-end.",
 % The --high-level-data option is not yet documented,
 % because it is not yet implemented
@@ -1827,6 +1879,19 @@
 %		"--gcc-nested-functions\t\t(grades: hl_nest, hlc_nest)",
 %		"\tSpecify whether or not to use GNU C's nested functions extension.",
 %		"\tThis option is ignored if the `--high-level-code' option is not enabled.",
+% The --det-copy-out option is not yet documented,
+% because it is not yet tested and probably not very useful.
+%		"--det-copy-out",
+%		"\tSpecify whether to handle output arguments for det/semidet",
+%		"\tprocedures using return-by-value rather than pass-by-reference.",
+%		"\tThis option is ignored if the `--high-level-code' option is not enabled.",
+% The --nondet-copy-out option is not yet documented,
+% because it is probably not very useful except for IL,
+% where it is the default.
+%		"--nondet-copy-out\t\t(grades: il, ilc)",
+%		"\tSpecify whether to handle output arguments for nondet",
+%		"\tprocedures using pass-by-value rather than pass-by-reference.",
+%		"\tThis option is ignored if the `--high-level-code' option is not enabled.",
 		"--gc {none, conservative, accurate}",
 		"--garbage-collection {none, conservative, accurate}",
 		"\t\t\t\t(`.gc' grades use `--gc conservative',",
@@ -2295,6 +2360,16 @@
 		"--pred-value-number",
 		"\tExtend value numbering to entire predicates."
 	]).
+
+:- pred options_help_mlds_mlds_optimization(io__state::di, io__state::uo) is det.
+
+options_help_mlds_mlds_optimization -->
+	io__write_string("\n    MLDS -> MLDS optimizations:\n"),
+	write_tabbed_lines([
+		"--no-llds-optimize",
+		"\tDisable the MLDS->MLDS optimization passes."
+	]).
+
 
 :- pred options_help_rl_rl_optimization(io__state::di, io__state::uo) is det.
 
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.218
diff -u -r1.218 user_guide.texi
--- doc/user_guide.texi	2000/09/01 00:50:12	1.218
+++ doc/user_guide.texi	2000/09/04 03:06:46
@@ -1818,24 +1818,8 @@
 @sp 1
 By default, this command is strict, and it uses the default print level.
 @sp 1
- at item next [-NSans] [@var{num}]
-Continues execution until it reaches the next event of
-the @var{num}'th ancestor of the call to which the current event refers.
-The default value of @var{num} is zero,
-which means skipping to the next event of the current call.
-Reports an error if execution is already at the end of the specified call.
- at sp 1
-The options @samp{-n} or @samp{--none}, @samp{-s} or @samp{--some},
- at samp{-a} or @samp{--all} specify the print level to use
-for the duration of the command,
-while the options @samp{-S} or @samp{--strict}
-and @samp{-N} or @samp{--nostrict} specify
-the strictness of the command.
- at sp 1
-By default, this command is strict, and it uses the default print level.
- at sp 1
 @item finish [-NSans] [@var{num}]
-Continues execution until it reaches a final (EXIT, FAIL or EXCP) port of
+Continues execution until it reaches a final (EXIT or FAIL) port of
 the @var{num}'th ancestor of the call to which the current event refers.
 The default value of @var{num} is zero,
 which means skipping to the end of the current call.
@@ -2122,21 +2106,10 @@
 specify the action to be taken at the break point.
 @sp 1
 By default, the initial state of the break point is @samp{stop}.
- at item break [-AOPSaei] @var{proc-spec}
+ at item break [-PSaei] @var{proc-spec}
 @c <module name> <predicate name> [<arity> [<mode> [<predfunc>]]]
 Puts a break point on the specified procedure.
 @sp 1
-The options @samp{-A} or @samp{--select-all},
-and @samp{-O} or @samp{--select-one}
-select the action to be taken
-if the specification matches more than one procedure.
-If you have specified option @samp{-A} or @samp{--select-all},
-mdb will put a breakpoint on all matched procedures,
-whereas if you have specified option @samp{-O} or @samp{--select-one},
-mdb will report an error.
-By default, mdb will ask you whether you want to put a breakpoint
-on all matched procedures or just one, and if so, which one.
- at sp 1
 The options @samp{-P} or @samp{--print}, and @samp{-S} or @samp{--stop}
 specify the action to be taken at the break point,
 while the options @samp{-a} or @samp{--all},
@@ -2306,12 +2279,12 @@
 the debugger will substitute the given command and parameters for this word
 before executing the command line.
 @sp 1
-If @var{name} is the upper-case word @samp{EMPTY},
+If @var{command} is the upper-case word @samp{EMPTY},
 the debugger will substitute the given command and parameters
 whenever the user types in an empty command line.
 @sp 1
 @sp 1
-If @var{name} is the upper-case word @samp{NUMBER},
+If @var{command} is the upper-case word @samp{NUMBER},
 the debugger will insert the given command and parameters
 before the command line
 whenever the user types in a command line that consists of a single number.
@@ -3056,9 +3029,9 @@
 
 @sp 1
 @item -C
- at itemx --compile-to-c
- at itemx --compile-to-C
-Generate C code in @file{@var{module}.c}, but not object code.
+ at itemx --target-code-only
+Generate target code (i.e. C in @file{@var{module}.c},
+or IL in @file{@var{module}.il}, but not object code.
 
 @sp 1
 @item -c
@@ -3242,10 +3215,12 @@
 
 @sp 1
 @item --infer-types
-If there is no type declaration for a predicate or function,
-try to infer the type, rather than just reporting an error.
 
 @sp 1
+ at item --infer-all
+An abbreviation for @samp{--infer-types --infer-modes --infer-det}.
+
+ at sp 1
 @item --infer-modes
 If there is no mode declaration for a predicate,
 try to infer the modes, rather than just reporting an error.
@@ -3360,9 +3335,10 @@
 The set of aspects and their alternatives are:
 
 @table @asis
- at item What combination of GNU C extensions to use:
+ at item What target language to use, and (for C) what combination of GNU C extensions to use:
 @samp{none}, @samp{reg}, @samp{jump}, @samp{asm_jump},
- at samp{fast}, @samp{asm_fast}, and @samp{hlc} (the default is system dependent).
+ at samp{fast}, @samp{asm_fast}, @samp{hlc}, and @samp{ilc}
+(the default is system dependent).
 
 @item What garbage collection strategy to use:
 @samp{gc}, and @samp{agc} (the default is no garbage collection).
@@ -3402,25 +3378,28 @@
 @var{Options implied}.
 
 @item @samp{none}
- at code{--no-gcc-global-registers --no-gcc-nonlocal_gotos --no-asm-labels}.
+ at code{--target c --no-gcc-global-registers --no-gcc-nonlocal_gotos --no-asm-labels}.
 
 @item @samp{reg}
- at code{--gcc-global-registers --no-gcc-nonlocal_gotos --no-asm-labels}.
+ at code{--target c --gcc-global-registers --no-gcc-nonlocal_gotos --no-asm-labels}.
 
 @item @samp{jump}
- at code{--no-gcc-global-registers --gcc-nonlocal-gotos --no-asm-labels}.
+ at code{--target c --no-gcc-global-registers --gcc-nonlocal-gotos --no-asm-labels}.
 
 @item @samp{fast}
- at code{--gcc-global-registers --gcc-nonlocal-gotos --no-asm-labels}.
+ at code{--target c --gcc-global-registers --gcc-nonlocal-gotos --no-asm-labels}.
 
 @item @samp{asm_jump}
- at code{--no-gcc-global-registers --gcc-nonlocal-gotos --asm-labels}.
+ at code{--target c --no-gcc-global-registers --gcc-nonlocal-gotos --asm-labels}.
 
 @item @samp{asm_fast}
- at code{--gcc-global-registers --gcc-nonlocal_gotos --asm-labels}.
+ at code{--target c --gcc-global-registers --gcc-nonlocal_gotos --asm-labels}.
 
 @item @samp{hlc}
- at code{--high-level-code}.
+ at code{--target c --high-level-code}.
+
+ at item @samp{il}
+ at code{--target il --high-level-code}.
 
 @item @samp{.gc}
 @code{--gc conservative}.
@@ -3458,6 +3437,27 @@
 @end table
 
 @sp 1
+ at item @code{--target c} (grades: none, reg, jump, fast, asm_jump, asm_fast, hlc)
+ at itemx @code{--il}, @code{--target il} (grades: ilc)
+Specify the target language used for compilation: C or IL.
+C means ANSI/ISO C, optionally with GNU C extensions (see below).
+IL means the Microsoft COM+ 2.0 Intermediate Language.
+ at samp{--target il} implies @samp{--high-level-code}.
+
+ at sp 1
+ at item @code{--il-only}
+An abbreviation for @samp{--target il --target-code-only}.
+Generate IL assembler code in @file{@var{module}.il}, but do not invoke
+ilasm to produce IL object code.
+
+ at sp 1
+ at item @code{--compile-to-c}
+ at itemx @code{--compile-to-C}
+An abbreviation for @samp{--target c --target-code-only}.
+Generate C code in @file{@var{module}.c}, but do not invoke the
+C compiler to generate object code.
+
+ at sp 1
 @item @code{--gcc-global-registers} (grades: reg, fast, asm_fast)
 @itemx @code{--no-gcc-global-registers} (grades: none, jump, asm_jump)
 Specify whether or not to use GNU C's global register variables extension.
@@ -3477,9 +3477,9 @@
 This option is ignored if the @samp{--high-level-code} option is enabled.
 
 @sp 1
- at item @code{-H}, @code{--high-level-code} (grades: hlc)
-Use an alternative back-end that generates high-level C code
-rather than the very low-level C code that is generated by our
+ at item @code{-H}, @code{--high-level-code} (grades: hlc, ilc)
+Use an alternative back-end that generates high-level code
+rather than the very low-level code that is generated by our
 original back-end.
 
 @sp 1
Index: scripts/final_grade_options.sh-subr
===================================================================
RCS file: /home/mercury1/repository/mercury/scripts/final_grade_options.sh-subr,v
retrieving revision 1.4
diff -u -r1.4 final_grade_options.sh-subr
--- scripts/final_grade_options.sh-subr	2000/02/08 15:32:35	1.4
+++ scripts/final_grade_options.sh-subr	2000/09/04 12:47:55
@@ -39,6 +39,13 @@
 esac
 
 #
+# IL implies --high-level-code
+#
+case $target in il)
+	highlevel_code=true ;;
+esac
+
+#
 # --high-level-code disables the use of low-level gcc extensions
 #
 case $highlevel_code in true)
Index: scripts/init_grade_options.sh-subr
===================================================================
RCS file: /home/mercury1/repository/mercury/scripts/init_grade_options.sh-subr,v
retrieving revision 1.11
diff -u -r1.11 init_grade_options.sh-subr
--- scripts/init_grade_options.sh-subr	2000/05/24 05:18:30	1.11
+++ scripts/init_grade_options.sh-subr	2000/09/04 12:47:55
@@ -23,6 +23,8 @@
 grade_usage="\
 Grade options:
 	-s <grade>, --grade <grade>
+	--target {il, c}
+	--il
 	--asm-labels
 	--gcc-non-local-gotos
 	--gcc-global-registers
@@ -47,6 +49,7 @@
 # --high-level is not yet documented because --high-level-data is
 #		not yet implemented
 
+target=c
 highlevel_code=false
 highlevel_data=false
 gcc_nested_functions=false
Index: scripts/parse_grade_options.sh-subr
===================================================================
RCS file: /home/mercury1/repository/mercury/scripts/parse_grade_options.sh-subr,v
retrieving revision 1.16
diff -u -r1.16 parse_grade_options.sh-subr
--- scripts/parse_grade_options.sh-subr	2000/05/24 05:03:04	1.16
+++ scripts/parse_grade_options.sh-subr	2000/09/04 12:47:55
@@ -19,6 +19,23 @@
 #
 #---------------------------------------------------------------------------#
 
+	--target)
+		shift
+		case "$1" in
+			c|C)
+				target=c ;;
+			il|IL)
+				target=il ;;
+			*)
+				echo "$0: invalid target \`$1'" 1>&2
+				exit 1
+				;;
+		esac
+		;;
+
+	--il|--IL)
+		target=il ;;
+
 	--high-level-code|-H)
 		highlevel_code=true ;;
 	--no-high-level-code|-H-)
@@ -148,6 +165,7 @@
 		# may also require changes to all the files indicated by
 		# runtime/mercury_grade.h.
 
+		target=c
 		highlevel_code=false
 		gcc_nested_functions=false
 		highlevel_data=false
@@ -170,7 +188,26 @@
 		for grade_piece in $grade_pieces
 		do
 			case "$grade_piece" in
+				il)
+					target=il
+					asm_labels=false
+					non_local_gotos=false
+					global_regs=false
+					highlevel_code=true
+					gcc_nested_functions=false
+					highlevel_data=true
+					;;
+				ilc)
+					target=il
+					asm_labels=false
+					non_local_gotos=false
+					global_regs=false
+					highlevel_code=true
+					gcc_nested_functions=false
+					highlevel_data=false
+					;;
 				hl)
+					target=c
 					asm_labels=false
 					non_local_gotos=false
 					global_regs=false
@@ -179,6 +216,7 @@
 					highlevel_data=true
 					;;
 				hlc)
+					target=c
 					asm_labels=false
 					non_local_gotos=false
 					global_regs=false
@@ -187,6 +225,7 @@
 					highlevel_data=false
 					;;
 				hl_nest)
+					target=c
 					asm_labels=false
 					non_local_gotos=false
 					global_regs=false
@@ -195,6 +234,7 @@
 					highlevel_data=true
 					;;
 				hlc_nest)
+					target=c
 					asm_labels=false
 					non_local_gotos=false
 					global_regs=false
@@ -203,6 +243,7 @@
 					highlevel_data=false
 					;;
 				asm_fast)
+					target=c
 					asm_labels=true
 					non_local_gotos=true
 					global_regs=true
@@ -211,6 +252,7 @@
 					highlevel_data=false
 					;;
 				asm_jump)
+					target=c
 					asm_labels=true
 					non_local_gotos=true
 					global_regs=false
@@ -219,6 +261,7 @@
 					highlevel_data=false
 					;;
 				fast)
+					target=c
 					asm_labels=false
 					non_local_gotos=true
 					global_regs=true
@@ -227,6 +270,7 @@
 					highlevel_data=false
 					;;
 				jump)
+					target=c
 					asm_labels=false
 					non_local_gotos=true
 					global_regs=false
@@ -235,6 +279,7 @@
 					highlevel_data=false
 					;;
 				reg)
+					target=c
 					asm_labels=false
 					non_local_gotos=false
 					global_regs=true
@@ -243,6 +288,7 @@
 					highlevel_data=false
 					;;
 				none)
+					target=c
 					asm_labels=false
 					non_local_gotos=false
 					global_regs=false


-- 
       Tyson Dowd           # 
                            #  Surreal humour isn't everyone's cup of fur.
     trd at cs.mu.oz.au        # 
http://www.cs.mu.oz.au/~trd #
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list