[m-dev.] diff: fix bug in type specialization

Simon Taylor stayl at cs.mu.OZ.AU
Wed Oct 11 10:40:23 AEDT 2000



Estimated hours taken: 2

Make sure that type specializations requested by `:- pragma type_spec'
declarations are always produced, even if
`--no-user-guided-type-specialization' is passed
to the compiler. This avoids link errors or runtime aborts
if calling modules are compiled with type specialization.

compiler/mercury_compile.m:
compiler/higher_order.m:
	Always process `:- pragma type_spec' declarations.

tests/hard_coded/typeclasses/Mmakefile:
tests/hard_coded/typeclasses/type_spec.m:
tests/hard_coded/typeclasses/type_spec_2.m:
tests/hard_coded/typeclasses/type_spec.exp:
	Test case.


Index: compiler/higher_order.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/higher_order.m,v
retrieving revision 1.75
diff -u -u -r1.75 higher_order.m
--- compiler/higher_order.m	2000/10/06 10:18:17	1.75
+++ compiler/higher_order.m	2000/10/10 23:15:17
@@ -61,7 +61,9 @@
 	{ map__init(NewPredMap) },
 	{ map__init(PredVarMap) },
 	{ NewPreds0 = new_preds(NewPredMap, PredVarMap) },
+	{ NextHOid0 = 1 },
 	{ map__init(GoalSizes0) },
+	{ set__init(Requests0) },
 
 	{ module_info_predids(ModuleInfo0, PredIds0) },
 	{ module_info_type_spec_info(ModuleInfo0,
@@ -70,30 +72,50 @@
 	%
 	% Make sure the user requested specializations are processed first,
 	% since we don't want to create more versions if one of these
-	% matches.
-	%
-	{ set__list_to_set(PredIds0, PredIdSet0) },
-	{ set__difference(PredIdSet0, UserSpecPreds, PredIdSet) },
-	{ set__to_sorted_list(PredIdSet, PredIds) },
-
-	{ set__init(Requests0) },
-	{ set__to_sorted_list(UserSpecPreds, UserSpecPredList) },
-	{ get_specialization_requests(Params, UserSpecPredList, NewPreds0,
-		Requests0, UserRequests, GoalSizes0, GoalSizes1,
-		ModuleInfo0, ModuleInfo1) },
-	process_requests(Params, UserRequests, Requests1,
-		GoalSizes1, 1, NextHOid, NewPreds0, NewPreds1,
-		ModuleInfo1, ModuleInfo2),
-
-	%
-	% Process all other specialization until no more requests
-	% are generated.
+	% matches. We need to process these even if specialization is
+	% not being performed in case any of the specialized versions
+	% are called from other modules.
 	%
-	{ get_specialization_requests(Params, PredIds, NewPreds1,
-		Requests1, Requests, GoalSizes1, GoalSizes,
-		ModuleInfo2, ModuleInfo3) },
-	recursively_process_requests(Params, Requests, GoalSizes,
-		NextHOid, _, NewPreds1, _NewPreds, ModuleInfo3, ModuleInfo4),
+	( { set__empty(UserSpecPreds) } ->
+		{ GoalSizes1 = GoalSizes0 },
+		{ ModuleInfo2 = ModuleInfo0 },
+		{ NewPreds1 = NewPreds0 },
+		{ NextHOid = NextHOid0 },
+		{ UserSpecPredList = [] },
+		{ PredIds = PredIds0 },
+		{ Requests1 = Requests0 }
+	;
+		{ set__list_to_set(PredIds0, PredIdSet0) },
+		{ set__difference(PredIdSet0, UserSpecPreds, PredIdSet) },
+		{ set__to_sorted_list(PredIdSet, PredIds) },
+
+		{ set__to_sorted_list(UserSpecPreds, UserSpecPredList) },
+		{ UserTypeSpec0 = yes },
+		{ Params0 = ho_params(HigherOrder, TypeSpec,
+			UserTypeSpec0, SizeLimit, unit) },
+		{ get_specialization_requests(Params0, UserSpecPredList,
+			NewPreds0, Requests0, UserRequests,
+			GoalSizes0, GoalSizes1, ModuleInfo0, ModuleInfo1) },
+		process_requests(Params, UserRequests, Requests1,
+			GoalSizes1, NextHOid0, NextHOid, NewPreds0, NewPreds1,
+			ModuleInfo1, ModuleInfo2)
+	),
+
+	( { bool__or_list([HigherOrder, TypeSpec, UserTypeSpec], yes) } ->
+
+		%
+		% Process all other specializations until no more requests
+		% are generated.
+		%
+		{ get_specialization_requests(Params, PredIds, NewPreds1,
+			Requests1, Requests, GoalSizes1, GoalSizes,
+			ModuleInfo2, ModuleInfo3) },
+		recursively_process_requests(Params, Requests, GoalSizes,
+			NextHOid, _, NewPreds1, _NewPreds,
+			ModuleInfo3, ModuleInfo4)
+	;
+		{ ModuleInfo4 = ModuleInfo2 }
+	),
 
 	% Remove the predicates which were used to force the production of
 	% user-requested type specializations, since they are not called
@@ -288,6 +310,7 @@
 	;	unchanged.	% Do nothing more for this predicate
 
 %-----------------------------------------------------------------------------%
+
 :- pred get_specialization_requests(ho_params::in, list(pred_id)::in,
 	new_preds::in, set(request)::in, set(request)::out, goal_sizes::in,
 	goal_sizes::out, module_info::in, module_info::out) is det.
Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mercury_compile.m,v
retrieving revision 1.179
diff -u -u -r1.179 mercury_compile.m
--- compiler/mercury_compile.m	2000/10/03 00:34:19	1.179
+++ compiler/mercury_compile.m	2000/10/10 23:17:58
@@ -1794,7 +1794,13 @@
 	% --type-specialization implies --user-guided-type-specialization.
 	globals__io_lookup_bool_option(user_guided_type_specialization, Types),
 
-	( { HigherOrder = yes ; Types = yes } ->
+	% Always produce the specialized versions for which
+	% `:- pragma type_spec' declarations exist, because
+	% importing modules might call them.
+	{ module_info_type_spec_info(HLDS0, TypeSpecInfo) },
+	{ TypeSpecInfo = type_spec_info(TypeSpecPreds, _, _, _) },
+
+	( { HigherOrder = yes ; Types = yes ; \+ set__empty(TypeSpecPreds) } ->
 		maybe_write_string(Verbose,
 		"% Specializing higher-order and polymorphic predicates...\n"),
 		maybe_flush_output(Verbose),
Index: tests/hard_coded/typeclasses/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/typeclasses/Mmakefile,v
retrieving revision 1.37
diff -u -u -r1.37 Mmakefile
--- tests/hard_coded/typeclasses/Mmakefile	2000/09/18 11:52:55	1.37
+++ tests/hard_coded/typeclasses/Mmakefile	2000/10/10 06:37:28
@@ -56,15 +56,18 @@
 #	complicated_constraint --
 #		because we don't support that feature yet
 
+MCFLAGS-abstract_instance = --infer-all
+MCFLAGS-existential_type_classes = --infer-all
 MCFLAGS-extra_typeinfo = --optimize-higher-order --no-type-specialization \
 				--body-typeinfo-liveness
 MCFLAGS-inference_test = --infer-all
 MCFLAGS-inference_test_2 = --infer-all
-MCFLAGS-existential_type_classes = --infer-all
 MCFLAGS-intermod_typeclass_bug = --intermodule-optimization
 MCFLAGS-intermod_typeclass_bug2 = --intermodule-optimization
 MCFLAGS-lambda_multi_constraint_same_tvar = --infer-all
-MCFLAGS-abstract_instance = --infer-all
+
+	# Check that the exported specialized versions are still created.
+MCFLAGS-type_spec_2 = --no-user-guided-type-specialization
 MCFLAGS-unbound_tvar = --no-user-guided-type-specialisation
 MCFLAGS-unqualified_method = --intermodule-optimization
 MCFLAGS-unqualified_method2 = --intermodule-optimization
Index: tests/hard_coded/typeclasses/type_spec.exp
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/typeclasses/type_spec.exp,v
retrieving revision 1.1
diff -u -u -r1.1 type_spec.exp
--- tests/hard_coded/typeclasses/type_spec.exp	2000/05/09 10:48:55	1.1
+++ tests/hard_coded/typeclasses/type_spec.exp	2000/10/10 23:26:01
@@ -7,3 +7,4 @@
 Succeeded
 Failed
 Succeeded
+Succeeded
Index: tests/hard_coded/typeclasses/type_spec.m
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/typeclasses/type_spec.m,v
retrieving revision 1.1
diff -u -u -r1.1 type_spec.m
--- tests/hard_coded/typeclasses/type_spec.m	2000/05/09 10:48:56	1.1
+++ tests/hard_coded/typeclasses/type_spec.m	2000/10/10 06:35:14
@@ -62,6 +62,8 @@
 
 :- implementation.
 
+:- import_module type_spec_2.
+
 main -->
 	{ type_spec([1,2,3], [3,4,5], Result1) },
 	io__write(Result1),
@@ -103,9 +105,12 @@
 		io__write_string("Succeeded\n")
 	;
 		io__write_string("Failed\n")
+	),
+	( { no_type_spec([1, 2, 3], [1, 2, 3]) } ->
+		io__write_string("Succeeded\n")
+	;
+		io__write_string("Failed\n")
 	).
-
-
 
 type_spec([], [], []).
 type_spec([_ | _], [], []).
Index: tests/hard_coded/typeclasses/type_spec_2.m
===================================================================
RCS file: type_spec_2.m
diff -N type_spec_2.m
--- /dev/null	Wed Oct 11 10:29:26 2000
+++ type_spec_2.m	Tue Oct 10 17:39:23 2000
@@ -0,0 +1,15 @@
+% This module should be compiled with `--no-user-guided-type-specialization'
+% to check that the declared specializations are still created, to avoid
+% link errors if importing modules are compiled with type specialization.
+:- module type_spec_2.
+
+:- interface.
+
+:- import_module list.
+
+:- pred no_type_spec(T::in, T::in) is semidet.
+:- pragma type_spec(no_type_spec/2, T = list(U)).
+
+:- implementation.
+
+no_type_spec(X, X).
--------------------------------------------------------------------------
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