[m-rev.] diff: fix deforestation performance problems

Simon Taylor stayl at cs.mu.OZ.AU
Tue Jul 31 04:59:10 AEST 2001


Estimated hours taken: 2
Branches: main

Avoid pathological behaviour of deforestation on
module_qual__process_assert.

compiler/deforest.m
	Avoid retrying specialization where a previous attempt to
	deforest a pair of called procedures was unsuccessful.

	Don't attempt deforestation if the goals involved
	are too large.

compiler/pd_info.m:
	Add field names to the data structures.

compiler/options.m:
doc/user_guide.texi:
	Add an option `--deforestation-size-limit' to limit
	the size of goals participating in deforestation.

	Make sure all the deforestation and inlining options
	are documented.

Index: compiler/deforest.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/deforest.m,v
retrieving revision 1.22
diff -u -u -r1.22 deforest.m
--- compiler/deforest.m	2001/04/09 07:29:59	1.22
+++ compiler/deforest.m	2001/07/30 18:48:51
@@ -7,9 +7,22 @@
 % Main author: stayl.
 %-----------------------------------------------------------------------------%
 %
-% Deforestation.
+% Deforestation attempts to remove multiple traversals over data structures,
+% and construction followed by immediate deconstruction of data structures.
+% It does this by combining the bodies of pairs of called procedures in
+% a conjunction where the top-level functor of one of the argument variables
+% of the first called procedure is known at the end of some of the branches
+% of the body of that procedure, and the second called procedure switches on
+% that variable.
 %
-% A start on the documentation for this is in $CVSROOT/papers/deforest.
+% The deforestation pass also inlines calls for which the top-level
+% goal in the called procedure is a switch and the functor of the
+% switched-on variable is known. This allows simplify.m to prune away
+% the failing branches.
+%  
+% For a more detailed description, see Simon Taylor's Honours thesis,
+% available from
+% <http://www.cs.mu.oz.au/research/mercury/information/papers/stayl_hons.ps.gz>
 %
 %-----------------------------------------------------------------------------%
 :- module deforest.
@@ -600,7 +613,18 @@
 	pd_info_get_module_info(ModuleInfo),
 	pd_info_lookup_option(fully_strict, FullyStrictOp),
 	pd_info_get_pred_info(PredInfo),
+	pd_info_get_useless_versions(UselessVersions),
+	pd_info_lookup_option(deforestation_size_threshold, SizeLimitOpt),
 	( 
+		{ EarlierGoal = call(PredId1, ProcId1, _, _, _, _) - _ },
+		{ LaterGoal = call(PredId2, ProcId2, _, _, _, _) - _ },
+		{ set__member(proc(PredId1, ProcId1) - proc(PredId2, ProcId2),
+			UselessVersions) }
+	->
+		pd_debug__message("version tried before, not worthwhile\n", 
+			[]),
+		{ ShouldTry = no }
+	;
 		{ DepthLimitOpt = int(MaxDepth) },
 		{ MaxDepth \= -1 }, 	% no depth limit set
 		{ Depth0 >= MaxDepth }
@@ -613,6 +637,28 @@
 		{ ShouldTry = no }
 	;
 		% Check whether either of the goals to be
+		% deforested is too large. XXX This is
+		% probably a bit too crude, especially for
+		% LaterGoal, which should be reduced in size
+		% in the specialized version (the specialized
+		% version will only include one branch of the
+		% top-level switch).
+		{ SizeLimitOpt = int(SizeLimit) },
+		{ SizeLimit \= -1 },
+		{ EarlierGoal = call(PredId, ProcId, _, _, _, _) - _
+		; LaterGoal = call(PredId, ProcId, _, _, _, _) - _
+		},
+		{ module_info_pred_proc_info(ModuleInfo, PredId, ProcId,
+			_, CalledProcInfo) },
+		{ proc_info_goal(CalledProcInfo, CalledGoal) },
+		{ goal_size(CalledGoal, CalledGoalSize) },
+		{ SizeLimit \= -1 },
+		{ CalledGoalSize > SizeLimit }
+	->
+		pd_debug__message("goal too large\n", []),
+		{ ShouldTry = no }
+	;
+		% Check whether either of the goals to be
 		% deforested can't be inlined.
 		{ EarlierGoal = call(PredId, ProcId, _, BuiltinState, _, _) - _
 		; LaterGoal = call(PredId, ProcId, _, BuiltinState, _, _) - _
@@ -1544,8 +1590,18 @@
 	pd_info_get_local_term_info(LocalTermInfo0),
 
 	pd_info_get_pred_info(PredInfo),
+	pd_info_lookup_option(deforestation_size_threshold, SizeThresholdOpt),
 	{ pred_info_get_markers(PredInfo, CallerMarkers) },
 	( 
+		% Check for extra information to the call.
+		{ map__search(ProcArgInfos, proc(PredId, ProcId), 
+			ProcArgInfo) },
+		{ ProcArgInfo = pd_branch_info(_, LeftArgs, _) },
+		{ set__member(LeftArg, LeftArgs) },
+		{ list__index1_det(Args, LeftArg, Arg) },
+		{ instmap__lookup_var(InstMap, Arg, ArgInst) },
+		{ inst_is_bound_to_functors(ModuleInfo, ArgInst, [_]) },
+
 		% We don't attempt to deforest predicates which are
 		% promised pure because the extra impurity propagated
 		% through the goal when such predicates are inlined
@@ -1555,13 +1611,16 @@
 		{ InlinePromisedPure = no },
 		{ inlining__can_inline_proc(PredId, ProcId, BuiltinState,
 			InlinePromisedPure, CallerMarkers, ModuleInfo) },
-		{ map__search(ProcArgInfos, proc(PredId, ProcId), 
-			ProcArgInfo) },
-		{ ProcArgInfo = pd_branch_info(_, LeftArgs, _) },
-		{ set__member(LeftArg, LeftArgs) },
-		{ list__index1_det(Args, LeftArg, Arg) },
-		{ instmap__lookup_var(InstMap, Arg, ArgInst) },
-		{ inst_is_bound_to_functors(ModuleInfo, ArgInst, [_]) }
+
+		% Check the goal size.
+		{ module_info_pred_proc_info(ModuleInfo, PredId, ProcId, _,
+			CalledProcInfo) },
+		{ proc_info_goal(CalledProcInfo, CalledGoal) },
+		{ goal_size(CalledGoal, CalledGoalSize) },
+		{ SizeThresholdOpt = int(SizeThreshold) },
+		{ SizeThreshold = -1
+		; CalledGoalSize < SizeThreshold
+		}
 	->
 		pd_debug__message(Context, 
 			"Found extra information for call to %s/%i\n", 
Index: compiler/options.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.328
diff -u -u -r1.328 options.m
--- compiler/options.m	2001/07/20 14:14:14	1.328
+++ compiler/options.m	2001/07/30 08:27:43
@@ -359,6 +359,7 @@
 		;	deforestation_depth_limit
 		;	deforestation_cost_factor
 		;	deforestation_vars_threshold
+		;	deforestation_size_threshold
 		;	termination
 		;	check_termination
 		;	verbose_check_termination
@@ -761,6 +762,7 @@
 	deforestation_depth_limit	-	int(4),
 	deforestation_cost_factor	-	int(1000),
 	deforestation_vars_threshold 	-	int(200),
+	deforestation_size_threshold 	-	int(15),
 
 % HLDS -> LLDS
 	smart_indexing		-	bool(no),
@@ -1175,6 +1177,7 @@
 long_option("deforestation-depth-limit",	deforestation_depth_limit).
 long_option("deforestation-cost-factor",	deforestation_cost_factor).
 long_option("deforestation-vars-threshold",	deforestation_vars_threshold).
+long_option("deforestation-size-threshold",	deforestation_size_threshold).
 long_option("enable-termination",	termination).
 long_option("enable-term",		termination).
 long_option("check-termination",	check_termination).
@@ -2429,6 +2432,11 @@
 		"\t`.opt' files. Note that changing this between writing",
 		"\tthe `.opt' file and compiling to C may cause link errors,",
 		"\tand too high a value may result in reduced performance.",
