[m-rev.] for review: il as a foreign language

Tyson Dowd trd at cs.mu.OZ.AU
Fri Jul 13 00:35:32 AEST 2001


On 11-Jul-2001, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> On 11-Jul-2001, Tyson Dowd <trd at cs.mu.OZ.AU> wrote:
> > Add support for foreign_proc("il", ....)
> 
> This should be documented in the language reference manual.
> 
> If you don't want to make the documentation official yet,
> then leave it commented out.

I'm working on documenting pragma foreign_proc in the language reference
manual, and the language specific information in the user's guide.

> > compiler/mlds.m:
> > 	Add a field in blocks, which is set to yes iff the block contains
> > 	handwritten foreign code.
> 
> Why?
> 
> > compiler/ml_code_util.m:
> > compiler/ml_elim_nested.m:
> > compiler/ml_optimize.m:
> > compiler/ml_simplify_switch.m:
> > compiler/ml_string_switch.m:
> > compiler/ml_tailcall.m:
> > compiler/ml_util.m:
> > 	Handle the new field in blocks indicating whether the block contains
> > 	handwritten code.
> 
> I'm not sure these changes are a good idea, because I'm not convinced that
> don't think the field is necessary.  Could you elaborate on why you think
> it is needed?

I'm not convinced it is needed either, I could simply search for the
il_asm_code in the IL stream and optimize differently depending upon
whether it is there or not.

All I need to do is maintain the invariant that the local variables for
a piece of il_asm_code are in the nearest enclosing block.

