[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