[m-dev.] for review: typeinfo-liveness bug fix

Zoltan Somogyi zs at cs.mu.OZ.AU
Thu Jul 20 14:20:57 AEST 2000


For review by anyone.

compiler/liveness.m:
	Fix a bug: the compiler did not make sure that the sets of variables
	in resume_points satisfy the requirements of typeinfo liveness when
	required (i.e. it included variables in the resume point set without
	also including the typeinfos describing their types). This lead to a
	compiler abort when compiling with options (e.g. --trace deep) that
	imply typeinfo liveness.

tests/debugger/resume_typeinfos.{m,inp,exp,exp2}
	A test case to exercise the fix.

tests/debugger/Mmakefile:
	Enable the new test case, and put the test list back into alphabetic
	order.

Zoltan.

cvs diff: Diffing .
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/liveness.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/liveness.m,v
retrieving revision 1.103
diff -u -b -r1.103 liveness.m
--- compiler/liveness.m	2000/02/10 04:47:41	1.103
+++ compiler/liveness.m	2000/07/17 22:56:21
@@ -679,7 +679,10 @@
 	Else0 = _ElseExpr0 - ElseInfo0,
 	goal_info_get_pre_deaths(ElseInfo0, ElsePreDeath0),
 	set__difference(Liveness0, ElsePreDeath0, CondResumeVars0),
-	set__union(CondResumeVars0, ResumeVars0, CondResumeVars),
+	liveness__maybe_complete_with_typeinfos(LiveInfo, CondResumeVars0,
+		CondResumeVars1),
+		% ResumeVars0 should already have been completed.
+	set__union(CondResumeVars1, ResumeVars0, CondResumeVars),
 
 	detect_resume_points_in_goal(Cond0, Liveness0, LiveInfo,
 		CondResumeVars, Cond1, LivenessCond),
@@ -722,7 +725,10 @@
 		not(Goal), Liveness) :-
 	detect_resume_points_in_goal(Goal0, Liveness0, LiveInfo, ResumeVars0,
 		_, Liveness),
-	set__union(Liveness, ResumeVars0, ResumeVars1),
+	liveness__maybe_complete_with_typeinfos(LiveInfo, Liveness,
+		CompletedLiveness),
+		% ResumeVars0 should already have been completed.
+	set__union(CompletedLiveness, ResumeVars0, ResumeVars1),
 	detect_resume_points_in_goal(Goal0, Liveness0, LiveInfo, ResumeVars1,
 		Goal1, _Liveness),
 
@@ -777,6 +783,14 @@
 	% we stop generating code after the first cannot_fail disjunct.
 	% Second, an empty pruned disjunction is legal, while an empty
 	% nondet disjunction isn't.
+	%
+	% For both kinds of disjunctions, the resume points to be attached to
+	% the non-last disjuncts must be completed with the required typeinfos
+	% if --typeinfo-liveness is set. ResumeVars0 should already be so
+	% completed, so need only completed the sets added here. We therefore
+	% perform this completion when we return the set of variables needed by
+	% the last disjunct, and when we add to this set the set of variables
+	% needed by a non-last disjunct.
 
 :- pred detect_resume_points_in_non_disj(list(hlds_goal), set(prog_var),
 		live_info, set(prog_var), list(hlds_goal),
@@ -876,7 +890,10 @@
 	Goal = _ - GoalInfo,
 	goal_info_get_pre_deaths(GoalInfo, PreDeaths),
 	set__difference(Liveness0, PreDeaths, NeededFirst),
-	set__union(NeededFirst, NeededRest, Needed),
+	liveness__maybe_complete_with_typeinfos(LiveInfo, NeededFirst,
+		CompletedNeededFirst),
+		% NeededRest has already been completed.
+	set__union(CompletedNeededFirst, NeededRest, Needed),
 
 	require_equal(Liveness, LivenessRest, "disjunction", LiveInfo).
 
@@ -886,12 +903,14 @@
 	is det.
 
 detect_resume_points_in_last_disjunct(Goal0, Liveness0, LiveInfo,
-		ResumeVars0, Goal, Liveness, Needed) :-
+		ResumeVars0, Goal, Liveness, CompletedNeeded) :-
 	detect_resume_points_in_goal(Goal0, Liveness0, LiveInfo,
 		ResumeVars0, Goal, Liveness),
 	Goal = _ - GoalInfo,
 	goal_info_get_pre_deaths(GoalInfo, PreDeaths),
-	set__difference(Liveness0, PreDeaths, Needed).
+	set__difference(Liveness0, PreDeaths, Needed),
+	liveness__maybe_complete_with_typeinfos(LiveInfo, Needed,
+		CompletedNeeded).
 
 :- pred detect_resume_points_in_cases(list(case), set(prog_var), live_info,
 		set(prog_var), list(case), set(prog_var)).
@@ -1166,23 +1185,27 @@
 	% Get the nonlocals, and, if doing alternate liveness, add the
 	% typeinfo vars for the nonlocals.
 
-:- pred liveness__get_nonlocals_and_typeinfos(live_info, hlds_goal_info,
-		set(prog_var)).
-:- mode liveness__get_nonlocals_and_typeinfos(in, in, out) is det.
+:- pred liveness__get_nonlocals_and_typeinfos(live_info::in, hlds_goal_info::in,
+	set(prog_var)::out) is det.
 
 liveness__get_nonlocals_and_typeinfos(LiveInfo, GoalInfo, 
 		NonLocals) :-
 	goal_info_get_code_gen_nonlocals(GoalInfo, NonLocals0),
