User-guided type specialization.

Estimated hours taken: 60

User-guided type specialization.

compiler/prog_data.m:
compiler/prog_io_pragma.m:
compiler/modules.m:
compiler/module_qual.m:
compiler/mercury_to_mercury.m:
	Handle `:- pragma type_spec'.

compiler/prog_io_pragma.m:
	Factor out some common code to parse predicate names with arguments.

compiler/hlds_module.m:
	Added a field to the module_sub_info to hold information about
	user-requested type specializations, filled in by make_hlds.m
	and not used by anything after higher_order.m.

compiler/make_hlds.m:
	For each `:- pragma type_spec' declaration, introduce a new predicate
	which just calls the predicate to be specialized with the
	specified argument types. This forces higher_order.m to produce
	the specialized versions.

compiler/higher_order.m:
	Process the user-requested type specializations first to ensure
	that they get the correct names.
	Allow partial matches against user-specified versions, e.g.
		map__lookup(map(int, list(int)), int, list(int)) matches
		map__lookup(map(int, V), int, V).
	Perform specialization where a typeclass constraint matches a
	known instance, but the construction of the typeclass_info is
	done in the calling module.
	Give slightly more informative progress messages.

compiler/dead_proc_elim.m:
	Remove specializations for dead procedures.

compiler/prog_io_util.m:
	Change the definition of the `maybe1' and `maybe_functor' types
	to avoid the need for copying to convert between `maybe1'
	and `maybe1(generic)'.
	Changed the interface of `make_pred_name_with_context' to allow
	creation of predicate names for type specializations which describe
	the type substitution.

compiler/make_hlds.m:
compiler/prog_io_pragma.m:
	Make the specification of pragma declarations in error
	messages consistent. (There are probably some more to
	be fixed elsewhere for termination and tabling).

compiler/intermod.m:
	Write type specialization pragmas for predicates declared
	in `.opt' files.

compiler/mercury_to_mercury.m:
	Export `mercury_output_item' for use by intermod.m.

compiler/options.m:
	Add an option `--user-guided-type-specialization' enabled
	with `-O2' or higher.

compiler/handle_options.m:
	`--type-specialization' implies `--user-guided-type-specialization'.

compiler/hlds_goal.m:
	Add predicates to construct constants. These are duplicated
	in several other places, I'll fix that as a separate change.