> > Index: compiler/mlds.m
> > ===================================================================
> > RCS file: /home/mercury1/repository/mercury/compiler/mlds.m,v
> > retrieving revision 1.58
> > diff -u -r1.58 mlds.m
> > --- compiler/mlds.m	2001/07/10 12:51:03	1.58
> > +++ compiler/mlds.m	2001/07/10 16:05:53
> > @@ -726,7 +726,13 @@
> >  	%
> >  	% sequence
> >  	%
> > -		block(mlds__defns, list(mlds__statement))
> > +		block(mlds__defns, list(mlds__statement), bool)	
> > +			% the `bool' is yes iff the block contains
> > +			% handwritten foreign language code.  
> > +			% If so, this block can be considered a boundary for 
> > +			% optimization purposes -- the code within the block
> > +			% should not be optimized as the optimizer will not
> > +			% (in general) understand the foreign code.
> 
> When you say "contains", do you mean contains directly, or is the bool supposed
> to be yes even if it is only contained indirectly, i.e. if you have a block
> containing another block containing the foreign code?
> 
> If the latter, then I think there is lots of code which doesn't respect that
> invariant (and in general this invariant would be hard to preserve).
> 
> If the former, then what's the advantage?
> Why does putting the marker on the block help?
> Can't code which does optimization check for foreign_code
> just as easily as it can check this marker?

Yes.  Good point.  Don't know why I didn't think of this.

> > Index: compiler/ml_code_gen.m
> > ===================================================================
> > RCS file: /home/mercury1/repository/mercury/compiler/ml_code_gen.m,v
> > retrieving revision 1.89
> > diff -u -r1.89 ml_code_gen.m
> > --- compiler/ml_code_gen.m	2001/06/22 09:14:30	1.89
> > +++ compiler/ml_code_gen.m	2001/07/10 16:05:51
> > @@ -1051,11 +1051,11 @@
> >  		% them from the byref_output_vars field in the ml_gen_info.
> >  		( CodeModel = model_non ->
> >  		
> > - 			ml_set_up_initial_succ_cont(ModuleInfo, 
> > +			ml_set_up_initial_succ_cont(ModuleInfo, 
> 
> > @@ -1989,20 +1989,20 @@
> >  		MLDS_Decls, MLDS_Statements).
> >  
> >  ml_gen_goal_expr(foreign_proc(Attributes,
> > -                PredId, ProcId, ArgVars, ArgDatas, OrigArgTypes, PragmaImpl),
> > +		PredId, ProcId, ArgVars, ArgDatas, OrigArgTypes, PragmaImpl),
> >  		CodeModel, OuterContext, MLDS_Decls, MLDS_Statements) -->
> > -        (
> > -                { PragmaImpl = ordinary(C_Code, _MaybeContext) },
> > -                ml_gen_ordinary_pragma_foreign_proc(CodeModel, Attributes,
> > -                        PredId, ProcId, ArgVars, ArgDatas, OrigArgTypes,
> > -                        C_Code, OuterContext, MLDS_Decls, MLDS_Statements)
> > -        ;
> > -                { PragmaImpl = nondet(
> > -                        LocalVarsDecls, LocalVarsContext,
> > +	(
> > +		{ PragmaImpl = ordinary(C_Code, _MaybeContext) },
> > +		ml_gen_ordinary_pragma_foreign_proc(CodeModel, Attributes,
> > +			PredId, ProcId, ArgVars, ArgDatas, OrigArgTypes,
> > +			C_Code, OuterContext, MLDS_Decls, MLDS_Statements)
> > +	;
> > +		{ PragmaImpl = nondet(
> > +			LocalVarsDecls, LocalVarsContext,
> >  			FirstCode, FirstContext, LaterCode, LaterContext,
> >  			_Treatment, SharedCode, SharedContext) },
> > -                ml_gen_nondet_pragma_foreign_proc(CodeModel, Attributes,
> > -                        PredId, ProcId, ArgVars, ArgDatas, OrigArgTypes,
> > +		ml_gen_nondet_pragma_foreign_proc(CodeModel, Attributes,
> > +			PredId, ProcId, ArgVars, ArgDatas, OrigArgTypes,
> >  			OuterContext, LocalVarsDecls, LocalVarsContext,
> >  			FirstCode, FirstContext, LaterCode, LaterContext,
> >  			SharedCode, SharedContext, MLDS_Decls, MLDS_Statements)
> >
> > @@ -2010,10 +2010,10 @@
> >  		{ PragmaImpl = import(Name, HandleReturn, Vars, _Context) },
> >  		{ C_Code = string__append_list([HandleReturn, " ",
> >  				Name, "(", Vars, ");"]) },
> > -                ml_gen_ordinary_pragma_foreign_proc(CodeModel, Attributes,
> > -                        PredId, ProcId, ArgVars, ArgDatas, OrigArgTypes,
> > -                        C_Code, OuterContext, MLDS_Decls, MLDS_Statements)
> > -        ).
> > +		ml_gen_ordinary_pragma_foreign_proc(CodeModel, Attributes,
> > +			PredId, ProcId, ArgVars, ArgDatas, OrigArgTypes,
> > +			C_Code, OuterContext, MLDS_Decls, MLDS_Statements)
> > +	).
> >  
> >  ml_gen_goal_expr(shorthand(_), _, _, _, _) -->
> >  	% these should have been expanded out by now
> 
> Are those all just whitespace changes?
> 
> Next time please do those separately, or use the `-b' option to `diff'.

Yeah, I will get rid of them since I didn't really mean to commit them.

