[m-rev.] diff: fix bug with impurity and deep profiling

Zoltan Somogyi zs at cs.mu.OZ.AU
Tue Jun 22 18:54:04 AEST 2004


Fix a bug caught by the nightly tests. The cause of the bug is described
in the following comment in the cut down test case:

% This code is a cut down version of merge_key_ranges_2 in rl_key.m.
% It is a regression test; the 21 June 2004 version of the compiler got
% a compiler abort when compiling this code with deep profiling enabled.
%
% The problem had several causes that had all to be present.
%
% 1. The inlined code of less_or_equal contains a call. Deep profiling inserts
%    prepare_for_normal_call before that call, making it impure.
%
% 2. The body of less_or_equal isn't a complete switch in any argument, so
%    switch detection leaves a disjunction in it.
%
% 3. The inlining of less_or_equal in merge_key_ranges_2 *after* the initial
%    semantic checks causes the second run of simplify to modify the code,
%    removing the redundant check of the second argument of less_or_equal in
%    the second clause. This causes simplify to rerun determinism analysis.
%    (If the inlining is done in the source code, the simplification will have
%    been done in the first run of simplify, and simplify won't find any
%    improvements to do after the deep profiling transformation.)
%
% 4. When determinism analysis looks at the inlined disjunction, it disregards
%    the fact that it has no outputs because it is impure.
%
% The original symptom required -O5 to inline the relevant call in rl_key.m.
% We mark the predicate with pragma inline to force the problem, if present,
% to appear also at lower optimization levels.

The fix is to alter the behavior of determinism analysis.

compiler/det_analysis.m:
	When the new goal feature not_impure_for_determinism is present on a
	goal, ignore the impurity of the goal when computing its determinism.

compiler/deep_profiling.m:
	Add the new feature when making pure goals impure. For goals that were
	impure to begin with, do not add the feature. In both cases, the goal
	is to get determinism analysis to get the same result as it would get
	without the deep profiling transformation.

compiler/hlds_goal.m:
	Add the new goal feature, and add predicates for adding and removing
	more than one feature at a time.

compiler/saved_vars.m:
	Minor diff to handle the new feature.

tests/valid/impure_detism.m:
	New regression test case for this bug.

tests/valid/Mmakefile:
tests/valid/Mercury.options:
	Enable the new test case, and specify the test options.

	Put test case lists into sorted order.

Zoltan.

cvs server: Diffing .
cvs server: Diffing analysis
cvs server: Diffing bindist
cvs server: Diffing boehm_gc
cvs server: Diffing boehm_gc/Mac_files
cvs server: Diffing boehm_gc/cord
cvs server: Diffing boehm_gc/cord/private
cvs server: Diffing boehm_gc/doc
cvs server: Diffing boehm_gc/include
cvs server: Diffing boehm_gc/include/private
cvs server: Diffing boehm_gc/tests
cvs server: Diffing browser
cvs server: Diffing bytecode
cvs server: Diffing compiler
Index: compiler/deep_profiling.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/deep_profiling.m,v
retrieving revision 1.26
diff -u -b -r1.26 deep_profiling.m
--- compiler/deep_profiling.m	14 Jun 2004 04:16:00 -0000	1.26
+++ compiler/deep_profiling.m	22 Jun 2004 08:17:55 -0000
@@ -624,7 +624,7 @@
 			[TopCSD, MiddleCSD], [], ExitPortCode)
 	),
 