compiler/type_util.m:
	Added functions `int_type/0', `string_type/0', `float_type/0'
	and `char_type/0' which return the builtin types.
	These are duplicated in several other places,
	I'll fix that as a separate change.

library/private_builtin.m:
	Added `instance_constraint_from_typeclass_info/3' to extract
	the typeclass_infos for a constraint on an instance declaration.
	This is useful for specializing class method calls.
	Added `thread_safe' to various `:- pragma c_code's.
	Added `:- pragma inline' declarations for `builtin_compare_*', which
	are important for user-guided type specialization. (`builtin_unify_*'
	are simple enough to go in the `.opt' files automatically).

compiler/polymorphism.m:
	`instance_constraint_from_typeclass_info/3' does not need type_infos.
	Add `instance_constraint_from_typeclass_info/3' to the
	list of `typeclass_info_manipulator's which higher_order.m
	can interpret.

NEWS:
doc/reference_manual.texi:
doc/user_guide.texi
	Document the new pragma and option.

tests/invalid/Mmakefile:
tests/invalid/type_spec.m:
tests/invalid/type_spec.err_exp:
	Test error reporting for invalid type specializations.

tests/hard_coded/Mmakefile:
tests/invalid/type_spec.m:
tests/invalid/type_spec.exp:
	Test type specialization.
This commit is contained in:
Simon Taylor
1999-04-23 01:03:51 +00:00
parent 425b5e5022
commit 79dcbbef15
32 changed files with 2448 additions and 805 deletions

View File

@@ -1,5 +1,5 @@
%-----------------------------------------------------------------------------%
% Copyright (C) 1994-1998 The University of Melbourne.
% Copyright (C) 1994-1999 The University of Melbourne.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%-----------------------------------------------------------------------------%
@@ -73,6 +73,15 @@
%-----------------------------------------------------------------------------%
% make_pred_name_with_context(ModuleName, Prefix, PredOrFunc, PredName,
% Line, Counter, SymName).
%
% Create a predicate name with context, e.g. for introduced
% lambda or deforestation predicates.
:- pred make_pred_name(module_name, string, maybe(pred_or_func),
string, new_pred_id, sym_name).
:- mode make_pred_name(in, in, in, in, in, out) is det.
% make_pred_name_with_context(ModuleName, Prefix, PredOrFunc, PredName,
% Line, Counter, SymName).
%
@@ -82,6 +91,11 @@
string, int, int, sym_name).
:- mode make_pred_name_with_context(in, in, in, in, in, in, out) is det.
:- type new_pred_id
---> counter(int, int) % Line number, Counter
; type_subst(tvarset, type_subst)
.
%-----------------------------------------------------------------------------%
% A pred declaration may contains just types, as in
@@ -113,8 +127,8 @@
%-----------------------------------------------------------------------------%
:- implementation.
:- import_module (inst).
:- import_module bool, string, int, map.
:- import_module mercury_to_mercury, (inst).
:- import_module bool, string, int, map, varset.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -306,15 +320,62 @@ match_sym_name(unqualified(Name), qualified(_, Name)).
make_pred_name_with_context(ModuleName, Prefix,
PredOrFunc, PredName, Line, Counter, SymName) :-
make_pred_name(ModuleName, Prefix, yes(PredOrFunc), PredName,
counter(Line, Counter), SymName).
make_pred_name(ModuleName, Prefix, MaybePredOrFunc, PredName,
NewPredId, SymName) :-
(
PredOrFunc = predicate,
PFS = "pred"
MaybePredOrFunc = yes(PredOrFunc),
(
PredOrFunc = predicate,
PFS = "pred"
;
PredOrFunc = function,
PFS = "func"
)
;
PredOrFunc = function,
PFS = "func"
MaybePredOrFunc = no,
PFS = "pred_or_func"
),
string__format("%s__%s__%s__%d__%d",
[s(Prefix), s(PFS), s(PredName), i(Line), i(Counter)], Name),
(
NewPredId = counter(Line, Counter),
string__format("%d__%d", [i(Line), i(Counter)], PredIdStr)
;
NewPredId = type_subst(VarSet, TypeSubst),
SubstToString = lambda([SubstElem::in, SubstStr::out] is det, (
SubstElem = Var - Type,
varset__lookup_name(VarSet, Var, VarName),
mercury_type_to_string(VarSet, Type, TypeString),
string__append_list([VarName, " = ", TypeString],
SubstStr)
)),
list_to_string(SubstToString, TypeSubst, PredIdStr)
),
string__format("%s__%s__%s__%s",
[s(Prefix), s(PredIdStr), s(PFS), s(PredName)], Name),
SymName = qualified(ModuleName, Name).
:- pred list_to_string(pred(T, string), list(T), string).
:- mode list_to_string(pred(in, out) is det, in, out) is det.
list_to_string(Pred, List, String) :-
list_to_string_2(Pred, List, Strings, ["]"]),
string__append_list(["[" | Strings], String).
:- pred list_to_string_2(pred(T, string), list(T), list(string), list(string)).
:- mode list_to_string_2(pred(in, out) is det, in, out, in) is det.
list_to_string_2(_, []) --> [].
list_to_string_2(Pred, [T | Ts]) -->
{ call(Pred, T, String) },
[String],
( { Ts = [] } ->
[]
;
[", "],
list_to_string_2(Pred, Ts)
).
%-----------------------------------------------------------------------------%