[m-rev.] for review: improve procname mangling for .NET backend.
Tyson Dowd
trd at cs.mu.OZ.AU
Wed May 9 23:24:18 AEST 2001
On 09-May-2001, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> On 09-May-2001, Tyson Dowd <trd at cs.mu.OZ.AU> wrote:
> > Index: compiler/mlds_to_il.m
> ...
> > + %
> > + % We mangle as follows:
> > + % - Problem:
> > + % Two preds or funcs with different arities in Mercury end
> > + % up having the same types and arities in IL.
>
> I suggest adding a bit more here to explain why that can happen, e.g.
>
> % Two preds or funcs with different arities in Mercury end
> % up having the same types and arities in IL, e.g. because
> % one of them takes io__state arguments which get omitted
> % in IL.
Done.
>
> > + % - Problem:
> > + % A semidet pred returns its success value, and so has
> > + % the same return type (bool) as a function.
> > + %
> > + % To avoid this, we mangle all semidet preds and
> > + % functions to include whether they are a pred or a
> > + % function using _p or _f.
>
> The spec is not clear here: do you mean to mangle all functions
> or just semidet functions? The code below just mangles semidet
> functions, but that's wrong, because the clash you're thinking of
> here occurs when you have a det function and a semidet predicate, e.g.
>
> :- func foo(int) = bool
> :- pred foo(int::in) is semidet.
> % both map to `bool foo_1(int)'
I thought the code mangled semidet predicates *and* functions.
Which is more than it needs to do.
Actually the case for the clash here is a bit more complex. The pred
and function will differ in arity by 1 (foo_1_p and foo_2 above).
So you need to find a case where they have the same arity in the source,
which will of course mean that their IL type signatures will be of
different arity (being a semidet pred adds one to your IL arity).
:- func foo(int) = bool
:- pred foo(int::in) is semidet.
map to 'bool foo_2(int)' and 'bool foo_1(int)'
:- func foo(int) = bool
:- pred foo(int::in, int::in) is semidet.
map to 'bool foo_2(int)' and 'bool foo_2(int, int)'
However, if a dummy argument is removed, or arguments are added, then we
have trouble.
:- func foo(int) = bool
:- pred foo(int::in, io__state::di) is semidet.
map to 'bool foo_2(int)' and 'bool foo_2(int)'
Actually, it might be fruitful to only add the _arity if the predicate
has dummy arguments removed or type_info arguments added. In all other
cases it should be safe to leave the arity off.
But we should think about this one.
>
> Anyway, to avoid a collision, you only need to mangle one of the two
> clashing identifiers; so you could just mangle semidet preds, and leave
> the functions alone. I think that would be a nicer approach.
That's fine too.
>
> However, there is another problem which you didn't mention.
> The same thing can occur for predicates which are not semidet:
>
> :- func foo(int::out) = (int::in) is det.
> :- pred foo(int::out, int::in) is det.
> % both map to `void foo_2(int &, int)'
>
> That needs to be fixed.
Ok, so non-default mode funcs should be mangled with _f.
> I think that it may be possible to have conflicts with user names
> in the case where there is a <modulename>. However, this is a minor
> issue; it's probably OK to just XXX it for now.
Ok, no problems.
Here's an incremental diff that addresses these problems.
--- zzlog.mangling2 Wed May 9 01:50:03 2001
+++ zzlog.mangling4 Wed May 9 23:22:36 2001
@@ -10,11 +10,12 @@
compiler/mlds.m:
compiler/mlds_to_c.m:
compiler/mlds_to_java.m:
- Add the code_model to the proc_label.
+ Add the code_model and a boolean indicating whether this
+ function has a non-default (in, in, in, out) mode to the proc_label.
compiler/mlds_to_il.m:
Mangle much more carefully. We still mangle in a predictable,
context-insensitive manner, however we take advantage of the
- .NET backend to avoid name clashes in most cases.
-
+ overloading available in the .NET backend to avoid name clashes
+ in most cases.
diff -u compiler/ml_code_util.m compiler/ml_code_util.m
--- compiler/ml_code_util.m
+++ compiler/ml_code_util.m
@@ -1183,7 +1183,7 @@
ml_gen_pred_label_from_rtti(RttiProcLabel, MLDS_PredLabel, MLDS_Module) :-
RttiProcLabel = rtti_proc_label(PredOrFunc, ThisModule, PredModule,
PredName, PredArity, ArgTypes, _PredId, ProcId,
- _VarSet, _HeadVars, _ArgModes, CodeModel,
+ _VarSet, _HeadVars, ArgModes, CodeModel,
IsImported, _IsPseudoImported, _IsExported,
IsSpecialPredInstance),
(
@@ -1245,14 +1245,28 @@
DefiningModule = PredModule,
MaybeDeclaringModule = no
),
+ (
+ PredOrFunc = function,
+ not (default_func_arg_modes(ArgModes))
+ ->
+ NonDefaultModeFunc = yes
+ ;
+ NonDefaultModeFunc = no
+ ),
MLDS_PredLabel = pred(PredOrFunc, MaybeDeclaringModule,
- PredName, PredArity, CodeModel)
+ PredName, PredArity, CodeModel,
+ NonDefaultModeFunc)
),
MLDS_Module = mercury_module_name_to_mlds(DefiningModule).
ml_gen_new_label(Label) -->
ml_gen_info_new_label(LabelNum),
{ string__format("label_%d", [i(LabelNum)], Label) }.
+
+:- pred default_func_arg_modes(list(arg_mode)::in) is semidet.
+default_func_arg_modes([top_out]).
+default_func_arg_modes([top_in, ArgMode2 | ArgModes]) :-
+ default_func_arg_modes([ArgMode2 | ArgModes]).
%-----------------------------------------------------------------------------%
%
diff -u compiler/ml_elim_nested.m compiler/ml_elim_nested.m
--- compiler/ml_elim_nested.m
+++ compiler/ml_elim_nested.m
@@ -607,7 +607,7 @@
:- func ml_pred_label_name(mlds__pred_label) = string.
ml_pred_label_name(pred(PredOrFunc, MaybeDefiningModule, Name, Arity,
- _CodeModel)) = LabelName :-
+ _CodeModel, _NonDefaultModeFunc)) = LabelName :-
( PredOrFunc = predicate, Suffix = "p"
; PredOrFunc = function, Suffix = "f"
),
diff -u compiler/ml_util.m compiler/ml_util.m
--- compiler/ml_util.m
+++ compiler/ml_util.m
@@ -143,7 +143,7 @@
list__member(Defn, Defns),
Defn = mlds__defn(Name, _, _, _),
Name = function(FuncName, _, _, _),
- FuncName = pred(predicate, _, "main", 2, _).
+ FuncName = pred(predicate, _, "main", 2, _, _).
can_optimize_tailcall(Name, Call) :-
Call = call(_Signature, FuncRval, MaybeObject, _CallArgs,
diff -u compiler/mlds.m compiler/mlds.m
--- compiler/mlds.m
+++ compiler/mlds.m
@@ -1376,7 +1376,8 @@
maybe(mercury_module_name),
string, % name
arity, % arity
- code_model % code model
+ code_model, % code model
+ bool % non-default mode function
)
; special_pred(
diff -u compiler/mlds_to_c.m compiler/mlds_to_c.m
--- compiler/mlds_to_c.m
+++ compiler/mlds_to_c.m
@@ -1337,7 +1337,7 @@
%
{ Name = function(PredLabel, _, _, _) },
{ PredLabel = pred(predicate, no, "main", 2,
- model_det) }
+ model_det, no) }
;
%
% don't module-qualify base_typeclass_infos
@@ -1370,7 +1370,7 @@
%
{ QualifiedName = qual(_ModuleName, Name) },
{ Name = PredLabel - _ProcId },
- { PredLabel = pred(predicate, no, "main", 2, model_det) }
+ { PredLabel = pred(predicate, no, "main", 2, model_det, no) }
->
mlds_output_proc_label(Name)
;
@@ -1424,7 +1424,7 @@
:- mode mlds_output_pred_label(in, di, uo) is det.
mlds_output_pred_label(pred(PredOrFunc, MaybeDefiningModule, Name, Arity,
- _CodeModel)) -->
+ _CodeModel, _NonDefaultModeFunc)) -->
( { PredOrFunc = predicate, Suffix = "p" }
; { PredOrFunc = function, Suffix = "f" }
),
diff -u compiler/mlds_to_il.m compiler/mlds_to_il.m
--- compiler/mlds_to_il.m
+++ compiler/mlds_to_il.m
@@ -329,7 +329,8 @@
% If this is main, add the entrypoint, set a
% flag, and call the initialization instructions
% in the cctor of this module.
- ( { PredLabel = pred(predicate, no, "main", 2, model_det) },
+ ( { PredLabel = pred(predicate, no, "main", 2, model_det,
+ no) },
{ MaybeSeqNum = no }
->
{ EntryPoint = [entrypoint] },
@@ -1972,8 +1973,10 @@
%
% We mangle as follows:
% - Problem:
- % Two preds or funcs with different arities in Mercury end
- % up having the same types and arities in IL.
+ % Two preds or funcs with different arities in Mercury
+ % end up having the same types and arities in IL, e.g.
+ % because one of them takes io__state arguments which
+ % get omitted in IL.
%
% To avoid this we append _<arity> to every procedure
% name.
@@ -1982,12 +1985,19 @@
% A semidet pred returns its success value, and so has
% the same return type (bool) as a function.
%
- % To avoid this, we mangle all semidet preds and
- % functions to include whether they are a pred or a
- % function using _p or _f.
+ % To avoid this, we mangle all semidet predicates
+ % to indicate that they are a pred by appending _p.
%
% - Problem:
- % A predicate or function with more than one mode
+ % A function with modes other than the default (in, in,
+ % in = out) may clash with a predicate which has the
+ % same types and modes.
+ %
+ % To avoid this, we mangle all functions with
+ % non-default modes by adding _f to the procedure name.
+ %
+ % - Problem:
+ % A predicate or function with more than one mode.
%
% To avoid this, we mangle all modes > 0 by adding
% _m<modenum> to the procedure name.
@@ -2008,22 +2018,27 @@
% it isn't possible to generate names that conflict with user
% names.
%
-predlabel_to_id(pred(PredOrFunc, MaybeModuleName, Name, Arity, CodeModel),
- ProcId, MaybeSeqNum, Id) :-
+ % XXX I think that it may be possible to have conflicts with
+ % user names in the case where there is a <modulename>. - fjh
+ %
+predlabel_to_id(pred(PredOrFunc, MaybeModuleName, Name, Arity, CodeModel,
+ NonDefaultModeFunc), ProcId, MaybeSeqNum, Id) :-
( MaybeModuleName = yes(ModuleName) ->
mlds_to_il__sym_name_to_string(ModuleName, MStr),
string__format("%s_", [s(MStr)], MaybeModuleStr)
;
MaybeModuleStr = ""
),
- ( CodeModel = model_semi ->
- (
- PredOrFunc = predicate,
- PredOrFuncStr = "_p"
- ;
- PredOrFunc = function,
- PredOrFuncStr = "_f"
- )
+ (
+ CodeModel = model_semi,
+ PredOrFunc = predicate
+ ->
+ PredOrFuncStr = "_p"
+ ;
+ PredOrFunc = function,
+ NonDefaultModeFunc = yes
+ ->
+ PredOrFuncStr = "_f"
;
PredOrFuncStr = ""
),
diff -u compiler/mlds_to_java.m compiler/mlds_to_java.m
--- compiler/mlds_to_java.m
+++ compiler/mlds_to_java.m
@@ -346,7 +346,7 @@
(
Label = special_pred(PredName, _, _, _)
;
- Label = pred(_, _, PredName, _, _)
+ Label = pred(_, _, PredName, _, _, _)
)
->
@@ -1120,7 +1120,7 @@
:- mode output_pred_label(in, di, uo) is det.
output_pred_label(pred(PredOrFunc, MaybeDefiningModule, Name, Arity,
- _CodeModel)) -->
+ _CodeModel, _NonDefaultModeFunc)) -->
( { PredOrFunc = predicate, Suffix = "p" }
; { PredOrFunc = function, Suffix = "f" }
),
--
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-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list