+	liveness__maybe_complete_with_typeinfos(LiveInfo,
+		NonLocals0, NonLocals).
+
+:- pred liveness__maybe_complete_with_typeinfos(live_info::in,
+	set(prog_var)::in, set(prog_var)::out) is det.
+
+liveness__maybe_complete_with_typeinfos(LiveInfo, Vars0, Vars) :-
 	live_info_get_typeinfo_liveness(LiveInfo, TypeinfoLiveness),
-	( 
-		TypeinfoLiveness = yes
-	->
+	( TypeinfoLiveness = yes ->
 		live_info_get_proc_info(LiveInfo, ProcInfo),
-		proc_info_get_typeinfo_vars_setwise(ProcInfo, NonLocals0,
-			TypeInfoVarsNonLocals),
-		set__union(NonLocals0, TypeInfoVarsNonLocals, NonLocals)
+		proc_info_get_typeinfo_vars_setwise(ProcInfo, Vars0,
+			TypeInfoVars),
+		set__union(Vars0, TypeInfoVars, Vars)
 	;
-		NonLocals = NonLocals0
+		Vars = Vars0
 	).
 
 %-----------------------------------------------------------------------------%
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/aditi
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing library
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
Index: tests/debugger/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/Mmakefile,v
retrieving revision 1.41
diff -u -b -r1.41 Mmakefile
--- tests/debugger/Mmakefile	2000/06/19 07:59:18	1.41
+++ tests/debugger/Mmakefile	2000/07/17 22:52:48
@@ -30,9 +30,10 @@
 	loopcheck			\
 	mdb_command_test		\
 	multi_parameter			\
+	polymorphic_output		\
 	queens				\
-	shallow				\
-	polymorphic_output
+	resume_typeinfos		\
+	shallow
 
 # The following tests are disabled, since currently they get some spurious
 # failures if readline support is enabled:
Index: tests/debugger/resume_typeinfos.exp
===================================================================
RCS file: resume_typeinfos.exp
diff -N resume_typeinfos.exp
--- /dev/null	Thu Mar  4 04:20:11 1999
+++ resume_typeinfos.exp	Mon Jul 17 18:40:42 2000
@@ -0,0 +1,14 @@
+       1:      1  1 CALL pred resume_typeinfos:main/2-0 (det) resume_typeinfos.m:25
+mdb> echo on
+Command echo enabled.
+mdb> context none
+Contexts will not be printed.
+mdb> goto 5
+       5:      4  3 CALL pred list:length/2-0 (det)
+mdb> finish
+      15:      4  3 EXIT pred list:length/2-0 (det)
+mdb> print *
+       HeadVar__1             	[1, 2]
+       HeadVar__2             	2
+mdb> continue
+no solution.
Index: tests/debugger/resume_typeinfos.exp2
===================================================================
RCS file: resume_typeinfos.exp2
diff -N resume_typeinfos.exp2
--- /dev/null	Thu Mar  4 04:20:11 1999
+++ resume_typeinfos.exp2	Mon Jul 17 18:40:42 2000
@@ -0,0 +1,14 @@
+       1:      1  1 CALL pred resume_typeinfos:main/2-0 (det) resume_typeinfos.m:25
+mdb> echo on
+Command echo enabled.
+mdb> context none
+Contexts will not be printed.
+mdb> goto 5
+       5:      4  3 CALL pred list:length/2-0 (det)
+mdb> finish
+      15:      4  3 EXIT pred list:length/2-0 (det)
+mdb> print *
+       HeadVar__1             	[1, 2]
+       HeadVar__2             	2
+mdb> continue
+no solution.
Index: tests/debugger/resume_typeinfos.inp
===================================================================
RCS file: resume_typeinfos.inp
diff -N resume_typeinfos.inp
--- /dev/null	Thu Mar  4 04:20:11 1999
+++ resume_typeinfos.inp	Mon Jul 17 18:40:42 2000
@@ -0,0 +1,6 @@
+echo on
+context none
+goto 5
+finish
+print *
+continue
Index: tests/debugger/resume_typeinfos.m
===================================================================
RCS file: resume_typeinfos.m
diff -N resume_typeinfos.m
--- /dev/null	Thu Mar  4 04:20:11 1999
+++ resume_typeinfos.m	Thu Jul 20 14:17:44 2000
@@ -0,0 +1,56 @@
+% This is a regression test. Earlier versions of the compiler had a bug:
+% they did not make sure that the sets of variables in resume_points satisfy
+% the requirements of typeinfo liveness (i.e. they included variables in the
+% resume point set without also including the typeinfos describing their
+% types). This lead to a compiler abort when compiling with options (e.g.
+% --trace deep) that imply typeinfo liveness.
+
+% Note that even the current implementation core dumps if we stop at the
+% interface events of introduce_new_typeinfo. This problem is being looked
+% into.
+
+:- module resume_typeinfos.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+:- import_module int, list.
+
+main -->
+	( { test([1, 2], Result) } ->
+		io__write_int(Result),
+		io__write_string("\n")
+	;
+		io__write_string("no solution.\n")
+	).
+
+:- some [U] pred introduce_new_typeinfo(list(T)::in, list(U)::out) is det.
+:- pragma no_inline(introduce_new_typeinfo/2).
+
+introduce_new_typeinfo(_, ["fortytwo"]).
+
+:- pred test(list(T)::in, int::out) is semidet.
+
+test(TestList, Result) :-
+	introduce_new_typeinfo(TestList, NewList),
+	(
+		list__length(TestList, Length),
+		Length > 5
+	->
+		Result = 10
+	;
+		% The code here does not need the typeinfo for the
+		% elements of NewList, but typeinfo liveness requires
+		% this typeinfo to be in the resume point established
+		% for the condition, since the debugger may need it to
+		% print the value of NewList at the else event.
+
+		NewList = [],
+		Result = 42
+	).
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing trial
cvs diff: Diffing util
--------------------------------------------------------------------------
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