+		"--inline-vars-threshold <threshold>",
+		"\tDon't inline a call if it would result in a procedure",
+		"\tcontaining more than <threshold> variables. Procedures",
+		"\tcontaining large numbers of variables can cause",
+		"\tslow compilation.",
 		"--no-common-struct",
 		"\tDisable optimization of common term structures.",
 		"--no-common-goal",
@@ -2501,14 +2509,18 @@
 		"\ttransformation whose aim is to avoid the construction of",
 		"\tintermediate data structures and to avoid repeated traversals",
 		"\tover data structures within a conjunction.",
-		"--deforestation-depth-limit",
-		"\tSpecify a depth limit for the deforestation algorithm",
-		"\tin addition to the usual termination checks.",
+		"--deforestation-depth-limit <limit>",
+		"\tSpecify a depth limit to prevent infinite loops in the",
+		"\tdeforestation algorithm.",
 		"\tA value of -1 specifies no depth limit. The default is 4.",
-		"--deforestation-vars-threshold",
+		"--deforestation-vars-threshold <threshold>",
 		"\tSpecify a rough limit on the number of variables",
 		"\tin a procedure created by deforestation.",
-		"\tA value of -1 specifies no limit. The default is 200."
+		"\tA value of -1 specifies no limit. The default is 200.",
+		"--deforestation-size-threshold <threshold>",
+		"\tSpecify a rough limit on the size of a goal",
+		"\tto be optimized by deforestation.",
+		"\tA value of -1 specifies no limit. The default is 15."
 	]).
 	 
 :- pred options_help_hlds_llds_optimization(io__state::di, io__state::uo) is det.
