[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