[m-rev.] for review: IL back-end: use value types for environments
Fergus Henderson
fjh at cs.mu.OZ.AU
Tue Jul 17 07:13:07 AEST 2001
On 15-Jul-2001, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> On 14-Jul-2001, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> > On 14-Jul-2001, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> > >
> > > For the IL back-end, use value types rather than class types
> > > for the environment structures used for nondeterministic code.
> >
> > This doesn't work, because you can't use `refany' types as fields of structures.
> >
> > We had the same problem with ordinary managed reference types, and worked around
> > that by putting a value rather than a reference in the environment struct,
> > and using copy-in copy-out.
> >
> > But that work-around won't help here, since there's no generic type we can use
> > for the value.
> >
> > :-(
>
> Plan B is to use unmanaged pointers rather than 'refany'.
>
> (Still not 100% sure if this plan is feasible,
> since I haven't implemented it yet.)
I've implemented it, and it works.
> This will of course be completely unverifiable.
> So it ought to be optional, with the other option being to
> allocate nondet environments on the heap (as we do currently).
I plan to implement that compiler switch in the long run.
But I think it might be best to just check in this change as is for now.
Comments?
----------
Estimated hours taken: 5
Branches: main
compiler/mlds_to_il.m:
Change il_envptr_type to an unmanaged pointer type.
(Currently `int32'. XXX We should use "native int".)
compiler/ml_elim_nested.m:
For the IL-back-end, when assigning the environment pointer
arg to the local environment pointer, just do an assignment,
rather than a cast.
Delete the other IL-specific hacks that we used previously,
because they aren't needed anymore.
Index: ml_elim_nested.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_elim_nested.m,v
retrieving revision 1.38
diff -u -d -u -r1.38 ml_elim_nested.m
--- ml_elim_nested.m 14 Jul 2001 19:54:59 -0000 1.38
+++ ml_elim_nested.m 16 Jul 2001 20:15:18 -0000
@@ -376,48 +376,16 @@
% <LocalVars>
% };
%
- % IL uses classes instead of structs, so the code
- % generated needs to be a little different.
- % XXX Perhaps if we used value classes this could go
- % away.
- globals__get_target(Globals, Target),
- ( Target = il ->
- EnvTypeKind = mlds__class
- ;
- EnvTypeKind = mlds__struct
- ),
+ EnvTypeKind = mlds__struct,
EnvTypeName = class_type(qual(ModuleName, EnvClassName), 0,
EnvTypeKind),
EnvTypeEntityName = type(EnvClassName, 0),
EnvTypeFlags = env_type_decl_flags,
Fields = list__map(convert_local_to_field, LocalVars),
- % IL uses classes instead of structs, so the code
- % generated needs to be a little different.
- % XXX Perhaps if we used value classes this could go
- % away.
- ( Target = il ->
- % Generate a ctor for the class.
-
- % We generate an empty block for the body of the
- % constructor.
- Stmt = mlds__statement(block([], []), Context),
-
- Ctor = mlds__function(no, func_params([], []),
- defined_here(Stmt)),
- CtorFlags = init_decl_flags(public, per_instance, non_virtual,
- overridable, modifiable, concrete),
-
- % Note that the name of constructor is
- % determined by the backend convention.
- CtorDefn = mlds__defn(export("<constructor>"), Context,
- CtorFlags, Ctor),
- Ctors = [CtorDefn]
- ;
- Ctors = []
- ),
+ Ctors = [],
EnvTypeDefnBody = mlds__class(mlds__class_defn(EnvTypeKind, [],
- [mlds__generic_env_ptr_type], [], Ctors, Fields)),
+ [], [], Ctors, Fields)),
EnvTypeDefn = mlds__defn(EnvTypeEntityName, Context, EnvTypeFlags,
EnvTypeDefnBody),
@@ -438,29 +406,10 @@
%
EnvVar = qual(ModuleName, mlds__var_name("env", no)),
- % IL uses classes instead of structs, so the code
- % generated needs to be a little different.
- % XXX Perhaps if we used value classes this could go
- % away.
- ( Target = il ->
- EnvVarAddr = lval(var(EnvVar, EnvTypeName)),
- ml_init_env(EnvTypeName, EnvVarAddr, Context, ModuleName,
- Globals, EnvPtrVarDecl, InitEnv0),
-
- NewObj = mlds__statement(
- atomic(new_object(
- var(EnvVar, EnvTypeName),
- no, EnvTypeName, no, no, [], [])),
- Context),
- InitEnv = mlds__statement(block([],
- [NewObj, InitEnv0]), Context),
- EnvDecls = [EnvVarDecl, EnvPtrVarDecl]
- ;
- EnvVarAddr = mem_addr(var(EnvVar, EnvTypeName)),
- ml_init_env(EnvTypeName, EnvVarAddr, Context, ModuleName,
- Globals, EnvPtrVarDecl, InitEnv),
- EnvDecls = [EnvVarDecl, EnvPtrVarDecl]
- ).
+ EnvVarAddr = mem_addr(var(EnvVar, EnvTypeName)),
+ ml_init_env(EnvTypeName, EnvVarAddr, Context, ModuleName,
+ Globals, EnvPtrVarDecl, InitEnv),
+ EnvDecls = [EnvVarDecl, EnvPtrVarDecl].
% When converting local variables into fields of the
% environment struct, we need to change `local' access
@@ -524,7 +473,27 @@
mlds__var_name("env_ptr_arg", no)),
mlds__generic_env_ptr_type)),
EnvPtrVarType = ml_make_env_ptr_type(Globals, TypeName),
- CastEnvPtrVal = unop(cast(EnvPtrVarType), EnvPtrVal),
+
+ % Insert a cast, to downcast from
+ % mlds__generic_env_ptr_type to the specific
+ % environment type for this procedure.
+ %
+ % XXX For the IL back-end, we're using
+ % unmanaged pointers (in fact currently just "int32")
+ % as the generic environment pointer type,
+ % and the .NET CLR seems to get very confused if
+ % you try to do a "castclass" here, so we don't
+ % want to insert a cast.
+ % (Even if it worked, we don't want the
+ % overhead of a dynamically checked cast,
+ % since the code we generate isn't verifiable anyway).
+ globals__get_target(Globals, Target),
+ ( Target = il ->
+ CastEnvPtrVal = EnvPtrVal
+ ;
+ CastEnvPtrVal = unop(cast(EnvPtrVarType), EnvPtrVal)
+ ),
+
ml_init_env(TypeName, CastEnvPtrVal, Context, ModuleName,
Globals, EnvPtrDecl, InitEnvPtr),
FuncBody = mlds__statement(block([EnvPtrDecl],
@@ -539,17 +508,8 @@
).
:- func ml_make_env_ptr_type(globals, mlds__type) = mlds__type.
-ml_make_env_ptr_type(Globals, EnvType) = EnvPtrType :-
- % IL uses classes instead of structs, so the type
- % is a little different.
- % XXX Perhaps if we used value classes this could go
- % away.
- globals__get_target(Globals, Target),
- ( Target = il ->
- EnvPtrType = EnvType
- ;
- EnvPtrType = mlds__ptr_type(EnvType)
- ).
+ml_make_env_ptr_type(_Globals, EnvType) = EnvPtrType :-
+ EnvPtrType = mlds__ptr_type(EnvType).
% Create the environment pointer and initialize it:
%
Index: mlds_to_il.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_il.m,v
retrieving revision 1.51
diff -u -d -u -r1.51 mlds_to_il.m
--- mlds_to_il.m 14 Jul 2001 19:55:00 -0000 1.51
+++ mlds_to_il.m 16 Jul 2001 20:15:23 -0000
@@ -3146,18 +3187,22 @@
%-----------------------------------------------------------------------------%
%
-% The mapping to the environment type.
+% The mapping to the generic environment pointer type.
%
-:- func il_envptr_type = ilds__type.
-il_envptr_type = ilds__type([], il_envptr_simple_type).
+% Unfortunately the .NET CLR doesn't have any verifiable way of creating a
+% generic pointer to an environment, unless you allocate them on the heap.
+% Using "refany" (a.k.a. "typedref") *almost* works, except that we need
+% to be able to put these pointers in environment structs, and the CLR
+% doesn't allow that (see ECMA CLI Partition 1, 8.6.1.3 "Local Signatures").
-:- func il_envptr_simple_type = simple_type.
-il_envptr_simple_type = class(il_envptr_class_name).
+% The unverifiable way of doing it is to use unmanaged pointers.
-:- func il_envptr_class_name = ilds__class_name.
-il_envptr_class_name = mercury_runtime_name(["Environment"]).
+% We don't want to allocate environments on the heap, because that is
+% inefficient. So we use unmanaged pointers.
+:- func il_envptr_type = ilds__type.
+il_envptr_type = ilds__type([], int32). % XXX we should use "native_int"
%-----------------------------------------------------------------------------%
%
cvs server: Diffing notes
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
The University of Melbourne | of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
--------------------------------------------------------------------------
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