[m-dev.] [reuse] diff: lifo
Peter Ross
petdr at miscrit.be
Fri Oct 13 01:27:21 AEDT 2000
Hi,
===================================================================
Estimated hours taken: 8
sr_choice.m:
Implement lifo for choosing which variable to use for structure
reuse.
Index: sr_choice.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/Attic/sr_choice.m,v
retrieving revision 1.1.2.8
diff -u -r1.1.2.8 sr_choice.m
--- sr_choice.m 2000/10/11 13:50:42 1.1.2.8
+++ sr_choice.m 2000/10/12 14:26:26
@@ -50,7 +50,7 @@
:- implementation.
:- import_module hlds_data, prog_data.
-:- import_module int, multi_map, require, set.
+:- import_module assoc_list, int, multi_map, require, set.
process_goal(Strategy, Goal0, Goal, MaybeReuseConditions) :-
Strategy = strategy(Constraint, SelectionRule),
@@ -261,12 +261,21 @@
---> selection_info(
local_used :: set(prog_var),
global_used :: set(prog_var),
- reuse_conds :: list(reuse_condition)
+ reuse_conds :: list(reuse_condition),
+
+ lifo :: lifo
).
+:- type lifo
+ ---> lifo(
+ all_locals :: list(list(prog_var)),
+ local :: list(prog_var),
+ global :: list(prog_var)
+ ).
+
:- func selection_info_init = selection_info.
-selection_info_init = selection_info(set__init, set__init, []).
+selection_info_init = selection_info(set__init, set__init, [], lifo([],[],[])).
:- pred select_reuses(selection::in, hlds_goal::in, hlds_goal::out,
list(reuse_condition)::out) is det.
@@ -298,6 +307,7 @@
select_reuses(Selection, Goal0 - GoalInfo, Goal - GoalInfo) -->
{ Goal0 = if_then_else(Vars, If0, Then0, Else0, SM) },
select_reuses(Selection, If0, If),
+ selection_start_branch,
=(IfInfo),
{ select_reuses(Selection, Then0, Then, IfInfo, ThenInfo) },
{ select_reuses(Selection, Else0, Else, IfInfo, ElseInfo) },
@@ -308,6 +318,7 @@
select_reuses(Selection, Goal0 - GoalInfo, Goal - GoalInfo) -->
{ Goal0 = switch(Var, CanFail, Cases0, StoreMap) },
+ selection_start_branch,
=(InitSwitchInfo),
select_reuses_cases(Selection, InitSwitchInfo, Cases0, Cases),
{ Goal = switch(Var, CanFail, Cases, StoreMap) }.
@@ -326,6 +337,7 @@
select_reuses(Selection, disj(Goal0s, SM) - GoalInfo,
disj(Goals, SM) - GoalInfo) -->
+ selection_start_branch,
=(InitDisjInfo),
select_reuses_disj(Selection, InitDisjInfo, Goal0s, Goals).
@@ -370,25 +382,81 @@
:- pred selection_merge(selection_info::in, selection_info::in,
selection_info::out) is det.
-selection_merge(selection_info(LocalA, GlobalA, CondsA),
- selection_info(LocalB, GlobalB, CondsB),
- selection_info(Local, Global, Conds)) :-
+selection_merge(selection_info(LocalA, GlobalA, CondsA, LifoA),
+ selection_info(LocalB, GlobalB, CondsB, LifoB),
+ selection_info(Local, Global, Conds, Lifo)) :-
Local = LocalA `set__union` LocalB,
Global = GlobalA `set__union` GlobalB,
- Conds = CondsA ++ CondsB.
+ Conds = CondsA ++ CondsB,
+
+ LifoA = lifo(AllLocalsA, LocalsA, GlobalsA),
+ LifoB = lifo(AllLocalsB, LocalsB, GlobalsB),
+ Lifo = lifo([LocalsA | AllLocalsB], [], GlobalsB),
+
+ require(unify(LocalsB, []),
+ "selection_merge: LocalsB not empty"),
+ require(unify(AllLocalsA, []),
+ "selection_merge: AllLocalsA not equal"),
+ require(unify(GlobalsA, GlobalsB),
+ "selection_merge: Globals not equal").
+
+
+ %
+ % At the start of processing all branches of a
+ % disj/switch/if_then_else this predicate should be called.
+ %
+:- pred selection_start_branch(selection_info::in, selection_info::out) is det.
+
+selection_start_branch(selection_info(Local0, Global0, Conds0, Lifo0),
+ selection_info(Local, Global, Conds, Lifo)) :-
+ Local = set__init,
+ Global = Local0 `set__union` Global0,
+ Conds = Conds0,
+ Lifo0 = lifo(AllLocals0, Locals0, Globals0),
+ Lifo = lifo(AllLocals0, [], Locals0 ++ Globals0).
+
%
% At the end of processing all branches of a
% disj/switch/if_then_else this predicate should be called.
%
:- pred selection_end_branch(selection_info::in, selection_info::out) is det.
-selection_end_branch(selection_info(Local0, Global0, Conds0),
- selection_info(Local, Global, Conds)) :-
+selection_end_branch(selection_info(Local0, Global0, Conds0, Lifo0),
+ selection_info(Local, Global, Conds, Lifo)) :-
Local = set__init,
Global = Local0 `set__union` Global0,
- Conds = Conds0.
+ Conds = Conds0,
+
+ Lifo0 = lifo(AllLocals0, Locals0, Globals0),
+ Lifo = lifo([], [], list_merge([Locals0 | AllLocals0]) ++ Globals0).
+
+ % [ [1a,2a], [2b,1b], [2c,3c,1c] ] -> [1a, 2b, 2c, 2a, 1b, 3c, 1c]
+:- func list_merge(list(list(T))) = list(T).
+
+list_merge(List) = Result :-
+ list_merge(List, Tail, Head),
+ ( Tail = [] ->
+ Result = list__reverse(Head)
+ ;
+ Result = Head ++ list_merge(Tail)
+ ).
+
+:- pred list_merge(list(list(T))::in, list(list(T))::out, list(T)::out) is det.
+
+list_merge([], [], []).
+list_merge([H | T], Tail, Head) :-
+ (
+ H = [],
+ list_merge(T, Tail, Head)
+ ;
+ H = [X | Xs],
+ list_merge(T, Tail0, Head0),
+ Tail = [Xs | Tail0],
+ Head = [X | Head0]
+ ).
+
:- pred select_reuses_unification(selection::in, unification::in,
hlds_goal_info::in, hlds_goal_info::out,
selection_info::in, selection_info::out) is det.
@@ -401,14 +469,23 @@
;
error("sr_choice__apply_selection_unification")
},
+
+ LocalReused0 =^ local_used,
+ GlobalReused =^ global_used,
+
(
{ Selection = lifo },
- { error("select_reuses_unification: lifo NYI.") }
+ Locals =^ lifo ^ local,
+ Globals =^ lifo ^ global,
+ { F = (pred(Var::in, Var - Cond::out) is semidet :-
+ assoc_list__search(PossibleCandidates,
+ Var, Cond),
+ \+ set__member(Var, LocalReused0),
+ \+ set__member(Var, GlobalReused)
+ )},
+ { list__filter_map(F, Locals ++ Globals, Candidates) }
;
{ Selection = random },
- LocalReused0 =^ local_used,
- GlobalReused =^ global_used,
-
{ P = (pred(Choice::out) is nondet :-
list__member(Choice, PossibleCandidates),
ChoiceVar = fst(Choice),
@@ -416,24 +493,28 @@
\+ set__member(ChoiceVar, GlobalReused)
)},
- { solutions(P, Candidates) },
- ( { Candidates = [ReuseVar - ReuseCond | _] } ->
- { set__insert(LocalReused0, ReuseVar, LocalReused) },
- { goal_info_set_reuse(GoalInfo0,
- reuse(cell_reused(ReuseVar)),
- GoalInfo) },
- ReuseConditions =^ reuse_conds,
- ^ reuse_conds := [ReuseCond | ReuseConditions]
- ;
- { LocalReused = LocalReused0 },
- { goal_info_set_reuse(GoalInfo0,
- reuse(no_reuse),
- GoalInfo) }
- ),
- ^ local_used := LocalReused
- ).
+ { solutions(P, Candidates) }
+ ),
+ ( { Candidates = [ReuseVar - ReuseCond | _] } ->
+ { set__insert(LocalReused0, ReuseVar, LocalReused) },
+ { goal_info_set_reuse(GoalInfo0,
+ reuse(cell_reused(ReuseVar)),
+ GoalInfo) },
+ ReuseConditions =^ reuse_conds,
+ ^ reuse_conds := [ReuseCond | ReuseConditions]
+ ;
+ { LocalReused = LocalReused0 },
+ { goal_info_set_reuse(GoalInfo0,
+ reuse(no_reuse),
+ GoalInfo) }
+ ),
+ ^ local_used := LocalReused.
+
select_reuses_unification(_Selection, Unif, GoalInfo, GoalInfo) -->
- { Unif = deconstruct(_Var, _ConsId, _Vars, _Modes, _CanFail, _CanCGC) }.
+ { Unif = deconstruct(Var, _ConsId, _Vars, _Modes, _CanFail, _CanCGC) },
+ Locals0 =^ lifo ^ local,
+ ^ lifo ^ local := [Var | Locals0].
+
select_reuses_unification(_Selection, Unif, GoalInfo, GoalInfo) -->
{ Unif = assign(_, _) }.
select_reuses_unification(_Selection, Unif, GoalInfo, GoalInfo) -->
--------------------------------------------------------------------------
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