Index: compiler/pd_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/pd_info.m,v
retrieving revision 1.7
diff -u -u -r1.7 pd_info.m
--- compiler/pd_info.m	2000/10/13 13:55:47	1.7
+++ compiler/pd_info.m	2001/07/30 15:01:25
@@ -19,28 +19,26 @@
 
 :- type pd_info 
 	---> pd_info(
-		io__state,
-		module_info,
-		maybe(unfold_info),
-		goal_version_index,
-		version_index,
-		pd_arg_info,
-		int,			% version counter.
-		global_term_info,
-		set(pred_proc_id),
-		int,			% current depth
-		set(pred_proc_id),	% created versions
-		set(pair(pred_proc_id)),% pairs of procedures which when
-					% paired for deforestation produce
-					% little improvement
-		unit,
-		unit
+		io :: io__state,
+		module_info :: module_info,
+		maybe_unfold_info :: maybe(unfold_info),
+		goal_version_index :: goal_version_index,
+		versions :: version_index,
+		proc_arg_info :: pd_arg_info,
+		counter :: int,
+		global_term_info :: global_term_info,
+		parent_versions :: set(pred_proc_id),
+		depth :: int,
+		created_versions :: set(pred_proc_id),
+		useless_versions :: useless_versions
 	).
 
 		% map from list of called preds in the 
 		% conjunctions to the specialised versions.
 :- type goal_version_index == map(list(pred_proc_id), list(pred_proc_id)).
 
+:- type useless_versions == set(pair(pred_proc_id)).
+
 		% map from version id to the info about the version.
 :- type version_index == map(pred_proc_id, version_info).
 
@@ -93,7 +91,7 @@
 :- pred pd_info_get_created_versions(set(pred_proc_id), pd_info, pd_info).
 :- mode pd_info_get_created_versions(out, pd_info_di, pd_info_uo) is det.
 
-:- pred pd_info_get_useless_versions(set(pair(pred_proc_id)), pd_info, pd_info).
+:- pred pd_info_get_useless_versions(useless_versions, pd_info, pd_info).
 :- mode pd_info_get_useless_versions(out, pd_info_di, pd_info_uo) is det.
 
 :- pred pd_info_set_io_state(io__state, pd_info, pd_info).
@@ -129,7 +127,7 @@
 :- pred pd_info_set_created_versions(set(pred_proc_id), pd_info, pd_info).
 :- mode pd_info_set_created_versions(in, pd_info_di, pd_info_uo) is det.
 
