[m-dev.] for review: improvements to intermodule specialization

Fergus Henderson fjh at cs.mu.OZ.AU
Tue Nov 14 22:00:52 AEDT 2000


On 26-Sep-2000, Simon Taylor <stayl at cs.mu.OZ.AU> wrote:
> 
> [Fergus wrote:]
> > 
> > Fix some problems with intermodule higher-order specialization that
> > were preventing the compiler from properly specializing calls
> > to list__sort/3, even at the highest optimization level.
> > 
> > compiler/intermod.m:
> > 	Allow procedures which are called from exported procedures
> > 	to be put in the `.opt' files.  This is needed e.g. for
> > 	list__hosort.
> 
> It would probably be better not to rely on the predicates being
> processed in the right order. It's also probably worth checking
> multiple levels down, rather than just one.

OK, here's a revised version that does as you suggest.
I enclose below both relative and full diffs.
I'll go ahead and commit this one.

*******************************************************************************
RELATIVE DIFF
*******************************************************************************

--- compiler/intermod.m
+++ compiler/intermod.m
@@ -187,2 +187,38 @@
-intermod__gather_preds([], _CollectTypes, _, _, _) --> [].
-intermod__gather_preds([PredId | PredIds], CollectTypes,
+intermod__gather_preds(AllPredIds, CollectTypes,
+		InlineThreshold, HigherOrderSizeLimit, Deforestation) -->
+	% first gather exported preds
+	{ ProcessLocalPreds = no },
+	intermod__gather_pred_list(AllPredIds, ProcessLocalPreds,
+		CollectTypes, InlineThreshold, HigherOrderSizeLimit,
+		Deforestation),
+
+	% then gather preds used by exported preds (recursively)
+	{ set__init(ExtraExportedPreds0) },
+	intermod__gather_preds_2(ExtraExportedPreds0, CollectTypes,
+		InlineThreshold, HigherOrderSizeLimit, Deforestation).
+
+:- pred intermod__gather_preds_2(set(pred_id)::in, bool::in, int::in,
+	int::in, bool::in, intermod_info::in, intermod_info::out) is det.
+
+intermod__gather_preds_2(ExtraExportedPreds0, CollectTypes,
+		InlineThreshold, HigherOrderSizeLimit, Deforestation) -->
+	intermod_info_get_pred_decls(ExtraExportedPreds),
+	{ NewlyExportedPreds = set__to_sorted_list(
+		ExtraExportedPreds `set__difference` ExtraExportedPreds0) },
+	( { NewlyExportedPreds = [] } ->
+		[]
+	;
+		{ ProcessLocalPreds = yes },
+		intermod__gather_pred_list(NewlyExportedPreds,
+			ProcessLocalPreds, CollectTypes,
+			InlineThreshold, HigherOrderSizeLimit, Deforestation),
+		intermod__gather_preds_2(ExtraExportedPreds, CollectTypes,
+			InlineThreshold, HigherOrderSizeLimit, Deforestation)
+	).
+
+:- pred intermod__gather_pred_list(list(pred_id)::in, bool::in, bool::in,
+	int::in, int::in, bool::in, intermod_info::in, intermod_info::out)
+	is det.
+
+intermod__gather_pred_list([], _, _, _, _, _) --> [].
+intermod__gather_pred_list([PredId | PredIds], ProcessLocalPreds, CollectTypes,
@@ -191 +226,0 @@
-	intermod_info_get_pred_decls(NewlyExportedPreds),
@@ -197,4 +232,3 @@
-		{ intermod__should_be_processed(PredId, PredInfo0,
-			TypeSpecForcePreds, InlineThreshold,
-			HigherOrderSizeLimit, Deforestation,
-			NewlyExportedPreds, ModuleInfo0) }
+		{ intermod__should_be_processed(ProcessLocalPreds, PredId,
+			PredInfo0, TypeSpecForcePreds, InlineThreshold,
+			HigherOrderSizeLimit, Deforestation, ModuleInfo0) }
@@ -238 +272 @@
-	intermod__gather_preds(PredIds, CollectTypes,
+	intermod__gather_pred_list(PredIds, ProcessLocalPreds, CollectTypes,
@@ -242 +276 @@
-:- pred intermod__should_be_processed(pred_id::in, pred_info::in,
+:- pred intermod__should_be_processed(bool::in, pred_id::in, pred_info::in,
@@ -244 +278 @@
-		set(pred_id)::in, module_info::in) is semidet.
+		module_info::in) is semidet.
@@ -246,3 +280,3 @@
-intermod__should_be_processed(PredId, PredInfo, TypeSpecForcePreds,
-		InlineThreshold, HigherOrderSizeLimit,
-		Deforestation, NewlyExportedPreds, ModuleInfo) :-
+intermod__should_be_processed(ProcessLocalPreds, PredId, PredInfo,
+		TypeSpecForcePreds, InlineThreshold, HigherOrderSizeLimit,
+		Deforestation, ModuleInfo) :-
@@ -254,0 +289 @@
+		ProcessLocalPreds = no,
@@ -257,2 +292,2 @@
-		pred_info_import_status(PredInfo, local),
-		set__member(PredId, NewlyExportedPreds)
+		ProcessLocalPreds = yes,
+		pred_info_import_status(PredInfo, local)

*******************************************************************************
FULL DIFF
*******************************************************************************

Estimated hours taken: 7

Fix some problems with intermodule higher-order specialization that
were preventing the compiler from properly specializing calls
to list__sort/3, even at the highest optimization level.

compiler/intermod.m:
	Allow procedures which are called from exported procedures
	to be put in the `.opt' files.  This is needed e.g. for
	list__hosort.