-	goal_info_add_feature(GoalInfo0, impure, GoalInfo),
+	make_impure(GoalInfo0, GoalInfo),
 	Goal = conj([
 		BindProcStaticVarGoal,
 		CallPortCode,
@@ -729,7 +729,7 @@
 	ExitConjGoalInfo = goal_info_add_nonlocals_make_impure(GoalInfo0,
 		NewNonlocals),
 
-	goal_info_add_feature(GoalInfo0, impure, GoalInfo),
+	make_impure(GoalInfo0, GoalInfo),
 	Goal = conj([
 		BindProcStaticVarGoal,
 		CallPortCode,
@@ -869,7 +869,7 @@
 	CallExitRedoGoalInfo = goal_info_add_nonlocals_make_impure(GoalInfo1,
 		ExitRedoNonLocals),
 
-	goal_info_add_feature(GoalInfo1, impure, GoalInfo),
+	make_impure(GoalInfo1, GoalInfo),
 	Goal = conj([
 		BindProcStaticVarGoal,
 		CallPortCode,
@@ -938,20 +938,6 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred add_impurity_if_needed(bool::in, hlds_goal_info::in,
-	hlds_goal_info::out) is det.
-
-add_impurity_if_needed(AddedImpurity, GoalInfo0, GoalInfo) :-
-	(
-		AddedImpurity = no,
-		GoalInfo = GoalInfo0
-	;
-		AddedImpurity = yes,
-		goal_info_add_feature(GoalInfo0, impure, GoalInfo)
-	).
-
-%-----------------------------------------------------------------------------%
-
 :- pred transform_goal(goal_path::in, hlds_goal::in, hlds_goal::out, bool::out,
 	deep_info::in, deep_info::out) is det.
 
@@ -1119,7 +1105,7 @@
 	ModuleInfo = !.DeepInfo ^ module_info,
 	goal_info_get_features(GoalInfo0, GoalFeatures),
 	goal_info_remove_feature(GoalInfo0, tailcall, GoalInfo1),
-	goal_info_add_feature(GoalInfo1, impure, GoalInfo),
+	make_impure(GoalInfo1, GoalInfo),
 
 	% We need to make the call itself impure. If we didn't do so,
 	% then simplify could eliminate the goal (e.g. if it was a duplicate
@@ -1258,7 +1244,8 @@
 				SaveRestoreVars, !DeepInfo)
 		;
 			VisSCC = [_, _ | _],
-			error("wrap_call: multi-procedure SCCs not yet implemented")
+			error("wrap_call: multi-procedure SCCs " ++
+				"not yet implemented")
 		),
 
 		goal_info_get_code_model(GoalInfo0, CodeModel),
@@ -1277,8 +1264,8 @@
 					ExtraVars),
 
 			ReturnFailsGoalInfo =
-				impure_unreachable_init_goal_info(
-					ExtraVars, failure),
+				impure_unreachable_init_goal_info(ExtraVars,
+					failure),
 
 			FailGoalInfo = fail_goal_info,
 			FailGoal = disj([]) - FailGoalInfo,
@@ -1381,7 +1368,7 @@
 	RezeroFailGoalInfo = impure_unreachable_init_goal_info(set__init,
 		failure),
 
-	goal_info_add_feature(GoalInfo0, impure, GoalInfo),
+	make_impure(GoalInfo0, GoalInfo),
 	(
 		CodeModel = model_det,
 		Goal = conj([
@@ -1449,7 +1436,7 @@
 	compress_filename(!.DeepInfo, FileName0, FileName),
 	CallSite = callback(FileName, LineNumber, GoalPath),
 
-	goal_info_add_feature(GoalInfo0, impure, GoalInfo),
+	make_impure(GoalInfo0, GoalInfo),
 	Goal = conj([
 		SiteNumVarGoal,
 		PrepareGoal,
@@ -1756,7 +1743,9 @@
 	= hlds_goal_info.
 
 impure_init_goal_info(NonLocals, InstMapDelta, Determinism) = GoalInfo :-
-	goal_info_init(NonLocals, InstMapDelta, Determinism, impure, GoalInfo).
+	goal_info_init(NonLocals, InstMapDelta, Determinism, impure,
+		GoalInfo0),
+	goal_info_add_feature(GoalInfo0, not_impure_for_determinism, GoalInfo).
 
 :- func impure_reachable_init_goal_info(set(prog_var), determinism)
 	= hlds_goal_info.
@@ -1770,7 +1759,9 @@
 
 impure_unreachable_init_goal_info(NonLocals, Determinism) = GoalInfo :-
 	instmap_delta_init_unreachable(InstMapDelta),
-	goal_info_init(NonLocals, InstMapDelta, Determinism, impure, GoalInfo).
+	goal_info_init(NonLocals, InstMapDelta, Determinism, impure,
+		GoalInfo0),
+	goal_info_add_feature(GoalInfo0, not_impure_for_determinism, GoalInfo).
 
 :- func goal_info_add_nonlocals_make_impure(hlds_goal_info, set(prog_var))
 	= hlds_goal_info.
@@ -1779,13 +1770,36 @@
 	goal_info_get_nonlocals(GoalInfo0, NonLocals0),
 	NonLocals = set__union(NonLocals0, NewNonLocals),
 	goal_info_set_nonlocals(GoalInfo0, NonLocals, GoalInfo1),
-	goal_info_add_feature(GoalInfo1, impure, GoalInfo).
+	make_impure(GoalInfo1, GoalInfo).
 
 :- func fail_goal_info = hlds_goal_info.
 
 fail_goal_info = GoalInfo :-
 	instmap_delta_init_unreachable(InstMapDelta),
 	goal_info_init(set__init, InstMapDelta, failure, pure, GoalInfo).
+
+:- pred make_impure(hlds_goal_info::in, hlds_goal_info::out) is det.
+
+make_impure(GoalInfo0, GoalInfo) :-
+	( goal_info_has_feature(GoalInfo0, (impure)) ->
+		% We don't add not_impure_for_determinism, since we want to
+		% keep the existing determinism.
+		GoalInfo = GoalInfo0
+	;
+		goal_info_add_features([impure, not_impure_for_determinism],
+			GoalInfo0, GoalInfo)
+	).
+
+:- pred add_impurity_if_needed(bool::in, hlds_goal_info::in,
+	hlds_goal_info::out) is det.
+
+add_impurity_if_needed(AddedImpurity, !GoalInfo) :-
+	(
+		AddedImpurity = no
+	;
+		AddedImpurity = yes,
+		make_impure(!GoalInfo)
+	).
 
 %-----------------------------------------------------------------------------%
 
Index: compiler/det_analysis.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/det_analysis.m,v
retrieving revision 1.169
diff -u -b -r1.169 det_analysis.m
--- compiler/det_analysis.m	14 Jun 2004 04:16:01 -0000	1.169
+++ compiler/det_analysis.m	22 Jun 2004 08:17:55 -0000
@@ -325,7 +325,12 @@
 	(
 		det_no_output_vars(NonLocalVars, InstMap0, DeltaInstMap,
 			DetInfo),
-		\+ goal_info_is_impure(GoalInfo0)
+		(
+			goal_info_is_impure(GoalInfo0)
+		=>
+			goal_info_has_feature(GoalInfo0,
+				not_impure_for_determinism)
+		)
 	->
 		AddPruning = yes,
 		SolnContext = first_soln
Index: compiler/hlds_goal.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_goal.m,v
retrieving revision 1.117
diff -u -b -r1.117 hlds_goal.m
--- compiler/hlds_goal.m	14 Jun 2004 04:16:06 -0000	1.117
+++ compiler/hlds_goal.m	22 Jun 2004 08:17:55 -0000
@@ -703,6 +703,11 @@
 
 :- pred goal_get_nonlocals(hlds_goal::in, set(prog_var)::out) is det.
 
+:- pred goal_info_add_features(list(goal_feature)::in,
+	hlds_goal_info::in, hlds_goal_info::out) is det.
+:- pred goal_info_remove_features(list(goal_feature)::in,
+	hlds_goal_info::in, hlds_goal_info::out) is det.
+
 :- pred goal_info_add_feature(hlds_goal_info::in, goal_feature::in,
 	hlds_goal_info::out) is det.
 :- pred goal_info_remove_feature(hlds_goal_info::in, goal_feature::in,
@@ -735,6 +740,13 @@
 				% for the definition of this.
 	;	(impure)	% This goal is impure.  See hlds_pred.m.
 	;	(semipure)	% This goal is semipure.  See hlds_pred.m.
+	;	not_impure_for_determinism
+				% This goal should not be treated as impure
+				% for the purpose of computing its determinism.
+				% This is intended to be used by program
+				% transformations that insert impure code into
+				% existing goals, and wish to keep the old
+				% determinism of those goals.
 	;	stack_opt	% This goal was created by stack slot
 				% optimization. Other optimizations should
 				% assume that it is there for a reason, and
@@ -1333,6 +1345,16 @@
 	goal_info_has_feature(GoalInfo, (impure)).
 
 %-----------------------------------------------------------------------------%
+
+goal_info_add_features([], GoalInfo, GoalInfo).
+goal_info_add_features([Feature | Features], GoalInfo0, GoalInfo) :-
+	goal_info_add_feature(GoalInfo0, Feature, GoalInfo1),
+	goal_info_add_features(Features, GoalInfo1, GoalInfo).
+
+goal_info_remove_features([], GoalInfo, GoalInfo).
+goal_info_remove_features([Feature | Features], GoalInfo0, GoalInfo) :-
+	goal_info_remove_feature(GoalInfo0, Feature, GoalInfo1),
+	goal_info_remove_features(Features, GoalInfo1, GoalInfo).
 
 goal_info_add_feature(GoalInfo0, Feature, GoalInfo) :-
 	goal_info_get_features(GoalInfo0, Features0),
Index: compiler/saved_vars.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/saved_vars.m,v
retrieving revision 1.40
diff -u -b -r1.40 saved_vars.m
--- compiler/saved_vars.m	7 Jun 2004 09:07:06 -0000	1.40
+++ compiler/saved_vars.m	22 Jun 2004 08:17:56 -0000
@@ -202,6 +202,7 @@
 ok_to_duplicate(constraint) = no.
 ok_to_duplicate(impure) = no.
 ok_to_duplicate(semipure) = no.
+ok_to_duplicate(not_impure_for_determinism) = no.
 ok_to_duplicate(stack_opt) = no.
 ok_to_duplicate(call_table_gen) = no.
 ok_to_duplicate(keep_this_commit) = no.
cvs server: Diffing compiler/notes
cvs server: Diffing debian
cvs server: Diffing deep_profiler
cvs server: Diffing deep_profiler/notes
cvs server: Diffing doc
cvs server: Diffing extras
cvs server: Diffing extras/aditi
cvs server: Diffing extras/cgi
cvs server: Diffing extras/complex_numbers
cvs server: Diffing extras/complex_numbers/samples
cvs server: Diffing extras/complex_numbers/tests
cvs server: Diffing extras/concurrency
cvs server: Diffing extras/curs
cvs server: Diffing extras/curs/samples
cvs server: Diffing extras/curses
cvs server: Diffing extras/curses/sample
cvs server: Diffing extras/dynamic_linking
cvs server: Diffing extras/error
cvs server: Diffing extras/graphics
cvs server: Diffing extras/graphics/mercury_glut
cvs server: Diffing extras/graphics/mercury_opengl
cvs server: Diffing extras/graphics/mercury_tcltk
cvs server: Diffing extras/graphics/samples
cvs server: Diffing extras/graphics/samples/calc
cvs server: Diffing extras/graphics/samples/gears
cvs server: Diffing extras/graphics/samples/maze
cvs server: Diffing extras/graphics/samples/pent
cvs server: Diffing extras/lazy_evaluation
cvs server: Diffing extras/lex
cvs server: Diffing extras/lex/samples
cvs server: Diffing extras/lex/tests
cvs server: Diffing extras/logged_output
cvs server: Diffing extras/moose
cvs server: Diffing extras/moose/samples
cvs server: Diffing extras/moose/tests
cvs server: Diffing extras/morphine
cvs server: Diffing extras/morphine/non-regression-tests
cvs server: Diffing extras/morphine/scripts
cvs server: Diffing extras/morphine/source
cvs server: Diffing extras/odbc
cvs server: Diffing extras/posix
cvs server: Diffing extras/quickcheck
cvs server: Diffing extras/quickcheck/tutes
cvs server: Diffing extras/references
cvs server: Diffing extras/references/samples
cvs server: Diffing extras/references/tests
cvs server: Diffing extras/stream
cvs server: Diffing extras/trailed_update
cvs server: Diffing extras/trailed_update/samples
cvs server: Diffing extras/trailed_update/tests
cvs server: Diffing extras/xml
cvs server: Diffing extras/xml/samples
cvs server: Diffing java
cvs server: Diffing java/runtime
cvs server: Diffing library
cvs server: Diffing profiler
cvs server: Diffing robdd
cvs server: Diffing runtime
cvs server: Diffing runtime/GETOPT
cvs server: Diffing runtime/machdeps
cvs server: Diffing samples
cvs server: Diffing samples/c_interface
cvs server: Diffing samples/c_interface/c_calls_mercury
cvs server: Diffing samples/c_interface/cplusplus_calls_mercury
cvs server: Diffing samples/c_interface/mercury_calls_c
cvs server: Diffing samples/c_interface/mercury_calls_cplusplus
cvs server: Diffing samples/c_interface/mercury_calls_fortran
cvs server: Diffing samples/c_interface/simpler_c_calls_mercury
cvs server: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs server: Diffing samples/diff
cvs server: Diffing samples/muz
cvs server: Diffing samples/rot13
cvs server: Diffing samples/solutions
cvs server: Diffing samples/tests
cvs server: Diffing samples/tests/c_interface
cvs server: Diffing samples/tests/c_interface/c_calls_mercury
cvs server: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs server: Diffing samples/tests/c_interface/mercury_calls_c
cvs server: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs server: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs server: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs server: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs server: Diffing samples/tests/diff
cvs server: Diffing samples/tests/muz
cvs server: Diffing samples/tests/rot13
cvs server: Diffing samples/tests/solutions
cvs server: Diffing samples/tests/toplevel
cvs server: Diffing scripts
cvs server: Diffing tests
cvs server: Diffing tests/benchmarks
cvs server: Diffing tests/debugger
cvs server: Diffing tests/debugger/declarative
cvs server: Diffing tests/dppd
cvs server: Diffing tests/general
cvs server: Diffing tests/general/accumulator
cvs server: Diffing tests/general/string_format
cvs server: Diffing tests/general/structure_reuse
cvs server: Diffing tests/grade_subdirs
cvs server: Diffing tests/hard_coded
cvs server: Diffing tests/hard_coded/exceptions
cvs server: Diffing tests/hard_coded/purity
cvs server: Diffing tests/hard_coded/sub-modules
cvs server: Diffing tests/hard_coded/typeclasses
cvs server: Diffing tests/invalid
cvs server: Diffing tests/invalid/purity
cvs server: Diffing tests/misc_tests
cvs server: Diffing tests/mmc_make
cvs server: Diffing tests/mmc_make/lib
cvs server: Diffing tests/recompilation
cvs server: Diffing tests/tabling
cvs server: Diffing tests/term
cvs server: Diffing tests/valid
Index: tests/valid/Mercury.options
===================================================================
RCS file: /home/mercury1/repository/tests/valid/Mercury.options,v
retrieving revision 1.11
diff -u -b -r1.11 Mercury.options
--- tests/valid/Mercury.options	5 Dec 2003 04:18:32 -0000	1.11
+++ tests/valid/Mercury.options	22 Jun 2004 08:18:00 -0000
@@ -22,14 +22,14 @@
 GRADEFLAGS-foreign_type_spec	= --grade il
 GRADEFLAGS-foreign_type_spec.foreign	= --grade il
 
-MCFLAGS-aditi_error_bug		= --aditi
 MCFLAGS-aditi_error_bug2	= --aditi
 MCFLAGS-aditi_error_bug3	= --aditi
+MCFLAGS-aditi_error_bug		= --aditi
 MCFLAGS-aditi_private_builtin	= --allow-stubs
 MCFLAGS-aditi_query		= --aditi-only
 MCFLAGS-aditi_update		= --aditi
-MCFLAGS-base_relation		= --aditi
 MCFLAGS-base_relation2		= --aditi
+MCFLAGS-base_relation		= --aditi
 MCFLAGS-compl_unify_bug		= -O3
 MCFLAGS-context_anc		= --aditi
 MCFLAGS-deforest_bug		= -O3
@@ -40,39 +40,40 @@
 MCFLAGS-foreign_underscore_var	= --halt-at-warn
 MCFLAGS-higher_order4		= -O3
 MCFLAGS-higher_order_implied_mode = -O-1
+MCFLAGS-impure_detism           = -O5 --deep-profiling
 MCFLAGS-inhibit_warn_test       = --inhibit-warnings --halt-at-warn
 MCFLAGS-intermod_bug_nested	= --intermodule-optimization
 MCFLAGS-intermod_bug_nested.parser	= --intermodule-optimization
-MCFLAGS-intermod_dcg_bug	= --intermodule-optimization
 MCFLAGS-intermod_dcg_bug2	= --intermodule-optimization
-MCFLAGS-intermod_impure		= --intermodule-optimization
+MCFLAGS-intermod_dcg_bug	= --intermodule-optimization
 MCFLAGS-intermod_impure2	= --intermodule-optimization
-MCFLAGS-intermod_lambda		= --intermodule-optimization
+MCFLAGS-intermod_impure		= --intermodule-optimization
 MCFLAGS-intermod_lambda2	= --intermodule-optimization
-MCFLAGS-intermod_nested		= --intermodule-optimization
+MCFLAGS-intermod_lambda		= --intermodule-optimization
 MCFLAGS-intermod_nested2	= --intermodule-optimization
-MCFLAGS-intermod_nested_module	= --intermodule-optimization
+MCFLAGS-intermod_nested		= --intermodule-optimization
 MCFLAGS-intermod_nested_module2	= --intermodule-optimization
-MCFLAGS-intermod_nested_module_bug = --intermodule-optimization
 MCFLAGS-intermod_nested_module_bug2 = --intermodule-optimization
-MCFLAGS-intermod_nested_uniq	= --intermodule-optimization
+MCFLAGS-intermod_nested_module_bug = --intermodule-optimization
+MCFLAGS-intermod_nested_module	= --intermodule-optimization
 MCFLAGS-intermod_nested_uniq2	= --intermodule-optimization
-MCFLAGS-intermod_pragma_import	= --intermodule-optimization
+MCFLAGS-intermod_nested_uniq	= --intermodule-optimization
 MCFLAGS-intermod_pragma_import2	= --intermodule-optimization
-MCFLAGS-intermod_quote		= --intermodule-optimization
+MCFLAGS-intermod_pragma_import	= --intermodule-optimization
 MCFLAGS-intermod_quote2		= --intermodule-optimization
-MCFLAGS-intermod_record		= --intermodule-optimization
+MCFLAGS-intermod_quote		= --intermodule-optimization
 MCFLAGS-intermod_record2	= --intermodule-optimization
-MCFLAGS-intermod_test		= --intermodule-optimization
+MCFLAGS-intermod_record		= --intermodule-optimization
 MCFLAGS-intermod_test2		= --intermodule-optimization
-MCFLAGS-intermod_typeclass	= --intermodule-optimization
+MCFLAGS-intermod_test		= --intermodule-optimization
 MCFLAGS-intermod_typeclass2	= --intermodule-optimization
-MCFLAGS-intermod_type_spec	= --intermodule-optimization
+MCFLAGS-intermod_typeclass	= --intermodule-optimization
 MCFLAGS-intermod_type_spec2	= --intermodule-optimization
-MCFLAGS-intermod_user_equality	= --intermodule-optimization
+MCFLAGS-intermod_type_spec	= --intermodule-optimization
 MCFLAGS-intermod_user_equality2	= --intermodule-optimization
-MCFLAGS-intermod_user_equality_nested	= --intermodule-optimization
+MCFLAGS-intermod_user_equality	= --intermodule-optimization
 MCFLAGS-intermod_user_equality_nested2	= --intermodule-optimization
+MCFLAGS-intermod_user_equality_nested	= --intermodule-optimization
 MCFLAGS-ite_to_disj		= --aditi
 MCFLAGS-lambda_inference	= --infer-all
 MCFLAGS-livevals_seq		= -O5 --opt-space
@@ -80,17 +81,17 @@
 MCFLAGS-mostly_uniq_mode_inf	= --infer-all
 MCFLAGS-pred_with_no_modes	= --infer-all
 MCFLAGS-quantifier_warning	= --halt-at-warn
-MGNUCFLAGS-reg_bug		= --no-ansi
-MCFLAGS-simplify_bug		= -O-1
 MCFLAGS-simplify_bug2		= -O3
-MCFLAGS-spurious_purity_warning	= --halt-at-warn
-MCFLAGS-solv			= --halt-at-warn
+MCFLAGS-simplify_bug		= -O-1
 MCFLAGS-solver_type_bug		= --halt-at-warn
+MCFLAGS-solv			= --halt-at-warn
+MCFLAGS-spurious_purity_warning	= --halt-at-warn
 MCFLAGS-tuple_eqv               = --smart-recompilation
 MCFLAGS-two_way_unif		= -O-1
-MCFLAGS-type_inf_ambig_test	= --infer-all
 MCFLAGS-typeclass_det_warning	= --halt-at-warn
+MCFLAGS-type_inf_ambig_test	= --infer-all
 MCFLAGS-unify_typeinfo_bug	= -O3 --no-special-preds
 MCFLAGS-uniq_mode_inf_bug	= --infer-all
 MCFLAGS-vn_float		= -O5
 MCFLAGS-zero_arity		= --infer-modes
+MGNUCFLAGS-reg_bug		= --no-ansi
Index: tests/valid/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/valid/Mmakefile,v
retrieving revision 1.140
diff -u -b -r1.140 Mmakefile
--- tests/valid/Mmakefile	31 May 2004 04:13:35 -0000	1.140
+++ tests/valid/Mmakefile	22 Jun 2004 08:18:00 -0000
@@ -53,9 +53,10 @@
 OTHER_PROGS= \
 	any_inst_merge \
 	any_matches_bound \
+	big_foreign_type \
 	common_struct_bug \
-	compl_unify_bug \
 	complicated_unify \
+	compl_unify_bug \
 	constrained_poly_bound_arg \
 	constrained_poly_insts \
 	constructor_arg_names \
@@ -77,10 +78,9 @@
 	exported_foreign_type \
 	fail_ite \
 	followcode_det_problem \
-	big_foreign_type \
 	foreign_underscore_var \
-	func_int_bug_main \
 	func_default_modes \
+	func_int_bug_main \
 	headvar_not_found \
 	higher_order \
 	higher_order2 \
@@ -93,6 +93,7 @@
 	ho_unify \
 	id_type_bug \
 	implied_mode \
+	impure_detism \
 	indexing \
 	inhibit_warn_test \
 	inlining_bug \
@@ -138,8 +139,8 @@
 	module_d \
 	module_e \
 	mostly_uniq_bug \
-	mostly_uniq_neg \
 	mostly_uniq_mode_inf \
+	mostly_uniq_neg \
 	multidet_prune1 \
 	multidet_test \
 	nasty_func_test \
@@ -168,14 +169,14 @@
 	some_switch \
 	spurious_purity_warning \
 	stack_alloc \
-	static \
 	state_var_bug \
+	static \
 	subtype_switch \
 	switch_detection_bug \
 	switch_detection_bug2 \
 	switches \
-	tabled_io \
 	tabled_for_io \
+	tabled_io \
 	transitive_instance \
 	tricky_assert2 \
 	tricky_ite \
@@ -187,8 +188,8 @@
 	unbound_inst_var \
 	unbound_tvar_in_lambda \
 	undead_proc \
-	uniq_unify \
 	uniq_mode_inf_bug \
+	uniq_unify \
 	unreachable_code \
 	unused_args_test2 \
 	vn_float \
Index: tests/valid/impure_detism.m
===================================================================
RCS file: tests/valid/impure_detism.m
diff -N tests/valid/impure_detism.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/valid/impure_detism.m	22 Jun 2004 08:18:00 -0000
@@ -0,0 +1,64 @@
+% This code is a cut down version of merge_key_ranges_2 in rl_key.m.
+% It is a regression test; the 21 June 2004 version of the compiler got
+% a compiler abort when compiling this code with deep profiling enabled.
+%
+% The problem had several causes that had all to be present.
+%
+% 1. The inlined code of less_or_equal contains a call. Deep profiling inserts
+%    prepare_for_normal_call before that call, making it impure.
+%
+% 2. The body of less_or_equal isn't a complete switch in any argument, so
+%    switch detection leaves a disjunction in it.
+%
+% 3. The inlining of less_or_equal in merge_key_ranges_2 *after* the initial
+%    semantic checks causes the second run of simplify to modify the code,
+%    removing the redundant check of the second argument of less_or_equal in
+%    the second clause. This causes simplify to rerun determinism analysis.
+%    (If the inlining is done in the source code, the simplification will have
+%    been done in the first run of simplify, and simplify won't find any
+%    improvements to do after the deep profiling transformation.)
+%
+% 4. When determinism analysis looks at the inlined disjunction, it disregards
+%    the fact that it has no outputs because it is impure.
+%
+% The original symptom required -O5 to inline cvs server: Diffing util
cvs server: Diffing vim
cvs server: Diffing vim/after
cvs server: Diffing vim/ftplugin
cvs server: Diffing vim/syntax
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list