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

Tyson Dowd trd at cs.mu.OZ.AU
Tue Sep 5 15:40:47 AEDT 2000


I've addressed fjh's comments, here is the incremental diff (mostly
removing stuff I didn't intend to commit just yet).

Below that is a full diff (which Peter Ross might find useful to
review).

--- compiler/globals.m
+++ compiler/globals.m
@@ -27 +27 @@
-			% IL is the Microsoft COM+ 2.0 Intermediate Language
+			% IL is the Microsoft .NET Intermediate Language
--- compiler/mercury_compile.m
+++ compiler/mercury_compile.m
@@ -481,15 +480,0 @@
-	% 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
-	).
-
--- compiler/ml_call_gen.m
+++ compiler/ml_call_gen.m
@@ -86 +86,5 @@
-	% XXX document this
+        % Generate the appropriate MLDS type for a continuation function
+        % for a nondet procedure whose output arguments have the
+        % specified types.
+        % 
+        %
--- compiler/ml_code_gen.m
+++ compiler/ml_code_gen.m
@@ -1874,4 +1873,0 @@
-	=(MLDSGenInfo),
-	{ ml_gen_info_get_module_info(MLDSGenInfo, ModuleInfo) },
-	{ module_info_globals(ModuleInfo, Globals) },
-	{ globals__lookup_string_option(Globals, target, Target) },
@@ -1879,8 +1875 @@
-		(
-			{ Target = "il" }
-		->
-			ml_gen_call_current_success_cont_indirectly(Context,
-				CallCont)
-		;
-			ml_gen_call_current_success_cont(Context, CallCont)
-		)
+		ml_gen_call_current_success_cont(Context, CallCont)
--- compiler/ml_code_util.m
+++ compiler/ml_code_util.m
@@ -340 +340,3 @@
-	% XXX need to update this documentation
+	% The output variable lvals and types need to be supplied when
+	% generating a continuation using --nondet-copy-out, otherwise
+	% they should be empty.
@@ -353,9 +354,0 @@
-	% 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.
-
@@ -1123 +1115,0 @@
-		{ dummy_call },
@@ -1144,3 +1135,0 @@
-:- pred dummy_call is det.
-dummy_call.
-
@@ -1350,11 +1338,0 @@
-	% Return rvals for 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.
-	% The `cont' argument is a continuation function that
-	% will be called when a model_non goal succeeds.
-	% The `cont_env' argument is a pointer to the environment (set
-	% of local variables in the containing procedure) for the continuation
-	% function.  (If we're using gcc nested function, the `cont_env'
-	% is not used.)
-	%
@@ -1416,81 +1393,0 @@
-
-	% 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")
-	}.
--- compiler/ml_unify_gen.m
+++ compiler/ml_unify_gen.m
@@ -417 +417 @@
-	{ ClosureLayoutRval = const(null(ClosureLayoutType)) },
+	{ ClosureLayoutRval = const(int_const(0)) }, 
--- compiler/mlds.m
+++ compiler/mlds.m
@@ -1093,6 +1093 @@
-	;	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).
+	;	data_addr_const(mlds__data_addr).
--- compiler/mlds_to_c.m
+++ compiler/mlds_to_c.m
@@ -2768,2 +2767,0 @@
-mlds_output_rval_const(null(_)) -->
-	io__write_string("NULL").




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


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 for model_det/model_semi procedures by
	reference, or whether to just return multiple values.
	Use the `--nondet-copy-out' option to decide whether to pass
	output arguments for model_non procedures 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/05 02:32:23
@@ -21,6 +21,13 @@
 
 :- type globals.
 
+:- type compilation_target
+	--->	c	% Generate C code
+	;	il	% Generate IL assembler code
+			% IL is the Microsoft .NET 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/05 02:32:42
@@ -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,
@@ -2195,8 +2196,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 +2391,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/05 02:33:21
@@ -83,6 +83,16 @@
 :- mode ml_gen_box_or_unbox_lval(in, in, in, in, in, out, out, out, out,
 		in, out) is det.
 
+        % Generate the appropriate MLDS type for a continuation function
+        % for a nondet procedure whose output arguments have the
+        % specified types.
+        % 
+        %
+:- 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 +100,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 +141,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 +201,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 +216,7 @@
 	%
 	{ ObjectRval = no },
 	{ DoGenCall = ml_gen_mlds_call(Signature, ObjectRval, FuncRval,
-		[ClosureRval | InputRvals], OutputLvals,
+		[ClosureRval | InputRvals], OutputLvals, OutputTypes,
 		CodeModel, Context) },
 
 	( { ConvArgDecls = [], ConvOutputStatements = [] } ->
@@ -300,8 +312,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 +325,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 +359,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 +421,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 +536,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 +554,7 @@
 	->
 		{ InputRvals = [] },
 		{ OutputLvals = [] },
+		{ OutputTypes = [] },
 		{ ConvDecls = [] },
 		{ ConvOutputStatements = [] }
 	;
@@ -440,17 +565,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 +600,7 @@
 				VarRval, ArgRval),
 			{ InputRvals = [ArgRval | InputRvals1] },
 			{ OutputLvals = OutputLvals1 },
+			{ OutputTypes = OutputTypes1 },
 			{ ConvDecls = ConvDecls1 },
 			{ ConvOutputStatements = ConvOutputStatements1 }
 		;
@@ -486,25 +615,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/05 02:46:47
@@ -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 | LocalVarDecls] },
+		{ MLDS_Statements = [TryCommitStatement] },
 
-		{ MLDS_Decls = [CommitRefDecl, SuccessFunc] },
-		{ 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.
@@ -2391,7 +2545,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 +2562,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/05 02:44:28
@@ -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,13 @@
 	% of local variables in the containing procedure) for the continuation
 	% function.  (If we're using gcc nested function, the `cont_env'
 	% is not used.)
+	% The output variable lvals and types need to be supplied when
+	% generating a continuation using --nondet-copy-out, otherwise
+	% they should be empty.
 	%
-:- 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.
@@ -376,6 +391,15 @@
 :- 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 +439,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 +500,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 +522,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 +550,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 +580,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 +698,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 +709,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 +836,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 +874,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 +976,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 +985,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))) }.
@@ -1262,42 +1336,55 @@
 
 %-----------------------------------------------------------------------------%
 
-	% Return rvals for 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.
-	% The `cont' argument is a continuation function that
-	% will be called when a model_non goal succeeds.
-	% The `cont_env' argument is a pointer to the environment (set
-	% of local variables in the containing procedure) for the continuation
-	% 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,
@@ -1333,9 +1420,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 +1462,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 +1505,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 +1545,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 +1562,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 +1571,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 +1617,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/05 02:51:26
@@ -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(int_const(0)) }, 
 
 	%
 	% 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/05 00:52:25
@@ -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.
 	.
 
 	%
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/05 02:01:37
@@ -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))) },
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