[m-dev.] for review: fix bug in inter-module optimization

Simon Taylor stayl at cs.mu.OZ.AU
Fri Jan 28 12:01:22 AEDT 2000



Estimated hours taken: 1

Fix a bug in inter-module optimization reported by Zoltan.

compiler/intermod.m:
	Make sure that user-defined equality predicates are exported
	if the types are exported.

compiler/hlds_data.m:
	Add predicate hlds_data__set_type_defn_body, to update the
	body of a discriminated union type after module qualifying
	the user-defined equality predicate.

tests/valid/Mmakefile:
tests/valid/intermod_user_equality.m:
tests/valid/intermod_user_equality2.m:
	Test case.



Index: compiler/hlds_data.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_data.m,v
retrieving revision 1.43
diff -u -u -r1.43 hlds_data.m
--- hlds_data.m	2000/01/13 06:15:35	1.43
+++ hlds_data.m	2000/01/27 02:14:59
@@ -236,6 +236,10 @@
 			hlds_type_defn).
 :- mode hlds_data__set_type_defn_status(in, in, out) is det.
 
+:- pred hlds_data__set_type_defn_body(hlds_type_defn, hlds_type_body,
+			hlds_type_defn).
+:- mode hlds_data__set_type_defn_body(in, in, out) is det.
+
 	% An `hlds_type_body' holds the body of a type definition:
 	% du = discriminated union, uu = undiscriminated union,
 	% eqv_type = equivalence type (a type defined to be equivalent
@@ -382,6 +386,8 @@
 hlds_data__get_type_defn_status(hlds_type_defn(_, _, _, Status, _), Status).
 hlds_data__get_type_defn_context(hlds_type_defn(_, _, _, _, Context), Context).
 
+hlds_data__set_type_defn_body(hlds_type_defn(A, B, _, D, E), Body,
+				hlds_type_defn(A, B, Body, D, E)).
 hlds_data__set_type_defn_status(hlds_type_defn(A, B, C, _, E), Status, 
 				hlds_type_defn(A, B, C, Status, E)).
 
Index: compiler/intermod.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/intermod.m,v
retrieving revision 1.76
diff -u -u -r1.76 intermod.m
--- intermod.m	1999/12/03 12:55:02	1.76
+++ intermod.m	2000/01/28 00:42:20
@@ -127,6 +127,8 @@
 			HigherOrderSizeLimit, Deforestation,
 			IntermodInfo0, IntermodInfo1) },
 		{ intermod__gather_instances(IntermodInfo1,
+			IntermodInfo2) },
+		{ intermod__gather_types(IntermodInfo2,
 			IntermodInfo) },
 		intermod__write_intermod_info(IntermodInfo),
 		{ intermod_info_get_module_info(ModuleInfo1,
@@ -148,10 +150,12 @@
 			set(module_name),	% modules to import
 			set(pred_id), 		% preds to output clauses for
 			set(pred_id),	 	% preds to output decls for
-			list(pair(class_id, hlds_instance_defn)),
+			assoc_list(class_id, hlds_instance_defn),
 						% instances declarations
 						% to write
-			unit,
+			assoc_list(type_id, hlds_type_defn),
+						% type declarations
+						% to write
 			unit,
 			module_info,
 			bool,			% do the c_header_codes for
@@ -170,7 +174,8 @@
 	map__init(VarTypes),
 	varset__init(TVarSet),
 	Instances = [],
-	IntermodInfo = info(Modules, Procs, ProcDecls, Instances, unit,
+	Types = [],
+	IntermodInfo = info(Modules, Procs, ProcDecls, Instances, Types,
 			unit, ModuleInfo, no, VarTypes, TVarSet).
 			
 %-----------------------------------------------------------------------------%
@@ -926,6 +931,62 @@
 	).
 
 %-----------------------------------------------------------------------------%
+
+:- pred intermod__gather_types(intermod_info::in, intermod_info::out) is det.
+
+intermod__gather_types -->
+	intermod_info_get_module_info(ModuleInfo),
+	{ module_info_types(ModuleInfo, Types) },
+	map__foldl(intermod__gather_types_2, Types).
+
+:- pred intermod__gather_types_2(type_id::in,
+	hlds_type_defn::in, intermod_info::in, intermod_info::out) is det.
+
+intermod__gather_types_2(TypeId, TypeDefn0, Info0, Info) :-
+	intermod_info_get_module_info(ModuleInfo, Info0, Info1),
+	module_info_name(ModuleInfo, ModuleName),
+	(
+	    intermod__should_write_type(ModuleName, TypeId, TypeDefn0)
+	->
+	    (
+		hlds_data__get_type_defn_body(TypeDefn0, TypeBody0),
+		TypeBody0 = du_type(Ctors, Tags, Enum, MaybeUserEq0),
+		MaybeUserEq0 = yes(UserEq0)
+	    ->
+		module_info_get_special_pred_map(ModuleInfo, SpecialPreds),
+		map__lookup(SpecialPreds, unify - TypeId, UnifyPredId),
+		module_info_pred_info(ModuleInfo, UnifyPredId, UnifyPredInfo),
+		pred_info_arg_types(UnifyPredInfo, TVarSet, _, ArgTypes),
+		typecheck__resolve_pred_overloading(ModuleInfo, ArgTypes,
+			TVarSet, UserEq0, UserEq, UserEqPredId),
+		TypeBody = du_type(Ctors, Tags, Enum, yes(UserEq)),
+		hlds_data__set_type_defn_body(TypeDefn0, TypeBody, TypeDefn),
+
+		% XXX this won't work if the predicate is
+		% exported to sub-modules.
+		intermod__add_proc(UserEqPredId, _, Info1, Info2)
+	    ;	
+		Info2 = Info1,
+		TypeDefn = TypeDefn0
+	    ),
+	    intermod_info_get_types(Types0, Info2, Info3),
+	    intermod_info_set_types([TypeId - TypeDefn | Types0], Info3, Info)
+	;
+	    Info = Info1
+	).
+
+:- pred intermod__should_write_type(module_name::in,
+		type_id::in, hlds_type_defn::in) is semidet.
+
+intermod__should_write_type(ModuleName, TypeId, TypeDefn) :-
+	hlds_data__get_type_defn_status(TypeDefn, ImportStatus),
+	TypeId = Name - _Arity,
+	Name = qualified(ModuleName, _),
+	( ImportStatus = local
+	; ImportStatus = abstract_exported
+	).
+
+%-----------------------------------------------------------------------------%
 	% Output module imports, types, modes, insts and predicates
 
 :- pred intermod__write_intermod_info(intermod_info::in,
@@ -968,7 +1029,7 @@
 		io__state::uo) is det.
 
 intermod__write_intermod_info_2(IntermodInfo) -->
-	{ IntermodInfo = info(_, Preds0, PredDecls0, Instances, _, _,
+	{ IntermodInfo = info(_, Preds0, PredDecls0, Instances, Types, _,
 				ModuleInfo, WriteHeader, _, _) },
 	{ set__to_sorted_list(Preds0, Preds) }, 
 	{ set__to_sorted_list(PredDecls0, PredDecls) },
@@ -985,7 +1046,7 @@
 		[]
 	),
 
-	intermod__write_types(ModuleInfo),
+	intermod__write_types(Types),
 	intermod__write_insts(ModuleInfo),
 	intermod__write_modes(ModuleInfo),
 	intermod__write_classes(ModuleInfo),
@@ -1027,50 +1088,38 @@
         intermod__write_c_header(Headers),
         mercury_output_pragma_c_header(Header).
 
-:- pred intermod__write_types(module_info::in,
+:- pred intermod__write_types(assoc_list(type_id, hlds_type_defn)::in,
 		io__state::di, io__state::uo) is det.
 
-intermod__write_types(ModuleInfo) -->
-	{ module_info_name(ModuleInfo, ModuleName) },
-	{ module_info_types(ModuleInfo, Types) },
-	map__foldl(intermod__write_type(ModuleName), Types).
+intermod__write_types(Types) -->
+	list__foldl(intermod__write_type, Types).
 
-:- pred intermod__write_type(module_name::in, type_id::in,
-		hlds_type_defn::in, io__state::di, io__state::uo) is det.
+:- pred intermod__write_type(pair(type_id, hlds_type_defn)::in,
+		io__state::di, io__state::uo) is det.
 
-intermod__write_type(ModuleName, TypeId, TypeDefn) -->
-	{ hlds_data__get_type_defn_status(TypeDefn, ImportStatus) },
+intermod__write_type(TypeId - TypeDefn) -->
+	{ hlds_data__get_type_defn_tvarset(TypeDefn, VarSet) },
+	{ hlds_data__get_type_defn_tparams(TypeDefn, Args) },
+	{ hlds_data__get_type_defn_body(TypeDefn, Body) },
+	{ hlds_data__get_type_defn_context(TypeDefn, Context) },
 	{ TypeId = Name - _Arity },
 	(
-		{ Name = qualified(ModuleName, _) },
-		{ ImportStatus = local
-		; ImportStatus = abstract_exported
-		}
-	->
-		{ hlds_data__get_type_defn_tvarset(TypeDefn, VarSet) },
-		{ hlds_data__get_type_defn_tparams(TypeDefn, Args) },
-		{ hlds_data__get_type_defn_body(TypeDefn, Body) },
-		{ hlds_data__get_type_defn_context(TypeDefn, Context) },
-		(
-			{ Body = du_type(Ctors, _, _, MaybeEqualityPred) },
-			mercury_output_type_defn(VarSet,
-				du_type(Name, Args, Ctors,
-					MaybeEqualityPred),
-				Context)
-		;
-			{ Body = uu_type(_) },
-			{ error("uu types not implemented") }
-		;
-			{ Body = eqv_type(EqvType) },
-			mercury_output_type_defn(VarSet,
-				eqv_type(Name, Args, EqvType), Context)
-		;
-			{ Body = abstract_type },
-			mercury_output_type_defn(VarSet,
-				abstract_type(Name, Args), Context)
-		)
-	;
-		[]
+		{ Body = du_type(Ctors, _, _, MaybeEqualityPred) },
+		mercury_output_type_defn(VarSet,
+			du_type(Name, Args, Ctors,
+				MaybeEqualityPred),
+			Context)
+	;
+		{ Body = uu_type(_) },
+		{ error("uu types not implemented") }
+	;
+		{ Body = eqv_type(EqvType) },
+		mercury_output_type_defn(VarSet,
+			eqv_type(Name, Args, EqvType), Context)
+	;
+		{ Body = abstract_type },
+		mercury_output_type_defn(VarSet,
+			abstract_type(Name, Args), Context)
 	).
 
 :- pred intermod__write_modes(module_info::in,
@@ -1590,8 +1639,8 @@
 :- pred intermod_info_get_instances(
 			assoc_list(class_id, hlds_instance_defn)::out, 
 			intermod_info::in, intermod_info::out) is det.
-%:- pred intermod_info_get_modes(set(mode_id)::out, 
-%			intermod_info::in, intermod_info::out) is det.
+:- pred intermod_info_get_types(assoc_list(type_id, hlds_type_defn)::out, 
+			intermod_info::in, intermod_info::out) is det.
 %:- pred intermod_info_get_insts(set(inst_id)::out, 
 %			intermod_info::in, intermod_info::out) is det.
 :- pred intermod_info_get_module_info(module_info::out,
@@ -1609,6 +1658,7 @@
 					=(info(_,_,ProcDecls,_,_,_,_,_,_,_)).
 intermod_info_get_instances(Instances) -->
 		=(info(_,_,_,Instances,_,_,_,_,_,_)).
+intermod_info_get_types(Types)		--> =(info(_,_,_,_,Types,_,_,_,_,_)).
 %intermod_info_get_modes(Modes)		--> =(info(_,_,_,_,Modes,_,_,_,_,_)).
 %intermod_info_get_insts(Insts)		--> =(info(_,_,_,_,_,Insts,_,_,_,_)).
 intermod_info_get_module_info(Module)	--> =(info(_,_,_,_,_,_,Module,_,_,_)).
@@ -1625,8 +1675,8 @@
 :- pred intermod_info_set_instances(
 			assoc_list(class_id, hlds_instance_defn)::in, 
 			intermod_info::in, intermod_info::out) is det.
-%:- pred intermod_info_set_modes(set(mode_id)::in, 
-%			intermod_info::in, intermod_info::out) is det.
+:- pred intermod_info_set_types(assoc_list(type_id, hlds_type_defn)::in, 
+			intermod_info::in, intermod_info::out) is det.
 %:- pred intermod_info_set_insts(set(inst_id)::in, 
 %			intermod_info::in, intermod_info::out) is det.
 :- pred intermod_info_set_module_info(module_info::in,
@@ -1649,10 +1699,10 @@
 
 intermod_info_set_instances(Instances, info(A,B,C,_,E,F,G,H,I,J),
 				info(A,B,C, Instances, E,F,G,H,I,J)).
+
+intermod_info_set_types(Types, info(A,B,C,D, _, F,G,H,I,J),
+				info(A,B,C,D, Types, F,G,H,I,J)).
 
-%intermod_info_set_modes(Modes, info(A,B,C,D,_,F,G,H,I,J),
-%				info(A,B,C,D, Modes, F,G,H,I,J)).
-%
 %intermod_info_set_insts(Insts, info(A,B,C,D,E,_,G,H,I,J),
 %				info(A,B,C,D,E, Insts, G,H,I,J)).
 
@@ -1688,7 +1738,8 @@
 	globals__lookup_int_option(Globals, higher_order_size_limit,
 		HigherOrderSizeLimit),
 	intermod__gather_preds(PredIds, yes, Threshold, HigherOrderSizeLimit,
-		Deforestation, Info0, Info),
+		Deforestation, Info0, Info1),
+	intermod__gather_types(Info1, Info),
 	do_adjust_pred_import_status(Info, Module0, Module),
 	maybe_write_string(VVerbose, " done\n", IO2, IO).
 
@@ -1719,14 +1770,8 @@
 
 adjust_type_status_2(TypeId - TypeDefn0, TypeId - TypeDefn,
 		ModuleInfo0, ModuleInfo) :-
-	hlds_data__get_type_defn_status(TypeDefn0, Status),
-	(
-		module_info_name(ModuleInfo0, ModuleName),
-		TypeId = qualified(ModuleName, _) - _,
-		( Status = local
-		; Status = abstract_exported
-		)
-	->
+	module_info_name(ModuleInfo0, ModuleName),
+	( intermod__should_write_type(ModuleName, TypeId, TypeDefn0) ->
 		hlds_data__set_type_defn_status(TypeDefn0, exported, TypeDefn),
 		fixup_special_preds(TypeId, ModuleInfo0, ModuleInfo)
 	;
Index: tests/valid/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/valid/Mmakefile,v
retrieving revision 1.50
diff -u -u -r1.50 Mmakefile
--- Mmakefile	1999/12/03 12:55:21	1.50
+++ Mmakefile	2000/01/28 00:30:19
@@ -67,6 +67,7 @@
 	intermod_quote.m \
 	intermod_test.m \
 	intermod_typeclass.m \
+	intermod_user_equality.m \
 	ite_to_disj.m \
 	lambda_inference.m\
 	lambda_instmap_bug.m \
@@ -197,6 +198,8 @@
 MCFLAGS-intermod_test2		= --intermodule-optimization
 MCFLAGS-intermod_typeclass	= --intermodule-optimization
 MCFLAGS-intermod_typeclass2	= --intermodule-optimization
+MCFLAGS-intermod_user_equality	= --intermodule-optimization
+MCFLAGS-intermod_user_equality2	= --intermodule-optimization
 MCFLAGS-ite_to_disj		= --aditi
 MCFLAGS-livevals_seq		= -O5 --opt-space
 MCFLAGS-middle_rec_labels	= --middle-rec --no-follow-vars 
Index: tests/valid/intermod_user_equality.m
===================================================================
RCS file: intermod_user_equality.m
diff -N intermod_user_equality.m
--- /dev/null	Fri Jan 28 11:36:10 2000
+++ intermod_user_equality.m	Fri Jan 28 11:31:27 2000
@@ -0,0 +1,11 @@
+:- module intermod_user_equality.
+
+:- interface.
+
+:- import_module intermod_user_equality2.
+:- pred check_foo(foo::in) is semidet.
+
+:- implementation.
+
+check_foo(Foo) :- Foo = Foo.
+
Index: tests/valid/intermod_user_equality2.m
===================================================================
RCS file: intermod_user_equality2.m
diff -N intermod_user_equality2.m
--- /dev/null	Fri Jan 28 11:36:10 2000
+++ intermod_user_equality2.m	Fri Jan 28 11:31:46 2000
@@ -0,0 +1,19 @@
+:- module intermod_user_equality2.
+
+:- interface.
+
+:- type foo.
+
+:- pred foo_field1(foo::in, int::out) is cc_nondet.
+
+:- implementation.
+
+:- type foo
+	--->	ctor1(int, int)
+	;	ctor2(int, int)
+	where equality is foo_unify.
+
+:- pred foo_unify(foo::in, foo::in) is semidet.
+foo_unify(X, X).
+
+foo_field1(ctor1(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