-:- pred pd_info_set_useless_versions(set(pair(pred_proc_id)), pd_info, pd_info).
+:- pred pd_info_set_useless_versions(useless_versions, pd_info, pd_info).
 :- mode pd_info_set_useless_versions(in, pd_info_di, pd_info_uo) is det.
 
 :- pred pd_info_update_goal(hlds_goal, pd_info, pd_info).
@@ -173,7 +171,7 @@
 	set__init(UselessVersions),
 	PdInfo = pd_info(IO, ModuleInfo, no, GoalVersionIndex, Versions, 
 		ProcArgInfos, 0, GlobalInfo, ParentVersions, 0, 
-		CreatedVersions, UselessVersions, unit, unit).
+		CreatedVersions, UselessVersions).
 
 pd_info_init_unfold_info(PredProcId, PredInfo, ProcInfo) -->
 	pd_info_get_module_info(ModuleInfo),
@@ -188,64 +186,39 @@
 	pd_info_set_unfold_info(UnfoldInfo).
 
 pd_info_get_io_state(IO, PdInfo, PdInfo) :-
-	PdInfo = pd_info(IO0, _,_,_,_,_,_,_,_,_,_,_,_,_),
-	unsafe_promise_unique(IO0, IO).
-pd_info_get_module_info(ModuleInfo, PdInfo, PdInfo) :-
-	PdInfo = pd_info(_, ModuleInfo, _,__,_,_,_,_,_,_,_,_,_,_).
+	unsafe_promise_unique(PdInfo ^ io, IO).
+pd_info_get_module_info(PdInfo ^ module_info, PdInfo, PdInfo).
 pd_info_get_unfold_info(UnfoldInfo, PdInfo, PdInfo) :-
-	PdInfo = pd_info(_,_, MaybeUnfoldInfo, _,_,_,_,_,_,_,_,_,_,_),
+	MaybeUnfoldInfo = PdInfo ^ maybe_unfold_info,
 	(
 		MaybeUnfoldInfo = yes(UnfoldInfo)
 	;
 		MaybeUnfoldInfo = no,
 		error("pd_info_get_unfold_info: unfold_info not set.")
 	).
