[m-rev.] for review: IL back-end: options for verifiable code

Fergus Henderson fjh at cs.mu.OZ.AU
Fri Aug 3 05:49:16 AEST 2001


On 02-Aug-2001, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> 
> Improve the support for generating verifiable code and/or efficient but
> unverifiable code for the IL back-end.
> 
> We now allocate nondet environments on the stack by default, but they will get
> allocated on the heap if you specify --verifiable-code.

Here's a relative diff that fixes the two XXX comments in my earlier log message.
I also accidentally forgot to include the changes to two files,
mlds_to_{csharp.m,mcpp.m} in my previous post (due to a typo
in the log message which confused my diff-posting script!),
so those are also included.

I've verified that
	(a) it still passes bootcheck in grade hlc.gc
	(b) with the `--verifiable-code' option, it generates exactly the same
	    IL for the standard library as it used to
	(c) without the `--verifiable-code' option, the generated IL looks
	    like what I expected.

I'll go ahead and commit this now.  Beware that the calling convention /
ABI is different depending on whether or not --verifiable-code is enabled.
Since --verifiable-code is not the default, you should either add
--verifiable-code to your MCFLAGS in all appropriate places,
or rebuild all your IL files.

Currently there is no good support for building multiple IL grades.

--- CHANGES.old	Fri Aug  3 05:38:38 2001
+++ CHANGES	Fri Aug  3 05:39:13 2001
@@ -1,3 +1,7 @@
+
+Branches: main
+Estimated hours taken: 30
+
 Improve the support for generating verifiable code and/or efficient but
 unverifiable code for the IL back-end.
 
@@ -26,10 +30,11 @@
 	Add a new field to the il_data_rep_type to handle the different
 	representations for the environment pointer types.
 	Add a new procedure get_il_data_rep for computing it.
+	Handle casts to/from `refany' by generating the appropriate IL
+	instructions, `mkrefany'/`refanyval'.
+	Handle casts to/from unmanaged pointers (native_uint) --
+	these are just a noop in IL, `.castclass' doesn't work for them.
 
-	XXX TODO: handle casts to/from refany
-	XXX TODO: handle casts to/from unmanaged pointers (don't cast)
-
-compiler/mlds_to_csharp.m
-compiler/mlds_to_mcpp.m
+compiler/mlds_to_csharp.m:
+compiler/mlds_to_mcpp.m:
 	Use get_il_data_rep rather than constructing it manually.

--- mlds_to_il.m.old	Fri Aug  3 01:42:01 2001
+++ mlds_to_il.m	Fri Aug  3 04:57:04 2001
@@ -1974,31 +1974,94 @@
 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.
-unaryop_to_il(cast(Type), Rval, Instrs) -->
+unaryop_to_il(cast(DestType), SrcRval, Instrs) -->
 	DataRep =^ il_data_rep,
-	{ ILType = mlds_type_to_ilds_type(DataRep, Type) },
-	{ rval_to_type(Rval, RvalType) },
-	{ RvalILType = mlds_type_to_ilds_type(DataRep, RvalType) },
-	{ already_boxed(ILType) ->
-		( already_boxed(RvalILType) ->
-			( RvalType = Type ->
+	{ DestILType = mlds_type_to_ilds_type(DataRep, DestType) },
+	{ rval_to_type(SrcRval, SrcType) },
+	{ SrcILType = mlds_type_to_ilds_type(DataRep, SrcType) },
+
+	%
+	% we need to handle casts to/from "refany" specially --
+	% IL has special instructions for those
+	%
+	{
+		% is it a cast to refany?
+		DestILType = ilds__type(_, refany)
+	->
+		(
+			% is it from refany?
+			SrcILType = ilds__type(_, refany)
+		->
+			% cast from refany to refany is a NOP
+			Instrs = empty
+		;
+			% cast to refany: use "mkrefany" instruction
+			( SrcILType = ilds__type(_Qual, '&'(ReferencedType)) ->
+				Instrs = node([mkrefany(ReferencedType)])
+			;
+				unexpected(this_file,
+					"cast from non-ref type to refany")
+			)
+		)
+	;
+		% is it a cast from refany?
+		SrcRval = lval(_),
+		rval_to_type(SrcRval, SrcType),
+		SrcILType = mlds_type_to_ilds_type(DataRep, SrcType),
+		SrcILType = ilds__type(_, refany)
+	->
+		% cast from refany: use "refanyval" instruction
+		( DestILType = ilds__type(_Qual, '&'(ReferencedType)) ->
+			Instrs = node([refanyval(ReferencedType)])
+		;
+			unexpected(this_file,
+				"cast from non-ref type to refany")
+		)
+	;
+	%
+	% we need to handle casts to/from unmanaged pointers specially --
+	% .castclass doesn't work for those.  These casts are generated
+	% by ml_elim_nested.m for the environment pointers.  If we're
+	% using unmanaged pointers, then this must be unverifiable code.
+	% We don't need to use any explicit conversion in the IL
+	%
+	% XXX Currently ilds uses `native_uint' for unmanaged pointers,
+	% because that's what IL does, but we should probably define a
+	% separate ilds type for this.
+	%
+		( DestILType = ilds__type(_, native_uint)
+		; SrcILType = ilds__type(_, native_uint)
+		)
+	->
+		Instrs = empty
+	;
+	%
+	% if we are casting from an unboxed type to a boxed type,
+	% we should box it first, and then cast.
+	%
+		already_boxed(DestILType)
+	->
+		( already_boxed(SrcILType) ->
+			( SrcType = DestType ->
 				Instrs = empty
 			;
-				Instrs = node([castclass(ILType)])
+				% cast one boxed type to another boxed type
+				Instrs = node([castclass(DestILType)])
 			)
 		;
+			% convert an unboxed type to a boxed type:
+			% box it first, then cast
 			Instrs = tree__list([
-				convert_to_object(RvalILType),
-				instr_node(castclass(ILType))
+				convert_to_object(SrcILType),
+				instr_node(castclass(DestILType))
 			])
 		)
 	;
