[m-dev.] for review: handle `:- external' in MLDS back-end
Fergus Henderson
fjh at cs.mu.OZ.AU
Sun Dec 10 01:16:58 AEDT 2000
----------
Estimated hours taken: 3
Fix the handling of procedures declared `:- external' for the MLDS back-end.
This change fixes some problems that broke many of the test cases in
tests/valid in the hl*prof* grades.
compiler/hlds_pred.m:
Add `external' as a new import_status, rather than using
`imported'.
compiler/assertion.m:
compiler/higher_order.m:
compiler/hlds_out.m:
compiler/hlds_pred.m:
compiler/intermod.m:
compiler/make_hlds.m:
Minor changes to handle the new import_status.
compiler/mlds.m:
Add a comment about the handling of procedures declared
`:- external'.
compiler/ml_code_gen.m:
Generate MLDS function definitions, with no function body,
for procedures declared `external'.
compiler/mlds_to_c.m:
Declare private functions with no function body as `extern'
rather than `static'.
Workspace: /home/pgrad/fjh/ws/hg
Index: compiler/assertion.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/assertion.m,v
retrieving revision 1.9
diff -u -d -r1.9 assertion.m
--- compiler/assertion.m 2000/11/17 17:46:53 1.9
+++ compiler/assertion.m 2000/12/09 10:44:56
@@ -830,8 +830,10 @@
is_defined_in_implementation_section(exported_to_submodules, yes).
is_defined_in_implementation_section(local, yes).
is_defined_in_implementation_section(imported(implementation), yes).
+is_defined_in_implementation_section(external(implementation), yes).
is_defined_in_implementation_section(imported(interface), no).
+is_defined_in_implementation_section(external(interface), no).
is_defined_in_implementation_section(opt_imported, no).
is_defined_in_implementation_section(abstract_imported, no).
is_defined_in_implementation_section(pseudo_imported, no).
Index: compiler/higher_order.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/higher_order.m,v
retrieving revision 1.82
diff -u -d -r1.82 higher_order.m
--- compiler/higher_order.m 2000/11/17 17:47:15 1.82
+++ compiler/higher_order.m 2000/12/09 10:48:18
@@ -1202,6 +1202,7 @@
% specialize any higher-order arguments. We may be
% able to do user guided type specialization.
CalleeStatus \= imported(_),
+ CalleeStatus \= external(_),
type_is_higher_order(CalleeArgType, _, _, _)
;
true
Index: compiler/hlds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_out.m,v
retrieving revision 1.252
diff -u -d -r1.252 hlds_out.m
--- compiler/hlds_out.m 2000/12/06 06:05:01 1.252
+++ compiler/hlds_out.m 2000/12/09 10:49:41
@@ -2282,6 +2282,10 @@
io__write_string("imported in the interface").
hlds_out__write_import_status(imported(implementation)) -->
io__write_string("imported in the implementation").
+hlds_out__write_import_status(external(interface)) -->
+ io__write_string("external (and exported)").
+hlds_out__write_import_status(external(implementation)) -->
+ io__write_string("external (and local)").
hlds_out__write_import_status(abstract_imported) -->
io__write_string("abstract_imported").
hlds_out__write_import_status(opt_imported) -->
Index: compiler/hlds_pred.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_pred.m,v
retrieving revision 1.88
diff -u -d -r1.88 hlds_pred.m
--- compiler/hlds_pred.m 2000/12/06 06:05:04 1.88
+++ compiler/hlds_pred.m 2000/12/09 10:41:16
@@ -258,9 +258,11 @@
% Only types can have status abstract_exported or abstract_imported.
:- type import_status
- ---> imported(section)
+ ---> external(section)
+ % declared `external',
+ % i.e. defined in some other language
+ ; imported(section)
% defined in the interface of some other module
- % or `external' (in some other language)
; opt_imported % defined in the optimization
% interface of another module
; abstract_imported % describes a type with only an abstract
@@ -747,6 +749,7 @@
invalid_proc_id(-1).
status_is_exported(imported(_), no).
+status_is_exported(external(_), no).
status_is_exported(abstract_imported, no).
status_is_exported(pseudo_imported, no).
status_is_exported(opt_imported, no).
@@ -761,6 +764,7 @@
bool__not(InThisModule, Imported).
status_defined_in_this_module(imported(_), no).
+status_defined_in_this_module(external(_), no).
status_defined_in_this_module(abstract_imported, no).
status_defined_in_this_module(pseudo_imported, no).
status_defined_in_this_module(opt_imported, no).
@@ -916,6 +920,8 @@
pred_info_import_status(PredInfo, ImportStatus),
( ImportStatus = imported(_) ->
ProcIds = []
+ ; ImportStatus = external(_) ->
+ ProcIds = []
; ImportStatus = pseudo_imported ->
pred_info_procids(PredInfo, ProcIds0),
% for pseduo_imported preds, procid 0 is imported
@@ -972,7 +978,10 @@
pred_info_import_status(PredInfo, PredInfo^import_status).
pred_info_is_imported(PredInfo) :-
- pred_info_import_status(PredInfo, imported(_)).
+ pred_info_import_status(PredInfo, Status),
+ ( Status = imported(_)
+ ; Status = external(_)
+ ).
pred_info_is_pseudo_imported(PredInfo) :-
pred_info_import_status(PredInfo, ImportStatus),
@@ -1004,10 +1013,10 @@
status_is_exported(PredInfo0^import_status, Exported),
(
Exported = yes,
- PredInfo = PredInfo0^import_status := imported(interface)
+ PredInfo = PredInfo0^import_status := external(interface)
;
Exported = no,
- PredInfo = PredInfo0^import_status := imported(implementation)
+ PredInfo = PredInfo0^import_status := external(implementation)
).
pred_info_set_import_status(PredInfo, X, PredInfo^import_status := X).
Index: compiler/intermod.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/intermod.m,v
retrieving revision 1.89
diff -u -d -r1.89 intermod.m
--- compiler/intermod.m 2000/11/17 17:47:28 1.89
+++ compiler/intermod.m 2000/12/09 10:54:34
@@ -651,7 +651,7 @@
% calls a predicate which is exported, then we don't
% need to do anything special.
%
- { Status = exported }
+ { Status = exported ; Status = external(interface) }
->
{ DoWrite = yes }
;
@@ -672,7 +672,7 @@
% we need to put the declaration for the called predicate
% in the `.opt' file.
%
- { Status = local }
+ { Status = local ; Status = external(implementation) }
->
{ DoWrite = yes },
intermod_info_get_pred_decls(PredDecls0),
@@ -683,31 +683,14 @@
; Status = opt_imported
}
->
+ %
+ % imported pred - add import for module
+ %
{ DoWrite = yes },
- { module_info_name(ModuleInfo, ThisModule) },
{ pred_info_module(PredInfo, PredModule) },
- (
- { PredModule = ThisModule }
- ->
- %
- % This can happen in the case of a local predicate
- % which has been declared as external using a
- % `:- external(Name/Arity)' declaration, e.g.
- % because it is implemented as low-level C code.
- %
- % We treat these the same as local predicates.
- %
- intermod_info_get_pred_decls(PredDecls0),
- { set__insert(PredDecls0, PredId, PredDecls) },
- intermod_info_set_pred_decls(PredDecls)
- ;
- %
- % imported pred - add import for module
- %
- intermod_info_get_modules(Modules0),
- { set__insert(Modules0, PredModule, Modules) },
- intermod_info_set_modules(Modules)
- )
+ intermod_info_get_modules(Modules0),
+ { set__insert(Modules0, PredModule, Modules) },
+ intermod_info_set_modules(Modules)
;
{ error("intermod__add_proc: unexpected status") }
).
Index: compiler/make_hlds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make_hlds.m,v
retrieving revision 1.359
diff -u -d -r1.359 make_hlds.m
--- compiler/make_hlds.m 2000/11/17 17:47:42 1.359
+++ compiler/make_hlds.m 2000/12/09 10:59:30
@@ -1911,7 +1911,7 @@
( combine_status_2(StatusA, StatusB, CombinedStatus) ->
Status = CombinedStatus
;
- error("pseudo_imported or pseudo_exported type definition")
+ error("unexpected status for type definition")
).
:- pred combine_status_2(import_status, import_status, import_status).
Index: compiler/ml_code_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_code_gen.m,v
retrieving revision 1.68
diff -u -d -r1.68 ml_code_gen.m
--- compiler/ml_code_gen.m 2000/11/23 04:32:43 1.68
+++ compiler/ml_code_gen.m 2000/12/09 14:09:03
@@ -876,10 +876,11 @@
{ PredIds0 = [PredId|PredIds] }
->
{ map__lookup(PredTable, PredId, PredInfo) },
- ( { pred_info_is_imported(PredInfo) } ->
+ { pred_info_import_status(PredInfo, ImportStatus) },
+ ( { ImportStatus = imported(_) } ->
{ MLDS_Defns1 = MLDS_Defns0 }
;
- ml_gen_pred(ModuleInfo, PredId, PredInfo,
+ ml_gen_pred(ModuleInfo, PredId, PredInfo, ImportStatus,
MLDS_Defns0, MLDS_Defns1)
),
ml_gen_preds_2(ModuleInfo, PredIds, PredTable,
@@ -891,12 +892,17 @@
% Generate MLDS definitions for all the non-imported
% procedures of a given predicate (or function).
%
-:- pred ml_gen_pred(module_info, pred_id, pred_info,
- mlds__defns, mlds__defns, io__state, io__state).
-:- mode ml_gen_pred(in, in, in, in, out, di, uo) is det.
+:- pred ml_gen_pred(module_info, pred_id, pred_info, import_status,
+ mlds__defns, mlds__defns, io__state, io__state).
+:- mode ml_gen_pred(in, in, in, in, in, out, di, uo) is det.
-ml_gen_pred(ModuleInfo, PredId, PredInfo, MLDS_Defns0, MLDS_Defns) -->
- { pred_info_non_imported_procids(PredInfo, ProcIds) },
+ml_gen_pred(ModuleInfo, PredId, PredInfo, ImportStatus,
+ MLDS_Defns0, MLDS_Defns) -->
+ ( { ImportStatus = external(_) } ->
+ { pred_info_procids(PredInfo, ProcIds) }
+ ;
+ { pred_info_non_imported_procids(PredInfo, ProcIds) }
+ ),
( { ProcIds = [] } ->
{ MLDS_Defns = MLDS_Defns0 }
;
@@ -993,6 +999,7 @@
ml_gen_proc_defn(ModuleInfo, PredId, ProcId, MLDS_ProcDefnBody, ExtraDefns) :-
module_info_pred_proc_info(ModuleInfo, PredId, ProcId,
PredInfo, ProcInfo),
+ pred_info_import_status(PredInfo, ImportStatus),
pred_info_arg_types(PredInfo, ArgTypes),
proc_info_interface_code_model(ProcInfo, CodeModel),
proc_info_headvars(ProcInfo, HeadVars),
@@ -1018,65 +1025,83 @@
MLDSGenInfo0 = ml_gen_info_init(ModuleInfo, PredId, ProcId),
MLDS_Params = ml_gen_proc_params(ModuleInfo, PredId, ProcId),
- % Set up the initial success continuation, if any.
- % Also figure out which output variables are returned by
- % value (rather than being passed by reference) and remove
- % them from the byref_output_vars field in the ml_gen_info.
- ( CodeModel = model_non ->
- ml_set_up_initial_succ_cont(ModuleInfo, CopiedOutputVars,
- MLDSGenInfo0, MLDSGenInfo1)
+ ( ImportStatus = external(_) ->
+ %
+ % For Mercury procedures declared `:- external', we generate
+ % an MLDS definition for them with no function body.
+ % The MLDS -> target code pass can treat this accordingly,
+ % e.g. for C it outputs a function declaration with no
+ % corresponding definition, making sure that the function
+ % is declared as `extern' rather than `static'.
+ %
+ MaybeStatement = no,
+ ExtraDefns = []
;
- (
- is_output_det_function(ModuleInfo, PredId, ProcId,
- ResultVar)
- ->
- CopiedOutputVars = [ResultVar],
- ml_gen_info_get_byref_output_vars(MLDSGenInfo0,
- ByRefOutputVars0),
- list__delete_all(ByRefOutputVars0,
- ResultVar, ByRefOutputVars),
- ml_gen_info_set_byref_output_vars(ByRefOutputVars,
- MLDSGenInfo0, MLDSGenInfo1)
+ % XXX FIXME wrap long lines
+ % Set up the initial success continuation, if any.
+ % Also figure out which output variables are returned by
+ % value (rather than being passed by reference) and remove
+ % them from the byref_output_vars field in the ml_gen_info.
+ ( CodeModel = model_non ->
+ ml_set_up_initial_succ_cont(ModuleInfo,
+ CopiedOutputVars, MLDSGenInfo0, MLDSGenInfo1)
;
- CopiedOutputVars = [],
- MLDSGenInfo1 = MLDSGenInfo0
- )
- ),
+ (
+ is_output_det_function(ModuleInfo, PredId,
+ ProcId, ResultVar)
+ ->
+ CopiedOutputVars = [ResultVar],
+ ml_gen_info_get_byref_output_vars(MLDSGenInfo0,
+ ByRefOutputVars0),
+ list__delete_all(ByRefOutputVars0,
+ ResultVar, ByRefOutputVars),
+ ml_gen_info_set_byref_output_vars(
+ ByRefOutputVars,
+ MLDSGenInfo0, MLDSGenInfo1)
+ ;
+ CopiedOutputVars = [],
+ MLDSGenInfo1 = MLDSGenInfo0
+ )
+ ),
- % This would generate all the local variables at the top of the
- % function:
- % 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,
- % plus locals for any output arguments that are returned by value
- % (e.g. if --nondet-copy-out is enabled, or for det function return
- % values).
- MLDS_Context = mlds__make_context(Context),
- ( CopiedOutputVars = [] ->
- % optimize common case
- OutputVarLocals = []
- ;
- proc_info_varset(ProcInfo, VarSet),
- proc_info_vartypes(ProcInfo, VarTypes),
- % note that for headvars we must use the types from
- % the procedure interface, not from the procedure body
- HeadVarTypes = map__from_corresponding_lists(HeadVars,
- ArgTypes),
- OutputVarLocals = ml_gen_local_var_decls(VarSet,
- map__overlay(VarTypes, HeadVarTypes),
- MLDS_Context, ModuleInfo, CopiedOutputVars)
+ % This would generate all the local variables at the top of
+ % the function:
+ % 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, plus locals
+ % for any output arguments that are returned by value
+ % (e.g. if --nondet-copy-out is enabled, or for det function
+ % return values).
+ MLDS_Context = mlds__make_context(Context),
+ ( CopiedOutputVars = [] ->
+ % optimize common case
+ OutputVarLocals = []
+ ;
+ proc_info_varset(ProcInfo, VarSet),
+ proc_info_vartypes(ProcInfo, VarTypes),
+ % note that for headvars we must use the types from
+ % the procedure interface, not from the procedure body
+ HeadVarTypes = map__from_corresponding_lists(HeadVars,
+ ArgTypes),
+ OutputVarLocals = ml_gen_local_var_decls(VarSet,
+ map__overlay(VarTypes, HeadVarTypes),
+ MLDS_Context, ModuleInfo, CopiedOutputVars)
+ ),
+ MLDS_LocalVars = [ml_gen_succeeded_var_decl(MLDS_Context) |
+ OutputVarLocals],
+ ml_gen_proc_body(CodeModel, HeadVars, ArgTypes,
+ CopiedOutputVars, Goal,
+ MLDS_Decls0, MLDS_Statements,
+ MLDSGenInfo1, MLDSGenInfo),
+ ml_gen_info_get_extra_defns(MLDSGenInfo, ExtraDefns),
+ MLDS_Decls = list__append(MLDS_LocalVars, MLDS_Decls0),
+ MLDS_Statement = ml_gen_block(MLDS_Decls, MLDS_Statements,
+ Context),
+ MaybeStatement = yes(MLDS_Statement)
),
- MLDS_LocalVars = [ml_gen_succeeded_var_decl(MLDS_Context) |
- OutputVarLocals],
- ml_gen_proc_body(CodeModel, HeadVars, ArgTypes, CopiedOutputVars, Goal,
- MLDS_Decls0, MLDS_Statements,
- MLDSGenInfo1, MLDSGenInfo),
- ml_gen_info_get_extra_defns(MLDSGenInfo, ExtraDefns),
- MLDS_Decls = list__append(MLDS_LocalVars, MLDS_Decls0),
- MLDS_Statement = ml_gen_block(MLDS_Decls, MLDS_Statements, Context),
MLDS_ProcDefnBody = mlds__function(yes(proc(PredId, ProcId)),
- MLDS_Params, yes(MLDS_Statement)).
+ MLDS_Params, MaybeStatement).
:- pred ml_set_up_initial_succ_cont(module_info, list(prog_var),
ml_gen_info, ml_gen_info).
Index: compiler/mlds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds.m,v
retrieving revision 1.43
diff -u -d -r1.43 mlds.m
--- compiler/mlds.m 2000/11/21 13:37:41 1.43
+++ compiler/mlds.m 2000/12/09 11:29:47
@@ -404,6 +404,10 @@
mlds__func_params, % the arguments & return types
maybe(mlds__statement) % the function body, or `no'
% if the function is abstract
+ % or if the function is defined
+ % externally (i.e. the original
+ % Mercury procedure was declared
+ % `:- external').
)
% packages, classes, interfaces, structs, enums
; mlds__class(
Index: compiler/mlds_to_c.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_c.m,v
retrieving revision 1.72
diff -u -d -r1.72 mlds_to_c.m
--- compiler/mlds_to_c.m 2000/12/03 02:22:38 1.72
+++ compiler/mlds_to_c.m 2000/12/09 13:55:41
@@ -827,7 +827,7 @@
% Now output the declaration for this mlds__defn.
%
mlds_indent(Context, Indent),
- mlds_output_decl_flags(Flags, forward_decl, Name),
+ mlds_output_decl_flags(Flags, forward_decl, Name, DefnBody),
mlds_output_decl_body(Indent, qual(ModuleName, Name), Context,
DefnBody)
).
@@ -907,7 +907,7 @@
[]
),
mlds_indent(Context, Indent),
- mlds_output_decl_flags(Flags, definition, Name),
+ mlds_output_decl_flags(Flags, definition, Name, DefnBody),
mlds_output_defn_body(Indent, qual(ModuleName, Name), Context,
DefnBody).
@@ -1753,10 +1753,10 @@
; definition.
:- pred mlds_output_decl_flags(mlds__decl_flags, decl_or_defn,
- mlds__entity_name, io__state, io__state).
-:- mode mlds_output_decl_flags(in, in, in, di, uo) is det.
+ mlds__entity_name, mlds__entity_defn, io__state, io__state).
+:- mode mlds_output_decl_flags(in, in, in, in, di, uo) is det.
-mlds_output_decl_flags(Flags, DeclOrDefn, Name) -->
+mlds_output_decl_flags(Flags, DeclOrDefn, Name, DefnBody) -->
%
% mlds_output_extern_or_static handles both the
% `access' and the `per_instance' fields of the mlds__decl_flags.
@@ -1770,7 +1770,7 @@
mlds_output_access_comment(access(Flags)),
mlds_output_per_instance_comment(per_instance(Flags)),
mlds_output_extern_or_static(access(Flags), per_instance(Flags),
- DeclOrDefn, Name),
+ DeclOrDefn, Name, DefnBody),
mlds_output_virtuality(virtuality(Flags)),
mlds_output_finality(finality(Flags)),
mlds_output_constness(constness(Flags)),
@@ -1813,13 +1813,17 @@
mlds_output_per_instance_comment_2(one_copy) --> io__write_string("/* one_copy */ ").
:- pred mlds_output_extern_or_static(access, per_instance, decl_or_defn,
- mlds__entity_name, io__state, io__state).
-:- mode mlds_output_extern_or_static(in, in, in, in, di, uo) is det.
+ mlds__entity_name, mlds__entity_defn, io__state, io__state).
+:- mode mlds_output_extern_or_static(in, in, in, in, in, di, uo) is det.
-mlds_output_extern_or_static(Access, PerInstance, DeclOrDefn, Name) -->
- (
+mlds_output_extern_or_static(Access, PerInstance, DeclOrDefn, Name, DefnBody)
+ -->
+ (
{ Access = private ; PerInstance = one_copy },
- { Name \= type(_, _) }
+ { Name \= type(_, _) },
+ % Don't output "static" for functions that don't have a body.
+ % This can happen for Mercury procedures declared `:- external'
+ { DefnBody \= mlds__function(_, _, no) }
->
io__write_string("static ")
;
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
| of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
--------------------------------------------------------------------------
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