[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