[m-dev.] for review: clarifying cse_detection.m
Zoltan Somogyi
zs at cs.mu.OZ.AU
Mon Dec 4 16:45:54 AEDT 2000
For review by Fergus or Simon.
compiler/cse_detection.m:
Make the code for finding common subexpressions significantly clearer
by using a single type for each possible state of the search, instead
of dividing the state between a maybe and a bool.
Instead of passing around several data structures separately,
wrap them up in a cse_info data structure.
Extend the cse_info data structure with fields that will be required
to fix common subexpression elimination over existentially typed
functors.
Switch to using predmode declarations when appropriate.
compiler/switch_detection.m:
Remove some redundancy from a comment.
Zoltan.
cvs diff: Diffing .
Index: cse_detection.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/cse_detection.m,v
retrieving revision 1.65
diff -u -b -r1.65 cse_detection.m
--- cse_detection.m 2000/11/17 17:46:59 1.65
+++ cse_detection.m 2000/12/04 05:36:16
@@ -20,13 +20,12 @@
:- import_module hlds_module, hlds_pred, io.
-:- pred detect_cse(module_info, module_info, io__state, io__state).
-:- mode detect_cse(in, out, di, uo) is det.
+:- pred detect_cse(module_info::in, module_info::out,
+ io__state::di, io__state::uo) is det.
-:- pred detect_cse_in_proc(proc_id, pred_id, module_info, module_info,
- io__state, io__state).
-% :- mode detect_cse_in_proc(in, in, di, uo, di, uo) is det.
-:- mode detect_cse_in_proc(in, in, in, out, di, uo) is det.
+:- pred detect_cse_in_proc(proc_id::in, pred_id::in,
+ module_info::in, module_info::out, io__state::di, io__state::uo)
+ is det.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -49,9 +48,9 @@
{ module_info_predids(ModuleInfo0, PredIds) },
detect_cse_in_preds(PredIds, ModuleInfo0, ModuleInfo).
-:- pred detect_cse_in_preds(list(pred_id), module_info, module_info,
- io__state, io__state).
-:- mode detect_cse_in_preds(in, in, out, di, uo) is det.
+:- pred detect_cse_in_preds(list(pred_id)::in,
+ module_info::in, module_info::out, io__state::di, io__state::uo)
+ is det.
detect_cse_in_preds([], ModuleInfo, ModuleInfo) --> [].
detect_cse_in_preds([PredId | PredIds], ModuleInfo0, ModuleInfo) -->
@@ -60,18 +59,17 @@
detect_cse_in_pred(PredId, PredInfo, ModuleInfo0, ModuleInfo1),
detect_cse_in_preds(PredIds, ModuleInfo1, ModuleInfo).
-:- pred detect_cse_in_pred(pred_id, pred_info, module_info, module_info,
- io__state, io__state).
-:- mode detect_cse_in_pred(in, in, in, out, di, uo) is det.
+:- pred detect_cse_in_pred(pred_id::in, pred_info::in,
+ module_info::in, module_info::out, io__state::di, io__state::uo)
+ is det.
detect_cse_in_pred(PredId, PredInfo0, ModuleInfo0, ModuleInfo) -->
{ pred_info_non_imported_procids(PredInfo0, ProcIds) },
detect_cse_in_procs(ProcIds, PredId, ModuleInfo0, ModuleInfo).
-:- pred detect_cse_in_procs(list(proc_id), pred_id, module_info, module_info,
- io__state, io__state).
-% :- mode detect_cse_in_procs(in, in, di, uo, di, uo) is det.
-:- mode detect_cse_in_procs(in, in, in, out, di, uo) is det.
+:- pred detect_cse_in_procs(list(proc_id)::in, pred_id::in,
+ module_info::in, module_info::out, io__state::di, io__state::uo)
+ is det.
detect_cse_in_procs([], _PredId, ModuleInfo, ModuleInfo) --> [].
detect_cse_in_procs([ProcId | ProcIds], PredId, ModuleInfo0, ModuleInfo) -->
@@ -120,11 +118,16 @@
).
:- type cse_info
- ---> cse_info(prog_varset, map(prog_var, type), module_info).
+ ---> cse_info(
+ varset :: prog_varset,
+ vartypes :: vartypes,
+ type_info_varmap :: type_info_varmap,
+ typeclass_info_varmap :: typeclass_info_varmap,
+ module_info :: module_info
+ ).
-:- pred detect_cse_in_proc_2(proc_id, pred_id, bool, module_info, module_info).
-% :- mode detect_cse_in_proc_2(in, in, out, di, uo) is det.
-:- mode detect_cse_in_proc_2(in, in, out, in, out) is det.
+:- pred detect_cse_in_proc_2(proc_id::in, pred_id::in, bool::out,
+ module_info::in, module_info::out) is det.
detect_cse_in_proc_2(ProcId, PredId, Redo, ModuleInfo0, ModuleInfo) :-
module_info_preds(ModuleInfo0, PredTable0),
@@ -140,7 +143,10 @@
proc_info_get_initial_instmap(ProcInfo0, ModuleInfo0, InstMap0),
proc_info_varset(ProcInfo0, Varset0),
proc_info_vartypes(ProcInfo0, VarTypes0),
- CseInfo0 = cse_info(Varset0, VarTypes0, ModuleInfo0),
+ proc_info_typeinfo_varmap(ProcInfo0, TypeInfoVarMap0),
+ proc_info_typeclass_info_varmap(ProcInfo0, TypeClassInfoVarMap0),
+ CseInfo0 = cse_info(Varset0, VarTypes0,
+ TypeInfoVarMap0, TypeClassInfoVarMap0, ModuleInfo0),
detect_cse_in_goal(Goal0, InstMap0, CseInfo0, CseInfo, Redo, Goal1),
(
@@ -150,15 +156,20 @@
Redo = yes,
% ModuleInfo should not be changed by detect_cse_in_goal
- CseInfo = cse_info(Varset1, VarTypes1, _),
+ CseInfo = cse_info(VarSet1, VarTypes1,
+ TypeInfoVarMap, TypeClassInfoVarMap, _),
proc_info_headvars(ProcInfo0, HeadVars),
- implicitly_quantify_clause_body(HeadVars, Goal1, Varset1,
- VarTypes1, Goal, Varset, VarTypes, _Warnings),
+ implicitly_quantify_clause_body(HeadVars, Goal1, VarSet1,
+ VarTypes1, Goal, VarSet, VarTypes, _Warnings),
proc_info_set_goal(ProcInfo0, Goal, ProcInfo1),
- proc_info_set_varset(ProcInfo1, Varset, ProcInfo2),
- proc_info_set_vartypes(ProcInfo2, VarTypes, ProcInfo),
+ proc_info_set_varset(ProcInfo1, VarSet, ProcInfo2),
+ proc_info_set_vartypes(ProcInfo2, VarTypes, ProcInfo3),
+ proc_info_set_typeinfo_varmap(ProcInfo3,
+ TypeInfoVarMap, ProcInfo4),
+ proc_info_set_typeclass_info_varmap(ProcInfo4,
+ TypeClassInfoVarMap, ProcInfo),
map__det_update(ProcTable0, ProcId, ProcInfo, ProcTable),
pred_info_set_procedures(PredInfo0, ProcTable, PredInfo),
@@ -173,9 +184,8 @@
% and hoist these out of the disjunction. At the moment
% we only look for cses that are deconstruction unifications.
-:- pred detect_cse_in_goal(hlds_goal, instmap, cse_info, cse_info,
- bool, hlds_goal).
-:- mode detect_cse_in_goal(in, in, in, out, out, out) is det.
+:- pred detect_cse_in_goal(hlds_goal::in, instmap::in, cse_info::in,
+ cse_info::out, bool::out, hlds_goal::out) is det.
detect_cse_in_goal(Goal0, InstMap0, CseInfo0, CseInfo, Redo, Goal) :-
detect_cse_in_goal_1(Goal0, InstMap0, CseInfo0, CseInfo,
@@ -186,9 +196,8 @@
% computed by applying the instmap delta specified in the
% goal's goalinfo.
-:- pred detect_cse_in_goal_1(hlds_goal, instmap, cse_info, cse_info, bool,
- hlds_goal, instmap).
-:- mode detect_cse_in_goal_1(in, in, in, out, out, out, out) is det.
+:- pred detect_cse_in_goal_1(hlds_goal::in, instmap::in, cse_info::in,
+ cse_info::out, bool::out, hlds_goal::out, instmap::out) is det.
detect_cse_in_goal_1(Goal0 - GoalInfo, InstMap0, CseInfo0, CseInfo, Redo,
Goal - GoalInfo, InstMap) :-
@@ -199,9 +208,9 @@
% Here we process each of the different sorts of goals.
-:- pred detect_cse_in_goal_2(hlds_goal_expr, hlds_goal_info, instmap,
- cse_info, cse_info, bool, hlds_goal_expr).
-:- mode detect_cse_in_goal_2(in, in, in, in, out, out, out) is det.
+:- pred detect_cse_in_goal_2(hlds_goal_expr::in, hlds_goal_info::in,
+ instmap::in, cse_info::in, cse_info::out, bool::out,
+ hlds_goal_expr::out) is det.
detect_cse_in_goal_2(pragma_foreign_code(A,B,C,D,E,F,G), _, _, CseInfo,
CseInfo, no, pragma_foreign_code(A,B,C,D,E,F,G)).
@@ -218,7 +227,7 @@
B0 = lambda_goal(PredOrFunc, EvalMethod, FixModes,
NonLocalVars, Vars, Modes, Det, Goal0)
->
- CseInfo0 = cse_info(_, _, ModuleInfo),
+ ModuleInfo = CseInfo0 ^ module_info,
instmap__pre_lambda_update(ModuleInfo,
Vars, Modes, InstMap0, InstMap),
detect_cse_in_goal(Goal0, InstMap, CseInfo0, CseInfo, Redo,
@@ -245,7 +254,8 @@
detect_cse_in_goal_2(par_conj(Goals0, SM), _, InstMap, CseInfo0, CseInfo, Redo,
par_conj(Goals, SM)) :-
- detect_cse_in_par_conj(Goals0, InstMap, CseInfo0, CseInfo, Redo, Goals).
+ detect_cse_in_par_conj(Goals0, InstMap, CseInfo0, CseInfo,
+ Redo, Goals).
detect_cse_in_goal_2(disj(Goals0, SM), GoalInfo, InstMap, CseInfo0, CseInfo,
Redo, Goal) :-
@@ -280,9 +290,8 @@
%-----------------------------------------------------------------------------%
-:- pred detect_cse_in_conj(list(hlds_goal), instmap, cse_info, cse_info,
- bool, list(hlds_goal)).
-:- mode detect_cse_in_conj(in, in, in, out, out, out) is det.
+:- pred detect_cse_in_conj(list(hlds_goal)::in, instmap::in, cse_info::in,
+ cse_info::out, bool::out, list(hlds_goal)::out) is det.
detect_cse_in_conj([], _InstMap, CseInfo, CseInfo, no, []).
detect_cse_in_conj([Goal0 | Goals0], InstMap0, CseInfo0, CseInfo,
@@ -299,9 +308,8 @@
%-----------------------------------------------------------------------------%
-:- pred detect_cse_in_par_conj(list(hlds_goal), instmap, cse_info, cse_info,
- bool, list(hlds_goal)).
-:- mode detect_cse_in_par_conj(in, in, in, out, out, out) is det.
+:- pred detect_cse_in_par_conj(list(hlds_goal)::in, instmap::in, cse_info::in,
+ cse_info::out, bool::out, list(hlds_goal)::out) is det.
detect_cse_in_par_conj([], _InstMap, CseInfo, CseInfo, no, []).
detect_cse_in_par_conj([Goal0 | Goals0], InstMap0, CseInfo0, CseInfo,
@@ -318,9 +326,9 @@
% structure. Now for each non-local variable, we check whether each
% branch matches that variable against the same functor.
-:- pred detect_cse_in_disj(list(prog_var), list(hlds_goal), hlds_goal_info,
- store_map, instmap, cse_info, cse_info, bool, hlds_goal_expr).
-:- mode detect_cse_in_disj(in, in, in, in, in, in, out, out, out) is det.
+:- pred detect_cse_in_disj(list(prog_var)::in, list(hlds_goal)::in,
+ hlds_goal_info::in, store_map::in, instmap::in, cse_info::in,
+ cse_info::out, bool::out, hlds_goal_expr::out) is det.
detect_cse_in_disj([], Goals0, _, SM, InstMap, CseInfo0, CseInfo,
Redo, disj(Goals, SM)) :-
@@ -329,7 +337,7 @@
CseInfo0, CseInfo, Redo, Goal) :-
(
instmap__lookup_var(InstMap, Var, VarInst0),
- CseInfo0 = cse_info(_, _, ModuleInfo),
+ ModuleInfo = CseInfo0 ^ module_info,
% XXX we only need inst_is_bound, but leave this as it is
% until mode analysis can handle aliasing between free
% variables.
@@ -345,22 +353,20 @@
CseInfo0, CseInfo, Redo, Goal)
).
-:- pred detect_cse_in_disj_2(list(hlds_goal), instmap, cse_info, cse_info,
- bool, list(hlds_goal)).
-:- mode detect_cse_in_disj_2(in, in, in, out, out, out) is det.
+:- pred detect_cse_in_disj_2(list(hlds_goal)::in, instmap::in, cse_info::in,
+ cse_info::out, bool::out, list(hlds_goal)::out) is det.
detect_cse_in_disj_2([], _InstMap, CseInfo, CseInfo, no, []).
detect_cse_in_disj_2([Goal0 | Goals0], InstMap0, CseInfo0, CseInfo, Redo,
[Goal | Goals]) :-
detect_cse_in_goal(Goal0, InstMap0, CseInfo0, CseInfo1, Redo1, Goal),
- detect_cse_in_disj_2(Goals0, InstMap0, CseInfo1, CseInfo, Redo2, Goals),
+ detect_cse_in_disj_2(Goals0, InstMap0, CseInfo1, CseInfo,
+ Redo2, Goals),
bool__or(Redo1, Redo2, Redo).
-:- pred detect_cse_in_cases(list(prog_var), prog_var, can_fail, list(case),
- hlds_goal_info, store_map, instmap, cse_info, cse_info, bool,
- hlds_goal_expr).
-:- mode detect_cse_in_cases(in, in, in, in, in, in, in, in, out, out, out)
- is det.
+:- pred detect_cse_in_cases(list(prog_var)::in, prog_var::in, can_fail::in,
+ list(case)::in, hlds_goal_info::in, store_map::in, instmap::in,
+ cse_info::in, cse_info::out, bool::out, hlds_goal_expr::out) is det.
detect_cse_in_cases([], SwitchVar, CanFail, Cases0, _GoalInfo, SM, InstMap,
CseInfo0, CseInfo, Redo,
@@ -371,7 +377,7 @@
(
Var \= SwitchVar,
instmap__lookup_var(InstMap, Var, VarInst0),
- CseInfo0 = cse_info(_, _, ModuleInfo),
+ ModuleInfo = CseInfo0 ^ module_info,
% XXX we only need inst_is_bound, but leave this as it is
% until mode analysis can handle aliasing between free
% variables.
@@ -388,9 +394,8 @@
SM, InstMap, CseInfo0, CseInfo, Redo, Goal)
).
-:- pred detect_cse_in_cases_2(list(case), instmap, cse_info, cse_info,
- bool, list(case)).
-:- mode detect_cse_in_cases_2(in, in, in, out, out, out) is det.
+:- pred detect_cse_in_cases_2(list(case)::in, instmap::in, cse_info::in,
+ cse_info::out, bool::out, list(case)::out) is det.
detect_cse_in_cases_2([], _, CseInfo, CseInfo, no, []).
detect_cse_in_cases_2([Case0 | Cases0], InstMap, CseInfo0, CseInfo, Redo,
@@ -398,14 +403,14 @@
Case0 = case(Functor, Goal0),
detect_cse_in_goal(Goal0, InstMap, CseInfo0, CseInfo1, Redo1, Goal),
Case = case(Functor, Goal),
- detect_cse_in_cases_2(Cases0, InstMap, CseInfo1, CseInfo, Redo2, Cases),
+ detect_cse_in_cases_2(Cases0, InstMap, CseInfo1, CseInfo,
+ Redo2, Cases),
bool__or(Redo1, Redo2, Redo).
-:- pred detect_cse_in_ite(list(prog_var), list(prog_var),
- hlds_goal, hlds_goal, hlds_goal, hlds_goal_info,
- store_map, instmap, cse_info, cse_info, bool, hlds_goal_expr).
-:- mode detect_cse_in_ite(in, in, in, in, in, in, in, in, in, out, out, out)
- is det.
+:- pred detect_cse_in_ite(list(prog_var)::in, list(prog_var)::in,
+ hlds_goal::in, hlds_goal::in, hlds_goal::in, hlds_goal_info::in,
+ store_map::in, instmap::in, cse_info::in,
+ cse_info::out, bool::out, hlds_goal_expr::out) is det.
detect_cse_in_ite([], IfVars, Cond0, Then0, Else0, _, SM, InstMap, CseInfo0,
CseInfo, Redo, if_then_else(IfVars, Cond, Then, Else, SM)) :-
@@ -414,7 +419,7 @@
detect_cse_in_ite([Var | Vars], IfVars, Cond0, Then0, Else0, GoalInfo,
SM, InstMap, CseInfo0, CseInfo, Redo, Goal) :-
(
- CseInfo0 = cse_info(_, _, ModuleInfo),
+ ModuleInfo = CseInfo0 ^ module_info,
instmap__lookup_var(InstMap, Var, VarInst0),
% XXX we only need inst_is_bound, but leave this as it is
% until mode analysis can handle aliasing between free
@@ -433,9 +438,9 @@
SM, InstMap, CseInfo0, CseInfo, Redo, Goal)
).
-:- pred detect_cse_in_ite_2(hlds_goal, hlds_goal, hlds_goal,
- instmap, cse_info, cse_info, bool, hlds_goal, hlds_goal, hlds_goal).
-:- mode detect_cse_in_ite_2(in, in, in, in, in, out, out, out, out, out) is det.
+:- pred detect_cse_in_ite_2(hlds_goal::in, hlds_goal::in, hlds_goal::in,
+ instmap::in, cse_info::in, cse_info::out, bool::out,
+ hlds_goal::out, hlds_goal::out, hlds_goal::out) is det.
detect_cse_in_ite_2(Cond0, Then0, Else0, InstMap0, CseInfo0, CseInfo, Redo,
Cond, Then, Else) :-
@@ -461,79 +466,76 @@
% has been hoisted out, with the new variables as the functor arguments.
% Unify is the unification that was hoisted out.
-:- pred common_deconstruct(list(hlds_goal), prog_var, cse_info, cse_info,
- hlds_goal, list(hlds_goal)).
-:- mode common_deconstruct(in, in, in, out, out, out) is semidet.
+:- pred common_deconstruct(list(hlds_goal)::in, prog_var::in, cse_info::in,
+ cse_info::out, hlds_goal::out, list(hlds_goal)::out) is semidet.
common_deconstruct(Goals0, Var, CseInfo0, CseInfo, Unify, Goals) :-
- common_deconstruct_2(Goals0, Var, no, CseInfo0, CseInfo,
- Goals, MaybeUnifyGoal),
- MaybeUnifyGoal = yes(Unify).
-
-:- pred common_deconstruct_2(list(hlds_goal), prog_var, maybe(hlds_goal),
- cse_info, cse_info, list(hlds_goal), maybe(hlds_goal)).
-:- mode common_deconstruct_2(in, in, in, in, out, out, out) is semidet.
-
-common_deconstruct_2([], _Var, MaybeUnify, CseInfo, CseInfo, [], MaybeUnify).
-common_deconstruct_2([Goal0 | Goals0], Var, MaybeUnify0,
- CseInfo0, CseInfo, [Goal | Goals], MaybeUnify) :-
+ common_deconstruct_2(Goals0, Var, before_candidate,
+ have_candidate(Unify, yes), CseInfo0, CseInfo, Goals).
+
+:- pred common_deconstruct_2(list(hlds_goal)::in, prog_var::in,
+ cse_state::in, cse_state::out, cse_info::in, cse_info::out,
+ list(hlds_goal)::out) is semidet.
+
+common_deconstruct_2([], _Var, CseState, CseState, CseInfo, CseInfo, []).
+common_deconstruct_2([Goal0 | Goals0], Var, CseState0, CseState,
+ CseInfo0, CseInfo, [Goal | Goals]) :-
find_bind_var(Var, find_bind_var_for_cse_in_deconstruct, Goal0, Goal,
- MaybeUnify0 - no, MaybeUnify1 - yes, CseInfo0, CseInfo1),
- MaybeUnify1 = yes(_),
- common_deconstruct_2(Goals0, Var, MaybeUnify1, CseInfo1, CseInfo,
- Goals, MaybeUnify).
+ CseState0, CseState1, CseInfo0, CseInfo1),
+ CseState1 = have_candidate(_, _),
+ common_deconstruct_2(Goals0, Var, CseState1, CseState,
+ CseInfo1, CseInfo, Goals).
%-----------------------------------------------------------------------------%
-:- pred common_deconstruct_cases(list(case), prog_var, cse_info, cse_info,
- hlds_goal, list(case)).
-:- mode common_deconstruct_cases(in, in, in, out, out, out) is semidet.
+:- pred common_deconstruct_cases(list(case)::in, prog_var::in, cse_info::in,
+ cse_info::out, hlds_goal::out, list(case)::out) is semidet.
common_deconstruct_cases(Cases0, Var, CseInfo0, CseInfo,
Unify, Cases) :-
- common_deconstruct_cases_2(Cases0, Var, no, CseInfo0, CseInfo,
- Cases, MaybeUnifyGoal),
- MaybeUnifyGoal = yes(Unify).
-
-:- pred common_deconstruct_cases_2(list(case), prog_var, maybe(hlds_goal),
- cse_info, cse_info, list(case), maybe(hlds_goal)).
-:- mode common_deconstruct_cases_2(in, in, in, in, out, out, out) is semidet.
-
-common_deconstruct_cases_2([], _Var, MaybeUnify, CseInfo, CseInfo,
- [], MaybeUnify).
-common_deconstruct_cases_2([case(ConsId, Goal0) | Cases0], Var, MaybeUnify0,
- CseInfo0, CseInfo, [case(ConsId, Goal) | Cases], MaybeUnify) :-
+ common_deconstruct_cases_2(Cases0, Var, before_candidate,
+ have_candidate(Unify, yes), CseInfo0, CseInfo, Cases).
+
+:- pred common_deconstruct_cases_2(list(case)::in, prog_var::in,
+ cse_state::in, cse_state::out, cse_info::in, cse_info::out,
+ list(case)::out) is semidet.
+
+common_deconstruct_cases_2([], _Var, CseState, CseState, CseInfo, CseInfo, []).
+common_deconstruct_cases_2([case(ConsId, Goal0) | Cases0], Var,
+ CseState0, CseState, CseInfo0, CseInfo,
+ [case(ConsId, Goal) | Cases]) :-
find_bind_var(Var, find_bind_var_for_cse_in_deconstruct, Goal0, Goal,
- MaybeUnify0 - no, MaybeUnify1 - yes, CseInfo0, CseInfo1),
- MaybeUnify1 = yes(_),
- common_deconstruct_cases_2(Cases0, Var, MaybeUnify1, CseInfo1, CseInfo,
- Cases, MaybeUnify).
+ CseState0, CseState1, CseInfo0, CseInfo1),
+ CseState1 = have_candidate(_, _),
+ common_deconstruct_cases_2(Cases0, Var, CseState1, CseState,
+ CseInfo1, CseInfo, Cases).
%-----------------------------------------------------------------------------%
% The hlds_goal is the common unification we are attemping to hoist.
% The boolean states whether such a deconstruction has been seen in
- % this branch.
-:- type cse_result == pair(maybe(hlds_goal), bool).
+ % another branch.
+:- type cse_state
+ ---> before_candidate
+ ; have_candidate(
+ goal :: hlds_goal,
+ seen_similar :: bool
+ )
+ ; multiple_candidates.
-:- pred find_bind_var_for_cse_in_deconstruct(prog_var, hlds_goal,
- list(hlds_goal), cse_result, cse_result, cse_info, cse_info).
-:- mode find_bind_var_for_cse_in_deconstruct(in, in, out,
- in, out, in, out) is det.
+:- pred find_bind_var_for_cse_in_deconstruct(prog_var::in, hlds_goal::in,
+ list(hlds_goal)::out, cse_state::in, cse_state::out,
+ cse_info::in, cse_info::out) is det.
find_bind_var_for_cse_in_deconstruct(Var, Goal0, Goals,
- CseResult0, CseResult, CseInfo0, CseInfo) :-
- CseResult0 = MaybeUnify0 - _,
+ CseState0, CseState, CseInfo0, CseInfo) :-
(
- MaybeUnify0 = no,
- CseInfo0 = cse_info(Varset0, Typemap0, ModuleInfo),
- construct_common_unify(Var, Goal0, Goal,
- Varset0, Varset, Typemap0, Typemap, Goals),
- CseInfo = cse_info(Varset, Typemap, ModuleInfo),
- MaybeUnify = yes(Goal),
- Seen = yes
+ CseState0 = before_candidate,
+ construct_common_unify(Var, Goal0, Goal, CseInfo0, CseInfo,
+ Goals),
+ CseState = have_candidate(Goal, no)
;
- MaybeUnify0 = yes(OldUnifyGoal),
+ CseState0 = have_candidate(OldUnifyGoal, _),
CseInfo = CseInfo0,
Goal0 = _ - GoalInfo,
goal_info_get_context(GoalInfo, Context),
@@ -542,66 +544,78 @@
Goal0, Context, Goals0)
->
Goals = Goals0,
- MaybeUnify = MaybeUnify0,
- Seen = yes
+ CseState = have_candidate(OldUnifyGoal, yes)
;
Goals = [Goal0],
- MaybeUnify = no,
- Seen = no
+ CseState = multiple_candidates
)
- ),
- CseResult = MaybeUnify - Seen.
+ ;
+ CseState0 = multiple_candidates,
+ Goals = [Goal0],
+ CseState = multiple_candidates,
+ CseInfo = CseInfo0
+ ).
-:- pred construct_common_unify(prog_var, hlds_goal, hlds_goal, prog_varset,
- prog_varset, map(prog_var, type), map(prog_var, type), list(hlds_goal)).
-:- mode construct_common_unify(in, in, out, in, out, in, out, out) is det.
+:- pred construct_common_unify(prog_var::in, hlds_goal::in, hlds_goal::out,
+ cse_info::in, cse_info::out, list(hlds_goal)::out) is det.
-construct_common_unify(Var, GoalExpr0 - GoalInfo, Goal, Varset0, Varset,
- Typemap0, Typemap, Replacements) :-
+construct_common_unify(Var, GoalExpr0 - GoalInfo, Goal, CseInfo0, CseInfo,
+ Replacements) :-
(
GoalExpr0 = unify(_, Term, Umode, Unif0, Ucontext),
Unif0 = deconstruct(_, Consid, Args, Submodes, CanFail, CanCGC)
->
- Unif = deconstruct(Var, Consid, Args,
- Submodes, CanFail, CanCGC),
+ Unif = deconstruct(Var, Consid, Args, Submodes, CanFail,
+ CanCGC),
( Term = functor(_, _) ->
GoalExpr1 = unify(Var, Term, Umode, Unif, Ucontext)
;
- error("unexpected unify structure in construct_common_unify")
+ error("non-functor unify in construct_common_unify")
),
goal_info_get_context(GoalInfo, Context),
create_parallel_subterms(Args, Context, Ucontext,
- Varset0, Varset, Typemap0, Typemap, Sub, Replacements),
+ CseInfo0, CseInfo, Sub, Replacements),
goal_util__rename_vars_in_goal(GoalExpr1 - GoalInfo, Sub, Goal)
;
- error("unexpected goal in construct_common_unify")
+ error("non-unify goal in construct_common_unify")
).
-:- pred create_parallel_subterms(list(prog_var), prog_context, unify_context,
- prog_varset, prog_varset, map(prog_var, type), map(prog_var, type),
- map(prog_var, prog_var), list(hlds_goal)).
-:- mode create_parallel_subterms(in, in, in, in, out, in, out, out, out) is det.
+:- pred create_parallel_subterms(list(prog_var)::in, prog_context::in,
+ unify_context::in, cse_info::in, cse_info::out,
+ map(prog_var, prog_var)::out, list(hlds_goal)::out) is det.
-create_parallel_subterms([], _, _, Varset, Varset, Typemap, Typemap, Sub, []) :-
+create_parallel_subterms([], _, _, CseInfo, CseInfo, Sub, []) :-
map__init(Sub).
-create_parallel_subterms([OFV | OFV0], Context, UnifyContext, Varset0, Varset,
- Typemap0, Typemap, Sub, Replacements) :-
- create_parallel_subterms(OFV0, Context, UnifyContext, Varset0, Varset1,
- Typemap0, Typemap1, Sub1, Replacements1),
- varset__new_var(Varset1, NFV, Varset),
- map__lookup(Typemap1, OFV, Type),
- map__det_insert(Typemap1, NFV, Type, Typemap),
- map__det_insert(Sub1, OFV, NFV, Sub),
+create_parallel_subterms([OFV | OFV0], Context, UnifyContext,
+ CseInfo0, CseInfo, Sub, Replacements) :-
+ create_parallel_subterms(OFV0, Context, UnifyContext,
+ CseInfo0, CseInfo1, Sub1, Replacements1),
+ create_parallel_subterm(OFV, Context, UnifyContext,
+ CseInfo1, CseInfo, Sub1, Sub, Goal),
+ Replacements = [Goal | Replacements1].
+
+:- pred create_parallel_subterm(prog_var::in, prog_context::in,
+ unify_context::in, cse_info::in, cse_info::out,
+ map(prog_var, prog_var)::in, map(prog_var, prog_var)::out,
+ hlds_goal::out) is det.
+
+create_parallel_subterm(OFV, Context, UnifyContext,
+ CseInfo0, CseInfo, Sub0, Sub, Goal) :-
+ VarSet0 = CseInfo0 ^ varset,
+ VarTypes0 = CseInfo0 ^ vartypes,
+ varset__new_var(VarSet0, NFV, VarSet),
+ map__lookup(VarTypes0, OFV, Type),
+ map__det_insert(VarTypes0, NFV, Type, VarTypes),
+ map__det_insert(Sub0, OFV, NFV, Sub),
UnifyContext = unify_context(MainCtxt, SubCtxt),
create_atomic_unification(OFV, var(NFV),
Context, MainCtxt, SubCtxt, Goal),
- Replacements = [Goal | Replacements1].
+ CseInfo = (CseInfo0 ^ varset := VarSet) ^ vartypes := VarTypes.
%-----------------------------------------------------------------------------%
-:- pred find_similar_deconstruct(hlds_goal, hlds_goal, prog_context,
- list(hlds_goal)).
-:- mode find_similar_deconstruct(in, in, in, out) is semidet.
+:- pred find_similar_deconstruct(hlds_goal::in, hlds_goal::in,
+ prog_context::in, list(hlds_goal)::out) is semidet.
find_similar_deconstruct(OldUnifyGoal, NewUnifyGoal, Context, Replacements) :-
(
@@ -619,16 +633,16 @@
error("find_similar_deconstruct: non-deconstruct unify")
).
-:- pred pair_subterms(list(prog_var), list(prog_var), prog_context,
- unify_context, list(hlds_goal)).
-:- mode pair_subterms(in, in, in, in, out) is det.
+:- pred pair_subterms(list(prog_var)::in, list(prog_var)::in,
+ prog_context::in, unify_context::in, list(hlds_goal)::out) is det.
pair_subterms(OFV0, NFV0, Context, UnifyContext, Replacements) :-
(
OFV0 = [OFV | OFV1],
NFV0 = [NFV | NFV1]
->
- pair_subterms(OFV1, NFV1, Context, UnifyContext, Replacements1),
+ pair_subterms(OFV1, NFV1, Context, UnifyContext,
+ Replacements1),
( OFV = NFV ->
Replacements = Replacements1
;
Index: switch_detection.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/switch_detection.m,v
retrieving revision 1.92
diff -u -b -r1.92 switch_detection.m
--- switch_detection.m 2000/11/17 17:48:43 1.92
+++ switch_detection.m 2000/12/04 05:37:19
@@ -30,9 +30,6 @@
% Used by both switch_detection and cse_detection.
% Searches through `Goal0' looking for the first deconstruction
% unification with `Var' or an alias of `Var'.
- % `ProcessUnify' is called if a deconstruction unification with
- % `Var' is found, returning either the cons_id for
- % switch_detection or the common deconstruction for cse_detection.
% If a deconstruction unification of the variable is found,
% `ProcessUnify' is called to handle it and searching is stopped.
% If not, `Result' is set to `Result0'.
cvs diff: Diffing notes
--------------------------------------------------------------------------
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