[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