-pd_info_get_goal_version_index(Index, PdInfo, PdInfo) :-
-	PdInfo = pd_info(_,_,_,Index,_,_,_,_,_,_,_,_,_,_).
-pd_info_get_versions(Versions, PdInfo, PdInfo) :-
-	PdInfo = pd_info(_,_,_,_,Versions,_,_,_,_,_,_,_,_,_).
-pd_info_get_proc_arg_info(ProcArgInfo, PdInfo, PdInfo) :-
-	PdInfo = pd_info(_,_,_,_,_,ProcArgInfo,_,_,_,_,_,_,_,_).
-pd_info_get_counter(Counter, PdInfo, PdInfo) :-
-	PdInfo = pd_info(_,_,_,_,_,_,Counter,_,_,_,_,_,_,_).
-pd_info_get_global_term_info(TermInfo, PdInfo, PdInfo) :-
-	PdInfo = pd_info(_,_,_,_,_,_,_,TermInfo,_,_,_,_,_,_).
-pd_info_get_parent_versions(Parents, PdInfo, PdInfo) :-
-	PdInfo = pd_info(_,_,_,_,_,_,_,_,Parents,_,_,_,_,_).
-pd_info_get_depth(Depth, PdInfo, PdInfo) :-
-	PdInfo = pd_info(_,_,_,_,_,_,_,_,_,Depth,_,_,_,_).
-pd_info_get_created_versions(Versions, PdInfo, PdInfo) :-
-	PdInfo = pd_info(_,_,_,_,_,_,_,_,_,_,Versions,_,_,_).
-pd_info_get_useless_versions(Versions, PdInfo, PdInfo) :-
-	PdInfo = pd_info(_,_,_,_,_,_,_,_,_,_,_,Versions,_,_).
-
-pd_info_set_io_state(IO0, pd_info(_, B,C,D,E,F,G,H,I,J,K,L,M,N), 
-		pd_info(IO, B,C,D,E,F,G,H,I,J,K,L,M,N)) :-
-	unsafe_promise_unique(IO0, IO).
-pd_info_set_module_info(ModuleInfo, pd_info(A,_,C,D,E,F,G,H,I,J,K,L,M,N),
-		pd_info(A, ModuleInfo, C,D,E,F,G,H,I,J,K,L,M,N)).
-pd_info_set_unfold_info(UnfoldInfo, pd_info(A,B,_,D,E,F,G,H,I,J,K,L,M,N),
-		pd_info(A,B, yes(UnfoldInfo), D,E,F,G,H,I,J,K,L,M,N)).
-pd_info_unset_unfold_info(pd_info(A,B,_,D,E,F,G,H,I,J,K,L,M,N),
-		pd_info(A,B, no, D,E,F,G,H,I,J,K,L,M,N)).
-pd_info_set_goal_version_index(Index, pd_info(A,B,C,_,E,F,G,H,I,J,K,L,M,N),
-		pd_info(A,B,C,Index,E,F,G,H,I,J,K,L,M,N)).
-pd_info_set_versions(Versions, pd_info(A,B,C,D,_,F,G,H,I,J,K,L,M,N),
-		pd_info(A,B,C,D,Versions,F,G,H,I,J,K,L,M,N)).
-pd_info_set_proc_arg_info(ProcArgInfo, pd_info(A,B,C,D,E,_,G,H,I,J,K,L,M,N),
-		pd_info(A,B,C,D,E,ProcArgInfo,G,H,I,J,K,L,M,N)).
-pd_info_set_counter(Counter, pd_info(A,B,C,D,E,F,_,H,I,J,K,L,M,N),
-		pd_info(A,B,C,D,E,F,Counter,H,I,J,K,L,M,N)).
-pd_info_set_global_term_info(TermInfo, pd_info(A,B,C,D,E,F,G,_,I,J,K,L,M,N),
-		pd_info(A,B,C,D,E,F,G,TermInfo,I,J,K,L,M,N)).
-pd_info_set_parent_versions(Parents, pd_info(A,B,C,D,E,F,G,H,_,J,K,L,M,N),
-		pd_info(A,B,C,D,E,F,G,H,Parents,J,K,L,M,N)).
-pd_info_set_depth(Depth, pd_info(A,B,C,D,E,F,G,H,I,_,K,L,M,N),
-		pd_info(A,B,C,D,E,F,G,H,I,Depth,K,L,M,N)).
-pd_info_set_created_versions(Versions, pd_info(A,B,C,D,E,F,G,H,I,J,_,L,M,N),
-		pd_info(A,B,C,D,E,F,G,H,I,J,Versions,L,M,N)).
-pd_info_set_useless_versions(Versions, pd_info(A,B,C,D,E,F,G,H,I,J,K,_,M,N),
-		pd_info(A,B,C,D,E,F,G,H,I,J,K,Versions,M,N)).
+pd_info_get_goal_version_index(PdInfo ^ goal_version_index, PdInfo, PdInfo).
+pd_info_get_versions(PdInfo ^ versions, PdInfo, PdInfo).
+pd_info_get_proc_arg_info(PdInfo ^ proc_arg_info, PdInfo, PdInfo).
+pd_info_get_counter(PdInfo ^ counter, PdInfo, PdInfo).
+pd_info_get_global_term_info(PdInfo ^ global_term_info, PdInfo, PdInfo).
+pd_info_get_parent_versions(PdInfo ^ parent_versions, PdInfo, PdInfo).
+pd_info_get_depth(PdInfo ^ depth, PdInfo, PdInfo).
+pd_info_get_created_versions(PdInfo ^ created_versions, PdInfo, PdInfo).
+pd_info_get_useless_versions(PdInfo ^ useless_versions, PdInfo, PdInfo).
+
+pd_info_set_io_state(IO) --> ^ io := IO.
+pd_info_set_module_info(ModuleInfo) --> ^ module_info := ModuleInfo.
+pd_info_set_unfold_info(UnfoldInfo) --> ^ maybe_unfold_info := yes(UnfoldInfo).
+pd_info_unset_unfold_info --> ^ maybe_unfold_info := no.
+pd_info_set_goal_version_index(Index) --> ^ goal_version_index := Index.
+pd_info_set_versions(Versions) --> ^ versions := Versions.
+pd_info_set_proc_arg_info(ProcArgInfo) --> ^ proc_arg_info := ProcArgInfo.
+pd_info_set_counter(Counter) --> ^ counter := Counter.
+pd_info_set_global_term_info(TermInfo) --> ^ global_term_info := TermInfo.
+pd_info_set_parent_versions(Parents) --> ^ parent_versions := Parents.
+pd_info_set_depth(Depth) --> ^ depth := Depth.
+pd_info_set_created_versions(Versions) --> ^ created_versions := Versions.
+pd_info_set_useless_versions(Versions) --> ^ useless_versions := Versions.
 
 pd_info_update_goal(_ - GoalInfo) -->
 	pd_info_get_instmap(InstMap0),
