[m-dev.] diff: performance improvements for Aditi

Simon Taylor stayl at cs.mu.OZ.AU
Thu Jun 24 12:08:11 AEST 1999


Estimated hours taken: 5

compiler/rl_out.pp:
	Use the `one_reference' bytecode to avoid unnecessary copying.
	Use the `has_index' bytecode to avoid adding indexes multiple times.

compiler/rl_sort.m:
	Fix bugs in the rules describing how required and available
	sorting and indexing are affected by the `make_unique' instruction.

compiler/rl.m:
	Remove an obsolete comment.

Index: rl.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/rl.m,v
retrieving revision 1.3
diff -u -u -r1.3 rl.m
--- rl.m	1999/06/16 00:34:46	1.3
+++ rl.m	1999/06/23 04:42:20
@@ -239,9 +239,6 @@
 		% to the input. To introduce this, the compiler must know that
 		% there are no later references in the code to the input
 		% relation.
-		% I'm not 100% sure that the reference counts maintained
-		% by Aditi can be used in this way - currently we always
-		% do the copy. 
 		% Make sure the output has the given set of indexes, even
 		% if it isn't copied.
 		make_unique(
Index: rl_out.pp
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/rl_out.pp,v
retrieving revision 1.4
diff -u -u -r1.4 rl_out.pp
--- rl_out.pp	1999/06/16 00:36:32	1.4
+++ rl_out.pp	1999/06/23 05:07:59
@@ -829,20 +829,22 @@
 	)) },
 	rl_out__generate_stream_instruction(Output, InstrCode, Code).
 rl_out__generate_instr(add_index(output_rel(Rel, Indexes)) - _, Code) -->
-	rl_out__add_indexes_to_rel(Rel, Indexes, IndexCodes),
-	{ Code = node(IndexCodes) }.
+	rl_out__add_indexes_to_rel(may_have_index, Rel, Indexes, Code).
 rl_out__generate_instr(clear(Rel) - _, Code) -->
 	rl_out_info_get_relation_addr(Rel, Addr),
 	{ Code = node([rl_PROC_clear(Addr)]) }.
 rl_out__generate_instr(init(output_rel(Rel, Indexes)) - _, Code) -->
 	rl_out_info_get_relation_addr(Rel, Addr),
 	rl_out_info_get_relation_schema_offset(Rel, SchemaOffset),
-	rl_out__add_indexes_to_rel(Rel, Indexes, IndexCodes),
-	{ Code = node([
-		rl_PROC_unsetrel(Addr),
-		rl_PROC_createtemprel(Addr, SchemaOffset) |
+	rl_out__add_indexes_to_rel(does_not_have_index,
+		Rel, Indexes, IndexCodes),
+	{ Code = 
+		tree(node([
+			rl_PROC_unsetrel(Addr),
+			rl_PROC_createtemprel(Addr, SchemaOffset)
+		]),
 		IndexCodes
-	]) }.
+	) }.
 rl_out__generate_instr(insert_tuple(Output, Input, Exprn) - _, Code) -->
 	rl_out__generate_stream(Input, InputStream),
 	rl_out_info_get_output_relation_schema_offset(Output,
@@ -904,17 +906,25 @@
 			rl_PROC_var_list_nil
 		])
 	) }.
-rl_out__generate_instr(make_unique(OutputRel, InputRel) - Comment,
-		Code) -->
-	% This should eventually do something like:
-	% 	if (num_references(InputRel) == 1) {
+rl_out__generate_instr(make_unique(OutputRel, Input) - Comment, Code) -->
+	% 	if (one_reference(InputRel)) {
 	% 		OutputRel = ref(InputRel)
 	% 	} else {
 	% 		OutputRel = copy(InputRel)
 	%	}
-	% At the moment reference counting doesn't work, so we always copy.
-	rl_out__generate_instr(copy(OutputRel, InputRel) - Comment,
-		Code).
+	rl_out_info_get_relation_addr(Input, InputAddr),
+	{ CondCode = node([rl_PROC_one_reference(InputAddr)]) },
+
+	{ OutputRel = output_rel(Output, _) },
+	rl_out__generate_instr(ref(Output, Input) - Comment, ThenCode0),
+	% We may not need to generate this instruction - rl_sort.m
+	% has enough information to work out whether this is actually needed.
+	rl_out__generate_instr(add_index(OutputRel) - Comment, ThenCode1),
+	{ ThenCode = tree(ThenCode0, ThenCode1) },
+
+	rl_out__generate_instr(copy(OutputRel, Input) - Comment, ElseCode),
+
+	rl_out__generate_ite(CondCode, ThenCode, ElseCode, Code).
 rl_out__generate_instr(call(ProcName, Inputs, OutputRels, SaveRels) - _,
 		Code) -->
 
@@ -932,7 +942,8 @@
 	rl_out_info_assign_const(string(ProcNameStr), ProcNameConst),
 	rl_out_info_return_tmp_vars(SaveTmpVars, SaveClearCode),
 	rl_out_info_return_tmp_vars(OverlapTmpVars, OverlapClearCode),
-	rl_out__add_indexes_to_rels(OutputRels, IndexCode),
+	rl_out__add_indexes_to_rels(does_not_have_index,
+		OutputRels, IndexCode),
 	{ Code =
 		tree(SaveCode,
 		tree(node([rl_PROC_call(ProcNameConst)]), 
@@ -1152,28 +1163,55 @@
 	string__append("#:", AttrStr, Str).
 
 %-----------------------------------------------------------------------------%
+
+:- type check_index
+	--->	may_have_index
+	;	does_not_have_index
+	.
 
-:- pred rl_out__add_indexes_to_rels(list(output_rel)::in, byte_tree::out,
+:- pred rl_out__add_indexes_to_rels(check_index::in,
+		list(output_rel)::in, byte_tree::out,
 		rl_out_info::in, rl_out_info::out) is det.
 	
-rl_out__add_indexes_to_rels([], empty) --> [].
-rl_out__add_indexes_to_rels([output_rel(Output, Indexes) | Outputs],
-		IndexCode) -->
-	rl_out__add_indexes_to_rel(Output, Indexes, Instrs),
-	rl_out__add_indexes_to_rels(Outputs, IndexCode1),
-	{ IndexCode = tree(node(Instrs), IndexCode1) }.
-
-:- pred rl_out__add_indexes_to_rel(relation_id::in, list(index_spec)::in,
-		list(bytecode)::out, rl_out_info::in, rl_out_info::out) is det.
-
-rl_out__add_indexes_to_rel(_, [], []) --> [].
-rl_out__add_indexes_to_rel(Output, [Index | Indexes],
-		[IndexInstr | IndexInstrs]) -->
+rl_out__add_indexes_to_rels(_, [], empty) --> [].
+rl_out__add_indexes_to_rels(CheckIndex,
+		[output_rel(Output, Indexes) | Outputs], IndexCode) -->
+	rl_out__add_indexes_to_rel(CheckIndex, Output, Indexes, IndexCode0),
+	rl_out__add_indexes_to_rels(CheckIndex, Outputs, IndexCode1),
+	{ IndexCode = tree(IndexCode0, IndexCode1) }.
+
+:- pred rl_out__add_indexes_to_rel(check_index::in, relation_id::in,
+		list(index_spec)::in, byte_tree::out,
+		rl_out_info::in, rl_out_info::out) is det.
+
+rl_out__add_indexes_to_rel(_, _, [], empty) --> [].
+rl_out__add_indexes_to_rel(CheckIndex, Output,
+		[Index | Indexes], IndexCode) -->
 	rl_out_info_get_relation_addr(Output, OutputAddr),
 	{ rl_out__index_spec_to_string(Index, IndexStr) },
 	rl_out_info_assign_const(string(IndexStr), IndexConst),
-	{ IndexInstr = rl_PROC_addindextorel(OutputAddr, IndexConst) },
-	rl_out__add_indexes_to_rel(OutputAddr, Indexes, IndexInstrs).
+
+	(
+		{ CheckIndex = may_have_index },
+		% Generate code to test whether the index already exists
+		% before adding it.
+		{ CondCode = node([
+			rl_PROC_has_index(OutputAddr, IndexConst)
+		]) },
+		{ ThenCode = empty },
+		{ ElseCode = node([
+			rl_PROC_addindextorel(OutputAddr, IndexConst)
+		]) },
+		rl_out__generate_ite(CondCode, ThenCode, ElseCode, IndexCode0)
+	;
+		{ CheckIndex = does_not_have_index },
+		{ IndexCode0 = node([
+			rl_PROC_addindextorel(OutputAddr, IndexConst)
+		]) }
+	),
+	rl_out__add_indexes_to_rel(CheckIndex,
+		OutputAddr, Indexes, IndexCode1),
+	{ IndexCode = tree(IndexCode0, IndexCode1) }.
 
 %-----------------------------------------------------------------------------%
 
@@ -1208,13 +1246,14 @@
 			TmpVar, TmpClearCode),
 
 		{ LockSpec = 0 },	% default lock spec
-		rl_out__add_indexes_to_rel(Output, Indexes, IndexInstrs),
+		rl_out__add_indexes_to_rel(does_not_have_index,
+			Output, Indexes, IndexInstrs),
 		rl_out_info_get_next_materialise_id(Id),
 		{ Code = 
 			tree(node([
-				rl_PROC_createtemprel(TmpVar, SchemaOffset) |
-				IndexInstrs
+				rl_PROC_createtemprel(TmpVar, SchemaOffset)
 			]),
+			tree(IndexInstrs,
 			tree(node([
 				rl_PROC_materialise(Id)
 			]),
@@ -1230,7 +1269,7 @@
 				rl_PROC_setrel(OutputAddr, TmpVar)
 			]),
 			TmpClearCode
-		)))) }
+		))))) }
 	).
 
 %-----------------------------------------------------------------------------%
Index: rl_sort.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/rl_sort.m,v
retrieving revision 1.2
diff -u -u -r1.2 rl_sort.m
--- rl_sort.m	1999/05/27 01:06:02	1.2
+++ rl_sort.m	1999/06/23 04:45:20
@@ -205,6 +205,16 @@
 
 %-----------------------------------------------------------------------------%
 
+	% Filter out unneeded specs.
+:- type spec_filter ==  pred(pair(sort_index, sort_req)).
+:- inst spec_filter == (pred(in) is semidet).
+
+:- func true_filter = (spec_filter::out(spec_filter)) is det.
+
+true_filter = (pred(_::in) is semidet :- true).
+
+%-----------------------------------------------------------------------------%
+
 :- pred rl_sort__init_block(block_id::in, sort_data_map::in,
 		sort_data_map::out, rl_opt_info::in, rl_opt_info::out) is det.
 
@@ -498,10 +508,21 @@
 
 	% Add the required sortedness of the first relation
 	% to that of the second.
-:- pred rl_sort__assign_relation_sortedness(block_id::in, relation_id::in,
-		relation_id::in, sort_info::in, sort_info::out) is det.
+:- pred rl_sort__assign_sortedness_and_indexing(block_id::in,
+		relation_id::in, relation_id::in,
+		sort_info::in, sort_info::out) is det.
+
+rl_sort__assign_sortedness_and_indexing(BlockId,
+		Relation1, Relation2) -->
+	rl_sort__assign_sortedness_and_indexing(true_filter, BlockId,
+		Relation1, Relation2).
+
+:- pred rl_sort__assign_sortedness_and_indexing(spec_filter::in(spec_filter),
+		block_id::in, relation_id::in, relation_id::in,
+		sort_info::in, sort_info::out) is det.
 
-rl_sort__assign_relation_sortedness(BlockId, Relation1, Relation2) -->
+rl_sort__assign_sortedness_and_indexing(SpecFilter, BlockId,
+		Relation1, Relation2) -->
 	=(sort_info(sortedness(RelMap0, _), _, RLInfo)),
 	{ rl_opt_info_get_relation_info(Relation2, RelInfo, RLInfo, _) },
 	( { RelInfo = relation_info(permanent(_), _, Indexes, _) } ->
@@ -512,9 +533,15 @@
 			(
 				map__set(SpecMap0, index(Index),
 					sort_req(definite, BlockIds), SpecMap)
-			)), Indexes, Specs0, Specs) },
+			)), Indexes, Specs0, Specs1) },
+		{ map__to_assoc_list(Specs1, SpecAL1) },
+		{ list__filter(SpecFilter, SpecAL1, SpecAL) },
+		{ map__from_assoc_list(SpecAL, Specs) },
 		rl_sort__add_relation_sortedness_map(Specs, Relation1)
-	; { map__search(RelMap0, Relation2, Specs) } ->
+	; { map__search(RelMap0, Relation2, Specs0) } ->
+		{ map__to_assoc_list(Specs0, SpecAL0) },
+		{ list__filter(SpecFilter, SpecAL0, SpecAL) },
+		{ map__from_assoc_list(SpecAL, Specs) },
 		rl_sort__add_relation_sortedness_map(Specs, Relation1)
 	;
 		[]
@@ -533,22 +560,21 @@
 	{ map__from_assoc_list(Specs0, Specs) },
 	rl_sort__add_relation_sortedness_map(Specs, Output).
 
-:- pred rl_sort__assign_indexing(relation_id::in, relation_id::in,
-		sort_info::in, sort_info::out) is det.
+:- pred rl_sort__assign_indexing(block_id::in, relation_id::in,
+		relation_id::in, sort_info::in, sort_info::out) is det.
 
-rl_sort__assign_indexing(Output, Input) -->
-	=(sort_info(sortedness(RelMap0, _VarMap0), _, _)),
-	( { map__search(RelMap0, Input, Specs0) } ->
-		{ map__to_assoc_list(Specs0, Specs1) },
-		{ list__filter(
-			lambda([SpecAndReq::in] is semidet, (
-				SpecAndReq = index(_) - _
-			)), Specs1, Specs2) },
-		{ map__from_assoc_list(Specs2, Specs) },
-		rl_sort__add_relation_sortedness_map(Specs, Output)
-	;
-		[]
-	).
+rl_sort__assign_indexing(BlockId, Output, Input) -->
+	{ FilterSpecs = (pred((index(_) - _)::in) is semidet) },
+	rl_sort__assign_sortedness_and_indexing(FilterSpecs,
+		BlockId, Output, Input).
+
+:- pred rl_sort__assign_sortedness(block_id::in, relation_id::in,
+		relation_id::in, sort_info::in, sort_info::out) is det.
+
+rl_sort__assign_sortedness(BlockId, Output, Input) -->
+	{ FilterSpecs = (pred((sort(_) - _)::in) is semidet) },
+	rl_sort__assign_sortedness_and_indexing(FilterSpecs,
+		BlockId, Output, Input).
 
 :- pred rl_sort__unset_relation(relation_id::in, 
 		sort_info::in, sort_info::out) is det.
@@ -643,7 +669,7 @@
 rl_sort__instr_needed(BlockId, insert(UoOutput, DiInput, _, InsertType, _) - _)
 		-->
 	( { InsertType = index(Index) } ->
-		rl_sort__assign_indexing(DiInput, UoOutput),
+		rl_sort__assign_indexing(BlockId, DiInput, UoOutput),
 		rl_sort__add_relation_sortedness(BlockId,
 			index(Index), DiInput)
 	;
@@ -651,17 +677,17 @@
 	).
 rl_sort__instr_needed(BlockId,
 		union_diff(UoOutput, DiInput, _, _, Index, _) - _) -->
-	rl_sort__assign_indexing(DiInput, UoOutput),
+	rl_sort__assign_indexing(BlockId, DiInput, UoOutput),
 	rl_sort__add_relation_sortedness(BlockId, index(Index), DiInput).
 rl_sort__instr_needed(_BlockId, sort(_Output, _Input, _Attrs) - _) --> [].
 rl_sort__instr_needed(BlockId, ref(Output, Input) - _) -->
-	rl_sort__assign_relation_sortedness(BlockId, Input, Output).
+	rl_sort__assign_sortedness_and_indexing(BlockId, Input, Output).
 rl_sort__instr_needed(BlockId, copy(Output, Input) - _) -->
 	{ Output = output_rel(OutputRel, _) },
-	rl_sort__assign_relation_sortedness(BlockId, Input, OutputRel).
+	rl_sort__assign_sortedness(BlockId, Input, OutputRel).
 rl_sort__instr_needed(BlockId, make_unique(Output, Input) - _) -->
 	{ Output = output_rel(OutputRel, _) },
-	rl_sort__assign_relation_sortedness(BlockId, Input, OutputRel).
+	rl_sort__assign_sortedness(BlockId, Input, OutputRel).
 rl_sort__instr_needed(_BlockId, init(_Output) - _) --> [].
 rl_sort__instr_needed(_BlockId, insert_tuple(_, _, _) - _) --> [].
 rl_sort__instr_needed(_BlockId, call(_, _Inputs, _Outputs, _) - _) --> [].
@@ -772,12 +798,12 @@
 	{ Output = output_rel(OutputRel, _) },
 	rl_sort__add_relation_sortedness(BlockId, sort(SortSpec), OutputRel),
 	rl_sort__handle_output_indexing(BlockId, Output).
-rl_sort__instr_avail(_, insert(UoOutput, DiInput, _Input, _Type, _) - _)
+rl_sort__instr_avail(BlockId, insert(UoOutput, DiInput, _Input, _Type, _) - _)
 		-->
-	rl_sort__assign_indexing(UoOutput, DiInput).
+	rl_sort__assign_indexing(BlockId, UoOutput, DiInput).
 rl_sort__instr_avail(BlockId,
 		union_diff(UoOutput, DiInput, _Input1, Diff, _, _) - _) -->
-	rl_sort__assign_indexing(UoOutput, DiInput),
+	rl_sort__assign_indexing(BlockId, UoOutput, DiInput),
 	rl_sort__handle_output_indexing(BlockId, Diff).
 rl_sort__instr_avail(BlockId, sort(Output, _Input, Attrs) - _) -->
 	{ Output = output_rel(OutputRel, _) },
@@ -785,14 +811,14 @@
 		sort(attributes(Attrs)), OutputRel),
 	rl_sort__handle_output_indexing(BlockId, Output).
 rl_sort__instr_avail(BlockId, ref(Output, Input) - _) -->
-	rl_sort__assign_relation_sortedness(BlockId, Output, Input).
+	rl_sort__assign_sortedness_and_indexing(BlockId, Output, Input).
 rl_sort__instr_avail(BlockId, copy(Output, Input) - _) -->
 	{ Output = output_rel(OutputRel, _) },
-	rl_sort__assign_relation_sortedness(BlockId, OutputRel, Input),
+	rl_sort__assign_sortedness(BlockId, OutputRel, Input),
 	rl_sort__handle_output_indexing(BlockId, Output).
 rl_sort__instr_avail(BlockId, make_unique(Output, Input) - _) -->
 	{ Output = output_rel(OutputRel, _) },
-	rl_sort__assign_relation_sortedness(BlockId, OutputRel, Input),
+	rl_sort__assign_sortedness(BlockId, OutputRel, Input),
 	rl_sort__handle_output_indexing(BlockId, Output).
 rl_sort__instr_avail(BlockId, init(Output) - _) -->
 	rl_sort__handle_output_indexing(BlockId, Output).

--------------------------------------------------------------------------
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