[m-dev.] diff: fix bug in Aditi compilation
Simon Taylor
stayl at cs.mu.OZ.AU
Mon Mar 13 15:05:48 AEDT 2000
Estimated hours taken: 2
Make sure that magic.m and rl_gen.m agree on which Aditi procedures
can be compiled together.
compiler/magic.m:
Run dead_proc_elim before working out which Aditi procedures
can be compiled together, so that calls from dead procedures
are not considered.
compiler/dead_proc_elim.m:
Remove the dependency graph if anything changed, because
the old dependency graph will still contain references
to the dead procedures.
compiler/dependency_graph.m:
Add a comment that dead_proc_elim should be run before
module_info_ensure_aditi_dependency_info.
Index: dead_proc_elim.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/dead_proc_elim.m,v
retrieving revision 1.53
diff -u -u -r1.53 dead_proc_elim.m
--- dead_proc_elim.m 2000/03/10 13:37:40 1.53
+++ dead_proc_elim.m 2000/03/13 00:28:54
@@ -524,26 +524,39 @@
---> elimination_info(
needed_map, % collected usage counts
module_info, % ye olde module_info
- pred_table % table of predicates in this module:
+ pred_table, % table of predicates in this module:
% preds and procs in this table
% may be eliminated
+ bool % has anything changed
).
dead_proc_elim__eliminate(ModuleInfo0, Needed0, ModuleInfo, State0, State) :-
module_info_predids(ModuleInfo0, PredIds),
module_info_preds(ModuleInfo0, PredTable0),
- ElimInfo0 = elimination_info(Needed0, ModuleInfo0, PredTable0),
+ Changed0 = no,
+ ElimInfo0 = elimination_info(Needed0, ModuleInfo0,
+ PredTable0, Changed0),
list__foldl2(dead_proc_elim__eliminate_pred, PredIds, ElimInfo0,
ElimInfo, State0, State),
- ElimInfo = elimination_info(Needed, ModuleInfo1, PredTable),
+ ElimInfo = elimination_info(Needed, ModuleInfo1, PredTable, Changed),
module_info_set_preds(ModuleInfo1, PredTable, ModuleInfo2),
module_info_type_ctor_gen_infos(ModuleInfo2, TypeCtorGenInfos0),
dead_proc_elim__eliminate_base_gen_infos(TypeCtorGenInfos0, Needed,
TypeCtorGenInfos),
module_info_set_type_ctor_gen_infos(ModuleInfo2, TypeCtorGenInfos,
- ModuleInfo).
+ ModuleInfo3),
+ (
+ Changed = yes,
+ % The dependency graph will still contain references to the
+ % eliminated procedures, so it must be rebuilt if it will
+ % be used later.
+ module_info_clobber_dependency_info(ModuleInfo3, ModuleInfo)
+ ;
+ Changed = no,
+ ModuleInfo = ModuleInfo3
+ ).
% eliminate any unused procedures for this pred
@@ -552,7 +565,7 @@
:- mode dead_proc_elim__eliminate_pred(in, in, out, di, uo) is det.
dead_proc_elim__eliminate_pred(PredId, ElimInfo0, ElimInfo, State0, State) :-
- ElimInfo0 = elimination_info(Needed, ModuleInfo, PredTable0),
+ ElimInfo0 = elimination_info(Needed, ModuleInfo, PredTable0, Changed0),
map__lookup(PredTable0, PredId, PredInfo0),
pred_info_import_status(PredInfo0, Status),
(
@@ -572,7 +585,8 @@
pred_info_procedures(PredInfo0, ProcTable0),
list__foldl2(dead_proc_elim__eliminate_proc(PredId, Keep,
ElimInfo0),
- ProcIds, ProcTable0, ProcTable, State0, State),
+ ProcIds, Changed0 - ProcTable0, Changed - ProcTable,
+ State0, State),
pred_info_set_procedures(PredInfo0, ProcTable, PredInfo),
map__det_update(PredTable0, PredId, PredInfo, PredTable)
;
@@ -580,6 +594,7 @@
% unoptimized opt_imported preds
Status = opt_imported
->
+ Changed = yes,
pred_info_procids(PredInfo0, ProcIds),
pred_info_procedures(PredInfo0, ProcTable0),
% Reduce memory usage by replacing the goals with
@@ -610,20 +625,22 @@
;
% This predicate is not defined in this module.
State = State0,
- PredTable = PredTable0
+ PredTable = PredTable0,
+ Changed = Changed0
),
- ElimInfo = elimination_info(Needed, ModuleInfo, PredTable).
+ ElimInfo = elimination_info(Needed, ModuleInfo, PredTable, Changed).
% eliminate a procedure, if unused
:- pred dead_proc_elim__eliminate_proc(pred_id, maybe(proc_id), elim_info,
- proc_id, proc_table, proc_table, io__state, io__state).
+ proc_id, pair(bool, proc_table), pair(bool, proc_table),
+ io__state, io__state).
:- mode dead_proc_elim__eliminate_proc(in, in, in, in, in, out, di, uo) is det.
dead_proc_elim__eliminate_proc(PredId, Keep, ElimInfo, ProcId,
- ProcTable0, ProcTable) -->
- { ElimInfo = elimination_info(Needed, ModuleInfo, _PredTable) },
+ Changed0 - ProcTable0, Changed - ProcTable) -->
+ { ElimInfo = elimination_info(Needed, ModuleInfo, _PredTable, _) },
(
% Keep the procedure if it is in the needed map
% or if it is to be kept because it is exported.
@@ -631,8 +648,10 @@
; { Keep = yes(ProcId) }
)
->
- { ProcTable = ProcTable0 }
+ { ProcTable = ProcTable0 },
+ { Changed = Changed0 }
;
+ { Changed = yes },
globals__io_lookup_bool_option(very_verbose, VeryVerbose),
( { VeryVerbose = yes } ->
write_proc_progress_message(
Index: dependency_graph.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/dependency_graph.m,v
retrieving revision 1.46
diff -u -u -r1.46 dependency_graph.m
--- dependency_graph.m 2000/02/25 03:44:32 1.46
+++ dependency_graph.m 2000/03/13 03:56:30
@@ -50,6 +50,9 @@
% negation or aggregation are merged into the parent SCC. This makes
% the low-level RL optimizations more effective while maintaining
% stratification.
+ % dead_proc_elim.m should be be run before this is called
+ % to avoid missing some opportunities for merging where
+ % a procedure is called from a dead procedure.
:- pred module_info_ensure_aditi_dependency_info(module_info, module_info).
:- mode module_info_ensure_aditi_dependency_info(in, out) is det.
Index: magic.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/magic.m,v
retrieving revision 1.13
diff -u -u -r1.13 magic.m
--- magic.m 2000/02/21 01:41:31 1.13
+++ magic.m 2000/03/08 03:42:58
@@ -21,6 +21,12 @@
% in context.m) must be applied to all Aditi predicates. The magic sets
% and context transformations are mutually exclusive.
%
+% It is important that no optimization which could optimize away calls
+% to Aditi procedures (e.g. simplify.m) be run between magic.m and rl_gen.m.
+% If Aditi calls are removed, the code in dependency_graph.m which merges
+% the SCCs containing Aditi predicates could become confused about which
+% predicates can be compiled together.
+%
%-----------------------------------------------------------------------------%
% Short example:
%
@@ -169,16 +175,38 @@
:- import_module dependency_graph, hlds_pred, hlds_goal, hlds_data, prog_data.
:- import_module passes_aux, mode_util, (inst), instmap, rl_gen, rl.
:- import_module globals, options, hlds_out, prog_out, goal_util, type_util.
-:- import_module polymorphism, quantification, saved_vars.
+:- import_module polymorphism, quantification, saved_vars, dead_proc_elim.
:- import_module int, list, map, require, set, std_util, string, term, varset.
:- import_module assoc_list, bool, simplify.
magic__process_module(ModuleInfo0, ModuleInfo) -->
- { module_info_ensure_aditi_dependency_info(ModuleInfo0, ModuleInfo1) },
- { module_info_aditi_dependency_ordering(ModuleInfo1, Ordering) },
- { magic_info_init(ModuleInfo1, Info0) },
- { module_info_predids(ModuleInfo1, PredIds) },
+
+ %
+ % Run simplification on Aditi procedures, mainly to get rid of
+ % nested explicit quantifications.
+ %
+ globals__io_get_globals(Globals),
+ { simplify__find_simplifications(no, Globals, Simplifications) },
+ process_matching_nonimported_procs(
+ update_module_io(
+ magic__ite_to_disj_and_simplify(Simplifications)),
+ _, hlds_pred__pred_info_is_aditi_relation,
+ ModuleInfo0, ModuleInfo1),
+
+ % We need to run dead_proc_elim before working out the
+ % Aditi dependency ordering because any calls from dead
+ % procedures could confuse the code to merge SCCs (because
+ % procedures called from multiple places are never merged).
+ %
+ % No optimizations which could optimize away calls to Aditi
+ % procedures (e.g. simplify.m) should be run after this is done.
+ dead_proc_elim(ModuleInfo1, ModuleInfo2),
+
+ { module_info_ensure_aditi_dependency_info(ModuleInfo2, ModuleInfo3) },
+ { module_info_aditi_dependency_ordering(ModuleInfo3, Ordering) },
+ { magic_info_init(ModuleInfo3, Info0) },
+ { module_info_predids(ModuleInfo3, PredIds) },
{ magic__process_imported_procs(PredIds, Info0, Info1) },
globals__io_lookup_bool_option(very_verbose, Verbose),
@@ -194,22 +222,79 @@
list__foldl2(magic__process_scc, Ordering, Info3, Info4),
{ list__foldl(magic__update_pred_status, PredIds, Info4, Info5) },
- { magic_info_get_module_info(ModuleInfo2, Info5, Info) },
+ { magic_info_get_module_info(ModuleInfo4, Info5, Info) },
{ magic_info_get_errors(Errors, Info, _) },
{ set__to_sorted_list(Errors, ErrorList) },
( { ErrorList = [] } ->
- { ModuleInfo3 = ModuleInfo2 }
+ { ModuleInfo5 = ModuleInfo4 }
;
globals__io_lookup_bool_option(verbose_errors, VerboseErrors),
magic_util__report_errors(ErrorList,
- ModuleInfo2, VerboseErrors),
- { module_info_incr_errors(ModuleInfo2, ModuleInfo3) },
+ ModuleInfo4, VerboseErrors),
+ { module_info_incr_errors(ModuleInfo4, ModuleInfo5) },
io__set_exit_status(1)
),
% New procedures were created, so the dependency_info
% is out of date.
- { module_info_clobber_dependency_info(ModuleInfo3, ModuleInfo) }.
+ { module_info_clobber_dependency_info(ModuleInfo5, ModuleInfo) }.
+
+%-----------------------------------------------------------------------------%
+
+ %
+ % Convert if-then-elses and switches to disjunctions,
+ % then run simplification to flatten goals and remove
+ % unnecessary existential quantifications.
+ %
+:- pred magic__ite_to_disj_and_simplify(list(simplification)::in, pred_id::in,
+ proc_id::in, proc_info::in, proc_info::out, module_info::in,
+ module_info::out, io__state::di, io__state::uo) is det.
+
+magic__ite_to_disj_and_simplify(Simplifications, PredId, ProcId,
+ ProcInfo0, ProcInfo, ModuleInfo0, ModuleInfo) -->
+ { proc_info_goal(ProcInfo0, Goal0) },
+
+ { Goal0 = if_then_else(_Vars, Cond, Then, Else, _SM) - GoalInfo ->
+ goal_util__if_then_else_to_disjunction(Cond, Then, Else,
+ GoalInfo, Disj),
+ Goal1 = Disj - GoalInfo,
+ proc_info_set_goal(ProcInfo0, Goal1, ProcInfo1),
+
+ % Requantify the goal to rename apart the variables
+ % in the copies of the condition.
+ requantify_proc(ProcInfo1, ProcInfo3),
+ ModuleInfo1 = ModuleInfo0
+ ; Goal0 = switch(Var, _Canfail, Cases, _SM) - GoalInfo ->
+ proc_info_varset(ProcInfo0, VarSet0),
+ proc_info_vartypes(ProcInfo0, VarTypes0),
+ proc_info_get_initial_instmap(ProcInfo0,
+ ModuleInfo0, InstMap),
+ % XXX check for existentially typed constructors first -
+ % they will cause an abort.
+ goal_util__switch_to_disjunction(Var, Cases,
+ InstMap, Disjuncts, VarSet0, VarSet1,
+ VarTypes0, VarTypes1, ModuleInfo0, ModuleInfo1),
+ proc_info_set_varset(ProcInfo0, VarSet1, ProcInfo1),
+ proc_info_set_vartypes(ProcInfo1, VarTypes1, ProcInfo2),
+ map__init(SM),
+ Goal1 = disj(Disjuncts, SM) - GoalInfo,
+ proc_info_set_goal(ProcInfo2, Goal1, ProcInfo3)
+ ;
+ ProcInfo3 = ProcInfo0,
+ ModuleInfo1 = ModuleInfo0
+ },
+
+ simplify__proc(Simplifications, PredId, ProcId,
+ ModuleInfo1, ModuleInfo2, ProcInfo3, ProcInfo4),
+
+ %
+ % Run saved_vars so that constructions of constants are close
+ % to their uses, and constant attributes aren't unnecessarily
+ % added to relations. We should be more aggressive about this -
+ % constructions of constant compound terms should also be pushed.
+ %
+ saved_vars_proc(PredId, ProcId, ProcInfo4, ProcInfo,
+ ModuleInfo2, ModuleInfo).
%-----------------------------------------------------------------------------%
@@ -1344,70 +1429,16 @@
magic__preprocess_proc(PredProcId, PredInfo, ProcInfo0, ProcInfo) -->
{ proc_info_goal(ProcInfo0, Goal0) },
-
- %
- % Convert if-then-elses and switches to disjunctions.
- %
- ( { Goal0 = if_then_else(_Vars, Cond, Then, Else, _SM) - GoalInfo } ->
- { goal_util__if_then_else_to_disjunction(Cond, Then, Else,
- GoalInfo, Disj) },
- { Goal1 = Disj - GoalInfo },
- { ProcInfo2 = ProcInfo0 }
- ; { Goal0 = switch(Var, _Canfail, Cases, _SM) - GoalInfo } ->
- { proc_info_varset(ProcInfo0, VarSet0) },
- { proc_info_vartypes(ProcInfo0, VarTypes0) },
- magic_info_get_module_info(ModuleInfo0),
- { proc_info_get_initial_instmap(ProcInfo0,
- ModuleInfo0, InstMap) },
- % XXX check for existentially typed constructors first -
- % they will cause an abort.
- { goal_util__switch_to_disjunction(Var, Cases,
- InstMap, Disjuncts, VarSet0, VarSet1,
- VarTypes0, VarTypes1, ModuleInfo0, ModuleInfo1) },
- magic_info_set_module_info(ModuleInfo1),
- { proc_info_set_varset(ProcInfo0, VarSet1, ProcInfo1) },
- { proc_info_set_vartypes(ProcInfo1, VarTypes1, ProcInfo2) },
- { map__init(SM) },
- { Goal1 = disj(Disjuncts, SM) - GoalInfo }
- ;
- { Goal1 = Goal0 },
- { ProcInfo2 = ProcInfo0 }
- ),
-
- { proc_info_set_goal(ProcInfo2, Goal1, ProcInfo3) },
-
- %
- % Run simplification, mainly to get rid of
- % nested explicit quantifications.
- %
- magic_info_get_module_info(ModuleInfo2),
- { module_info_globals(ModuleInfo2, Globals) },
- { simplify__find_simplifications(no, Globals, Simplifications) },
- { PredProcId = proc(PredId, ProcId) },
- { simplify__proc_2(Simplifications, PredId, ProcId,
- ModuleInfo2, ModuleInfo3, ProcInfo3, ProcInfo4, _) },
-
- %
- % Run saved_vars so that constructions of constants are close
- % to their uses, and constant attributes aren't unnecessarily
- % added to relations. We should be more aggressive about this -
- % constructions of constant compound terms should also be pushed.
- %
- { saved_vars_proc_no_io(PredId, ProcId, ProcInfo4, ProcInfo5,
- ModuleInfo3, ModuleInfo4) },
-
- { proc_info_goal(ProcInfo5, Goal2) },
magic_info_set_curr_pred_proc_id(PredProcId),
magic_info_set_pred_info(PredInfo),
- magic_info_set_proc_info(ProcInfo5),
- magic_info_set_module_info(ModuleInfo4),
- { Goal2 = _ - GoalInfo2 },
- { goal_to_disj_list(Goal2, GoalList2) },
+ magic_info_set_proc_info(ProcInfo0),
+ { Goal0 = _ - GoalInfo0 },
+ { goal_to_disj_list(Goal0, GoalList0) },
list__map_foldl(magic__preprocess_disjunct,
- GoalList2, GoalList),
- { disj_list_to_goal(GoalList, GoalInfo2, Goal) },
- magic_info_get_proc_info(ProcInfo6),
- { proc_info_set_goal(ProcInfo6, Goal, ProcInfo) }.
+ GoalList0, GoalList),
+ { disj_list_to_goal(GoalList, GoalInfo0, Goal) },
+ magic_info_get_proc_info(ProcInfo1),
+ { proc_info_set_goal(ProcInfo1, Goal, ProcInfo) }.
% Undo common structure elimination of higher-order terms in an
% attempt to avoid creating procedures with higher-order arguments
--------------------------------------------------------------------------
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