@@ -295,20 +268,25 @@
 	% body for unfolding and deforestation opportunities.
 :- type unfold_info
 	--->	unfold_info(
-			proc_info,
-			instmap,
-			int,		% improvement in cost measured while
+			proc_info :: proc_info,
+			instmap :: instmap,
+			cost_delta :: int,
+					% improvement in cost measured while
 					% processing this procedure
-			local_term_info,% information used to prevent
+			local_term_info :: local_term_info,
+					% information used to prevent
 					% infinite unfolding within the 
 					% current procedure.
-			pred_info,
-			set(pred_proc_id),
-			pred_proc_id,	% current pred_proc_id
-			bool,		% has anything changed
-			int,		% increase in size measured while
+			pred_info :: pred_info,
+			parents :: set(pred_proc_id),
+			pred_proc_id :: pred_proc_id,
+					% current pred_proc_id
+			changed :: bool,% has anything changed
+			size_delta :: int,
+					% increase in size measured while
 					% processing this procedure
-			bool		% does determinism analysis
+			rerun_det :: bool	
+					% does determinism analysis
 					% need to be rerun.
 		).	
 
@@ -405,86 +383,66 @@
 
 :- implementation.
 
-pd_info_get_proc_info(ProcInfo) -->
-	pd_info_get_unfold_info(UnfoldInfo),
-	{ UnfoldInfo = unfold_info(ProcInfo, _,_,_,_,_,_,_,_,_) }.
-pd_info_get_instmap(InstMap) -->
-	pd_info_get_unfold_info(UnfoldInfo),
-	{ UnfoldInfo = unfold_info(_, InstMap, _,_,_,_,_,_,_,_) }.
-pd_info_get_cost_delta(CostDelta) -->
-	pd_info_get_unfold_info(UnfoldInfo),
-	{ UnfoldInfo = unfold_info(_,_, CostDelta, _,_,_,_,_,_,_) }.
-pd_info_get_local_term_info(TermInfo) -->
-	pd_info_get_unfold_info(UnfoldInfo),
-	{ UnfoldInfo = unfold_info(_,_,_,TermInfo,_,_,_,_,_,_) }.
-pd_info_get_pred_info(PredInfo) -->
-	pd_info_get_unfold_info(UnfoldInfo),
-	{ UnfoldInfo = unfold_info(_,_,_,_,PredInfo,_,_,_,_,_) }.
-pd_info_get_parents(Parents) -->
-	pd_info_get_unfold_info(UnfoldInfo),
-	{ UnfoldInfo = unfold_info(_,_,_,_,_,Parents,_,_,_,_) }.
-pd_info_get_pred_proc_id(PredProcId) -->
-	pd_info_get_unfold_info(UnfoldInfo),
-	{ UnfoldInfo = unfold_info(_,_,_,_,_,_,PredProcId,_,_,_) }.
-pd_info_get_changed(Changed) -->
-	pd_info_get_unfold_info(UnfoldInfo),
-	{ UnfoldInfo = unfold_info(_,_,_,_,_,_,_,Changed,_,_) }.
-pd_info_get_size_delta(SizeDelta) -->
-	pd_info_get_unfold_info(UnfoldInfo),
-	{ UnfoldInfo = unfold_info(_,_,_,_,_,_,_,_,SizeDelta,_) }.
-pd_info_get_rerun_det(Rerun) -->
-	pd_info_get_unfold_info(UnfoldInfo),
-	{ UnfoldInfo = unfold_info(_,_,_,_,_,_,_,_,_,Rerun) }.
+pd_info_get_proc_info(UnfoldInfo ^ proc_info) -->
+	pd_info_get_unfold_info(UnfoldInfo).
+pd_info_get_instmap(UnfoldInfo ^ instmap) -->
+	pd_info_get_unfold_info(UnfoldInfo).
+pd_info_get_cost_delta(UnfoldInfo ^ cost_delta) -->
+	pd_info_get_unfold_info(UnfoldInfo).
+pd_info_get_local_term_info(UnfoldInfo ^ local_term_info) -->
+	pd_info_get_unfold_info(UnfoldInfo).
+pd_info_get_pred_info(UnfoldInfo ^ pred_info) -->
+	pd_info_get_unfold_info(UnfoldInfo).
+pd_info_get_parents(UnfoldInfo ^ parents) -->
+	pd_info_get_unfold_info(UnfoldInfo).
+pd_info_get_pred_proc_id(UnfoldInfo ^ pred_proc_id) -->
+	pd_info_get_unfold_info(UnfoldInfo).
+pd_info_get_changed(UnfoldInfo ^ changed) -->
+	pd_info_get_unfold_info(UnfoldInfo).
+pd_info_get_size_delta(UnfoldInfo ^ size_delta) -->
+	pd_info_get_unfold_info(UnfoldInfo).
+pd_info_get_rerun_det(UnfoldInfo ^ rerun_det) -->
+	pd_info_get_unfold_info(UnfoldInfo).
 	
 pd_info_set_proc_info(ProcInfo) -->
 	pd_info_get_unfold_info(UnfoldInfo0),
