diff: bug fix for infinite loop in mode analysis

Fergus Henderson fjh at cs.mu.oz.au
Mon Jun 16 17:55:31 AEST 1997


Hi,

Tom, can you please review this one?

compiler/inst_match.m:
	Fix an infinite loop in inst_matches_final for higher-order
	recursive insts.

compiler/mode_util.m:
	Avoid creating insts of the form `typed_inst(..., typed_inst(...))',
	because that is unnecessary, and could lead to inefficiencies or
	perhaps even infinite loops (?).

Index: inst_match.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/inst_match.m,v
retrieving revision 1.29
diff -u -r1.29 inst_match.m
--- inst_match.m	1997/04/10 20:18:32	1.29
+++ inst_match.m	1997/06/16 07:46:21
@@ -265,32 +265,48 @@
 	%	This is true if they both have the same PredOrFunc indicator
 	%	and the same determinism, and if the arguments match
 	%	using pred_inst_argmodes_match.
+	% pred_inst_matches_2(PredInstA, PredInstB, ModuleInfo, Expansions)
+	%	Same as pred_inst_matches_2, except that inst pairs in
+	%	Expansions are assumed to match_final each other.
+	%	(This avoids infinite loops when calling inst_matches_final
+	%	on higher-order recursive insts.)
 	%
 :- pred pred_inst_matches(pred_inst_info, pred_inst_info, module_info).
 :- mode pred_inst_matches(in, in, in) is semidet.
 
+pred_inst_matches(PredInstA, PredInstB, ModuleInfo) :-
+	set__init(Expansions),
+	pred_inst_matches_2(PredInstA, PredInstB, ModuleInfo, Expansions).
+
+:- pred pred_inst_matches_2(pred_inst_info, pred_inst_info, module_info,
+			exapansions).
+:- mode pred_inst_matches_2(in, in, in, in) is semidet.
+
 pred_inst_matches(pred_inst_info(PredOrFunc, ModesA, Det),
-		pred_inst_info(PredOrFunc, ModesB, Det), ModuleInfo) :-
-	pred_inst_argmodes_matches(ModesA, ModesB, ModuleInfo).
+		pred_inst_info(PredOrFunc, ModesB, Det),
+		ModuleInfo, Expansions) :-
+	pred_inst_argmodes_matches(ModesA, ModesB, ModuleInfo, Expansions).
 
-	% pred_inst_matches_argmodes(ModesA, ModesB, ModuleInfo):
+	% pred_inst_matches_argmodes(ModesA, ModesB, ModuleInfo, Expansions):
 	% succeeds if the initial insts of ModesB specify at least as
 	% much information as, and the same binding as, the initial
 	% insts of ModesA; and the final insts of ModesA specify at
 	% least as much information as, and the same binding as, the
-	% final insts of ModesB.
+	% final insts of ModesB.  Any inst pairs in Expansions are assumed
+	% to match_final each other.
 	%
-:- pred pred_inst_argmodes_matches(list(mode), list(mode), module_info).
-:- mode pred_inst_argmodes_matches(in, in, in) is semidet.
+:- pred pred_inst_argmodes_matches(list(mode), list(mode),
+				module_info, expansions).
+:- mode pred_inst_argmodes_matches(in, in, in, in) is semidet.
 
-pred_inst_argmodes_matches([], [], _).
+pred_inst_argmodes_matches([], [], _, _).
 pred_inst_argmodes_matches([ModeA|ModeAs], [ModeB|ModeBs],
-		ModuleInfo) :-
+		ModuleInfo, Expansions) :-
 	mode_get_insts(ModuleInfo, ModeA, InitialA, FinalA),
 	mode_get_insts(ModuleInfo, ModeB, InitialB, FinalB),
-	inst_matches_final(InitialB, InitialA, ModuleInfo),
-	inst_matches_final(FinalA, FinalB, ModuleInfo),
-	pred_inst_argmodes_matches(ModeAs, ModeBs, ModuleInfo).
+	inst_matches_final_2(InitialB, InitialA, ModuleInfo, Expansions),
+	inst_matches_final_2(FinalA, FinalB, ModuleInfo, Expansions),
+	pred_inst_argmodes_matches(ModeAs, ModeBs, ModuleInfo, Expansions).
 
 :- pred unique_matches_initial(uniqueness, uniqueness).
 :- mode unique_matches_initial(in, in) is semidet.
@@ -456,8 +472,9 @@
 		% of all the constructors for the type in question.
 	%%% error("not implemented: `ground' matches_final `bound(...)'").
 inst_matches_final_3(ground(UniqA, PredInstA), ground(UniqB, PredInstB),
-		ModuleInfo, _) :-
-	maybe_pred_inst_matches_final(PredInstA, PredInstB, ModuleInfo),
+		ModuleInfo, Expansions) :-
+	maybe_pred_inst_matches_final(PredInstA, PredInstB,
+		ModuleInfo, Expansions),
 	unique_matches_final(UniqA, UniqB).
 /* not yet:
 inst_matches_final_2(abstract_inst(_, _), any(shared), _, _).
@@ -468,13 +485,14 @@
 inst_matches_final_3(not_reached, _, _, _).
 
 :- pred maybe_pred_inst_matches_final(maybe(pred_inst_info),
-		maybe(pred_inst_info), module_info).
-:- mode maybe_pred_inst_matches_final(in, in, in) is semidet.
+		maybe(pred_inst_info), module_info, expansions).
+:- mode maybe_pred_inst_matches_final(in, in, in, in) is semidet.
 
-maybe_pred_inst_matches_final(no, no, _).
-maybe_pred_inst_matches_final(yes(_), no, _).
-maybe_pred_inst_matches_final(yes(PredInstA), yes(PredInstB), ModuleInfo) :-
-	pred_inst_matches(PredInstA, PredInstB, ModuleInfo).
+maybe_pred_inst_matches_final(no, no, _, _).
+maybe_pred_inst_matches_final(yes(_), no, _, _).
+maybe_pred_inst_matches_final(yes(PredInstA), yes(PredInstB),
+		ModuleInfo, Expansions) :-
+	pred_inst_matches_2(PredInstA, PredInstB, ModuleInfo, Expansions).
 
 :- pred inst_list_matches_final(list(inst), list(inst), module_info,
 				expansions).
-- 
Fergus Henderson <fjh at cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3         |     -- the last words of T. S. Garp.



More information about the developers mailing list