compiler/options.m:
	Increase the --higher-order-size-limit at higher optimization
	levels.  --optimize-higher-order is enabled at -O3, with a
	default size limit of 20.  I changed the limit at higher
	optimization levels: at -O4, the limit is set to 30, and at
	-O5, it is set to 40.

Workspace: /home/mercury0/fjh/mercury
Index: compiler/intermod.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/intermod.m,v
retrieving revision 1.87
diff -u -d -r1.87 intermod.m
--- compiler/intermod.m	2000/11/03 03:11:50	1.87
+++ compiler/intermod.m	2000/11/14 07:33:49
@@ -184,8 +184,44 @@
 :- pred intermod__gather_preds(list(pred_id)::in, bool::in, int::in,
 	int::in, bool::in, intermod_info::in, intermod_info::out) is det.
 
-intermod__gather_preds([], _CollectTypes, _, _, _) --> [].
-intermod__gather_preds([PredId | PredIds], CollectTypes,
+intermod__gather_preds(AllPredIds, CollectTypes,
+		InlineThreshold, HigherOrderSizeLimit, Deforestation) -->
+	% first gather exported preds
+	{ ProcessLocalPreds = no },
+	intermod__gather_pred_list(AllPredIds, ProcessLocalPreds,
+		CollectTypes, InlineThreshold, HigherOrderSizeLimit,
+		Deforestation),
+
+	% then gather preds used by exported preds (recursively)
+	{ set__init(ExtraExportedPreds0) },
+	intermod__gather_preds_2(ExtraExportedPreds0, CollectTypes,
+		InlineThreshold, HigherOrderSizeLimit, Deforestation).
+
+:- pred intermod__gather_preds_2(set(pred_id)::in, bool::in, int::in,
+	int::in, bool::in, intermod_info::in, intermod_info::out) is det.
+
+intermod__gather_preds_2(ExtraExportedPreds0, CollectTypes,
+		InlineThreshold, HigherOrderSizeLimit, Deforestation) -->
+	intermod_info_get_pred_decls(ExtraExportedPreds),
+	{ NewlyExportedPreds = set__to_sorted_list(
+		ExtraExportedPreds `set__difference` ExtraExportedPreds0) },
+	( { NewlyExportedPreds = [] } ->
+		[]
+	;
+		{ ProcessLocalPreds = yes },
+		intermod__gather_pred_list(NewlyExportedPreds,
+			ProcessLocalPreds, CollectTypes,
+			InlineThreshold, HigherOrderSizeLimit, Deforestation),
+		intermod__gather_preds_2(ExtraExportedPreds, CollectTypes,
+			InlineThreshold, HigherOrderSizeLimit, Deforestation)
+	).
+
+:- pred intermod__gather_pred_list(list(pred_id)::in, bool::in, bool::in,
+	int::in, int::in, bool::in, intermod_info::in, intermod_info::out)
+	is det.
+
+intermod__gather_pred_list([], _, _, _, _, _) --> [].
+intermod__gather_pred_list([PredId | PredIds], ProcessLocalPreds, CollectTypes,
 		InlineThreshold, HigherOrderSizeLimit, Deforestation) -->
 	intermod_info_get_module_info(ModuleInfo0),
 	{ module_info_preds(ModuleInfo0, PredTable0) },
@@ -193,8 +229,8 @@
 	{ module_info_type_spec_info(ModuleInfo0, TypeSpecInfo) },
 	{ TypeSpecInfo = type_spec_info(_, TypeSpecForcePreds, _, _) },
 	(
-		{ intermod__should_be_processed(PredId, PredInfo0,
-			TypeSpecForcePreds, InlineThreshold,
+		{ intermod__should_be_processed(ProcessLocalPreds, PredId,
+			PredInfo0, TypeSpecForcePreds, InlineThreshold,
 			HigherOrderSizeLimit, Deforestation, ModuleInfo0) }
 	->
 		=(IntermodInfo0),
@@ -233,23 +269,29 @@
 	;
 		[]
 	),
-	intermod__gather_preds(PredIds, CollectTypes,
+	intermod__gather_pred_list(PredIds, ProcessLocalPreds, CollectTypes,
 		InlineThreshold, HigherOrderSizeLimit, Deforestation).
 
 
-:- pred intermod__should_be_processed(pred_id::in, pred_info::in,
+:- pred intermod__should_be_processed(bool::in, pred_id::in, pred_info::in,
 		set(pred_id)::in, int::in, int::in, bool::in,
 		module_info::in) is semidet.
 
-intermod__should_be_processed(PredId, PredInfo, TypeSpecForcePreds,
-		InlineThreshold, HigherOrderSizeLimit,
+intermod__should_be_processed(ProcessLocalPreds, PredId, PredInfo,
+		TypeSpecForcePreds, InlineThreshold, HigherOrderSizeLimit,
 		Deforestation, ModuleInfo) :-
 	%
 	% note: we can't include exported_to_submodules predicates in
 	% the `.opt' file, for reasons explained in the comments for
 	% intermod__add_proc
 	%
-	pred_info_is_exported(PredInfo),
+	(
+		ProcessLocalPreds = no,
+		pred_info_is_exported(PredInfo)
+	;
+		ProcessLocalPreds = yes,
+		pred_info_import_status(PredInfo, local)
+	),
 	(
 		pred_info_clauses_info(PredInfo, ClauseInfo),
 		clauses_info_clauses(ClauseInfo, Clauses),
Index: compiler/options.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.299
diff -u -d -r1.299 options.m
--- compiler/options.m	2000/11/08 08:20:45	1.299
+++ compiler/options.m	2000/11/14 06:39:11
@@ -1446,7 +1446,8 @@
 	lazy_code		-	bool(yes),
 	optimize_value_number	-	bool(yes),
 	inline_simple_threshold	-	int(8),
-	inline_compound_threshold -	int(20)
+	inline_compound_threshold -	int(20),
+	higher_order_size_limit -	int(30)
 ]).
 
 % Optimization level 5: apply optimizations which may have some
@@ -1459,7 +1460,8 @@
 	pred_value_number	-	bool(yes),
 	optimize_repeat		-	int(5),
 	optimize_vnrepeat	-	int(2),
-	inline_compound_threshold -	int(100)
+	inline_compound_threshold -	int(100),
+	higher_order_size_limit -	int(40)
 ]).
 
 % Optimization level 6: apply optimizations which may have any
-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
                                    |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
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