-	{ UnfoldInfo0 = unfold_info(_,B,C,D,E,F,G,H,I,J) },
-	{ UnfoldInfo = unfold_info(ProcInfo, B,C,D,E,F,G,H,I,J) },
+	{ UnfoldInfo = UnfoldInfo0 ^ proc_info := ProcInfo },
 	pd_info_set_unfold_info(UnfoldInfo).
 pd_info_set_instmap(InstMap) -->
 	pd_info_get_unfold_info(UnfoldInfo0),
-	{ UnfoldInfo0 = unfold_info(A,_,C,D,E,F,G,H,I,J) },
-	{ UnfoldInfo = unfold_info(A, InstMap,C,D,E,F,G,H,I,J) },
+	{ UnfoldInfo = UnfoldInfo0 ^ instmap := InstMap },
 	pd_info_set_unfold_info(UnfoldInfo).
 pd_info_set_cost_delta(CostDelta) -->
 	pd_info_get_unfold_info(UnfoldInfo0),
-	{ UnfoldInfo0 = unfold_info(A,B,_,D,E,F,G,H,I,J) },
-	{ UnfoldInfo = unfold_info(A,B,CostDelta,D,E,F,G,H,I,J) },
+	{ UnfoldInfo = UnfoldInfo0 ^ cost_delta := CostDelta },
 	pd_info_set_unfold_info(UnfoldInfo).
 pd_info_set_local_term_info(TermInfo) -->
 	pd_info_get_unfold_info(UnfoldInfo0),
-	{ UnfoldInfo0 = unfold_info(A,B,C,_,E,F,G,H,I,J) },
-	{ UnfoldInfo = unfold_info(A,B,C,TermInfo,E,F,G,H,I,J) },
+	{ UnfoldInfo = UnfoldInfo0 ^ local_term_info := TermInfo },
 	pd_info_set_unfold_info(UnfoldInfo).
 pd_info_set_pred_info(PredInfo) -->
 	pd_info_get_unfold_info(UnfoldInfo0),
-	{ UnfoldInfo0 = unfold_info(A,B,C,D,_,F,G,H,I,J) },
-	{ UnfoldInfo = unfold_info(A,B,C,D,PredInfo,F,G,H,I,J) },
+	{ UnfoldInfo = UnfoldInfo0 ^ pred_info := PredInfo },
 	pd_info_set_unfold_info(UnfoldInfo).
 pd_info_set_parents(Parents) -->
 	pd_info_get_unfold_info(UnfoldInfo0),
