mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-20 00:15:27 +00:00
492 lines
19 KiB
Mathematica
492 lines
19 KiB
Mathematica
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- module liveness.
|
|
% Main author: conway.
|
|
|
|
% This module traverses the goal for each procedure, and adds
|
|
% liveness annotations to the goal_info for each sub-goal.
|
|
|
|
% Note - the concept of `liveness' here is different to that
|
|
% used in the mode analysis. The mode analysis is concerned
|
|
% with the liveness of what is *pointed* to by a variable, for
|
|
% the purpose of avoiding aliasing and for structure re-use
|
|
% optimization, whereas here we are concerned with the liveness
|
|
% of the variable itself, for the purposes of minimizing stack
|
|
% slot usage and for register re-use.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- interface.
|
|
:- import_module hlds, llds.
|
|
|
|
:- pred detect_liveness(module_info, module_info).
|
|
:- mode detect_liveness(in, out) is det.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
:- import_module list, map, set, std_util.
|
|
:- import_module mode_util, term.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% Traverse the module structure, calling `detect_liveness_in_goal'
|
|
% for each procedure body.
|
|
|
|
detect_liveness(ModuleInfo0, ModuleInfo1) :-
|
|
module_info_predids(ModuleInfo0, PredIds),
|
|
detect_liveness_in_preds(PredIds, ModuleInfo0, ModuleInfo1).
|
|
|
|
:- pred detect_liveness_in_preds(list(pred_id), module_info, module_info).
|
|
:- mode detect_liveness_in_preds(in, in, out) is det.
|
|
|
|
detect_liveness_in_preds([], ModuleInfo, ModuleInfo).
|
|
detect_liveness_in_preds([PredId | PredIds], ModuleInfo0, ModuleInfo) :-
|
|
module_info_preds(ModuleInfo0, PredTable),
|
|
map__lookup(PredTable, PredId, PredInfo),
|
|
( pred_info_is_imported(PredInfo) ->
|
|
ModuleInfo1 = ModuleInfo0
|
|
;
|
|
pred_info_procids(PredInfo, ProcIds),
|
|
detect_liveness_in_procs(ProcIds, PredId, ModuleInfo0,
|
|
ModuleInfo1)
|
|
),
|
|
detect_liveness_in_preds(PredIds, ModuleInfo1, ModuleInfo).
|
|
|
|
:- pred detect_liveness_in_procs(list(proc_id), pred_id, module_info,
|
|
module_info).
|
|
:- mode detect_liveness_in_procs(in, in, in, out) is det.
|
|
|
|
detect_liveness_in_procs([], _PredId, ModuleInfo, ModuleInfo).
|
|
detect_liveness_in_procs([ProcId | ProcIds], PredId, ModuleInfo0,
|
|
ModuleInfo) :-
|
|
module_info_preds(ModuleInfo0, PredTable0),
|
|
map__lookup(PredTable0, PredId, PredInfo0),
|
|
pred_info_procedures(PredInfo0, ProcTable0),
|
|
map__lookup(ProcTable0, ProcId, ProcInfo0),
|
|
|
|
% To process each ProcInfo, we get the goal,
|
|
% initialize the instmap based on the modes of the head vars,
|
|
% and pass these to `detect_liveness_in_goal'.
|
|
proc_info_goal(ProcInfo0, Goal0),
|
|
|
|
detect_initial_liveness(ProcInfo0, ModuleInfo0, Liveness0),
|
|
detect_liveness_in_goal(Goal0, Liveness0, ModuleInfo0, Goal1),
|
|
|
|
detect_initial_deadness(ProcInfo0, ModuleInfo0, Deadness0),
|
|
detect_deadness_in_goal(Goal1, Deadness0, ModuleInfo0, Goal),
|
|
|
|
proc_info_set_goal(ProcInfo0, Goal, ProcInfo1),
|
|
proc_info_set_liveness_info(ProcInfo1, Liveness0, ProcInfo),
|
|
map__set(ProcTable0, ProcId, ProcInfo, ProcTable),
|
|
pred_info_set_procedures(PredInfo0, ProcTable, PredInfo),
|
|
map__set(PredTable0, PredId, PredInfo, PredTable),
|
|
module_info_set_preds(ModuleInfo0, PredTable, ModuleInfo1),
|
|
detect_liveness_in_procs(ProcIds, PredId, ModuleInfo1, ModuleInfo).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- pred detect_liveness_in_goal(hlds__goal, liveness_info, module_info,
|
|
liveness_info, hlds__goal).
|
|
:- mode detect_liveness_in_goal(in, in, in, out, out) is det.
|
|
|
|
detect_liveness_in_goal(Goal0 - GoalInfo0, Liveness0, ModuleInfo,
|
|
Liveness, Goal - GoalInfo) :-
|
|
goal_info_pre_delta_liveness(GoalInfo0, PreDelta0),
|
|
goal_info_post_delta_liveness(GoalInfo0, PostDelta0),
|
|
goal_info_get_nonlocals(GoalInfo0, NonLocals),
|
|
PreDelta0 = _PreBirths0 - PreDeaths,
|
|
PostDelta0 = _PostBirths0 - PostDeaths,
|
|
% work out which variables get born in this goal
|
|
set__difference(NonLocals, Liveness0, NewVarsSet),
|
|
set__to_sorted_list(NewVarsSet, NewVarsList),
|
|
goal_info_get_instmap_delta(GoalInfo0, InstMapDelta),
|
|
set__init(Births0),
|
|
find_binding_occurrences(NewVarsList, ModuleInfo, InstMapDelta,
|
|
Births0, Births),
|
|
set__union(Liveness0, Births, Liveness),
|
|
(
|
|
goal_is_atomic(Goal0)
|
|
->
|
|
PreBirths = Births,
|
|
Goal = Goal0,
|
|
PostDelta = PostDelta0
|
|
;
|
|
set__init(PreBirths),
|
|
detect_liveness_in_goal_2(Goal0, Liveness0,
|
|
ModuleInfo, Liveness1, Goal),
|
|
set__difference(Births, Liveness1, PostBirths),
|
|
PostDelta = PostBirths - PostDeaths
|
|
),
|
|
PreDelta = PreBirths - PreDeaths,
|
|
goal_info_set_pre_delta_liveness(GoalInfo0, PreDelta, GoalInfo1),
|
|
goal_info_set_post_delta_liveness(GoalInfo1, PostDelta, GoalInfo).
|
|
|
|
:- pred detect_liveness_in_goal(hlds__goal, liveness_info, module_info,
|
|
hlds__goal).
|
|
:- mode detect_liveness_in_goal(in, in, in, out) is det.
|
|
|
|
detect_liveness_in_goal(Goal0, Liveness0, ModuleInfo, Goal) :-
|
|
detect_liveness_in_goal(Goal0, Liveness0, ModuleInfo, _, Goal).
|
|
|
|
% Here we process each of the different sorts of goals.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% Given a list of variables and an instmap delta, determine
|
|
% which of those variables become bound (according to the instmap
|
|
% delta) and insert them into the accumulated set of bound vars.
|
|
|
|
:- pred find_binding_occurrences(list(var), module_info, instmap_delta,
|
|
set(var), set(var)).
|
|
:- mode find_binding_occurrences(in, in, in, in, out) is det.
|
|
|
|
find_binding_occurrences([], _, _, BoundVars, BoundVars).
|
|
find_binding_occurrences([Var | Vars], ModuleInfo, InstMapDelta, BoundVars0,
|
|
BoundVars) :-
|
|
instmap_lookup_var(InstMapDelta, Var, Inst),
|
|
( inst_is_bound(ModuleInfo, Inst) ->
|
|
set__insert(BoundVars0, Var, BoundVars1)
|
|
;
|
|
BoundVars1 = BoundVars0
|
|
),
|
|
find_binding_occurrences(Vars, ModuleInfo, InstMapDelta, BoundVars1,
|
|
BoundVars).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- pred detect_liveness_in_goal_2(hlds__goal_expr, liveness_info,
|
|
module_info, liveness_info, hlds__goal_expr).
|
|
:- mode detect_liveness_in_goal_2(in, in, in, out, out) is det.
|
|
|
|
detect_liveness_in_goal_2(conj(Goals0), Liveness0, ModuleInfo,
|
|
Liveness, conj(Goals)) :-
|
|
detect_liveness_in_conj(Goals0, Liveness0, ModuleInfo, Liveness, Goals).
|
|
|
|
detect_liveness_in_goal_2(disj(Goals0), Liveness0, ModuleInfo,
|
|
Liveness, disj(Goals)) :-
|
|
set__init(Union0),
|
|
detect_liveness_in_disj(Goals0, Liveness0, ModuleInfo,
|
|
Union0, Union, Goals),
|
|
set__union(Liveness0, Union, Liveness).
|
|
|
|
detect_liveness_in_goal_2(not(Goal0), Liveness0, ModuleInfo,
|
|
Liveness, not(Goal)) :-
|
|
detect_liveness_in_goal(Goal0, Liveness0, ModuleInfo, Liveness, Goal).
|
|
|
|
detect_liveness_in_goal_2(switch(Var, Det, Cases0), Liveness0,
|
|
ModuleInfo, Liveness, switch(Var, Det, Cases)) :-
|
|
set__init(Union0),
|
|
detect_liveness_in_cases(Cases0, Liveness0, ModuleInfo,
|
|
Union0, Union, Cases),
|
|
set__union(Liveness0, Union, Liveness).
|
|
|
|
detect_liveness_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0), Liveness0,
|
|
M, Liveness, if_then_else(Vars, Cond, Then, Else)) :-
|
|
detect_liveness_in_goal(Cond0, Liveness0, M, LivenessCond, Cond),
|
|
detect_liveness_in_goal(Then0, LivenessCond, M, LivenessThen, Then1),
|
|
detect_liveness_in_goal(Else0, Liveness0, M, LivenessElse, Else1),
|
|
|
|
set__difference(LivenessThen, LivenessCond, ProducedInThen),
|
|
set__difference(LivenessElse, Liveness0, ProducedInElse),
|
|
|
|
set__difference(ProducedInElse, ProducedInThen, ResidueThen),
|
|
set__difference(ProducedInThen, ProducedInElse, ResidueElse),
|
|
|
|
stuff_liveness_residue_into_goal(Then1, ResidueThen, Then),
|
|
stuff_liveness_residue_into_goal(Else1, ResidueElse, Else),
|
|
|
|
set__union(LivenessThen, LivenessElse, Liveness).
|
|
|
|
detect_liveness_in_goal_2(some(Vars, Goal0), Liveness0, ModuleInfo,
|
|
Liveness, some(Vars, Goal)) :-
|
|
detect_liveness_in_goal(Goal0, Liveness0, ModuleInfo, Liveness, Goal).
|
|
|
|
detect_liveness_in_goal_2(call(A,B,C,D,E,F), L, _, L, call(A,B,C,D,E,F)).
|
|
|
|
detect_liveness_in_goal_2(unify(A,B,C,D,E), L, _, L, unify(A,B,C,D,E)).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- pred detect_liveness_in_conj(list(hlds__goal), set(var), module_info,
|
|
set(var), list(hlds__goal)).
|
|
:- mode detect_liveness_in_conj(in, in, in, out, out) is det.
|
|
|
|
detect_liveness_in_conj([], Liveness, _ModuleInfo, Liveness, []).
|
|
detect_liveness_in_conj([Goal0|Goals0], Liveness0,
|
|
ModuleInfo, Liveness, [Goal|Goals]) :-
|
|
% (
|
|
% Goal0 = _ - GoalInfo,
|
|
% goal_info_get_instmap_delta(GoalInfo, unreachable)
|
|
% ->
|
|
% Goal = Goal0,
|
|
% Goals = Goals0,
|
|
% Liveness = Liveness0
|
|
% ;
|
|
detect_liveness_in_goal(Goal0, Liveness0,
|
|
ModuleInfo, Liveness1, Goal),
|
|
detect_liveness_in_conj(Goals0, Liveness1,
|
|
ModuleInfo, Liveness, Goals).
|
|
% ).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- pred detect_liveness_in_disj(list(hlds__goal), set(var), module_info,
|
|
set(var), set(var), list(hlds__goal)).
|
|
:- mode detect_liveness_in_disj(in, in, in, in, out, out) is det.
|
|
|
|
detect_liveness_in_disj([], _Liveness, _ModuleInfo, Union, Union, []).
|
|
detect_liveness_in_disj([Goal0|Goals0], Liveness, ModuleInfo,
|
|
Union0, Union, [Goal|Goals]) :-
|
|
detect_liveness_in_goal(Goal0, Liveness, ModuleInfo, Liveness1, Goal1),
|
|
set__union(Union0, Liveness1, Union1),
|
|
detect_liveness_in_disj(Goals0, Liveness, ModuleInfo,
|
|
Union1, Union, Goals),
|
|
set__difference(Union, Liveness1, Residue),
|
|
stuff_liveness_residue_into_goal(Goal1, Residue, Goal).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- pred detect_liveness_in_cases(list(case), set(var), module_info,
|
|
set(var), set(var), list(case)).
|
|
:- mode detect_liveness_in_cases(in, in, in, in, out, out) is det.
|
|
|
|
detect_liveness_in_cases([], _Liveness, _ModuleInfo, Union, Union, []).
|
|
detect_liveness_in_cases([case(Cons, Goal0)|Goals0], Liveness, ModuleInfo,
|
|
Union0, Union, [case(Cons, Goal)|Goals]) :-
|
|
detect_liveness_in_goal(Goal0, Liveness, ModuleInfo, Liveness1, Goal1),
|
|
set__union(Union0, Liveness1, Union1),
|
|
detect_liveness_in_cases(Goals0, Liveness, ModuleInfo,
|
|
Union1, Union, Goals),
|
|
set__difference(Union, Liveness1, Residue),
|
|
stuff_liveness_residue_into_goal(Goal1, Residue, Goal).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- pred detect_deadness_in_goal(hlds__goal, liveness_info, module_info,
|
|
liveness_info, hlds__goal).
|
|
:- mode detect_deadness_in_goal(in, in, in, out, out) is det.
|
|
|
|
detect_deadness_in_goal(Goal0 - GoalInfo0, Deadness0, ModuleInfo,
|
|
Deadness, Goal - GoalInfo) :-
|
|
goal_info_post_delta_liveness(GoalInfo0, PostDelta0),
|
|
goal_info_pre_delta_liveness(GoalInfo0, PreDelta0),
|
|
goal_info_get_nonlocals(GoalInfo0, NonLocals),
|
|
PostDelta0 = PostBirths - _PostDeaths0,
|
|
PreDelta0 = PreBirths - _PreDeaths0,
|
|
(
|
|
goal_is_atomic(Goal0)
|
|
->
|
|
set__difference(NonLocals, Deadness0, PostDeaths),
|
|
set__union(Deadness0, PostDeaths, Deadness),
|
|
Goal = Goal0,
|
|
PreDelta = PreDelta0
|
|
;
|
|
set__union(Deadness0, NonLocals, Deadness),
|
|
set__init(PostDeaths),
|
|
detect_deadness_in_goal_2(Goal0, Deadness0,
|
|
ModuleInfo, Deadness1, Goal),
|
|
set__difference(Deadness, Deadness1, PreDeaths),
|
|
PreDelta = PreBirths - PreDeaths
|
|
),
|
|
PostDelta = PostBirths - PostDeaths,
|
|
goal_info_set_post_delta_liveness(GoalInfo0, PostDelta, GoalInfo1),
|
|
goal_info_set_pre_delta_liveness(GoalInfo1, PreDelta, GoalInfo).
|
|
|
|
:- pred detect_deadness_in_goal(hlds__goal, liveness_info, module_info,
|
|
hlds__goal).
|
|
:- mode detect_deadness_in_goal(in, in, in, out) is det.
|
|
|
|
detect_deadness_in_goal(Goal0, Deadness, ModuleInfo, Goal) :-
|
|
detect_deadness_in_goal(Goal0, Deadness, ModuleInfo, _, Goal).
|
|
|
|
% Here we process each of the different sorts of goals.
|
|
|
|
:- pred detect_deadness_in_goal_2(hlds__goal_expr, liveness_info,
|
|
module_info, liveness_info, hlds__goal_expr).
|
|
:- mode detect_deadness_in_goal_2(in, in, in, out, out) is det.
|
|
|
|
detect_deadness_in_goal_2(conj(Goals0), Deadness0, ModuleInfo,
|
|
Deadness, conj(Goals)) :-
|
|
detect_deadness_in_conj(Goals0, Deadness0,
|
|
ModuleInfo, Goals, Deadness).
|
|
|
|
detect_deadness_in_goal_2(disj(Goals0), Deadness0,
|
|
ModuleInfo, Deadness, disj(Goals)) :-
|
|
set__init(Union0),
|
|
detect_deadness_in_disj(Goals0, Deadness0, ModuleInfo, Union0,
|
|
Union, Goals),
|
|
set__union(Deadness0, Union, Deadness).
|
|
|
|
detect_deadness_in_goal_2(not(Goal0), Deadness0, ModuleInfo,
|
|
Deadness, not(Goal)) :-
|
|
detect_deadness_in_goal(Goal0, Deadness0, ModuleInfo, Deadness, Goal).
|
|
|
|
detect_deadness_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0), Deadness0,
|
|
ModuleInfo, Deadness, if_then_else(Vars, Cond, Then, Else)) :-
|
|
detect_deadness_in_goal(Then0, Deadness0, ModuleInfo,
|
|
DeadnessThen, Then1),
|
|
detect_deadness_in_goal(Else0, Deadness0, ModuleInfo,
|
|
DeadnessElse, Else1),
|
|
set__union(DeadnessThen, DeadnessElse, DeadnessThenElse),
|
|
detect_deadness_in_goal(Cond0, DeadnessThenElse, ModuleInfo,
|
|
Deadness, Cond),
|
|
set__difference(DeadnessElse, DeadnessThen, ResidueThen),
|
|
stuff_deadness_residue_into_goal(Then1, ResidueThen, Then),
|
|
set__difference(DeadnessThen, DeadnessElse, ResidueElse),
|
|
stuff_deadness_residue_into_goal(Else1, ResidueElse, Else).
|
|
|
|
detect_deadness_in_goal_2(switch(Var, Det, Cases0), Deadness0,
|
|
ModuleInfo, Deadness, switch(Var, Det, Cases)) :-
|
|
set__init(Union0),
|
|
detect_deadness_in_cases(Cases0, Deadness0, ModuleInfo, Union0,
|
|
Union, Cases),
|
|
set__union(Deadness0, Union, Deadness).
|
|
|
|
detect_deadness_in_goal_2(some(Vars, Goal0), Deadness0, ModuleInfo,
|
|
Deadness, some(Vars, Goal)) :-
|
|
detect_deadness_in_goal(Goal0, Deadness0, ModuleInfo, Deadness, Goal).
|
|
|
|
detect_deadness_in_goal_2(call(A,B,C,D,E,F), Dn, _, Dn, call(A,B,C,D,E,F)).
|
|
|
|
detect_deadness_in_goal_2(unify(A,B,C,D,E), Dn, _, Dn, unify(A,B,C,D,E)).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- pred detect_deadness_in_conj(list(hlds__goal), set(var), module_info,
|
|
list(hlds__goal), set(var)).
|
|
:- mode detect_deadness_in_conj(in, in, in, out, out) is det.
|
|
|
|
detect_deadness_in_conj([], Deadness, _ModuleInfo, [], Deadness).
|
|
detect_deadness_in_conj([Goal0|Goals0], Deadness0, ModuleInfo,
|
|
[Goal|Goals], Deadness) :-
|
|
(
|
|
Goal0 = _ - GoalInfo,
|
|
goal_info_get_instmap_delta(GoalInfo, unreachable)
|
|
->
|
|
detect_deadness_in_conj(Goals0, Deadness0,
|
|
ModuleInfo, Goals, Deadness2),
|
|
detect_deadness_in_goal(Goal0, Deadness2,
|
|
ModuleInfo, Deadness, Goal)
|
|
;
|
|
detect_deadness_in_conj(Goals0, Deadness0,
|
|
ModuleInfo, Goals, Deadness1),
|
|
detect_deadness_in_goal(Goal0, Deadness1,
|
|
ModuleInfo, Deadness, Goal)
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- pred detect_deadness_in_disj(list(hlds__goal), set(var), module_info,
|
|
set(var), set(var), list(hlds__goal)).
|
|
:- mode detect_deadness_in_disj(in, in, in, in, out, out) is det.
|
|
|
|
detect_deadness_in_disj([], _Deadness, _ModuleInfo, Union, Union, []).
|
|
detect_deadness_in_disj([Goal0|Goals0], Deadness, ModuleInfo,
|
|
Union0, Union, [Goal|Goals]) :-
|
|
detect_deadness_in_goal(Goal0, Deadness, ModuleInfo, Deadness1, Goal1),
|
|
set__union(Union0, Deadness1, Union1),
|
|
detect_deadness_in_disj(Goals0, Deadness, ModuleInfo,
|
|
Union1, Union, Goals),
|
|
set__difference(Union, Deadness1, Residue),
|
|
stuff_deadness_residue_into_goal(Goal1, Residue, Goal).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- pred detect_deadness_in_cases(list(case), set(var), module_info, set(var),
|
|
set(var), list(case)).
|
|
:- mode detect_deadness_in_cases(in, in, in, in, out, out) is det.
|
|
|
|
detect_deadness_in_cases([], _Deadness, _ModuleInfo, Union, Union, []).
|
|
detect_deadness_in_cases([case(Cons, Goal0)|Goals0], Deadness0, ModuleInfo,
|
|
Union0, Union, [case(Cons, Goal)|Goals]) :-
|
|
detect_deadness_in_goal(Goal0, Deadness0, ModuleInfo, Deadness1, Goal1),
|
|
set__union(Union0, Deadness1, Union1),
|
|
detect_deadness_in_cases(Goals0, Deadness0, ModuleInfo,
|
|
Union1, Union, Goals),
|
|
set__difference(Union, Deadness1, Residue),
|
|
stuff_deadness_residue_into_goal(Goal1, Residue, Goal).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- pred detect_initial_liveness(proc_info, module_info, set(var)).
|
|
:- mode detect_initial_liveness(in, in, out) is det.
|
|
|
|
detect_initial_liveness(ProcInfo, ModuleInfo, Liveness) :-
|
|
proc_info_headvars(ProcInfo, Vars),
|
|
proc_info_argmodes(ProcInfo, Args),
|
|
assoc_list__from_corresponding_lists(Vars, Args, VarArgs),
|
|
set__init(Liveness0),
|
|
detect_initial_liveness_2(VarArgs, ModuleInfo, Liveness0, Liveness).
|
|
|
|
:- pred detect_initial_liveness_2(assoc_list(var,mode), module_info,
|
|
set(var), set(var)).
|
|
:- mode detect_initial_liveness_2(in, in, in, out) is det.
|
|
|
|
detect_initial_liveness_2([], _ModuleInfo, Liveness, Liveness).
|
|
detect_initial_liveness_2([V - M|VAs], ModuleInfo,
|
|
Liveness0, Liveness) :-
|
|
(
|
|
mode_is_input(ModuleInfo, M)
|
|
->
|
|
set__insert(Liveness0, V, Liveness1)
|
|
;
|
|
Liveness1 = Liveness0
|
|
),
|
|
detect_initial_liveness_2(VAs, ModuleInfo, Liveness1, Liveness).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- pred detect_initial_deadness(proc_info, module_info, set(var)).
|
|
:- mode detect_initial_deadness(in, in, out) is det.
|
|
|
|
detect_initial_deadness(ProcInfo, ModuleInfo, Deadness) :-
|
|
proc_info_headvars(ProcInfo, Vars),
|
|
proc_info_argmodes(ProcInfo, Args),
|
|
assoc_list__from_corresponding_lists(Vars, Args, VarArgs),
|
|
set__init(Deadness0),
|
|
detect_initial_deadness_2(VarArgs, ModuleInfo, Deadness0, Deadness).
|
|
|
|
:- pred detect_initial_deadness_2(assoc_list(var,mode), module_info,
|
|
set(var), set(var)).
|
|
:- mode detect_initial_deadness_2(in, in, in, out) is det.
|
|
|
|
detect_initial_deadness_2([], _ModuleInfo, Deadness, Deadness).
|
|
detect_initial_deadness_2([V - M|VAs], ModuleInfo, Deadness0, Deadness) :-
|
|
(
|
|
mode_is_output(ModuleInfo, M)
|
|
->
|
|
set__insert(Deadness0, V, Deadness1)
|
|
;
|
|
Deadness1 = Deadness0
|
|
),
|
|
detect_initial_deadness_2(VAs, ModuleInfo, Deadness1, Deadness).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- pred stuff_liveness_residue_into_goal(hlds__goal, liveness_info, hlds__goal).
|
|
:- mode stuff_liveness_residue_into_goal(in, in, out) is det.
|
|
|
|
stuff_liveness_residue_into_goal(Goal - GoalInfo0, Residue, Goal - GoalInfo) :-
|
|
goal_info_post_delta_liveness(GoalInfo0, Births0 - Deaths),
|
|
set__union(Births0, Residue, Births),
|
|
goal_info_set_post_delta_liveness(GoalInfo0, Births - Deaths, GoalInfo).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- pred stuff_deadness_residue_into_goal(hlds__goal, liveness_info, hlds__goal).
|
|
:- mode stuff_deadness_residue_into_goal(in, in, out) is det.
|
|
|
|
stuff_deadness_residue_into_goal(Goal - GoalInfo0, Residue, Goal - GoalInfo) :-
|
|
goal_info_pre_delta_liveness(GoalInfo0, Births - Deaths0),
|
|
set__union(Deaths0, Residue, Deaths),
|
|
goal_info_set_pre_delta_liveness(GoalInfo0, Births - Deaths, GoalInfo).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|