[m-rev.] [reuse] diff: optimize for fields already containing the correct value
Peter Ross
peter.ross at miscrit.be
Fri Mar 16 20:13:41 AEDT 2001
Hi,
===================================================================
Estimated hours taken: 8
Branches: reuse
Optimize the following situation.
P0 => p(X, Y, Z),
P <= p(Z, Y, X).
If we reuse the cell P0 for storing P, then the second field already
contains the correct value, so we don't need to store it.
compiler/sr_choice.m:
Determine which of the fields of a cell which is being reused
already contain the correct value. Note we need to be careful when
a cons_id requires a remote secondary tag.
compiler/ml_unify_gen.m:
Modify ml_gen_unify_args so that it takes a possible list of fields
which already contain the correct value.
compiler/hlds_out.m:
compiler/sr_data.m:
compiler/sr_dead.m:
compiler/sr_direct.m:
compiler/sr_split.m:
Minor changes to handle changes to the various data structures.
Index: compiler/hlds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_out.m,v
retrieving revision 1.243.2.17
diff -u -r1.243.2.17 hlds_out.m
--- compiler/hlds_out.m 2001/03/12 20:24:34 1.243.2.17
+++ compiler/hlds_out.m 2001/03/16 09:01:47
@@ -1180,7 +1180,7 @@
;
{ REUSE = reuse(cell_reused(ProgVar,
IntroducesCondition,
- ConsIds)) }
+ ConsIds, _ReuseFields)) }
->
io__write_string("cell "),
mercury_output_var(ProgVar, VarSet,
Index: compiler/ml_unify_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_unify_gen.m,v
retrieving revision 1.16.2.12
diff -u -r1.16.2.12 ml_unify_gen.m
--- compiler/ml_unify_gen.m 2001/03/13 09:51:46 1.16.2.12
+++ compiler/ml_unify_gen.m 2001/03/16 09:01:56
@@ -1041,7 +1041,8 @@
{ MLDS_Statements = [AssignStatement] }
;
{ HowToConstruct = reuse_cell(CellToReuse) },
- { CellToReuse = cell_to_reuse(ReuseVar, ReuseConsIds, _) },
+ { CellToReuse = cell_to_reuse(ReuseVar,
+ ReuseConsIds, ReuseFields) },
{ MaybeConsId = yes(ConsId0) ->
ConsId = ConsId0
@@ -1089,11 +1090,9 @@
%
% For each field in the construction unification we need
% to generate an rval.
- % XXX we do more work then we need to here, as some of
- % the cells may already contain the correct values.
%
- ml_gen_unify_args(ConsId, ArgVars, ArgModes, ArgTypes,
- Fields, Type, VarLval, OffSet,
+ ml_gen_unify_args(ConsId, ArgVars, ArgModes, ArgTypes, Fields,
+ yes(ReuseFields), Type, VarLval, OffSet,
ArgNum, PrimaryTag, Context, MLDS_Statements0),
{ MLDS_Decls = [] },
@@ -1337,8 +1336,8 @@
ml_variable_types(Args, ArgTypes),
ml_field_names_and_types(Type, ConsId, ArgTypes, Fields),
{ ml_tag_offset_and_argnum(Tag, _, OffSet, ArgNum) },
- ml_gen_unify_args(ConsId, Args, Modes, ArgTypes, Fields, Type,
- VarLval, OffSet, ArgNum,
+ ml_gen_unify_args(ConsId, Args, Modes, ArgTypes, Fields, no,
+ Type, VarLval, OffSet, ArgNum,
UnsharedTag, Context, MLDS_Statements)
;
{ Tag = shared_remote_tag(PrimaryTag, _SecondaryTag) },
@@ -1346,8 +1345,8 @@
ml_variable_types(Args, ArgTypes),
ml_field_names_and_types(Type, ConsId, ArgTypes, Fields),
{ ml_tag_offset_and_argnum(Tag, _, OffSet, ArgNum) },
- ml_gen_unify_args(ConsId, Args, Modes, ArgTypes, Fields, Type,
- VarLval, OffSet, ArgNum,
+ ml_gen_unify_args(ConsId, Args, Modes, ArgTypes, Fields, no,
+ Type, VarLval, OffSet, ArgNum,
PrimaryTag, Context, MLDS_Statements)
;
{ Tag = shared_local_tag(_Bits1, _Num1) },
@@ -1453,44 +1452,57 @@
).
:- pred ml_gen_unify_args(cons_id, prog_vars, list(uni_mode), list(prog_type),
- list(constructor_arg), prog_type, mlds__lval, int, int,
- mlds__tag, prog_context, mlds__statements,
- ml_gen_info, ml_gen_info).
-:- mode ml_gen_unify_args(in, in, in, in, in, in, in, in, in, in, in, out,
+ list(constructor_arg), maybe(list(bool)), prog_type,
+ mlds__lval, int, int, mlds__tag, prog_context,
+ mlds__statements, ml_gen_info, ml_gen_info).
+:- mode ml_gen_unify_args(in, in, in, in, in, in, in, in, in, in, in, in, out,
in, out) is det.
-ml_gen_unify_args(ConsId, Args, Modes, ArgTypes, Fields, VarType, VarLval,
- Offset, ArgNum, PrimaryTag, Context, MLDS_Statements) -->
+ml_gen_unify_args(ConsId, Args, Modes, ArgTypes, Fields,
+ MaybeAlreadyInitialised, VarType, VarLval, Offset,
+ ArgNum, PrimaryTag, Context, MLDS_Statements) -->
+ { MaybeAlreadyInitialised = yes(IsInitialised0) ->
+ IsInitialised = IsInitialised0
+ ;
+ IsInitialised = list__duplicate(list__length(Args), no)
+ },
(
- ml_gen_unify_args_2(ConsId, Args, Modes, ArgTypes, Fields,
- VarType, VarLval, Offset, ArgNum, PrimaryTag, Context,
- [], MLDS_Statements0)
+ ml_gen_unify_args_2(ConsId, Args, Modes, ArgTypes,
+ Fields, IsInitialised, VarType, VarLval,
+ Offset, ArgNum, PrimaryTag,
+ Context, [], MLDS_Statements0)
->
{ MLDS_Statements = MLDS_Statements0 }
;
{ error("ml_gen_unify_args: length mismatch") }
).
-:- pred ml_gen_unify_args_2(cons_id, prog_vars, list(uni_mode), list(prog_type),
- list(constructor_arg), prog_type, mlds__lval, int, int,
- mlds__tag, prog_context, mlds__statements, mlds__statements,
- ml_gen_info, ml_gen_info).
-:- mode ml_gen_unify_args_2(in, in, in, in, in, in, in, in, in, in, in, in, out,
- in, out) is semidet.
+:- pred ml_gen_unify_args_2(cons_id::in, prog_vars::in,
+ list(uni_mode)::in, list(prog_type)::in,
+ list(constructor_arg)::in, list(bool)::in,
+ prog_type::in, mlds__lval::in, int::in, int::in,
+ mlds__tag::in, prog_context::in,
+ mlds__statements::in, mlds__statements::out,
+ ml_gen_info::in, ml_gen_info::out) is semidet.
-ml_gen_unify_args_2(_, [], [], [], _, _, _, _, _, _, _, Statements, Statements)
- --> [].
+ml_gen_unify_args_2(_, [], [], [], [],
+ _, _, _, _, _, _, _, Statements, Statements) --> [].
ml_gen_unify_args_2(ConsId, [Arg|Args], [Mode|Modes], [ArgType|ArgTypes],
- [Field|Fields], VarType, VarLval, Offset, ArgNum, PrimaryTag,
- Context, MLDS_Statements0, MLDS_Statements) -->
+ [Field|Fields], [IsInitialised|IsInitialiseds], VarType,
+ VarLval, Offset, ArgNum, PrimaryTag, Context,
+ MLDS_Statements0, MLDS_Statements) -->
{ Offset1 = Offset + 1 },
{ ArgNum1 = ArgNum + 1 },
- ml_gen_unify_args_2(ConsId, Args, Modes, ArgTypes, Fields, VarType,
- VarLval, Offset1, ArgNum1, PrimaryTag, Context,
- MLDS_Statements0, MLDS_Statements1),
- ml_gen_unify_arg(ConsId, Arg, Mode, ArgType, Field, VarType, VarLval,
- Offset, ArgNum, PrimaryTag, Context,
- MLDS_Statements1, MLDS_Statements).
+ ml_gen_unify_args_2(ConsId, Args, Modes, ArgTypes, Fields,
+ IsInitialiseds, VarType, VarLval, Offset1, ArgNum1,
+ PrimaryTag, Context, MLDS_Statements0, MLDS_Statements1),
+ ( { IsInitialised = no } ->
+ ml_gen_unify_arg(ConsId, Arg, Mode, ArgType, Field,
+ VarType, VarLval, Offset, ArgNum, PrimaryTag,
+ Context, MLDS_Statements1, MLDS_Statements)
+ ;
+ { MLDS_Statements = MLDS_Statements1 }
+ ).
:- pred ml_gen_unify_arg(cons_id, prog_var, uni_mode, prog_type,
constructor_arg, prog_type, mlds__lval, int, int, mlds__tag,
Index: compiler/sr_choice.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/Attic/sr_choice.m,v
retrieving revision 1.1.2.17
diff -u -r1.1.2.17 sr_choice.m
--- compiler/sr_choice.m 2001/03/14 14:48:04 1.1.2.17
+++ compiler/sr_choice.m 2001/03/16 09:02:16
@@ -17,7 +17,7 @@
:- module sr_choice.
:- interface.
-:- import_module hlds_goal, hlds_module, sr_data.
+:- import_module hlds_goal, hlds_pred, hlds_module, sr_data.
:- import_module io, list, std_util.
:- type strategy
@@ -41,7 +41,8 @@
; random
.
-:- pred sr_choice__process_goal(strategy::in, hlds_goal::in, hlds_goal::out,
+:- pred sr_choice__process_goal(strategy::in, vartypes::in, module_info::in,
+ hlds_goal::in, hlds_goal::out,
maybe(list(reuse_condition))::out) is det.
:- pred get_strategy(strategy::out, module_info::in, module_info::out,
io__state::di, io__state::uo) is det.
@@ -52,13 +53,14 @@
:- implementation.
-:- import_module hlds_data, prog_data.
+:- import_module hlds_data, prog_data, type_util.
:- import_module assoc_list, bool, globals, int.
-:- import_module multi_map, options, require, set.
+:- import_module map, multi_map, options, require, set.
-process_goal(Strategy, Goal0, Goal, MaybeReuseConditions) :-
+process_goal(Strategy, VarTypes, ModuleInfo,
+ Goal0, Goal, MaybeReuseConditions) :-
Strategy = strategy(Constraint, SelectionRule),
- apply_constraint(Constraint, Goal0, Goal1),
+ apply_constraint(Constraint, VarTypes, ModuleInfo, Goal0, Goal1),
select_reuses(SelectionRule, Goal1, Goal, ReuseConditions),
( ReuseConditions = [] ->
MaybeReuseConditions = no
@@ -70,76 +72,89 @@
:- type constraint_info
---> constraint_info(
- map :: multi_map(prog_var,
- pair(cons_id, prog_vars))
+ map :: multi_map(prog_var,
+ reuse_cell_data),
+ module_info :: module_info,
+ vartypes :: vartypes
).
-:- pred constraint_info_init(constraint_info::out) is det.
+:- type reuse_cell_data
+ ---> data(
+ cons_id :: cons_id,
+ vars :: prog_vars,
+ secondary_tag :: bool
+ ).
+
+:- pred constraint_info_init(vartypes::in, module_info::in,
+ constraint_info::out) is det.
-constraint_info_init(constraint_info(Map)) :-
+constraint_info_init(VarTypes, ModuleInfo,
+ constraint_info(Map, ModuleInfo, VarTypes)) :-
multi_map__init(Map).
-:- pred apply_constraint(constraint::in, hlds_goal::in, hlds_goal::out) is det.
+:- pred apply_constraint(constraint::in, vartypes::in, module_info::in,
+ hlds_goal::in, hlds_goal::out) is det.
-apply_constraint(Constraint, Goal0, Goal) :-
- constraint_info_init(ConstraintInfo),
- apply_constraint(Constraint, Goal0, Goal, ConstraintInfo, _).
+apply_constraint(Constraint, VarTypes, ModuleInfo, Goal0, Goal) :-
+ constraint_info_init(VarTypes, ModuleInfo, ConstraintInfo),
+ apply_constraint_2(Constraint, Goal0, Goal, ConstraintInfo, _).
-:- pred apply_constraint(constraint::in, hlds_goal::in, hlds_goal::out,
+:- pred apply_constraint_2(constraint::in, hlds_goal::in, hlds_goal::out,
constraint_info::in, constraint_info::out) is det.
-apply_constraint(_Constraint, Goal - GoalInfo, Goal - GoalInfo) -->
+apply_constraint_2(_Constraint, Goal - GoalInfo, Goal - GoalInfo) -->
{ Goal = call(_PredId, _ProcId, _Args, _Builtin, _MaybeCtxt, _Name) }.
-apply_constraint(Constraint, Goal - GoalInfo0, Goal - GoalInfo) -->
+apply_constraint_2(Constraint, Goal - GoalInfo0, Goal - GoalInfo) -->
{ Goal = unify(_Var, _Rhs, _Mode, Unification, _Ctxt) },
- apply_constraint_unification(Constraint, Unification, GoalInfo0, GoalInfo).
+ apply_constraint_unification(Constraint, Unification,
+ GoalInfo0, GoalInfo).
-apply_constraint(_Constraint, Goal0 - GoalInfo, Goal - GoalInfo) -->
+apply_constraint_2(_Constraint, Goal0 - GoalInfo, Goal - GoalInfo) -->
{ Goal0 = generic_call(_, _, _, _) },
{ Goal = Goal0 }.
-apply_constraint(_Constraint, Goal0 - GoalInfo, Goal - GoalInfo) -->
+apply_constraint_2(_Constraint, Goal0 - GoalInfo, Goal - GoalInfo) -->
{ Goal0 = pragma_foreign_code(_, _, _, _, _, _, _) },
{ Goal = Goal0 }.
-apply_constraint(_Constraint, Goal0 - _GoalInfo, _) -->
+apply_constraint_2(_Constraint, Goal0 - _GoalInfo, _) -->
{ Goal0 = bi_implication(_, _) },
{ error("structure_reuse: bi_implication.\n") }.
-apply_constraint(Constraint, Goal0 - GoalInfo, Goal - GoalInfo) -->
+apply_constraint_2(Constraint, Goal0 - GoalInfo, Goal - GoalInfo) -->
{ Goal0 = if_then_else(Vars, If0, Then0, Else0, SM) },
=(BeforeIfInfo),
- apply_constraint(Constraint, If0, If),
+ apply_constraint_2(Constraint, If0, If),
=(IfInfo),
- { apply_constraint(Constraint, Then0, Then, IfInfo, ThenInfo) },
- { apply_constraint(Constraint, Else0, Else, BeforeIfInfo, ElseInfo) },
+ { apply_constraint_2(Constraint, Then0, Then, IfInfo, ThenInfo) },
+ { apply_constraint_2(Constraint, Else0, Else, BeforeIfInfo, ElseInfo) },
merge(ThenInfo),
merge(ElseInfo),
{ Goal = if_then_else(Vars, If, Then, Else, SM) }.
-apply_constraint(Constraint, Goal0 - GoalInfo, Goal - GoalInfo) -->
+apply_constraint_2(Constraint, Goal0 - GoalInfo, Goal - GoalInfo) -->
{ Goal0 = switch(Var, CanFail, Cases0, StoreMap) },
=(InitSwitchInfo),
apply_constraint_cases(Constraint, InitSwitchInfo, Cases0, Cases),
{ Goal = switch(Var, CanFail, Cases, StoreMap) }.
-apply_constraint(Constraint, Goal0 - GoalInfo, Goal - GoalInfo) -->
+apply_constraint_2(Constraint, Goal0 - GoalInfo, Goal - GoalInfo) -->
{ Goal0 = some(Vars, CanRemove, SomeGoal0) },
- apply_constraint(Constraint, SomeGoal0, SomeGoal),
+ apply_constraint_2(Constraint, SomeGoal0, SomeGoal),
{ Goal = some(Vars, CanRemove, SomeGoal) }.
-apply_constraint(Constraint, not(Goal0) - GoalInfo, not(Goal) - GoalInfo) -->
- apply_constraint(Constraint, Goal0, Goal).
+apply_constraint_2(Constraint, not(Goal0) - GoalInfo, not(Goal) - GoalInfo) -->
+ apply_constraint_2(Constraint, Goal0, Goal).
-apply_constraint(Constraint, conj(Goal0s) - GoalInfo,
+apply_constraint_2(Constraint, conj(Goal0s) - GoalInfo,
conj(Goals) - GoalInfo) -->
apply_constraint_list(Constraint, Goal0s, Goals).
-apply_constraint(Constraint, disj(Goal0s, SM) - GoalInfo,
+apply_constraint_2(Constraint, disj(Goal0s, SM) - GoalInfo,
disj(Goals, SM) - GoalInfo) -->
=(InitDisjInfo),
apply_constraint_disj(Constraint, InitDisjInfo, Goal0s, Goals).
-apply_constraint(Constraint, par_conj(Goal0s, SM) - GoalInfo,
+apply_constraint_2(Constraint, par_conj(Goal0s, SM) - GoalInfo,
par_conj(Goals, SM) - GoalInfo) -->
apply_constraint_list(Constraint, Goal0s, Goals).
@@ -150,7 +165,7 @@
apply_constraint_cases(_Constraint, _Info0, [], []) --> [].
apply_constraint_cases(Constraint, Info0, [Case0 | Case0s], [Case | Cases]) -->
{ Case0 = case(ConsId, Goal0) },
- { apply_constraint(Constraint, Goal0, Goal, Info0, Info) },
+ { apply_constraint_2(Constraint, Goal0, Goal, Info0, Info) },
merge(Info),
{ Case = case(ConsId, Goal) },
apply_constraint_cases(Constraint, Info0, Case0s, Cases).
@@ -160,7 +175,7 @@
apply_constraint_list(_Constraint, [], []) --> [].
apply_constraint_list(Constraint, [Goal0 | Goal0s], [Goal | Goals]) -->
- apply_constraint(Constraint, Goal0, Goal),
+ apply_constraint_2(Constraint, Goal0, Goal),
apply_constraint_list(Constraint, Goal0s, Goals).
:- pred apply_constraint_disj(constraint::in,
@@ -169,7 +184,7 @@
apply_constraint_disj(_Constraint, _Info0, [], []) --> [].
apply_constraint_disj(Constraint, Info0, [Goal0 | Goal0s], [Goal | Goals]) -->
- { apply_constraint(Constraint, Goal0, Goal, Info0, Info) },
+ { apply_constraint_2(Constraint, Goal0, Goal, Info0, Info) },
merge(Info),
apply_constraint_disj(Constraint, Info0, Goal0s, Goals).
@@ -185,13 +200,14 @@
constraint_info::in, constraint_info::out) is det.
apply_constraint_unification(Constraint, Unif, GoalInfo0, GoalInfo) -->
- { Unif = construct(_Var, ConsId, Vars, _Ms, _HTC, _IsUniq, _Aditi) },
+ { Unif = construct(Var, ConsId, Vars, _Ms, _HTC, _IsUniq, _Aditi) },
{ goal_info_get_reuse(GoalInfo0, ReuseInfo) },
{ ReuseInfo = choice(construct(Pairs)) ->
PossibleCandidates = set__to_sorted_list(Pairs)
;
error("sr_choice__apply_constraint_unification")
},
+ has_secondary_tag(Var, ConsId, HasSecondaryTag),
Map =^ map,
(
{ Constraint = same_cons_id },
@@ -201,9 +217,14 @@
list__member(Candidate0, PossibleCandidates),
CandidateVar = Candidate0 ^ var,
multi_map__search(Map, CandidateVar, CandidateData),
- list__map(fst, CandidateData, ConsIds),
+ ConsIds = list__map((func(D) = D ^ cons_id),
+ CandidateData),
list__remove_dups(ConsIds, [ConsId]),
- Candidate = Candidate0 ^ cons_ids := yes([ConsId])
+ ReuseFields = reuse_fields(HasSecondaryTag, Vars,
+ CandidateData),
+ Candidate = (Candidate0
+ ^ cons_ids := yes([ConsId]))
+ ^ reuse_fields := yes(ReuseFields)
)}
;
{ Constraint = within_n_cells_difference(Difference) },
@@ -214,9 +235,10 @@
CandidateVar = Candidate0 ^ var,
multi_map__search(Map, CandidateVar, CandidateData),
ConsIds = list__remove_dups(
- list__map(fst, CandidateData)),
+ list__map((func(D) = D ^ cons_id),
+ CandidateData)),
ReuseSizes = list__map(
- (func(Data) = list__length(snd(Data))),
+ (func(Data) = list__length(Data^vars)),
CandidateData),
Size = list__length(Vars),
all [ReuseSize] (
@@ -226,7 +248,12 @@
ReuseSize - Size =< Difference
)
),
- Candidate = Candidate0 ^ cons_ids := yes(ConsIds)
+ ReuseFields = reuse_fields(HasSecondaryTag, Vars,
+ CandidateData),
+ Candidate = (Candidate0
+ ^ cons_ids := yes(ConsIds))
+ ^ reuse_fields := yes(ReuseFields)
+
)}
),
{ solutions(P, Candidates) },
@@ -253,7 +280,8 @@
},
Map0 =^ map,
- { multi_map__set(Map0, Var, ConsId - Vars, Map) },
+ has_secondary_tag(Var, ConsId, SecondaryTag),
+ { multi_map__set(Map0, Var, data(ConsId, Vars, SecondaryTag), Map) },
^ map := Map.
apply_constraint_unification(_Constraint, Unif, GoalInfo, GoalInfo) -->
{ Unif = assign(_, _) }.
@@ -263,6 +291,133 @@
{ Unif = complicated_unify(_, _, _) }.
+ %
+ % has_secondary_tag(Var, ConsId, HasSecTag) is true iff the
+ % variable, Var, with cons_id, ConsId, requires a remote
+ % secondary tag to distinguish between its various functors.
+ %
+:- pred has_secondary_tag(prog_var::in, cons_id::in, bool::out,
+ constraint_info::in, constraint_info::out) is det.
+
+has_secondary_tag(Var, ConsId, SecondaryTag) -->
+ ModuleInfo =^ module_info,
+ VarTypes =^ vartypes,
+ {
+ map__lookup(VarTypes, Var, Type),
+ type_to_type_id(Type, TypeId, _Args)
+ ->
+ module_info_types(ModuleInfo, Types),
+ ( map__search(Types, TypeId, TypeDefn) ->
+ hlds_data__get_type_defn_body(TypeDefn, TypeBody),
+ ( TypeBody = du_type(_, ConsTagValues, _, _) ->
+ (
+ % The search can fail
+ % for such types as
+ % private_builtin:type_info,
+ % if the search fails we
+ % will not have a
+ % secondary tag.
+ map__search(ConsTagValues, ConsId,
+ ConsTag),
+ ConsTag = shared_remote_tag(_, _)
+ ->
+ SecondaryTag = yes
+ ;
+ SecondaryTag = no
+ )
+ ;
+ error("has_secondary_tag: not du type.")
+ )
+ ;
+ % Must be a basic type.
+ SecondaryTag = no
+ )
+ ;
+ error("has_secondary_tag: type_to_type_id failed.")
+
+ }.
+
+ %
+ % Determine which of the fields already contain references to
+ % the correct variable, and hence don't need to be updated. To
+ % do this requires knowledge of whether or not the current field
+ % has a secondary tag or not.
+ %
+:- func reuse_fields(bool, prog_vars, list(reuse_cell_data)) = list(bool).
+
+reuse_fields(HasSecTag, Vars, CandidateData)
+ = list__foldl(and_list, Tail, Head) :-
+ Pairs = list__map((func(Data) =
+ Data ^ secondary_tag - Data ^ vars),
+ CandidateData),
+ BoolsList = list__map(
+ already_correct_fields(HasSecTag, Vars), Pairs),
+ ( BoolsList = [H | T] ->
+ Head = H,
+ Tail = T
+ ;
+ error("reuse_fields: empty list")
+ ).
+
+ %
+ % already_correct_fields(HasSecTagC, VarsC, HasSecTagR, VarsR)
+ % takes a list of variables, VarsC, which are the arguments for
+ % the cell to be constructed and the list of variables, VarsR,
+ % which are the arguments for the cell to be reused and returns
+ % a list of bool where each yes indicates that argument already
+ % has the correct value stored in it. To do this correctly we
+ % need to know whether each cell has a secondary tag field.
+ %
+:- func already_correct_fields(bool, prog_vars,
+ pair(bool, prog_vars)) = list(bool).
+
+already_correct_fields(SecTagC, CurrentCellVars, SecTagR - ReuseCellVars)
+ = Bools ++ list__duplicate(LengthC - LengthB, no) :-
+ Bools = already_correct_fields_2(SecTagC, CurrentCellVars,
+ SecTagR, ReuseCellVars),
+ LengthC = list__length(CurrentCellVars),
+ LengthB = list__length(Bools).
+
+:- func already_correct_fields_2(bool, prog_vars, bool, prog_vars) = list(bool).
+
+already_correct_fields_2(yes, CurrentCellVars, yes, ReuseCellVars)
+ = equals(CurrentCellVars, ReuseCellVars).
+already_correct_fields_2(yes, CurrentCellVars, no, ReuseCellVars)
+ = [no | equals(CurrentCellVars, drop_one(ReuseCellVars))].
+already_correct_fields_2(no, CurrentCellVars, yes, ReuseCellVars)
+ = [no | equals(drop_one(CurrentCellVars), ReuseCellVars)].
+already_correct_fields_2(no, CurrentCellVars, no, ReuseCellVars)
+ = equals(CurrentCellVars, ReuseCellVars).
+
+ %
+ % equals(ListA, ListB) produces a list of bools which indicates
+ % whether the corresponding elements from ListA and ListB were
+ % equal. If ListA and ListB are of different lengths, the
+ % resulting list is the length of the shorter of the two.
+ %
+:- func equals(list(T), list(T)) = list(bool).
+
+equals([], []) = [].
+equals([], [_|_]) = [].
+equals([_|_], []) = [].
+equals([X | Xs], [Y | Ys]) = [Bool | equals(Xs, Ys)] :-
+ ( X = Y ->
+ Bool = yes
+ ;
+ Bool = no
+ ).
+
+:- func drop_one(list(T)) = list(T).
+
+drop_one([]) = [].
+drop_one([_ | Xs]) = Xs.
+
+:- func and_list(list(bool), list(bool)) = list(bool).
+
+and_list(ListA, ListB)
+ = list__map((func(A - B) = A `and` B),
+ from_corresponding_lists(ListA, ListB)).
+
%-----------------------------------------------------------------------------%
:- import_module queue.
@@ -516,10 +671,14 @@
{ solutions(P, Candidates) }
),
( { Candidates = [Candidate | _] } ->
- { ReuseVar = Candidate ^ var },
- { ReuseCond = Candidate ^ condition },
- { Candidate ^ cons_ids = yes(ConsIds0) ->
- ConsIds = ConsIds0
+ { Candidate = reuse_var(ReuseVar, ReuseCond,
+ MaybeConsIds, MaybeReuseFields) },
+ {
+ MaybeConsIds = yes(ConsIds0),
+ MaybeReuseFields = yes(ReuseFields0)
+ ->
+ ConsIds = ConsIds0,
+ ReuseFields = ReuseFields0
;
error("select_reuses_unification: no cons_ids.")
},
@@ -533,7 +692,7 @@
},
{ goal_info_set_reuse(GoalInfo0,
reuse(cell_reused(ReuseVar, ConditionalReuse,
- ConsIds)),
+ ConsIds, ReuseFields)),
GoalInfo) },
ReuseConditions =^ reuse_conds,
^ reuse_conds := [ReuseCond | ReuseConditions]
Index: compiler/sr_data.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/Attic/sr_data.m,v
retrieving revision 1.1.2.16
diff -u -r1.1.2.16 sr_data.m
--- compiler/sr_data.m 2001/03/12 20:24:44 1.1.2.16
+++ compiler/sr_data.m 2001/03/16 09:02:20
@@ -33,16 +33,25 @@
:- type short_reuse_info --->
no_reuse
; cell_died
+ ; cell_reused(
+ % The variable selected
+ % for reuse.
+ prog_var,
+ % Is the reuse conditional?
+ bool,
+ % What are the possible
+ % cons_ids that the cell
+ % to be reused can have.
+ list(cons_id),
+ % Which of the fields of
+ % the cell to be reused
+ % already contain the
+ % correct value.
+ list(bool)
+ )
- % The variable we have selected
- % for reuse and whether the
- % reuse is conditional and the
- % possible cons_ids that
- % variable may have.
- ; cell_reused(prog_var, bool, list(cons_id))
-
% Call the reuse version of the
- % call and wheter calling the
+ % call and whether calling the
% reuse version is conditional.
; reuse_call(bool)
; missed_reuse_call(list(string)).
@@ -51,7 +60,8 @@
---> reuse_var(
var :: prog_var,
condition :: reuse_condition,
- cons_ids :: maybe(list(cons_id))
+ cons_ids :: maybe(list(cons_id)),
+ reuse_fields :: maybe(list(bool))
).
:- type choice_info
Index: compiler/sr_dead.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/Attic/sr_dead.m,v
retrieving revision 1.1.2.14
diff -u -r1.1.2.14 sr_dead.m
--- compiler/sr_dead.m 2001/03/14 14:48:05 1.1.2.14
+++ compiler/sr_dead.m 2001/03/16 09:02:22
@@ -458,5 +458,5 @@
:- pred to_pair_var_condition(pair(prog_var, dead_extra_info), reuse_var).
:- mode to_pair_var_condition(in, out) is det.
-to_pair_var_condition(Var - Extra, reuse_var(Var, Condition, no)) :-
+to_pair_var_condition(Var - Extra, reuse_var(Var, Condition, no, no)) :-
Extra = extra(_, Condition, _).
Index: compiler/sr_direct.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/Attic/sr_direct.m,v
retrieving revision 1.1.2.11
diff -u -r1.1.2.11 sr_direct.m
--- compiler/sr_direct.m 2001/03/13 12:10:59 1.1.2.11
+++ compiler/sr_direct.m 2001/03/16 09:02:22
@@ -64,7 +64,8 @@
% compile time garbage collected.
maybe_write_string(VeryVerbose, "%\tchoice analysis..."),
sr_choice__get_strategy(Strategy, ModuleInfo0, ModuleInfo),
- { sr_choice__process_goal(Strategy,
+ { proc_info_vartypes(ProcInfo0, VarTypes) },
+ { sr_choice__process_goal(Strategy, VarTypes, ModuleInfo,
Goal1, Goal, MaybeReuseConditions) },
(
{ VeryVerbose = yes }
Index: compiler/sr_split.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/Attic/sr_split.m,v
retrieving revision 1.1.2.11
diff -u -r1.1.2.11 sr_split.m
--- compiler/sr_split.m 2001/03/12 20:24:45 1.1.2.11
+++ compiler/sr_split.m 2001/03/16 09:02:40
@@ -312,7 +312,8 @@
{ Goal0 = unify(UVar, Rhs, Mode, Unification0, Ctxt) },
{
goal_info_get_reuse(GoalInfo0, Reuse),
- Reuse = reuse(cell_reused(ReuseVar, ConditionalReuse, ConsIds))
+ Reuse = reuse(cell_reused(ReuseVar,
+ ConditionalReuse, ConsIds, ReuseFields))
->
( ConditionalReuse = yes, LocalReuseOnly = yes ->
Unification = Unification0,
@@ -323,15 +324,8 @@
Unification0 = construct(Var, ConsId, Vars,
Modes, _HTC, IsUnique, MaybeRL)
->
- % XXX Wrong cons_id but safe for the
- % moment because we use the
- % strategy that only cells with
- % the same cons_id can be shared.
HTC = reuse_cell(cell_to_reuse(ReuseVar,
- ConsIds,
- list__duplicate(
- list__length(Vars), no)
- )),
+ ConsIds, ReuseFields)),
Unification = construct(Var, ConsId, Vars,
Modes, HTC, IsUnique, MaybeRL)
;
--------------------------------------------------------------------------
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