-		( already_boxed(RvalILType) ->
-			( RvalType = mercury_type(_, user_type) ->
+		( already_boxed(SrcILType) ->
+			( SrcType = mercury_type(_, user_type) ->
 				% XXX we should look into a nicer way to
 				% generate MLDS so we don't need to do this
+				% XXX This looks wrong for --high-level-data. -fjh.
 				Instrs = tree__list([
 					comment_node(
 						"loading out of an MR_Word"),
@@ -2007,17 +2070,15 @@
 						il_generic_simple_type)),
 					comment_node(
 						"turning a cast into an unbox"),
-					convert_from_object(ILType)
+					convert_from_object(DestILType)
 				])
-
-
 			;
 				% XXX It would be nicer if the MLDS used an
 				% unbox to do this.
 				Instrs = tree__list([
 					comment_node(
 					"turning a cast into an unbox"),
-					convert_from_object(ILType)
+					convert_from_object(DestILType)
 				])
 			)
 		;
@@ -3279,7 +3340,11 @@
 		ILType = ilds__type([], refany)
 	;
 		% Use unmanaged pointers
-		ILType = ilds__type([], int32)  % XXX we should use native_int
+		ILType = ilds__type([], native_uint)
+		% XXX we should introduce an ILDS type for unmanaged pointers,
+		%     rather than using native_uint; that's what IL does, but
+		%     it sucks -- we should delay the loss of type information
+		%     to the last possible moment, i.e. when writing out IL.
 	).
 
 :- func il_heap_envptr_type = ilds__type.
Index: mlds_to_csharp.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_csharp.m,v
retrieving revision 1.12
diff -u -d -u -r1.12 mlds_to_csharp.m
--- mlds_to_csharp.m	20 Jul 2001 14:14:00 -0000	1.12
+++ mlds_to_csharp.m	2 Aug 2001 16:12:03 -0000
@@ -201,8 +201,7 @@
 		{ has_foreign_languages(Statement, Langs) },
 		{ list__member(csharp, Langs) }
 	->