> 
> > +:- pred ml_gen_ordinary_pragma_il_proc(code_model, 
> > +	pragma_foreign_proc_attributes, pred_id, proc_id, list(prog_var),
> > +	list(maybe(pair(string, mode))), list(prog_type), string, prog_context,
> > +	mlds__defns, mlds__statements, ml_gen_info, ml_gen_info).
> > +:- mode ml_gen_ordinary_pragma_il_proc(in, in, in, in, in, in, in, in, in,
> > +	out, out, in, out) is det.
> > +
> > +ml_gen_ordinary_pragma_il_proc(_CodeModel, Attributes,
> > +	PredId, ProcId, ArgVars, _ArgDatas, OrigArgTypes,
> > +	ForeignCode, Context, MLDS_Decls, MLDS_Statements) -->
> > +
> > +	{ MLDSContext = mlds__make_context(Context) },
> > +
> > +	=(MLDSGenInfo),
> > +	{ ml_gen_info_get_module_info(MLDSGenInfo, ModuleInfo) },
> > +	{ module_info_pred_proc_info(ModuleInfo, PredId, ProcId,
> > +			_PredInfo, ProcInfo) },
> > +	{ proc_info_varset(ProcInfo, VarSet) },
> > +%	{ proc_info_vartypes(ProcInfo, VarTypes) },
> > +	% note that for headvars we must use the types from
> > +	% the procedure interface, not from the procedure body
> > +	{ HeadVarTypes = map__from_corresponding_lists(ArgVars,
> > +		OrigArgTypes) },
> > +	{ ml_gen_info_get_byref_output_vars(MLDSGenInfo, ByRefOutputVars) },
> > +	{ ml_gen_info_get_value_output_vars(MLDSGenInfo, CopiedOutputVars) },
> > +	{ module_info_name(ModuleInfo, ModuleName) },
> > +	{ MLDSModuleName = mercury_module_name_to_mlds(ModuleName) },
> > +
> > +	{ list__filter_map(	
> > +		(pred(Var::in, Statement::out) is semidet :- 
> > +			map__lookup(HeadVarTypes, Var, Type),
> > +			not type_util__is_dummy_argument_type(Type),
> > +			VarName = mlds__var_name(VarNameString, _MangleInt),
> > +			MLDSType = mercury_type_to_mlds_type(ModuleInfo, Type),
> > +
> > +			VarName = ml_gen_var_name(VarSet, Var),
> > +			QualVarName = qual(MLDSModuleName, VarName),
> > +			OutputVarLval = mem_ref(lval(
> > +				var(QualVarName, MLDSType)), MLDSType),
> > +
> > +			NonMangledVarName = mlds__var_name(VarNameString, no),
> > +			QualLocalVarName= qual(MLDSModuleName,
> > +				NonMangledVarName),
> > +			LocalVarLval = var(QualLocalVarName, MLDSType),
> > +
> > +			Statement = ml_gen_assign(OutputVarLval,
> > +				lval(LocalVarLval), Context)
> > +		), ByRefOutputVars, ByRefAssignStatements) },
> 
> I think this code won't handle the case where the types in the
> procedure interface are polymorphic, but the types of the
> vars in the `foreign_proc' HLDS goal are concrete instances of
> those types, which can happen when the procedure is inlined
> or specialized.  The assignment that you generate here with
> ml_gen_assign won't be type-correct.  In general you may need
> to box/unbox the arguments.

Ok, this might be a bug, but I'm not sure how to test for this case and
generate the right code.

> > +:- func inline_code_to_il_asm(list(target_code_component)) = instr_tree.
> > +inline_code_to_il_asm([]) = empty.
> > +inline_code_to_il_asm([T | Ts]) = tree(Instrs, Rest) :-
> > +	( 
> > +		T = user_target_code(Code, MaybeContext, Attrs),
> > +		( yes(max_stack_size(N)) = get_max_stack_attribute(Attrs) ->
> > +			Instrs = tree__list([
> > +				( MaybeContext = yes(Context) ->
> > +					context_node(mlds__make_context(
> > +						Context))
> > +				;
> > +					empty
> > +				),
> > +				instr_node(il_asm_code(Code, N))
> > +				])
> > +		;
> > +			error(this_file ++ ": max_stack_size not set")
> > +		)
> > +	;
> > +		T = raw_target_code(Code, Attrs),
> > +		( yes(max_stack_size(N)) = get_max_stack_attribute(Attrs) ->
> > +			Instrs = instr_node(il_asm_code(Code, N))
> > +		;
> > +			error(this_file ++ ": max_stack_size not set")
> > +		)
> > +	;
> > +		T = target_code_input(_),
> > +		Instrs = empty
> > +	;
> > +		T = target_code_output(_),
> > +		Instrs = empty
> > +	;
> > +		T = name(_ `with_type` mlds__qualified_entity_name),
> 
> Is the explicit type qualifier really needed here?

Errr.. no.  Compiler was playing funny buggers with me for a while, but
it seem have all been sorted out now.  Move along.

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