Files
mercury/compiler/special_pred.m
Simon Taylor 3e244090d7 Rework the handling of types in higher_order.m.
Estimated hours taken: 50

Rework the handling of types in higher_order.m.
- Fix bugs in higher_order.m that stopped it working with --typeinfo-liveness.
- Perform type and typeclass specialisation.

compiler/polymorphism.m:
	Previously the type of typeclass_infos variables did not contain
	any information about the constraint about which the variable contains
	information. Now the type of a typeclass_info is
	`private_builtin:typeclass_info(
		private_builtin:constraint([ClassName, ConstrainedTypes]))'.
	This allows predicates such as type_list_subsumes to check that
	the class constraints match.
	Note that `private_builtin:constraint' has no declaration, so
	a lookup in the type definition map will fail. That's OK, because
	type_to_type_id will fail on it, so it will be treated as a type
	variable by any code which doesn't manipulate types directly.
	Added polymorphism__typeclass_info_class_constraint to get the
	class_constraint from a typeclass_info's type. This isn't used yet.

	Also, fix a bug in extract_type_info: an entry in the typeinfo_var_map
	was being overwritten using an entry from a dummy typevarset. Actually
	the optimization to overwrite the location of the type_info after
	extracting it from a typeclass_info was wrong because the type_info
	won't be in that location in other branches.

compiler/higher_order.m:
	Rework the handling of type substitutions. Now the types of the
	called procedure are `inlined' into the calling procedure, rather
	than building up the types of the specialised version using the
	higher-order arguments. The advantage of this is that the code is
	a bit simpler and handles extra type_infos properly. The disadvantage
	is that the argument types for specialised versions may be more
	specific than they need to be, so in some cases more specialised
	versions will be created than before.
	Also, don't actually rebuild the higher-order terms in the specialised
	versions - just pass the terms through in case they are needed.
	Handle the extra typeinfos required for --typeinfo-liveness.
	Specialize calls to unify/2, index/2 and compare/3.
	Specialize class_method_calls.
	Specialize calls to the predicates in private_builtin.m which
	manipulate typeclass_infos.

compiler/type_util.m:
	type_to_type_id now fails on the dummy `constraint' type.
	Remove typeinfos for non-variable types from the typeinfo_varmap
	after inlining and higher-order specialisation.

compiler/inlining.m:
	Factor out some common code to handle type substitutions
	for use by higher_order.m.

compiler/hlds_pred.m:
	Return the list of extra type_info variables added to the
	argument list.

compiler/goal_util.m:
	Take a set of non-locals as an argument to
	goal_util__extra_nonlocal_typeinfos rather than extracting
	them from a goal.

compiler/special_pred.m:
	Handle unmangled unify/compare/index in special_pred_get_type.

compiler/base_type_layout.m:
	Don't generate references to the typeinfo for
	`private_builtin:constraint' - it doesn't exist.

compiler/unused_args.m:
	Don't barf on specialised unification predicate names.

compiler/options.m:
	Added options:
	`--type-specialization' (default off).
	`--higher-order-size-limit' - restrict the size of specialized
		versions produced by higher_order.m.
	`--disable-opt-for-trace' (default on) - where possible don't
		change the options to make the trace match the source code.

compiler/handle_options.m:
	Don't disable higher_order.m when --typeinfo-liveness is set.
	Handle `--disable-opt-for-trace'.

compiler/hlds_data.m:
compiler/*.m:
	Add the instance number to `base_typeclass_info_const' cons_ids,
	so that higher_order.m can easily index into the list of instances
	for a class to find the methods.

compiler/hlds_out.m:
	Use the correct varset when printing out the constraint proofs.
	Write the typeclass_info_varmap for each procedure.

compiler/mercury_to_mercury.m:
	Print type variables with variable numbers.

library/private_builtin.m:
	Add the argument to the typeclass_info type to hold the representation
	of the constraint.

runtime/mercury_ho_call.c:
	Semidet and nondet class_method_calls where
	(0 < num_arg_typeclass_infos < 4) were aborting at runtime
	because arguments were being placed starting at r1 rather
	than at r(1 + num_arg_typeclass_infos).

doc/user_guide.texi
	Document the new options.

compiler/notes/compiler_design.html:
	Update the role of higher_order.m.

