[m-dev.] for review: structure reuse non-locals computation
Simon Taylor
stayl at cs.mu.OZ.AU
Mon Feb 7 14:47:43 AEDT 2000
Estimated hours taken: 3
compiler/quantification.m:
Add an alternative method of computing the non-locals for
goals which do structure reuse, This is done to avoid unnecessary
field extractions and variable saves for arguments of reused terms.
The code-gen non-locals are the same as the ordinary non-locals
except that arguments of a reconstruction which are taken
from the reused cell are not included in the non-locals set.
Mode analysis still uses the full non-locals set.
Add a field to type quant_info to record which set
of non-locals is being computed. Use record syntax
for the access predicates.
compiler/hlds_goal.m:
Add access predicates to extract and update the code_gen_nonlocals
in a goal_info. When structure reuse is not performed, the nonlocals
and the code-gen nonlocals will always be the same.
Use record syntax for hlds_goal_info access predicates.
compiler/goal_util.m:
Add a predicate `goal_contains_reconstruction', which
succeeds if the goal does any structure reuse.
This will always fail on the main branch.
Add missing disjuncts for par_conj goals in `goal_calls' and
`goal_calls_pred_id'.
compiler/liveness.m:
compiler/live_vars.m:
compiler/ml_code_gen.m:
compiler/par_conj_gen.m:
Use the code_gen_nonlocals rather than the ordinary nonlocals.
configure.in:
Add a test for record syntax.
Index: configure.in
===================================================================
RCS file: /home/mercury1/repository/mercury/configure.in,v
retrieving revision 1.200
diff -u -u -r1.200 configure.in
--- configure.in 2000/01/05 16:38:00 1.200
+++ configure.in 2000/02/07 00:51:54
@@ -84,12 +84,21 @@
:- pred main(io__state::di, io__state::uo) is det.
:- implementation.
:- import_module list.
+
+ % Check that record syntax is recognised.
+ :- type foo ---> foo(field1::int).
+
% Check that promise declarations can be parsed
% and that every variable in the assertion doesn't
% need to be explicitly quantified.
:- promise all [[H,T,L]] (list__last([[H|T]], L)).
main -->
- print("Hello, world\n").
+ { Foo = foo(1) },
+ ( { Foo ^ field1 = 1 } ->
+ print("Hello, world\n")
+ ;
+ [[]]
+ ).
EOF
if
echo $BOOTSTRAP_MC conftest >&AC_FD_CC 2>&1 &&
Index: goal_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/goal_util.m,v
retrieving revision 1.60
diff -u -u -r1.60 goal_util.m
--- goal_util.m 1999/10/28 00:57:02 1.60
+++ goal_util.m 2000/02/04 05:45:16
@@ -130,6 +130,11 @@
:- mode goal_calls_pred_id(in, in) is semidet.
:- mode goal_calls_pred_id(in, out) is nondet.
+ % Test whether the goal contains a reconstruction
+ % (a construction where the `cell_to_reuse' field is `yes(_)').
+:- pred goal_contains_reconstruction(hlds_goal).
+:- mode goal_contains_reconstruction(in) is semidet.
+
% goal_contains_goal(Goal, SubGoal) is true iff Goal contains SubGoal,
% i.e. iff Goal = SubGoal or Goal contains SubGoal as a direct
% or indirect sub-goal.
@@ -786,6 +791,8 @@
goal_expr_calls(conj(Goals), PredProcId) :-
goals_calls(Goals, PredProcId).
+goal_expr_calls(par_conj(Goals, _), PredProcId) :-
+ goals_calls(Goals, PredProcId).
goal_expr_calls(disj(Goals, _), PredProcId) :-
goals_calls(Goals, PredProcId).
goal_expr_calls(switch(_, _, Goals, _), PredProcId) :-
@@ -844,6 +851,8 @@
goal_expr_calls_pred_id(conj(Goals), PredId) :-
goals_calls_pred_id(Goals, PredId).
+goal_expr_calls_pred_id(par_conj(Goals, _), PredId) :-
+ goals_calls_pred_id(Goals, PredId).
goal_expr_calls_pred_id(disj(Goals, _), PredId) :-
goals_calls_pred_id(Goals, PredId).
goal_expr_calls_pred_id(switch(_, _, Goals, _), PredId) :-
@@ -862,6 +871,43 @@
goal_calls_pred_id(Goal, PredId).
goal_expr_calls_pred_id(call(PredId, _, _, _, _, _), PredId).
+%-----------------------------------------------------------------------------%
+
+goal_contains_reconstruction(_Goal - _) :-
+ % This will only succeed on the alias branch with structure reuse.
+ semidet_fail.
+ %goal_expr_contains_reconstruction(Goal).
+
+:- pred goal_expr_contains_reconstruction(hlds_goal_expr).
+:- mode goal_expr_contains_reconstruction(in) is semidet.
+
+goal_expr_contains_reconstruction(conj(Goals)) :-
+ goals_contain_reconstruction(Goals).
+goal_expr_contains_reconstruction(disj(Goals, _)) :-
+ goals_contain_reconstruction(Goals).
+goal_expr_contains_reconstruction(par_conj(Goals, _)) :-
+ goals_contain_reconstruction(Goals).
+goal_expr_contains_reconstruction(switch(_, _, Cases, _)) :-
+ list__member(Case, Cases),
+ Case = case(_, Goal),
+ goal_contains_reconstruction(Goal).
+goal_expr_contains_reconstruction(if_then_else(_, Cond, Then, Else, _)) :-
+ goals_contain_reconstruction([Cond, Then, Else]).
+goal_expr_contains_reconstruction(not(Goal)) :-
+ goal_contains_reconstruction(Goal).
+goal_expr_contains_reconstruction(some(_, _, Goal)) :-
+ goal_contains_reconstruction(Goal).
+goal_expr_contains_reconstruction(unify(_, _, _, Unify, _)) :-
+ Unify = construct(_, _, _, _, Reuse, _, _),
+ Reuse = yes(_).
+
+:- pred goals_contain_reconstruction(list(hlds_goal)).
+:- mode goals_contain_reconstruction(in) is semidet.
+
+goals_contain_reconstruction(Goals) :-
+ list__member(Goal, Goals),
+ goal_contains_reconstruction(Goal).
+
%-----------------------------------------------------------------------------%
% goal_contains_goal(Goal, SubGoal) is true iff Goal contains SubGoal,
Index: hlds_goal.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_goal.m,v
retrieving revision 1.67
diff -u -u -r1.67 hlds_goal.m
--- hlds_goal.m 2000/01/13 06:15:38 1.67
+++ hlds_goal.m 2000/02/07 03:38:22
@@ -400,6 +400,9 @@
% of the lambda expression.
maybe(cell_to_reuse),
% Cell to destructively update.
+ % Constructions for which this
+ % field is `yes(_)' are described
+ % as "reconstructions".
cell_is_unique, % Can the cell be allocated
% in shared data.
maybe(rl_exprn_id)
@@ -621,20 +624,22 @@
% if this structure is modified.
:- type hlds_goal_info
---> goal_info(
- set(prog_var), % the pre-birth set
- set(prog_var), % the post-birth set
- set(prog_var), % the pre-death set
- set(prog_var), % the post-death set
+ pre_births :: set(prog_var), % the pre-birth set
+ post_births :: set(prog_var), % the post-birth set
+ pre_deaths :: set(prog_var), % the pre-death set
+ post_deaths :: set(prog_var), % the post-death set
% (all four are computed by liveness.m)
% NB for atomic goals, the post-deadness
% should be applied _before_ the goal
- determinism, % the overall determinism of the goal
+ determinism :: determinism,
+ % the overall determinism of the goal
% (computed during determinism analysis)
% [because true determinism is undecidable,
% this may be a conservative approximation]
- instmap_delta, % the change in insts over this goal
+ instmap_delta :: instmap_delta,
+ % the change in insts over this goal
% (computed during mode analysis)
% [because true unreachability is undecidable,
% the instmap_delta may be reachable even
@@ -653,9 +658,10 @@
% conservative approximations, so if either
% says a goal is unreachable then it is.
- prog_context,
+ context :: prog_context,
- set(prog_var), % the non-local vars in the goal,
+ nonlocals :: set(prog_var),
+ % the non-local vars in the goal,
% i.e. the variables that occur both inside
% and outside of the goal.
% (computed by quantification.m)
@@ -663,25 +669,46 @@
% conservative approximation: it may be
% a superset of the real non-locals]
- maybe(follow_vars),
+ /*
+ code_gen_nonlocals :: maybe(set(prog_var)),
+ % the non-local vars in the goal,
+ % modified slightly for code generation.
+ % The difference between the code-gen nonlocals
+ % and the ordinary nonlocals is that arguments
+ % of a reconstruction which are taken from the
+ % reused cell are not considered to be
+ % `code_gen_nonlocals' of the goal.
+ % This avoids allocating stack slots and
+ % generating unnecessary field extraction
+ % instructions for those arguments.
+ % Mode information is still computed using
+ % the ordinary non-locals.
+ %
+ % If the field has value `no', the ordinary
+ % nonlocals are used instead. This will
+ % be the case if the procedure body does not
+ % contain any reconstructions.
+ */
+
+ follow_vars :: maybe(follow_vars),
% advisory information about where variables
% ought to be put next. The legal range
% includes the nonexistent register r(-1),
% which indicates any available register.
- set(goal_feature),
+ features :: set(goal_feature),
% The set of used-defined "features" of
% this goal, which optimisers may wish
% to know about.
- resume_point,
+ resume_point :: resume_point,
% If this goal establishes a resumption point,
% state what variables need to be saved for
% that resumption point, and which entry
% labels of the resumption point will be
% needed. (See compiler/notes/allocation.html)
- goal_path
+ goal_path :: goal_path
% The path to this goal from the root in
% reverse order.
).
@@ -786,9 +813,16 @@
:- pred goal_info_get_nonlocals(hlds_goal_info, set(prog_var)).
:- mode goal_info_get_nonlocals(in, out) is det.
+:- pred goal_info_get_code_gen_nonlocals(hlds_goal_info, set(prog_var)).
+:- mode goal_info_get_code_gen_nonlocals(in, out) is det.
+
:- pred goal_info_set_nonlocals(hlds_goal_info, set(prog_var), hlds_goal_info).
:- mode goal_info_set_nonlocals(in, in, out) is det.
+:- pred goal_info_set_code_gen_nonlocals(hlds_goal_info,
+ set(prog_var), hlds_goal_info).
+:- mode goal_info_set_code_gen_nonlocals(in, in, out) is det.
+
:- pred goal_info_get_features(hlds_goal_info, set(goal_feature)).
:- mode goal_info_get_features(in, out) is det.
@@ -1056,106 +1090,74 @@
goal_info_set_nonlocals(GoalInfo0, NonLocals, GoalInfo1),
goal_info_set_instmap_delta(GoalInfo1, InstMapDelta, GoalInfo2),
goal_info_set_determinism(GoalInfo2, Detism, GoalInfo).
+
+goal_info_get_pre_births(GoalInfo, GoalInfo ^ pre_births).
+
+goal_info_get_post_births(GoalInfo, GoalInfo ^ post_births).
+
+goal_info_get_pre_deaths(GoalInfo, GoalInfo ^ pre_deaths).
+
+goal_info_get_post_deaths(GoalInfo, GoalInfo ^ post_deaths).
+
+goal_info_get_determinism(GoalInfo, GoalInfo ^ determinism).
+
+goal_info_get_instmap_delta(GoalInfo, GoalInfo ^ instmap_delta).
+
+goal_info_get_context(GoalInfo, GoalInfo ^ context).
+
+goal_info_get_nonlocals(GoalInfo, GoalInfo ^ nonlocals).
+
+ % The code-gen non-locals are always the same as the
+ % non-locals when structure reuse is not being performed.
+goal_info_get_code_gen_nonlocals(GoalInfo, NonLocals) :-
+ goal_info_get_nonlocals(GoalInfo, NonLocals).
+
+goal_info_get_follow_vars(GoalInfo, GoalInfo ^ follow_vars).
+
+goal_info_get_features(GoalInfo, GoalInfo ^ features).
+
+goal_info_get_resume_point(GoalInfo, GoalInfo ^ resume_point).
+
+goal_info_get_goal_path(GoalInfo, GoalInfo ^ goal_path).
+
+goal_info_set_pre_births(GoalInfo0, PreBirths,
+ GoalInfo0 ^ pre_births := PreBirths).
+
+goal_info_set_post_births(GoalInfo0, PostBirths,
+ GoalInfo0 ^ post_births := PostBirths).
+
+goal_info_set_pre_deaths(GoalInfo0, PreDeaths,
+ GoalInfo0 ^ pre_deaths := PreDeaths).
+
+goal_info_set_post_deaths(GoalInfo0, PostDeaths,
+ GoalInfo0 ^ post_deaths := PostDeaths).
+
+goal_info_set_determinism(GoalInfo0, Determinism,
+ GoalInfo0 ^ determinism := Determinism).
+
+goal_info_set_instmap_delta(GoalInfo0, InstMapDelta,
+ GoalInfo0 ^ instmap_delta := InstMapDelta).
+
+goal_info_set_context(GoalInfo0, Context, GoalInfo0 ^ context := Context).
+
+goal_info_set_nonlocals(GoalInfo0, NonLocals,
+ GoalInfo0 ^ nonlocals := NonLocals).
+
+ % The code-gen non-locals are always the same as the
+ % non-locals when structure reuse is not being performed.
+goal_info_set_code_gen_nonlocals(GoalInfo0, NonLocals, GoalInfo) :-
+ goal_info_set_nonlocals(GoalInfo0, NonLocals, GoalInfo).
-goal_info_get_pre_births(GoalInfo, PreBirths) :-
- GoalInfo = goal_info(PreBirths, _, _, _, _, _, _, _, _, _, _, _).
+goal_info_set_follow_vars(GoalInfo0, FollowVars,
+ GoalInfo0 ^ follow_vars := FollowVars).
-goal_info_get_post_births(GoalInfo, PostBirths) :-
- GoalInfo = goal_info(_, PostBirths, _, _, _, _, _, _, _, _, _, _).
+goal_info_set_features(GoalInfo0, Features, GoalInfo0 ^ features := Features).
-goal_info_get_pre_deaths(GoalInfo, PreDeaths) :-
- GoalInfo = goal_info(_, _, PreDeaths, _, _, _, _, _, _, _, _, _).
+goal_info_set_resume_point(GoalInfo0, ResumePoint,
+ GoalInfo0 ^ resume_point := ResumePoint).
-goal_info_get_post_deaths(GoalInfo, PostDeaths) :-
- GoalInfo = goal_info(_, _, _, PostDeaths, _, _, _, _, _, _, _, _).
-
-goal_info_get_determinism(GoalInfo, Determinism) :-
- GoalInfo = goal_info(_, _, _, _, Determinism, _, _, _, _, _, _, _).
-
-goal_info_get_instmap_delta(GoalInfo, InstMapDelta) :-
- GoalInfo = goal_info(_, _, _, _, _, InstMapDelta, _, _, _, _, _, _).
-
-goal_info_get_context(GoalInfo, Context) :-
- GoalInfo = goal_info(_, _, _, _, _, _, Context, _, _, _, _, _).
-
-goal_info_get_nonlocals(GoalInfo, NonLocals) :-
- GoalInfo = goal_info(_, _, _, _, _, _, _, NonLocals, _, _, _, _).
-
-goal_info_get_follow_vars(GoalInfo, MaybeFollowVars) :-
- GoalInfo = goal_info(_, _, _, _, _, _, _, _, MaybeFollowVars, _, _, _).
-
-goal_info_get_features(GoalInfo, Features) :-
- GoalInfo = goal_info(_, _, _, _, _, _, _, _, _, Features, _, _).
-
-goal_info_get_resume_point(GoalInfo, ResumePoint) :-
- GoalInfo = goal_info(_, _, _, _, _, _, _, _, _, _, ResumePoint, _).
-
-goal_info_get_goal_path(GoalInfo, GoalPath) :-
- GoalInfo = goal_info(_, _, _, _, _, _, _, _, _, _, _, GoalPath).
-
-% :- type hlds_goal_info
-% ---> goal_info(
-% A set(prog_var), % the pre-birth set
-% B set(prog_var), % the post-birth set
-% C set(prog_var), % the pre-death set
-% D set(prog_var), % the post-death set
-% E determinism, % the overall determinism of the goal
-% F instmap_delta, % the change in insts over this goal
-% G prog_context,
-% H set(prog_var), % the non-local vars in the goal
-% I maybe(follow_vars),
-% J set(goal_feature),
-% K resume_point,
-% L goal_path
-% ).
-
-goal_info_set_pre_births(GoalInfo0, PreBirths, GoalInfo) :-
- GoalInfo0 = goal_info(_, B, C, D, E, F, G, H, I, J, K, L),
- GoalInfo = goal_info(PreBirths, B, C, D, E, F, G, H, I, J, K, L).
-
-goal_info_set_post_births(GoalInfo0, PostBirths, GoalInfo) :-
- GoalInfo0 = goal_info(A, _, C, D, E, F, G, H, I, J, K, L),
- GoalInfo = goal_info(A, PostBirths, C, D, E, F, G, H, I, J, K, L).
-
-goal_info_set_pre_deaths(GoalInfo0, PreDeaths, GoalInfo) :-
- GoalInfo0 = goal_info(A, B, _, D, E, F, G, H, I, J, K, L),
- GoalInfo = goal_info(A, B, PreDeaths, D, E, F, G, H, I, J, K, L).
-
-goal_info_set_post_deaths(GoalInfo0, PostDeaths, GoalInfo) :-
- GoalInfo0 = goal_info(A, B, C, _, E, F, G, H, I, J, K, L),
- GoalInfo = goal_info(A, B, C, PostDeaths, E, F, G, H, I, J, K, L).
-
-goal_info_set_determinism(GoalInfo0, Determinism, GoalInfo) :-
- GoalInfo0 = goal_info(A, B, C, D, _, F, G, H, I, J, K, L),
- GoalInfo = goal_info(A, B, C, D, Determinism, F, G, H, I, J, K, L).
-
-goal_info_set_instmap_delta(GoalInfo0, InstMapDelta, GoalInfo) :-
- GoalInfo0 = goal_info(A, B, C, D, E, _, G, H, I, J, K, L),
- GoalInfo = goal_info(A, B, C, D, E, InstMapDelta, G, H, I, J, K, L).
-
-goal_info_set_context(GoalInfo0, Context, GoalInfo) :-
- GoalInfo0 = goal_info(A, B, C, D, E, F, _, H, I, J, K, L),
- GoalInfo = goal_info(A, B, C, D, E, F, Context, H, I, J, K, L).
-
-goal_info_set_nonlocals(GoalInfo0, NonLocals, GoalInfo) :-
- GoalInfo0 = goal_info(A, B, C, D, E, F, G, _, I, J, K, L),
- GoalInfo = goal_info(A, B, C, D, E, F, G, NonLocals, I, J, K, L).
-
-goal_info_set_follow_vars(GoalInfo0, FollowVars, GoalInfo) :-
- GoalInfo0 = goal_info(A, B, C, D, E, F, G, H, _, J, K, L),
- GoalInfo = goal_info(A, B, C, D, E, F, G, H, FollowVars, J, K, L).
-
-goal_info_set_features(GoalInfo0, Features, GoalInfo) :-
- GoalInfo0 = goal_info(A, B, C, D, E, F, G, H, I, _, K, L),
- GoalInfo = goal_info(A, B, C, D, E, F, G, H, I, Features, K, L).
-
-goal_info_set_resume_point(GoalInfo0, ResumePoint, GoalInfo) :-
- GoalInfo0 = goal_info(A, B, C, D, E, F, G, H, I, J, _, L),
- GoalInfo = goal_info(A, B, C, D, E, F, G, H, I, J, ResumePoint, L).
-
-goal_info_set_goal_path(GoalInfo0, GoalPath, GoalInfo) :-
- GoalInfo0 = goal_info(A, B, C, D, E, F, G, H, I, J, K, _),
- GoalInfo = goal_info(A, B, C, D, E, F, G, H, I, J, K, GoalPath).
+goal_info_set_goal_path(GoalInfo0, GoalPath,
+ GoalInfo0 ^ goal_path := GoalPath).
goal_info_get_code_model(GoalInfo, CodeModel) :-
goal_info_get_determinism(GoalInfo, Determinism),
Index: live_vars.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/live_vars.m,v
retrieving revision 1.85
diff -u -u -r1.85 live_vars.m
--- live_vars.m 1999/10/25 03:49:06 1.85
+++ live_vars.m 2000/02/04 05:14:01
@@ -191,7 +191,7 @@
build_live_sets_in_goal_2(par_conj(Goals0, _SM), Liveness0, ResumeVars0,
LiveSets0, GoalInfo, ModuleInfo, ProcInfo, TypeInfoLiveness,
Liveness, ResumeVars, LiveSets) :-
- goal_info_get_nonlocals(GoalInfo, NonLocals),
+ goal_info_get_code_gen_nonlocals(GoalInfo, NonLocals),
set__union(NonLocals, Liveness0, LiveSet),
% We insert all the union of the live vars and the nonlocals.
% Since each parallel conjunct may be run on a different
Index: liveness.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/liveness.m,v
retrieving revision 1.102
diff -u -u -r1.102 liveness.m
--- liveness.m 1999/10/25 03:49:08 1.102
+++ liveness.m 2000/02/04 05:12:57
@@ -472,7 +472,7 @@
detect_deadness_in_goal_2(par_conj(Goals0, SM), GoalInfo, Deadness0, LiveInfo,
Deadness, par_conj(Goals, SM)) :-
set__init(Union0),
- goal_info_get_nonlocals(GoalInfo, NonLocals),
+ goal_info_get_code_gen_nonlocals(GoalInfo, NonLocals),
detect_deadness_in_par_conj(Goals0, Deadness0, NonLocals,
LiveInfo, Union0, Union, Goals),
set__union(Union, Deadness0, Deadness).
@@ -979,7 +979,7 @@
% typeinfo vars.
module_info_globals(ModuleInfo, Globals),
proc_info_goal(ProcInfo, _Goal - GoalInfo),
- goal_info_get_nonlocals(GoalInfo, NonLocals0),
+ goal_info_get_code_gen_nonlocals(GoalInfo, NonLocals0),
module_info_pred_info(ModuleInfo, PredId, PredInfo),
body_should_use_typeinfo_liveness(Globals, TypeinfoLiveness),
pred_info_module(PredInfo, PredModule),
@@ -1172,7 +1172,7 @@
liveness__get_nonlocals_and_typeinfos(LiveInfo, GoalInfo,
NonLocals) :-
- goal_info_get_nonlocals(GoalInfo, NonLocals0),
+ goal_info_get_code_gen_nonlocals(GoalInfo, NonLocals0),
live_info_get_typeinfo_liveness(LiveInfo, TypeinfoLiveness),
(
TypeinfoLiveness = yes
Index: ml_code_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_code_gen.m,v
retrieving revision 1.27
diff -u -u -r1.27 ml_code_gen.m
--- ml_code_gen.m 2000/01/26 02:04:25 1.27
+++ ml_code_gen.m 2000/02/04 05:17:56
@@ -819,10 +819,10 @@
%
proc_info_headvars(ProcInfo, HeadVars),
Goal0 = GoalExpr - GoalInfo0,
- goal_info_get_nonlocals(GoalInfo0, NonLocals0),
+ goal_info_get_code_gen_nonlocals(GoalInfo0, NonLocals0),
set__list_to_set(HeadVars, HeadVarsSet),
set__intersect(HeadVarsSet, NonLocals0, NonLocals),
- goal_info_set_nonlocals(GoalInfo0, NonLocals, GoalInfo),
+ goal_info_set_code_gen_nonlocals(GoalInfo0, NonLocals, GoalInfo),
Goal = GoalExpr - GoalInfo,
goal_info_get_context(GoalInfo, Context),
@@ -996,7 +996,7 @@
goal_util__goal_vars(Goal, GoalVars),
% delete the non-locals
Goal = _ - GoalInfo,
- goal_info_get_nonlocals(GoalInfo, NonLocalVars),
+ goal_info_get_code_gen_nonlocals(GoalInfo, NonLocalVars),
set__difference(GoalVars, NonLocalVars, LocalVars).
:- func union_of_direct_subgoal_locals(hlds_goal) = set(prog_var).
Index: par_conj_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/par_conj_gen.m,v
retrieving revision 1.5
diff -u -u -r1.5 par_conj_gen.m
--- par_conj_gen.m 1999/08/30 04:57:54 1.5
+++ par_conj_gen.m 2000/02/04 05:15:07
@@ -128,7 +128,7 @@
{ globals__lookup_int_option(Globals, sync_term_size, STSize) },
code_info__get_known_variables(Vars),
code_info__save_variables_on_stack(Vars, SaveCode),
- { goal_info_get_nonlocals(GoalInfo, Nonlocals) },
+ { goal_info_get_code_gen_nonlocals(GoalInfo, Nonlocals) },
{ set__to_sorted_list(Nonlocals, Variables) },
code_info__get_instmap(Initial),
{ goal_info_get_instmap_delta(GoalInfo, Delta) },
Index: quantification.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/quantification.m,v
retrieving revision 1.70
diff -u -u -r1.70 quantification.m
--- quantification.m 1999/12/22 03:31:24 1.70
+++ quantification.m 2000/02/07 01:49:02
@@ -41,6 +41,45 @@
:- import_module hlds_goal, hlds_pred, prog_data.
:- import_module map, list, set.
+ %
+ % When the compiler performs structure reuse, using
+ % the ordinary non-locals during code generation
+ % causes variables taken from the reused cell in
+ % a reconstruction to be extracted and possibly stored
+ % on the stack unnecessarily.
+ %
+ % For the example below, the variables `B' ... `H' are
+ % extracted from the term and stored on the stack across
+ % the call.
+ %
+ % To avoid this, the compiler computes a set of `code-gen non-locals'
+ % which are the same as the ordinary non-locals, except that the
+ % variables taken from the reused cell are considered to be local
+ % to the goal. No renaming is performed when computing
+ % the code-gen non-locals to avoid stuffing up the ordinary
+ % non-locals.
+ %
+ % Mode information is always computed using the ordinary non-locals.
+ %
+ % :- pred update(X::in, foo::di, foo::uo) is det.
+ % update(A0, Foo0, Foo) :-
+ % Foo0 = foo(_, B, C, D, E, F, G, H),
+ % some_call(A0, A),
+ % Foo0 = foo(A, B, C, D, E, F, G, H).
+ %
+:- type nonlocals_to_recompute
+ ---> ordinary_nonlocals
+ ; code_gen_nonlocals.
+
+:- pred implicitly_quantify_clause_body(nonlocals_to_recompute, list(prog_var),
+ hlds_goal, prog_varset, map(prog_var, type),
+ hlds_goal, prog_varset, map(prog_var, type),
+ list(quant_warning)).
+:- mode implicitly_quantify_clause_body(in, in, in, in, in, out, out, out, out)
+ is det.
+
+
+ % As above, with `ordinary_nonlocals' passed as the first argument.
:- pred implicitly_quantify_clause_body(list(prog_var),
hlds_goal, prog_varset, map(prog_var, type),
hlds_goal, prog_varset, map(prog_var, type),
@@ -48,11 +87,22 @@
:- mode implicitly_quantify_clause_body(in, in, in, in, out, out, out, out)
is det.
+:- pred implicitly_quantify_goal(nonlocals_to_recompute, hlds_goal, prog_varset,
+ map(prog_var, type), set(prog_var), hlds_goal, prog_varset,
+ map(prog_var, type), list(quant_warning)).
+:- mode implicitly_quantify_goal(in, in, in, in, in,
+ out, out, out, out) is det.
+
+ % As above, with `ordinary_nonlocals' passed as the first argument.
:- pred implicitly_quantify_goal(hlds_goal, prog_varset, map(prog_var, type),
- set(prog_var), hlds_goal, prog_varset, map(prog_var, type),
- list(quant_warning)).
+ set(prog_var), hlds_goal, prog_varset,
+ map(prog_var, type), list(quant_warning)).
:- mode implicitly_quantify_goal(in, in, in, in, out, out, out, out) is det.
+:- pred requantify_proc(nonlocals_to_recompute, proc_info, proc_info) is det.
+:- mode requantify_proc(in, in, out) is det.
+
+ % As above, with `ordinary_nonlocals' passed as the first argument.
:- pred requantify_proc(proc_info, proc_info) is det.
:- mode requantify_proc(in, out) is det.
@@ -66,6 +116,11 @@
% quantification__goal_vars(Goal, Vars):
% Vars is the set of variables that are free (unquantified)
% in Goal.
+:- pred quantification__goal_vars(nonlocals_to_recompute,
+ hlds_goal, set(prog_var)).
+:- mode quantification__goal_vars(in, in, out) is det.
+
+ % As above, with `ordinary_nonlocals' passed as the first argument.
:- pred quantification__goal_vars(hlds_goal, set(prog_var)).
:- mode quantification__goal_vars(in, out) is det.
@@ -84,16 +139,18 @@
% are threaded (i.e. both input and output).
% We use the convention that the input fields are callee save,
% and the outputs are caller save.
+ % The nonlocals_to_recompute field is constant.
:- type quant_info
---> quant_info(
- set(prog_var), % outside vars
- set(prog_var), % quant vars
- set(prog_var), % outside lambda vars
- set(prog_var), % nonlocals
- set(prog_var), % seen so far
- prog_varset,
- map(prog_var, type),
- list(quant_warning)
+ nonlocals_to_recompute :: nonlocals_to_recompute,
+ outside :: set(prog_var),
+ quant_vars :: set(prog_var),
+ lambda_outside :: set(prog_var),
+ nonlocals :: set(prog_var),
+ seen :: set(prog_var),
+ varset :: prog_varset,
+ vartypes :: vartypes,
+ warnings :: list(quant_warning)
).
% `OutsideVars' are the variables that have occurred free outside
@@ -127,24 +184,68 @@
implicitly_quantify_clause_body(HeadVars, Goal0, Varset0, VarTypes0,
Goal, Varset, VarTypes, Warnings) :-
+ implicitly_quantify_clause_body(ordinary_nonlocals,
+ HeadVars, Goal0, Varset0, VarTypes0,
+ Goal, Varset, VarTypes, Warnings).
+
+implicitly_quantify_clause_body(RecomputeNonLocals, HeadVars, Goal0,
+ Varset0, VarTypes0, Goal, Varset, VarTypes, Warnings) :-
set__list_to_set(HeadVars, OutsideVars),
- implicitly_quantify_goal(Goal0, Varset0, VarTypes0,
+ implicitly_quantify_goal(RecomputeNonLocals, Goal0, Varset0, VarTypes0,
OutsideVars, Goal, Varset, VarTypes, Warnings).
requantify_proc(ProcInfo0, ProcInfo) :-
+ requantify_proc(ordinary_nonlocals, ProcInfo0, ProcInfo).
+
+requantify_proc(RecomputeNonLocals, ProcInfo0, ProcInfo) :-
proc_info_varset(ProcInfo0, Varset0),
proc_info_vartypes(ProcInfo0, VarTypes0),
proc_info_headvars(ProcInfo0, HeadVars),
proc_info_goal(ProcInfo0, Goal0),
- implicitly_quantify_clause_body(HeadVars, Goal0, Varset0, VarTypes0,
- Goal, Varset, VarTypes, _),
+ implicitly_quantify_clause_body(RecomputeNonLocals, HeadVars,
+ Goal0, Varset0, VarTypes0, Goal, Varset, VarTypes, _),
proc_info_set_varset(ProcInfo0, Varset, ProcInfo1),
proc_info_set_vartypes(ProcInfo1, VarTypes, ProcInfo2),
proc_info_set_goal(ProcInfo2, Goal, ProcInfo).
implicitly_quantify_goal(Goal0, Varset0, VarTypes0, OutsideVars,
- Goal, Varset, VarTypes, Warnings) :-
- quantification__init(OutsideVars, Varset0, VarTypes0, QuantInfo0),
+ Goal, Varset, VarTypes, Warnings) :-
+ implicitly_quantify_goal(ordinary_nonlocals, Goal0, Varset0, VarTypes0,
+ OutsideVars, Goal, Varset, VarTypes, Warnings).
+
+implicitly_quantify_goal(RecomputeNonLocals, Goal0, Varset0, VarTypes0,
+ OutsideVars, Goal, Varset, VarTypes, Warnings) :-
+ implicitly_quantify_goal_2(ordinary_nonlocals,
+ Goal0, Varset0, VarTypes0, OutsideVars,
+ Goal1, Varset1, VarTypes1, Warnings),
+ (
+ RecomputeNonLocals = code_gen_nonlocals,
+
+ % If the goal does not contain a reconstruction,
+ % the code-gen nonlocals and the ordinary non-locals
+ % are the same.
+ goal_contains_reconstruction(Goal1)
+ ->
+ implicitly_quantify_goal_2(code_gen_nonlocals,
+ Goal1, Varset1, VarTypes1, OutsideVars,
+ Goal, Varset, VarTypes, _)
+ ;
+ Goal = Goal1,
+ Varset = Varset1,
+ VarTypes = VarTypes1
+ ).
+
+:- pred implicitly_quantify_goal_2(nonlocals_to_recompute, hlds_goal,
+ prog_varset, vartypes, set(prog_var), hlds_goal,
+ prog_varset, vartypes, list(quant_warning)).
+:- mode implicitly_quantify_goal_2(in, in, in, in, in,
+ out, out, out, out) is det.
+
+implicitly_quantify_goal_2(RecomputeNonLocals,
+ Goal0, Varset0, VarTypes0, OutsideVars,
+ Goal, Varset, VarTypes, Warnings) :-
+ quantification__init(RecomputeNonLocals, OutsideVars,
+ Varset0, VarTypes0, QuantInfo0),
implicitly_quantify_goal(Goal0, Goal, QuantInfo0, QuantInfo),
quantification__get_varset(Varset, QuantInfo, _),
quantification__get_vartypes(VarTypes, QuantInfo, _),
@@ -160,11 +261,13 @@
{ goal_info_get_context(GoalInfo0, Context) },
implicitly_quantify_goal_2(Goal0, Context, Goal1),
quantification__get_nonlocals(NonLocalVars),
+ quantification__get_nonlocals_to_recompute(NonLocalsToRecompute),
(
% If there are any variables that are local to the goal
% which we have come across before, then we rename them
% apart.
- { quantification__goal_vars(Goal0 - GoalInfo0, GoalVars0) },
+ { quantification__goal_vars(NonLocalsToRecompute,
+ Goal0 - GoalInfo0, GoalVars0) },
{ set__difference(GoalVars0, NonLocalVars, LocalVars) },
{ set__intersect(SeenVars, LocalVars, RenameVars) },
{ \+ set__empty(RenameVars) }
@@ -175,7 +278,7 @@
{ Goal = Goal1 },
{ GoalInfo1 = GoalInfo0 }
),
- { goal_info_set_nonlocals(GoalInfo1, NonLocalVars, GoalInfo2) },
+ quantification__set_goal_nonlocals(GoalInfo1, NonLocalVars, GoalInfo2),
%
% If the non-locals set has shrunk (e.g. because some optimization
% optimizes away the other occurrences of a variable, causing it
@@ -292,7 +395,9 @@
{ goal_util__rename_var_list(Vars0, no, RenameMap, Vars) }
),
{ set__insert_list(QuantVars, Vars, QuantVars1) },
- { quantification__goal_vars(Then1, VarsThen, LambdaVarsThen) },
+ quantification__get_nonlocals_to_recompute(NonLocalsToRecompute),
+ { quantification__goal_vars(NonLocalsToRecompute,
+ Then1, VarsThen, LambdaVarsThen) },
{ set__union(OutsideVars, VarsThen, OutsideVars1) },
{ set__union(LambdaOutsideVars, LambdaVarsThen, LambdaOutsideVars1) },
quantification__set_quant_vars(QuantVars1),
@@ -334,19 +439,25 @@
quantification__get_outside(OutsideVars),
quantification__get_lambda_outside(LambdaOutsideVars),
{ quantification__get_unify_typeinfos(Unification0, TypeInfoVars) },
- implicitly_quantify_unify_rhs(UnifyRHS0, Unification0, Context,
- UnifyRHS, Unification),
+
+ { Unification0 = construct(_, _, _, _, CellToReuse0, _, _) ->
+ CellToReuse = CellToReuse0
+ ;
+ CellToReuse = no
+ },
+
+ implicitly_quantify_unify_rhs(UnifyRHS0, CellToReuse,
+ Unification0, Context, UnifyRHS, Unification),
quantification__get_nonlocals(VarsUnifyRHS),
{ set__insert(VarsUnifyRHS, Var, GoalVars0) },
{ set__insert_list(GoalVars0, TypeInfoVars, GoalVars1) },
- {
- Unification = construct(_, _, _, _, CellToReuse, _, _),
- CellToReuse = yes(cell_to_reuse(ReuseVar, _, _))
- ->
+
+ { CellToReuse = yes(cell_to_reuse(ReuseVar, _, _)) ->
set__insert(GoalVars1, ReuseVar, GoalVars)
;
GoalVars = GoalVars1
},
+
quantification__update_seen_vars(GoalVars),
{ set__intersect(GoalVars, OutsideVars, NonLocalVars1) },
{ set__intersect(GoalVars, LambdaOutsideVars, NonLocalVars2) },
@@ -358,6 +469,7 @@
implicitly_quantify_atomic_goal(Vars).
implicitly_quantify_goal_2(bi_implication(LHS0, RHS0), Context, Goal) -->
+
% get the initial values of various settings
quantification__get_quant_vars(QuantVars0),
quantification__get_outside(OutsideVars0),
@@ -375,7 +487,9 @@
% prepare for quantifying the LHS:
% add variables from the RHS to the outside vars
% and the outside lambda vars sets.
- { quantification__goal_vars(RHS0, RHS_Vars, RHS_LambdaVars) },
+ quantification__get_nonlocals_to_recompute(NonLocalsToRecompute),
+ { quantification__goal_vars(NonLocalsToRecompute,
+ RHS0, RHS_Vars, RHS_LambdaVars) },
{ set__union(OutsideVars1, RHS_Vars, LHS_OutsideVars) },
{ set__union(LambdaOutsideVars1, RHS_LambdaVars,
LHS_LambdaOutsideVars) },
@@ -424,9 +538,11 @@
%
{ goal_info_init(GoalInfo0) },
{ goal_info_set_context(GoalInfo0, Context, GoalInfo1) },
- { goal_info_set_nonlocals(GoalInfo1, LHS_NonLocalVars, LHS_GI) },
- { goal_info_set_nonlocals(GoalInfo1, RHS_NonLocalVars, RHS_GI) },
- { goal_info_set_nonlocals(GoalInfo1, NonLocalVars, GI) },
+ quantification__set_goal_nonlocals(GoalInfo1,
+ LHS_NonLocalVars, LHS_GI),
+ quantification__set_goal_nonlocals(GoalInfo1,
+ RHS_NonLocalVars, RHS_GI),
+ quantification__set_goal_nonlocals(GoalInfo1, NonLocalVars, GI),
{ NotLHS = not(LHS) - LHS_GI },
{ NotRHS = not(RHS) - RHS_GI },
{ ForwardsImplication = not(conj([LHS, NotRHS]) - GI) - GI },
@@ -436,7 +552,8 @@
% we've just duplicated.
%
{ ReverseImplication0 = not(conj([RHS, NotLHS]) - GI) - GI },
- { quantification__goal_vars(ReverseImplication0, GoalVars) },
+ { quantification__goal_vars(NonLocalsToRecompute,
+ ReverseImplication0, GoalVars) },
{ set__difference(GoalVars, NonLocalVars, RenameVars) },
quantification__rename_apart(RenameVars, _,
ReverseImplication0, ReverseImplication),
@@ -456,22 +573,35 @@
{ set__union(NonLocals1, NonLocals2, NonLocals) },
quantification__set_nonlocals(NonLocals).
-:- pred implicitly_quantify_unify_rhs(unify_rhs, unification, prog_context,
- unify_rhs, unification,
- quant_info, quant_info).
-:- mode implicitly_quantify_unify_rhs(in, in, in, out, out, in, out) is det.
+:- pred implicitly_quantify_unify_rhs(unify_rhs, maybe(cell_to_reuse),
+ unification, prog_context, unify_rhs, unification,
+ quant_info, quant_info).
+:- mode implicitly_quantify_unify_rhs(in, in, in, in,
+ out, out, in, out) is det.
-implicitly_quantify_unify_rhs(var(X), Unification, _, var(X), Unification) -->
+implicitly_quantify_unify_rhs(var(X), _, Unification, _,
+ var(X), Unification) -->
{ set__singleton_set(Vars, X) },
quantification__set_nonlocals(Vars).
-implicitly_quantify_unify_rhs(functor(Functor, ArgVars), Unification, _,
+implicitly_quantify_unify_rhs(functor(Functor, ArgVars), Reuse, Unification, _,
functor(Functor, ArgVars), Unification) -->
- { set__list_to_set(ArgVars, Vars) },
+ quantification__get_nonlocals_to_recompute(NonLocalsToRecompute),
+ {
+ NonLocalsToRecompute = code_gen_nonlocals,
+ Reuse = yes(cell_to_reuse(_, _, SetArgs))
+ ->
+ % The fields taken from the reused cell aren't
+ % counted as code-gen nonlocals.
+ quantification__get_updated_fields(SetArgs, ArgVars, Vars0),
+ set__list_to_set(Vars0, Vars)
+ ;
+ set__list_to_set(ArgVars, Vars)
+ },
quantification__set_nonlocals(Vars).
implicitly_quantify_unify_rhs(
lambda_goal(PredOrFunc, EvalMethod, FixModes, LambdaNonLocals0,
LambdaVars0, Modes, Det, Goal0),
- Unification0,
+ _, Unification0,
Context,
lambda_goal(PredOrFunc, EvalMethod, FixModes, LambdaNonLocals,
LambdaVars, Modes, Det, Goal),
@@ -577,7 +707,8 @@
:- mode implicitly_quantify_conj(in, out, in, out) is det.
implicitly_quantify_conj(Goals0, Goals) -->
- { get_vars(Goals0, FollowingVarsList) },
+ quantification__get_nonlocals_to_recompute(NonLocalsToRecompute),
+ { get_vars(NonLocalsToRecompute, Goals0, FollowingVarsList) },
implicitly_quantify_conj_2(Goals0, FollowingVarsList, Goals).
:- pred implicitly_quantify_conj_2(list(hlds_goal), list(pair(set(prog_var))),
@@ -667,76 +798,100 @@
% contains following variables that occur not in lambda goals,
% and the second contains following variables that
% occur in lambda goals.
-
-:- pred get_vars(list(hlds_goal), list(pair(set(prog_var)))).
-:- mode get_vars(in, out) is det.
-get_vars([], []).
-get_vars([_Goal | Goals], [Set - LambdaSet | SetPairs]) :-
- get_vars_2(Goals, Set, LambdaSet, SetPairs).
-
-:- pred get_vars_2(list(hlds_goal), set(prog_var), set(prog_var),
+:- pred get_vars(nonlocals_to_recompute, list(hlds_goal),
list(pair(set(prog_var)))).
-:- mode get_vars_2(in, out, out, out) is det.
+:- mode get_vars(in, in, out) is det.
+
+get_vars(_, [], []).
+get_vars(NonLocalsToRecompute, [_Goal | Goals],
+ [Set - LambdaSet | SetPairs]) :-
+ get_vars_2(NonLocalsToRecompute, Goals, Set, LambdaSet, SetPairs).
+
+:- pred get_vars_2(nonlocals_to_recompute, list(hlds_goal),
+ set(prog_var), set(prog_var), list(pair(set(prog_var)))).
+:- mode get_vars_2(in, in, out, out, out) is det.
-get_vars_2([], Set, LambdaSet, []) :-
+get_vars_2(_, [], Set, LambdaSet, []) :-
set__init(Set),
set__init(LambdaSet).
-get_vars_2([Goal | Goals], Set, LambdaSet, SetPairList) :-
- get_vars_2(Goals, Set0, LambdaSet0, SetPairList0),
- quantification__goal_vars(Goal, Set1, LambdaSet1),
+get_vars_2(NonLocalsToRecompute, [Goal | Goals],
+ Set, LambdaSet, SetPairList) :-
+ get_vars_2(NonLocalsToRecompute, Goals,
+ Set0, LambdaSet0, SetPairList0),
+ quantification__goal_vars(NonLocalsToRecompute,
+ Goal, Set1, LambdaSet1),
set__union(Set0, Set1, Set),
set__union(LambdaSet0, LambdaSet1, LambdaSet),
SetPairList = [Set0 - LambdaSet0 | SetPairList0].
-
-:- pred goal_list_vars_2(list(hlds_goal), set(prog_var), set(prog_var),
- set(prog_var), set(prog_var)).
-:- mode goal_list_vars_2(in, in, in, out, out) is det.
-
-goal_list_vars_2([], Set, LambdaSet, Set, LambdaSet).
-goal_list_vars_2([Goal - _GoalInfo| Goals], Set0, LambdaSet0, Set, LambdaSet) :-
- quantification__goal_vars_2(Goal, Set0, LambdaSet0, Set1, LambdaSet1),
- goal_list_vars_2(Goals, Set1, LambdaSet1, Set, LambdaSet).
-
-:- pred case_list_vars_2(list(case), set(prog_var), set(prog_var),
- set(prog_var), set(prog_var)).
-:- mode case_list_vars_2(in, in, in, out, out) is det.
-case_list_vars_2([], Set, LambdaSet, Set, LambdaSet).
-case_list_vars_2([case(_Cons, Goal - _GoalInfo)| Cases], Set0, LambdaSet0,
- Set, LambdaSet) :-
- quantification__goal_vars_2(Goal, Set0, LambdaSet0, Set1, LambdaSet1),
- case_list_vars_2(Cases, Set1, LambdaSet1, Set, LambdaSet).
+:- pred goal_list_vars_2(nonlocals_to_recompute, list(hlds_goal),
+ set(prog_var), set(prog_var), set(prog_var), set(prog_var)).
+:- mode goal_list_vars_2(in, in, in, in, out, out) is det.
+
+goal_list_vars_2(_, [], Set, LambdaSet, Set, LambdaSet).
+goal_list_vars_2(NonLocalsToRecompute, [Goal - _GoalInfo| Goals],
+ Set0, LambdaSet0, Set, LambdaSet) :-
+ quantification__goal_vars_2(NonLocalsToRecompute,
+ Goal, Set0, LambdaSet0, Set1, LambdaSet1),
+ goal_list_vars_2(NonLocalsToRecompute, Goals,
+ Set1, LambdaSet1, Set, LambdaSet).
+
+:- pred case_list_vars_2(nonlocals_to_recompute, list(case),
+ set(prog_var), set(prog_var), set(prog_var), set(prog_var)).
+:- mode case_list_vars_2(in, in, in, in, out, out) is det.
+
+case_list_vars_2(_, [], Set, LambdaSet, Set, LambdaSet).
+case_list_vars_2(NonLocalsToRecompute,
+ [case(_Cons, Goal - _GoalInfo)| Cases], Set0,
+ LambdaSet0, Set, LambdaSet) :-
+ quantification__goal_vars_2(NonLocalsToRecompute,
+ Goal, Set0, LambdaSet0, Set1, LambdaSet1),
+ case_list_vars_2(NonLocalsToRecompute, Cases,
+ Set1, LambdaSet1, Set, LambdaSet).
- % quantification__goal_vars(Goal, Vars):
+ % quantification__goal_vars(NonLocalsToRecompute, Goal, Vars):
% Vars is the set of variables that occur free (unquantified)
- % in Goal.
-quantification__goal_vars(Goal, BothSet) :-
- quantification__goal_vars(Goal, NonLambdaSet, LambdaSet),
+ % in Goal, excluding unset fields of reconstructions if
+ % NonLocalsToRecompute is `code_gen_nonlocals'.
+quantification__goal_vars(NonLocalsToRecompute, Goal, BothSet) :-
+ quantification__goal_vars(NonLocalsToRecompute,
+ Goal, NonLambdaSet, LambdaSet),
set__union(NonLambdaSet, LambdaSet, BothSet).
+quantification__goal_vars(Goal, BothSet) :-
+ quantification__goal_vars(ordinary_nonlocals, Goal, BothSet).
+
% quantification__goal_vars(Goal, NonLambdaSet, LambdaSet):
% Set is the set of variables that occur free (unquantified)
% in Goal, not counting occurrences in lambda expressions.
% LambdaSet is the set of variables that occur free (unquantified)
% in lambda expressions in Goal.
-:- pred quantification__goal_vars(hlds_goal, set(prog_var), set(prog_var)).
-:- mode quantification__goal_vars(in, out, out) is det.
+:- pred quantification__goal_vars(nonlocals_to_recompute,
+ hlds_goal, set(prog_var), set(prog_var)).
+:- mode quantification__goal_vars(in, in, out, out) is det.
-quantification__goal_vars(Goal - _GoalInfo, Set, LambdaSet) :-
+quantification__goal_vars(NonLocalsToRecompute,
+ Goal - _GoalInfo, Set, LambdaSet) :-
set__init(Set0),
set__init(LambdaSet0),
- quantification__goal_vars_2(Goal, Set0, LambdaSet0, Set, LambdaSet).
+ quantification__goal_vars_2(NonLocalsToRecompute,
+ Goal, Set0, LambdaSet0, Set, LambdaSet).
-:- pred quantification__goal_vars_2(hlds_goal_expr, set(prog_var),
- set(prog_var), set(prog_var), set(prog_var)).
-:- mode quantification__goal_vars_2(in, in, in, out, out) is det.
+:- pred quantification__goal_vars_2(nonlocals_to_recompute, hlds_goal_expr,
+ set(prog_var), set(prog_var), set(prog_var), set(prog_var)).
+:- mode quantification__goal_vars_2(in, in, in, in, out, out) is det.
-quantification__goal_vars_2(unify(A, B, _, Unification, _), Set0, LambdaSet0,
+quantification__goal_vars_2(NonLocalsToRecompute,
+ unify(A, B, _, Unification, _), Set0, LambdaSet0,
Set, LambdaSet) :-
set__insert(Set0, A, Set1),
+ ( Unification = construct(_, _, _, _, Reuse0, _, _) ->
+ Reuse = Reuse0
+ ;
+ Reuse = no
+ ),
(
- Unification = construct(_, _, _, _, Reuse, _, _),
Reuse = yes(cell_to_reuse(ReuseVar, _, _))
->
set__insert(Set1, ReuseVar, Set2)
@@ -747,87 +902,148 @@
;
Set2 = Set1
),
- quantification__unify_rhs_vars(B, Set2, LambdaSet0, Set, LambdaSet).
+ quantification__unify_rhs_vars(NonLocalsToRecompute, B, Reuse,
+ Set2, LambdaSet0, Set, LambdaSet).
-quantification__goal_vars_2(generic_call(GenericCall, ArgVars1, _, _),
+quantification__goal_vars_2(_, generic_call(GenericCall, ArgVars1, _, _),
Set0, LambdaSet, Set, LambdaSet) :-
goal_util__generic_call_vars(GenericCall, ArgVars0),
set__insert_list(Set0, ArgVars0, Set1),
set__insert_list(Set1, ArgVars1, Set).
-quantification__goal_vars_2(call(_, _, ArgVars, _, _, _), Set0, LambdaSet,
+quantification__goal_vars_2(_, call(_, _, ArgVars, _, _, _), Set0, LambdaSet,
Set, LambdaSet) :-
set__insert_list(Set0, ArgVars, Set).
-
-quantification__goal_vars_2(conj(Goals), Set0, LambdaSet0, Set, LambdaSet) :-
- goal_list_vars_2(Goals, Set0, LambdaSet0, Set, LambdaSet).
-
-quantification__goal_vars_2(par_conj(Goals, _SM), Set0, LambdaSet0, Set, LambdaSet) :-
- goal_list_vars_2(Goals, Set0, LambdaSet0, Set, LambdaSet).
-quantification__goal_vars_2(disj(Goals, _), Set0, LambdaSet0, Set, LambdaSet) :-
- goal_list_vars_2(Goals, Set0, LambdaSet0, Set, LambdaSet).
+quantification__goal_vars_2(NonLocalsToRecompute, conj(Goals),
+ Set0, LambdaSet0, Set, LambdaSet) :-
+ goal_list_vars_2(NonLocalsToRecompute, Goals,
+ Set0, LambdaSet0, Set, LambdaSet).
+
+quantification__goal_vars_2(NonLocalsToRecompute, par_conj(Goals, _SM),
+ Set0, LambdaSet0, Set, LambdaSet) :-
+ goal_list_vars_2(NonLocalsToRecompute, Goals,
+ Set0, LambdaSet0, Set, LambdaSet).
+
+quantification__goal_vars_2(NonLocalsToRecompute, disj(Goals, _),
+ Set0, LambdaSet0, Set, LambdaSet) :-
+ goal_list_vars_2(NonLocalsToRecompute, Goals, Set0, LambdaSet0,
+ Set, LambdaSet).
-quantification__goal_vars_2(switch(Var, _Det, Cases, _), Set0, LambdaSet0,
- Set, LambdaSet) :-
+quantification__goal_vars_2(NonLocalsToRecompute, switch(Var, _Det, Cases, _),
+ Set0, LambdaSet0, Set, LambdaSet) :-
set__insert(Set0, Var, Set1),
- case_list_vars_2(Cases, Set1, LambdaSet0, Set, LambdaSet).
+ case_list_vars_2(NonLocalsToRecompute, Cases,
+ Set1, LambdaSet0, Set, LambdaSet).
-quantification__goal_vars_2(some(Vars, _, Goal), Set0, LambdaSet0,
- Set, LambdaSet) :-
- quantification__goal_vars(Goal, Set1, LambdaSet1),
+quantification__goal_vars_2(NonLocalsToRecompute, some(Vars, _, Goal),
+ Set0, LambdaSet0, Set, LambdaSet) :-
+ quantification__goal_vars(NonLocalsToRecompute,
+ Goal, Set1, LambdaSet1),
set__delete_list(Set1, Vars, Set2),
set__delete_list(LambdaSet1, Vars, LambdaSet2),
set__union(Set0, Set2, Set),
set__union(LambdaSet0, LambdaSet2, LambdaSet).
-quantification__goal_vars_2(not(Goal - _GoalInfo), Set0, LambdaSet0,
- Set, LambdaSet) :-
- quantification__goal_vars_2(Goal, Set0, LambdaSet0, Set, LambdaSet).
-
-quantification__goal_vars_2(if_then_else(Vars, A, B, C, _), Set0, LambdaSet0,
- Set, LambdaSet) :-
+quantification__goal_vars_2(NonLocalsToRecompute, not(Goal - _GoalInfo),
+ Set0, LambdaSet0, Set, LambdaSet) :-
+ quantification__goal_vars_2(NonLocalsToRecompute, Goal,
+ Set0, LambdaSet0, Set, LambdaSet).
+
+quantification__goal_vars_2(NonLocalsToRecompute,
+ if_then_else(Vars, A, B, C, _),
+ Set0, LambdaSet0, Set, LambdaSet) :-
% This code does the following:
% Set = Set0 + ( (vars(A) + vars(B)) \ Vars ) + vars(C)
% where `+' is set union and `\' is relative complement.
- quantification__goal_vars(A, Set1, LambdaSet1),
- quantification__goal_vars(B, Set2, LambdaSet2),
+ quantification__goal_vars(NonLocalsToRecompute, A, Set1, LambdaSet1),
+ quantification__goal_vars(NonLocalsToRecompute, B, Set2, LambdaSet2),
set__union(Set1, Set2, Set3),
set__union(LambdaSet1, LambdaSet2, LambdaSet3),
set__delete_list(Set3, Vars, Set4),
set__delete_list(LambdaSet3, Vars, LambdaSet4),
set__union(Set0, Set4, Set5),
set__union(LambdaSet0, LambdaSet4, LambdaSet5),
- quantification__goal_vars(C, Set6, LambdaSet6),
+ quantification__goal_vars(NonLocalsToRecompute, C, Set6, LambdaSet6),
set__union(Set5, Set6, Set),
set__union(LambdaSet5, LambdaSet6, LambdaSet).
-quantification__goal_vars_2(pragma_c_code(_, _, _, ArgVars, _, _, _),
+quantification__goal_vars_2(_, pragma_c_code(_, _, _, ArgVars, _, _, _),
Set0, LambdaSet, Set, LambdaSet) :-
set__insert_list(Set0, ArgVars, Set).
+
+quantification__goal_vars_2(NonLocalsToRecompute, bi_implication(LHS, RHS),
+ Set0, LambdaSet0, Set, LambdaSet) :-
+ goal_list_vars_2(NonLocalsToRecompute, [LHS, RHS],
+ Set0, LambdaSet0, Set, LambdaSet).
-quantification__goal_vars_2(bi_implication(LHS, RHS), Set0, LambdaSet0, Set,
- LambdaSet) :-
- goal_list_vars_2([LHS, RHS], Set0, LambdaSet0, Set, LambdaSet).
-
-:- pred quantification__unify_rhs_vars(unify_rhs, set(prog_var), set(prog_var),
- set(prog_var), set(prog_var)).
-:- mode quantification__unify_rhs_vars(in, in, in, out, out) is det.
+:- pred quantification__unify_rhs_vars(nonlocals_to_recompute, unify_rhs,
+ maybe(cell_to_reuse), set(prog_var), set(prog_var),
+ set(prog_var), set(prog_var)).
+:- mode quantification__unify_rhs_vars(in, in, in, in, in, out, out) is det.
-quantification__unify_rhs_vars(var(X), Set0, LambdaSet, Set, LambdaSet) :-
+quantification__unify_rhs_vars(_, var(X), _,
+ Set0, LambdaSet, Set, LambdaSet) :-
set__insert(Set0, X, Set).
-quantification__unify_rhs_vars(functor(_Functor, ArgVars), Set0, LambdaSet,
- Set, LambdaSet) :-
- set__insert_list(Set0, ArgVars, Set).
-quantification__unify_rhs_vars(
+quantification__unify_rhs_vars(NonLocalsToRecompute,
+ functor(_Functor, ArgVars), Reuse,
+ Set0, LambdaSet, Set, LambdaSet) :-
+ (
+ NonLocalsToRecompute = code_gen_nonlocals,
+ Reuse = yes(cell_to_reuse(_, _, SetArgs))
+ ->
+ % Ignore the fields taken from the reused cell.
+ quantification__get_updated_fields(SetArgs, ArgVars,
+ ArgsToSet),
+ set__insert_list(Set0, ArgsToSet, Set)
+ ;
+ set__insert_list(Set0, ArgVars, Set)
+ ).
+quantification__unify_rhs_vars(NonLocalsToRecompute,
lambda_goal(_POrF, _E, _F, _N, LambdaVars, _M, _D, Goal),
- Set, LambdaSet0, Set, LambdaSet) :-
+ _, Set, LambdaSet0, Set, LambdaSet) :-
% Note that the NonLocals list is not counted, since all the
% variables in that list must occur in the goal.
- quantification__goal_vars(Goal, GoalVars),
+ quantification__goal_vars(NonLocalsToRecompute, Goal, GoalVars),
set__delete_list(GoalVars, LambdaVars, GoalVars1),
set__union(LambdaSet0, GoalVars1, LambdaSet).
+:- pred quantification__insert_set_fields(list(bool), list(prog_var),
+ set(prog_var), set(prog_var)).
+:- mode quantification__insert_set_fields(in, in, in, out) is det.
+
+quantification__insert_set_fields(SetArgs, Args, Set0, Set) :-
+ quantification__get_updated_fields(SetArgs, Args, ArgsToSet),
+ set__insert_list(Set0, ArgsToSet, Set).
+
+:- pred quantification__get_updated_fields(list(bool),
+ list(prog_var), list(prog_var)).
+:- mode quantification__get_updated_fields(in, in, out) is det.
+
+quantification__get_updated_fields(SetArgs, Args, ArgsToSet) :-
+ quantification__get_updated_fields(SetArgs, Args, [], ArgsToSet).
+
+:- pred quantification__get_updated_fields(list(bool),
+ list(prog_var), list(prog_var), list(prog_var)).
+:- mode quantification__get_updated_fields(in, in, in, out) is det.
+
+quantification__get_updated_fields([], [], Fields, Fields).
+quantification__get_updated_fields([], [_|_], _, _) :-
+ error("quantification__get_updated_fields").
+quantification__get_updated_fields([_|_], [], _, _) :-
+ error("quantification__get_updated_fields").
+quantification__get_updated_fields([SetArg | SetArgs], [Arg | Args],
+ ArgsToSet0, ArgsToSet) :-
+ (
+ SetArg = yes,
+ ArgsToSet1 = [Arg | ArgsToSet0]
+ ;
+ SetArg = no,
+ ArgsToSet1 = ArgsToSet0
+ ),
+ quantification__get_updated_fields(SetArgs, Args,
+ ArgsToSet1, ArgsToSet).
+
:- pred quantification__get_unify_typeinfos(unification, list(prog_var)).
:- mode quantification__get_unify_typeinfos(in, out) is det.
@@ -862,7 +1078,21 @@
:- mode quantification__rename_apart(in, out, in, out, in, out) is det.
quantification__rename_apart(RenameSet, RenameMap, Goal0, Goal) -->
- ( { set__empty(RenameSet) } ->
+ quantification__get_nonlocals_to_recompute(NonLocalsToRecompute),
+ (
+ %
+ % Don't rename apart variables when recomputing the
+ % code-gen nonlocals -- that would stuff up the
+ % ordinary non-locals and the mode information.
+ % The ordinary non-locals are always recomputed
+ % before the code-gen nonlocals -- any necessary
+ % renaming will have been done while recomputing
+ % the ordinary non-locals.
+ %
+ { set__empty(RenameSet)
+ ; NonLocalsToRecompute = code_gen_nonlocals
+ }
+ ->
{ map__init(RenameMap) },
{ Goal = Goal0 }
;
@@ -890,129 +1120,133 @@
).
%-----------------------------------------------------------------------------%
+
+:- pred quantification__set_goal_nonlocals(hlds_goal_info,
+ set(prog_var), hlds_goal_info, quant_info, quant_info).
+:- mode quantification__set_goal_nonlocals(in, in, out, in, out) is det.
+
+quantification__set_goal_nonlocals(GoalInfo0, NonLocals, GoalInfo) -->
+ quantification__get_nonlocals_to_recompute(NonLocalsToRecompute),
+ {
+ NonLocalsToRecompute = ordinary_nonlocals,
+ goal_info_set_nonlocals(GoalInfo0, NonLocals, GoalInfo)
+ ;
+ NonLocalsToRecompute = code_gen_nonlocals,
+ goal_info_set_code_gen_nonlocals(GoalInfo0,
+ NonLocals, GoalInfo)
+ }.
+
+%-----------------------------------------------------------------------------%
-:- pred quantification__init(set(prog_var), prog_varset, map(prog_var, type),
- quant_info).
-:- mode quantification__init(in, in, in, out) is det.
+%-----------------------------------------------------------------------------%
+
+:- pred quantification__init(nonlocals_to_recompute, set(prog_var),
+ prog_varset, map(prog_var, type), quant_info).
+:- mode quantification__init(in, in, in, in, out) is det.
-quantification__init(OutsideVars, Varset, VarTypes, QuantInfo) :-
+quantification__init(RecomputeNonLocals, OutsideVars,
+ Varset, VarTypes, QuantInfo) :-
set__init(QuantVars),
set__init(NonLocals),
set__init(LambdaOutsideVars),
Seen = OutsideVars,
OverlapWarnings = [],
- QuantInfo = quant_info(OutsideVars, QuantVars, LambdaOutsideVars,
- NonLocals, Seen, Varset, VarTypes, OverlapWarnings).
+ QuantInfo = quant_info(RecomputeNonLocals, OutsideVars, QuantVars,
+ LambdaOutsideVars, NonLocals, Seen, Varset, VarTypes,
+ OverlapWarnings).
+
+:- pred quantification__get_nonlocals_to_recompute(nonlocals_to_recompute,
+ quant_info, quant_info).
+:- mode quantification__get_nonlocals_to_recompute(out, in, out) is det.
+
+quantification__get_nonlocals_to_recompute(Q ^ nonlocals_to_recompute, Q, Q).
:- pred quantification__get_outside(set(prog_var), quant_info, quant_info).
:- mode quantification__get_outside(out, in, out) is det.
-quantification__get_outside(A, Q, Q) :-
- Q = quant_info(A, _, _, _, _, _, _, _).
+quantification__get_outside(Q ^ outside, Q, Q).
:- pred quantification__set_outside(set(prog_var), quant_info, quant_info).
:- mode quantification__set_outside(in, in, out) is det.
-quantification__set_outside(A, Q0, Q) :-
- Q0 = quant_info(_, B, C, D, E, F, G, H),
- Q = quant_info(A, B, C, D, E, F, G, H).
+quantification__set_outside(Outside, Q0, Q0 ^ outside := Outside).
:- pred quantification__get_quant_vars(set(prog_var), quant_info, quant_info).
:- mode quantification__get_quant_vars(out, in, out) is det.
-quantification__get_quant_vars(B, Q, Q) :-
- Q = quant_info(_, B, _, _, _, _, _, _).
+quantification__get_quant_vars(Q ^ quant_vars, Q, Q).
:- pred quantification__set_quant_vars(set(prog_var), quant_info, quant_info).
:- mode quantification__set_quant_vars(in, in, out) is det.
-quantification__set_quant_vars(B, Q0, Q) :-
- Q0 = quant_info(A, _, C, D, E, F, G, H),
- Q = quant_info(A, B, C, D, E, F, G, H).
+quantification__set_quant_vars(QuantVars, Q0, Q0 ^ quant_vars := QuantVars).
:- pred quantification__get_lambda_outside(set(prog_var),
quant_info, quant_info).
:- mode quantification__get_lambda_outside(out, in, out) is det.
-quantification__get_lambda_outside(C, Q, Q) :-
- Q = quant_info(_, _, C, _, _, _, _, _).
+quantification__get_lambda_outside(Q ^ lambda_outside, Q, Q).
:- pred quantification__set_lambda_outside(set(prog_var),
quant_info, quant_info).
:- mode quantification__set_lambda_outside(in, in, out) is det.
-quantification__set_lambda_outside(C, Q0, Q) :-
- Q0 = quant_info(A, B, _, D, E, F, G, H),
- Q = quant_info(A, B, C, D, E, F, G, H).
+quantification__set_lambda_outside(LambdaOutsideVars, Q0,
+ Q0 ^ lambda_outside := LambdaOutsideVars).
:- pred quantification__get_nonlocals(set(prog_var), quant_info, quant_info).
:- mode quantification__get_nonlocals(out, in, out) is det.
-quantification__get_nonlocals(D, Q, Q) :-
- Q = quant_info(_, _, _, D, _, _, _, _).
+quantification__get_nonlocals(Q ^ nonlocals, Q, Q).
:- pred quantification__set_nonlocals(set(prog_var), quant_info, quant_info).
:- mode quantification__set_nonlocals(in, in, out) is det.
-quantification__set_nonlocals(D, Q0, Q) :-
- Q0 = quant_info(A, B, C, _, E, F, G, H),
- Q = quant_info(A, B, C, D, E, F, G, H).
+quantification__set_nonlocals(NonLocals, Q0, Q0 ^ nonlocals := NonLocals).
:- pred quantification__get_seen(set(prog_var), quant_info, quant_info).
:- mode quantification__get_seen(out, in, out) is det.
-quantification__get_seen(E, Q, Q) :-
- Q = quant_info(_, _, _, _, E, _, _, _).
+quantification__get_seen(Q ^ seen, Q, Q).
:- pred quantification__set_seen(set(prog_var), quant_info, quant_info).
:- mode quantification__set_seen(in, in, out) is det.
-quantification__set_seen(E, Q0, Q) :-
- Q0 = quant_info(A, B, C, D, _, F, G, H),
- Q = quant_info(A, B, C, D, E, F, G, H).
+quantification__set_seen(Seen, Q0, Q0 ^ seen := Seen).
:- pred quantification__get_varset(prog_varset, quant_info, quant_info).
:- mode quantification__get_varset(out, in, out) is det.
-quantification__get_varset(F, Q, Q) :-
- Q = quant_info(_, _, _, _, _, F, _, _).
+quantification__get_varset(Q ^ varset, Q, Q).
:- pred quantification__set_varset(prog_varset, quant_info, quant_info).
:- mode quantification__set_varset(in, in, out) is det.
-quantification__set_varset(F, Q0, Q) :-
- Q0 = quant_info(A, B, C, D, E, _, G, H),
- Q = quant_info(A, B, C, D, E, F, G, H).
+quantification__set_varset(Varset, Q0, Q0 ^ varset := Varset).
:- pred quantification__get_vartypes(map(prog_var, type),
quant_info, quant_info).
:- mode quantification__get_vartypes(out, in, out) is det.
-quantification__get_vartypes(G, Q, Q) :-
- Q = quant_info(_, _, _, _, _, _, G, _).
+quantification__get_vartypes(Q ^ vartypes, Q, Q).
:- pred quantification__set_vartypes(map(prog_var, type),
quant_info, quant_info).
:- mode quantification__set_vartypes(in, in, out) is det.
-quantification__set_vartypes(G, Q0, Q) :-
- Q0 = quant_info(A, B, C, D, E, F, _, H),
- Q = quant_info(A, B, C, D, E, F, G, H).
+quantification__set_vartypes(VarTypes, Q0, Q0 ^ vartypes := VarTypes).
:- pred quantification__get_warnings(list(quant_warning),
quant_info, quant_info).
:- mode quantification__get_warnings(out, in, out) is det.
-quantification__get_warnings(H, Q, Q) :-
- Q = quant_info(_, _, _, _, _, _, _, H).
+quantification__get_warnings(Q ^ warnings, Q, Q).
:- pred quantification__set_warnings(list(quant_warning),
quant_info, quant_info).
:- mode quantification__set_warnings(in, in, out) is det.
-quantification__set_warnings(H, Q0, Q) :-
- Q0 = quant_info(A, B, C, D, E, F, G, _),
- Q = quant_info(A, B, C, D, E, F, G, H).
+quantification__set_warnings(Warnings, Q0, Q0 ^ warnings := Warnings).
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
--------------------------------------------------------------------------
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