[m-dev.] diff: bug fix - impurity in .opt files

Simon Taylor stayl at cs.mu.OZ.AU
Wed Aug 25 16:09:21 AEST 1999



Estimated hours taken: 1

compiler/intermod.m:
	Don't write the clauses for predicates which call impure predicates
	to `.opt' files. This avoids mode errors when mode checking
	the clauses from `.opt' files. The errors occur because the
	head unifications in clauses read from `.opt' files have been
	expanded twice - once when read from the `.m' file and again when
	read from the `.opt' file. Only the original head unifications may
	be reordered with impure goals. Fixing this in mode analysis would
	be tricky.
	Compilation of the browser directory fails without this change.

	Don't write items to the `.opt' file which were needed only by
	clauses which were traversed but not written out.

tests/valid/Mmakefile:
tests/valid/intermod_impure.m:
tests/valid/intermod_impure_2.m:
	Test case.


Index: compiler/intermod.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/intermod.m,v
retrieving revision 1.66
diff -u -u -r1.66 intermod.m
--- intermod.m	1999/07/13 08:53:01	1.66
+++ intermod.m	1999/08/24 02:41:22
@@ -215,6 +215,7 @@
 			)
 		)
 	->
+		=(IntermodInfo0),
 		{ pred_info_clauses_info(PredInfo0, ClausesInfo0) },
 		{ pred_info_typevarset(PredInfo0, TVarSet) },
 		{ clauses_info_vartypes(ClausesInfo0, VarTypes) },
@@ -251,7 +252,9 @@
 			),
 			intermod_info_set_module_info(ModuleInfo)
 		;
-			[]
+			% Remove any items added for the clauses
+			% for this predicate.
+			dcg_set(IntermodInfo0)
 		)
 	;
 		[]
@@ -259,6 +262,9 @@
 	intermod__gather_preds(PredIds, CollectTypes,
 		InlineThreshold, Deforestation).
 
+:- pred dcg_set(T::in, T::unused, T::out) is det.
+dcg_set(T, _, T).
+
 :- pred intermod__traverse_clauses(list(clause)::in, list(clause)::out,
 		bool::out, intermod_info::in, intermod_info::out) is det.
 
@@ -542,6 +548,30 @@
 			proc_info_declared_determinism(ProcInfo, no)
 		}
 	->
+		{ DoWrite = no }
+	;
+		% Goals which call impure predicates cannot be written
+		% due to limitations in mode analysis. The problem is that
+		% only head unifications are allowed to be reordered with
+		% impure goals.
+		% 	
+		% e.g
+		%	p(A::in, B::in, C::out) :- impure foo(A, B, C).
+		% becomes
+		% 	p(HeadVar1, HeadVar2, HeadVar3) :-
+		%		A = HeadVar1, B = HeadVar2, C = HeadVar3,
+		% 		impure_goal(A, B, C).
+		% 
+		% In the clauses written to `.opt' files, the head
+		% unifications are already expanded, and are expanded
+		% again when the `.opt' file is read in. The `C = HeadVar3'
+		% unficiation cannot be reordered with the impure goal,
+		% resulting in a mode error. Fixing this in mode analysis
+		% would be tricky.
+		%
+		% See tests/valid/impure_intermod.m.
+		{ pred_info_get_purity(PredInfo, impure) }
+	->	
 		{ DoWrite = no }
 	;
 		%
Index: tests/valid/Mmakefile
===================================================================
RCS file: /home/staff/zs/imp/tests/valid/Mmakefile,v
retrieving revision 1.39
diff -u -u -r1.39 Mmakefile
--- Mmakefile	1999/08/04 02:45:40	1.39
+++ Mmakefile	1999/08/25 05:56:55
@@ -57,6 +57,7 @@
 	inhibit_warn_test.m \
 	inlining_bug.m \
 	int64.m \
+	intermod_impure.m \
 	intermod_lambda.m \
 	intermod_quote.m \
 	intermod_test.m \
@@ -173,6 +174,8 @@
 MCFLAGS-explicit_quant		= --halt-at-warn
 MCFLAGS-higher_order_implied_mode = -O-1
 MCFLAGS-inhibit_warn_test       = --inhibit-warnings --halt-at-warn
+MCFLAGS-intermod_impure		= --intermodule-optimization
+MCFLAGS-intermod_impure2	= --intermodule-optimization
 MCFLAGS-intermod_lambda		= --intermodule-optimization
 MCFLAGS-intermod_lambda2	= --intermodule-optimization
 MCFLAGS-intermod_quote		= --intermodule-optimization
Index: tests/valid/intermod_impure.m
===================================================================
RCS file: intermod_impure.m
diff -N intermod_impure.m
--- /dev/null	Wed Aug 25 15:49:58 1999
+++ intermod_impure.m	Wed Aug 25 15:56:46 1999
@@ -0,0 +1,25 @@
+% The compiler of 23/8/1999 had a bug which caused a mode error
+% if the clauses in a `.opt' file contained a call to an impure predicate.
+% The problem was that mode analysis was not reordering the head
+% unifications with the impure call because the head unifications
+% had been expanded into separate unifications twice - once
+% when reading the `.m' file and once when reading the `.opt' file.
+% The fix was to avoid putting goals which call impure predicates
+% in the `.opt' files.
+:- module intermod_impure.
+
+:- interface.
+
+:- import_module io.
+
+:- impure pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+:- import_module intermod_impure2.
+
+main -->
+	{ impure intermod_impure(Int) },
+	io__write_int(Int),
+	io__nl.
+
Index: tests/valid/intermod_impure2.m
===================================================================
RCS file: intermod_impure2.m
diff -N intermod_impure2.m
--- /dev/null	Wed Aug 25 15:49:58 1999
+++ intermod_impure2.m	Wed Aug 25 15:56:47 1999
@@ -0,0 +1,24 @@
+% See intermod_impure.m.
+:- module intermod_impure2.
+
+:- interface.
+
+:- impure pred intermod_impure(int::out) is det.
+
+:- implementation.
+
+intermod_impure(Int) :-
+	impure intermod_impure_2(Int).
+
+:- impure pred intermod_impure_2(int::out) is det.
+
+:- pragma c_header_code(
+"
+#include <stdio.h>
+").
+
+:- pragma c_code(intermod_impure_2(Int::out), will_not_call_mercury,
+"
+printf(""Output from impure predicate\\n"");
+Int = 2;
+").
--------------------------------------------------------------------------
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