tests/hard_coded/typeclasses/extra_typeinfo.m:
	Test case for the mercury_ho_call.c bug and the polymorphism.m
	extract_typeinfo bug and for updating the typeclass_info_varmap
	for specialised versions.
1998-09-10 06:56:14 +00:00

115 lines
4.2 KiB
Mathematica

%-----------------------------------------------------------------------------%
% Copyright (C) 1995-1998 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.
%-----------------------------------------------------------------------------%
% file: special_pred.m
% main author: fjh
% Certain predicates are implicitly defined for every type by the compiler.
% This module defines most of the characteristics of those predicates.
% (The actual code for these predicates is generated in unify_proc.m.)
%-----------------------------------------------------------------------------%
:- module special_pred.
:- interface.
:- import_module prog_data, hlds_data, hlds_pred.
:- import_module list, map, std_util.
:- type special_pred_map == map(special_pred, pred_id).
:- type special_pred == pair(special_pred_id, type_id).
:- type special_pred_id
---> unify
; index
; compare.
:- pred special_pred_info(special_pred_id, type, string, list(type),
list(mode), determinism).
:- mode special_pred_info(in, in, out, out, out, out) is det.
% special_pred_name_arity(SpecialPredType, GenericPredName,
% TypeSpecificVersionPredName, Arity):
% true iff there is a special predicate of category
% SpecialPredType, called builtin:GenericPredName/Arity,
% for which the type-specific versions will be called
% TypeSpecificVersionPredName.
:- pred special_pred_name_arity(special_pred_id, string, string, int).
:- mode special_pred_name_arity(in, out, out, out) is det.
:- mode special_pred_name_arity(out, in, out, in) is semidet.
:- mode special_pred_name_arity(out, out, in, in) is semidet.
:- pred special_pred_mode_num(special_pred_id, int).
:- mode special_pred_mode_num(in, out) is det.
:- pred special_pred_list(list(special_pred_id)).
:- mode special_pred_list(out) is det.
:- pred special_pred_get_type(string, list(Type), Type).
:- mode special_pred_get_type(in, in, out) is semidet.
:- pred special_pred_description(special_pred_id, string).
:- mode special_pred_description(in, out) is det.
:- implementation.
:- import_module type_util, mode_util, prog_util.
special_pred_list([unify, index, compare]).
special_pred_name_arity(unify, "unify", "__Unify__", 2).
special_pred_name_arity(index, "index", "__Index__", 2).
special_pred_name_arity(compare, "compare", "__Compare__", 3).
% mode num for special procs is always 0 (the first mode)
special_pred_mode_num(_, 0).
special_pred_info(unify, Type, "__Unify__", [Type, Type], [In, In], semidet) :-
in_mode(In).
special_pred_info(index, Type, "__Index__", [Type, IntType], [In, Out], det) :-
construct_type(unqualified("int") - 0, [], IntType),
in_mode(In),
out_mode(Out).
special_pred_info(compare, Type,
"__Compare__", [ResType, Type, Type], [Uo, In, In], det) :-
mercury_public_builtin_module(PublicBuiltin),
construct_type(qualified(PublicBuiltin, "comparison_result") - 0,
[], ResType),
in_mode(In),
uo_mode(Uo).
% Given the mangled predicate name and the list of argument types,
% work out which type this special predicate is for.
% Note that this gets called after the polymorphism.m pass, so
% type_info arguments may have been inserted at the start; hence we
% find the type at a known position from the end of the list
% (by using list__reverse).
% Currently for most of the special predicates the type variable
% can be found in the last type argument, except for index, for
% which it is the second-last argument.
special_pred_get_type("__Unify__", Types, T) :-
list__reverse(Types, [T | _]).
special_pred_get_type("unify", Types, T) :-
list__reverse(Types, [T | _]).
special_pred_get_type("__Index__", Types, T) :-
list__reverse(Types, [_, T | _]).
special_pred_get_type("index", Types, T) :-
list__reverse(Types, [_, T | _]).
special_pred_get_type("__Compare__", Types, T) :-
list__reverse(Types, [T | _]).
special_pred_get_type("compare", Types, T) :-
list__reverse(Types, [T | _]).
special_pred_description(unify, "unification predicate").
special_pred_description(compare, "comparison predicate").
special_pred_description(index, "indexing predicate").
%-----------------------------------------------------------------------------%