[m-dev.] diff: RL optimization bugs
Simon Taylor
stayl at cs.mu.OZ.AU
Tue Jun 15 16:36:54 AEST 1999
Estimated hours taken: 5
Fix bugs that resulted in incorrect output for some test cases.
compiler/rl.m:
The relation for an `add_index' instruction is
both input and output.
compiler/rl_block_opt.m:
Make sure all needed instructions are included in the
topological sort which determines the order of instructions.
Handle properly the case where an input relation to
a block has an index added to it.
Index: compiler/rl.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/rl.m,v
retrieving revision 1.2
diff -u -u -r1.2 rl.m
--- rl.m 1999/04/28 01:18:38 1.2
+++ rl.m 1999/06/15 04:30:20
@@ -541,7 +541,7 @@
rl__instr_relations(init(output_rel(Rel, _)) - _, [], [Rel]).
rl__instr_relations(insert_tuple(output_rel(Output, _), Input, _) - _,
[Input], [Output]).
-rl__instr_relations(add_index(output_rel(Rel, _)) - _, [], [Rel]).
+rl__instr_relations(add_index(output_rel(Rel, _)) - _, [Rel], [Rel]).
rl__instr_relations(clear(Rel) - _, [], [Rel]).
rl__instr_relations(unset(Rel) - _, [], [Rel]).
rl__instr_relations(label(_) - _, [], []).
Index: compiler/rl_block_opt.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/rl_block_opt.m,v
retrieving revision 1.3
diff -u -u -r1.3 rl_block_opt.m
--- rl_block_opt.m 1999/05/19 04:41:26 1.3
+++ rl_block_opt.m 1999/06/15 04:30:36
@@ -248,8 +248,6 @@
rl_block_opt__set_output_rel_id(output_rel(Relation, Indexes),
OutputId) -->
rl_block_opt__unset_relation_node(Relation),
- dag_get_relation_info(Relation, RelationInfo),
- { RelationInfo = relation_info(_, _, _, _) },
dag_get_node_info_map(NodeInfoMap0),
dag_get_rel_node_map(RelNodeMap0),
dag_get_output_loc_map(Locs),
@@ -1176,14 +1174,10 @@
% Find out which of the non-locals are evaluated by this block.
dag_get_rel_node_map(RelNodeMap),
dag_get_output_loc_map(Locs),
- dag_get_node_info_map(NodeInfoMap),
{ IsProducedNonLocal =
lambda([Rel::in, Node::out] is semidet, (
map__search(RelNodeMap, Rel, OutputId),
- map__lookup(Locs, OutputId, input_node(Node, _)),
- map__lookup(NodeInfoMap, Node, NodeInfo),
- NodeInfo = node_info(NodeInstr, _),
- NodeInstr \= input(Rel)
+ map__lookup(Locs, OutputId, input_node(Node, _))
)) },
{ list__filter_map(IsProducedNonLocal, LiveAtEnd,
@@ -1243,7 +1237,9 @@
list__foldl(AddDep, SubNodes, NodeRel0, NodeRel1)
;
Nodes1 = Nodes0,
- NodeRel1 = NodeRel0
+ % Make sure this node is in the topological
+ % sort of the required nodes.
+ relation__add_element(NodeRel0, Node, _, NodeRel1)
}
),
rl_block_opt__get_required_nodes(Nodes1, Required1, Required,
@@ -1277,27 +1273,10 @@
dag_get_node_info_map(NodeInfoMap),
{ map__lookup(NodeInfoMap, Node, NodeInfo) },
{ NodeInfo = node_info(Instr0, OutputRels) },
-
- ( { Instr0 = input(InputRel) } ->
- { rl_block_opt__one_output(OutputRels, OutputNode) },
- { OutputNode = output_node(Schema, Index, AllOutputs) },
- { set__delete(AllOutputs, InputRel, Outputs0) },
- { set__intersect(Outputs0, NonLocalRels, NonLocalOutputs) },
- ( { set__empty(NonLocalOutputs) } ->
- { NodeInstrs = [] },
- { NodeOutputs = [output_rel(InputRel, [])] }
- ;
- rl_block_opt__handle_node_outputs(Schema, Index,
- NonLocalOutputs, OutputRel, NodeInstrs),
- { NodeOutputs = [OutputRel] }
- ),
- { AssignInstrs1 = [] }
- ;
- rl_block_opt__get_node_outputs(NonLocalRels,
- OutputRels, NodeOutputs, [], AssignInstrs1),
- rl_block_opt__generate_instr(OutputRels, NodeOutputs,
- NodeRels0, Instr0, NodeInstrs)
- ),
+ rl_block_opt__get_node_outputs(Instr0, NonLocalRels,
+ OutputRels, NodeOutputs, [], AssignInstrs1),
+ rl_block_opt__generate_instr(OutputRels, NodeOutputs,
+ NodeRels0, Instr0, NodeInstrs),
{ map__det_insert(NodeRels0, Node, NodeOutputs, NodeRels) },
{ list__reverse(NodeInstrs, RevNodeInstrs) },
{ list__append(RevNodeInstrs, RevInstrs0, RevInstrs) },
@@ -1306,34 +1285,53 @@
% Select a relation variable to collect the output for each
% output argument of the node. Create `ref' instructions
% for each of the other relations produced by the position.
-:- pred rl_block_opt__get_node_outputs(set(relation_id)::in,
+:- pred rl_block_opt__get_node_outputs(instr::in, set(relation_id)::in,
list(output_node)::in, list(output_rel)::out, list(rl_instruction)::in,
list(rl_instruction)::out, dag::in, dag::out) is det.
-rl_block_opt__get_node_outputs(_, [], [], Instrs, Instrs) --> [].
-rl_block_opt__get_node_outputs(NonLocalRels, [OutputRel | OutputRels],
- [RelationId | RelationIds], RefInstrs0, RefInstrs) -->
- { OutputRel = output_node(Schema, Index, AllOutputs0) },
- { set__intersect(AllOutputs0, NonLocalRels, NonLocalOutputs) },
- rl_block_opt__handle_node_outputs(Schema,
- Index, NonLocalOutputs, RelationId, NewRefInstrs),
+rl_block_opt__get_node_outputs(_, _, [], [], Instrs, Instrs) --> [].
+rl_block_opt__get_node_outputs(Instr, NonLocalRels, [OutputNode | OutputNodes],
+ [OutputRel | OutputRels], RefInstrs0, RefInstrs) -->
+ { OutputNode = output_node(Schema, Index, AllOutputs0) },
+ { set__intersect(AllOutputs0, NonLocalRels, NonLocalOutputs0) },
+ { Instr = input(InputRel1) ->
+ % Don't assigning the input relation to itself.
+ set__delete(NonLocalOutputs0, InputRel1, NonLocalOutputs)
+ ;
+ NonLocalOutputs = NonLocalOutputs0
+ },
+ (
+ {
+ % If an input relation is passed through without change,
+ % we don't need to generate any code for the instruction.
+ Instr = input(InputRel2),
+ Index = [],
+
+ % If the input relation is not an output of the `input'
+ % instruction, another instruction has overwritten its value.
+ set__member(InputRel2, NonLocalOutputs0)
+ }
+ ->
+ { RelationId = InputRel2 }
+ ;
+ dag_add_relation(Schema, RelationId)
+ ),
+ { OutputRel = output_rel(RelationId, Index) },
+ { set__to_sorted_list(NonLocalOutputs, OutputList) },
+ { rl_block_opt__get_ref_instrs(RelationId, OutputList, NewRefInstrs) },
{ list__append(NewRefInstrs, RefInstrs0, RefInstrs1) },
- rl_block_opt__get_node_outputs(NonLocalRels, OutputRels,
- RelationIds, RefInstrs1, RefInstrs).
+ rl_block_opt__get_node_outputs(Instr, NonLocalRels, OutputNodes,
+ OutputRels, RefInstrs1, RefInstrs).
-:- pred rl_block_opt__handle_node_outputs(list(type)::in, list(index_spec)::in,
- set(relation_id)::in, output_rel::out, list(rl_instruction)::out,
- dag::in, dag::out) is det.
+:- pred rl_block_opt__get_ref_instrs(relation_id::in, list(relation_id)::in,
+ list(rl_instruction)::out) is det.
-rl_block_opt__handle_node_outputs(Schema, Index, NonLocalOutputs,
- output_rel(RelationId, Index), NewRefInstrs) -->
- { set__to_sorted_list(NonLocalOutputs, OutputList) },
- dag_add_relation(Schema, RelationId),
- { GetRefInstr =
+rl_block_opt__get_ref_instrs(RelationId, OutputList, RefInstrs) :-
+ GetRefInstr =
lambda([OtherOutput::in, Instr::out] is det, (
Instr = ref(OtherOutput, RelationId) - ""
- )) },
- { list__map(GetRefInstr, OutputList, NewRefInstrs) }.
+ )),
+ list__map(GetRefInstr, OutputList, RefInstrs).
%-----------------------------------------------------------------------------%
@@ -1439,7 +1437,21 @@
init(_), [init(Output) - ""]) -->
{ rl_block_opt__one_output(NodeOutputs, Output) }.
-rl_block_opt__generate_instr(_, _, _, input(_), []) --> [].
+rl_block_opt__generate_instr(_, NodeOutputs, _, input(Input), Instrs) -->
+ { rl_block_opt__one_output(NodeOutputs, OutputRel) },
+ { OutputRel = output_rel(Output, Indexes) },
+
+ { Indexes = [] ->
+ IndexInstrs = []
+ ;
+ IndexInstrs = [add_index(OutputRel) - ""]
+ },
+
+ { Output = Input ->
+ Instrs = IndexInstrs
+ ;
+ Instrs = [ref(Output, Input) - "" | IndexInstrs]
+ }.
%-----------------------------------------------------------------------------%
@@ -1455,7 +1467,7 @@
%-----------------------------------------------------------------------------%
% Produce a new relation to hold a copy of the destructively updated
- % input to union_diff or insert instruction.
+ % input to a union_diff or insert instruction.
:- pred rl_block_opt__get_copy_info(output_id::in, relation_id::in,
output_rel::out, dag::in, dag::out) is det.
--------------------------------------------------------------------------
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