[m-dev.] for review: add `:- pragma type_spec' declarations to the library
Simon Taylor
stayl at cs.mu.OZ.AU
Fri Nov 3 19:12:31 AEDT 2000
Estimated hours taken: 5
Type specialize predicates in the library. This change
reduces the time taken by `mmc -C make_hlds' by 3-4%.
It increases the size of the compiler on murlibobo from
9.3M to 9.5M.
library/Mmakefile:
Add options to MCFLAGS for the modules containing
`:- pragma type_spec' declarations to make sure that
all calls to builtin_compare_int are inlined.
library/builtin.m:
Reorder the modes of compare/3 so that mode 0 of
compare/3 matches mode 0 of the compiler-generated
type specific compare predicates. higher_order.m
only specializes calls to compare/3 with mode
`compare(uo, in, in)' because that is the only mode
which the compiler-generated procedures have.
library/map.m:
library/tree234.m:
Type specialize predicates operating on maps with integer
or variable keys.
library/set.m:
library/set_ordlist.m:
library/list.m:
Type specialize predicates operating on sets of integers
or variables.
Index: Mmakefile
===================================================================
RCS file: /home/mercury1/repository/mercury/library/Mmakefile,v
retrieving revision 1.53
diff -u -u -r1.53 Mmakefile
--- Mmakefile 2000/08/17 05:31:07 1.53
+++ Mmakefile 2000/10/30 13:26:42
@@ -22,6 +22,17 @@
MCFLAGS-int = --no-halt-at-warn
+# Modules which use user-guided type specialization need to be
+# compiled with these flags to make sure all calls
+# to the builtin comparison routines are inlined.
+TYPE_SPEC_FLAGS = --deforestation --inline-vars-threshold 10000
+MCFLAGS-list = $(TYPE_SPEC_FLAGS)
+MCFLAGS-map = $(TYPE_SPEC_FLAGS)
+MCFLAGS-tree234 = $(TYPE_SPEC_FLAGS)
+MCFLAGS-set = $(TYPE_SPEC_FLAGS)
+MCFLAGS-set_ordlist = $(TYPE_SPEC_FLAGS)
+
#-----------------------------------------------------------------------------#
# If we're going to generate both `.$O' files and `.pic_o' files, then
Index: builtin.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/builtin.m,v
retrieving revision 1.42
diff -u -u -r1.42 builtin.m
--- builtin.m 2000/10/31 07:54:00 1.42
+++ builtin.m 2000/11/02 05:50:55
@@ -171,10 +171,11 @@
% depending on wheither X is =, <, or > Y in the
% standard ordering.
:- pred compare(comparison_result, T, T).
+ % This mode must be first -- compiler/higher_order.m depends on it.
+:- mode compare(uo, in, in) is det.
:- mode compare(uo, ui, ui) is det.
:- mode compare(uo, ui, in) is det.
:- mode compare(uo, in, ui) is det.
-:- mode compare(uo, in, in) is det.
% In addition, the following predicate-like constructs are builtin:
%
Index: library.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/library.m,v
retrieving revision 1.51
diff -u -u -r1.51 library.m
--- library.m 2000/10/16 01:33:46 1.51
+++ library.m 2000/10/30 13:26:43
@@ -30,8 +30,9 @@
:- import_module bt_array, char, counter, dir, eqvclass, float.
:- import_module math, getopt, graph, group, int.
:- import_module io, list, map, multi_map, pqueue, queue, random, relation.
-:- import_module require, set, set_bbbtree, set_ordlist, set_unordlist, stack.
-:- import_module std_util, string, term, term_io, tree234, varset.
+:- import_module require, set, set_bbbtree, set_ordlist, set_unordlist.
+:- import_module sparse_bitset, stack, std_util, string, term, term_io.
+:- import_module tree234, varset.
:- import_module store, rbtree, parser, lexer, ops.
:- import_module prolog.
:- import_module integer, rational.
Index: list.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/list.m,v
retrieving revision 1.94
diff -u -u -r1.94 list.m
--- list.m 2000/09/27 08:01:12 1.94
+++ list.m 2000/10/30 13:26:44
@@ -15,6 +15,7 @@
:- module list.
:- interface.
:- import_module int.
+:- import_module term. % for var/1.
%-----------------------------------------------------------------------------%
@@ -102,6 +103,7 @@
% in ascending order. L1 and L2 must be sorted.
:- pred list__merge(list(T), list(T), list(T)).
:- mode list__merge(in, in, out) is det.
+:- pragma type_spec(list__merge(in, in, out), T = var(_)).
% list__merge_and_remove_dups(L1, L2, L):
% L is the result of merging the elements of L1 and L2,
@@ -110,12 +112,14 @@
% duplicates.
:- pred list__merge_and_remove_dups(list(T), list(T), list(T)).
:- mode list__merge_and_remove_dups(in, in, out) is det.
+:- pragma type_spec(list__merge_and_remove_dups(in, in, out), T = var(_)).
% list__remove_adjacent_dups(L0, L) :
% L is the result of replacing every sequence of duplicate
% elements in L0 with a single such element.
:- pred list__remove_adjacent_dups(list(T), list(T)).
:- mode list__remove_adjacent_dups(in, out) is det.
+:- pragma type_spec(list__remove_adjacent_dups/2, T = var(_)).
% list__remove_dups(L0, L) :
% L is the result of deleting the second and subsequent
@@ -128,6 +132,7 @@
:- pred list__member(T, list(T)).
:- mode list__member(in, in) is semidet.
:- mode list__member(out, in) is nondet.
+:- pragma type_spec(list__member(in, in), T = var(_)).
% list__member(Elem, List, SubList) :
% True iff `List' contains `Elem', and `SubList' is
@@ -269,12 +274,14 @@
%
:- pred list__sort_and_remove_dups(list(T), list(T)).
:- mode list__sort_and_remove_dups(in, out) is det.
+:- pragma type_spec(list__sort_and_remove_dups/2, T = var(_)).
% list__sort(List0, List):
% List is List0 sorted.
%
:- pred list__sort(list(T), list(T)).
:- mode list__sort(in, out) is det.
+:- pragma type_spec(list__sort(in, out), T = var(_)).
% list__reverse(List, Reverse):
% `Reverse' is a list containing the same elements as `List'
@@ -798,6 +805,7 @@
:- pred list__merge_sort(list(T), list(T)).
:- mode list__merge_sort(in, out) is det.
+:- pragma type_spec(list__merge_sort(in, out), T = var(_)).
list__merge_sort([], []).
list__merge_sort([X], [X]).
@@ -842,6 +850,7 @@
:- pred list__remove_adjacent_dups_2(list(T), T, list(T)).
:- mode list__remove_adjacent_dups_2(in, in, out) is det.
+:- pragma type_spec(list__remove_adjacent_dups_2/3, T = var(_)).
list__remove_adjacent_dups_2([], X, [X]).
list__remove_adjacent_dups_2([X1|Xs], X0, L) :-
@@ -1190,8 +1199,10 @@
:- func list__merge(list(T), list(T)) = list(T).
:- func list__merge_and_remove_dups(list(T), list(T)) = list(T).
+:- pragma type_spec(list__merge_and_remove_dups/2, T = var(_)).
:- func list__remove_adjacent_dups(list(T)) = list(T).
+:- pragma type_spec(list__remove_adjacent_dups/1, T = var(_)).
:- func list__remove_dups(list(T)) = list(T).
@@ -1208,8 +1219,10 @@
:- func list__replace_nth_det(list(T), int, T) = list(T).
:- func list__sort_and_remove_dups(list(T)) = list(T).
+:- pragma type_spec(list__sort_and_remove_dups/1, T = var(_)).
:- func list__sort(list(T)) = list(T).
+:- pragma type_spec(list__sort/1, T = var(_)).
:- func list__reverse(list(T)) = list(T).
Index: map.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/map.m,v
retrieving revision 1.76
diff -u -u -r1.76 map.m
--- map.m 2000/10/03 02:21:38 1.76
+++ map.m 2000/10/30 15:15:01
@@ -23,6 +23,7 @@
:- module map.
:- interface.
:- import_module set, list, assoc_list.
+:- import_module term. % for var/1.
%-----------------------------------------------------------------------------%
@@ -48,10 +49,14 @@
% Search map for key.
:- pred map__search(map(K,V), K, V).
:- mode map__search(in, in, out) is semidet.
+:- pragma type_spec(map__search/3, K = var(_)).
+:- pragma type_spec(map__search/3, K = int).
% Search map for key, but abort if search fails.
:- pred map__lookup(map(K,V), K, V).
:- mode map__lookup(in, in, out) is det.
+:- pragma type_spec(map__lookup/3, K = var(_)).
+:- pragma type_spec(map__lookup/3, K = int).
:- pred map__lower_bound_search(map(K,V), K, K, V).
:- mode map__lower_bound_search(in, in, out, out) is semidet.
@@ -104,6 +109,7 @@
:- pred map__set(map(K,V), K, V, map(K,V)).
:- mode map__set(di, di, di, uo) is det.
:- mode map__set(in, in, in, out) is det.
+:- pragma type_spec(map__set(in, in, in, out), K = var(_)).
% Given a map, return a list of all the keys in the map.
:- pred map__keys(map(K, _V), list(K)).
@@ -175,12 +181,14 @@
% over MapA.
:- pred map__overlay(map(K,V), map(K,V), map(K,V)).
:- mode map__overlay(in, in, out) is det.
+:- pragma type_spec(map__overlay/3, K = var(_)).
% map__select takes a map and a set of keys and returns
% a map containing the keys in the set and their corresponding
% values.
:- pred map__select(map(K,V), set(K), map(K,V)).
:- mode map__select(in, in, out) is det.
+:- pragma type_spec(map__select/3, K = var(_)).
% Given a list of keys, produce a list of their corresponding
% values in a specified map.
@@ -460,6 +468,7 @@
:- pred map__overlay_2(assoc_list(K,V), map(K,V), map(K,V)).
:- mode map__overlay_2(in, in, out) is det.
+:- pragma type_spec(map__overlay_2/3, K = var(_)).
map__overlay_2([], Map, Map).
map__overlay_2([K - V | AssocList], Map0, Map) :-
@@ -475,6 +484,7 @@
:- pred map__select_2(list(K), map(K,V), map(K,V), map(K,V)).
:- mode map__select_2(in, in, in, out) is det.
+:- pragma type_spec(map__select_2/4, K = var(_)).
map__select_2([], _Original, New, New).
map__select_2([K|Ks], Original, New0, New) :-
@@ -642,8 +652,12 @@
:- mode map__init = uo is det.
:- func map__search(map(K,V), K) = V is semidet.
+:- pragma type_spec(map__search/2, K = var(_)).
+:- pragma type_spec(map__search/2, K = int).
:- func map__lookup(map(K,V), K) = V.
+:- pragma type_spec(map__lookup/2, K = var(_)).
+:- pragma type_spec(map__lookup/2, K = int).
:- func map__insert(map(K,V), K, V) = map(K,V) is semidet.
@@ -659,6 +673,7 @@
:- func map__det_update(map(K,V), K, V) = map(K,V).
:- func map__set(map(K,V), K, V) = map(K,V).
+:- pragma type_spec(map__set/3, K = var(_)).
:- func map__keys(map(K, _V)) = list(K).
@@ -685,8 +700,10 @@
:- func map__merge(map(K, V), map(K, V)) = map(K, V).
:- func map__overlay(map(K,V), map(K,V)) = map(K,V).
+:- pragma type_spec(map__overlay/2, K = var(_)).
:- func map__select(map(K,V), set(K)) = map(K,V).
+:- pragma type_spec(map__select/2, K = var(_)).
:- func map__apply_to_list(list(K), map(K, V)) = list(V).
Index: set.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/set.m,v
retrieving revision 1.52
diff -u -u -r1.52 set.m
--- set.m 2000/07/19 03:42:41 1.52
+++ set.m 2000/10/30 13:26:45
@@ -20,6 +20,7 @@
:- module set.
:- interface.
:- import_module bool, list.
+:- import_module term. % for var/1.
:- type set(T).
@@ -28,8 +29,10 @@
:- pred set__list_to_set(list(T), set(T)).
:- mode set__list_to_set(in, out) is det.
+:- pragma type_spec(set__list_to_set/2, T = var(_)).
:- func set__list_to_set(list(T)) = set(T).
+:- pragma type_spec(set__list_to_set/1, T = var(_)).
% `set__sorted_list_to_set(List, Set)' is true iff `Set' is the set
% containing only the members of `List'. `List' must be sorted
@@ -93,6 +96,7 @@
:- pred set__member(T, set(T)).
:- mode set__member(in, in) is semidet.
:- mode set__member(out, in) is nondet.
+:- pragma type_spec(set__member(in, in), T = var(_)).
% `set_is_member(X, Set, Result)' returns
% `Result = yes' iff `X' is a member of `Set'.
@@ -106,20 +110,24 @@
:- pred set__insert(set(T), T, set(T)).
:- mode set__insert(di, di, uo) is det.
:- mode set__insert(in, in, out) is det.
+:- pragma type_spec(set__insert/3, T = var(_)).
% XXX rwab1: I think we should reverse the args. here for
% higher order programming.
:- func set__insert(set(T), T) = set(T).
+:- pragma type_spec(set__insert/2, T = var(_)).
% `set__insert_list(Set0, Xs, Set)' is true iff `Set' is the union of
% `Set0' and the set containing only the members of `Xs'.
:- pred set__insert_list(set(T), list(T), set(T)).
:- mode set__insert_list(in, in, out) is det.
+:- pragma type_spec(set__insert_list/3, T = var(_)).
% XXX rwab1: I think we should reverse the args. here for
% higher order programming.
:- func set__insert_list(set(T), list(T)) = set(T).
+:- pragma type_spec(set__insert_list/2, T = var(_)).
% `set__delete(Set0, X, Set)' is true iff `Set' is the relative
% complement of `Set0' and the set containing only `X', i.e.
@@ -181,8 +189,10 @@
:- pred set__union(set(T), set(T), set(T)).
:- mode set__union(in, in, out) is det.
+:- pragma type_spec(set__union/3, T = var(_)).
:- func set__union(set(T), set(T)) = set(T).
+:- pragma type_spec(set__union/2, T = var(_)).
% `set__power_union(A, B)' is true iff `B' is the union of
% all the sets in `A'
@@ -204,8 +214,10 @@
:- pred set__intersect(set(T), set(T), set(T)).
:- mode set__intersect(in, in, out) is det.
+:- pragma type_spec(set__intersect/3, T = var(_)).
:- func set__intersect(set(T), set(T)) = set(T).
+:- pragma type_spec(set__intersect/2, T = var(_)).
% `set__power_intersect(A, B)' is true iff `B' is the intersection of
% all the sets in `A'
@@ -221,8 +233,10 @@
:- pred set__difference(set(T), set(T), set(T)).
:- mode set__difference(in, in, out) is det.
+:- pragma type_spec(set__difference/3, T = var(_)).
:- func set__difference(set(T), set(T)) = set(T).
+:- pragma type_spec(set__difference/2, T = var(_)).
% `set__count(Set, Count)' is true iff `Set' has `Count' elements.
Index: set_ordlist.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/set_ordlist.m,v
retrieving revision 1.9
diff -u -u -r1.9 set_ordlist.m
--- set_ordlist.m 1999/10/30 04:16:07 1.9
+++ set_ordlist.m 2000/10/30 13:26:45
@@ -16,6 +16,7 @@
:- module set_ordlist.
:- interface.
:- import_module bool, list.
+:- import_module term. % for var/1.
:- type set_ordlist(_T).
@@ -24,6 +25,7 @@
:- pred set_ordlist__list_to_set(list(T), set_ordlist(T)).
:- mode set_ordlist__list_to_set(in, out) is det.
+:- pragma type_spec(set_ordlist__list_to_set/2, T = var(_)).
% `set_ordlist__sorted_list_to_set(List, Set)' is true iff `Set' is
% the set containing only the members of `List'. `List' must be sorted.
@@ -77,6 +79,7 @@
:- pred set_ordlist__member(T, set_ordlist(T)).
:- mode set_ordlist__member(in, in) is semidet.
:- mode set_ordlist__member(out, in) is nondet.
+:- pragma type_spec(set_ordlist__member(in, in), T = var(_)).
% `set_ordlist__is_member(X, Set, Result)' returns
% `Result = yes' iff `X' is a member of `Set'.
@@ -90,12 +93,14 @@
:- pred set_ordlist__insert(set_ordlist(T), T, set_ordlist(T)).
:- mode set_ordlist__insert(di, di, uo) is det.
:- mode set_ordlist__insert(in, in, out) is det.
+:- pragma type_spec(set_ordlist__insert/3, T = var(_)).
% `set_ordlist__insert_list(Set0, Xs, Set)' is true iff `Set' is the
% union of `Set0' and the set containing only the members of `Xs'.
:- pred set_ordlist__insert_list(set_ordlist(T), list(T), set_ordlist(T)).
:- mode set_ordlist__insert_list(in, in, out) is det.
+:- pragma type_spec(set_ordlist__insert_list/3, T = var(_)).
% `set_ordlist__delete(Set0, X, Set)' is true iff `Set' is the
% relative complement of `Set0' and the set containing only `X', i.e.
@@ -144,6 +149,7 @@
:- pred set_ordlist__union(set_ordlist(T), set_ordlist(T),
set_ordlist(T)).
:- mode set_ordlist__union(in, in, out) is det.
+:- pragma type_spec(set_ordlist__union/3, T = var(_)).
% `set_ordlist__power_union(A, B)' is true iff `B' is the union of
% all the sets in `A'
@@ -160,6 +166,7 @@
set_ordlist(T)).
:- mode set_ordlist__intersect(in, in, out) is det.
:- mode set_ordlist__intersect(in, in, in) is semidet.
+:- pragma type_spec(set_ordlist__intersect/3, T = var(_)).
% `set_ordlist__power_intersect(A, B)' is true iff `B' is the
% intersection of all the sets in `A'.
@@ -175,6 +182,7 @@
:- pred set_ordlist__difference(set_ordlist(T), set_ordlist(T),
set_ordlist(T)).
:- mode set_ordlist__difference(in, in, out) is det.
+:- pragma type_spec(set_ordlist__difference/3, T = var(_)).
% `set_ordlist__count(Set, Count)' is true iff `Set' has
% `Count' elements.
Index: tree234.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/tree234.m,v
retrieving revision 1.32
diff -u -u -r1.32 tree234.m
--- tree234.m 2000/10/03 02:21:38 1.32
+++ tree234.m 2000/10/30 15:16:19
@@ -17,6 +17,7 @@
:- interface.
:- import_module list, assoc_list.
+:- import_module term. % for var/1.
:- type tree234(K, V).
@@ -31,9 +32,12 @@
:- pred tree234__search(tree234(K, V), K, V).
:- mode tree234__search(in, in, out) is semidet.
+:- pragma type_spec(tree234__search/3, K = var(_)).
+:- pragma type_spec(tree234__search/3, K = int).
:- pred tree234__lookup(tree234(K, V), K, V).
:- mode tree234__lookup(in, in, out) is det.
+:- pragma type_spec(tree234__lookup/3, K = var(_)).
:- pred tree234__lower_bound_search(tree234(K, V), K, K, V).
:- mode tree234__lower_bound_search(in, in, out, out) is semidet.
@@ -56,6 +60,7 @@
:- mode tree234__set(di, di, di, uo) is det.
% :- mode tree234__set(di_tree234, in, in, uo_tree234) is det.
:- mode tree234__set(in, in, in, out) is det.
+:- pragma type_spec(tree234__set(in, in, in, out), K = var(_)).
:- pred tree234__delete(tree234(K, V), K, tree234(K, V)).
:- mode tree234__delete(di, in, uo) is det.
@@ -1170,6 +1175,7 @@
:- mode tree234__set2(di_two, di, di, uo) is det.
% :- mode tree234__set2(sdi_two, in, in, uo_tree234) is det.
:- mode tree234__set2(in_two, in, in, out) is det.
+:- pragma type_spec(tree234__set2(in_two, in, in, out), K = var(_)).
tree234__set2(two(K0, V0, T0, T1), K, V, Tout) :-
(
@@ -1267,6 +1273,7 @@
:- mode tree234__set3(di_three, di, di, uo) is det.
% :- mode tree234__set3(sdi_three, in, in, uo_tree234) is det.
:- mode tree234__set3(in_three, in, in, out) is det.
+:- pragma type_spec(tree234__set3(in_three, in, in, out), K = var(_)).
tree234__set3(three(K0, V0, K1, V1, T0, T1, T2), K, V, Tout) :-
(
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to: mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions: mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------
More information about the developers
mailing list