[m-rev.] for review: IL back-end: use value types for environments
Fergus Henderson
fjh at cs.mu.OZ.AU
Sat Jul 14 01:54:21 AEST 2001
I haven't really tested this yet, except by manually looking
at the generated IL, so there might still be some problems.
But we may as well overlap testing and code review.
----------
Estimated hours taken: 5
Branches: main
For the IL back-end, use value types rather than class types
for the environment structures used for nondeterministic code.
compiler/ml_elim_nested.m:
Delete the previous IL-specific hacks, because they aren't
needed anymore.
Fix up the type of the env_ptr variable,
so that it doesn't remain "mlds__unknown_type".
compiler/mlds_to_il.m:
Change il_envptr_type to `refany'.
Handle casts to/from `refany' specially --
generate the `mkrefany' / `refanyval' instructions.
Don't call constructors for non-class types,
for mlds__generic_env_ptr_type, or for mlds__commit_type.
Fix bugs where it wasn't handling value types correctly:
- map mlds__struct classes to the `ilds__value_class' type
rather than to the `ilds__class' type
- mlds__struct classes must inherit from System.ValueType
- likewise mlds__enum classes are must inherit from System.EnumType
compiler/ml_call_gen.m:
compiler/ml_code_util.m:
Cast the env_ptr argument to mlds__generic_env_ptr_type.
Although the C, Java, etc. back-ends don't need a cast here,
since this is just an upcast, the cast is needed for the IL
back-end because it gets converted to a special instruction
(mkrefany).
runtime/mercury_mcpp.cpp:
Delete the `Environment' type, since it is no longer needed
(we use `refany' instead).
Workspace: /home/mars/fjh/ws1/mercury
Index: compiler/ml_call_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_call_gen.m,v
retrieving revision 1.25
diff -u -d -r1.25 ml_call_gen.m
--- compiler/ml_call_gen.m 2001/07/06 17:11:59 1.25
+++ compiler/ml_call_gen.m 2001/07/13 14:32:30
@@ -406,8 +406,10 @@
( { UseNestedFuncs = yes } ->
{ ArgRvals = list__append(ArgRvals0, [FuncPtrRval]) }
;
+ { CastEnvPtrRval = unop(cast(
+ mlds__generic_env_ptr_type), EnvPtrRval) },
{ ArgRvals = list__append(ArgRvals0,
- [FuncPtrRval, EnvPtrRval]) }
+ [FuncPtrRval, CastEnvPtrRval]) }
),
% for --nondet-copy-out, the output arguments will be
% passed to the continuation rather than being returned
Index: compiler/ml_code_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_code_util.m,v
retrieving revision 1.43
diff -u -d -r1.43 ml_code_util.m
--- compiler/ml_code_util.m 2001/07/13 08:04:41 1.43
+++ compiler/ml_code_util.m 2001/07/13 13:37:31
@@ -1692,7 +1692,8 @@
;
{ ArgTypes = list__append(ArgTypes0,
[mlds__generic_env_ptr_type]) },
- { ArgRvals = list__append(ArgRvals0, [EnvPtrRval]) }
+ { ArgRvals = list__append(ArgRvals0,
+ [unop(cast(mlds__generic_env_ptr_type), EnvPtrRval)]) }
),
{ RetTypes = [] },
{ Signature = mlds__func_signature(ArgTypes, RetTypes) },
Index: compiler/ml_elim_nested.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_elim_nested.m,v
retrieving revision 1.35
diff -u -d -r1.35 ml_elim_nested.m
--- compiler/ml_elim_nested.m 2001/07/13 10:27:44 1.35
+++ compiler/ml_elim_nested.m 2001/07/13 14:12:42
@@ -383,33 +383,12 @@
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.
- globals__get_target(Globals, Target),
- ( 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 = []
- ),
- EnvTypeDefnBody = mlds__class(mlds__class_defn(EnvTypeKind, [],
- [mlds__generic_env_ptr_type], [], Ctors, Fields)),
+ Imports = [],
+ Inherits = [],
+ Implements = [],
+ Ctors = [],
+ EnvTypeDefnBody = mlds__class(mlds__class_defn(EnvTypeKind, Imports,
+ Inherits, Implements, Ctors, Fields)),
EnvTypeDefn = mlds__defn(EnvTypeEntityName, Context, EnvTypeFlags,
EnvTypeDefnBody),
@@ -430,29 +409,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
@@ -531,17 +491,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:
%
@@ -1140,6 +1091,15 @@
EnvPtrVarType),
Tag = yes(0),
Lval = field(Tag, EnvPtr, FieldName, FieldType, EnvPtrVarType)
+ ;
+ % Check for references to the env_ptr itself.
+ % For those, the code generator will have left the
+ % type as mlds__unknown_type, and we need to fill
+ % it in here.
+ ThisVarName = mlds__var_name("env_ptr", no),
+ ThisVarType = mlds__unknown_type
+ ->
+ Lval = var(ThisVar, EnvPtrVarType)
;
%
% leave everything else unchanged
Index: compiler/mlds_to_il.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_il.m,v
retrieving revision 1.49
diff -u -d -r1.49 mlds_to_il.m
--- compiler/mlds_to_il.m 2001/07/13 12:02:18 1.49
+++ compiler/mlds_to_il.m 2001/07/13 15:39:59
@@ -23,6 +23,9 @@
%
% [ ] advanced name mangling:
% - optionally only mangle names when it is absolutely necessary
+% (Partly done; we now mangle names less often than we used to.
+% The only way to mangle less would be to use a context-sensitive
+% name mangling algorithm, which may not be a good idea.)
% [ ] solutions
% [ ] Type classes
% - now work, but...
@@ -497,10 +500,10 @@
generate_class_body(Name, ClassDefn, ClassName, EntityName, Extends, Interfaces,
ClassDecls, Info0, Info) :-
EntityName = entity_name_to_ilds_id(Name),
- ClassDefn = class_defn(_Kind, _Imports, Inherits, Implements,
+ ClassDefn = class_defn(Kind, _Imports, Inherits, Implements,
Ctors, Members),
Parent - Extends = generate_parent_and_extends(Info0 ^ il_data_rep,
- Inherits),
+ Kind, Inherits),
Interfaces = implements(
list__map(interface_id_to_class_name, Implements)),
@@ -512,13 +515,21 @@
ClassDecls = IlCtors ++ MethodsAndFields.
-:- func generate_parent_and_extends(il_data_rep, list(mlds__class_id))
- = pair(ilds__class_name, extends).
+:- func generate_parent_and_extends(il_data_rep, mlds__class_kind,
+ list(mlds__class_id)) = pair(ilds__class_name, extends).
-generate_parent_and_extends(DataRep, Inherits) = Parent - Extends :-
+generate_parent_and_extends(DataRep, Kind, Inherits) = Parent - Extends :-
( Inherits = [],
- Parent = il_generic_class_name,
- Extends = extends_nothing
+ ( Kind = mlds__struct ->
+ Parent = il_generic_valuetype_name,
+ Extends = extends(Parent)
+ ; Kind = mlds__enum ->
+ Parent = il_generic_enum_name,
+ Extends = extends(Parent)
+ ; % Kind = mlds__class, mlds__package, or mlds__interface
+ Parent = il_generic_class_name,
+ Extends = extends_nothing
+ )
; Inherits = [Parent0 | Rest],
( Rest = [] ->
Parent = mlds_type_to_ilds_class_name(DataRep, Parent0),
@@ -1485,19 +1496,15 @@
DataRep =^ il_data_rep,
(
{
- Type = mlds__generic_env_ptr_type
- ;
- Type = mlds__class_type(_, _, _)
+ Type = mlds__class_type(_, _, mlds__class)
;
- Type = mlds__commit_type
- ;
DataRep ^ highlevel_data = yes,
Type = mlds__mercury_type(_, user_type)
}
->
- % If this is an env_ptr we should call the
+ % If this is an class, we should call the
% constructor.
- % (This is also how we will handle high-level data).
+ % (This is needed to handle high-level data).
% We generate code of the form:
%
% ... load memory reference ...
@@ -1828,23 +1835,54 @@
unaryop_to_il(std_unop((not)), _,
node([ldc(int32, i(1)), clt(unsigned)])) --> [].
- % if we are casting from an unboxed type, we should box
- % it first.
- % XXX should also test the cast-to type, to handle the
- % cases where it is unboxed.
-unaryop_to_il(cast(Type), Rval, Instrs) -->
+unaryop_to_il(cast(DestType), Rval, Instrs) -->
DataRep =^ il_data_rep,
- { ILType = mlds_type_to_ilds_type(DataRep, Type) },
+ { ILDestType = mlds_type_to_ilds_type(DataRep, DestType) },
{
+ %
+ % we need to handle casts to/from "refany" specially --
+ % IL has special instructions for those
+ %
+ % is it a cast to refany?
+ ILDestType = ilds__type(_, refany)
+ ->
+ rval_to_type(Rval, SrcType),
+ ILSrcType = mlds_type_to_ilds_type(DataRep, SrcType),
+ (
+ % is it from refany?
+ ILSrcType = ilds__type(_, refany)
+ ->
+ % cast from refany to refany is a NOP
+ Instrs = empty
+ ;
+ % cast to refany: use "mkrefany" instruction
+ Instrs = node([mkrefany(ILSrcType)])
+ )
+ ;
+ % is it a cast from refany?
+ Rval = lval(_),
+ rval_to_type(Rval, SrcType),
+ ILSrcType = mlds_type_to_ilds_type(DataRep, SrcType),
+ ILSrcType = ilds__type(_, refany)
+ ->
+ % cast from refany: use "refanyval" instruction
+ Instrs = node([refanyval(ILDestType)])
+ ;
+ %
+ % if we are casting from an unboxed type, we should box
+ % it first.
+ % XXX should also test the cast-to type, to handle the
+ % cases where it is unboxed.
+ %
Rval = const(Const),
- RvalType = rval_const_to_type(Const),
- RvalILType = mlds_type_to_ilds_type(DataRep, RvalType),
- not already_boxed(RvalILType)
+ SrcType = rval_const_to_type(Const),
+ ILSrcType = mlds_type_to_ilds_type(DataRep, SrcType),
+ not already_boxed(ILSrcType)
->
- Instrs = node([call(convert_to_object(RvalILType)),
- castclass(ILType)])
+ Instrs = node([call(convert_to_object(ILSrcType)),
+ castclass(ILDestType)])
;
- Instrs = node([castclass(ILType)])
+ Instrs = node([castclass(ILDestType)])
}.
@@ -2296,9 +2334,10 @@
% see comments about function types above.
mlds_type_to_ilds_type(_, mlds__cont_type(_ArgTypes)) = ilds__type([], int32).
-mlds_type_to_ilds_type(_, mlds__class_type(Class, Arity, _Kind)) =
- ilds__type([], class(
- mlds_class_name_to_ilds_class_name(Class, Arity))).
+mlds_type_to_ilds_type(_, mlds__class_type(Class, Arity, Kind)) =
+ ilds__type([], SimpleType) :-
+ ClassName = mlds_class_name_to_ilds_class_name(Class, Arity),
+ SimpleType = mlds_class_to_ilds_simple_type(Kind, ClassName).
mlds_type_to_ilds_type(_, mlds__commit_type) = il_commit_type.
@@ -2338,6 +2377,18 @@
;
il_array_type
).
+mlds_type_to_ilds_type(_, mlds__unknown_type) = _ :-
+ unexpected(this_file, "mlds_type_to_ilds_type: unknown_type").
+
+:- func mlds_class_to_ilds_simple_type(mlds__class_kind, ilds__class_name) =
+ ilds__simple_type.
+mlds_class_to_ilds_simple_type(Kind, ClassName) = SimpleType :-
+ ( Kind = mlds__package, SimpleType = class(ClassName)
+ ; Kind = mlds__class, SimpleType = class(ClassName)
+ ; Kind = mlds__interface, SimpleType = class(ClassName)
+ ; Kind = mlds__struct, SimpleType = value_class(ClassName)
+ ; Kind = mlds__enum, SimpleType = value_class(ClassName)
+ ).
:- func mercury_type_to_highlevel_class_type(mercury_type) = ilds__type.
mercury_type_to_highlevel_class_type(MercuryType) = ILType :-
@@ -2358,10 +2409,7 @@
-mlds_type_to_ilds_type(_, mlds__unknown_type) = _ :-
- unexpected(this_file, "mlds_type_to_ilds_type: unknown_type").
-
:- func mlds_class_name_to_ilds_class_name(mlds__class, arity) =
ilds__class_name.
@@ -3027,6 +3075,14 @@
il_generic_class_name = il_system_name(["Object"]).
+ % Return the class name for System.ValueType.
+:- func il_generic_valuetype_name = ilds__class_name.
+il_generic_valuetype_name = il_system_name(["ValueType"]).
+
+ % Return the class name for System.Enum
+:- func il_generic_enum_name = ilds__class_name.
+il_generic_enum_name = il_system_name(["Enum"]).
+
%-----------------------------------------------------------------------------%
%
% The mapping to the array type (used like MR_Word).
@@ -3064,14 +3120,7 @@
%
:- func il_envptr_type = ilds__type.
-il_envptr_type = ilds__type([], il_envptr_simple_type).
-
-:- func il_envptr_simple_type = simple_type.
-il_envptr_simple_type = class(il_envptr_class_name).
-
-:- func il_envptr_class_name = ilds__class_name.
-il_envptr_class_name = mercury_runtime_name(["Environment"]).
-
+il_envptr_type = ilds__type([], refany).
%-----------------------------------------------------------------------------%
%
--
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