mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 01:13:30 +00:00
Improve debuggability and style in cse_detection.m.
This commit is contained in:
@@ -83,13 +83,12 @@
|
|||||||
:- import_module hlds.hlds_pred.
|
:- import_module hlds.hlds_pred.
|
||||||
|
|
||||||
:- import_module io.
|
:- import_module io.
|
||||||
:- import_module maybe.
|
|
||||||
|
|
||||||
:- pred detect_cse_in_module(io.text_output_stream::in,
|
:- pred detect_cse_in_module(io.text_output_stream::in,
|
||||||
module_info::in, module_info::out) is det.
|
module_info::in, module_info::out) is det.
|
||||||
|
|
||||||
:- pred detect_cse_in_proc(maybe(io.text_output_stream)::in,
|
:- pred detect_cse_in_queued_proc(pred_id::in, proc_id::in,
|
||||||
pred_id::in, proc_id::in, module_info::in, module_info::out) is det.
|
module_info::in, module_info::out) is det.
|
||||||
|
|
||||||
%---------------------------------------------------------------------------%
|
%---------------------------------------------------------------------------%
|
||||||
%---------------------------------------------------------------------------%
|
%---------------------------------------------------------------------------%
|
||||||
@@ -102,6 +101,7 @@
|
|||||||
:- import_module hlds.hlds_goal.
|
:- import_module hlds.hlds_goal.
|
||||||
:- import_module hlds.hlds_markers.
|
:- import_module hlds.hlds_markers.
|
||||||
:- import_module hlds.hlds_out.
|
:- import_module hlds.hlds_out.
|
||||||
|
:- import_module hlds.hlds_out.hlds_out_goal.
|
||||||
:- import_module hlds.hlds_out.hlds_out_util.
|
:- import_module hlds.hlds_out.hlds_out_util.
|
||||||
:- import_module hlds.hlds_proc_util.
|
:- import_module hlds.hlds_proc_util.
|
||||||
:- import_module hlds.hlds_rtti.
|
:- import_module hlds.hlds_rtti.
|
||||||
@@ -121,6 +121,7 @@
|
|||||||
:- import_module parse_tree.prog_data.
|
:- import_module parse_tree.prog_data.
|
||||||
:- import_module parse_tree.prog_type.
|
:- import_module parse_tree.prog_type.
|
||||||
:- import_module parse_tree.set_of_var.
|
:- import_module parse_tree.set_of_var.
|
||||||
|
:- import_module parse_tree.var_db.
|
||||||
:- import_module parse_tree.var_table.
|
:- import_module parse_tree.var_table.
|
||||||
:- import_module parse_tree.write_error_spec.
|
:- import_module parse_tree.write_error_spec.
|
||||||
|
|
||||||
@@ -128,10 +129,13 @@
|
|||||||
:- import_module bool.
|
:- import_module bool.
|
||||||
:- import_module list.
|
:- import_module list.
|
||||||
:- import_module map.
|
:- import_module map.
|
||||||
|
:- import_module maybe.
|
||||||
:- import_module pair.
|
:- import_module pair.
|
||||||
:- import_module require.
|
:- import_module require.
|
||||||
:- import_module string.
|
:- import_module string.
|
||||||
:- import_module term.
|
:- import_module term.
|
||||||
|
:- import_module uint.
|
||||||
|
:- import_module varset.
|
||||||
|
|
||||||
%---------------------------------------------------------------------------%
|
%---------------------------------------------------------------------------%
|
||||||
|
|
||||||
@@ -180,13 +184,25 @@ detect_cse_in_pred(ProgressStream, PredId, PredInfo, !ModuleInfo) :-
|
|||||||
|
|
||||||
detect_cse_in_procs(_ProgressStream,_PredId, [], !ModuleInfo).
|
detect_cse_in_procs(_ProgressStream,_PredId, [], !ModuleInfo).
|
||||||
detect_cse_in_procs(ProgressStream, PredId, [ProcId | ProcIds], !ModuleInfo) :-
|
detect_cse_in_procs(ProgressStream, PredId, [ProcId | ProcIds], !ModuleInfo) :-
|
||||||
detect_cse_in_proc(yes(ProgressStream), PredId, ProcId, !ModuleInfo),
|
detect_cse_in_proc(yes(ProgressStream), 1u, PredId, ProcId, !ModuleInfo),
|
||||||
detect_cse_in_procs(ProgressStream, PredId, ProcIds, !ModuleInfo).
|
detect_cse_in_procs(ProgressStream, PredId, ProcIds, !ModuleInfo).
|
||||||
|
|
||||||
detect_cse_in_proc(MaybeProgressStream, PredId, ProcId, !ModuleInfo) :-
|
detect_cse_in_queued_proc(PredId, ProcId, !ModuleInfo) :-
|
||||||
|
detect_cse_in_proc(maybe.no, 1u, PredId, ProcId, !ModuleInfo).
|
||||||
|
|
||||||
|
:- pred detect_cse_in_proc(maybe(io.text_output_stream)::in, uint::in,
|
||||||
|
pred_id::in, proc_id::in, module_info::in, module_info::out) is det.
|
||||||
|
|
||||||
|
detect_cse_in_proc(MaybeProgressStream, PassNum, PredId, ProcId,
|
||||||
|
!ModuleInfo) :-
|
||||||
module_info_get_globals(!.ModuleInfo, Globals),
|
module_info_get_globals(!.ModuleInfo, Globals),
|
||||||
globals.lookup_bool_option(Globals, very_verbose, VeryVerbose),
|
globals.lookup_bool_option(Globals, very_verbose, VeryVerbose),
|
||||||
|
|
||||||
|
trace [compile_time(flag("dump_cse_stages")), io(!IO)] (
|
||||||
|
dump_stage_goal(!.ModuleInfo, PredId, ProcId,
|
||||||
|
PassNum, 0u, "before_detect_cse", !IO)
|
||||||
|
),
|
||||||
|
|
||||||
% XXX We wouldn't have to keep getting the proc_info out of and back into
|
% XXX We wouldn't have to keep getting the proc_info out of and back into
|
||||||
% the module_info if modecheck didn't take a whole module_info.
|
% the module_info if modecheck didn't take a whole module_info.
|
||||||
module_info_pred_info(!.ModuleInfo, PredId, PredInfo0),
|
module_info_pred_info(!.ModuleInfo, PredId, PredInfo0),
|
||||||
@@ -197,6 +213,11 @@ detect_cse_in_proc(MaybeProgressStream, PredId, ProcId, !ModuleInfo) :-
|
|||||||
pred_info_set_proc_info(ProcId, ProcInfo1, PredInfo0, PredInfo1),
|
pred_info_set_proc_info(ProcId, ProcInfo1, PredInfo0, PredInfo1),
|
||||||
module_info_set_pred_info(PredId, PredInfo1, !ModuleInfo),
|
module_info_set_pred_info(PredId, PredInfo1, !ModuleInfo),
|
||||||
|
|
||||||
|
trace [compile_time(flag("dump_cse_stages")), io(!IO)] (
|
||||||
|
dump_stage_goal(!.ModuleInfo, PredId, ProcId,
|
||||||
|
PassNum, 1u, "after_detect_cse", !IO)
|
||||||
|
),
|
||||||
|
|
||||||
globals.lookup_bool_option(Globals, detailed_statistics, Statistics),
|
globals.lookup_bool_option(Globals, detailed_statistics, Statistics),
|
||||||
trace [io(!IO)] (
|
trace [io(!IO)] (
|
||||||
report_stats_if_called_for(MaybeProgressStream, Statistics, !IO)
|
report_stats_if_called_for(MaybeProgressStream, Statistics, !IO)
|
||||||
@@ -215,6 +236,10 @@ detect_cse_in_proc(MaybeProgressStream, PredId, ProcId, !ModuleInfo) :-
|
|||||||
trace [io(!IO)] (
|
trace [io(!IO)] (
|
||||||
report_stats_if_called_for(MaybeProgressStream, Statistics, !IO)
|
report_stats_if_called_for(MaybeProgressStream, Statistics, !IO)
|
||||||
),
|
),
|
||||||
|
trace [compile_time(flag("dump_cse_stages")), io(!IO)] (
|
||||||
|
dump_stage_goal(!.ModuleInfo, PredId, ProcId,
|
||||||
|
PassNum, 2u, "after_modecheck", !IO)
|
||||||
|
),
|
||||||
ContainsErrors = contains_errors(Globals, ModeSpecs),
|
ContainsErrors = contains_errors(Globals, ModeSpecs),
|
||||||
(
|
(
|
||||||
ContainsErrors = yes,
|
ContainsErrors = yes,
|
||||||
@@ -250,16 +275,18 @@ detect_cse_in_proc(MaybeProgressStream, PredId, ProcId, !ModuleInfo) :-
|
|||||||
pred_info_set_proc_info(ProcId, ProcInfo, PredInfo2, PredInfo3),
|
pred_info_set_proc_info(ProcId, ProcInfo, PredInfo2, PredInfo3),
|
||||||
module_info_set_pred_info(PredId, PredInfo3, !ModuleInfo),
|
module_info_set_pred_info(PredId, PredInfo3, !ModuleInfo),
|
||||||
|
|
||||||
|
trace [compile_time(flag("dump_cse_stages")), io(!IO)] (
|
||||||
|
dump_stage_goal(!.ModuleInfo, PredId, ProcId,
|
||||||
|
PassNum, 3u, "after_switch_detect", !IO)
|
||||||
|
),
|
||||||
trace [io(!IO)] (
|
trace [io(!IO)] (
|
||||||
report_stats_if_called_for(MaybeProgressStream, Statistics, !IO),
|
report_stats_if_called_for(MaybeProgressStream, Statistics, !IO),
|
||||||
print_very_verbose_msg_for_pred(MaybeProgressStream, VeryVerbose,
|
print_very_verbose_msg_for_pred(MaybeProgressStream, VeryVerbose,
|
||||||
!.ModuleInfo, PredId,
|
!.ModuleInfo, PredId,
|
||||||
"Repeating common deconstruction detection for", !IO)
|
"Repeating common deconstruction detection for", !IO)
|
||||||
),
|
),
|
||||||
disable_warning [suspicious_recursion] (
|
detect_cse_in_proc(MaybeProgressStream, PassNum + 1u, PredId, ProcId,
|
||||||
detect_cse_in_proc(MaybeProgressStream, PredId, ProcId,
|
!ModuleInfo)
|
||||||
!ModuleInfo)
|
|
||||||
)
|
|
||||||
).
|
).
|
||||||
|
|
||||||
:- type cse_info
|
:- type cse_info
|
||||||
@@ -284,7 +311,7 @@ detect_cse_in_proc_pass(ModuleInfo, Redo, !ProcInfo) :-
|
|||||||
proc_info_get_rtti_varmaps(!.ProcInfo, RttiVarMaps0),
|
proc_info_get_rtti_varmaps(!.ProcInfo, RttiVarMaps0),
|
||||||
Redo0 = no,
|
Redo0 = no,
|
||||||
CseInfo0 = cse_info(ModuleInfo, VarTable0, RttiVarMaps0, Redo0, []),
|
CseInfo0 = cse_info(ModuleInfo, VarTable0, RttiVarMaps0, Redo0, []),
|
||||||
detect_cse_in_goal(Goal0, Goal1, CseInfo0, CseInfo, InstMap0),
|
detect_cse_in_goal(InstMap0, Goal0, Goal1, CseInfo0, CseInfo),
|
||||||
CseInfo = cse_info(_, _, _, Redo, CseNoPullContexts),
|
CseInfo = cse_info(_, _, _, Redo, CseNoPullContexts),
|
||||||
proc_info_get_cse_nopull_contexts(!.ProcInfo, NoPullContexts0),
|
proc_info_get_cse_nopull_contexts(!.ProcInfo, NoPullContexts0),
|
||||||
NoPullContexts = CseNoPullContexts ++ NoPullContexts0,
|
NoPullContexts = CseNoPullContexts ++ NoPullContexts0,
|
||||||
@@ -308,26 +335,29 @@ detect_cse_in_proc_pass(ModuleInfo, Redo, !ProcInfo) :-
|
|||||||
|
|
||||||
%---------------------------------------------------------------------------%
|
%---------------------------------------------------------------------------%
|
||||||
|
|
||||||
|
% This version is the same as the predicate below except that
|
||||||
|
% it also returns the resulting instmap on exit from the goal,
|
||||||
|
% which is computed by applying the instmap delta specified
|
||||||
|
% in the goal's goalinfo.
|
||||||
|
%
|
||||||
|
:- pred detect_cse_in_goal_update_instmap(instmap::in, instmap::out,
|
||||||
|
hlds_goal::in, hlds_goal::out, cse_info::in, cse_info::out) is det.
|
||||||
|
|
||||||
|
detect_cse_in_goal_update_instmap(InstMap0, InstMap, Goal0, Goal, !CseInfo) :-
|
||||||
|
detect_cse_in_goal(InstMap0, Goal0, Goal, !CseInfo),
|
||||||
|
Goal0 = hlds_goal(_, GoalInfo0),
|
||||||
|
InstMapDelta = goal_info_get_instmap_delta(GoalInfo0),
|
||||||
|
apply_instmap_delta(InstMapDelta, InstMap0, InstMap).
|
||||||
|
|
||||||
% Given a goal, and the instmap on entry to that goal,
|
% Given a goal, and the instmap on entry to that goal,
|
||||||
% find disjunctions that contain common subexpressions
|
% find disjunctions that contain common subexpressions
|
||||||
% and hoist these out of the disjunction. At the moment
|
% and hoist these out of the disjunction. At the moment
|
||||||
% we only look for cses that are deconstruction unifications.
|
% we only look for cses that are deconstruction unifications.
|
||||||
%
|
%
|
||||||
:- pred detect_cse_in_goal(hlds_goal::in, hlds_goal::out,
|
:- pred detect_cse_in_goal(instmap::in, hlds_goal::in, hlds_goal::out,
|
||||||
cse_info::in, cse_info::out, instmap::in) is det.
|
cse_info::in, cse_info::out) is det.
|
||||||
|
|
||||||
detect_cse_in_goal(Goal0, Goal, !CseInfo, InstMap0) :-
|
detect_cse_in_goal(InstMap0, Goal0, Goal, !CseInfo) :-
|
||||||
detect_cse_in_goal_update_instmap(Goal0, Goal, !CseInfo,
|
|
||||||
InstMap0, _InstMap).
|
|
||||||
|
|
||||||
% This version is the same as the above except that it returns
|
|
||||||
% the resulting instmap on exit from the goal, which is computed by
|
|
||||||
% applying the instmap delta specified in the goal's goalinfo.
|
|
||||||
%
|
|
||||||
:- pred detect_cse_in_goal_update_instmap(hlds_goal::in, hlds_goal::out,
|
|
||||||
cse_info::in, cse_info::out, instmap::in, instmap::out) is det.
|
|
||||||
|
|
||||||
detect_cse_in_goal_update_instmap(Goal0, Goal, !CseInfo, InstMap0, InstMap) :-
|
|
||||||
Goal0 = hlds_goal(GoalExpr0, GoalInfo),
|
Goal0 = hlds_goal(GoalExpr0, GoalInfo),
|
||||||
(
|
(
|
||||||
( GoalExpr0 = call_foreign_proc(_, _, _, _, _, _, _)
|
( GoalExpr0 = call_foreign_proc(_, _, _, _, _, _, _)
|
||||||
@@ -343,19 +373,19 @@ detect_cse_in_goal_update_instmap(Goal0, Goal, !CseInfo, InstMap0, InstMap) :-
|
|||||||
ModuleInfo = !.CseInfo ^ csei_module_info,
|
ModuleInfo = !.CseInfo ^ csei_module_info,
|
||||||
instmap.pre_lambda_update(ModuleInfo, VarsModes,
|
instmap.pre_lambda_update(ModuleInfo, VarsModes,
|
||||||
InstMap0, InstMap1),
|
InstMap0, InstMap1),
|
||||||
detect_cse_in_goal(LambdaGoal0, LambdaGoal, !CseInfo, InstMap1),
|
detect_cse_in_goal(InstMap1, LambdaGoal0, LambdaGoal, !CseInfo),
|
||||||
RHS = rhs_lambda_goal(Purity, Groundness, PredOrFunc,
|
RHS = rhs_lambda_goal(Purity, Groundness, PredOrFunc,
|
||||||
NonLocalVars, VarsModes, Det, LambdaGoal)
|
NonLocalVars, VarsModes, Det, LambdaGoal),
|
||||||
|
GoalExpr = unify(LHS, RHS, Mode,Unify, UnifyContext)
|
||||||
;
|
;
|
||||||
( RHS0 = rhs_var(_)
|
( RHS0 = rhs_var(_)
|
||||||
; RHS0 = rhs_functor(_, _, _)
|
; RHS0 = rhs_functor(_, _, _)
|
||||||
),
|
),
|
||||||
RHS = RHS0
|
GoalExpr = GoalExpr0
|
||||||
),
|
)
|
||||||
GoalExpr = unify(LHS, RHS, Mode,Unify, UnifyContext)
|
|
||||||
;
|
;
|
||||||
GoalExpr0 = negation(SubGoal0),
|
GoalExpr0 = negation(SubGoal0),
|
||||||
detect_cse_in_goal(SubGoal0, SubGoal, !CseInfo, InstMap0),
|
detect_cse_in_goal(InstMap0, SubGoal0, SubGoal, !CseInfo),
|
||||||
GoalExpr = negation(SubGoal)
|
GoalExpr = negation(SubGoal)
|
||||||
;
|
;
|
||||||
GoalExpr0 = scope(Reason0, SubGoal0),
|
GoalExpr0 = scope(Reason0, SubGoal0),
|
||||||
@@ -387,12 +417,12 @@ detect_cse_in_goal_update_instmap(Goal0, Goal, !CseInfo, InstMap0, InstMap) :-
|
|||||||
% simpler not to modify such the arms of such switches at all.
|
% simpler not to modify such the arms of such switches at all.
|
||||||
% Since require_switch_arms_detism scopes are rare, the impact
|
% Since require_switch_arms_detism scopes are rare, the impact
|
||||||
% should be negligible in terms of both code size and speed.
|
% should be negligible in terms of both code size and speed.
|
||||||
detect_cse_in_cases_arms(Cases0, Cases, !CseInfo, InstMap0),
|
detect_cse_in_case_arms(InstMap0, Cases0, Cases, !CseInfo),
|
||||||
SubGoalExpr = switch(SwitchVar, CanFail, Cases),
|
SubGoalExpr = switch(SwitchVar, CanFail, Cases),
|
||||||
SubGoal = hlds_goal(SubGoalExpr, SubGoalInfo0),
|
SubGoal = hlds_goal(SubGoalExpr, SubGoalInfo0),
|
||||||
GoalExpr = scope(Reason0, SubGoal)
|
GoalExpr = scope(Reason0, SubGoal)
|
||||||
else
|
else
|
||||||
detect_cse_in_goal(SubGoal0, SubGoal, !CseInfo, InstMap0),
|
detect_cse_in_goal(InstMap0, SubGoal0, SubGoal, !CseInfo),
|
||||||
GoalExpr = scope(Reason0, SubGoal)
|
GoalExpr = scope(Reason0, SubGoal)
|
||||||
)
|
)
|
||||||
;
|
;
|
||||||
@@ -407,12 +437,12 @@ detect_cse_in_goal_update_instmap(Goal0, Goal, !CseInfo, InstMap0, InstMap) :-
|
|||||||
; Reason0 = require_detism(_)
|
; Reason0 = require_detism(_)
|
||||||
; Reason0 = trace_goal(_, _, _, _, _)
|
; Reason0 = trace_goal(_, _, _, _, _)
|
||||||
),
|
),
|
||||||
detect_cse_in_goal(SubGoal0, SubGoal, !CseInfo, InstMap0),
|
detect_cse_in_goal(InstMap0, SubGoal0, SubGoal, !CseInfo),
|
||||||
GoalExpr = scope(Reason0, SubGoal)
|
GoalExpr = scope(Reason0, SubGoal)
|
||||||
)
|
)
|
||||||
;
|
;
|
||||||
GoalExpr0 = conj(ConjType, Goals0),
|
GoalExpr0 = conj(ConjType, Goals0),
|
||||||
detect_cse_in_conj(Goals0, Goals, !CseInfo, ConjType, InstMap0),
|
detect_cse_in_conj(InstMap0, ConjType, Goals0, Goals, !CseInfo),
|
||||||
GoalExpr = conj(ConjType, Goals)
|
GoalExpr = conj(ConjType, Goals)
|
||||||
;
|
;
|
||||||
GoalExpr0 = disj(Goals0),
|
GoalExpr0 = disj(Goals0),
|
||||||
@@ -422,30 +452,30 @@ detect_cse_in_goal_update_instmap(Goal0, Goal, !CseInfo, InstMap0, InstMap) :-
|
|||||||
;
|
;
|
||||||
Goals0 = [_ | _],
|
Goals0 = [_ | _],
|
||||||
NonLocals = goal_info_get_nonlocals(GoalInfo),
|
NonLocals = goal_info_get_nonlocals(GoalInfo),
|
||||||
NonLocalsList = set_of_var.to_sorted_list(NonLocals),
|
NonLocalVars = set_of_var.to_sorted_list(NonLocals),
|
||||||
detect_cse_in_disj(NonLocalsList, Goals0, GoalInfo,
|
detect_cse_in_disj_loop_over_vars(InstMap0, Goals0, GoalInfo,
|
||||||
InstMap0, !CseInfo, GoalExpr)
|
NonLocalVars, GoalExpr, !CseInfo)
|
||||||
)
|
)
|
||||||
;
|
;
|
||||||
GoalExpr0 = switch(Var, CanFail, Cases0),
|
GoalExpr0 = switch(Var, CanFail, Cases0),
|
||||||
NonLocals = goal_info_get_nonlocals(GoalInfo),
|
NonLocals = goal_info_get_nonlocals(GoalInfo),
|
||||||
NonLocalsList = set_of_var.to_sorted_list(NonLocals),
|
NonLocalVars = set_of_var.to_sorted_list(NonLocals),
|
||||||
detect_cse_in_cases(NonLocalsList, Var, CanFail, Cases0, GoalInfo,
|
detect_cse_in_cases_loop_over_vars(InstMap0, Var, CanFail, Cases0,
|
||||||
InstMap0, !CseInfo, GoalExpr)
|
GoalInfo, NonLocalVars, GoalExpr, !CseInfo)
|
||||||
;
|
;
|
||||||
GoalExpr0 = if_then_else(Vars, Cond0, Then0, Else0),
|
GoalExpr0 = if_then_else(QVars, Cond0, Then0, Else0),
|
||||||
NonLocals = goal_info_get_nonlocals(GoalInfo),
|
NonLocals = goal_info_get_nonlocals(GoalInfo),
|
||||||
NonLocalsList = set_of_var.to_sorted_list(NonLocals),
|
NonLocalVars = set_of_var.to_sorted_list(NonLocals),
|
||||||
detect_cse_in_ite(NonLocalsList, Vars, Cond0, Then0, Else0, GoalInfo,
|
detect_cse_in_ite_loop_over_vars(InstMap0, QVars, Cond0, Then0, Else0,
|
||||||
InstMap0, !CseInfo, GoalExpr)
|
GoalInfo, NonLocalVars, GoalExpr, !CseInfo)
|
||||||
;
|
;
|
||||||
GoalExpr0 = shorthand(ShortHand0),
|
GoalExpr0 = shorthand(ShortHand0),
|
||||||
(
|
(
|
||||||
ShortHand0 = atomic_goal(AtomicGoalType, Outer, Inner,
|
ShortHand0 = atomic_goal(AtomicGoalType, Outer, Inner,
|
||||||
MaybeOutputVars, MainGoal0, OrElseGoals0, OrElseInners),
|
MaybeOutputVars, MainGoal0, OrElseGoals0, OrElseInners),
|
||||||
detect_cse_in_goal(MainGoal0, MainGoal, !CseInfo, InstMap0),
|
detect_cse_in_goal(InstMap0, MainGoal0, MainGoal, !CseInfo),
|
||||||
detect_cse_in_independent_goals(OrElseGoals0, OrElseGoals,
|
detect_cse_in_independent_goals(InstMap0,
|
||||||
!CseInfo, InstMap0),
|
OrElseGoals0, OrElseGoals, !CseInfo),
|
||||||
ShortHand = atomic_goal(AtomicGoalType, Outer, Inner,
|
ShortHand = atomic_goal(AtomicGoalType, Outer, Inner,
|
||||||
MaybeOutputVars, MainGoal, OrElseGoals, OrElseInners)
|
MaybeOutputVars, MainGoal, OrElseGoals, OrElseInners)
|
||||||
;
|
;
|
||||||
@@ -456,24 +486,23 @@ detect_cse_in_goal_update_instmap(Goal0, Goal, !CseInfo, InstMap0, InstMap) :-
|
|||||||
ShortHand0 = try_goal(MaybeIO, ResultVar, SubGoal0),
|
ShortHand0 = try_goal(MaybeIO, ResultVar, SubGoal0),
|
||||||
% XXX not sure about this as SubGoal0 is not in its final form.
|
% XXX not sure about this as SubGoal0 is not in its final form.
|
||||||
% Also, mightn't the try "Goal" part get hoisted out?
|
% Also, mightn't the try "Goal" part get hoisted out?
|
||||||
detect_cse_in_goal(SubGoal0, SubGoal, !CseInfo, InstMap0),
|
detect_cse_in_goal(InstMap0, SubGoal0, SubGoal, !CseInfo),
|
||||||
ShortHand = try_goal(MaybeIO, ResultVar, SubGoal)
|
ShortHand = try_goal(MaybeIO, ResultVar, SubGoal)
|
||||||
),
|
),
|
||||||
GoalExpr = shorthand(ShortHand)
|
GoalExpr = shorthand(ShortHand)
|
||||||
),
|
),
|
||||||
Goal = hlds_goal(GoalExpr, GoalInfo),
|
Goal = hlds_goal(GoalExpr, GoalInfo).
|
||||||
InstMapDelta = goal_info_get_instmap_delta(GoalInfo),
|
|
||||||
apply_instmap_delta(InstMapDelta, InstMap0, InstMap).
|
|
||||||
|
|
||||||
%---------------------------------------------------------------------------%
|
%---------------------------------------------------------------------------%
|
||||||
|
|
||||||
:- pred detect_cse_in_conj(list(hlds_goal)::in, list(hlds_goal)::out,
|
:- pred detect_cse_in_conj(instmap::in, conj_type::in,
|
||||||
cse_info::in, cse_info::out, conj_type::in, instmap::in) is det.
|
list(hlds_goal)::in, list(hlds_goal)::out,
|
||||||
|
cse_info::in, cse_info::out) is det.
|
||||||
|
|
||||||
detect_cse_in_conj([], [], !CseInfo, _ConjType, _InstMap).
|
detect_cse_in_conj(_ConjType, _InstMap, [], [], !CseInfo).
|
||||||
detect_cse_in_conj([Goal0 | Goals0], Goals, !CseInfo, ConjType, !.InstMap) :-
|
detect_cse_in_conj(!.InstMap, ConjType, [Goal0 | Goals0], Goals, !CseInfo) :-
|
||||||
detect_cse_in_goal_update_instmap(Goal0, Goal, !CseInfo, !InstMap),
|
detect_cse_in_goal_update_instmap(!InstMap, Goal0, Goal, !CseInfo),
|
||||||
detect_cse_in_conj(Goals0, TailGoals, !CseInfo, ConjType, !.InstMap),
|
detect_cse_in_conj(!.InstMap, ConjType, Goals0, TailGoals, !CseInfo),
|
||||||
% Flatten any non-flat conjunctions we create.
|
% Flatten any non-flat conjunctions we create.
|
||||||
( if
|
( if
|
||||||
Goal = hlds_goal(conj(InnerConjType, ConjGoals), _),
|
Goal = hlds_goal(conj(InnerConjType, ConjGoals), _),
|
||||||
@@ -492,168 +521,179 @@ detect_cse_in_conj([Goal0 | Goals0], Goals, !CseInfo, ConjType, !.InstMap) :-
|
|||||||
% the same functor.
|
% the same functor.
|
||||||
%
|
%
|
||||||
|
|
||||||
:- pred detect_cse_in_disj(list(prog_var)::in, list(hlds_goal)::in,
|
:- pred detect_cse_in_disj_loop_over_vars(instmap::in,
|
||||||
hlds_goal_info::in, instmap::in, cse_info::in, cse_info::out,
|
list(hlds_goal)::in, hlds_goal_info::in, list(prog_var)::in,
|
||||||
hlds_goal_expr::out) is det.
|
hlds_goal_expr::out, cse_info::in, cse_info::out) is det.
|
||||||
|
|
||||||
detect_cse_in_disj([], Goals0, _GoalInfo0, InstMap0, !CseInfo, GoalExpr) :-
|
detect_cse_in_disj_loop_over_vars(InstMap0, Goals0, GoalInfo0, Vars,
|
||||||
% We get here only if we couldn't pull any common unifications
|
GoalExpr, !CseInfo) :-
|
||||||
% out of two or more of the disjuncts represented by Goals0.
|
(
|
||||||
% In that case, we look for transformation opportunities inside
|
Vars = [HeadVar | TailVars],
|
||||||
% *each* disjunct.
|
CseInfo0 = !.CseInfo,
|
||||||
detect_cse_in_independent_goals(Goals0, Goals, !CseInfo, InstMap0),
|
( if
|
||||||
GoalExpr = disj(Goals).
|
common_deconstruct(HeadVar, UnifyGoal, ConsId,
|
||||||
detect_cse_in_disj([Var | Vars], Goals0, GoalInfo0, InstMap0,
|
FirstOldNew, LaterOldNew, Goals0, Goals, !CseInfo)
|
||||||
!CseInfo, GoalExpr) :-
|
then
|
||||||
CseInfo0 = !.CseInfo,
|
instmap_lookup_var(InstMap0, HeadVar, HeadVarInst0),
|
||||||
( if
|
( if may_pull_lhs_inst_cons_id(!.CseInfo, HeadVarInst0, ConsId) then
|
||||||
common_deconstruct(Goals0, Var, !CseInfo, UnifyGoal, ConsId,
|
maybe_update_existential_data_structures(UnifyGoal,
|
||||||
FirstOldNew, LaterOldNew, Goals)
|
FirstOldNew, LaterOldNew, !CseInfo),
|
||||||
then
|
GoalExpr = conj(plain_conj,
|
||||||
instmap_lookup_var(InstMap0, Var, VarInst0),
|
[UnifyGoal, hlds_goal(disj(Goals), GoalInfo0)]),
|
||||||
( if may_pull_lhs_inst_cons_id(!.CseInfo, VarInst0, ConsId) then
|
!CseInfo ^ csei_redo := yes
|
||||||
maybe_update_existential_data_structures(UnifyGoal,
|
else
|
||||||
FirstOldNew, LaterOldNew, !CseInfo),
|
% Throw away any changes made by common_deconstruct above.
|
||||||
GoalExpr = conj(plain_conj,
|
!:CseInfo = CseInfo0,
|
||||||
[UnifyGoal, hlds_goal(disj(Goals), GoalInfo0)]),
|
% Record the fact that we *could* have pulled a deconstruction
|
||||||
!CseInfo ^ csei_redo := yes
|
% out of two or more arms *if* uniqueness in the inst of the
|
||||||
|
% variable concerned didn't stop us.
|
||||||
|
record_pull_decline(UnifyGoal, !CseInfo),
|
||||||
|
detect_cse_in_disj_loop_over_vars(InstMap0, Goals0, GoalInfo0,
|
||||||
|
TailVars, GoalExpr, !CseInfo)
|
||||||
|
)
|
||||||
else
|
else
|
||||||
% Throw away any changes made by common_deconstruct above.
|
detect_cse_in_disj_loop_over_vars(InstMap0, Goals0, GoalInfo0,
|
||||||
!:CseInfo = CseInfo0,
|
TailVars, GoalExpr, !CseInfo)
|
||||||
% Record the fact that we *could* have pulled a deconstruction
|
|
||||||
% out of two or more arms *if* uniqueness in the inst of the
|
|
||||||
% variable concerned didn't stop us.
|
|
||||||
record_pull_decline(UnifyGoal, !CseInfo),
|
|
||||||
detect_cse_in_disj(Vars, Goals0, GoalInfo0, InstMap0,
|
|
||||||
!CseInfo, GoalExpr)
|
|
||||||
)
|
)
|
||||||
else
|
;
|
||||||
detect_cse_in_disj(Vars, Goals0, GoalInfo0, InstMap0,
|
Vars = [],
|
||||||
!CseInfo, GoalExpr)
|
% We get here only if we couldn't pull any common unifications
|
||||||
|
% out of two or more of the disjuncts represented by Goals0.
|
||||||
|
% In that case, we look for transformation opportunities inside
|
||||||
|
% *each* disjunct.
|
||||||
|
detect_cse_in_independent_goals(InstMap0, Goals0, Goals, !CseInfo),
|
||||||
|
GoalExpr = disj(Goals)
|
||||||
).
|
).
|
||||||
|
|
||||||
:- pred detect_cse_in_independent_goals(
|
:- pred detect_cse_in_independent_goals(instmap::in,
|
||||||
list(hlds_goal)::in, list(hlds_goal)::out,
|
list(hlds_goal)::in, list(hlds_goal)::out,
|
||||||
cse_info::in, cse_info::out, instmap::in) is det.
|
cse_info::in, cse_info::out) is det.
|
||||||
|
|
||||||
detect_cse_in_independent_goals([], [], !CseInfo, _).
|
detect_cse_in_independent_goals(_, [], [], !CseInfo).
|
||||||
detect_cse_in_independent_goals([Goal0 | Goals0], [Goal | Goals], !CseInfo,
|
detect_cse_in_independent_goals(InstMap0, [Goal0 | Goals0], [Goal | Goals],
|
||||||
InstMap0) :-
|
!CseInfo) :-
|
||||||
detect_cse_in_goal(Goal0, Goal, !CseInfo, InstMap0),
|
detect_cse_in_goal(InstMap0, Goal0, Goal, !CseInfo),
|
||||||
detect_cse_in_independent_goals(Goals0, Goals, !CseInfo, InstMap0).
|
detect_cse_in_independent_goals(InstMap0, Goals0, Goals, !CseInfo).
|
||||||
|
|
||||||
:- pred detect_cse_in_cases(list(prog_var)::in, prog_var::in, can_fail::in,
|
:- pred detect_cse_in_cases_loop_over_vars(instmap::in, prog_var::in,
|
||||||
list(case)::in, hlds_goal_info::in, instmap::in,
|
can_fail::in, list(case)::in, hlds_goal_info::in, list(prog_var)::in,
|
||||||
cse_info::in, cse_info::out, hlds_goal_expr::out) is det.
|
hlds_goal_expr::out, cse_info::in, cse_info::out) is det.
|
||||||
|
|
||||||
detect_cse_in_cases([], SwitchVar, CanFail, Cases0, _GoalInfo,
|
detect_cse_in_cases_loop_over_vars(InstMap0, SwitchVar, CanFail, Cases0,
|
||||||
InstMap0, !CseInfo, GoalExpr) :-
|
GoalInfo, Vars, GoalExpr, !CseInfo) :-
|
||||||
% We get here only if we couldn't pull any common unifications
|
(
|
||||||
% out of two or more of the switch arms represented by Cases0.
|
Vars = [HeadVar | TailVars],
|
||||||
% In that case, we look for transformation opportunities inside
|
CseInfo0 = !.CseInfo,
|
||||||
% *each* switch arm.
|
( if
|
||||||
detect_cse_in_cases_arms(Cases0, Cases, !CseInfo, InstMap0),
|
HeadVar \= SwitchVar,
|
||||||
GoalExpr = switch(SwitchVar, CanFail, Cases).
|
common_deconstruct_cases(Cases0, HeadVar, !CseInfo, UnifyGoal,
|
||||||
detect_cse_in_cases([Var | Vars], SwitchVar, CanFail, Cases0, GoalInfo,
|
ConsId, FirstOldNew, LaterOldNew, Cases)
|
||||||
InstMap0, !CseInfo, GoalExpr) :-
|
then
|
||||||
CseInfo0 = !.CseInfo,
|
instmap_lookup_var(InstMap0, HeadVar, HeadVarInst0),
|
||||||
( if
|
( if may_pull_lhs_inst_cons_id(!.CseInfo, HeadVarInst0, ConsId) then
|
||||||
Var \= SwitchVar,
|
maybe_update_existential_data_structures(UnifyGoal,
|
||||||
common_deconstruct_cases(Cases0, Var, !CseInfo, UnifyGoal, ConsId,
|
FirstOldNew, LaterOldNew, !CseInfo),
|
||||||
FirstOldNew, LaterOldNew, Cases)
|
SwitchGoalExpr = switch(SwitchVar, CanFail, Cases),
|
||||||
then
|
SwitchGoal = hlds_goal(SwitchGoalExpr, GoalInfo),
|
||||||
instmap_lookup_var(InstMap0, Var, VarInst0),
|
GoalExpr = conj(plain_conj, [UnifyGoal, SwitchGoal]),
|
||||||
( if may_pull_lhs_inst_cons_id(!.CseInfo, VarInst0, ConsId) then
|
!CseInfo ^ csei_redo := yes
|
||||||
maybe_update_existential_data_structures(UnifyGoal,
|
else
|
||||||
FirstOldNew, LaterOldNew, !CseInfo),
|
% Throw away any changes made by common_deconstruct above.
|
||||||
SwitchGoalExpr = switch(SwitchVar, CanFail, Cases),
|
!:CseInfo = CseInfo0,
|
||||||
SwitchGoal = hlds_goal(SwitchGoalExpr, GoalInfo),
|
% Record the fact that we *could* have pulled a deconstruction
|
||||||
GoalExpr = conj(plain_conj, [UnifyGoal, SwitchGoal]),
|
% out of two or more arms *if* uniqueness in the inst of the
|
||||||
!CseInfo ^ csei_redo := yes
|
% variable concerned didn't stop us.
|
||||||
|
record_pull_decline(UnifyGoal, !CseInfo),
|
||||||
|
detect_cse_in_cases_loop_over_vars(InstMap0, SwitchVar,
|
||||||
|
CanFail, Cases0, GoalInfo, TailVars, GoalExpr, !CseInfo)
|
||||||
|
)
|
||||||
else
|
else
|
||||||
% Throw away any changes made by common_deconstruct above.
|
detect_cse_in_cases_loop_over_vars(InstMap0, SwitchVar, CanFail,
|
||||||
!:CseInfo = CseInfo0,
|
Cases0, GoalInfo, TailVars, GoalExpr, !CseInfo)
|
||||||
% Record the fact that we *could* have pulled a deconstruction
|
|
||||||
% out of two or more arms *if* uniqueness in the inst of the
|
|
||||||
% variable concerned didn't stop us.
|
|
||||||
record_pull_decline(UnifyGoal, !CseInfo),
|
|
||||||
detect_cse_in_cases(Vars, SwitchVar, CanFail, Cases0, GoalInfo,
|
|
||||||
InstMap0, !CseInfo, GoalExpr)
|
|
||||||
)
|
)
|
||||||
else
|
;
|
||||||
detect_cse_in_cases(Vars, SwitchVar, CanFail, Cases0, GoalInfo,
|
Vars = [],
|
||||||
InstMap0, !CseInfo, GoalExpr)
|
% We get here only if we couldn't pull any common unifications
|
||||||
|
% out of two or more of the switch arms represented by Cases0.
|
||||||
|
% In that case, we look for transformation opportunities inside
|
||||||
|
% *each* switch arm.
|
||||||
|
detect_cse_in_case_arms(InstMap0, Cases0, Cases, !CseInfo),
|
||||||
|
GoalExpr = switch(SwitchVar, CanFail, Cases)
|
||||||
).
|
).
|
||||||
|
|
||||||
:- pred detect_cse_in_cases_arms(list(case)::in, list(case)::out,
|
:- pred detect_cse_in_case_arms(instmap::in, list(case)::in, list(case)::out,
|
||||||
cse_info::in, cse_info::out, instmap::in) is det.
|
cse_info::in, cse_info::out) is det.
|
||||||
|
|
||||||
detect_cse_in_cases_arms([], [], !CseInfo, _).
|
detect_cse_in_case_arms(_, [], [], !CseInfo).
|
||||||
detect_cse_in_cases_arms([Case0 | Cases0], [Case | Cases], !CseInfo,
|
detect_cse_in_case_arms(InstMap0, [Case0 | Cases0], [Case | Cases],
|
||||||
InstMap0) :-
|
!CseInfo) :-
|
||||||
Case0 = case(MainConsId, OtherConsIds, Goal0),
|
Case0 = case(MainConsId, OtherConsIds, Goal0),
|
||||||
detect_cse_in_goal(Goal0, Goal, !CseInfo, InstMap0),
|
detect_cse_in_goal(InstMap0, Goal0, Goal, !CseInfo),
|
||||||
Case = case(MainConsId, OtherConsIds, Goal),
|
Case = case(MainConsId, OtherConsIds, Goal),
|
||||||
detect_cse_in_cases_arms(Cases0, Cases, !CseInfo, InstMap0).
|
detect_cse_in_case_arms(InstMap0, Cases0, Cases, !CseInfo).
|
||||||
|
|
||||||
:- pred detect_cse_in_ite(list(prog_var)::in, list(prog_var)::in,
|
:- pred detect_cse_in_ite_loop_over_vars(instmap::in, list(prog_var)::in,
|
||||||
hlds_goal::in, hlds_goal::in, hlds_goal::in, hlds_goal_info::in,
|
hlds_goal::in, hlds_goal::in, hlds_goal::in, hlds_goal_info::in,
|
||||||
instmap::in, cse_info::in, cse_info::out, hlds_goal_expr::out) is det.
|
list(prog_var)::in, hlds_goal_expr::out, cse_info::in, cse_info::out)
|
||||||
|
is det.
|
||||||
|
|
||||||
detect_cse_in_ite([], IfVars, Cond0, Then0, Else0, _, InstMap0, !CseInfo,
|
detect_cse_in_ite_loop_over_vars(InstMap0, QVars, Cond0, Then0, Else0,
|
||||||
GoalExpr) :-
|
GoalInfo, Vars, GoalExpr, !CseInfo) :-
|
||||||
% We get here only if we couldn't pull any common unifications
|
(
|
||||||
% out of both arms of the if-then-else. In that case, we look for
|
Vars = [HeadVar | TailVars],
|
||||||
% transformation opportunities inside *each* arm.
|
CseInfo0 = !.CseInfo,
|
||||||
detect_cse_in_ite_arms(Cond0, Cond, Then0, Then, Else0, Else, !CseInfo,
|
( if
|
||||||
InstMap0),
|
common_deconstruct(HeadVar, UnifyGoal, ConsId,
|
||||||
GoalExpr = if_then_else(IfVars, Cond, Then, Else).
|
FirstOldNew, LaterOldNew, [Then0, Else0], Goals, !CseInfo)
|
||||||
detect_cse_in_ite([Var | Vars], IfVars, Cond0, Then0, Else0, GoalInfo,
|
then
|
||||||
InstMap0, !CseInfo, GoalExpr) :-
|
( if Goals = [Then1, Else1] then
|
||||||
CseInfo0 = !.CseInfo,
|
Then = Then1,
|
||||||
( if
|
Else = Else1
|
||||||
common_deconstruct([Then0, Else0], Var, !CseInfo, UnifyGoal, ConsId,
|
else
|
||||||
FirstOldNew, LaterOldNew, Goals)
|
unexpected($pred, "common_deconstruct changes number of goals")
|
||||||
then
|
),
|
||||||
( if Goals = [Then1, Else1] then
|
instmap_lookup_var(InstMap0, HeadVar, HeadVarInst0),
|
||||||
Then = Then1,
|
( if may_pull_lhs_inst_cons_id(!.CseInfo, HeadVarInst0, ConsId) then
|
||||||
Else = Else1
|
maybe_update_existential_data_structures(UnifyGoal,
|
||||||
|
FirstOldNew, LaterOldNew, !CseInfo),
|
||||||
|
IfGoalExpr = if_then_else(QVars, Cond0, Then, Else),
|
||||||
|
IfGoal = hlds_goal(IfGoalExpr, GoalInfo),
|
||||||
|
GoalExpr = conj(plain_conj, [UnifyGoal, IfGoal]),
|
||||||
|
!CseInfo ^ csei_redo := yes
|
||||||
|
else
|
||||||
|
% Throw away any changes made by common_deconstruct above.
|
||||||
|
!:CseInfo = CseInfo0,
|
||||||
|
% Record the fact that we *could* have pulled a deconstruction
|
||||||
|
% out of two or more arms *if* uniqueness in the inst of the
|
||||||
|
% variable concerned didn't stop us.
|
||||||
|
record_pull_decline(UnifyGoal, !CseInfo),
|
||||||
|
detect_cse_in_ite_loop_over_vars(InstMap0, QVars,
|
||||||
|
Cond0, Then0, Else0, GoalInfo, TailVars, GoalExpr, !CseInfo)
|
||||||
|
)
|
||||||
else
|
else
|
||||||
unexpected($pred, "common_deconstruct changes number of goals")
|
detect_cse_in_ite_loop_over_vars(InstMap0, QVars,
|
||||||
),
|
Cond0, Then0, Else0, GoalInfo, TailVars, GoalExpr, !CseInfo)
|
||||||
instmap_lookup_var(InstMap0, Var, VarInst0),
|
|
||||||
( if may_pull_lhs_inst_cons_id(!.CseInfo, VarInst0, ConsId) then
|
|
||||||
maybe_update_existential_data_structures(UnifyGoal,
|
|
||||||
FirstOldNew, LaterOldNew, !CseInfo),
|
|
||||||
IfGoalExpr = if_then_else(IfVars, Cond0, Then, Else),
|
|
||||||
IfGoal = hlds_goal(IfGoalExpr, GoalInfo),
|
|
||||||
GoalExpr = conj(plain_conj, [UnifyGoal, IfGoal]),
|
|
||||||
!CseInfo ^ csei_redo := yes
|
|
||||||
else
|
|
||||||
% Throw away any changes made by common_deconstruct above.
|
|
||||||
!:CseInfo = CseInfo0,
|
|
||||||
% Record the fact that we *could* have pulled a deconstruction
|
|
||||||
% out of two or more arms *if* uniqueness in the inst of the
|
|
||||||
% variable concerned didn't stop us.
|
|
||||||
record_pull_decline(UnifyGoal, !CseInfo),
|
|
||||||
detect_cse_in_ite(Vars, IfVars, Cond0, Then0, Else0, GoalInfo,
|
|
||||||
InstMap0, !CseInfo, GoalExpr)
|
|
||||||
)
|
)
|
||||||
else
|
;
|
||||||
detect_cse_in_ite(Vars, IfVars, Cond0, Then0, Else0, GoalInfo,
|
Vars = [],
|
||||||
InstMap0, !CseInfo, GoalExpr)
|
% We get here only if we couldn't pull any common unifications
|
||||||
|
% out of both arms of the if-then-else. In that case, we look for
|
||||||
|
% transformation opportunities inside *each* arm.
|
||||||
|
detect_cse_in_ite_arms(InstMap0, Cond0, Cond, Then0, Then,
|
||||||
|
Else0, Else, !CseInfo),
|
||||||
|
GoalExpr = if_then_else(QVars, Cond, Then, Else)
|
||||||
).
|
).
|
||||||
|
|
||||||
:- pred detect_cse_in_ite_arms(hlds_goal::in, hlds_goal::out,
|
:- pred detect_cse_in_ite_arms(instmap::in, hlds_goal::in, hlds_goal::out,
|
||||||
hlds_goal::in, hlds_goal::out, hlds_goal::in, hlds_goal::out,
|
hlds_goal::in, hlds_goal::out, hlds_goal::in, hlds_goal::out,
|
||||||
cse_info::in, cse_info::out, instmap::in) is det.
|
cse_info::in, cse_info::out) is det.
|
||||||
|
|
||||||
detect_cse_in_ite_arms(Cond0, Cond, Then0, Then, Else0, Else, !CseInfo,
|
detect_cse_in_ite_arms(InstMap0, Cond0, Cond, Then0, Then, Else0, Else,
|
||||||
InstMap0) :-
|
!CseInfo) :-
|
||||||
detect_cse_in_goal_update_instmap(Cond0, Cond, !CseInfo,
|
detect_cse_in_goal_update_instmap(InstMap0, InstMap1, Cond0, Cond,
|
||||||
InstMap0, InstMap1),
|
!CseInfo),
|
||||||
detect_cse_in_goal(Then0, Then, !CseInfo, InstMap1),
|
detect_cse_in_goal(InstMap1, Then0, Then, !CseInfo),
|
||||||
detect_cse_in_goal(Else0, Else, !CseInfo, InstMap0).
|
detect_cse_in_goal(InstMap0, Else0, Else, !CseInfo).
|
||||||
|
|
||||||
%---------------------------------------------------------------------------%
|
%---------------------------------------------------------------------------%
|
||||||
|
|
||||||
@@ -669,7 +709,7 @@ record_pull_decline(UnifyGoal, !CseInfo) :-
|
|||||||
%---------------------------------------------------------------------------%
|
%---------------------------------------------------------------------------%
|
||||||
|
|
||||||
% common_deconstruct(Goals0, Var, !CseInfo, Unify, ConsId,
|
% common_deconstruct(Goals0, Var, !CseInfo, Unify, ConsId,
|
||||||
% FirstOldNew, LaterOldNew, Goals):
|
% FirstOldNew, LaterOldNew, Goals, !CseInfo):
|
||||||
% input vars:
|
% input vars:
|
||||||
% Goals0 is a list of parallel goals in a branched structure
|
% Goals0 is a list of parallel goals in a branched structure
|
||||||
% (disjunction, if-then-else, or switch).
|
% (disjunction, if-then-else, or switch).
|
||||||
@@ -687,30 +727,30 @@ record_pull_decline(UnifyGoal, !CseInfo) :-
|
|||||||
% in the old unification in the first and later branches respectively
|
% in the old unification in the first and later branches respectively
|
||||||
% to the freshly created argument variables in Unify.
|
% to the freshly created argument variables in Unify.
|
||||||
%
|
%
|
||||||
:- pred common_deconstruct(list(hlds_goal)::in, prog_var::in,
|
:- pred common_deconstruct(prog_var::in, hlds_goal::out, cons_id::out,
|
||||||
cse_info::in, cse_info::out, hlds_goal::out, cons_id::out,
|
|
||||||
assoc_list(prog_var)::out, list(assoc_list(prog_var))::out,
|
assoc_list(prog_var)::out, list(assoc_list(prog_var))::out,
|
||||||
list(hlds_goal)::out) is semidet.
|
list(hlds_goal)::in, list(hlds_goal)::out,
|
||||||
|
cse_info::in, cse_info::out) is semidet.
|
||||||
|
|
||||||
common_deconstruct(Goals0, Var, !CseInfo, Unify, ConsId,
|
common_deconstruct(Var, Unify, ConsId, FirstOldNew, LaterOldNew,
|
||||||
FirstOldNew, LaterOldNew, Goals) :-
|
Goals0, Goals, !CseInfo) :-
|
||||||
CseState0 = before_candidate,
|
CseState0 = before_candidate,
|
||||||
common_deconstruct_branch_goals(Goals0, Var, CseState0, CseState,
|
common_deconstruct_branch_goals(Var, Goals0, Goals,
|
||||||
!CseInfo, Goals),
|
CseState0, CseState, !CseInfo),
|
||||||
CseState = have_candidate(Unify, ConsId, FirstOldNew, LaterOldNew),
|
CseState = have_candidate(Unify, ConsId, FirstOldNew, LaterOldNew),
|
||||||
LaterOldNew = [_ | _].
|
LaterOldNew = [_ | _].
|
||||||
|
|
||||||
:- pred common_deconstruct_branch_goals(list(hlds_goal)::in, prog_var::in,
|
:- pred common_deconstruct_branch_goals(prog_var::in,
|
||||||
cse_state::in, cse_state::out, cse_info::in, cse_info::out,
|
list(hlds_goal)::in, list(hlds_goal)::out,
|
||||||
list(hlds_goal)::out) is semidet.
|
cse_state::in, cse_state::out, cse_info::in, cse_info::out) is semidet.
|
||||||
|
|
||||||
common_deconstruct_branch_goals([], _Var, !CseState, !CseInfo, []).
|
common_deconstruct_branch_goals(_Var, [], [], !CseState, !CseInfo).
|
||||||
common_deconstruct_branch_goals([Goal0 | Goals0], Var, !CseState, !CseInfo,
|
common_deconstruct_branch_goals(Var, [Goal0 | Goals0], [Goal | Goals],
|
||||||
[Goal | Goals]) :-
|
!CseState, !CseInfo) :-
|
||||||
find_bind_var(Var, find_bind_var_for_cse_in_deconstruct,
|
find_bind_var(Var, find_bind_var_for_cse_in_deconstruct,
|
||||||
Goal0, Goal, !CseState, !CseInfo, did_find_deconstruct),
|
Goal0, Goal, !CseState, !CseInfo, did_find_deconstruct),
|
||||||
!.CseState = have_candidate(_, _, _, _),
|
!.CseState = have_candidate(_, _, _, _),
|
||||||
common_deconstruct_branch_goals(Goals0, Var, !CseState, !CseInfo, Goals).
|
common_deconstruct_branch_goals(Var, Goals0, Goals, !CseState, !CseInfo).
|
||||||
|
|
||||||
%---------------------------------------------------------------------------%
|
%---------------------------------------------------------------------------%
|
||||||
|
|
||||||
@@ -947,7 +987,7 @@ pair_subterms([OldVar - HoistedVar | OldHoistedVars], Context, UnifyContext,
|
|||||||
% mode analysis on the resulting goal. It would be nicer to generate
|
% mode analysis on the resulting goal. It would be nicer to generate
|
||||||
% the right assignment unification directly, but that would require
|
% the right assignment unification directly, but that would require
|
||||||
% keeping track of the inst of OldVar.
|
% keeping track of the inst of OldVar.
|
||||||
create_pure_atomic_complicated_unification(HoistedVar, rhs_var(OldVar),
|
create_pure_atomic_complicated_unification(OldVar, rhs_var(HoistedVar),
|
||||||
Context, MainCtxt, SubCtxt, Goal),
|
Context, MainCtxt, SubCtxt, Goal),
|
||||||
Replacements = [Goal | Replacements1]
|
Replacements = [Goal | Replacements1]
|
||||||
).
|
).
|
||||||
@@ -1204,6 +1244,38 @@ print_very_verbose_msg_for_pred(MaybeProgressStream, VeryVerbose,
|
|||||||
true
|
true
|
||||||
).
|
).
|
||||||
|
|
||||||
|
:- pred dump_stage_goal(module_info::in, pred_id::in, proc_id::in,
|
||||||
|
uint::in, uint::in, string::in, io::di, io::uo) is det.
|
||||||
|
|
||||||
|
dump_stage_goal(ModuleInfo, PredId, ProcId, PassNum, DumpNum, Msg, !IO) :-
|
||||||
|
( if proc_to_be_dumped(PredId, ProcId) then
|
||||||
|
string.format("CSE_DEBUG/%u_%u_%s",
|
||||||
|
[u(PassNum), u(DumpNum), s(Msg)], FileName),
|
||||||
|
io.open_output(FileName, OpenResult, !IO),
|
||||||
|
( if OpenResult = ok(FileStream) then
|
||||||
|
module_info_pred_proc_info(ModuleInfo, PredId, ProcId,
|
||||||
|
_, ProcInfo),
|
||||||
|
proc_info_get_var_table(ProcInfo, VarTable),
|
||||||
|
proc_info_get_goal(ProcInfo, Goal),
|
||||||
|
io.format(FileStream, "PASS %u %s\n\n", [u(PassNum), s(Msg)], !IO),
|
||||||
|
dump_goal_nl(FileStream, ModuleInfo, vns_var_table(VarTable),
|
||||||
|
varset.init, varset.init, Goal, !IO),
|
||||||
|
io.nl(FileStream, !IO),
|
||||||
|
io.close_output(FileStream, !IO)
|
||||||
|
else
|
||||||
|
true
|
||||||
|
)
|
||||||
|
else
|
||||||
|
true
|
||||||
|
).
|
||||||
|
|
||||||
|
:- pred proc_to_be_dumped(pred_id::in, proc_id::in) is semidet.
|
||||||
|
|
||||||
|
proc_to_be_dumped(PredId, ProcId) :-
|
||||||
|
% Replace these with the ids of the procedure you wish to debug.
|
||||||
|
pred_id_to_int(PredId) = -1,
|
||||||
|
proc_id_to_int(ProcId) = -1.
|
||||||
|
|
||||||
%---------------------------------------------------------------------------%
|
%---------------------------------------------------------------------------%
|
||||||
:- end_module check_hlds.cse_detection.
|
:- end_module check_hlds.cse_detection.
|
||||||
%---------------------------------------------------------------------------%
|
%---------------------------------------------------------------------------%
|
||||||
|
|||||||
@@ -1370,7 +1370,7 @@ modecheck_queued_proc(ProgressStream, HowToCheckGoal, PredProcId,
|
|||||||
pred_info_set_proc_info(ProcId, ProcInfo3, PredInfo2, PredInfo3),
|
pred_info_set_proc_info(ProcId, ProcInfo3, PredInfo2, PredInfo3),
|
||||||
module_info_set_pred_info(PredId, PredInfo3, !ModuleInfo),
|
module_info_set_pred_info(PredId, PredInfo3, !ModuleInfo),
|
||||||
|
|
||||||
detect_cse_in_proc(maybe.no, PredId, ProcId, !ModuleInfo),
|
detect_cse_in_queued_proc(PredId, ProcId, !ModuleInfo),
|
||||||
determinism_check_proc(ProgressStream, PredId, ProcId,
|
determinism_check_proc(ProgressStream, PredId, ProcId,
|
||||||
DetismSpecs, !ModuleInfo),
|
DetismSpecs, !ModuleInfo),
|
||||||
expect(unify(DetismSpecs, []), $pred, "found detism error"),
|
expect(unify(DetismSpecs, []), $pred, "found detism error"),
|
||||||
|
|||||||
Reference in New Issue
Block a user