From d344165793a5c164d30d34be122e1951a142e7d4 Mon Sep 17 00:00:00 2001 From: Zoltan Somogyi Date: Sat, 20 Apr 1996 08:37:36 +0000 Subject: [PATCH] Add a new option, --branch-delay-slot, intended for use by mc on Estimated hours taken: 3 options: Add a new option, --branch-delay-slot, intended for use by mc on the basis of the configuattion script. It says whether the machine architecture has delays slots on branches. The setting of option should affect whether we set --optimize-delay-slots at -O2, but this doesn't work yet. hlds_goal: Add an extra field to hold follow_vars infromation to disjunctions, switches and if-then-elses. I intend to use this information to generate better code. *.m: Changes to accommodate the extra field. --- compiler/clause_to_proc.m | 3 +- compiler/code_aux.m | 6 +-- compiler/code_gen.pp | 69 ++++++++++++++++-------------- compiler/code_util.m | 6 +-- compiler/constraint.m | 10 ++--- compiler/cse_detection.m | 62 ++++++++++++++------------- compiler/dead_proc_elim.m | 6 +-- compiler/dependency_graph.m | 6 +-- compiler/det_analysis.m | 83 +++++++++++++++++++------------------ compiler/det_report.m | 6 +-- compiler/disj_gen.m | 20 ++++----- compiler/dnf.m | 24 +++++------ compiler/excess.m | 12 +++--- compiler/follow_code.m | 39 +++++++---------- compiler/follow_vars.m | 46 ++++++++++---------- compiler/goal_util.m | 34 ++++++++++----- compiler/higher_order.m | 10 ++--- compiler/hlds_goal.m | 28 +++++++++---- compiler/hlds_out.m | 12 +++--- compiler/inlining.m | 14 +++---- compiler/ite_gen.m | 20 +++++---- compiler/lambda.m | 11 ++--- compiler/live_vars.m | 10 ++--- compiler/liveness.m | 70 ++++++++++++++++--------------- compiler/make_hlds.m | 12 +++--- compiler/mercury_to_c.m | 9 ++-- compiler/middle_rec.m | 4 +- compiler/mode_util.m | 10 ++--- compiler/modes.m | 10 ++--- compiler/options.m | 36 ++++++++++++---- compiler/polymorphism.m | 11 ++--- compiler/quantification.m | 16 +++---- compiler/store_alloc.m | 30 +++++--------- compiler/switch_detection.m | 48 ++++++++++----------- compiler/switch_gen.m | 9 ++-- compiler/tag_switch.m | 2 +- compiler/typecheck.m | 18 ++++---- compiler/unify_proc.m | 22 ++++------ compiler/unique_modes.m | 11 ++--- compiler/unused_args.m | 16 +++---- compiler/value_number.m | 3 +- compiler/vn_verify.m | 7 ++-- 42 files changed, 463 insertions(+), 418 deletions(-) diff --git a/compiler/clause_to_proc.m b/compiler/clause_to_proc.m index cc2189ea7..cf6ca7c27 100644 --- a/compiler/clause_to_proc.m +++ b/compiler/clause_to_proc.m @@ -117,7 +117,8 @@ copy_clauses_to_proc(ProcId, ClausesInfo, Proc0, Proc) :- goal_info_set_context(GoalInfo0, Context, GoalInfo1), set__list_to_set(HeadVars, NonLocalVars), goal_info_set_nonlocals(GoalInfo1, NonLocalVars, GoalInfo), - Goal = disj(GoalList) - GoalInfo + map__init(Empty), + Goal = disj(GoalList, Empty) - GoalInfo ), proc_info_set_body(Proc0, VarSet, VarTypes, HeadVars, Goal, Proc). diff --git a/compiler/code_aux.m b/compiler/code_aux.m index aa2f312b2..4052cc708 100644 --- a/compiler/code_aux.m +++ b/compiler/code_aux.m @@ -94,15 +94,15 @@ code_aux__contains_only_builtins(Goal - _GoalInfo) :- code_aux__contains_only_builtins_2(conj(Goals)) :- code_aux__contains_only_builtins_list(Goals). -code_aux__contains_only_builtins_2(disj(Goals)) :- +code_aux__contains_only_builtins_2(disj(Goals, _)) :- code_aux__contains_only_builtins_list(Goals). -code_aux__contains_only_builtins_2(switch(_Var, _Category, Cases)) :- +code_aux__contains_only_builtins_2(switch(_Var, _Category, Cases, _)) :- code_aux__contains_only_builtins_cases(Cases). code_aux__contains_only_builtins_2(not(Goal)) :- code_aux__contains_only_builtins(Goal). code_aux__contains_only_builtins_2(some(_Vars, Goal)) :- code_aux__contains_only_builtins(Goal). -code_aux__contains_only_builtins_2(if_then_else(_Vars, Cond, Then, Else)) :- +code_aux__contains_only_builtins_2(if_then_else(_Vars, Cond, Then, Else, _)) :- code_aux__contains_only_builtins(Cond), code_aux__contains_only_builtins(Then), code_aux__contains_only_builtins(Else). diff --git a/compiler/code_gen.pp b/compiler/code_gen.pp index 76ca3d2f3..f2f07fe06 100644 --- a/compiler/code_gen.pp +++ b/compiler/code_gen.pp @@ -698,7 +698,7 @@ code_gen__generate_det_goal_2(some(_Vars, Goal), _GoalInfo, Instr) --> code_info__generate_det_commit(Commit), { Instr = tree(PreCommit, tree(GoalCode, Commit)) } ). -code_gen__generate_det_goal_2(disj(_Goals), _GoalInfo, _Instr) --> +code_gen__generate_det_goal_2(disj(_Goals, _FV), _GoalInfo, _Instr) --> { error("Disjunction cannot occur in deterministic code.") }. code_gen__generate_det_goal_2(not(Goal), _GoalInfo, Instr) --> code_gen__generate_negation_general(model_det, Goal, Instr). @@ -713,31 +713,34 @@ code_gen__generate_det_goal_2( code_info__set_succip_used(yes), call_gen__generate_det_call(PredId, ProcId, Args, Instr) ). -code_gen__generate_det_goal_2(switch(Var, CanFail, CaseList), GoalInfo, Instr) --> +code_gen__generate_det_goal_2(switch(Var, CanFail, CaseList, FV), GoalInfo, + Instr) --> { goal_info_store_map(GoalInfo, StoreMap0) }, ( { StoreMap0 = yes(StoreMap) } -> code_info__push_store_map(StoreMap), switch_gen__generate_switch(model_det, Var, CanFail, - CaseList, GoalInfo, Instr), + CaseList, FV, GoalInfo, Instr), code_info__pop_store_map ; - switch_gen__generate_switch(model_det, - Var, CanFail, CaseList, GoalInfo, Instr) + switch_gen__generate_switch(model_det, Var, CanFail, + CaseList, FV, GoalInfo, Instr) ). code_gen__generate_det_goal_2( - if_then_else(_Vars, CondGoal, ThenGoal, ElseGoal), + if_then_else(_Vars, CondGoal, ThenGoal, ElseGoal, FV), GoalInfo, Instr) --> { goal_info_store_map(GoalInfo, StoreMap0) }, ( { StoreMap0 = yes(StoreMap) } -> code_info__push_store_map(StoreMap), - ite_gen__generate_det_ite(CondGoal, ThenGoal, ElseGoal, Instr), + ite_gen__generate_det_ite(CondGoal, ThenGoal, ElseGoal, + FV, Instr), code_info__pop_store_map ; - ite_gen__generate_det_ite(CondGoal, ThenGoal, ElseGoal, Instr) + ite_gen__generate_det_ite(CondGoal, ThenGoal, ElseGoal, + FV, Instr) ). code_gen__generate_det_goal_2(unify(L, R, _U, Uni, _C), _GoalInfo, Instr) --> ( @@ -968,16 +971,16 @@ code_gen__generate_semi_goal_2(some(_Vars, Goal), _GoalInfo, Code) --> code_info__generate_semi_commit(Label, Commit), { Code = tree(PreCommit, tree(GoalCode, Commit)) } ). -code_gen__generate_semi_goal_2(disj(Goals), GoalInfo, Code) --> +code_gen__generate_semi_goal_2(disj(Goals, FV), GoalInfo, Code) --> { goal_info_store_map(GoalInfo, StoreMap0) }, ( { StoreMap0 = yes(StoreMap) } -> code_info__push_store_map(StoreMap), - disj_gen__generate_semi_disj(Goals, Code), + disj_gen__generate_semi_disj(Goals, FV, Code), code_info__pop_store_map ; - disj_gen__generate_semi_disj(Goals, Code) + disj_gen__generate_semi_disj(Goals, FV, Code) ). code_gen__generate_semi_goal_2(not(Goal), _GoalInfo, Code) --> code_gen__generate_negation(Goal, Code). @@ -992,31 +995,34 @@ code_gen__generate_semi_goal_2( code_info__set_succip_used(yes), call_gen__generate_semidet_call(PredId, ProcId, Args, Code) ). -code_gen__generate_semi_goal_2(switch(Var, CanFail, CaseList), GoalInfo, Instr) --> +code_gen__generate_semi_goal_2(switch(Var, CanFail, CaseList, FV), GoalInfo, + Instr) --> { goal_info_store_map(GoalInfo, StoreMap0) }, ( { StoreMap0 = yes(StoreMap) } -> code_info__push_store_map(StoreMap), - switch_gen__generate_switch(model_semi, - Var, CanFail, CaseList, GoalInfo, Instr), + switch_gen__generate_switch(model_semi, Var, CanFail, + CaseList, FV, GoalInfo, Instr), code_info__pop_store_map ; - switch_gen__generate_switch(model_semi, - Var, CanFail, CaseList, GoalInfo, Instr) + switch_gen__generate_switch(model_semi, Var, CanFail, + CaseList, FV, GoalInfo, Instr) ). code_gen__generate_semi_goal_2( - if_then_else(_Vars, CondGoal, ThenGoal, ElseGoal), + if_then_else(_Vars, CondGoal, ThenGoal, ElseGoal, FV), GoalInfo, Instr) --> { goal_info_store_map(GoalInfo, StoreMap0) }, ( { StoreMap0 = yes(StoreMap) } -> code_info__push_store_map(StoreMap), - ite_gen__generate_semidet_ite(CondGoal, ThenGoal, ElseGoal, Instr), + ite_gen__generate_semidet_ite(CondGoal, ThenGoal, ElseGoal, + FV, Instr), code_info__pop_store_map ; - ite_gen__generate_semidet_ite(CondGoal, ThenGoal, ElseGoal, Instr) + ite_gen__generate_semidet_ite(CondGoal, ThenGoal, ElseGoal, + FV, Instr) ). code_gen__generate_semi_goal_2(unify(L, R, _U, Uni, _C), _GoalInfo, Code) --> @@ -1150,16 +1156,16 @@ code_gen__generate_non_goal_2(some(_Vars, Goal), _GoalInfo, Code) --> { Goal = _ - InnerGoalInfo }, { goal_info_get_code_model(InnerGoalInfo, CodeModel) }, code_gen__generate_goal(CodeModel, Goal, Code). -code_gen__generate_non_goal_2(disj(Goals), GoalInfo, Code) --> +code_gen__generate_non_goal_2(disj(Goals, FV), GoalInfo, Code) --> { goal_info_store_map(GoalInfo, StoreMap0) }, ( { StoreMap0 = yes(StoreMap) } -> code_info__push_store_map(StoreMap), - disj_gen__generate_non_disj(Goals, Code), + disj_gen__generate_non_disj(Goals, FV, Code), code_info__pop_store_map ; - disj_gen__generate_non_disj(Goals, Code) + disj_gen__generate_non_disj(Goals, FV, Code) ). code_gen__generate_non_goal_2(not(_Goal), _GoalInfo, _Code) --> { error("Cannot have a nondet negation.") }. @@ -1174,31 +1180,34 @@ code_gen__generate_non_goal_2( code_info__set_succip_used(yes), call_gen__generate_nondet_call(PredId, ProcId, Args, Code) ). -code_gen__generate_non_goal_2(switch(Var, CanFail, CaseList), GoalInfo, Instr) --> +code_gen__generate_non_goal_2(switch(Var, CanFail, CaseList, FV), GoalInfo, + Instr) --> { goal_info_store_map(GoalInfo, StoreMap0) }, ( { StoreMap0 = yes(StoreMap) } -> code_info__push_store_map(StoreMap), - switch_gen__generate_switch(model_non, - Var, CanFail, CaseList, GoalInfo, Instr), + switch_gen__generate_switch(model_non, Var, CanFail, + CaseList, FV, GoalInfo, Instr), code_info__pop_store_map ; - switch_gen__generate_switch(model_non, - Var, CanFail, CaseList, GoalInfo, Instr) + switch_gen__generate_switch(model_non, Var, CanFail, + CaseList, FV, GoalInfo, Instr) ). code_gen__generate_non_goal_2( - if_then_else(_Vars, CondGoal, ThenGoal, ElseGoal), + if_then_else(_Vars, CondGoal, ThenGoal, ElseGoal, FV), GoalInfo, Instr) --> { goal_info_store_map(GoalInfo, StoreMap0) }, ( { StoreMap0 = yes(StoreMap) } -> code_info__push_store_map(StoreMap), - ite_gen__generate_nondet_ite(CondGoal, ThenGoal, ElseGoal, Instr), + ite_gen__generate_nondet_ite(CondGoal, ThenGoal, ElseGoal, + FV, Instr), code_info__pop_store_map ; - ite_gen__generate_nondet_ite(CondGoal, ThenGoal, ElseGoal, Instr) + ite_gen__generate_nondet_ite(CondGoal, ThenGoal, ElseGoal, + FV, Instr) ). code_gen__generate_non_goal_2(unify(_L, _R, _U, _Uni, _C), _GoalInfo, _Code) --> diff --git a/compiler/code_util.m b/compiler/code_util.m index 90695c65b..f8bcf4516 100644 --- a/compiler/code_util.m +++ b/compiler/code_util.m @@ -262,11 +262,11 @@ code_util__goal_may_allocate_heap_2(not(Goal)) :- code_util__goal_may_allocate_heap(Goal). code_util__goal_may_allocate_heap_2(conj(Goals)) :- code_util__goal_list_may_allocate_heap(Goals). -code_util__goal_may_allocate_heap_2(disj(Goals)) :- +code_util__goal_may_allocate_heap_2(disj(Goals, _)) :- code_util__goal_list_may_allocate_heap(Goals). -code_util__goal_may_allocate_heap_2(switch(_Var, _Det, Cases)) :- +code_util__goal_may_allocate_heap_2(switch(_Var, _Det, Cases, _)) :- code_util__cases_may_allocate_heap(Cases). -code_util__goal_may_allocate_heap_2(if_then_else(_Vars, A, B, C)) :- +code_util__goal_may_allocate_heap_2(if_then_else(_Vars, A, B, C, _)) :- ( code_util__goal_may_allocate_heap(A) ; diff --git a/compiler/constraint.m b/compiler/constraint.m index 906270739..c773c866b 100644 --- a/compiler/constraint.m +++ b/compiler/constraint.m @@ -144,19 +144,19 @@ constraint__propagate_goal_2(conj(Goals0), conj(Goals)) --> constraint__propagate_conj(Goals0, Goals), constraint__checkpoint(exit, "conj"). -constraint__propagate_goal_2(disj(Goals0), disj(Goals)) --> +constraint__propagate_goal_2(disj(Goals0, FV), disj(Goals, FV)) --> constraint__checkpoint(enter, "disj"), constraint__propagate_disj(Goals0, Goals), constraint__checkpoint(exit, "disj"). -constraint__propagate_goal_2(switch(Var, Det, Cases0), - switch(Var, Det, Cases)) --> +constraint__propagate_goal_2(switch(Var, Det, Cases0, FV), + switch(Var, Det, Cases, FV)) --> constraint__checkpoint(enter, "switch"), constraint__propagate_cases(Cases0, Cases), constraint__checkpoint(exit, "switch"). -constraint__propagate_goal_2(if_then_else(Vars, Cond0, Then0, Else0), - if_then_else(Vars, Cond, Then, Else)) --> +constraint__propagate_goal_2(if_then_else(Vars, Cond0, Then0, Else0, FV), + if_then_else(Vars, Cond, Then, Else, FV)) --> constraint__checkpoint(enter, "if_then_else"), mode_info_dcg_get_instmap(InstMap0), constraint__propagate_goal(Cond0, Cond), diff --git a/compiler/cse_detection.m b/compiler/cse_detection.m index e18959684..0f614895c 100644 --- a/compiler/cse_detection.m +++ b/compiler/cse_detection.m @@ -230,32 +230,32 @@ detect_cse_in_goal_2(conj(Goals0), _GoalInfo, InstMap, CseInfo0, CseInfo, Redo, conj(Goals)) :- detect_cse_in_conj(Goals0, InstMap, CseInfo0, CseInfo, Redo, Goals). -detect_cse_in_goal_2(disj(Goals0), GoalInfo, InstMap, CseInfo0, CseInfo, +detect_cse_in_goal_2(disj(Goals0, FV), GoalInfo, InstMap, CseInfo0, CseInfo, Redo, Goal) :- ( Goals0 = [] -> CseInfo = CseInfo0, Redo = no, - Goal = disj([]) + Goal = disj([], FV) ; goal_info_get_nonlocals(GoalInfo, NonLocals), set__to_sorted_list(NonLocals, NonLocalsList), detect_cse_in_disj(NonLocalsList, Goals0, GoalInfo, - InstMap, CseInfo0, CseInfo, Redo, Goal) + FV, InstMap, CseInfo0, CseInfo, Redo, Goal) ). -detect_cse_in_goal_2(switch(Var, CanFail, Cases0), GoalInfo, InstMap, +detect_cse_in_goal_2(switch(Var, CanFail, Cases0, FV), GoalInfo, InstMap, CseInfo0, CseInfo, Redo, Goal) :- goal_info_get_nonlocals(GoalInfo, NonLocals), set__to_sorted_list(NonLocals, NonLocalsList), detect_cse_in_cases(NonLocalsList, Var, CanFail, Cases0, GoalInfo, - InstMap, CseInfo0, CseInfo, Redo, Goal). + FV, InstMap, CseInfo0, CseInfo, Redo, Goal). -detect_cse_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0), GoalInfo, +detect_cse_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0, FV), GoalInfo, InstMap, CseInfo0, CseInfo, Redo, Goal) :- goal_info_get_nonlocals(GoalInfo, NonLocals), set__to_sorted_list(NonLocals, NonLocalsList), detect_cse_in_ite(NonLocalsList, Vars, Cond0, Then0, Else0, GoalInfo, - InstMap, CseInfo0, CseInfo, Redo, Goal). + FV, InstMap, CseInfo0, CseInfo, Redo, Goal). %-----------------------------------------------------------------------------% @@ -284,14 +284,14 @@ detect_cse_in_conj([Goal0 | Goals0], InstMap0, CseInfo0, CseInfo, % branch matches that variable against the same functor. :- pred detect_cse_in_disj(list(var), list(hlds__goal), hlds__goal_info, - instmap, cse_info, cse_info, bool, hlds__goal_expr). -:- mode detect_cse_in_disj(in, in, in, in, in, out, out, out) is det. + follow_vars, 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. -detect_cse_in_disj([], Goals0, _, InstMap, CseInfo0, CseInfo, - Redo, disj(Goals)) :- +detect_cse_in_disj([], Goals0, _, FV, InstMap, CseInfo0, CseInfo, + Redo, disj(Goals, FV)) :- detect_cse_in_disj_2(Goals0, InstMap, CseInfo0, CseInfo, Redo, Goals). -detect_cse_in_disj([Var | Vars], Goals0, GoalInfo0, InstMap, CseInfo0, CseInfo, - Redo, Goal) :- +detect_cse_in_disj([Var | Vars], Goals0, GoalInfo0, FV, InstMap, + CseInfo0, CseInfo, Redo, Goal) :- ( instmap_lookup_var(InstMap, Var, VarInst0), CseInfo0 = cse_info(_, _, ModuleInfo), @@ -302,10 +302,10 @@ detect_cse_in_disj([Var | Vars], Goals0, GoalInfo0, InstMap, CseInfo0, CseInfo, Unify, Goals) -> CseInfo = CseInfo1, - Goal = conj([Unify, disj(Goals) - GoalInfo0]), + Goal = conj([Unify, disj(Goals, FV) - GoalInfo0]), Redo = yes ; - detect_cse_in_disj(Vars, Goals0, GoalInfo0, InstMap, + detect_cse_in_disj(Vars, Goals0, GoalInfo0, FV, InstMap, CseInfo0, CseInfo, Redo, Goal) ). @@ -321,14 +321,17 @@ detect_cse_in_disj_2([Goal0 | Goals0], InstMap0, CseInfo0, CseInfo, Redo, bool__or(Redo1, Redo2, Redo). :- pred detect_cse_in_cases(list(var), var, can_fail, list(case), - hlds__goal_info, instmap, cse_info, cse_info, bool, hlds__goal_expr). -:- mode detect_cse_in_cases(in, in, in, in, in, in, in, out, out, out) is det. + hlds__goal_info, follow_vars, 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. -detect_cse_in_cases([], SwitchVar, CanFail, Cases0, _GoalInfo, InstMap, - CseInfo0, CseInfo, Redo, switch(SwitchVar, CanFail, Cases)) :- +detect_cse_in_cases([], SwitchVar, CanFail, Cases0, _GoalInfo, FV, InstMap, + CseInfo0, CseInfo, Redo, + switch(SwitchVar, CanFail, Cases, FV)) :- detect_cse_in_cases_2(Cases0, InstMap, CseInfo0, CseInfo, Redo, Cases). detect_cse_in_cases([Var | Vars], SwitchVar, CanFail, Cases0, GoalInfo, - InstMap, CseInfo0, CseInfo, Redo, Goal) :- + FV, InstMap, CseInfo0, CseInfo, Redo, Goal) :- ( Var \= SwitchVar, instmap_lookup_var(InstMap, Var, VarInst0), @@ -340,12 +343,12 @@ detect_cse_in_cases([Var | Vars], SwitchVar, CanFail, Cases0, GoalInfo, Unify, Cases) -> CseInfo = CseInfo1, - Goal = conj([Unify, switch(SwitchVar, CanFail, Cases) + Goal = conj([Unify, switch(SwitchVar, CanFail, Cases, FV) - GoalInfo]), Redo = yes ; detect_cse_in_cases(Vars, SwitchVar, CanFail, Cases0, GoalInfo, - InstMap, CseInfo0, CseInfo, Redo, Goal) + FV, InstMap, CseInfo0, CseInfo, Redo, Goal) ). :- pred detect_cse_in_cases_2(list(case), instmap, cse_info, cse_info, @@ -363,15 +366,16 @@ detect_cse_in_cases_2([Case0 | Cases0], InstMap, CseInfo0, CseInfo, Redo, :- pred detect_cse_in_ite(list(var), list(var), hlds__goal, hlds__goal, hlds__goal, hlds__goal_info, - instmap, cse_info, cse_info, bool, hlds__goal_expr). -:- mode detect_cse_in_ite(in, in, in, in, in, in, in, in, out, out, out) is det. + follow_vars, 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. -detect_cse_in_ite([], IfVars, Cond0, Then0, Else0, _, InstMap, CseInfo0, - CseInfo, Redo, if_then_else(IfVars, Cond, Then, Else)) :- +detect_cse_in_ite([], IfVars, Cond0, Then0, Else0, _, FV, InstMap, CseInfo0, + CseInfo, Redo, if_then_else(IfVars, Cond, Then, Else, FV)) :- detect_cse_in_ite_2(Cond0, Then0, Else0, InstMap, CseInfo0, CseInfo, Redo, Cond, Then, Else). detect_cse_in_ite([Var | Vars], IfVars, Cond0, Then0, Else0, GoalInfo, - InstMap, CseInfo0, CseInfo, Redo, Goal) :- + FV, InstMap, CseInfo0, CseInfo, Redo, Goal) :- ( CseInfo0 = cse_info(_, _, ModuleInfo), instmap_lookup_var(InstMap, Var, VarInst0), @@ -383,12 +387,12 @@ detect_cse_in_ite([Var | Vars], IfVars, Cond0, Then0, Else0, GoalInfo, Goals = [Then, Else] -> CseInfo = CseInfo1, - Goal = conj([Unify, if_then_else(IfVars, Cond0, Then, Else) + Goal = conj([Unify, if_then_else(IfVars, Cond0, Then, Else, FV) - GoalInfo]), Redo = yes ; detect_cse_in_ite(Vars, IfVars, Cond0, Then0, Else0, GoalInfo, - InstMap, CseInfo0, CseInfo, Redo, Goal) + FV, InstMap, CseInfo0, CseInfo, Redo, Goal) ). :- pred detect_cse_in_ite_2(hlds__goal, hlds__goal, hlds__goal, diff --git a/compiler/dead_proc_elim.m b/compiler/dead_proc_elim.m index 2eb7fd50d..63522761f 100644 --- a/compiler/dead_proc_elim.m +++ b/compiler/dead_proc_elim.m @@ -181,7 +181,7 @@ dead_proc_elim__traverse_goal(GoalExpr - _, Queue0, Queue, Needed0, Needed) :- set(pred_proc_id), set(pred_proc_id)). :- mode dead_proc_elim__traverse_expr(in, in, out, in, out) is det. -dead_proc_elim__traverse_expr(disj(Goals), Queue0, Queue, Needed0, Needed) :- +dead_proc_elim__traverse_expr(disj(Goals, _), Queue0, Queue, Needed0, Needed) :- dead_proc_elim__traverse_goals(Goals, Queue0, Queue, Needed0, Needed). dead_proc_elim__traverse_expr(conj(Goals), Queue0, Queue, Needed0, Needed) :- dead_proc_elim__traverse_goals(Goals, Queue0, Queue, Needed0, Needed). @@ -189,10 +189,10 @@ dead_proc_elim__traverse_expr(not(Goal), Queue0, Queue, Needed0, Needed) :- dead_proc_elim__traverse_goal(Goal, Queue0, Queue, Needed0, Needed). dead_proc_elim__traverse_expr(some(_, Goal), Queue0, Queue, Needed0, Needed) :- dead_proc_elim__traverse_goal(Goal, Queue0, Queue, Needed0, Needed). -dead_proc_elim__traverse_expr(switch(_, _, Cases), Queue0, Queue, +dead_proc_elim__traverse_expr(switch(_, _, Cases, _), Queue0, Queue, Needed0, Needed) :- dead_proc_elim__traverse_cases(Cases, Queue0, Queue, Needed0, Needed). -dead_proc_elim__traverse_expr(if_then_else(_, Cond, Then, Else), +dead_proc_elim__traverse_expr(if_then_else(_, Cond, Then, Else, _), Queue0, Queue, Needed0, Needed) :- dead_proc_elim__traverse_goal(Cond, Queue0, Queue1, Needed0, Needed1), dead_proc_elim__traverse_goal(Then, Queue1, Queue2, Needed1, Needed2), diff --git a/compiler/dependency_graph.m b/compiler/dependency_graph.m index 7462672d0..c844706f7 100644 --- a/compiler/dependency_graph.m +++ b/compiler/dependency_graph.m @@ -175,15 +175,15 @@ dependency_graph__add_arcs_in_goal_2(conj(Goals), Caller, DepGraph0, DepGraph) :- dependency_graph__add_arcs_in_list(Goals, Caller, DepGraph0, DepGraph). -dependency_graph__add_arcs_in_goal_2(disj(Goals), Caller, +dependency_graph__add_arcs_in_goal_2(disj(Goals, _FV), Caller, DepGraph0, DepGraph) :- dependency_graph__add_arcs_in_list(Goals, Caller, DepGraph0, DepGraph). -dependency_graph__add_arcs_in_goal_2(switch(_Var, _Det, Cases), +dependency_graph__add_arcs_in_goal_2(switch(_Var, _Det, Cases, _FV), Caller, DepGraph0, DepGraph) :- dependency_graph__add_arcs_in_cases(Cases, Caller, DepGraph0, DepGraph). -dependency_graph__add_arcs_in_goal_2(if_then_else(_Vars, Cond, Then, Else), +dependency_graph__add_arcs_in_goal_2(if_then_else(_Vars, Cond, Then, Else, _FV), Caller, DepGraph0, DepGraph) :- dependency_graph__add_arcs_in_goal(Cond, Caller, DepGraph0, DepGraph1), dependency_graph__add_arcs_in_goal(Then, Caller, DepGraph1, DepGraph2), diff --git a/compiler/det_analysis.m b/compiler/det_analysis.m index 5e871cbdc..13f1b65c0 100644 --- a/compiler/det_analysis.m +++ b/compiler/det_analysis.m @@ -379,7 +379,7 @@ det_infer_goal(Goal0 - GoalInfo0, InstMap0, SolnContext0, MiscInfo, % See how we should introduce the commit operator, if one is needed. ( - Goal1 = disj(Disjuncts), + Goal1 = disj(Disjuncts, FV), Disjuncts \= [], determinism_components(Detism, _, ExternalSolns), ExternalSolns \= at_most_many @@ -388,7 +388,7 @@ det_infer_goal(Goal0 - GoalInfo0, InstMap0, SolnContext0, MiscInfo, % needs to get converted into an if-then-else or % something similar det_fixup_disj(Disjuncts, InternalDetism, OutputVars, - GoalInfo, InstMap0, MiscInfo, Goal, Msgs1, Msgs) + GoalInfo, FV, InstMap0, MiscInfo, Goal, Msgs1, Msgs) ; Detism \= InternalDetism, Goal1 \= some(_, _) @@ -441,12 +441,12 @@ det_infer_goal(Goal0 - GoalInfo0, InstMap0, SolnContext0, MiscInfo, % % The second argument is the *internal* determinism of the disjunction. -:- pred det_fixup_disj(list(hlds__goal), determinism, bool, - hlds__goal_info, instmap, misc_info, hlds__goal_expr, - list(det_msg), list(det_msg)). -:- mode det_fixup_disj(in, in, in, in, in, in, out, in, out) is det. +:- pred det_fixup_disj(list(hlds__goal), determinism, bool, hlds__goal_info, + follow_vars, instmap, misc_info, hlds__goal_expr, + list(det_msg), list(det_msg)). +:- mode det_fixup_disj(in, in, in, in, in, in, in, out, in, out) is det. -det_fixup_disj(Disjuncts, cc_multidet, OutputVars, GoalInfo, _, _, +det_fixup_disj(Disjuncts, cc_multidet, OutputVars, GoalInfo, _, _, _, Goal, Msgs0, Msgs) :- ( OutputVars = no -> Msgs = [multidet_disj(GoalInfo, Disjuncts) | Msgs0] @@ -456,7 +456,7 @@ det_fixup_disj(Disjuncts, cc_multidet, OutputVars, GoalInfo, _, _, % Same considerations apply to GoalInfos as for det disjunctions % below. det_pick_no_fail_disjunct(Disjuncts, Goal - _). -det_fixup_disj(Disjuncts, multidet, OutputVars, GoalInfo, _, _, +det_fixup_disj(Disjuncts, multidet, OutputVars, GoalInfo, _, _, _, Goal, Msgs0, Msgs) :- ( OutputVars = no -> Msgs = [multidet_disj(GoalInfo, Disjuncts) | Msgs0] @@ -466,11 +466,11 @@ det_fixup_disj(Disjuncts, multidet, OutputVars, GoalInfo, _, _, % Same considerations apply to GoalInfos as for det disjunctions % below. det_pick_no_fail_disjunct(Disjuncts, Goal - _). -det_fixup_disj(Disjuncts, cc_nondet, OutputVars, GoalInfo, _InstMap, _MiscInfo, - Goal, Msgs0, Msgs) :- +det_fixup_disj(Disjuncts, cc_nondet, OutputVars, GoalInfo, FV, + _InstMap, _MiscInfo, Goal, Msgs0, Msgs) :- Msgs = Msgs0, ( OutputVars = no -> - det_disj_to_ite(Disjuncts, GoalInfo, IfThenElse), + det_disj_to_ite(Disjuncts, GoalInfo, FV, IfThenElse), IfThenElse = Goal - _ ; % This is the case of a nondet disjunction in a @@ -479,13 +479,13 @@ det_fixup_disj(Disjuncts, cc_nondet, OutputVars, GoalInfo, _InstMap, _MiscInfo, % variables. We just leave it as a model_semi disjunction; % the code generator will generate similar code to what % it would for an if-then-else. - Goal = disj(Disjuncts) + Goal = disj(Disjuncts, FV) ). -det_fixup_disj(Disjuncts, nondet, OutputVars, GoalInfo, _InstMap, _MiscInfo, - Goal, Msgs0, Msgs) :- +det_fixup_disj(Disjuncts, nondet, OutputVars, GoalInfo, FV, + _InstMap, _MiscInfo, Goal, Msgs0, Msgs) :- Msgs = Msgs0, ( OutputVars = no -> - det_disj_to_ite(Disjuncts, GoalInfo, IfThenElse), + det_disj_to_ite(Disjuncts, GoalInfo, FV, IfThenElse), IfThenElse = Goal - _ ; % This is the case of a nondet disjunction in a @@ -494,9 +494,9 @@ det_fixup_disj(Disjuncts, nondet, OutputVars, GoalInfo, _InstMap, _MiscInfo, % variables. We just leave it as a model_semi disjunction; % the code generator will generate similar code to what % it would for an if-then-else. - Goal = disj(Disjuncts) + Goal = disj(Disjuncts, FV) ). -det_fixup_disj(Disjuncts, det, _OutputVars, GoalInfo, _, _, Goal, +det_fixup_disj(Disjuncts, det, _OutputVars, GoalInfo, _, _, _, Goal, Msgs0, Msgs) :- % We are discarding the GoalInfo of the picked goal; we will % replace it with the GoalInfo inferred for the disjunction @@ -507,24 +507,24 @@ det_fixup_disj(Disjuncts, det, _OutputVars, GoalInfo, _, _, Goal, % errors outside the disjunction. Msgs = [det_disj(GoalInfo, Disjuncts) | Msgs0], det_pick_no_fail_disjunct(Disjuncts, Goal - _). -det_fixup_disj(Disjuncts, semidet, OutputVars, GoalInfo, _, _, Goal, +det_fixup_disj(Disjuncts, semidet, OutputVars, GoalInfo, FV, _, _, Goal, Msgs0, Msgs) :- ( OutputVars = yes -> Msgs = [semidet_disj(GoalInfo, Disjuncts) | Msgs0] ; Msgs = Msgs0 ), - Goal = disj(Disjuncts). -det_fixup_disj(Disjuncts, erroneous, _OutputVars, GoalInfo, _, _, Goal, + Goal = disj(Disjuncts, FV). +det_fixup_disj(Disjuncts, erroneous, _OutputVars, GoalInfo, _, _, _, Goal, Msgs0, Msgs) :- % Same considerations apply to GoalInfos as for det disjunctions % above. Msgs = [zero_soln_disj(GoalInfo, Disjuncts) | Msgs0], det_pick_no_fail_disjunct(Disjuncts, Goal - _). -det_fixup_disj(Disjuncts, failure, _OutputVars, GoalInfo, _, _, Goal, +det_fixup_disj(Disjuncts, failure, _OutputVars, GoalInfo, FV, _, _, Goal, Msgs0, Msgs) :- Msgs = [zero_soln_disj(GoalInfo, Disjuncts) | Msgs0], - Goal = disj(Disjuncts). + Goal = disj(Disjuncts, FV). :- pred det_pick_no_fail_disjunct(list(hlds__goal), hlds__goal). :- mode det_pick_no_fail_disjunct(in, out) is det. @@ -541,9 +541,9 @@ det_pick_no_fail_disjunct([Goal0 | Goals0], Goal) :- det_pick_no_fail_disjunct(Goals0, Goal) ). -:- pred det_disj_to_ite(list(hlds__goal), hlds__goal_info, hlds__goal). -% :- mode det_disj_to_ite(di, in, uo) is det. -:- mode det_disj_to_ite(in, in, out) is det. +:- pred det_disj_to_ite(list(hlds__goal), hlds__goal_info, follow_vars, + hlds__goal). +:- mode det_disj_to_ite(in, in, in, out) is det. % det_disj_to_ite is used to transform disjunctions that occur % in prunable contexts into if-then-elses. @@ -562,8 +562,8 @@ det_pick_no_fail_disjunct([Goal0 | Goals0], Goal) :- % Disjunct3 % ). -det_disj_to_ite([], GoalInfo, disj([]) - GoalInfo). -det_disj_to_ite([Disjunct | Disjuncts], GoalInfo, Goal) :- +det_disj_to_ite([], GoalInfo, FV, disj([], FV) - GoalInfo). +det_disj_to_ite([Disjunct | Disjuncts], GoalInfo, FV, Goal) :- ( Disjuncts = [] -> Goal = Disjunct ; @@ -576,7 +576,7 @@ det_disj_to_ite([Disjunct | Disjuncts], GoalInfo, Goal) :- reachable(InstMap1), InitGoalInfo), Then = conj([]) - InitGoalInfo, - det_disj_to_ite(Disjuncts, GoalInfo, Rest), + det_disj_to_ite(Disjuncts, GoalInfo, FV, Rest), Rest = _RestGoal - RestGoalInfo, goal_info_get_nonlocals(CondGoalInfo, CondNonLocals), @@ -596,7 +596,7 @@ det_disj_to_ite([Disjunct | Disjuncts], GoalInfo, Goal) :- goal_info_set_instmap_delta(NewGoalInfo0, InstMapDelta, NewGoalInfo), - Goal = if_then_else([], Cond, Then, Rest) - NewGoalInfo + Goal = if_then_else([], Cond, Then, Rest, FV) - NewGoalInfo ). %-----------------------------------------------------------------------------% @@ -640,7 +640,7 @@ det_infer_goal_2(conj(Goals0), GoalInfo0, InstMap0, SolnContext, MiscInfo, _, _, ) ). -det_infer_goal_2(disj(Goals0), _, InstMap0, SolnContext, MiscInfo, _, _, +det_infer_goal_2(disj(Goals0, FV), _, InstMap0, SolnContext, MiscInfo, _, _, Goal, Detism, Msgs) :- ( Goals0 = [SingleGoal0] -> % a singleton disjunction is equivalent to the goal itself @@ -649,7 +649,7 @@ det_infer_goal_2(disj(Goals0), _, InstMap0, SolnContext, MiscInfo, _, _, ; det_infer_disj(Goals0, InstMap0, SolnContext, MiscInfo, can_fail, at_most_zero, Goals, Detism, Msgs), - Goal = disj(Goals) + Goal = disj(Goals, FV) ). % The determinism of a switch is the worst of the determinism of each @@ -657,9 +657,9 @@ det_infer_goal_2(disj(Goals0), _, InstMap0, SolnContext, MiscInfo, _, _, % then it is semideterministic or worse - this is determined % in switch_detection.m and handled via the SwitchCanFail field. -det_infer_goal_2(switch(Var, SwitchCanFail, Cases0), _, InstMap0, SolnContext, - MiscInfo, _, _, - switch(Var, SwitchCanFail, Cases), Detism, Msgs) :- +det_infer_goal_2(switch(Var, SwitchCanFail, Cases0, FV), _, + InstMap0, SolnContext, MiscInfo, _, _, + switch(Var, SwitchCanFail, Cases, FV), Detism, Msgs) :- det_infer_switch(Cases0, InstMap0, SolnContext, MiscInfo, cannot_fail, at_most_zero, Cases, CasesDetism, Msgs), determinism_components(CasesDetism, CasesCanFail, CasesSolns), @@ -708,8 +708,8 @@ det_infer_goal_2(unify(LT, RT0, M, U, C), GoalInfo, InstMap0, _SolnContext, ), det_infer_unify(U, UnifyDet). -det_infer_goal_2(if_then_else(Vars, Cond0, Then0, Else0), GoalInfo0, InstMap0, - SolnContext, MiscInfo, NonLocalVars, DeltaInstMap, +det_infer_goal_2(if_then_else(Vars, Cond0, Then0, Else0, FV), GoalInfo0, + InstMap0, SolnContext, MiscInfo, NonLocalVars, DeltaInstMap, Goal, Detism, Msgs) :- % We process the goal right-to-left, doing the `then' before @@ -789,7 +789,7 @@ det_infer_goal_2(if_then_else(Vars, Cond0, Then0, Else0), GoalInfo0, InstMap0, % % Finally combine the results from the three parts % - Goal = if_then_else(Vars, Cond, Then, Else), + Goal = if_then_else(Vars, Cond, Then, Else, FV), det_conjunction_maxsoln(CondSolns, ThenSolns, AllThenSolns), det_switch_maxsoln(AllThenSolns, ElseSolns, Solns), det_switch_canfail(ThenCanFail, ElseCanFail, CanFail), @@ -817,13 +817,14 @@ det_infer_goal_2(not(Goal0), _, InstMap0, _SolnContext, MiscInfo, _, _, Goal, ; MaybeDet = yes(Det), ( - % replace `not true' with `fail' + % replace `not true' with `fail' Goal1 = conj([]) - _GoalInfo -> - Goal = disj([]) + map__init(Empty), + Goal = disj([], Empty) ; - % replace `not fail' with `true' - Goal1 = disj([]) - _GoalInfo2 + % replace `not fail' with `true' + Goal1 = disj([], _) - _GoalInfo2 -> Goal = conj([]) ; diff --git a/compiler/det_report.m b/compiler/det_report.m index 3636f6ef3..6d8ccc181 100644 --- a/compiler/det_report.m +++ b/compiler/det_report.m @@ -287,7 +287,7 @@ det_diagnose_goal_2(conj(Goals), _GoalInfo, Desired, _Actual, Context, MiscInfo, Diagnosed) --> det_diagnose_conj(Goals, Desired, Context, MiscInfo, Diagnosed). -det_diagnose_goal_2(disj(Goals), GoalInfo, Desired, _Actual, SwitchContext, +det_diagnose_goal_2(disj(Goals, _), GoalInfo, Desired, _Actual, SwitchContext, MiscInfo, Diagnosed) --> det_diagnose_disj(Goals, Desired, SwitchContext, MiscInfo, 0, Clauses, Diagnosed1), @@ -309,7 +309,7 @@ det_diagnose_goal_2(disj(Goals), GoalInfo, Desired, _Actual, SwitchContext, % then it is semideterministic or worse - this is determined % in switch_detection.m and handled via the CanFail field. -det_diagnose_goal_2(switch(Var, SwitchCanFail, Cases), GoalInfo, +det_diagnose_goal_2(switch(Var, SwitchCanFail, Cases, _), GoalInfo, Desired, _Actual, SwitchContext, MiscInfo, Diagnosed) --> ( { SwitchCanFail = can_fail }, @@ -414,7 +414,7 @@ det_diagnose_goal_2(unify(LT, RT, _, _, UnifyContext), GoalInfo, io__write_string(".\n") ). -det_diagnose_goal_2(if_then_else(_Vars, Cond, Then, Else), _GoalInfo, +det_diagnose_goal_2(if_then_else(_Vars, Cond, Then, Else, _), _GoalInfo, Desired, _Actual, SwitchContext, MiscInfo, Diagnosed) --> { determinism_components(Desired, _DesiredCanFail, DesiredSolns), diff --git a/compiler/disj_gen.m b/compiler/disj_gen.m index 42d521bd8..abfd88e33 100644 --- a/compiler/disj_gen.m +++ b/compiler/disj_gen.m @@ -17,13 +17,13 @@ :- import_module hlds_goal, llds, code_gen, code_info, code_util, std_util. -:- pred disj_gen__generate_semi_disj(list(hlds__goal), +:- pred disj_gen__generate_semi_disj(list(hlds__goal), follow_vars, code_tree, code_info, code_info). -:- mode disj_gen__generate_semi_disj(in, out, in, out) is det. +:- mode disj_gen__generate_semi_disj(in, in, out, in, out) is det. -:- pred disj_gen__generate_non_disj(list(hlds__goal), +:- pred disj_gen__generate_non_disj(list(hlds__goal), follow_vars, code_tree, code_info, code_info). -:- mode disj_gen__generate_non_disj(in, out, in, out) is det. +:- mode disj_gen__generate_non_disj(in, in, out, in, out) is det. %---------------------------------------------------------------------------% :- implementation. @@ -33,18 +33,18 @@ %---------------------------------------------------------------------------% -disj_gen__generate_semi_disj(Goals, Code) --> +disj_gen__generate_semi_disj(Goals, FollowVars, Code) --> ( { Goals = [] } -> code_info__generate_failure(Code) ; - disj_gen__generate_semi_disj_2(Goals, Code) + disj_gen__generate_semi_disj_2(Goals, FollowVars, Code) ). -:- pred disj_gen__generate_semi_disj_2(list(hlds__goal), +:- pred disj_gen__generate_semi_disj_2(list(hlds__goal), follow_vars, code_tree, code_info, code_info). -:- mode disj_gen__generate_semi_disj_2(in, out, in, out) is det. +:- mode disj_gen__generate_semi_disj_2(in, in, out, in, out) is det. -disj_gen__generate_semi_disj_2(Goals, Code) --> +disj_gen__generate_semi_disj_2(Goals, _FollowVars, Code) --> code_info__generate_nondet_saves(SaveVarsCode), /**** % This heap restore code only works for goals with no output variables. @@ -129,7 +129,7 @@ disj_gen__generate_semi_cases([Goal|Goals], EndLabel, GoalsCode) --> %---------------------------------------------------------------------------% -disj_gen__generate_non_disj(Goals1, Code) --> +disj_gen__generate_non_disj(Goals1, _FollowVars, Code) --> % Sanity check { Goals1 = [] -> diff --git a/compiler/dnf.m b/compiler/dnf.m index 7f9f2ebfc..76081a86e 100644 --- a/compiler/dnf.m +++ b/compiler/dnf.m @@ -181,24 +181,24 @@ dnf__transform_goal(Goal0, InstMap0, MaybeNonAtomic, ModuleInfo0, ModuleInfo, Goals, NewPredIds0, NewPredIds), Goal = conj(Goals) - GoalInfo ; - GoalExpr0 = disj(Goals0), + GoalExpr0 = disj(Goals0, FV), dnf__transform_disj(Goals0, InstMap0, MaybeNonAtomic, ModuleInfo0, ModuleInfo, Base, 0, DnfInfo, Goals, NewPredIds0, NewPredIds), - Goal = disj(Goals) - GoalInfo + Goal = disj(Goals, FV) - GoalInfo ; - GoalExpr0 = switch(Var, CanFail, Cases0), + GoalExpr0 = switch(Var, CanFail, Cases0, FV), dnf__transform_switch(Cases0, InstMap0, MaybeNonAtomic, ModuleInfo0, ModuleInfo, Base, 0, DnfInfo, Cases, NewPredIds0, NewPredIds), - Goal = switch(Var, CanFail, Cases) - GoalInfo + Goal = switch(Var, CanFail, Cases, FV) - GoalInfo ; - GoalExpr0 = if_then_else(Vars, Cond0, Then0, Else0), + GoalExpr0 = if_then_else(Vars, Cond0, Then0, Else0, FV), % XXX should handle nonempty Vars dnf__transform_ite(Cond0, Then0, Else0, InstMap0, MaybeNonAtomic, ModuleInfo0, ModuleInfo, Base, 0, DnfInfo, Cond, Then, Else, NewPredIds0, NewPredIds), - Goal = if_then_else(Vars, Cond, Then, Else) - GoalInfo + Goal = if_then_else(Vars, Cond, Then, Else, FV) - GoalInfo ; GoalExpr0 = call(_, _, _, _, _, _, _), ModuleInfo = ModuleInfo0, @@ -424,13 +424,13 @@ dnf__is_considered_atomic_expr(GoalExpr, MaybeNonAtomic) :- dnf__is_atomic_expr(conj(_), no). dnf__is_atomic_expr(call(_, _, _, _, _, _, _), yes). -dnf__is_atomic_expr(switch(_, _, _), no). +dnf__is_atomic_expr(switch(_, _, _, _), no). dnf__is_atomic_expr(unify(_, _, _, _, _), yes). -dnf__is_atomic_expr(disj(_), no). +dnf__is_atomic_expr(disj(_, _), no). dnf__is_atomic_expr(not(_), no). dnf__is_atomic_expr(some(_, GoalExpr - _), IsAtomic) :- dnf__is_atomic_expr(GoalExpr, IsAtomic). -dnf__is_atomic_expr(if_then_else(_, _, _, _), no). +dnf__is_atomic_expr(if_then_else(_, _, _, _, _), no). dnf__is_atomic_expr(pragma_c_code(_, _, _, _, _), yes). :- pred dnf__expr_free_of_nonatomic(hlds__goal_expr::in, @@ -440,16 +440,16 @@ dnf__expr_free_of_nonatomic(conj(Goals), NonAtomic) :- dnf__goals_free_of_nonatomic(Goals, NonAtomic). dnf__expr_free_of_nonatomic(call(PredId, ProcId, _, _, _, _, _), NonAtomic) :- \+ set__member(proc(PredId, ProcId), NonAtomic). -dnf__expr_free_of_nonatomic(switch(_, _, Cases), NonAtomic) :- +dnf__expr_free_of_nonatomic(switch(_, _, Cases, _), NonAtomic) :- dnf__cases_free_of_nonatomic(Cases, NonAtomic). dnf__expr_free_of_nonatomic(unify(_, _, _, _, _), _NonAtomic). -dnf__expr_free_of_nonatomic(disj(Goals), NonAtomic) :- +dnf__expr_free_of_nonatomic(disj(Goals, _), NonAtomic) :- dnf__goals_free_of_nonatomic(Goals, NonAtomic). dnf__expr_free_of_nonatomic(not(Goal), NonAtomic) :- dnf__goal_free_of_nonatomic(Goal, NonAtomic). dnf__expr_free_of_nonatomic(some(_, Goal), NonAtomic) :- dnf__goal_free_of_nonatomic(Goal, NonAtomic). -dnf__expr_free_of_nonatomic(if_then_else(_, Cond, Then, Else), NonAtomic) :- +dnf__expr_free_of_nonatomic(if_then_else(_, Cond, Then, Else, _), NonAtomic) :- dnf__goal_free_of_nonatomic(Cond, NonAtomic), dnf__goal_free_of_nonatomic(Then, NonAtomic), dnf__goal_free_of_nonatomic(Else, NonAtomic). diff --git a/compiler/excess.m b/compiler/excess.m index b194ac102..f2f5d129d 100644 --- a/compiler/excess.m +++ b/compiler/excess.m @@ -132,25 +132,25 @@ excess_assignments_in_goal(GoalExpr0 - GoalInfo0, ElimVars0, Goal, ElimVars) :- Goals, ElimVars), conj_list_to_goal(Goals, GoalInfo0, Goal) ; - GoalExpr0 = disj(Goals0), + GoalExpr0 = disj(Goals0, FV), excess_assignments_in_disj(Goals0, ElimVars0, Goals, ElimVars), - Goal = disj(Goals) - GoalInfo0 + Goal = disj(Goals, FV) - GoalInfo0 ; GoalExpr0 = not(NegGoal0), excess_assignments_in_goal(NegGoal0, ElimVars0, NegGoal, ElimVars), Goal = not(NegGoal) - GoalInfo0 ; - GoalExpr0 = switch(Var, CanFail, Cases0), + GoalExpr0 = switch(Var, CanFail, Cases0, FV), excess_assignments_in_switch(Cases0, ElimVars0, Cases, ElimVars), - Goal = switch(Var, CanFail, Cases) - GoalInfo0 + Goal = switch(Var, CanFail, Cases, FV) - GoalInfo0 ; - GoalExpr0 = if_then_else(Vars, Cond0, Then0, Else0), + GoalExpr0 = if_then_else(Vars, Cond0, Then0, Else0, FV), excess_assignments_in_goal(Cond0, ElimVars0, Cond, ElimVars1), excess_assignments_in_goal(Then0, ElimVars1, Then, ElimVars2), excess_assignments_in_goal(Else0, ElimVars2, Else, ElimVars), - Goal = if_then_else(Vars, Cond, Then, Else) - GoalInfo0 + Goal = if_then_else(Vars, Cond, Then, Else, FV) - GoalInfo0 ; GoalExpr0 = some(Var, SubGoal0), excess_assignments_in_goal(SubGoal0, ElimVars0, diff --git a/compiler/follow_code.m b/compiler/follow_code.m index e5a11cd70..aef05366f 100644 --- a/compiler/follow_code.m +++ b/compiler/follow_code.m @@ -29,7 +29,8 @@ :- implementation. -:- import_module hlds_goal, hlds_data, det_analysis, mode_util, quantification. +:- import_module hlds_goal, hlds_data, goal_util, mode_util. +:- import_module det_analysis, quantification. :- import_module list, map, set. :- import_module term, require. @@ -120,18 +121,18 @@ move_follow_code_in_goal(Goal0 - GoalInfo, Goal - GoalInfo, Flags, R0, R) :- move_follow_code_in_goal_2(conj(Goals0), conj(Goals), Flags, R0, R) :- move_follow_code_in_conj(Goals0, Goals, Flags, R0, R). -move_follow_code_in_goal_2(disj(Goals0), disj(Goals), Flags, R0, R) :- +move_follow_code_in_goal_2(disj(Goals0, FV), disj(Goals, FV), Flags, R0, R) :- move_follow_code_in_disj(Goals0, Goals, Flags, R0, R). move_follow_code_in_goal_2(not(Goal0), not(Goal), Flags, R0, R) :- move_follow_code_in_goal(Goal0, Goal, Flags, R0, R). -move_follow_code_in_goal_2(switch(Var, Det, Cases0), - switch(Var, Det, Cases), Flags, R0, R) :- +move_follow_code_in_goal_2(switch(Var, Det, Cases0, FV), + switch(Var, Det, Cases, FV), Flags, R0, R) :- move_follow_code_in_cases(Cases0, Cases, Flags, R0, R). -move_follow_code_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0), - if_then_else(Vars, Cond, Then, Else), Flags, R0, R) :- +move_follow_code_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0, FV), + if_then_else(Vars, Cond, Then, Else, FV), Flags, R0, R) :- move_follow_code_in_goal(Cond0, Cond, Flags, R0, R1), move_follow_code_in_goal(Then0, Then, Flags, R1, R2), move_follow_code_in_goal(Else0, Else, Flags, R2, R). @@ -194,7 +195,8 @@ move_follow_code_in_conj_2([Goal0 | Goals0], RevPrevGoals0, RevPrevGoals, Flags = PushFollowCode - PushPrevCode, ( PushFollowCode = yes, - move_follow_code_is_branched(Goal0), + Goal0 = GoalExpr0 - _, + goal_util__goal_is_branched(GoalExpr0), move_follow_code_select(Goals0, FollowGoals, RestGoalsPrime), FollowGoals \= [], move_follow_code_move_goals(Goal0, FollowGoals, Goal1Prime) @@ -253,18 +255,18 @@ move_follow_code_select([Goal|Goals], FollowGoals, RestGoals) :- move_follow_code_move_goals(Goal0 - GoalInfo, FollowGoals, Goal - GoalInfo) :- ( - Goal0 = switch(Var, Det, Cases0), + Goal0 = switch(Var, Det, Cases0, FV), move_follow_code_move_goals_cases(Cases0, FollowGoals, Cases), - Goal = switch(Var, Det, Cases) + Goal = switch(Var, Det, Cases, FV) ; - Goal0 = disj(Goals0), + Goal0 = disj(Goals0, FV), move_follow_code_move_goals_disj(Goals0, FollowGoals, Goals), - Goal = disj(Goals) + Goal = disj(Goals, FV) ; - Goal0 = if_then_else(Vars, Cond, Then0, Else0), + Goal0 = if_then_else(Vars, Cond, Then0, Else0, FV), conjoin_goal_and_goal_list(Then0, FollowGoals, Then), conjoin_goal_and_goal_list(Else0, FollowGoals, Else), - Goal = if_then_else(Vars, Cond, Then, Else) + Goal = if_then_else(Vars, Cond, Then, Else, FV) ). %-----------------------------------------------------------------------------% @@ -327,17 +329,6 @@ check_follow_code_detism([_ - GoalInfo | Goals], CanFail0, MaxSolns0) :- det_conjunction_canfail(CanFail0, CanFail1, CanFail0), check_follow_code_detism(Goals, CanFail0, MaxSolns0). -%-----------------------------------------------------------------------------% - - % See if the given goal has multiple paths through it. - -:- pred move_follow_code_is_branched(hlds__goal). -:- mode move_follow_code_is_branched(in) is semidet. - -move_follow_code_is_branched(switch(_,_,_) - _GoalInfo). -move_follow_code_is_branched(if_then_else(_,_,_,_) - _GoalInfo). -move_follow_code_is_branched(disj(_) - _GoalInfo). - %-----------------------------------------------------------------------------% :- pred move_follow_code_is_builtin(hlds__goal). diff --git a/compiler/follow_vars.m b/compiler/follow_vars.m index 37b5aa95a..15dccbda5 100644 --- a/compiler/follow_vars.m +++ b/compiler/follow_vars.m @@ -5,6 +5,7 @@ %-----------------------------------------------------------------------------% % Main author: conway. +% Major modification by zs. % This module traverses the goal for every procedure, filling in the % follow_vars field for call(...) goals, and filling in the initial @@ -143,58 +144,59 @@ find_follow_vars_in_goal(Goal0 - GoalInfo, ModuleInfo, FollowVars0, %-----------------------------------------------------------------------------% :- pred find_follow_vars_in_goal_2(hlds__goal_expr, module_info, follow_vars, - hlds__goal_expr, follow_vars). + hlds__goal_expr, follow_vars). :- mode find_follow_vars_in_goal_2(in, in, in, out, out) is det. find_follow_vars_in_goal_2(conj(Goals0), ModuleInfo, FollowVars0, - conj(Goals), FollowVars) :- + conj(Goals), FollowVars) :- find_follow_vars_in_conj(Goals0, ModuleInfo, FollowVars0, Goals, - FollowVars). + FollowVars). -find_follow_vars_in_goal_2(disj(Goals0), ModuleInfo, FollowVars0, - disj(Goals), FollowVars) :- +find_follow_vars_in_goal_2(disj(Goals0, _), ModuleInfo, FollowVars0, + disj(Goals, FollowVars0), FollowVars) :- find_follow_vars_in_disj(Goals0, ModuleInfo, FollowVars0, Goals, - FollowVars). + FollowVars). find_follow_vars_in_goal_2(not(Goal0), ModuleInfo, FollowVars0, - not(Goal), FollowVars) :- + not(Goal), FollowVars) :- find_follow_vars_in_goal(Goal0, ModuleInfo, FollowVars0, Goal, - FollowVars). + FollowVars). -find_follow_vars_in_goal_2(switch(Var, Det, Cases0), - ModuleInfo, FollowVars0, switch(Var, Det, Cases), FollowVars) :- +find_follow_vars_in_goal_2(switch(Var, Det, Cases0, _), ModuleInfo, FollowVars0, + switch(Var, Det, Cases, FollowVars0), FollowVars) :- find_follow_vars_in_cases(Cases0, ModuleInfo, FollowVars0, - Cases, FollowVars). + Cases, FollowVars). -find_follow_vars_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0), - ModuleInfo, FollowVars0, - if_then_else(Vars, Cond, Then, Else), FollowVars) :- +find_follow_vars_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0, _), + ModuleInfo, FollowVars0, + if_then_else(Vars, Cond, Then, Else, FollowVars0), + FollowVars) :- find_follow_vars_in_goal(Then0, ModuleInfo, FollowVars0, Then, - FollowVars1), + FollowVars1), find_follow_vars_in_goal(Cond0, ModuleInfo, FollowVars1, Cond, - FollowVars), + FollowVars), % To a first approximation, ignore the else branch. find_follow_vars_in_goal(Else0, ModuleInfo, FollowVars0, Else, _FollowVars1A). find_follow_vars_in_goal_2(some(Vars, Goal0), ModuleInfo, FollowVars0, - some(Vars, Goal), FollowVars) :- + some(Vars, Goal), FollowVars) :- find_follow_vars_in_goal(Goal0, ModuleInfo, FollowVars0, Goal, FollowVars). find_follow_vars_in_goal_2(call(A,B,C,D,E,F,_), ModuleInfo, FollowVars0, - call(A,B,C,D,E,F, FollowVars0), FollowVars) :- + call(A,B,C,D,E,F, FollowVars0), FollowVars) :- ( hlds__is_builtin_is_inline(D) -> FollowVars = FollowVars0 ; - find_follow_vars_in_call(A, B, C, ModuleInfo, - FollowVars0, FollowVars) + find_follow_vars_in_call(A, B, C, ModuleInfo, FollowVars0, + FollowVars) ). find_follow_vars_in_goal_2(unify(A,B,C,D0,E), _ModuleInfo, FollowVars0, - unify(A,B,C,D,E), FollowVars) :- + unify(A,B,C,D,E), FollowVars) :- ( B = var(BVar), D0 = complicated_unify(Mode, CanFail, _F), @@ -203,7 +205,7 @@ find_follow_vars_in_goal_2(unify(A,B,C,D0,E), _ModuleInfo, FollowVars0, map__init(Follow0), arg_info__unify_arg_info(CodeModel, ArgInfo), find_follow_vars_in_call_2(ArgInfo, [A, BVar], - Follow0, FollowVars1) + Follow0, FollowVars1) -> D = complicated_unify(Mode, CanFail, FollowVars0), FollowVars = FollowVars1 diff --git a/compiler/goal_util.m b/compiler/goal_util.m index b5f24d4f8..88b8db2c0 100644 --- a/compiler/goal_util.m +++ b/compiler/goal_util.m @@ -55,6 +55,9 @@ :- mode goal_util__create_variables(in, in, in, in, in, in, out, out, out) is det. +:- pred goal_util__goal_is_branched(hlds__goal_expr). +:- mode goal_util__goal_is_branched(in) is semidet. + %-----------------------------------------------------------------------------% %-----------------------------------------------------------------------------% @@ -157,20 +160,23 @@ goal_util__rename_vars_in_goal(Goal0 - GoalInfo0, Must, Subn, Goal - GoalInfo) : goal_util__name_apart_2(conj(Goals0), Must, Subn, conj(Goals)) :- goal_util__name_apart_list(Goals0, Must, Subn, Goals). -goal_util__name_apart_2(disj(Goals0), Must, Subn, disj(Goals)) :- - goal_util__name_apart_list(Goals0, Must, Subn, Goals). +goal_util__name_apart_2(disj(Goals0, FV0), Must, Subn, disj(Goals, FV)) :- + goal_util__name_apart_list(Goals0, Must, Subn, Goals), + goal_util__rename_follow_vars(FV0, Must, Subn, FV). -goal_util__name_apart_2(switch(Var0, Det, Cases0), Must, Subn, - switch(Var, Det, Cases)) :- +goal_util__name_apart_2(switch(Var0, Det, Cases0, FV0), Must, Subn, + switch(Var, Det, Cases, FV)) :- goal_util__rename_var(Var0, Must, Subn, Var), - goal_util__name_apart_cases(Cases0, Must, Subn, Cases). + goal_util__name_apart_cases(Cases0, Must, Subn, Cases), + goal_util__rename_follow_vars(FV0, Must, Subn, FV). -goal_util__name_apart_2(if_then_else(Vars0, Cond0, Then0, Else0), Must, Subn, - if_then_else(Vars, Cond, Then, Else)) :- +goal_util__name_apart_2(if_then_else(Vars0, Cond0, Then0, Else0, FV0), + Must, Subn, if_then_else(Vars, Cond, Then, Else, FV)) :- goal_util__rename_var_list(Vars0, Must, Subn, Vars), goal_util__rename_vars_in_goal(Cond0, Must, Subn, Cond), goal_util__rename_vars_in_goal(Then0, Must, Subn, Then), - goal_util__rename_vars_in_goal(Else0, Must, Subn, Else). + goal_util__rename_vars_in_goal(Else0, Must, Subn, Else), + goal_util__rename_follow_vars(FV0, Must, Subn, FV). goal_util__name_apart_2(not(Goal0), Must, Subn, not(Goal)) :- goal_util__rename_vars_in_goal(Goal0, Must, Subn, Goal). @@ -180,11 +186,11 @@ goal_util__name_apart_2(some(Vars0, Goal0), Must, Subn, some(Vars, Goal)) :- goal_util__rename_vars_in_goal(Goal0, Must, Subn, Goal). goal_util__name_apart_2( - call(PredId, ProcId, Args0, Builtin, Context, Sym, Follow0), + call(PredId, ProcId, Args0, Builtin, Context, Sym, FV0), Must, Subn, - call(PredId, ProcId, Args, Builtin, Context, Sym, Follow)) :- + call(PredId, ProcId, Args, Builtin, Context, Sym, FV)) :- goal_util__rename_var_list(Args0, Must, Subn, Args), - goal_util__rename_follow_vars(Follow0, Must, Subn, Follow). + goal_util__rename_follow_vars(FV0, Must, Subn, FV). goal_util__name_apart_2(unify(TermL0,TermR0,Mode,Unify0,Context), Must, Subn, unify(TermL,TermR,Mode,Unify,Context)) :- @@ -355,3 +361,9 @@ goal_util__name_apart_set(Vars0, Must, Subn, Vars) :- set__list_to_set(VarsList, Vars). %-----------------------------------------------------------------------------% + +goal_util__goal_is_branched(if_then_else(_, _, _, _, _)). +goal_util__goal_is_branched(switch(_, _, _, _)). +goal_util__goal_is_branched(disj(_, _)). + +%-----------------------------------------------------------------------------% diff --git a/compiler/higher_order.m b/compiler/higher_order.m index 409475054..f7480c8c1 100644 --- a/compiler/higher_order.m +++ b/compiler/higher_order.m @@ -243,13 +243,13 @@ traverse_goal(conj(Goals0) - Info, conj(Goals) - Info, PredProcId, Changed, GoalSize) --> traverse_conj(Goals0, Goals, PredProcId, no, Changed, 0, GoalSize). -traverse_goal(disj(Goals0) - Info, disj(Goals) - Info, +traverse_goal(disj(Goals0, FV) - Info, disj(Goals, FV) - Info, PredProcId, Changed, GoalSize) --> traverse_disj(Goals0, Goals, PredProcId, Changed, GoalSize). % a switch is treated as a disjunction -traverse_goal(switch(Var, CanFail, Cases0) - Info, - switch(Var, CanFail, Cases) - Info, +traverse_goal(switch(Var, CanFail, Cases0, FV) - Info, + switch(Var, CanFail, Cases, FV) - Info, PredProcId, Changed, GoalSize) --> traverse_cases(Cases0, Cases, PredProcId, Changed, GoalSize). @@ -260,14 +260,14 @@ traverse_goal(Goal0, Goal, PredProcId, Changed, 1) --> % if-then-elses are handled as disjunctions traverse_goal(Goal0, Goal, PredProcId, Changed, GoalSize, Info0, Info) :- - Goal0 = if_then_else(Vars, Cond0, Then0, Else0) - GoalInfo, + Goal0 = if_then_else(Vars, Cond0, Then0, Else0, FV) - GoalInfo, traverse_goal(Cond0, Cond, PredProcId, Changed1, GoalSize1, Info0, Info1), traverse_goal(Then0, Then, PredProcId, Changed2, GoalSize2, Info1, Info2), traverse_goal(Else0, Else, PredProcId, Changed3, GoalSize3, Info0, Info3), - Goal = if_then_else(Vars, Cond, Then, Else) - GoalInfo, + Goal = if_then_else(Vars, Cond, Then, Else, FV) - GoalInfo, GoalSize is GoalSize1 + GoalSize2 + GoalSize3, bool__or_list([Changed1, Changed2, Changed3], Changed), merge_higher_order_infos(Info2, Info3, Info). diff --git a/compiler/hlds_goal.m b/compiler/hlds_goal.m index 1fe2646c2..c2fac39e6 100644 --- a/compiler/hlds_goal.m +++ b/compiler/hlds_goal.m @@ -63,7 +63,10 @@ can_fail, % whether or not the switch test itself % can fail (i.e. whether or not it % covers all the possible cases) - list(case) + list(case), + follow_vars % advisory storage locations for + % placing variables at the end of + % each arm of the switch ) % A unification. @@ -87,7 +90,12 @@ % A disjunction. % Note: disjunctions should be fully flattened. - ; disj(hlds__goals) + ; disj( + hlds__goals, + follow_vars % advisory storage locations for + % placing variables at the end of + % each arm of the disjunction + ) % A negation ; not(hlds__goal) @@ -111,7 +119,10 @@ % variables . hlds__goal, % The hlds__goal, % The part - hlds__goal % The part + hlds__goal, % The part + follow_vars % advisory storage locations for + % placing variables at the end of + % each arm of the ite ) % C code from a pragma(c_code, ...) decl. @@ -619,7 +630,7 @@ goal_to_conj_list(Goal, ConjList) :- % otherwise return the goal as a singleton list. goal_to_disj_list(Goal, DisjList) :- - ( Goal = (disj(List) - _) -> + ( Goal = (disj(List, _) - _) -> DisjList = List ; DisjList = [Goal] @@ -642,17 +653,18 @@ conj_list_to_goal(ConjList, GoalInfo, Goal) :- % otherwise return the disjunction of the conjuncts, % with the specified goal_info. -disj_list_to_goal(ConjList, GoalInfo, Goal) :- - ( ConjList = [Goal0] -> +disj_list_to_goal(DisjList, GoalInfo, Goal) :- + ( DisjList = [Goal0] -> Goal = Goal0 ; - Goal = disj(ConjList) - GoalInfo + map__init(Empty), + Goal = disj(DisjList, Empty) - GoalInfo ). %-----------------------------------------------------------------------------% goal_is_atomic(conj([])). -goal_is_atomic(disj([])). +goal_is_atomic(disj([], _)). goal_is_atomic(call(_,_,_,_,_,_,_)). goal_is_atomic(unify(_,_,_,_,_)). goal_is_atomic(pragma_c_code(_,_,_,_,_)). diff --git a/compiler/hlds_out.m b/compiler/hlds_out.m index afd7c1f84..04c97dfd6 100644 --- a/compiler/hlds_out.m +++ b/compiler/hlds_out.m @@ -599,8 +599,8 @@ hlds_out__write_goal(Goal - GoalInfo, ModuleInfo, VarSet, Indent) --> io__state, io__state). :- mode hlds_out__write_goal_2(in, in, in, in, di, uo) is det. -hlds_out__write_goal_2(switch(Var, CanFail, CasesList), ModuleInfo, VarSet, Indent) - --> +hlds_out__write_goal_2(switch(Var, CanFail, CasesList, _), ModuleInfo, VarSet, + Indent) --> io__write_string("( % "), hlds_out__write_can_fail(CanFail), io__write_string(" switch on `"), @@ -627,8 +627,8 @@ hlds_out__write_goal_2(some(Vars, Goal), ModuleInfo, VarSet, Indent) --> mercury_output_newline(Indent), io__write_string(")"). -hlds_out__write_goal_2(if_then_else(Vars, A, B, C), ModuleInfo, VarSet, Indent) - --> +hlds_out__write_goal_2(if_then_else(Vars, A, B, C, _), ModuleInfo, VarSet, + Indent) --> io__write_string("(if"), hlds_out__write_some(Vars, VarSet), { Indent1 is Indent + 1 }, @@ -643,7 +643,7 @@ hlds_out__write_goal_2(if_then_else(Vars, A, B, C), ModuleInfo, VarSet, Indent) globals__io_lookup_bool_option(verbose_dump_hlds, Verbose), ( { Verbose = no }, - { C = if_then_else(_, _, _, _) - _ } + { C = if_then_else(_, _, _, _, _) - _ } -> io__write_string(" "), hlds_out__write_goal(C, ModuleInfo, VarSet, Indent) @@ -682,7 +682,7 @@ hlds_out__write_goal_2(conj(List), ModuleInfo, VarSet, Indent) --> io__write_string("true") ). -hlds_out__write_goal_2(disj(List), ModuleInfo, VarSet, Indent) --> +hlds_out__write_goal_2(disj(List, _), ModuleInfo, VarSet, Indent) --> ( { List = [Goal | Goals] } -> io__write_string("( % disjunction"), { Indent1 is Indent + 1 }, diff --git a/compiler/inlining.m b/compiler/inlining.m index 087fd0e3f..b7068c15c 100644 --- a/compiler/inlining.m +++ b/compiler/inlining.m @@ -104,23 +104,23 @@ inlining__inlining_in_goal_2(conj(Goals0), Varset0, VarTypes0, TVarSet, ModuleInfo, Goals, Varset, VarTypes). -inlining__inlining_in_goal_2(disj(Goals0), Varset0, VarTypes0, +inlining__inlining_in_goal_2(disj(Goals0, FV), Varset0, VarTypes0, TVarset, ModuleInfo, - disj(Goals), Varset, VarTypes) :- + disj(Goals, FV), Varset, VarTypes) :- inlining__inlining_in_disj(Goals0, Varset0, VarTypes0, TVarset, ModuleInfo, Goals, Varset, VarTypes). -inlining__inlining_in_goal_2(switch(Var, Det, Cases0), Varset0, VarTypes0, +inlining__inlining_in_goal_2(switch(Var, Det, Cases0, FV), Varset0, VarTypes0, TVarset, ModuleInfo, - switch(Var, Det, Cases), Varset, VarTypes) :- + switch(Var, Det, Cases, FV), Varset, VarTypes) :- inlining__inlining_in_cases(Cases0, Varset0, VarTypes0, TVarset, ModuleInfo, Cases, Varset, VarTypes). -inlining__inlining_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0), Varset0, - VarTypes0, TVarSet, ModuleInfo, - if_then_else(Vars, Cond, Then, Else), Varset, VarTypes) :- +inlining__inlining_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0, FV), + Varset0, VarTypes0, TVarSet, ModuleInfo, + if_then_else(Vars, Cond, Then, Else, FV), Varset, VarTypes) :- inlining__inlining_in_goal(Cond0, Varset0, VarTypes0, TVarSet, ModuleInfo, Cond, Varset1, VarTypes1), inlining__inlining_in_goal(Then0, Varset1, VarTypes1, diff --git a/compiler/ite_gen.m b/compiler/ite_gen.m index d40ade253..1021c1db9 100644 --- a/compiler/ite_gen.m +++ b/compiler/ite_gen.m @@ -19,16 +19,16 @@ :- import_module hlds_goal, llds, code_gen, code_info, code_util. :- pred ite_gen__generate_det_ite(hlds__goal, hlds__goal, hlds__goal, - code_tree, code_info, code_info). -:- mode ite_gen__generate_det_ite(in, in, in, out, in, out) is det. + follow_vars, code_tree, code_info, code_info). +:- mode ite_gen__generate_det_ite(in, in, in, in, out, in, out) is det. :- pred ite_gen__generate_semidet_ite(hlds__goal, hlds__goal, hlds__goal, - code_tree, code_info, code_info). -:- mode ite_gen__generate_semidet_ite(in, in, in, out, in, out) is det. + follow_vars, code_tree, code_info, code_info). +:- mode ite_gen__generate_semidet_ite(in, in, in, in, out, in, out) is det. :- pred ite_gen__generate_nondet_ite(hlds__goal, hlds__goal, hlds__goal, - code_tree, code_info, code_info). -:- mode ite_gen__generate_nondet_ite(in, in, in, out, in, out) is det. + follow_vars, code_tree, code_info, code_info). +:- mode ite_gen__generate_nondet_ite(in, in, in, in, out, in, out) is det. %---------------------------------------------------------------------------% :- implementation. @@ -36,7 +36,7 @@ :- import_module bool, set, tree, list, map, std_util, require. :- import_module options, globals. -ite_gen__generate_det_ite(CondGoal, ThenGoal, ElseGoal, Instr) --> +ite_gen__generate_det_ite(CondGoal, ThenGoal, ElseGoal, _FollowVars, Instr) --> code_info__get_globals(Options), { CondGoal = _Goal - CondGoalInfo }, { goal_info_cont_lives(CondGoalInfo, MaybeLives) }, @@ -117,7 +117,8 @@ ite_gen__generate_det_ite(CondGoal, ThenGoal, ElseGoal, Instr) --> %---------------------------------------------------------------------------% -ite_gen__generate_semidet_ite(CondGoal, ThenGoal, ElseGoal, Instr) --> +ite_gen__generate_semidet_ite(CondGoal, ThenGoal, ElseGoal, _FollowVars, Instr) + --> code_info__get_globals(Options), { CondGoal = _Goal - CondGoalInfo }, { goal_info_cont_lives(CondGoalInfo, MaybeLives) }, @@ -192,7 +193,8 @@ ite_gen__generate_semidet_ite(CondGoal, ThenGoal, ElseGoal, Instr) --> %---------------------------------------------------------------------------% -ite_gen__generate_nondet_ite(CondGoal, ThenGoal, ElseGoal, Instr) --> +ite_gen__generate_nondet_ite(CondGoal, ThenGoal, ElseGoal, _FollowVars, Instr) + --> code_info__get_globals(Options), { globals__lookup_bool_option(Options, diff --git a/compiler/lambda.m b/compiler/lambda.m index 473e9642a..2af5c4ce3 100644 --- a/compiler/lambda.m +++ b/compiler/lambda.m @@ -155,18 +155,19 @@ lambda__process_goal_2(unify(XVar, Y, Mode, Unification, Context), GoalInfo, lambda__process_goal_2(conj(Goals0), GoalInfo, conj(Goals) - GoalInfo) --> lambda__process_goal_list(Goals0, Goals). -lambda__process_goal_2(disj(Goals0), GoalInfo, disj(Goals) - GoalInfo) --> +lambda__process_goal_2(disj(Goals0, FV), GoalInfo, disj(Goals, FV) - GoalInfo) + --> lambda__process_goal_list(Goals0, Goals). lambda__process_goal_2(not(Goal0), GoalInfo, not(Goal) - GoalInfo) --> lambda__process_goal(Goal0, Goal). -lambda__process_goal_2(switch(Var, CanFail, Cases0), GoalInfo, - switch(Var, CanFail, Cases) - GoalInfo) --> +lambda__process_goal_2(switch(Var, CanFail, Cases0, FV), GoalInfo, + switch(Var, CanFail, Cases, FV) - GoalInfo) --> lambda__process_cases(Cases0, Cases). lambda__process_goal_2(some(Vars, Goal0), GoalInfo, some(Vars, Goal) - GoalInfo) --> lambda__process_goal(Goal0, Goal). -lambda__process_goal_2(if_then_else(Vars, A0, B0, C0), GoalInfo, - if_then_else(Vars, A, B, C) - GoalInfo) --> +lambda__process_goal_2(if_then_else(Vars, A0, B0, C0, FV), GoalInfo, + if_then_else(Vars, A, B, C, FV) - GoalInfo) --> lambda__process_goal(A0, A), lambda__process_goal(B0, B), lambda__process_goal(C0, C). diff --git a/compiler/live_vars.m b/compiler/live_vars.m index 68925d45e..c0293d855 100644 --- a/compiler/live_vars.m +++ b/compiler/live_vars.m @@ -175,7 +175,7 @@ detect_live_vars_in_goal_2(conj(Goals0), _NondetLives, Liveness0, LiveSets0, detect_live_vars_in_conj(Goals0, Liveness0, LiveSets0, CodeModel, ModuleInfo, Liveness, LiveSets). -detect_live_vars_in_goal_2(disj(Goals0), NondetLives, Liveness0, LiveSets0, +detect_live_vars_in_goal_2(disj(Goals0, _), NondetLives, Liveness0, LiveSets0, CodeModel, ModuleInfo, Liveness, LiveSets) :- % All the currently live variables need to be saved % on the stack at the start of a disjunction, since we @@ -187,13 +187,13 @@ detect_live_vars_in_goal_2(disj(Goals0), NondetLives, Liveness0, LiveSets0, detect_live_vars_in_disj(Goals0, Liveness0, LiveSets1, CodeModel, ModuleInfo, Liveness, LiveSets). -detect_live_vars_in_goal_2(switch(_Var, _Det, Cases0), _NondetLives, Liveness0, - LiveSets0, CodeModel, ModuleInfo, - Liveness, LiveSets) :- +detect_live_vars_in_goal_2(switch(_Var, _Det, Cases0, _), + _NondetLives, Liveness0, LiveSets0, CodeModel, + ModuleInfo, Liveness, LiveSets) :- detect_live_vars_in_cases(Cases0, Liveness0, LiveSets0, CodeModel, ModuleInfo, Liveness, LiveSets). -detect_live_vars_in_goal_2(if_then_else(_Vars, Cond0, Then0, Else0), +detect_live_vars_in_goal_2(if_then_else(_Vars, Cond0, Then0, Else0, _), NondetLives, Liveness0, LiveSets0, CodeModel, ModuleInfo, Liveness, LiveSets) :- set__union(Liveness0, NondetLives, LiveVars), diff --git a/compiler/liveness.m b/compiler/liveness.m index 3a0f4d782..48f4c63cf 100644 --- a/compiler/liveness.m +++ b/compiler/liveness.m @@ -184,8 +184,8 @@ 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)) :- +detect_liveness_in_goal_2(disj(Goals0, FV), Liveness0, ModuleInfo, + Liveness, disj(Goals, FV)) :- set__init(Union0), detect_liveness_in_disj(Goals0, Liveness0, ModuleInfo, Union0, Union, Goals), @@ -195,15 +195,16 @@ 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)) :- +detect_liveness_in_goal_2(switch(Var, Det, Cases0, FV), Liveness0, + ModuleInfo, Liveness, switch(Var, Det, Cases, FV)) :- 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_2(if_then_else(Vars, Cond0, Then0, Else0, FV), + Liveness0, M, Liveness, + if_then_else(Vars, Cond, Then, Else, FV)) :- 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), @@ -326,48 +327,49 @@ 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). + 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(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)) :- +detect_deadness_in_goal_2(disj(Goals0, FV), Deadness0, ModuleInfo, Deadness, + disj(Goals, FV)) :- set__init(Union0), - detect_deadness_in_disj(Goals0, Deadness0, ModuleInfo, Union0, - Union, Goals), + 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_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_2(if_then_else(Vars, Cond0, Then0, Else0, FV), + Deadness0, ModuleInfo, Deadness, + if_then_else(Vars, Cond, Then, Else, FV)) :- detect_deadness_in_goal(Then0, Deadness0, ModuleInfo, - DeadnessThen, Then1), + DeadnessThen, Then1), detect_deadness_in_goal(Else0, Deadness0, ModuleInfo, - DeadnessElse, Else1), + DeadnessElse, Else1), set__union(DeadnessThen, DeadnessElse, DeadnessThenElse), detect_deadness_in_goal(Cond0, DeadnessThenElse, ModuleInfo, - Deadness, Cond), + 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)) :- +detect_deadness_in_goal_2(switch(Var, Det, Cases0, FV), Deadness0, ModuleInfo, + Deadness, switch(Var, Det, Cases, FV)) :- set__init(Union0), detect_deadness_in_cases(Var, Cases0, Deadness0, ModuleInfo, Union0, - Union, Cases), + 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_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,G), Dn, _, Dn, call(A,B,C,D,E,F,G)). @@ -539,7 +541,7 @@ add_nondet_lives_to_goal(Goal0 - GoalInfo0, Liveness0, goal_info_get_code_model(GoalInfo0, GoalModel), ( GoalModel = model_non, - Goal0 = disj(_) + Goal0 = disj(_, _) -> % If the goal is a nondet disj then all the variables % that are live at the start of the disj will be @@ -577,20 +579,20 @@ add_nondet_lives_to_goal_2(conj(Goals0), Liveness0, Extras0, add_nondet_lives_to_conj(Goals0, Liveness0, Extras0, Goals, Liveness, Extras). -add_nondet_lives_to_goal_2(disj(Goals0), Liveness0, Extras0, - disj(Goals), Liveness, Extras) :- +add_nondet_lives_to_goal_2(disj(Goals0, FV), Liveness0, Extras0, + disj(Goals, FV), Liveness, Extras) :- ExtrasAcc = Extras0, add_nondet_lives_to_disj(Goals0, Liveness0, Extras0, Goals, Liveness, ExtrasAcc, Extras). -add_nondet_lives_to_goal_2(switch(Var, CF, Goals0), Liveness0, Extras0, - switch(Var, CF, Goals), Liveness, Extras) :- +add_nondet_lives_to_goal_2(switch(Var, CF, Goals0, FV), Liveness0, Extras0, + switch(Var, CF, Goals, FV), Liveness, Extras) :- ExtrasAcc = Extras0, add_nondet_lives_to_switch(Goals0, Liveness0, Extras0, Goals, Liveness, ExtrasAcc, Extras). -add_nondet_lives_to_goal_2(if_then_else(Vars, Cond0, Then0, Else0), Liveness0, - Extras0, if_then_else(Vars, Cond, Then, Else), +add_nondet_lives_to_goal_2(if_then_else(Vars, Cond0, Then0, Else0, FV), + Liveness0, Extras0, if_then_else(Vars, Cond, Then, Else, FV), Liveness, Extras) :- add_nondet_lives_to_goal(Cond0, Liveness0, Extras0, Cond, Liveness1, Extras1), diff --git a/compiler/make_hlds.m b/compiler/make_hlds.m index 3bf3c23d8..555bccf29 100644 --- a/compiler/make_hlds.m +++ b/compiler/make_hlds.m @@ -1362,11 +1362,11 @@ warn_singletons_in_goal_2(conj(Goals), _GoalInfo, QuantVars, VarSet, PredCallId) --> warn_singletons_in_goal_list(Goals, QuantVars, VarSet, PredCallId). -warn_singletons_in_goal_2(disj(Goals), _GoalInfo, QuantVars, VarSet, +warn_singletons_in_goal_2(disj(Goals, _), _GoalInfo, QuantVars, VarSet, PredCallId) --> warn_singletons_in_goal_list(Goals, QuantVars, VarSet, PredCallId). -warn_singletons_in_goal_2(switch(_Var, _CanFail, Cases), +warn_singletons_in_goal_2(switch(_Var, _CanFail, Cases, _), _GoalInfo, QuantVars, VarSet, PredCallId) --> warn_singletons_in_cases(Cases, QuantVars, VarSet, PredCallId). @@ -1391,7 +1391,7 @@ warn_singletons_in_goal_2(some(Vars, SubGoal), GoalInfo, QuantVars, VarSet, { set__insert_list(QuantVars, Vars, QuantVars1) }, warn_singletons_in_goal(SubGoal, QuantVars1, VarSet, PredCallId). -warn_singletons_in_goal_2(if_then_else(Vars, Cond, Then, Else), GoalInfo, +warn_singletons_in_goal_2(if_then_else(Vars, Cond, Then, Else, _), GoalInfo, QuantVars, VarSet, PredCallId) --> % % warn if any quantified variables do not occur in the condition @@ -1814,7 +1814,8 @@ transform_goal(Goal0 - Context, VarSet0, Subst, Goal1 - GoalInfo1, VarSet) :- hlds__goal, varset). :- mode transform_goal_2(in, in, in, in, out, out) is det. -transform_goal_2(fail, _, VarSet, _, disj([]) - GoalInfo, VarSet) :- +transform_goal_2(fail, _, VarSet, _, disj([], Empty) - GoalInfo, VarSet) :- + map__init(Empty), goal_info_init(GoalInfo). transform_goal_2(true, _, VarSet, _, conj([]) - GoalInfo, VarSet) :- @@ -1833,11 +1834,12 @@ transform_goal_2(some(Vars0, Goal0), _, VarSet0, Subst, goal_info_init(GoalInfo). transform_goal_2(if_then_else(Vars0, A0, B0, C0), _, VarSet0, Subst, - if_then_else(Vars, A, B, C) - GoalInfo, VarSet) :- + if_then_else(Vars, A, B, C, Empty) - GoalInfo, VarSet) :- substitute_vars(Vars0, Subst, Vars), transform_goal(A0, VarSet0, Subst, A, VarSet1), transform_goal(B0, VarSet1, Subst, B, VarSet2), transform_goal(C0, VarSet2, Subst, C, VarSet), + map__init(Empty), goal_info_init(GoalInfo). transform_goal_2(if_then(Vars0, A0, B0), Context, Subst, VarSet0, diff --git a/compiler/mercury_to_c.m b/compiler/mercury_to_c.m index 958d42c4c..0ffbe9375 100644 --- a/compiler/mercury_to_c.m +++ b/compiler/mercury_to_c.m @@ -514,7 +514,8 @@ c_gen_goal(Goal - GoalInfo, Indent, CGenInfo0, CGenInfo) --> io__state, io__state). :- mode c_gen_goal_2(in, in, in, out, di, uo) is det. -c_gen_goal_2(switch(Var, _CanFail, CasesList), Indent, CGenInfo0, CGenInfo) --> +c_gen_goal_2(switch(Var, _CanFail, CasesList, _), Indent, + CGenInfo0, CGenInfo) --> { sorry(7) }, io__write_string("/* "), % c_gen_can_fail(CanFail), @@ -544,7 +545,7 @@ c_gen_goal_2(some(Vars, Goal), Indent, CGenInfo0, CGenInfo) --> mercury_output_newline(Indent), io__write_string(")"). -c_gen_goal_2(if_then_else(_Vars, A, B, C), Indent, CGenInfo0, CGenInfo) +c_gen_goal_2(if_then_else(_Vars, A, B, C, _), Indent, CGenInfo0, CGenInfo) --> % XXX need to handle nondet { c_gen_info_new_label(ElseLabel, CGenInfo0, CGenInfo1) }, @@ -570,7 +571,7 @@ c_gen_goal_2(if_then_else(_Vars, A, B, C), Indent, CGenInfo0, CGenInfo) c_gen_indent(Indent), io__write_string("/* else */\n"), ( - { C = if_then_else(_, _, _, _) - _ } + { C = if_then_else(_, _, _, _, _) - _ } -> c_gen_goal(C, Indent, CGenInfo6, CGenInfo) ; @@ -599,7 +600,7 @@ c_gen_goal_2(not(Goal), Indent, CGenInfo0, CGenInfo) --> c_gen_goal_2(conj(Goals), Indent, CGenInfo0, CGenInfo) --> c_gen_conj(Goals, Indent, CGenInfo0, CGenInfo). -c_gen_goal_2(disj(List), Indent, CGenInfo0, CGenInfo) --> +c_gen_goal_2(disj(List, _), Indent, CGenInfo0, CGenInfo) --> { c_gen_info_get_code_model(CGenInfo0, CodeModel) }, ( { CodeModel = model_non } -> { true } diff --git a/compiler/middle_rec.m b/compiler/middle_rec.m index 73420ba60..1ba517c44 100644 --- a/compiler/middle_rec.m +++ b/compiler/middle_rec.m @@ -33,7 +33,7 @@ middle_rec__match_and_generate(Goal, Instrs, CodeInfo0, CodeInfo) :- Goal = GoalExpr - GoalInfo, ( - GoalExpr = switch(Var, cannot_fail, [Case1, Case2]), + GoalExpr = switch(Var, cannot_fail, [Case1, Case2], _), Case1 = case(ConsId1, Goal1), Case2 = case(ConsId2, Goal2), ( @@ -54,7 +54,7 @@ middle_rec__match_and_generate(Goal, Instrs, CodeInfo0, CodeInfo) :- fail ) ; - GoalExpr = if_then_else(Vars, Cond, Then, Else), + GoalExpr = if_then_else(Vars, Cond, Then, Else, _), ( code_aux__contains_only_builtins(Cond), code_aux__contains_only_builtins(Then), diff --git a/compiler/mode_util.m b/compiler/mode_util.m index 5e30268ba..71e03b51f 100644 --- a/compiler/mode_util.m +++ b/compiler/mode_util.m @@ -1145,22 +1145,22 @@ recompute_instmap_delta(Goal0 - GoalInfo0, Goal - GoalInfo, InstMapDelta) --> instmap_delta, module_info, module_info). :- mode recompute_instmap_delta_2(in, out, out, in, out) is det. -recompute_instmap_delta_2(switch(Var, Det, Cases0), switch(Var, Det, Cases), - InstMapDelta) --> +recompute_instmap_delta_2(switch(Var, Det, Cases0, FV), + switch(Var, Det, Cases, FV), InstMapDelta) --> recompute_instmap_delta_cases(Cases0, Cases, InstMapDelta). recompute_instmap_delta_2(conj(Goals0), conj(Goals), InstMapDelta) --> recompute_instmap_delta_conj(Goals0, Goals, InstMapDelta). -recompute_instmap_delta_2(disj(Goals0), disj(Goals), InstMapDelta) --> +recompute_instmap_delta_2(disj(Goals0, FV), disj(Goals, FV), InstMapDelta) --> recompute_instmap_delta_disj(Goals0, Goals, InstMapDelta). recompute_instmap_delta_2(not(Goal0), not(Goal), InstMapDelta) --> { instmap_init(InstMapDelta) }, recompute_instmap_delta(Goal0, Goal). -recompute_instmap_delta_2(if_then_else(Vars,A0,B0,C0), - if_then_else(Vars,A,B,C), InstMapDelta) --> +recompute_instmap_delta_2(if_then_else(Vars, A0, B0, C0, FV), + if_then_else(Vars, A, B, C, FV), InstMapDelta) --> recompute_instmap_delta(A0, A, InstMapDelta1), recompute_instmap_delta(B0, B, InstMapDelta2), recompute_instmap_delta(C0, C, InstMapDelta3), diff --git a/compiler/modes.m b/compiler/modes.m index a9ca3c3d9..0ee0dc6d3 100644 --- a/compiler/modes.m +++ b/compiler/modes.m @@ -515,7 +515,7 @@ modecheck_goal_2(conj(List0), _GoalInfo0, conj(List)) --> ), mode_checkpoint(exit, "conj"). -modecheck_goal_2(disj(List0), GoalInfo0, disj(List)) --> +modecheck_goal_2(disj(List0, FV), GoalInfo0, disj(List, FV)) --> mode_checkpoint(enter, "disj"), ( { List0 = [] } -> % for efficiency, optimize common case { List = [] }, @@ -527,7 +527,7 @@ modecheck_goal_2(disj(List0), GoalInfo0, disj(List)) --> ), mode_checkpoint(exit, "disj"). -modecheck_goal_2(if_then_else(Vs, A0, B0, C0), GoalInfo0, Goal) --> +modecheck_goal_2(if_then_else(Vs, A0, B0, C0, FV), GoalInfo0, Goal) --> mode_checkpoint(enter, "if-then-else"), { goal_info_get_nonlocals(GoalInfo0, NonLocals) }, { goal_get_nonlocals(B0, B_Vars) }, @@ -569,7 +569,7 @@ modecheck_goal_2(if_then_else(Vs, A0, B0, C0), GoalInfo0, Goal) --> { Goal = conj([not(some(Vs, A) - SomeA_GoalInfo) - NotSomeA_GoalInfo, C]) } ; - { Goal = if_then_else(Vs, A, B, C) } + { Goal = if_then_else(Vs, A, B, C, FV) } ), mode_checkpoint(exit, "if-then-else"). @@ -619,8 +619,8 @@ modecheck_goal_2(unify(A0, B0, _, UnifyInfo0, UnifyContext), GoalInfo0, Goal) mode_info_unset_call_context, mode_checkpoint(exit, "unify"). -modecheck_goal_2(switch(Var, CanFail, Cases0), GoalInfo0, - switch(Var, CanFail, Cases)) --> +modecheck_goal_2(switch(Var, CanFail, Cases0, FV), GoalInfo0, + switch(Var, CanFail, Cases, FV)) --> mode_checkpoint(enter, "switch"), ( { Cases0 = [] } -> { Cases = [] }, diff --git a/compiler/options.m b/compiler/options.m index f5762afd6..8a2d45d8a 100644 --- a/compiler/options.m +++ b/compiler/options.m @@ -106,6 +106,7 @@ ; reclaim_heap_on_nondet_failure ; lazy_code ; use_macro_for_redo_fail + ; branch_delay_slot ; num_real_r_regs ; num_real_temps ; cc @@ -296,6 +297,10 @@ option_defaults_2(code_gen_option, [ reclaim_heap_on_semidet_failure - bool(yes), reclaim_heap_on_nondet_failure - bool(yes), use_macro_for_redo_fail - bool(no), + branch_delay_slot - bool(no), + % the `mc' script may override the + % above default if configure says + % the machine has branch delay slots num_real_r_regs - int(5), num_real_temps - int(5), % the `mc' script will override the @@ -513,7 +518,9 @@ long_option("reclaim-heap-on-semidet-failure", long_option("reclaim-heap-on-nondet-failure", reclaim_heap_on_nondet_failure). long_option("use-macro-for-redo-fail", use_macro_for_redo_fail). +long_option("branch-delay-slot", branch_delay_slot). long_option("num-real-r-regs", num_real_r_regs). +long_option("num-real-temps", num_real_temps). long_option("cc", cc). long_option("cflags", cflags). long_option("cflags-for-regs", cflags_for_regs). @@ -660,7 +667,7 @@ set_opt_level(N, OptionTable0, OptionTable) :- enable_opt_levels(N0, N, OptionTable0, OptionTable) :- ( N0 > N -> OptionTable = OptionTable0 - ; opt_level(N0, OptionSettingsList) -> + ; opt_level(N0, OptionTable0, OptionSettingsList) -> override_options(OptionSettingsList, OptionTable0, OptionTable1), N1 is N0 + 1, @@ -691,7 +698,8 @@ opt_space([ %-----------------------------------------------------------------------------% -:- pred opt_level(int::in, list(pair(option, option_data))::out) is semidet. +:- pred opt_level(int::in, option_table::in, + list(pair(option, option_data))::out) is semidet. % Optimization level -1: % Generate totally unoptimized code; turns off ALL optimizations that @@ -702,7 +710,7 @@ opt_space([ % Optimization level 0: aim to minimize overall compilation time. % XXX I just guessed. We should run lots of experiments. -opt_level(0, [ +opt_level(0, _, [ optimize - bool(yes), optimize_repeat - int(1), optimize_peep - bool(yes), @@ -716,7 +724,7 @@ opt_level(0, [ % Optimization level 1: apply optimizations which are cheap and % have a good payoff while still keeping compilation time small -opt_level(1, [ +opt_level(1, _OptionTable, [ c_optimize - bool(yes), % XXX we want `gcc -O1' optimize_jumps - bool(yes), optimize_labels - bool(yes), @@ -727,12 +735,19 @@ opt_level(1, [ emit_c_loops - bool(yes) % dups? ]). +% This doesn't work at startup because the table is empty then +% map__lookup(OptionTable, branch_delay_slot, Option), +% ( Option = bool(Configured) -> +% DelaySlot = Configured +% ; +% error("configured value of branch-delay-slot is not boolean") +% ). % Optimization level 2: apply optimizations which have a good % payoff relative to their cost; but include optimizations % which are more costly than with -O1 -opt_level(2, [ +opt_level(2, _, [ optimize_fulljumps - bool(yes), optimize_repeat - int(3), optimize_dups - bool(yes), @@ -745,7 +760,7 @@ opt_level(2, [ % Optimization level 3: apply optimizations which usually have a good % payoff even if they increase compilation time quite a bit -opt_level(3, [ +opt_level(3, _, [ optimize_value_number - bool(yes), optimize_dead_procs - bool(yes), %%% optimize_copyprop - bool(yes), @@ -760,7 +775,7 @@ opt_level(3, [ % Currently this just enables pred_value_number -opt_level(4, [ +opt_level(4, _, [ pred_value_number - bool(yes) ]). @@ -769,7 +784,7 @@ opt_level(4, [ % Currently this just runs a second pass of value numbering -opt_level(5, [ +opt_level(5, _, [ optimize_repeat - int(5), optimize_vnrepeat - int(2) ]). @@ -782,7 +797,7 @@ opt_level(5, [ % the compiler to put everything in the one C function and treat % calls to predicates in the same module as local. -opt_level(6, [ +opt_level(6, _, [ procs_per_c_function - int(0) % everything in one C function ]). @@ -973,6 +988,9 @@ options_help --> % The --bytes-per-word option is intended for use % by the `mc' script; it is deliberately not documented. + io__write_string("\t--branch-delay-slot\t"), + io__write_string("\t(This option is not for general use.)\n"), + io__write_string("\t\tAssume that branch instructions have a delay slot.\n"), io__write_string("\t--num-real-r-regs \t"), io__write_string("\t(This option is not for general use.)\n"), io__write_string("\t\tAssume registers r1 up to r are real machine registers.\n"), diff --git a/compiler/polymorphism.m b/compiler/polymorphism.m index 7c2b794d6..67957451d 100644 --- a/compiler/polymorphism.m +++ b/compiler/polymorphism.m @@ -416,18 +416,19 @@ polymorphism__process_goal_2(unify(XVar, Y, Mode, Unification, Context), polymorphism__process_goal_2(conj(Goals0), GoalInfo, conj(Goals) - GoalInfo) --> polymorphism__process_goal_list(Goals0, Goals). -polymorphism__process_goal_2(disj(Goals0), GoalInfo, disj(Goals) - GoalInfo) --> +polymorphism__process_goal_2(disj(Goals0, FV), GoalInfo, + disj(Goals, FV) - GoalInfo) --> polymorphism__process_goal_list(Goals0, Goals). polymorphism__process_goal_2(not(Goal0), GoalInfo, not(Goal) - GoalInfo) --> polymorphism__process_goal(Goal0, Goal). -polymorphism__process_goal_2(switch(Var, CanFail, Cases0), GoalInfo, - switch(Var, CanFail, Cases) - GoalInfo) --> +polymorphism__process_goal_2(switch(Var, CanFail, Cases0, FV), GoalInfo, + switch(Var, CanFail, Cases, FV) - GoalInfo) --> polymorphism__process_case_list(Cases0, Cases). polymorphism__process_goal_2(some(Vars, Goal0), GoalInfo, some(Vars, Goal) - GoalInfo) --> polymorphism__process_goal(Goal0, Goal). -polymorphism__process_goal_2(if_then_else(Vars, A0, B0, C0), GoalInfo, - if_then_else(Vars, A, B, C) - GoalInfo) --> +polymorphism__process_goal_2(if_then_else(Vars, A0, B0, C0, FV), GoalInfo, + if_then_else(Vars, A, B, C, FV) - GoalInfo) --> polymorphism__process_goal(A0, A), polymorphism__process_goal(B0, B), polymorphism__process_goal(C0, C). diff --git a/compiler/quantification.m b/compiler/quantification.m index 889bf14c2..b112d28f5 100644 --- a/compiler/quantification.m +++ b/compiler/quantification.m @@ -180,11 +180,11 @@ implicitly_quantify_goal_2(some(Vars0, Goal0), Context, some(Vars, Goal)) --> implicitly_quantify_goal_2(conj(List0), _, conj(List)) --> implicitly_quantify_conj(List0, List). -implicitly_quantify_goal_2(disj(Goals0), _, disj(Goals)) --> +implicitly_quantify_goal_2(disj(Goals0, FV), _, disj(Goals, FV)) --> implicitly_quantify_disj(Goals0, Goals). -implicitly_quantify_goal_2(switch(Var, Det, Cases0), _, - switch(Var, Det, Cases)) --> +implicitly_quantify_goal_2(switch(Var, Det, Cases0, FV), _, + switch(Var, Det, Cases, FV)) --> implicitly_quantify_cases(Cases0, Cases), % The switch variable is guaranteed to be non-local to the % switch, since it has to be bound elsewhere, so we put it @@ -207,8 +207,8 @@ implicitly_quantify_goal_2(not(Goal0), _, not(Goal)) --> quantification__set_outside(OutsideVars), quantification__set_quant_vars(QuantVars). -implicitly_quantify_goal_2(if_then_else(Vars0, Cond0, Then0, Else0), Context, - if_then_else(Vars, Cond, Then, Else)) --> +implicitly_quantify_goal_2(if_then_else(Vars0, Cond0, Then0, Else0, FV), + Context, if_then_else(Vars, Cond, Then, Else, FV)) --> quantification__get_quant_vars(QuantVars), quantification__get_outside(OutsideVars), { set__list_to_set(Vars0, QVars) }, @@ -481,10 +481,10 @@ goal_vars_2(call(_, _, ArgVars, _, _, _, _), Set0, Set) :- goal_vars_2(conj(Goals), Set0, Set) :- goal_list_vars_2(Goals, Set0, Set). -goal_vars_2(disj(Goals), Set0, Set) :- +goal_vars_2(disj(Goals, _), Set0, Set) :- goal_list_vars_2(Goals, Set0, Set). -goal_vars_2(switch(Var, _Det, Cases), Set0, Set) :- +goal_vars_2(switch(Var, _Det, Cases, _), Set0, Set) :- set__insert(Set0, Var, Set1), case_list_vars_2(Cases, Set1, Set). @@ -496,7 +496,7 @@ goal_vars_2(some(Vars, Goal), Set0, Set) :- goal_vars_2(not(Goal - _GoalInfo), Set0, Set) :- goal_vars_2(Goal, Set0, Set). -goal_vars_2(if_then_else(Vars, A, B, C), Set0, Set) :- +goal_vars_2(if_then_else(Vars, A, B, C, _), Set0, Set) :- % This code does the following: % % Set = Set0 + ( (vars(A) + vars(B)) \ Vars ) + vars(C) diff --git a/compiler/store_alloc.m b/compiler/store_alloc.m index 775799bbe..580f1d814 100644 --- a/compiler/store_alloc.m +++ b/compiler/store_alloc.m @@ -34,7 +34,7 @@ :- implementation. -:- import_module hlds_goal, mode_util. +:- import_module hlds_goal, goal_util, mode_util. :- import_module list, map, set, std_util, assoc_list. :- import_module int, term, require. @@ -112,7 +112,7 @@ store_alloc_in_goal(Goal0 - GoalInfo0, Liveness0, Follow0, ModuleInfo, % so we don't need to allocate anything for them. set__union(Liveness4, PostBirths, Liveness), ( - Goal = disj(_) + Goal = disj(_, _) -> % For disjunctions, we only want to allocate registers % for the variables that are generated by the disjunction @@ -125,7 +125,7 @@ store_alloc_in_goal(Goal0 - GoalInfo0, Liveness0, Follow0, ModuleInfo, store_alloc_allocate_storage(LiveVarList, 1, Follow, StoreMap), goal_info_set_store_map(GoalInfo0, yes(StoreMap), GoalInfo) ; - goal_is_branched(Goal) + goal_util__goal_is_branched(Goal) -> set__to_sorted_list(Liveness, LiveVarList), store_alloc_allocate_storage(LiveVarList, 1, Follow, StoreMap), @@ -147,8 +147,8 @@ store_alloc_in_goal_2(conj(Goals0), Liveness0, Follow0, _NondetLives, store_alloc_in_conj(Goals0, Liveness0, Follow0, ModuleInfo, Goals, Liveness, Follow). -store_alloc_in_goal_2(disj(Goals0), Liveness0, Follow0, _NondetLives, - ModuleInfo, disj(Goals), Liveness, Follow) :- +store_alloc_in_goal_2(disj(Goals0, FV), Liveness0, Follow0, _NondetLives, + ModuleInfo, disj(Goals, FV), Liveness, Follow) :- store_alloc_in_disj(Goals0, Liveness0, Follow0, ModuleInfo, Goals, Liveness, Follow). @@ -161,16 +161,15 @@ store_alloc_in_goal_2(not(Goal0), Liveness0, Follow0, NondetLives, ModuleInfo, goal_info_set_cont_lives(GoalInfo0, yes(ContLives), GoalInfo), Goal = GoalGoal - GoalInfo. -store_alloc_in_goal_2(switch(Var, Det, Cases0), Liveness0, Follow0, - _NondetLives, ModuleInfo, switch(Var, Det, Cases), +store_alloc_in_goal_2(switch(Var, Det, Cases0, FV), Liveness0, Follow0, + _NondetLives, ModuleInfo, switch(Var, Det, Cases, FV), Liveness, Follow) :- store_alloc_in_cases(Cases0, Liveness0, Follow0, ModuleInfo, Cases, Liveness, Follow). -store_alloc_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0), Liveness0, - Follow0, NondetLives, ModuleInfo, - if_then_else(Vars, Cond, Then, Else), - Liveness, Follow) :- +store_alloc_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0, FV), + Liveness0, Follow0, NondetLives, ModuleInfo, + if_then_else(Vars, Cond, Then, Else, FV), Liveness, Follow) :- store_alloc_in_goal(Cond0, Liveness0, Follow0, ModuleInfo, Cond1, Liveness1, Follow1), Cond1 = CondGoal - GoalInfo0, @@ -331,14 +330,5 @@ next_free_reg(N0, Values, N) :- N = N0 ). -%-----------------------------------------------------------------------------% - -:- pred goal_is_branched(hlds__goal_expr). -:- mode goal_is_branched(in) is semidet. - -goal_is_branched(if_then_else(_,_,_,_)). -goal_is_branched(switch(_,_,_)). -goal_is_branched(disj(_)). - %-----------------------------------------------------------------------------% %-----------------------------------------------------------------------------% diff --git a/compiler/switch_detection.m b/compiler/switch_detection.m index 489fffe95..b8e33f23f 100644 --- a/compiler/switch_detection.m +++ b/compiler/switch_detection.m @@ -132,15 +132,16 @@ detect_switches_in_goal_1(Goal0 - GoalInfo, InstMap0, VarTypes, ModuleInfo, map(var, type), module_info, hlds__goal_expr). :- mode detect_switches_in_goal_2(in, in, in, in, in, out) is det. -detect_switches_in_goal_2(disj(Goals0), GoalInfo, InstMap0, +detect_switches_in_goal_2(disj(Goals0, FV), GoalInfo, InstMap0, VarTypes, ModuleInfo, Goal) :- ( Goals0 = [] -> - Goal = disj([]) + Goal = disj([], FV) ; goal_info_get_nonlocals(GoalInfo, NonLocals), set__to_sorted_list(NonLocals, NonLocalsList), detect_switches_in_disj(NonLocalsList, Goals0, GoalInfo, - InstMap0, VarTypes, NonLocalsList, ModuleInfo, [], Goal) + FV, InstMap0, VarTypes, NonLocalsList, ModuleInfo, + [], Goal) ). detect_switches_in_goal_2(conj(Goals0), _GoalInfo, InstMap0, @@ -151,9 +152,9 @@ detect_switches_in_goal_2(not(Goal0), _GoalInfo, InstMap0, VarTypes, ModuleInfo, not(Goal)) :- detect_switches_in_goal(Goal0, InstMap0, VarTypes, ModuleInfo, Goal). -detect_switches_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0), _GoalInfo, - InstMap0, VarTypes, ModuleInfo, - if_then_else(Vars, Cond, Then, Else)) :- +detect_switches_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0, FV), + _GoalInfo, InstMap0, VarTypes, ModuleInfo, + if_then_else(Vars, Cond, Then, Else, FV)) :- detect_switches_in_goal_1(Cond0, InstMap0, VarTypes, ModuleInfo, Cond, InstMap1), detect_switches_in_goal(Then0, InstMap1, VarTypes, ModuleInfo, Then), @@ -176,8 +177,8 @@ detect_switches_in_goal_2(unify(A,RHS0,C,D,E), __GoalInfo, InstMap0, RHS = RHS0 ). -detect_switches_in_goal_2(switch(Var, CanFail, Cases0), _, InstMap, - VarTypes, ModuleInfo, switch(Var, CanFail, Cases)) :- +detect_switches_in_goal_2(switch(Var, CanFail, Cases0, FV), _, InstMap, + VarTypes, ModuleInfo, switch(Var, CanFail, Cases, FV)) :- detect_switches_in_cases(Cases0, InstMap, VarTypes, ModuleInfo, Cases). detect_switches_in_goal_2(pragma_c_code(A,B,C,D,E), _, _, _, _, @@ -201,11 +202,11 @@ detect_switches_in_goal_2(pragma_c_code(A,B,C,D,E), _, _, _, _, :- type again ---> again(var, list(hlds__goal), sorted_case_list). :- pred detect_switches_in_disj(list(var), list(hlds__goal), hlds__goal_info, - instmap, map(var, type), list(var), module_info, list(again), - hlds__goal_expr). -:- mode detect_switches_in_disj(in, in, in, in, in, in, in, in, out) is det. + follow_vars, instmap, map(var, type), list(var), module_info, + list(again), hlds__goal_expr). +:- mode detect_switches_in_disj(in, in, in, in, in, in, in, in, in, out) is det. -detect_switches_in_disj([Var | Vars], Goals0, GoalInfo, InstMap, +detect_switches_in_disj([Var | Vars], Goals0, GoalInfo, FV, InstMap, VarTypes, AllVars, ModuleInfo, Again0, Goal) :- % can we do at least a partial switch on this variable? ( @@ -218,18 +219,18 @@ detect_switches_in_disj([Var | Vars], Goals0, GoalInfo, InstMap, Left = [] -> cases_to_switch(CasesList, Var, VarTypes, GoalInfo, - InstMap, ModuleInfo, Goal) + FV, InstMap, ModuleInfo, Goal) ; detect_switches_in_disj(Vars, Goals0, GoalInfo, - InstMap, VarTypes, AllVars, ModuleInfo, + FV, InstMap, VarTypes, AllVars, ModuleInfo, [again(Var, Left, CasesList) | Again0], Goal) ) ; - detect_switches_in_disj(Vars, Goals0, GoalInfo, InstMap, + detect_switches_in_disj(Vars, Goals0, GoalInfo, FV, InstMap, VarTypes, AllVars, ModuleInfo, Again0, Goal) ). -detect_switches_in_disj([], Goals0, GoalInfo, InstMap, - VarTypes, AllVars, ModuleInfo, AgainList0, disj(Goals)) :- +detect_switches_in_disj([], Goals0, GoalInfo, FV, InstMap, + VarTypes, AllVars, ModuleInfo, AgainList0, disj(Goals, FV)) :- ( AgainList0 = [], detect_sub_switches_in_disj(Goals0, InstMap, VarTypes, @@ -238,9 +239,9 @@ detect_switches_in_disj([], Goals0, GoalInfo, InstMap, AgainList0 = [Again | AgainList1], select_best_switch(AgainList1, Again, BestAgain), BestAgain = again(Var, Left0, CasesList), - cases_to_switch(CasesList, Var, VarTypes, GoalInfo, InstMap, + cases_to_switch(CasesList, Var, VarTypes, GoalInfo, FV, InstMap, ModuleInfo, SwitchGoal), - detect_switches_in_disj(AllVars, Left0, GoalInfo, InstMap, + detect_switches_in_disj(AllVars, Left0, GoalInfo, FV, InstMap, VarTypes, AllVars, ModuleInfo, [], Left), goal_to_disj_list(Left - GoalInfo, LeftList), Goals = [SwitchGoal - GoalInfo | LeftList] @@ -438,11 +439,10 @@ interpret_unify(_X, lambda_goal(_LambdaVars, _Modes, _Det, _Goal), Subst = Subst0. :- pred cases_to_switch(sorted_case_list, var, map(var, type), hlds__goal_info, - instmap, module_info, hlds__goal_expr). -% :- mode cases_to_switch(di, in, in, in, in, in, uo) is det. -:- mode cases_to_switch(in, in, in, in, in, in, out) is det. + follow_vars, instmap, module_info, hlds__goal_expr). +:- mode cases_to_switch(in, in, in, in, in, in, in, out) is det. -cases_to_switch(CasesList, Var, VarTypes, GoalInfo, InstMap, ModuleInfo, +cases_to_switch(CasesList, Var, VarTypes, GoalInfo, FV, InstMap, ModuleInfo, Goal) :- instmap_lookup_var(InstMap, Var, VarInst), ( inst_is_bound_to_functors(ModuleInfo, VarInst, Functors) -> @@ -465,7 +465,7 @@ cases_to_switch(CasesList, Var, VarTypes, GoalInfo, InstMap, ModuleInfo, ), fix_case_list(CasesList1, GoalInfo, Cases0), detect_switches_in_cases(Cases0, InstMap, VarTypes, ModuleInfo, Cases), - Goal = switch(Var, CanFail, Cases). + Goal = switch(Var, CanFail, Cases, FV). :- pred delete_unreachable_cases(sorted_case_list, list(cons_id), sorted_case_list). diff --git a/compiler/switch_gen.m b/compiler/switch_gen.m index 92865eb07..b1e6ad7f4 100644 --- a/compiler/switch_gen.m +++ b/compiler/switch_gen.m @@ -45,8 +45,9 @@ :- import_module hlds_goal, hlds_data, code_info. :- pred switch_gen__generate_switch(code_model, var, can_fail, list(case), - hlds__goal_info, code_tree, code_info, code_info). -:- mode switch_gen__generate_switch(in, in, in, in, in, out, in, out) is det. + follow_vars, hlds__goal_info, code_tree, code_info, code_info). +:- mode switch_gen__generate_switch(in, in, in, in, in, in, out, in, out) + is det. % These types are exported to dense_switch, string_switch and tag_switch. @@ -73,8 +74,8 @@ % Choose which method to use to generate the switch. % CanFail says whether the switch covers all cases. -switch_gen__generate_switch(CodeModel, CaseVar, CanFail, Cases, GoalInfo, - Code) --> +switch_gen__generate_switch(CodeModel, CaseVar, CanFail, Cases, _FollowVars, + GoalInfo, Code) --> switch_gen__determine_category(CaseVar, SwitchCategory), code_info__get_next_label(EndLabel), switch_gen__lookup_tags(Cases, CaseVar, TaggedCases0), diff --git a/compiler/tag_switch.m b/compiler/tag_switch.m index 6be252257..b9cd25e4b 100644 --- a/compiler/tag_switch.m +++ b/compiler/tag_switch.m @@ -26,7 +26,7 @@ :- implementation. -:- import_module hlds_module, hlds_data, options, globals, code_gen, code_exprn. +:- import_module hlds_module, hlds_data, options, globals, code_gen. :- import_module map, tree, type_util, std_util, int, require. % where is the secondary tag (if any) for this primary tag value diff --git a/compiler/typecheck.m b/compiler/typecheck.m index 6b06ae76b..401aa4bf6 100644 --- a/compiler/typecheck.m +++ b/compiler/typecheck.m @@ -36,7 +36,7 @@ % - a type_assign_set which stores the set of possible % type assignments and is modified as we traverse through % the clause -% +% % 3. For accumulating type_assign_sets. This is when we are % type-checking a single atomic construct (unification or % predicate), and we are iterating through all the @@ -496,10 +496,11 @@ typecheck_goal(Goal0 - GoalInfo0, Goal - GoalInfo, TypeInfo0, TypeInfo) :- typecheck_goal_2(conj(List0), conj(List)) --> checkpoint("conj"), typecheck_goal_list(List0, List). -typecheck_goal_2(disj(List0), disj(List)) --> +typecheck_goal_2(disj(List0, FV), disj(List, FV)) --> checkpoint("disj"), typecheck_goal_list(List0, List). -typecheck_goal_2(if_then_else(Vs, A0, B0, C0), if_then_else(Vs, A, B, C)) --> +typecheck_goal_2(if_then_else(Vs, A0, B0, C0, FV), + if_then_else(Vs, A, B, C, FV)) --> checkpoint("if"), typecheck_goal(A0, A), checkpoint("then"), @@ -522,11 +523,10 @@ typecheck_goal_2(unify(A, B0, Mode, Info, UnifyContext), type_info_set_arg_num(0), type_info_set_unify_context(UnifyContext), typecheck_unification(A, B0, B). -typecheck_goal_2(switch(_, _, _), _) --> +typecheck_goal_2(switch(_, _, _, _), _) --> { error("unexpected switch") }. % no need to typecheck pragmas typecheck_goal_2(pragma_c_code(A,B,C,D,E), pragma_c_code(A,B,C,D,E)) --> []. - %-----------------------------------------------------------------------------% @@ -650,7 +650,7 @@ typecheck_call_overloaded_pred(PredIdList, Args, TypeInfo0, TypeInfo) :- % typecheck_var_has_arg_type_list(Args, 0, ArgsTypeAssignSet, TypeInfo0, TypeInfo). - + :- pred get_overloaded_pred_arg_types(list(pred_id), pred_table, type_assign_set, args_type_assign_set, args_type_assign_set). :- mode get_overloaded_pred_arg_types(in, in, in, in, out) is det. @@ -1063,7 +1063,7 @@ checkpoint(Msg, T0, T) :- globals__io_lookup_bool_option(debug_types, DoCheckPoint, I0, I1), ( DoCheckPoint = yes -> checkpoint_2(Msg, T0, I1, I) - ; + ; I = I1 ), type_info_set_io_state(T0, I, T). @@ -1228,7 +1228,7 @@ typecheck_unify_var_functor(Var, Functor, Args, TypeInfo0, TypeInfo) :- % typecheck_unify_var_functor_get_ctors(TypeAssignSet, TypeInfo, % ConsDefns): - % + % % Iterate over all the different possible type assignments and % constructor definitions. % For each type assignment in `TypeAssignSet', and constructor @@ -2902,6 +2902,6 @@ identical_types(Type1, Type2) :- map__init(TypeSubst0), type_unify(Type1, Type2, [], TypeSubst0, TypeSubst), TypeSubst = TypeSubst0. - + %-----------------------------------------------------------------------------% %-----------------------------------------------------------------------------% diff --git a/compiler/unify_proc.m b/compiler/unify_proc.m index 34c74766b..5edfe3f2f 100644 --- a/compiler/unify_proc.m +++ b/compiler/unify_proc.m @@ -504,7 +504,6 @@ unify_proc__generate_type_to_term_clauses(TypeBody, X, Term, Clauses) --> { Clauses = [clause([], Body, Context)] } ). - %-----------------------------------------------------------------------------% /* @@ -722,7 +721,8 @@ unify_proc__generate_du_compare_clauses_2(Ctors, Res, X, Y, Goal) --> Return_R) }, unify_proc__generate_compare_cases(Ctors, R, X, Y, Cases), - { CasesGoal = disj(Cases) - GoalInfo }, + { map__init(Empty) }, + { CasesGoal = disj(Cases, Empty) - GoalInfo }, unify_proc__build_call("compare_error", [], Abort), @@ -731,10 +731,9 @@ unify_proc__generate_du_compare_clauses_2(Ctors, Res, X, Y, Goal) --> Call_Y_Index, if_then_else([], Call_Less_Than, Return_Less_Than, if_then_else([], Call_Greater_Than, Return_Greater_Than, - if_then_else([], CasesGoal, Return_R, - Abort - ) - GoalInfo - ) - GoalInfo + if_then_else([], CasesGoal, Return_R, Abort, Empty + ) - GoalInfo, Empty + ) - GoalInfo, Empty ) - GoalInfo ]) - GoalInfo }. @@ -850,7 +849,8 @@ unify_proc__compare_args([X|Xs], [Y|Ys], R, Goal) --> R, var(R1), Context, explicit, [], Return_R1) }, { Condition = conj([Do_Comparison, Check_Not_Equal]) - GoalInfo }, - { Goal = if_then_else([], Condition, Return_R1, ElseCase) + { map__init(Empty) }, + { Goal = if_then_else([], Condition, Return_R1, ElseCase, Empty) - GoalInfo}, unify_proc__compare_args(Xs, Ys, R, ElseCase) ). @@ -859,7 +859,6 @@ unify_proc__compare_args([], [_|_], _, _) --> unify_proc__compare_args([_|_], [], _, _) --> { error("unify_proc__compare_args: length mismatch") }. - /* For a type such as type tree(T1, T2) ---> @@ -909,7 +908,6 @@ unify_proc__compare_args([_|_], [], _, _) --> ). */ - :- pred unify_proc__generate_du_term_to_type_clauses(list(constructor), var, var, list(clause), unify_proc_info, unify_proc_info). :- mode unify_proc__generate_du_term_to_type_clauses(in, in, in, out, in, out) @@ -965,7 +963,6 @@ unify_proc__generate_du_term_to_type_clauses([Ctor | Ctors], Term, X, unify_proc__info_set_types(Types), { Clause = clause([], Body, Context) }. - :- pred unify_proc__generate_du_term_to_type_disjunctions( list(constructor), var, var, var, term, term, term, term, term, list(hlds__goal), @@ -1014,7 +1011,6 @@ unify_proc__generate_du_term_to_type_disjunctions([Ctor | Ctors], V2, V4, X, ConstType, TermType, TermListType, ContextType, StringType, Goals). - :- pred unify_proc__generate_du_term_to_type_recursive( list(var), var, term__context, type, type, list(hlds__goal), list(hlds__goal), unify_proc_info, unify_proc_info). @@ -1046,7 +1042,6 @@ unify_proc__generate_du_term_to_type_recursive( ArgVars, TermListVar, Context, TermType, TermListType, TermGoals, Term_To_TypeGoals). - /* For a type such as type tree(T1, T2) ---> @@ -1102,13 +1097,11 @@ unify_proc__generate_du_term_to_type_recursive( ). */ - :- pred unify_proc__generate_du_type_to_term_clauses(list(constructor), var, var, list(clause), unify_proc_info, unify_proc_info). :- mode unify_proc__generate_du_type_to_term_clauses(in, in, in, out, in, out) is det. - unify_proc__generate_du_type_to_term_clauses([], _X, _Term, []) --> []. unify_proc__generate_du_type_to_term_clauses([Ctor | Ctors], X, Term, [Clause | Clauses]) --> @@ -1212,7 +1205,6 @@ unify_proc__generate_du_type_to_term_clauses([Ctor | Ctors], X, Term, % Make clauses for other functors of type unify_proc__generate_du_type_to_term_clauses(Ctors, X, Term, Clauses). - :- pred unify_proc__generate_du_type_to_term_recursive_clauses( list(var), var, term__context, type, type, list(hlds__goal), unify_proc_info, unify_proc_info). diff --git a/compiler/unique_modes.m b/compiler/unique_modes.m index 6294f6c17..717f6a500 100644 --- a/compiler/unique_modes.m +++ b/compiler/unique_modes.m @@ -385,7 +385,7 @@ unique_modes__check_goal_2(conj(List0), _GoalInfo0, conj(List)) --> ), mode_checkpoint(exit, "conj"). -unique_modes__check_goal_2(disj(List0), GoalInfo0, disj(List)) --> +unique_modes__check_goal_2(disj(List0, FV), GoalInfo0, disj(List, FV)) --> mode_checkpoint(enter, "disj"), ( { List0 = [] } -> % for efficiency, optimize common case { List = [] }, @@ -410,7 +410,8 @@ unique_modes__check_goal_2(disj(List0), GoalInfo0, disj(List)) --> ), mode_checkpoint(exit, "disj"). -unique_modes__check_goal_2(if_then_else(Vs, A0, B0, C0), GoalInfo0, Goal) --> +unique_modes__check_goal_2(if_then_else(Vs, A0, B0, C0, FV), GoalInfo0, Goal) + --> mode_checkpoint(enter, "if-then-else"), { goal_info_get_nonlocals(GoalInfo0, NonLocals) }, { unique_modes__goal_get_nonlocals(A0, A_Vars) }, @@ -478,7 +479,7 @@ unique_modes__check_goal_2(if_then_else(Vs, A0, B0, C0), GoalInfo0, Goal) --> { Goal = if_then_else(Vs, A, B, C) } ), */ - { Goal = if_then_else(Vs, A, B, C) }, + { Goal = if_then_else(Vs, A, B, C, FV) }, mode_checkpoint(exit, "if-then-else"). unique_modes__check_goal_2(not(A0), GoalInfo0, not(A)) --> @@ -522,8 +523,8 @@ unique_modes__check_goal_2(unify(A0, B0, _, UnifyInfo0, UnifyContext), mode_info_unset_call_context, mode_checkpoint(exit, "unify"). -unique_modes__check_goal_2(switch(Var, CanFail, Cases0), GoalInfo0, - switch(Var, CanFail, Cases)) --> +unique_modes__check_goal_2(switch(Var, CanFail, Cases0, FV), GoalInfo0, + switch(Var, CanFail, Cases, FV)) --> mode_checkpoint(enter, "switch"), ( { Cases0 = [] } -> { Cases = [] }, diff --git a/compiler/unused_args.m b/compiler/unused_args.m index 4a83fa0ca..94ed25860 100644 --- a/compiler/unused_args.m +++ b/compiler/unused_args.m @@ -261,11 +261,11 @@ traverse_goal(ModuleInfo, conj(Goals), UseInf0, UseInf) :- traverse_list_of_goals(ModuleInfo, Goals, UseInf0, UseInf). % handle disjunction -traverse_goal(ModuleInfo, disj(Goals), UseInf0, UseInf) :- +traverse_goal(ModuleInfo, disj(Goals, _), UseInf0, UseInf) :- traverse_list_of_goals(ModuleInfo, Goals, UseInf0, UseInf). % handle switch -traverse_goal(ModuleInfo, switch(Var, _, Cases), UseInf0, UseInf) :- +traverse_goal(ModuleInfo, switch(Var, _, Cases, _), UseInf0, UseInf) :- map__delete(UseInf0, Var, UseInf1), list_case_to_list_goal(Cases, Goals), traverse_list_of_goals(ModuleInfo, Goals, UseInf1, UseInf). @@ -279,7 +279,7 @@ traverse_goal(ModuleInfo, call(PredId, ProcId, Args, _, _, _, _), UseInf0, UseInf). % handle if then else -traverse_goal(ModuleInfo, if_then_else(_, Cond - _, Then - _, Else - _), +traverse_goal(ModuleInfo, if_then_else(_, Cond - _, Then - _, Else - _, _), UseInf0, UseInf) :- traverse_goal(ModuleInfo, Cond, UseInf0, UseInf1), traverse_goal(ModuleInfo, Then, UseInf1, UseInf2), @@ -840,7 +840,7 @@ fixup_goal_expr(UnusedVars, ProcCallInfo, Changed, fixup_conjuncts(UnusedVars, ProcCallInfo, no, Changed, Goals0, Goals). fixup_goal_expr(UnusedVars, ProcCallInfo, Changed, - disj(Goals0) - GoalInfo, disj(Goals) - GoalInfo) :- + disj(Goals0, FV) - GoalInfo, disj(Goals, FV) - GoalInfo) :- fixup_disjuncts(UnusedVars, ProcCallInfo, no, Changed, Goals0, Goals). fixup_goal_expr(UnusedVars, ProcCallInfo, Changed, @@ -848,13 +848,13 @@ fixup_goal_expr(UnusedVars, ProcCallInfo, Changed, fixup_goal(UnusedVars, ProcCallInfo, Changed, NegGoal0, NegGoal). fixup_goal_expr(UnusedVars, ProcCallInfo, Changed, - switch(Var, CanFail, Cases0) - GoalInfo, - switch(Var, CanFail, Cases) - GoalInfo) :- + switch(Var, CanFail, Cases0, FV) - GoalInfo, + switch(Var, CanFail, Cases, FV) - GoalInfo) :- fixup_cases(UnusedVars, ProcCallInfo, no, Changed, Cases0, Cases). fixup_goal_expr(UnusedVars, ProcCallInfo, Changed, - if_then_else(Vars, Cond0, Then0, Else0) - GoalInfo, - if_then_else(Vars, Cond, Then, Else) - GoalInfo) :- + if_then_else(Vars, Cond0, Then0, Else0, FV) - GoalInfo, + if_then_else(Vars, Cond, Then, Else, FV) - GoalInfo) :- fixup_goal(UnusedVars, ProcCallInfo, Changed1, Cond0, Cond), fixup_goal(UnusedVars, ProcCallInfo, Changed2, Then0, Then), fixup_goal(UnusedVars, ProcCallInfo, Changed3, Else0, Else), diff --git a/compiler/value_number.m b/compiler/value_number.m index 96eeddd4e..ad8b7ad46 100644 --- a/compiler/value_number.m +++ b/compiler/value_number.m @@ -339,7 +339,8 @@ value_number__optimize_fragment_2(Instrs0, LiveMap, Params, ParEntries, { value_number__push_incr_sp_forw(Instrs2, Instrs3) }, { value_number__push_livevals_back(Instrs3, Instrs4) }, { value_number__convert_back_modframe(Instrs4, Instrs5) }, - { vn_filter__block(Instrs5, Instrs6) }, + % { vn_filter__block(Instrs5, Instrs6) }, + { Instrs6 = Instrs5 }, { bimap__init(TeardownMap) }, { peephole__optimize(Instrs6, Instrs7, TeardownMap, no, _) }, diff --git a/compiler/vn_verify.m b/compiler/vn_verify.m index e748bf463..f66a0657d 100644 --- a/compiler/vn_verify.m +++ b/compiler/vn_verify.m @@ -436,10 +436,11 @@ vn_verify__tags_rval(binop(_, Rval1, Rval2), NoDeref) :- vn_verify__tags_cond(Cond, NoDeref0, NoDeref, Tested0, Tested) :- ( - Cond = binop(Binop, Rval1, Rval2), - ( Binop = eq ; Binop = (<) ; Binop = (>) - ; Binop = ne ; Binop = (<=) ; Binop = (>=) ) + Cond = binop(Binop, Rval1, Rval2) + % ( Binop = eq ; Binop = (<) ; Binop = (>) + % ; Binop = ne ; Binop = (<=) ; Binop = (>=) ) -> + ( Binop = eq ; Binop = ne ), ( vn_verify__tags_is_base(Rval1, Base1) -> set__insert(NoDeref0, Base1, NoDeref1) ;