[m-dev.] [reuse] diff: structure reuse inside one module
Peter Ross
Peter.Ross at cs.kuleuven.ac.be
Thu Sep 21 23:27:11 AEDT 2000
Hi,
===================================================================
Estimated hours taken: 8
Get structure reuse working inside one module.
hlds_module.m:
Add the type structure_reuse_info. This type stores a mapping from
original procedure to the the version of the procedure with
structure reuse.
sr_reuse.m:
Add predicates contains_unconditional_reuse and
contains_conditional_reuse.
sr_reuse_run.m:
We now create two versions of a procedure if the procedure contains
conditional reuse. If it contains unconditional reuse then we
replace the original version with a version that does reuse.
Do a traversal of all the procedures replacing calls with calls to
the reuse version of the procedure when possible.
call_verify_reuse had to be changed to reflect that we now possibly
create two versions of a procedure, one with reuse and one without.
Index: hlds_module.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_module.m,v
retrieving revision 1.59.2.1
diff -u -r1.59.2.1 hlds_module.m
--- hlds_module.m 2000/09/19 10:01:24 1.59.2.1
+++ hlds_module.m 2000/09/20 17:08:54
@@ -100,6 +100,14 @@
% becomes exported.
).
+:- type structure_reuse_info
+ ---> structure_reuse_info(
+ map(pred_proc_id, pair(pred_proc_id, sym_name))
+ % Given a procedure, determine
+ % the structure reuse version of
+ % that procedure.
+ ).
+
% This field should be set to `do_aditi_compilation' if there
% are local Aditi predicates.
:- type do_aditi_compilation
@@ -312,6 +320,13 @@
type_spec_info, module_info).
:- mode module_info_set_type_spec_info(in, in, out) is det.
+:- pred module_info_structure_reuse_info(module_info, structure_reuse_info).
+:- mode module_info_structure_reuse_info(in, out) is det.
+
+:- pred module_info_set_structure_reuse_info(module_info,
+ structure_reuse_info, module_info).
+:- mode module_info_set_structure_reuse_info(in, in, out) is det.
+
%-----------------------------------------------------------------------------%
:- pred module_info_preds(module_info, pred_table).
@@ -499,9 +514,13 @@
do_aditi_compilation :: do_aditi_compilation,
% are there any local Aditi predicates
% for which Aditi-RL must be produced.
- type_spec_info :: type_spec_info
+ type_spec_info :: type_spec_info,
% data used for user-guided type
% specialization.
+ structure_reuse_info :: structure_reuse_info
+ % information about which
+ % procedures use structure
+ % reuse.
).
% A predicate which creates an empty module
@@ -524,6 +543,9 @@
TypeSpecInfo = type_spec_info(TypeSpecPreds,
TypeSpecForcePreds, SpecMap, PragmaMap),
+ map__init(ReuseMap),
+ ReuseSpecInfo = structure_reuse_info(ReuseMap),
+
map__init(ClassTable),
map__init(InstanceTable),
map__init(SuperClassTable),
@@ -539,7 +561,8 @@
ModuleSubInfo = module_sub(Name, Globals, [], [], no, 0, 0, [],
[], StratPreds, UnusedArgInfo, 0, ImportedModules,
- IndirectlyImportedModules, no_aditi_compilation, TypeSpecInfo),
+ IndirectlyImportedModules, no_aditi_compilation, TypeSpecInfo,
+ ReuseSpecInfo),
ModuleInfo = module(ModuleSubInfo, PredicateTable, Requests,
UnifyPredMap, QualifierInfo, Types, Insts, Modes, Ctors,
ClassTable, SuperClassTable, InstanceTable, AssertionTable,
@@ -609,6 +632,7 @@
module_info_get_indirectly_imported_module_specifiers(MI,
MI^sub_info^indirectly_imported_module_specifiers).
module_info_type_spec_info(MI, MI^sub_info^type_spec_info).
+module_info_structure_reuse_info(MI, MI^sub_info^structure_reuse_info).
module_info_get_do_aditi_compilation(MI,
MI^sub_info^do_aditi_compilation).
@@ -647,6 +671,8 @@
MI^sub_info^indirectly_imported_module_specifiers, Modules)).
module_info_set_type_spec_info(MI, NewVal,
MI^sub_info^type_spec_info := NewVal).
+module_info_set_structure_reuse_info(MI, NewVal,
+ MI^sub_info^structure_reuse_info := NewVal).
module_info_set_do_aditi_compilation(MI,
MI^sub_info^do_aditi_compilation := do_aditi_compilation).
Index: sr_reuse.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/Attic/sr_reuse.m,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 sr_reuse.m
--- sr_reuse.m 2000/09/19 10:02:13 1.1.2.1
+++ sr_reuse.m 2000/09/20 17:08:58
@@ -165,7 +165,14 @@
tabled_reuse).
:- mode tabled_reuse_rename( in, in, out ) is det.
+ % The procedure contains reuse which requires we check
+ % conditions before being able to use the reuse. This implies
+ % that we need to create a new version of the code.
+:- pred contains_conditional_reuse(tabled_reuse::in) is semidet.
+ % The procedure contains unconditional reuse.
+:- pred contains_unconditional_reuse(tabled_reuse::in) is semidet.
+
%-------------------------------------------------------------------%
%-------------------------------------------------------------------%
%-------------------------------------------------------------------%
@@ -371,6 +378,9 @@
%-------------------------------------------------------------------%
:- type tabled_reuse == maybe(list(reuse_condition)).
+
+contains_conditional_reuse(yes([_ | _])).
+contains_unconditional_reuse(yes([])).
to_tabled_reuse( ReusesIN, TabledReuse ):-
% remove all the dead deconstructs which do not have
Index: sr_reuse_run.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/Attic/sr_reuse_run.m,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 sr_reuse_run.m
--- sr_reuse_run.m 2000/09/20 11:16:51 1.1.2.2
+++ sr_reuse_run.m 2000/09/20 17:08:59
@@ -42,7 +42,7 @@
% library modules
:- import_module require.
:- import_module bool, set, list, map, int.
-:- import_module std_util, string.
+:- import_module std_util, string, term.
% compiler modules
:- import_module dependency_graph.
@@ -70,7 +70,10 @@
->
{ hlds_dependency_info_get_dependency_ordering( DepInfo, DepOrdering ) },
% perform the analysis, and annotate the procedures
- run_with_dependencies( DepOrdering, HLDS1, HLDSout) %,
+ run_with_dependencies( DepOrdering, HLDS1, HLDS2),
+ process_all_nonimported_procs(
+ update_module_io(process_proc),
+ HLDS2, HLDSout)
;
{ error("(sr_reuse_run) reuse_pass: no dependency info") }
).
@@ -415,9 +418,19 @@
in, out,
in, out) is det.
-call_verify_reuse( ProcInfo, HLDS, PredId, ProcId, ActualVars, Alias0,
+call_verify_reuse( ProcInfo, HLDS, PredId0, ProcId0, ActualVars, Alias0,
Reuses0, Reuses,
Info0, Info, FP0, FP ) :-
+
+ module_info_structure_reuse_info(HLDS, ReuseInfo),
+ ReuseInfo = structure_reuse_info(ReuseMap),
+ ( map__search(ReuseMap, proc(PredId0, ProcId0), Result) ->
+ Result = proc(PredId, ProcId) - _Name
+ ;
+ PredId = PredId0,
+ ProcId = ProcId0
+ ),
+
% 0. fetch the procinfo of the called procedure:
module_info_pred_proc_info( HLDS, PredId, ProcId, _,
ProcInfo0),
@@ -465,11 +478,6 @@
)
).
-
-
-
-
-
:- pred unification_verify_reuse( hlds_goal__unification,
alias_as, reuses, reuses,
hlds_goal_info, hlds_goal_info).
@@ -579,15 +587,74 @@
:- mode update_reuse_in_module_info(in, in, in, out) is det.
update_reuse_in_module_info( FP, PRED_PROC_ID ,HLDSin, HLDSout) :-
- module_info_pred_proc_info( HLDSin, PRED_PROC_ID, PredInfo0,
+ module_info_pred_proc_info(HLDSin, PRED_PROC_ID, PredInfo0,
ProcInfo0),
- sr_reuse_util__sr_fixpoint_table_get_final_reuse( PRED_PROC_ID,
- TREUSE, HLDS_GOAL, FP ),
- proc_info_set_reuse_information( ProcInfo0, TREUSE, ProcInfo1 ),
- proc_info_set_goal( ProcInfo1, HLDS_GOAL, ProcInfo),
- module_info_set_pred_proc_info( HLDSin, PRED_PROC_ID,
- PredInfo0, ProcInfo, HLDSout).
+ sr_reuse_util__sr_fixpoint_table_get_final_reuse(PRED_PROC_ID,
+ TREUSE, HLDS_GOAL, FP),
+ ( contains_conditional_reuse(TREUSE) ->
+ create_reuse_pred(TREUSE, HLDS_GOAL, PredInfo0, ProcInfo0,
+ ReusePredInfo, _ReuseProcInfo,
+ ReuseProcId, ReuseName),
+
+ module_info_get_predicate_table(HLDSin, PredTable0),
+ predicate_table_insert(PredTable0, ReusePredInfo,
+ ReusePredId, PredTable),
+ module_info_structure_reuse_info(HLDSin, StrReuseInfo0),
+ StrReuseInfo0 = structure_reuse_info(ReuseMap0),
+ map__det_insert(ReuseMap0, PRED_PROC_ID,
+ proc(ReusePredId, ReuseProcId) - ReuseName,
+ ReuseMap),
+ StrReuseInfo = structure_reuse_info(ReuseMap),
+ module_info_set_structure_reuse_info(HLDSin,
+ StrReuseInfo, HLDSin1),
+ module_info_set_predicate_table(HLDSin1, PredTable, HLDSout)
+ ; contains_unconditional_reuse(TREUSE) ->
+ proc_info_set_reuse_information(ProcInfo0, TREUSE, ProcInfo1),
+ proc_info_set_goal(ProcInfo1, HLDS_GOAL, ProcInfo),
+ module_info_set_pred_proc_info(HLDSin, PRED_PROC_ID,
+ PredInfo0, ProcInfo, HLDSout)
+ ;
+ HLDSout = HLDSin
+ ).
+
+%-----------------------------------------------------------------------------%
+:- pred create_reuse_pred(tabled_reuse::in, hlds_goal::in,
+ pred_info::in, proc_info::in,
+ pred_info::out, proc_info::out,
+ proc_id::out, sym_name::out) is det.
+
+create_reuse_pred(TabledReuse, ReuseGoal, PredInfo, ProcInfo,
+ ReusePredInfo, ReuseProcInfo, ReuseProcId, SymName) :-
+ proc_info_set_reuse_information(ProcInfo, TabledReuse, ReuseProcInfo0),
+ proc_info_set_goal(ReuseProcInfo0, ReuseGoal, ReuseProcInfo),
+
+ pred_info_module(PredInfo, ModuleName),
+ pred_info_name(PredInfo, Name),
+ pred_info_arg_types(PredInfo, TypeVarSet, ExistQVars, Types),
+ Cond = true,
+ pred_info_context(PredInfo, PredContext),
+ pred_info_get_markers(PredInfo, Markers),
+ pred_info_get_is_pred_or_func(PredInfo, PredOrFunc),
+ pred_info_get_class_context(PredInfo, ClassContext),
+ pred_info_get_aditi_owner(PredInfo, Owner),
+
+ set__init(Assertions),
+
+ proc_info_context(ProcInfo, Context),
+ term__context_line(Context, Line),
+ Counter = 0,
+
+ make_pred_name_with_context(ModuleName, "Reuse", PredOrFunc, Name,
+ Line, Counter, SymName),
+
+ pred_info_create(ModuleName, SymName, TypeVarSet, ExistQVars, Types,
+ Cond, PredContext, local, Markers, PredOrFunc,
+ ClassContext, Owner, Assertions, ReuseProcInfo,
+ ReuseProcId, ReusePredInfo).
+
+%-----------------------------------------------------------------------------%
+
:- pred lookup_tabled_reuse( pred_id, proc_id, module_info,
sr_fixpoint_table, sr_fixpoint_table,
tabled_reuse ).
@@ -628,3 +695,98 @@
_TrueList,
[] ).
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- pred process_proc(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.
+
+process_proc(_PredId, _ProcId, ProcInfo0, ProcInfo,
+ ModuleInfo0, ModuleInfo) -->
+ { proc_info_goal(ProcInfo0, Goal0) },
+ { process_goal(Goal0, Goal, ModuleInfo0, ModuleInfo) },
+ { proc_info_set_goal(ProcInfo0, Goal, ProcInfo) }.
+
+%-----------------------------------------------------------------------------%
+
+:- pred process_goal(hlds_goal::in, hlds_goal::out,
+ module_info::in, module_info::out) is det.
+
+process_goal(Goal0 - GoalInfo, Goal - GoalInfo) -->
+ { Goal0 = call(PredId0, ProcId0, Args, Builtin, MaybeContext, Name0) },
+ =(ModuleInfo),
+ { module_info_structure_reuse_info(ModuleInfo, ReuseInfo) },
+ { ReuseInfo = structure_reuse_info(ReuseMap) },
+ {
+ goal_info_get_reuse(GoalInfo, reuse_call),
+ map__search(ReuseMap, proc(PredId0, ProcId0), Result)
+ ->
+ Result = proc(PredId, ProcId) - Name
+ ;
+ PredId = PredId0,
+ ProcId = ProcId0,
+ Name = Name0
+ },
+ { Goal = call(PredId, ProcId, Args, Builtin, MaybeContext, Name) }.
+
+process_goal(Goal0 - GoalInfo, Goal - GoalInfo) -->
+ { Goal0 = unify(_, _, _, _, _) },
+ { Goal = Goal0 }.
+process_goal(Goal0 - GoalInfo, Goal - GoalInfo) -->
+ { Goal0 = generic_call(_, _, _, _) },
+ { Goal = Goal0 }.
+process_goal(Goal0 - GoalInfo, Goal - GoalInfo) -->
+ { Goal0 = pragma_foreign_code(_, _, _, _, _, _, _, _) },
+ { Goal = Goal0 }.
+process_goal(Goal0 - _GoalInfo, _) -->
+ { Goal0 = bi_implication(_, _) },
+ { error("structure_reuse: bi_implication.\n") }.
+
+process_goal(Goal0 - GoalInfo, Goal - GoalInfo) -->
+ { Goal0 = if_then_else(Vars, If0, Then0, Else0, SM) },
+ process_goal(If0, If),
+ process_goal(Then0, Then),
+ process_goal(Else0, Else),
+ { Goal = if_then_else(Vars, If, Then, Else, SM) }.
+
+process_goal(Goal0 - GoalInfo, Goal - GoalInfo) -->
+ { Goal0 = switch(Var, CanFail, Cases0, StoreMap) },
+ process_goal_cases(Cases0, Cases),
+ { Goal = switch(Var, CanFail, Cases, StoreMap) }.
+
+process_goal(Goal0 - GoalInfo, Goal - GoalInfo) -->
+ { Goal0 = some(Vars, CanRemove, SomeGoal0) },
+ process_goal(SomeGoal0, SomeGoal),
+ { Goal = some(Vars, CanRemove, SomeGoal) }.
+
+process_goal(not(Goal0) - GoalInfo, not(Goal) - GoalInfo) -->
+ process_goal(Goal0, Goal).
+process_goal(conj(Goal0s) - GoalInfo, conj(Goals) - GoalInfo) -->
+ process_goal_list(Goal0s, Goals).
+process_goal(disj(Goal0s, SM) - GoalInfo, disj(Goals, SM) - GoalInfo) -->
+ process_goal_list(Goal0s, Goals).
+process_goal(par_conj(Goal0s, SM) - GoalInfo,
+ par_conj(Goals, SM) - GoalInfo) -->
+ process_goal_list(Goal0s, Goals).
+
+:- pred process_goal_cases(list(case)::in, list(case)::out,
+ module_info::in, module_info::out) is det.
+
+process_goal_cases([], []) --> [].
+process_goal_cases([Case0 | Case0s], [Case | Cases]) -->
+ { Case0 = case(ConsId, Goal0) },
+ process_goal(Goal0, Goal),
+ { Case = case(ConsId, Goal) },
+ process_goal_cases(Case0s, Cases).
+
+:- pred process_goal_list(hlds_goals::in, hlds_goals::out,
+ module_info::in, module_info::out) is det.
+
+process_goal_list([], []) --> [].
+process_goal_list([Goal0 | Goal0s], [Goal | Goals]) -->
+ process_goal(Goal0, Goal),
+ process_goal_list(Goal0s, Goals).
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
--------------------------------------------------------------------------
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