My previous fix to dead proc elimination helped fixed some compiler aborts,

Estimated hours taken: 8
Branches: main

My previous fix to dead proc elimination helped fixed some compiler aborts,
but a related problem remained.

The problem involved an unused procedure that was kept around so that the code
generator would create the table associated with it. Since the procedure was
unused, its body was thought to be unused too. If it contained a reference to a
procedure that wasn't referred to from anywhere else, that procedure would be
removed, leaving a dangling reference. This would cause a code generator abort.

We can't fix the abort by replacing the kept-around procedure's body with
"true", since that would cause a different code generator abort when moving the
(now unbound) output variables to their argument registers. We could avoid
generating any code for the procedure at all by e.g. marking it as
opt_imported, but this would (a) be inconsistent and (b) require special case
coding to still generate the table structure.

The fix is to generate the global variable used for tabling *independently* of
the procedure that enters things in the table.

compiler/hlds_module.m:
	Add a field to the module_info (actually module_sub_info) that records
	the information the backends need to create the global variables
	representing call tables.

	Name all the fields of the module_info and module_sub_info during
	initialization, to make it easier to know where to add a new field.
	Put the initializations of the fields in the same order as the fields
	themselves.

compiler/hlds_pred.m:
	Keep only the info for I/O tabling in procedures, since such tabling
	does not require defining a per-procedure global variable.

	Since the info for the forms of tabling that *do* require a
	per-procedure global variable are now divorced from the procedure,
	change their definition to avoid storing prog_vars in them, since
	those prog_vars would be separated from their varset. Instead, we
	record their numbers and their names (both are used only for debug
	support).

	On the other hand, some info from the pred_info and proc_info are
	to create the global variable; copy them into the data structure stored
	in hlds_module.

	Rename some fields to avoid ambiguities.

compiler/table_gen.m:
	Continue to record information about I/O tabling in the proc_info,
	but record information about other forms of tabling in the new field
	in the module_info.

compiler/rtti.m:
compiler/hlds_rtti.m:
	Move the functions for constructing and deconstructing rtti_proc_labels
	from rtti.m (which is in backend_libs) to hlds_rtti.m (which is in
	hlds); the definition of rtti_proc_label was already in hlds_rtti.m.
	The move is needed to allow table_gen to put an rtti_proc_label
	in the data structures it puts in the module_info.

compiler/hlds_out.m:
	Print out the new module_info field, and conform to the change to
	hlds_pred and table_arg_info.

	Always print variable numbers for type variables in table_arg_infos.

compiler/continuation_info.m:
	Make room for either kind of tabling info for a procedure.
	(While the LLDS code generator doesn't need to know about the global
	variable representing the call table in order to create it, it does
	need to know about it in order to describe it to the debugger.)

	Conform to the change in table_arg_info.

	Rename some fields to avoid ambiguities.

compiler/proc_gen.m:
	When generating code for procedures, do not try to create a
	per-procedure tabling struct, but do fill in the slot describing it
	in the continuation_info.

	Add a predicate to define all the tabling structs in a module.

compiler/mercury_compile.m:
	Call proc_gen separately to define all the tabling structs.

compiler/ml_code_gen.m:
	As with proc_gen, define tabling structs directly from the module_info
	and not when generating code from each proc_info.

	(The code for handling each proc is now logically not contiguous;
	I will address that in a separate change, to make the diff for this one
	easier to read.)

compiler/dead_proc_elim.m:
	Don't keep unused tabled procedures alive, since that leads to the
	problem described up top.

	Keep track of which tabling structs are live, but don't yet act on that
	information, since some uses are hidden (for now).

	Add conditionally compiled tracing code that helped me trace down the
	problem.

	Fix an oversight in the severity level of an error spec.

compiler/base_typeclass_info.m:
compiler/code_util.m:
compiler/deep_profiling.m:
compiler/ml_code_util.m:
compiler/proc_label.m:
compiler/type_ctor_info.m:
	Conform to the move of make_rtti_proc_label.

compiler/optimize.m:
	Conform to the change to continuation_info.

compiler/stack_layout.m:
	Conform to the data structure changes above.

doc/user_guide.texi:
	Document 'Z' as the character in -D arguments that tells hlds_out
	to dump the global structures needed for tabling.

	Fix an old oversight: document 'S' as the character in -D arguments
	that tells hlds_out to dump info about structure sharing.

compiler/handle_options.m:
	Include 'Z' in -DALL -and -Dall.

tests/tabling/mercury_java_parser_dead_proc_elim_bug.{m,exp}:
	Move this test case here from valid, since compiling all the way to
	executable doesn't work in valid (in yields link errors unrelated to
	the bug we are testing for).

tests/tabling/mercury_java_parser_dead_proc_elim_bug2.{m,exp}:
	Add this new test case that in unfixed compilers gives the problem
	described up top.

tests/tabling/Mmakefile:
	Enable the new tests.

tests/valid/Mmakefile:
tests/valid/Mercury.options:
tests/valid/mercury_java_parser_dead_proc_elim_bug.m:
	Remove references to the moved test and the test itself.
This commit is contained in:
Zoltan Somogyi
2007-08-13 03:02:02 +00:00
parent 94a45f1477
commit fcf0847a91
28 changed files with 2882 additions and 433 deletions

View File

@@ -104,7 +104,7 @@
%---------------------------------------------------------------------------%
make_entry_label(ModuleInfo, PredId, ProcId, Immed) = ProcAddr :-
RttiProcLabel = rtti.make_rtti_proc_label(ModuleInfo, PredId, ProcId),
RttiProcLabel = make_rtti_proc_label(ModuleInfo, PredId, ProcId),
ProcAddr = make_entry_label_from_rtti(RttiProcLabel, Immed).
make_entry_label_from_rtti(RttiProcLabel, Immed) = ProcAddr :-
@@ -117,7 +117,7 @@ make_entry_label_from_rtti(RttiProcLabel, Immed) = ProcAddr :-
).
make_local_entry_label(ModuleInfo, PredId, ProcId, Immed) = Label :-
RttiProcLabel = rtti.make_rtti_proc_label(ModuleInfo, PredId, ProcId),
RttiProcLabel = make_rtti_proc_label(ModuleInfo, PredId, ProcId),
Label = make_local_entry_label_from_rtti(RttiProcLabel, Immed).
:- func make_local_entry_label_from_rtti(rtti_proc_label, immed) = label.