-		globals__io_lookup_bool_option(highlevel_data, HighLevelData),
-		{ DataRep = il_data_rep(HighLevelData) },
+		get_il_data_rep(DataRep),
 		{ Params = mlds__func_params(Inputs, Outputs) },
 		{ Outputs = [] ->
 			ReturnType = void
@@ -418,8 +417,7 @@
 :- pred write_csharp_parameter_type(mlds__type, io__state, io__state).
 :- mode write_csharp_parameter_type(in, di, uo) is det.
 write_csharp_parameter_type(Type) -->
-	globals__io_lookup_bool_option(highlevel_data, HighLevelData),
-	{ DataRep = il_data_rep(HighLevelData) },
+	get_il_data_rep(DataRep),
 	{ ILType = mlds_type_to_ilds_type(DataRep, Type) },
 	write_il_type_as_csharp_type(ILType).
 
@@ -516,8 +514,7 @@
 	pair(mlds__entity_name, mlds__type)::in,
 	io__state::di, io__state::uo) is det.
 write_input_arg_as_csharp_type(EntityName - Type) --> 
-	globals__io_lookup_bool_option(highlevel_data, HighLevelData),
-	{ DataRep = il_data_rep(HighLevelData) },
+	get_il_data_rep(DataRep),
 	write_il_type_as_csharp_type(mlds_type_to_ilds_type(DataRep, Type)),
 	io__write_string(" "),
 	( { EntityName = data(var(VarName)) } ->
Index: mlds_to_mcpp.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_mcpp.m,v
retrieving revision 1.15
diff -u -d -u -r1.15 mlds_to_mcpp.m
--- mlds_to_mcpp.m	20 Jul 2001 14:14:04 -0000	1.15
+++ mlds_to_mcpp.m	2 Aug 2001 16:14:35 -0000
@@ -221,8 +221,7 @@
 			{ list__member(managed_cplusplus, Langs) }
 		)
 	->
-		globals__io_lookup_bool_option(highlevel_data, HighLevelData),
-		{ DataRep = il_data_rep(HighLevelData) },
+		get_il_data_rep(DataRep),
 		{ ILSignature = params_to_il_signature(DataRep, ModuleName,
 			Params) },
 		{ predlabel_to_id(PredLabel, ProcId, MaybeSeqNum, Id) },
@@ -274,7 +273,7 @@
 	io__state, io__state).
 :- mode write_managed_cpp_statement(in, di, uo) is det.
 write_managed_cpp_statement(Statement) -->
-	globals__io_lookup_bool_option(highlevel_data, HighLevelData),
+	get_il_data_rep(ILDataRep),
 	( 
 			% XXX this ignores the language target.
 		{ Statement = statement(atomic(inline_target_code(
@@ -341,8 +340,7 @@
 		{ Statement = statement(atomic(
 			new_object(Target, _MaybeTag, Type, _MaybeSize, 
 				_MaybeCtorName, _Args, _ArgTypes)), _) },
-		{ ClassName = mlds_type_to_ilds_class_name(
-			il_data_rep(HighLevelData), Type) }
+		{ ClassName = mlds_type_to_ilds_class_name(ILDataRep, Type) }
 	->
 		write_managed_cpp_lval(Target),
 		io__write_string(" = new "),
@@ -521,8 +519,7 @@
 :- pred write_managed_cpp_type(mlds__type, io__state, io__state).
 :- mode write_managed_cpp_type(in, di, uo) is det.
 write_managed_cpp_type(Type) -->
-	globals__io_lookup_bool_option(highlevel_data, HighLevelData),
-	{ DataRep = il_data_rep(HighLevelData) },
+	get_il_data_rep(DataRep),
 	write_il_type_as_managed_cpp_type(
 		mlds_type_to_ilds_type(DataRep, Type)).
 

-- 
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