-	{ UnfoldInfo0 = unfold_info(A,B,C,D,E,_,G,H,I,J) },
-	{ UnfoldInfo = unfold_info(A,B,C,D,E,Parents,G,H,I,J) },
+	{ UnfoldInfo = UnfoldInfo0 ^ parents := Parents },
 	pd_info_set_unfold_info(UnfoldInfo).
 pd_info_set_pred_proc_id(PredProcId) -->
 	pd_info_get_unfold_info(UnfoldInfo0),
-	{ UnfoldInfo0 = unfold_info(A,B,C,D,E,F,_,H,I,J) },
-	{ UnfoldInfo = unfold_info(A,B,C,D,E,F,PredProcId,H,I,J) },
+	{ UnfoldInfo = UnfoldInfo0 ^ pred_proc_id := PredProcId },
 	pd_info_set_unfold_info(UnfoldInfo).
 pd_info_set_changed(Changed) -->
 	pd_info_get_unfold_info(UnfoldInfo0),
-	{ UnfoldInfo0 = unfold_info(A,B,C,D,E,F,G,_,I,J) },
-	{ UnfoldInfo = unfold_info(A,B,C,D,E,F,G, Changed, I,J) },
+	{ UnfoldInfo = UnfoldInfo0 ^ changed := Changed },
 	pd_info_set_unfold_info(UnfoldInfo).
 pd_info_set_size_delta(SizeDelta) -->
 	pd_info_get_unfold_info(UnfoldInfo0),
-	{ UnfoldInfo0 = unfold_info(A,B,C,D,E,F,G,H,_,J) },
-	{ UnfoldInfo = unfold_info(A,B,C,D,E,F,G,H, SizeDelta, J) },
+	{ UnfoldInfo = UnfoldInfo0 ^ size_delta := SizeDelta },
 	pd_info_set_unfold_info(UnfoldInfo).
 pd_info_set_rerun_det(Rerun) -->
 	pd_info_get_unfold_info(UnfoldInfo0),
-	{ UnfoldInfo0 = unfold_info(A,B,C,D,E,F,G,H,I,_) },
-	{ UnfoldInfo = unfold_info(A,B,C,D,E,F,G,H,I, Rerun) },
+	{ UnfoldInfo = UnfoldInfo0 ^ rerun_det := Rerun },
 	pd_info_set_unfold_info(UnfoldInfo).
 
 pd_info_incr_cost_delta(Delta1) -->
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.265
diff -u -u -r1.265 user_guide.texi
--- doc/user_guide.texi	2001/07/25 14:13:35	1.265
+++ doc/user_guide.texi	2001/07/30 08:27:54
@@ -4776,6 +4776,12 @@
 between writing the @samp{.opt} file and compiling to C may cause link errors,
 and too high a value may result in reduced performance.
 
+ at item --inline-vars-threshold @var{threshold}
+ at findex --inline-vars-threshold
+Don't inline a call if it would result in a procedure
+containing more than @var{threshold} variables. Procedures
+containing large numbers of variables can cause
+slow compilation.
 
 @sp 1
 @item --no-common-struct
@@ -4938,6 +4944,27 @@
 Enable deforestation. Deforestation is a program transformation whose aim
 is to avoid the construction of intermediate data structures and to avoid
 repeated traversals over data structures within a conjunction.
+
+ at sp 1
+ at item --deforestation-depth-limit
+ at findex --deforestation-depth-limit
+Specify a depth limit to prevent infinite loops in the
+deforestation algorithm.
+A value of -1 specifies no depth limit. The default is 4.
+
+ at sp 1
+ at item --deforestation-vars-threshold
+ at findex --deforestation-vars-threshold
+Specify a rough limit on the number of variables",
+in a procedure created by deforestation.",
+A value of -1 specifies no limit. The default is 200."
+
+ at sp 1
+ at item --deforestation-size-threshold
+ at findex --deforestation-size-threshold
+Specify a rough limit on the size of a goal
+to be optimized by deforestation.
+A value of -1 specifies no limit. The default is 15.
 
 @end table
 
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list