[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