[m-rev.] for review: exception analysis, intermodule-analysis and optimization
Julien Fischer
juliensf at cs.mu.OZ.AU
Thu Feb 16 01:10:23 AEDT 2006
For review by anyone. (Peter, could you please have a look the changes
to exception_analysis.m.)
Estimated hours taken: 10
Branches: main
Convert those optimization passes that make use of exception analysis
information to make use of the intermodule-analysis framework.
Make preparations to do the same thing for the termination analyses.
s/list(prog_var)/prog_vars/
s/list(hlds_goal)/hlds_goals/
Style cleanups and formatting fixes for these modules as necessary.
compiler/exception_analysis.m:
Export a predicate that allows optimizations to access exception
analysis results without worrying about where they are stored. When
using intermodule-analysis information about imported procedures is
stored in the analysis registry, not in the exception_info table; with
intermodule-optimization information about imported procedures is
stored in the exception_info table.
compiler/goal_form.m:
Add a version of goal_cannot_throw that uses information from the
intermodule-analysis framework.
Mention that the existing versions of this predicate are deprecated
and will eventually be deleted.
compiler/goal_util.m:
Provide alternative versions of the predicates can_reorder_goals and
reordering_maintains_termination that can use information from the
intermodule-analysis framework. We will eventually use these versions
exclusively.
compiler/simplify.m:
compiler/constraint.m:
Use information from the intermodule-analysis framework when
performing these optimizations.
compiler/accumulator.m:
Mention that this module needs to be updated to use the
intermodule-analysis framework. (I'll do this as separate change
since it's probably going to require a fairly major rewrite of this
module to do this.)
compiler/deforest.m:
compiler/pd_util.m:
compiler/size_prof.m:
Conform to the above changes.
Julien.
Index: compiler/accumulator.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/accumulator.m,v
retrieving revision 1.48
diff -u -r1.48 accumulator.m
--- compiler/accumulator.m 28 Nov 2005 04:11:36 -0000 1.48
+++ compiler/accumulator.m 15 Feb 2006 13:49:19 -0000
@@ -137,6 +137,9 @@
% until one succeeds. This makes the order of independent recursive
% calls in the body irrelevant.
+% XXX replace calls to can_reorder_goals with calls to the version that
+% use the intermodule-analysis framework.
+
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
Index: compiler/constraint.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/constraint.m,v
retrieving revision 1.67
diff -u -r1.67 constraint.m
--- compiler/constraint.m 17 Nov 2005 15:57:05 -0000 1.67
+++ compiler/constraint.m 15 Feb 2006 14:02:49 -0000
@@ -5,18 +5,18 @@
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%-----------------------------------------------------------------------------%
-%
+
% File: constraint.m
% Main author: stayl.
-%
+
% The constraint propagation transformation attempts to improve the efficiency
% of a generate-and-test style program by statically scheduling constraints as
% early as possible, where a "constraint" is any pure goal which has no
% outputs, can fail, cannot loop and cannot throw an exception.
-%
+
%-----------------------------------------------------------------------------%
-:- module transform_hlds__constraint.
+:- module transform_hlds.constraint.
:- interface.
:- import_module hlds.hlds_goal.
@@ -25,6 +25,7 @@
:- import_module parse_tree.prog_data.
:- import_module bool.
+:- import_module io.
%-----------------------------------------------------------------------------%
@@ -37,7 +38,7 @@
% goal feature.
%
:- pred propagate_constraints_in_goal(hlds_goal::in, hlds_goal::out,
- constraint_info::in, constraint_info::out) is det.
+ constraint_info::in, constraint_info::out, io::di, io::uo) is det.
:- pred constraint_info_init(module_info::in, vartypes::in, prog_varset::in,
instmap::in, constraint_info::out) is det.
@@ -72,7 +73,7 @@
%-----------------------------------------------------------------------------%
-propagate_constraints_in_goal(Goal0, Goal, !Info) :-
+propagate_constraints_in_goal(Goal0, Goal, !Info, !IO) :-
% We need to strip off any existing constraint markers first.
% Constraint markers are meant to indicate where a constraint is
% meant to be attached to a call, and that deforest.m should
@@ -80,12 +81,13 @@
% deforest.m rearranges the goal, the constraints may not remain
% next to the call.
Goal1 = strip_constraint_markers(Goal0),
- propagate_goal(Goal1, [], Goal, !Info).
+ propagate_goal(Goal1, [], Goal, !Info, !IO).
:- pred propagate_goal(hlds_goal::in, list(constraint)::in,
- hlds_goal::out, constraint_info::in, constraint_info::out) is det.
+ hlds_goal::out, constraint_info::in, constraint_info::out,
+ io::di, io::uo) is det.
-propagate_goal(Goal0, Constraints, Goal, !Info) :-
+propagate_goal(Goal0, Constraints, Goal, !Info, !IO) :-
% We need to treat all single goals as conjunctions so that
% propagate_conj can move the constraints to the left of the goal
% if that is allowed.
@@ -93,7 +95,7 @@
goal_info_get_features(GoalInfo0, Features0),
goal_info_get_context(GoalInfo0, Context),
goal_to_conj_list(Goal0, Goals0),
- propagate_conj(Goals0, Constraints, Goals, !Info),
+ propagate_conj(Goals0, Constraints, Goals, !Info, !IO),
goal_list_nonlocals(Goals, NonLocals),
goal_list_instmap_delta(Goals, Delta),
goal_list_determinism(Goals, ConjDetism),
@@ -106,9 +108,9 @@
:- pred propagate_conj_sub_goal(hlds_goal::in,
list(constraint)::in, hlds_goals::out,
- constraint_info::in, constraint_info::out) is det.
+ constraint_info::in, constraint_info::out, io::di, io::uo) is det.
-propagate_conj_sub_goal(Goal0, Constraints, Goals, !Info) :-
+propagate_conj_sub_goal(Goal0, Constraints, Goals, !Info, !IO) :-
Goal0 = GoalExpr0 - _,
( goal_is_atomic(GoalExpr0) ->
true
@@ -119,67 +121,67 @@
constraint_info_update_changed(Constraints, !Info)
),
InstMap0 = !.Info ^ instmap,
- propagate_conj_sub_goal_2(Goal0, Constraints, Goals, !Info),
+ propagate_conj_sub_goal_2(Goal0, Constraints, Goals, !Info, !IO),
!:Info = !.Info ^ instmap := InstMap0.
:- pred propagate_conj_sub_goal_2(hlds_goal::in, list(constraint)::in,
- list(hlds_goal)::out, constraint_info::in, constraint_info::out)
- is det.
+ list(hlds_goal)::out, constraint_info::in, constraint_info::out,
+ io::di, io::uo) is det.
propagate_conj_sub_goal_2(conj(Goals0) - Info, Constraints,
- [conj(Goals) - Info], !Info) :-
- propagate_conj(Goals0, Constraints, Goals, !Info).
+ [conj(Goals) - Info], !Info, !IO) :-
+ propagate_conj(Goals0, Constraints, Goals, !Info, !IO).
propagate_conj_sub_goal_2(disj(Goals0) - Info, Constraints,
- [disj(Goals) - Info], !Info) :-
- propagate_disj(Goals0, Constraints, Goals, !Info).
+ [disj(Goals) - Info], !Info, !IO) :-
+ propagate_disj(Goals0, Constraints, Goals, !Info, !IO).
propagate_conj_sub_goal_2(switch(Var, CanFail, Cases0) - Info,
- Constraints, [switch(Var, CanFail, Cases) - Info], !Info) :-
- propagate_cases(Var, Constraints, Cases0, Cases, !Info).
+ Constraints, [switch(Var, CanFail, Cases) - Info], !Info, !IO) :-
+ propagate_cases(Var, Constraints, Cases0, Cases, !Info, !IO).
propagate_conj_sub_goal_2(
if_then_else(Vars, Cond0, Then0, Else0) - Info,
Constraints,
- [if_then_else(Vars, Cond, Then, Else) - Info], !Info) :-
+ [if_then_else(Vars, Cond, Then, Else) - Info], !Info, !IO) :-
InstMap0 = !.Info ^ instmap,
% We can't safely propagate constraints into
% the condition of an if-then-else, because that
% would change the answers generated by the procedure.
- propagate_goal(Cond0, [], Cond, !Info),
+ propagate_goal(Cond0, [], Cond, !Info, !IO),
constraint_info_update_goal(Cond, !Info),
- propagate_goal(Then0, Constraints, Then, !Info),
+ propagate_goal(Then0, Constraints, Then, !Info, !IO),
!:Info = !.Info ^ instmap := InstMap0,
- propagate_goal(Else0, Constraints, Else, !Info).
+ propagate_goal(Else0, Constraints, Else, !Info, !IO).
% XXX propagate constraints into par_conjs -- this isn't
% possible at the moment because par_conj goals must have
% determinism det.
propagate_conj_sub_goal_2(par_conj(Goals0) - GoalInfo,
Constraints0,
- [par_conj(Goals) - GoalInfo | Constraints], !Info) :-
+ [par_conj(Goals) - GoalInfo | Constraints], !Info, !IO) :-
% Propagate constraints within the goals of the conjunction.
% propagate_disj treats its list of goals as
% independent rather than specifically disjoint, so we can
% use it to process a list of independent parallel conjuncts.
- propagate_disj(Goals0, [], Goals, !Info),
+ propagate_disj(Goals0, [], Goals, !Info, !IO),
flatten_constraints(Constraints0, Constraints).
propagate_conj_sub_goal_2(scope(Reason, Goal0) - GoalInfo, Constraints,
- [scope(Reason, Goal) - GoalInfo], !Info) :-
- propagate_goal(Goal0, Constraints, Goal, !Info).
+ [scope(Reason, Goal) - GoalInfo], !Info, !IO) :-
+ propagate_goal(Goal0, Constraints, Goal, !Info, !IO).
propagate_conj_sub_goal_2(not(NegGoal0) - GoalInfo, Constraints0,
- [not(NegGoal) - GoalInfo | Constraints], !Info) :-
+ [not(NegGoal) - GoalInfo | Constraints], !Info, !IO) :-
% We can't safely propagate constraints into a negation,
% because that would change the answers computed by the
% procedure.
- propagate_goal(NegGoal0, [], NegGoal, !Info),
+ propagate_goal(NegGoal0, [], NegGoal, !Info, !IO),
flatten_constraints(Constraints0, Constraints).
propagate_conj_sub_goal_2(Goal, Constraints0,
- [Goal | Constraints], !Info) :-
+ [Goal | Constraints], !Info, !IO) :-
% propagate_conj will move the constraints
% to the left of the call if that is possible, so nothing
% needs to be done here.
@@ -187,21 +189,21 @@
flatten_constraints(Constraints0, Constraints).
propagate_conj_sub_goal_2(Goal, Constraints0,
- [Goal | Constraints], !Info) :-
+ [Goal | Constraints], !Info, !IO) :-
Goal = generic_call(_, _, _, _) - _,
flatten_constraints(Constraints0, Constraints).
propagate_conj_sub_goal_2(Goal, Constraints0,
- [Goal | Constraints], !Info) :-
+ [Goal | Constraints], !Info, !IO) :-
Goal = foreign_proc(_, _, _, _, _, _) - _,
flatten_constraints(Constraints0, Constraints).
-propagate_conj_sub_goal_2(Goal, _, _, !Info) :-
+propagate_conj_sub_goal_2(Goal, _, _, !Info, !IO) :-
Goal = shorthand(_) - _,
unexpected(this_file, "propagate_conj_sub_goal_2: shorthand").
propagate_conj_sub_goal_2(Goal, Constraints0,
- [Goal | Constraints], !Info) :-
+ [Goal | Constraints], !Info, !IO) :-
Goal = unify(_, _, _, _, _) - _,
flatten_constraints(Constraints0, Constraints).
@@ -209,7 +211,7 @@
% Put the constant constructions in front of the constraint.
%
-:- pred flatten_constraints(list(constraint)::in, list(hlds_goal)::out) is det.
+:- pred flatten_constraints(list(constraint)::in, hlds_goals::out) is det.
flatten_constraints(Constraints0, Goals) :-
list__map((pred(Constraint::in, Lists::out) is det :-
@@ -221,31 +223,31 @@
%-----------------------------------------------------------------------------%
-:- pred propagate_disj(list(hlds_goal)::in, list(constraint)::in,
- list(hlds_goal)::out, constraint_info::in, constraint_info::out)
- is det.
+:- pred propagate_disj(hlds_goals::in, list(constraint)::in,
+ hlds_goals::out, constraint_info::in, constraint_info::out,
+ io::di, io::uo) is det.
-propagate_disj([], _, [], !Info).
-propagate_disj([Goal0 | Goals0], Constraints, [Goal | Goals], !Info) :-
+propagate_disj([], _, [], !Info, !IO).
+propagate_disj([Goal0 | Goals0], Constraints, [Goal | Goals], !Info, !IO) :-
InstMap0 = !.Info ^ instmap,
- propagate_goal(Goal0, Constraints, Goal, !Info),
+ propagate_goal(Goal0, Constraints, Goal, !Info, !IO),
!:Info = !.Info ^ instmap := InstMap0,
- propagate_disj(Goals0, Constraints, Goals, !Info).
+ propagate_disj(Goals0, Constraints, Goals, !Info, !IO).
%-----------------------------------------------------------------------------%
:- pred propagate_cases(prog_var::in, list(constraint)::in,
list(case)::in, list(case)::out,
- constraint_info::in, constraint_info::out) is det.
+ constraint_info::in, constraint_info::out, io::di, io::uo) is det.
-propagate_cases(_, _, [], [], !Info).
+propagate_cases(_, _, [], [], !Info, !IO).
propagate_cases(Var, Constraints, [case(ConsId, Goal0) | Cases0],
- [case(ConsId, Goal) | Cases], !Info) :-
+ [case(ConsId, Goal) | Cases], !Info, !IO) :-
InstMap0 = !.Info ^ instmap,
constraint_info_bind_var_to_functor(Var, ConsId, !Info),
- propagate_goal(Goal0, Constraints, Goal, !Info),
+ propagate_goal(Goal0, Constraints, Goal, !Info, !IO),
!:Info = !.Info ^ instmap := InstMap0,
- propagate_cases(Var, Constraints, Cases0, Cases, !Info).
+ propagate_cases(Var, Constraints, Cases0, Cases, !Info, !IO).
%-----------------------------------------------------------------------------%
@@ -255,16 +257,16 @@
% encountered to increase the likelihood of folding recursive
% calls.
%
-:- pred propagate_conj(list(hlds_goal)::in, list(constraint)::in,
- list(hlds_goal)::out, constraint_info::in, constraint_info::out)
- is det.
+:- pred propagate_conj(hlds_goals::in, list(constraint)::in,
+ hlds_goals::out, constraint_info::in, constraint_info::out,
+ io::di, io::uo) is det.
-propagate_conj(Goals0, Constraints, Goals, !Info) :-
+propagate_conj(Goals0, Constraints, Goals, !Info, !IO) :-
constraint_info_update_changed(Constraints, !Info),
( Goals0 = [] ->
flatten_constraints(Constraints, Goals)
; Goals0 = [Goal0], Constraints = [] ->
- propagate_conj_sub_goal(Goal0, [], Goals, !Info)
+ propagate_conj_sub_goal(Goal0, [], Goals, !Info, !IO)
;
InstMap0 = !.Info ^ instmap,
ModuleInfo = !.Info ^ module_info,
@@ -272,8 +274,8 @@
annotate_conj_output_vars(Goals0, ModuleInfo,
VarTypes, InstMap0, [], RevGoals1),
annotate_conj_constraints(ModuleInfo, RevGoals1,
- Constraints, [], Goals2, !Info),
- propagate_conj_constraints(Goals2, [], Goals, !Info)
+ Constraints, [], Goals2, !Info, !IO),
+ propagate_conj_constraints(Goals2, [], Goals, !Info, !IO)
).
% Annotate each conjunct with the variables it produces.
@@ -389,12 +391,12 @@
% Pass backwards over the conjunction, annotating each conjunct
% with the constraints that should be pushed into it.
- %
+ %
:- pred annotate_conj_constraints(module_info::in, annotated_conj::in,
list(constraint)::in, constrained_conj::in, constrained_conj::out,
- constraint_info::in, constraint_info::out) is det.
+ constraint_info::in, constraint_info::out, io::di, io::uo) is det.
-annotate_conj_constraints(_, [], Constraints0, Goals0, Goals, !Info) :-
+annotate_conj_constraints(_, [], Constraints0, Goals0, Goals, !Info, !IO) :-
flatten_constraints(Constraints0, Constraints1),
list__map((pred(Goal::in, CnstrGoal::out) is det :-
CnstrGoal = Goal - []
@@ -402,11 +404,15 @@
list__append(Constraints, Goals0, Goals).
annotate_conj_constraints(ModuleInfo,
[Conjunct | RevConjuncts0],
- Constraints0, Goals0, Goals, !Info) :-
+ Constraints0, Goals0, Goals, !Info, !IO) :-
Conjunct = annotated_conjunct(Goal, ChangedVars, OutputVars,
IncompatibleInstVars),
Goal = GoalExpr - GoalInfo,
goal_info_get_nonlocals(GoalInfo, NonLocals),
+ CI_ModuleInfo0 = !.Info ^ module_info,
+ goal_cannot_loop_or_throw(Goal, GoalCannotLoopOrThrow,
+ CI_ModuleInfo0, CI_ModuleInfo, !IO),
+ !:Info = !.Info ^ module_info := CI_ModuleInfo,
(
% Propagate goals that can fail and have no output
% variables. Propagating cc_nondet goals would be
@@ -428,8 +434,8 @@
% Don't propagate impure goals.
goal_info_is_pure(GoalInfo),
- % Don't propagate goals that can loop or throw exceptions..
- goal_cannot_loop_or_throw(ModuleInfo, Goal)
+ % Don't propagate goals that can loop or throw exceptions.
+ GoalCannotLoopOrThrow = no
->
% It's a constraint, add it to the list of constraints
% to be attached to goals earlier in the conjunction.
@@ -508,7 +514,7 @@
| Goals0]
),
annotate_conj_constraints(ModuleInfo, RevConjuncts0,
- Constraints1, Goals1, Goals, !Info).
+ Constraints1, Goals1, Goals, !Info, !IO).
:- pred add_empty_constraints(hlds_goal::in,
pair(hlds_goal, list(constraint))::out) is det.
@@ -668,22 +674,23 @@
%
:- pred propagate_conj_constraints(constrained_conj::in,
list(hlds_goal)::in, list(hlds_goal)::out,
- constraint_info::in, constraint_info::out) is det.
+ constraint_info::in, constraint_info::out,
+ io::di, io::uo) is det.
-propagate_conj_constraints([], RevGoals, Goals, !Info) :-
+propagate_conj_constraints([], RevGoals, Goals, !Info, !IO) :-
list__reverse(RevGoals, Goals).
propagate_conj_constraints([Goal0 - Constraints0 | Goals0],
- RevGoals0, RevGoals, !Info) :-
+ RevGoals0, RevGoals, !Info, !IO) :-
filter_complex_constraints(Constraints0,
SimpleConstraints, ComplexConstraints0),
- propagate_conj_sub_goal(Goal0, SimpleConstraints, GoalList1, !Info),
+ propagate_conj_sub_goal(Goal0, SimpleConstraints, GoalList1, !Info, !IO),
flatten_constraints(ComplexConstraints0, ComplexConstraints),
list__reverse(ComplexConstraints, RevComplexConstraints),
list__reverse(GoalList1, RevGoalList1),
list__condense([RevComplexConstraints, RevGoalList1, RevGoals0],
RevGoals1),
constraint_info_update_goal(Goal0, !Info),
- propagate_conj_constraints(Goals0, RevGoals1, RevGoals, !Info).
+ propagate_conj_constraints(Goals0, RevGoals1, RevGoals, !Info, !IO).
:- pred filter_complex_constraints(list(constraint)::in,
list(constraint)::out, list(constraint)::out) is det.
Index: compiler/deforest.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/deforest.m,v
retrieving revision 1.57
diff -u -r1.57 deforest.m
--- compiler/deforest.m 28 Nov 2005 04:11:40 -0000 1.57
+++ compiler/deforest.m 15 Feb 2006 08:04:51 -0000
@@ -208,7 +208,7 @@
% Inlining may have created some opportunities for simplification.
globals__io_get_globals(Globals, !IO),
simplify__find_simplifications(no, Globals, Simplifications),
- pd_util__simplify_goal(Simplifications, !Goal, !PDInfo),
+ pd_util__simplify_goal(Simplifications, !Goal, !PDInfo, !IO),
pd_util__propagate_constraints(!Goal, !PDInfo, !IO),
@@ -1629,7 +1629,7 @@
% Be a bit more aggressive with common structure elimination.
% This helps achieve folding in some cases.
Simplifications = [extra_common_struct | Simplifications0],
- pd_util__simplify_goal(Simplifications, Goal2, Goal3, !PDInfo),
+ pd_util__simplify_goal(Simplifications, Goal2, Goal3, !PDInfo, !IO),
pd_info_set_instmap(InstMap0, !PDInfo),
% Perform any folding which may now be possible.
@@ -1858,7 +1858,7 @@
pd_info_get_module_info(!.PDInfo, ModuleInfo),
module_info_get_globals(ModuleInfo, Globals),
simplify__find_simplifications(no, Globals, Simplifications),
- pd_util__simplify_goal(Simplifications, Goal3, Goal4, !PDInfo),
+ pd_util__simplify_goal(Simplifications, Goal3, Goal4, !PDInfo, !IO),
pd_info_get_cost_delta(!.PDInfo, CostDelta1),
CostDelta = CostDelta1 - CostDelta0,
Index: compiler/exception_analysis.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/exception_analysis.m,v
retrieving revision 1.19
diff -u -r1.19 exception_analysis.m
--- compiler/exception_analysis.m 6 Feb 2006 05:39:41 -0000 1.19
+++ compiler/exception_analysis.m 15 Feb 2006 05:30:29 -0000
@@ -81,6 +81,7 @@
:- import_module analysis.
:- import_module hlds.hlds_module.
:- import_module hlds.hlds_pred.
+:- import_module parse_tree.prog_data.
:- import_module io.
@@ -96,6 +97,19 @@
:- pred write_pragma_exceptions(module_info::in, exception_info::in,
pred_id::in, io::di, io::uo) is det.
+ % Look the exception status of the given procedure. This predicate
+ % is intended to be used by optimisations that use exception analysis
+ % information, *not* for use within the exception analysis itself.
+ % This predicate abstracts away differences between
+ % intermodule-optimization and intermodule-analysis.
+ %
+ % NOTE: if intermodule-analysis is enabled then this procedure will
+ % update the IMDG as well.
+ %
+:- pred lookup_exception_analysis_result(pred_proc_id::in,
+ exception_status::out, module_info::in, module_info::out, io::di, io::uo)
+ is det.
+
%----------------------------------------------------------------------------%
%
% Types and instances for the intermodule analysis framework
@@ -125,7 +139,6 @@
:- import_module mdbcomp.prim_data.
:- import_module parse_tree.mercury_to_mercury.
:- import_module parse_tree.modules.
-:- import_module parse_tree.prog_data.
:- import_module parse_tree.prog_out.
:- import_module parse_tree.prog_type.
:- import_module parse_tree.prog_util.
@@ -1162,6 +1175,63 @@
).
%----------------------------------------------------------------------------%
+%
+% External interface to exception analysis information
+%
+
+lookup_exception_analysis_result(PPId, ExceptionStatus, !ModuleInfo, !IO) :-
+ PPId = proc(PredId, _),
+ module_info_pred_info(!.ModuleInfo, PredId, PredInfo),
+ IsImported = pred_to_bool(pred_info_is_imported(PredInfo)),
+ globals.io_lookup_bool_option(intermodule_analysis, IntermodAnalysis,
+ !IO),
+ %
+ % If we the procedure we are calling is imported and we are using
+ % intermodule-analysis then we need to look up the exception status in the
+ % analysis registry; otherwise we look it up in the the exception_info
+ % table.
+ %
+ UseAnalysisRegistry = IsImported `bool.and` IntermodAnalysis,
+ (
+ % If the procedure is not imported then it's exception_status
+ % will be in the exception_info table.
+ UseAnalysisRegistry = no,
+ module_info_get_exception_info(!.ModuleInfo, ExceptionInfo),
+ (
+ map.search(ExceptionInfo, PPId, ProcExceptionInfo)
+ ->
+ ProcExceptionInfo = proc_exception_info(ExceptionStatus, _)
+ ;
+ ExceptionStatus = may_throw(user_exception)
+ )
+ ;
+ UseAnalysisRegistry = yes,
+ some [!AnalysisInfo] (
+ module_info_get_analysis_info(!.ModuleInfo, !:AnalysisInfo),
+ module_id_func_id(!.ModuleInfo, PPId, ModuleId, FuncId),
+ lookup_best_result(ModuleId, FuncId, any_call, MaybeBestStatus,
+ !AnalysisInfo, !IO),
+ (
+ MaybeBestStatus = yes({_Call, Answer, AnalysisStatus}),
+ ( AnalysisStatus = invalid ->
+ % Don't make use of invalid analysis results.
+ ExceptionStatus = may_throw(user_exception)
+ ;
+ Answer = exception_analysis_answer(ExceptionStatus)
+ )
+ ;
+ MaybeBestStatus = no,
+ ExceptionStatus = may_throw(user_exception)
+ ),
+ module_info_get_name(!.ModuleInfo, ThisModuleName),
+ ThisModuleId = module_name_to_module_id(ThisModuleName),
+ record_dependency(ThisModuleId, analysis_name, ModuleId, FuncId,
+ any_call, !AnalysisInfo),
+ module_info_set_analysis_info(!.AnalysisInfo, !ModuleInfo)
+ )
+ ).
+
+%----------------------------------------------------------------------------%
:- func this_file = string.
Index: compiler/goal_form.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/goal_form.m,v
retrieving revision 1.24
diff -u -r1.24 goal_form.m
--- compiler/goal_form.m 1 Feb 2006 04:02:45 -0000 1.24
+++ compiler/goal_form.m 15 Feb 2006 13:38:32 -0000
@@ -5,14 +5,13 @@
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%-----------------------------------------------------------------------------%
-%
+
% File: goal_form.m.
% Main authors: conway, zs.
-%
+
% A module that provides functions that check whether goals fulfill particular
% criteria.
-%
-%
+
%-----------------------------------------------------------------------------%
:- module hlds__goal_form.
@@ -22,14 +21,41 @@
:- import_module hlds.hlds_module.
:- import_module hlds.hlds_pred.
-:- import_module list.
+:- import_module bool.
+:- import_module io.
+
+%-----------------------------------------------------------------------------%
+%
+% These versions use information from the intermodule-analysis framework
+%
+
+% XXX Eventually we will only use these versions and the others can be
+% deleted.
+
+ % Return `yes' if the given goal cannot throw an exception; return `no'
+ % otherwise.
+ %
+ % This version differs from the ones below in that it can use results from
+ % the intermodule-analysis framework (if they are available). The HLDS
+ % and I/O state need to be threaded through in case analysis files need to
+ % be read and in case IMDGs need to be updated.
+ %
+:- pred goal_cannot_throw(hlds_goal::in, bool::out,
+ module_info::in, module_info::out, io::di, io::uo) is det.
+
+ % Return `yes' if the goal cannot loop and cannot throw an exception;
+ % return `no' otherwise.
+ %
+:- pred goal_cannot_loop_or_throw(hlds_goal::in, bool::out, module_info::in,
+ module_info::out, io::di, io::uo) is det.
%-----------------------------------------------------------------------------%
%
% The first three versions may be more accurate because they can use
% results of the termination and exception analyses.
-%
+% XXX These don't work with the intermodule-analysis framework, so don't
+% use them in new code.
% Succeeds if the goal cannot loop forever.
%
@@ -82,7 +108,7 @@
% allocate heap space, such as construction of boxed constants.
%
:- pred goal_may_allocate_heap(hlds_goal::in) is semidet.
-:- pred goal_list_may_allocate_heap(list(hlds_goal)::in) is semidet.
+:- pred goal_list_may_allocate_heap(hlds_goals::in) is semidet.
% Succeed if execution of the given goal cannot encounter a context
% that causes any variable to be flushed to its stack slot. If such a
@@ -129,15 +155,132 @@
:- import_module hlds.hlds_data.
:- import_module libs.compiler_util.
:- import_module parse_tree.prog_data.
+:- import_module transform_hlds.exception_analysis.
:- import_module transform_hlds.term_constr_main.
:- import_module transform_hlds.term_util.
-:- import_module bool.
:- import_module int.
+:- import_module list.
:- import_module map.
:- import_module std_util.
%-----------------------------------------------------------------------------%
+%
+% A version of goal_cannot_loop_or_throw that uses results from the
+% intermodule-analysis framework
+%
+
+goal_cannot_throw(GoalExpr - GoalInfo, Result, !ModuleInfo, !IO) :-
+ goal_info_get_determinism(GoalInfo, Determinism),
+ ( Determinism \= erroneous ->
+ goal_cannot_throw_2(GoalExpr, GoalInfo, Result, !ModuleInfo, !IO)
+ ;
+ Result = no
+ ).
+
+:- pred goal_cannot_throw_2(hlds_goal_expr::in, hlds_goal_info::in,
+ bool::out, module_info::in, module_info::out, io::di, io::uo) is det.
+
+goal_cannot_throw_2(Goal, _GoalInfo, Result, !ModuleInfo, !IO) :-
+ (
+ Goal = conj(Goals)
+ ;
+ Goal = disj(Goals)
+ ;
+ Goal = par_conj(Goals)
+ ;
+ Goal = if_then_else(_, IfGoal, ThenGoal, ElseGoal),
+ Goals = [IfGoal, ThenGoal, ElseGoal]
+ ),
+ goals_cannot_throw(Goals, Result, !ModuleInfo, !IO).
+goal_cannot_throw_2(Goal, _GoalInfo, Result, !ModuleInfo, !IO) :-
+ Goal = call(PredId, ProcId, _, _, _, _),
+ lookup_exception_analysis_result(proc(PredId, ProcId),
+ Status, !ModuleInfo, !IO),
+ ( Status = will_not_throw ->
+ Result = yes
+ ;
+ Result = no
+ ).
+goal_cannot_throw_2(Goal, _GoalInfo, Result, !ModuleInfo, !IO) :-
+ % XXX We should use results form closure analysis here.
+ Goal = generic_call(_, _, _, _),
+ Result = no.
+goal_cannot_throw_2(Goal, _GoalInfo, Result, !ModuleInfo, !IO) :-
+ Goal = switch(_, _, Cases),
+ cases_cannot_throw(Cases, Result, !ModuleInfo, !IO).
+goal_cannot_throw_2(Goal, _GoalInfo, Result, !ModuleInfo, !IO) :-
+ Goal = unify(_, _, _, Uni, _),
+ % Complicated unifies are _non_builtin_
+ ( Uni = complicated_unify(_, _, _) ->
+ Result = no
+ ;
+ Result = yes
+ ).
+goal_cannot_throw_2(OuterGoal, _, Result, !ModuleInfo, !IO) :-
+ (
+ OuterGoal = not(InnerGoal)
+ ;
+ OuterGoal = scope(_, InnerGoal)
+ ),
+ goal_cannot_throw(InnerGoal, Result, !ModuleInfo, !IO).
+goal_cannot_throw_2(Goal, _, Result, !ModuleInfo, !IO) :-
+ Goal = foreign_proc(Attributes, _, _, _, _, _),
+ ExceptionStatus = may_throw_exception(Attributes),
+ (
+ (
+ ExceptionStatus = will_not_throw_exception
+ ;
+ ExceptionStatus = default_exception_behaviour,
+ may_call_mercury(Attributes) = will_not_call_mercury
+ )
+ ->
+ Result = yes
+ ;
+ Result = no
+ ).
+goal_cannot_throw_2(Goal, _, yes, !ModuleInfo, !IO) :-
+ Goal = shorthand(_). % XXX maybe call unexpected/2 here.
+
+:- pred goals_cannot_throw(hlds_goals::in, bool::out,
+ module_info::in, module_info::out, io::di, io::uo) is det.
+
+goals_cannot_throw([], yes, !ModuleInfo, !IO).
+goals_cannot_throw([Goal | Goals], Result, !ModuleInfo, !IO) :-
+ goal_cannot_throw(Goal, Result0, !ModuleInfo, !IO),
+ (
+ Result0 = yes,
+ goals_cannot_throw(Goals, Result, !ModuleInfo, !IO)
+ ;
+ Result0 = no,
+ Result = no
+ ).
+
+:- pred cases_cannot_throw(list(case)::in, bool::out,
+ module_info::in, module_info::out, io::di, io::uo) is det.
+
+cases_cannot_throw([], yes, !ModuleInfo, !IO).
+cases_cannot_throw([Case | Cases], Result, !ModuleInfo, !IO) :-
+ Case = case(_, Goal),
+ goal_cannot_throw(Goal, Result0, !ModuleInfo, !IO),
+ (
+ Result0 = yes,
+ cases_cannot_throw(Cases, Result, !ModuleInfo, !IO)
+ ;
+ Result0 = no,
+ Result = no
+ ).
+
+goal_cannot_loop_or_throw(Goal, Result, !ModuleInfo, !IO) :-
+ % XXX this will need to change after the termination analyses are
+ % converted to use the intermodule-analysis framework.
+ ( goal_cannot_loop(!.ModuleInfo, Goal) ->
+ goal_cannot_throw(Goal, Result, !ModuleInfo, !IO)
+ ;
+ Result = no
+ ).
+
+%-----------------------------------------------------------------------------%
goal_cannot_loop(ModuleInfo, Goal) :-
goal_cannot_loop_aux(yes(ModuleInfo), Goal).
Index: compiler/goal_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/goal_util.m,v
retrieving revision 1.121
diff -u -r1.121 goal_util.m
--- compiler/goal_util.m 25 Jan 2006 03:27:34 -0000 1.121
+++ compiler/goal_util.m 15 Feb 2006 13:27:36 -0000
@@ -14,7 +14,7 @@
%-----------------------------------------------------------------------------%
-:- module hlds__goal_util.
+:- module hlds.goal_util.
:- interface.
:- import_module hlds.hlds_goal.
@@ -26,6 +26,7 @@
:- import_module assoc_list.
:- import_module bool.
+:- import_module io.
:- import_module list.
:- import_module map.
:- import_module set.
@@ -52,10 +53,9 @@
% insts of NewVar are taken from the insts of the corresponding
% OutputVar in InstMapDelta (the initial inst is free).
%
-:- pred create_renaming(list(prog_var)::in, instmap_delta::in,
+:- pred create_renaming(prog_vars::in, instmap_delta::in,
vartypes::in, vartypes::out, prog_varset::in, prog_varset::out,
- list(hlds_goal)::out, list(prog_var)::out,
- prog_var_renaming::out) is det.
+ hlds_goals::out, prog_vars::out, prog_var_renaming::out) is det.
% The predicates rename_var* take a structure and a mapping from var -> var
% and apply that translation. If a var in the input structure does not
@@ -63,7 +63,7 @@
% rename_vars_in_goals(MustRename, Substitution, GoalList, NewGoalList).
:- pred rename_vars_in_goals(bool::in, prog_var_renaming::in,
- list(hlds_goal)::in, list(hlds_goal)::out) is det.
+ hlds_goals::in, hlds_goals::out) is det.
:- pred rename_vars_in_goal(prog_var_renaming::in,
hlds_goal::in, hlds_goal::out) is det.
@@ -99,9 +99,8 @@
% uniqueness in the type map for this reason - such is the sacrifice
% for generality.)
%
-:- pred create_variables(list(prog_var)::in, prog_varset::in,
- vartypes::in, prog_varset::in, prog_varset::out,
- vartypes::in, vartypes::out,
+:- pred create_variables(prog_vars::in, prog_varset::in, vartypes::in,
+ prog_varset::in, prog_varset::out, vartypes::in, vartypes::out,
prog_var_renaming::in, prog_var_renaming::out) is det.
% Return all the variables in the goal.
@@ -114,13 +113,12 @@
% Unlike quantification.goal_vars, this predicate returns
% even the explicitly quantified variables.
%
-:- pred goals_goal_vars(list(hlds_goal)::in, set(prog_var)::in,
+:- pred goals_goal_vars(hlds_goals::in, set(prog_var)::in,
set(prog_var)::out) is det.
% Return all the variables in a generic call.
%
-:- pred generic_call_vars(generic_call::in, list(prog_var)::out)
- is det.
+:- pred generic_call_vars(generic_call::in, prog_vars::out) is det.
% Attach the given goal features to the given goal and all its subgoals.
%
@@ -145,9 +143,8 @@
% i.e. a constraint which contrains an existentially quantified type
% variable.
%
-:- pred extra_nonlocal_typeinfos(rtti_varmaps::in,
- vartypes::in, existq_tvars::in,
- set(prog_var)::in, set(prog_var)::out) is det.
+:- pred extra_nonlocal_typeinfos(rtti_varmaps::in, vartypes::in,
+ existq_tvars::in, set(prog_var)::in, set(prog_var)::out) is det.
% See whether the goal is a branched structure.
%
@@ -159,7 +156,7 @@
% Return an indication of the size of the list of goals.
%
-:- pred goals_size(list(hlds_goal)::in, int::out) is det.
+:- pred goals_size(hlds_goals::in, int::out) is det.
% Return an indication of the size of the list of clauses.
%
@@ -201,7 +198,7 @@
% Returns all the predids that are used in a list of goals.
%
-:- pred predids_from_goals(list(hlds_goal)::in, list(pred_id)::out) is det.
+:- pred predids_from_goals(hlds_goals::in, list(pred_id)::out) is det.
% Returns all the procedures that are used within a goal.
%
@@ -214,9 +211,8 @@
% This aborts if any of the constructors are existentially typed.
%
:- pred switch_to_disjunction(prog_var::in, list(case)::in,
- instmap::in, list(hlds_goal)::out, prog_varset::in, prog_varset::out,
- vartypes::in, vartypes::out,
- module_info::in, module_info::out) is det.
+ instmap::in, hlds_goals::out, prog_varset::in, prog_varset::out,
+ vartypes::in, vartypes::out, module_info::in, module_info::out) is det.
% Convert a case into a conjunction by adding a tag test
% (deconstruction unification) to the case goal.
@@ -224,8 +220,7 @@
%
:- pred case_to_disjunct(prog_var::in, cons_id::in, hlds_goal::in,
instmap::in, hlds_goal::out, prog_varset::in, prog_varset::out,
- vartypes::in, vartypes::out,
- module_info::in, module_info::out) is det.
+ vartypes::in, vartypes::out, module_info::in, module_info::out) is det.
% Transform an if-then-else into ( Cond, Then ; \+ Cond, Else ),
% since magic.m and rl_gen.m don't handle if-then-elses.
@@ -235,28 +230,67 @@
%-----------------------------------------------------------------------------%
- % can_reorder_goals(ModuleInfo, FullyStrict, Goal1, Goal2).
+ % can_reorder_goals(ModuleInfo, VarTypes, FullyStrict,
+ % InstmapBeforeGoal1, Goal1, InstmapBeforegoal2, Goal2).
%
% Goals can be reordered if
% - the goals are independent
% - the goals are not impure
- % - any possible change in termination behaviour is allowed
- % according to the semantics options.
+ % - any possible change in termination behaviour is allowed according
+ % to the semantics options.
+ %
+ % NOTE: this version is deprecated; new code should use the following
+ % version because it supports the intermodule-analysis framework.
%
:- pred can_reorder_goals(module_info::in, vartypes::in, bool::in,
instmap::in, hlds_goal::in, instmap::in, hlds_goal::in) is semidet.
- % reordering_maintains_termination(ModuleInfo,
- % FullyStrict, Goal1, Goal2)
+ % can_reorder_goals(VarTypes, FullyStrict, InstmapBeforeGoal1, Goal1,
+ % InstmapBeforeGoal2, Goal2, Result, !ModuleInfo, !IO).
%
- % Succeeds if any possible change in termination behaviour from
- % reordering the goals is allowed according to the semantics options.
- % The information computed by termination analysis is used when
- % making this decision.
+ % Result is `yes' if the goals can be reordered; no otherwise.
+ %
+ % Goals can be reordered if
+ % - the goals are independent
+ % - the goals are not impure
+ % - any possible change in termination behaviour is allowed according
+ % to the semantics options.
+ %
+ % NOTE: new code should use this version as it supports the
+ % intermodule-analysis framework.
+ %
+:- pred can_reorder_goals(vartypes::in, bool::in, instmap::in,
+ hlds_goal::in, instmap::in, hlds_goal::in, bool::out,
+ module_info::in, module_info::out, io::di, io::uo) is det.
+
+ % reordering_maintains_termination(ModuleInfo, FullyStrict, Goal1, Goal2).
+ %
+ % Succeeds if any possible change in termination behaviour from reordering
+ % the goals is allowed according to the semantics options.
+ % The information computed by termination and exception analyses is used
+ % when making this decision.
+ %
+ % NOTE: this version is deprecated; new code should use the following
+ % version because it supports the intermodule-analysis framework.
%
:- pred reordering_maintains_termination(module_info::in, bool::in,
hlds_goal::in, hlds_goal::in) is semidet.
+ % reordering_maintains_termination(FullyStrict, Goal1, Goal2, Result,
+ % !ModuleInfo, !IO).
+ %
+ % Result is `yes' if any possible change in termination behaviour from
+ % reordering the goals is allowed according to the semantics options.
+ % The information computed by termination and exception analyses is used
+ % when making this decision.
+ %
+ % NOTE: new code should use this version as it supports the
+ % intermodule-analysis framework.
+ %
+:- pred reordering_maintains_termination(bool::in, hlds_goal::in,
+ hlds_goal::in, bool::out, module_info::in, module_info::out,
+ io::di, io::uo) is det.
+
% generate_simple_call(ModuleName, ProcName, PredOrFunc, ModeNo,
% Detism, Args, Features, InstMapDelta, ModuleInfo, Context,
% CallGoal):
@@ -272,7 +306,7 @@
% from 0.
%
:- pred generate_simple_call(module_name::in, string::in,
- pred_or_func::in, mode_no::in, determinism::in, list(prog_var)::in,
+ pred_or_func::in, mode_no::in, determinism::in, prog_vars::in,
list(goal_feature)::in, assoc_list(prog_var, mer_inst)::in,
module_info::in, term__context::in, hlds_goal::out) is det.
@@ -354,10 +388,9 @@
list__reverse(RevNewVars, NewVars),
list__reverse(RevUnifies, Unifies).
-:- pred create_renaming_2(list(prog_var)::in, instmap_delta::in,
+:- pred create_renaming_2(prog_vars::in, instmap_delta::in,
vartypes::in, vartypes::out, prog_varset::in, prog_varset::out,
- list(hlds_goal)::in, list(hlds_goal)::out,
- list(prog_var)::in, list(prog_var)::out,
+ hlds_goals::in, hlds_goals::out, prog_vars::in, prog_vars::out,
prog_var_renaming::in, prog_var_renaming::out) is det.
create_renaming_2([], _, !VarTypes, !VarSet, !RevUnifies, !RevNewVars,
@@ -1059,7 +1092,7 @@
goal_calls(GoalExpr - _, PredProcId) :-
goal_expr_calls(GoalExpr, PredProcId).
-:- pred goals_calls(list(hlds_goal), pred_proc_id).
+:- pred goals_calls(hlds_goals, pred_proc_id).
:- mode goals_calls(in, in) is semidet.
:- mode goals_calls(in, out) is nondet.
@@ -1119,7 +1152,7 @@
goal_calls_pred_id(GoalExpr - _, PredId) :-
goal_expr_calls_pred_id(GoalExpr, PredId).
-:- pred goals_calls_pred_id(list(hlds_goal), pred_id).
+:- pred goals_calls_pred_id(hlds_goals, pred_id).
:- mode goals_calls_pred_id(in, in) is semidet.
:- mode goals_calls_pred_id(in, out) is nondet.
@@ -1196,7 +1229,7 @@
Unify = construct(_, _, _, _, HowToConstruct, _, _),
HowToConstruct = reuse_cell(_).
-:- pred goals_contain_reconstruction(list(hlds_goal)::in) is semidet.
+:- pred goals_contain_reconstruction(hlds_goals::in) is semidet.
goals_contain_reconstruction(Goals) :-
list__member(Goal, Goals),
@@ -1408,6 +1441,51 @@
\+ goal_depends_on_earlier_goal(EarlierGoal, LaterGoal,
InstmapBeforeLaterGoal, VarTypes, ModuleInfo).
+can_reorder_goals(VarTypes, FullyStrict, InstmapBeforeEarlierGoal,
+ EarlierGoal, InstmapBeforeLaterGoal, LaterGoal, CanReorder,
+ !ModuleInfo, !IO) :-
+
+ EarlierGoal = _ - EarlierGoalInfo,
+ LaterGoal = _ - LaterGoalInfo,
+
+ % Impure goals cannot be reordered.
+ ( goal_info_is_impure(EarlierGoalInfo) ->
+ CanReorder = no
+ ; goal_info_is_impure(LaterGoalInfo) ->
+ CanReorder = no
+ ;
+ reordering_maintains_termination(FullyStrict,
+ EarlierGoal, LaterGoal, MaintainsTermination, !ModuleInfo, !IO),
+ (
+ MaintainsTermination = no,
+ CanReorder = no
+ ;
+ MaintainsTermination = yes,
+ (
+ % Don't reorder the goals if the later goal depends on the
+ % outputs of the current goal.
+ %
+ goal_depends_on_earlier_goal(LaterGoal, EarlierGoal,
+ InstmapBeforeEarlierGoal, VarTypes, !.ModuleInfo)
+ ->
+ CanReorder = no
+ ;
+ % Don't reorder the goals if the later goal changes the
+ % instantiatedness of any of the non-locals of the earlier
+ % goal. This is necessary if the later goal clobbers any of
+ % the non-locals of the earlier goal, and avoids rerunning
+ % full mode analysis in other cases.
+ %
+ goal_depends_on_earlier_goal(EarlierGoal, LaterGoal,
+ InstmapBeforeLaterGoal, VarTypes, !.ModuleInfo)
+ ->
+ CanReorder = no
+ ;
+ CanReorder = yes
+ )
+ )
+ ).
+
reordering_maintains_termination(ModuleInfo, FullyStrict,
EarlierGoal, LaterGoal) :-
EarlierGoal = _ - EarlierGoalInfo,
@@ -1437,7 +1515,43 @@
true
).
+reordering_maintains_termination(FullyStrict, EarlierGoal, LaterGoal,
+ MaintainsTermination, !ModuleInfo, !IO) :-
+ EarlierGoal = _ - EarlierGoalInfo,
+ LaterGoal = _ - LaterGoalInfo,
+
+ goal_info_get_determinism(EarlierGoalInfo, EarlierDetism),
+ determinism_components(EarlierDetism, EarlierCanFail, _),
+ goal_info_get_determinism(LaterGoalInfo, LaterDetism),
+ determinism_components(LaterDetism, LaterCanFail, _),
+ %
+ % If --fully-strict was specified, don't convert (can_loop, can_fail) into
+ % (can_fail, can_loop).
%
+ goal_cannot_loop_or_throw(EarlierGoal, EarlierCannotLoopOrThrow,
+ !ModuleInfo, !IO),
+ (
+ FullyStrict = yes,
+ EarlierCannotLoopOrThrow = no,
+ LaterCanFail = can_fail
+ ->
+ MaintainsTermination = no
+ ;
+ % Don't convert (can_fail, can_loop) into (can_loop, can_fail), since
+ % this could worsen the termination properties of the program.
+ %
+ goal_cannot_loop_or_throw(LaterGoal, LaterCannotLoopOrThrow,
+ !ModuleInfo, !IO),
+ (
+ EarlierCanFail = can_fail,
+ LaterCannotLoopOrThrow = no
+ ->
+ MaintainsTermination = no
+ ;
+ MaintainsTermination = yes
+ )
+ ).
+
% If the earlier goal changes the instantiatedness of a variable
% that is used in the later goal, then the later goal depends on
% the earlier goal.
Index: compiler/pd_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/pd_util.m,v
retrieving revision 1.45
diff -u -r1.45 pd_util.m
--- compiler/pd_util.m 28 Nov 2005 04:11:50 -0000 1.45
+++ compiler/pd_util.m 15 Feb 2006 13:47:07 -0000
@@ -31,6 +31,8 @@
:- import_module set.
:- import_module std_util.
+%-----------------------------------------------------------------------------%
+
% Pick out the pred_proc_ids of the calls in a list of atomic goals.
%
:- pred goal_get_calls(hlds_goal::in, list(pred_proc_id)::out) is det.
@@ -44,7 +46,7 @@
% Apply simplify.m to the goal.
%
:- pred simplify_goal(list(simplification)::in, hlds_goal::in,
- hlds_goal::out, pd_info::in, pd_info::out) is det.
+ hlds_goal::out, pd_info::in, pd_info::out, io::di, io::uo) is det.
% Apply unique_modes.m to the goal.
%
@@ -86,7 +88,7 @@
% information about the argument variables.
%
:- pred convert_branch_info(pd_branch_info(int)::in,
- list(prog_var)::in, pd_branch_info(prog_var)::out) is det.
+ prog_vars::in, pd_branch_info(prog_var)::out) is det.
% inst_MSG(InstA, InstB, InstC):
%
@@ -130,7 +132,7 @@
% which contain only conj, some, not and atomic goals, since deforest.m
% only attempts to optimize those types of conjunctions.
%
-:- pred goals_match(module_info::in, hlds_goal::in, list(prog_var)::in,
+:- pred goals_match(module_info::in, hlds_goal::in, prog_vars::in,
list(mer_type)::in, hlds_goal::in, vartypes::in,
map(prog_var, prog_var)::out, tsubst::out) is semidet.
@@ -142,10 +144,15 @@
% - any possible change in termination behaviour is allowed
% according to the semantics options.
%
+ % XXX use the intermodule-analysis framework here (and see if this
+ % version can be merged with the similarly named predicate in
+ % goal_util.m).
+ %
:- pred can_reorder_goals(module_info::in, bool::in,
hlds_goal::in, hlds_goal::in) is semidet.
%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
:- implementation.
@@ -205,7 +212,7 @@
constraint_info_init(ModuleInfo0, VarTypes0, VarSet0, InstMap, CInfo0),
Goal0 = _ - GoalInfo0,
goal_info_get_nonlocals(GoalInfo0, NonLocals),
- constraint__propagate_constraints_in_goal(!Goal, CInfo0, CInfo),
+ constraint__propagate_constraints_in_goal(!Goal, CInfo0, CInfo, !IO),
constraint_info_deconstruct(CInfo, ModuleInfo, VarTypes, VarSet,
Changed),
pd_info_set_module_info(ModuleInfo, !PDInfo),
@@ -221,10 +228,10 @@
rerun_det_analysis(!Goal, !PDInfo, !IO),
module_info_get_globals(ModuleInfo, Globals),
simplify__find_simplifications(no, Globals, Simplifications),
- simplify_goal(Simplifications, !Goal, !PDInfo)
+ simplify_goal(Simplifications, !Goal, !PDInfo, !IO)
;
% Use Goal0 rather than the output of propagate_constraints_in_goal
- % because constraint propagation can make the % quantification
+ % because constraint propagation can make the quantification
% information more conservative even if it doesn't optimize
% anything.
Changed = no,
@@ -236,7 +243,7 @@
%-----------------------------------------------------------------------------%
-simplify_goal(Simplifications, Goal0, Goal, !PDInfo) :-
+simplify_goal(Simplifications, Goal0, Goal, !PDInfo, !IO) :-
% Construct a simplify_info.
pd_info_get_module_info(!.PDInfo, ModuleInfo0),
module_info_get_globals(ModuleInfo0, Globals),
@@ -248,7 +255,7 @@
simplify_info_init(DetInfo0, Simplifications, InstMap0, ProcInfo0,
SimplifyInfo0),
- simplify__process_goal(Goal0, Goal, SimplifyInfo0, SimplifyInfo),
+ simplify__process_goal(Goal0, Goal, SimplifyInfo0, SimplifyInfo, !IO),
% Deconstruct the simplify_info.
simplify_info_get_module_info(SimplifyInfo, ModuleInfo),
@@ -328,7 +335,7 @@
get_goal_live_vars_2(ModuleInfo, NonLocalsList, InstMap, InstMapDelta,
!Vars).
-:- pred get_goal_live_vars_2(module_info::in, list(prog_var)::in,
+:- pred get_goal_live_vars_2(module_info::in, prog_vars::in,
instmap::in, instmap_delta::in,
set(prog_var)::in, set(prog_var)::out) is det.
@@ -401,7 +408,7 @@
VarInfo = pd_branch_info(BranchVarMap, LeftVars, OpaqueVars).
:- pred convert_branch_info_2(assoc_list(int, set(int))::in,
- list(prog_var)::in, pd_var_info::in, pd_var_info::out) is det.
+ prog_vars::in, pd_var_info::in, pd_var_info::out) is det.
convert_branch_info_2([], _, !VarInfo).
convert_branch_info_2([ArgNo - Branches | ArgInfos], Args,
@@ -481,7 +488,7 @@
% in the branches, compute the argument numbers for which we have extra
% information.
%
-:- pred get_extra_info_headvars(list(prog_var)::in, int::in,
+:- pred get_extra_info_headvars(prog_vars::in, int::in,
set(prog_var)::in, pd_var_info::in,
branch_info_map(int)::in, branch_info_map(int)::out,
set(int)::in, set(int)::out) is det.
@@ -530,7 +537,7 @@
MaybeBranchInfo = no
).
-:- pred get_branch_vars_goal_2(module_info::in, list(hlds_goal)::in,
+:- pred get_branch_vars_goal_2(module_info::in, hlds_goals::in,
bool::in, vartypes::in, instmap::in,
set(prog_var)::in, set(prog_var)::out,
pd_var_info::in, pd_var_info::out) is semidet.
@@ -643,7 +650,7 @@
% Look at the goals in the branches for extra information.
%
:- pred get_sub_branch_vars_goal(pd_arg_info::in,
- list(hlds_goal)::in, vartypes::in, instmap::in,
+ hlds_goals::in, vartypes::in, instmap::in,
branch_info_map(prog_var)::in, branch_info_map(prog_var)::out,
module_info::in, module_info::out) is det.
@@ -676,7 +683,7 @@
VarTypes, InstMap, Vars2, SubVars, !ModuleInfo).
:- pred examine_branch_list(module_info::in, pd_arg_info::in, int::in,
- list(hlds_goal)::in, vartypes::in, instmap::in,
+ hlds_goals::in, vartypes::in, instmap::in,
branch_info_map(prog_var)::in, branch_info_map(prog_var)::out) is det.
examine_branch_list(_, _, _, [], _, _, !Vars).
@@ -708,7 +715,7 @@
VarTypes, InstMap, !Vars, !ModuleInfo).
:- pred examine_branch(module_info::in, pd_arg_info::in, int::in,
- list(hlds_goal)::in, vartypes::in, instmap::in,
+ hlds_goals::in, vartypes::in, instmap::in,
branch_info_map(prog_var)::in, branch_info_map(prog_var)::out) is det.
examine_branch(_, _, _, [], _, _, !Vars).
@@ -740,7 +747,7 @@
examine_branch(ModuleInfo, ProcArgInfo, BranchNo,
Goals, VarTypes, InstMap1, !Vars).
-:- pred combine_vars(int::in, list(prog_var)::in,
+:- pred combine_vars(int::in, prog_vars::in,
branch_info_map(prog_var)::in, branch_info_map(prog_var)::out) is det.
combine_vars(_, [], !Vars).
@@ -966,7 +973,7 @@
map__apply_to_list(NewArgs, NewVarTypes, NewArgTypes),
type_list_subsumes(MatchingArgTypes, NewArgTypes, TypeSubn).
-:- pred collect_matching_arg_types(list(prog_var)::in, list(mer_type)::in,
+:- pred collect_matching_arg_types(prog_vars::in, list(mer_type)::in,
map(prog_var, prog_var)::in, list(mer_type)::in, list(mer_type)::out)
is det.
@@ -989,7 +996,7 @@
% Check that the shape of the goals matches, and that there is a mapping
% from the variables in the old goal to the variables in the new goal.
%
-:- pred goals_match_2(list(hlds_goal)::in, list(hlds_goal)::in,
+:- pred goals_match_2(hlds_goals::in, hlds_goals::in,
map(prog_var, prog_var)::in, map(prog_var, prog_var)::out) is semidet.
goals_match_2([], [], !ONRenaming).
Index: compiler/simplify.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/simplify.m,v
retrieving revision 1.162
diff -u -r1.162 simplify.m
--- compiler/simplify.m 27 Jan 2006 05:52:05 -0000 1.162
+++ compiler/simplify.m 15 Feb 2006 13:42:42 -0000
@@ -56,10 +56,11 @@
:- pred simplify_proc_return_msgs(list(simplification)::in, pred_id::in,
proc_id::in, module_info::in, module_info::out,
- proc_info::in, proc_info::out, set(context_det_msg)::out) is det.
+ proc_info::in, proc_info::out, set(context_det_msg)::out,
+ io::di, io::uo) is det.
:- pred process_goal(hlds_goal::in, hlds_goal::out,
- simplify_info::in, simplify_info::out) is det.
+ simplify_info::in, simplify_info::out, io::di, io::uo) is det.
% Find out which simplifications should be run from the options table
% stored in the globals. The first argument states whether warnings
@@ -144,7 +145,7 @@
),
MaybeMsgs0 = no,
simplify_procs(Simplifications, PredId, ProcIds, !ModuleInfo, !PredInfo,
- MaybeMsgs0, MaybeMsgs),
+ MaybeMsgs0, MaybeMsgs, !IO),
(
MaybeMsgs = yes(Msgs0 - Msgs1),
set__union(Msgs0, Msgs1, Msgs2),
@@ -162,15 +163,16 @@
list(proc_id)::in, module_info::in, module_info::out,
pred_info::in, pred_info::out,
maybe(pair(set(context_det_msg)))::in,
- maybe(pair(set(context_det_msg)))::out) is det.
+ maybe(pair(set(context_det_msg)))::out,
+ io::di, io::uo) is det.
-simplify_procs(_, _, [], !ModuleInfo, !PredInfo, !Msgs).
+simplify_procs(_, _, [], !ModuleInfo, !PredInfo, !Msgs, !IO).
simplify_procs(Simplifications, PredId, [ProcId | ProcIds], !ModuleInfo,
- !PredInfo, !MaybeMsgs) :-
+ !PredInfo, !MaybeMsgs, !IO) :-
pred_info_procedures(!.PredInfo, Procs0),
map__lookup(Procs0, ProcId, Proc0),
simplify_proc_return_msgs(Simplifications, PredId, ProcId,
- !ModuleInfo, Proc0, Proc, ProcMsgSet),
+ !ModuleInfo, Proc0, Proc, ProcMsgSet, !IO),
map__det_update(Procs0, ProcId, Proc, Procs),
pred_info_set_procedures(Procs, !PredInfo),
set__to_sorted_list(ProcMsgSet, ProcMsgs),
@@ -189,15 +191,15 @@
!:MaybeMsgs = yes(ProcAnyModeMsgSet - ProcAllModeMsgSet)
),
simplify_procs(Simplifications, PredId, ProcIds, !ModuleInfo, !PredInfo,
- !MaybeMsgs).
+ !MaybeMsgs, !IO).
simplify_proc(Simplifications, PredId, ProcId, !ModuleInfo, !Proc, !IO) :-
write_pred_progress_message("% Simplifying ", PredId, !.ModuleInfo, !IO),
simplify_proc_return_msgs(Simplifications, PredId, ProcId, !ModuleInfo,
- !Proc, _).
+ !Proc, _, !IO).
simplify_proc_return_msgs(Simplifications, PredId, ProcId, !ModuleInfo,
- !ProcInfo, DetMsgs) :-
+ !ProcInfo, DetMsgs, !IO) :-
module_info_get_globals(!.ModuleInfo, Globals),
proc_info_vartypes(!.ProcInfo, VarTypes0),
det_info_init(!.ModuleInfo, VarTypes0, PredId, ProcId, Globals,
@@ -221,7 +223,7 @@
Goal1 = Goal0
),
- process_goal(Goal1, Goal, Info0, Info),
+ process_goal(Goal1, Goal, Info0, Info, !IO),
simplify_info_get_varset(Info, VarSet),
simplify_info_get_var_types(Info, VarTypes),
@@ -264,7 +266,7 @@
DetMsgs = DetMsgs1
).
-process_goal(Goal0, Goal, !Info) :-
+process_goal(Goal0, Goal, !Info, !IO) :-
simplify_info_get_simplifications(!.Info, Simplifications0),
simplify_info_get_instmap(!.Info, InstMap0),
@@ -279,7 +281,7 @@
set__delete_list(Simplifications0, NotOnFirstPass, Simplifications1),
simplify_info_set_simplifications(Simplifications1, !Info),
- do_process_goal(Goal0, Goal1, !Info),
+ do_process_goal(Goal0, Goal1, !Info, !IO),
NotOnSecondPass = [warn_simple_code, warn_duplicate_calls,
common_struct, duplicate_calls],
@@ -290,14 +292,14 @@
),
% On the second pass do excess assignment elimination and some cleaning up
% after the common structure pass.
- do_process_goal(Goal1, Goal, !Info).
+ do_process_goal(Goal1, Goal, !Info, !IO).
:- pred do_process_goal(hlds_goal::in, hlds_goal::out,
- simplify_info::in, simplify_info::out) is det.
+ simplify_info::in, simplify_info::out, io::di, io::uo) is det.
-do_process_goal(Goal0, Goal, !Info) :-
+do_process_goal(Goal0, Goal, !Info, !IO) :-
simplify_info_get_instmap(!.Info, InstMap0),
- simplify_goal(Goal0, Goal1, !Info),
+ simplify_goal(Goal0, Goal1, !Info, !IO),
simplify_info_get_varset(!.Info, VarSet0),
simplify_info_get_var_types(!.Info, VarTypes0),
( simplify_info_requantify(!.Info) ->
@@ -393,12 +395,16 @@
%-----------------------------------------------------------------------------%
:- pred simplify_goal(hlds_goal::in, hlds_goal::out,
- simplify_info::in, simplify_info::out) is det.
+ simplify_info::in, simplify_info::out, io::di, io::uo) is det.
-simplify_goal(Goal0, Goal - GoalInfo, !Info) :-
+simplify_goal(Goal0, Goal - GoalInfo, !Info, !IO) :-
Goal0 = _ - GoalInfo0,
goal_info_get_determinism(GoalInfo0, Detism),
simplify_info_get_det_info(!.Info, DetInfo),
+ simplify_info_get_module_info(!.Info, ModuleInfo0),
+ goal_cannot_loop_or_throw(Goal0, Goal0CannotLoopOrThrow, ModuleInfo0,
+ ModuleInfo, !IO),
+ simplify_info_set_module_info(ModuleInfo, !Info),
(
%
% if --no-fully-strict,
@@ -408,7 +414,7 @@
% ensure goal is pure or semipure
\+ goal_info_is_impure(GoalInfo0),
( det_info_get_fully_strict(DetInfo, no)
- ; goal_cannot_loop_or_throw(Goal0)
+ ; Goal0CannotLoopOrThrow = yes
)
->
% warn about this, unless the goal was an explicit
@@ -456,7 +462,7 @@
% ensure goal is pure or semipure
\+ goal_info_is_impure(GoalInfo0),
( det_info_get_fully_strict(DetInfo, no)
- ; goal_cannot_loop_or_throw(Goal0)
+ ; Goal0CannotLoopOrThrow = yes
)
->
% The following warning is disabled, because it often results in spurious
@@ -521,7 +527,7 @@
),
simplify_info_maybe_clear_structs(before, Goal2, !Info),
Goal2 = GoalExpr2 - GoalInfo2,
- simplify_goal_2(GoalExpr2, Goal, GoalInfo2, GoalInfo3, !Info),
+ simplify_goal_2(GoalExpr2, Goal, GoalInfo2, GoalInfo3, !Info, !IO),
simplify_info_maybe_clear_structs(after, Goal - GoalInfo3, !Info),
enforce_invariant(GoalInfo3, GoalInfo, !Info).
@@ -558,12 +564,12 @@
:- pred simplify_goal_2(hlds_goal_expr::in, hlds_goal_expr::out,
hlds_goal_info::in, hlds_goal_info::out,
- simplify_info::in, simplify_info::out) is det.
+ simplify_info::in, simplify_info::out, io::di, io::uo) is det.
-simplify_goal_2(conj(Goals0), Goal, GoalInfo0, GoalInfo, !Info) :-
+simplify_goal_2(conj(Goals0), Goal, GoalInfo0, GoalInfo, !Info, !IO) :-
simplify_info_get_instmap(!.Info, InstMap0),
excess_assigns_in_conj(GoalInfo0, Goals0, Goals1, !Info),
- simplify_conj(Goals1, [], Goals, GoalInfo0, !Info),
+ simplify_conj(Goals1, [], Goals, GoalInfo0, !Info, !IO),
simplify_info_set_instmap(InstMap0, !Info),
(
Goals = [],
@@ -597,26 +603,27 @@
GoalInfo = GoalInfo0
).
-simplify_goal_2(par_conj(Goals0), Goal, GoalInfo0, GoalInfo, !Info) :-
+simplify_goal_2(par_conj(Goals0), Goal, GoalInfo0, GoalInfo, !Info, !IO) :-
(
Goals0 = [],
goal_info_get_context(GoalInfo0, Context),
true_goal(Context, Goal - GoalInfo)
;
Goals0 = [SingleGoal0],
- simplify_goal(SingleGoal0, SingleGoal - SingleGoalInfo, !Info),
+ simplify_goal(SingleGoal0, SingleGoal - SingleGoalInfo, !Info, !IO),
maybe_wrap_goal(GoalInfo0, SingleGoalInfo, SingleGoal, Goal, GoalInfo,
!Info)
;
Goals0 = [_, _ | _],
GoalInfo = GoalInfo0,
- simplify_par_conj(Goals0, Goals, !.Info, !Info),
+ simplify_par_conj(Goals0, Goals, !.Info, !Info, !IO),
Goal = par_conj(Goals)
).
-simplify_goal_2(disj(Disjuncts0), Goal, GoalInfo0, GoalInfo, !Info) :-
+simplify_goal_2(disj(Disjuncts0), Goal, GoalInfo0, GoalInfo, !Info, !IO) :-
simplify_info_get_instmap(!.Info, InstMap0),
- simplify_disj(Disjuncts0, [], Disjuncts, [], InstMaps, !.Info, !Info),
+ simplify_disj(Disjuncts0, [], Disjuncts, [], InstMaps, !.Info, !Info,
+ !IO),
(
Disjuncts = [],
goal_info_get_context(GoalInfo0, Context),
@@ -662,7 +669,7 @@
).
simplify_goal_2(switch(Var, SwitchCanFail0, Cases0), Goal,
- GoalInfo0, GoalInfo, !Info) :-
+ GoalInfo0, GoalInfo, !Info, !IO) :-
simplify_info_get_instmap(!.Info, InstMap0),
simplify_info_get_module_info(!.Info, ModuleInfo0),
instmap__lookup_var(InstMap0, Var, VarInst),
@@ -676,7 +683,7 @@
MaybeConsIds = no
),
simplify_switch(Var, Cases1, [], Cases, [], InstMaps,
- SwitchCanFail0, SwitchCanFail, !.Info, !Info),
+ SwitchCanFail0, SwitchCanFail, !.Info, !Info, !IO),
(
Cases = [],
% An empty switch always fails.
@@ -780,7 +787,7 @@
true
).
-simplify_goal_2(Goal0, Goal, GoalInfo, GoalInfo, !Info) :-
+simplify_goal_2(Goal0, Goal, GoalInfo, GoalInfo, !Info, !IO) :-
Goal0 = generic_call(GenericCall, Args, Modes, Det),
(
simplify_do_calls(!.Info),
@@ -807,7 +814,7 @@
Goal = Goal0
).
-simplify_goal_2(Goal0, Goal, GoalInfo0, GoalInfo, !Info) :-
+simplify_goal_2(Goal0, Goal, GoalInfo0, GoalInfo, !Info, !IO) :-
Goal0 = call(PredId, ProcId, Args, IsBuiltin, _, _),
simplify_info_get_module_info(!.Info, ModuleInfo),
module_info_pred_info(ModuleInfo, PredId, PredInfo),
@@ -838,7 +845,7 @@
GoalInfo0, GoalInfo, !Info)
).
-simplify_goal_2(Goal0, Goal, GoalInfo0, GoalInfo, !Info) :-
+simplify_goal_2(Goal0, Goal, GoalInfo0, GoalInfo, !Info, !IO) :-
Goal0 = unify(LT0, RT0, M, U0, C),
(
% A unification of the form X = X can be safely
@@ -866,7 +873,7 @@
simplify_info_set_common_info(common_info_init, !Info),
% Don't attempt to pass structs out of lambda_goals.
- simplify_goal(LambdaGoal0, LambdaGoal, !Info),
+ simplify_goal(LambdaGoal0, LambdaGoal, !Info, !IO),
simplify_info_set_common_info(Common1, !Info),
simplify_info_set_instmap(InstMap1, !Info),
RT = lambda_goal(Purity, PredOrFunc, EvalMethod, FixModes,
@@ -879,7 +886,7 @@
->
( RT0 = var(V) ->
process_compl_unify(LT0, V, UniMode, CanFail, TypeInfoVars, C,
- GoalInfo0, Goal1, !Info),
+ GoalInfo0, Goal1, !Info, !IO),
Goal1 = Goal - GoalInfo
;
unexpected(this_file, "invalid RHS for complicated unify")
@@ -909,7 +916,7 @@
).
simplify_goal_2(if_then_else(Vars, Cond0, Then0, Else0), Goal,
- GoalInfo0, GoalInfo, !Info) :-
+ GoalInfo0, GoalInfo, !Info, !IO) :-
% (A -> B ; C) is logically equivalent to (A, B ; ~A, C).
% If the determinism of A means that one of these disjuncts
% cannot succeed, then we replace the if-then-else with the
@@ -942,7 +949,7 @@
goal_to_conj_list(Cond0, CondList),
goal_to_conj_list(Then0, ThenList),
list__append(CondList, ThenList, List),
- simplify_goal(conj(List) - GoalInfo0, Goal - GoalInfo, !Info),
+ simplify_goal(conj(List) - GoalInfo0, Goal - GoalInfo, !Info, !IO),
goal_info_get_context(GoalInfo0, Context),
Msg = ite_cond_cannot_fail,
ContextMsg = context_det_msg(Context, Msg),
@@ -985,7 +992,7 @@
),
goal_to_conj_list(Else0, ElseList),
List = [Cond | ElseList],
- simplify_goal(conj(List) - GoalInfo0, Goal - GoalInfo, !Info),
+ simplify_goal(conj(List) - GoalInfo0, Goal - GoalInfo, !Info, !IO),
goal_info_get_context(GoalInfo0, Context),
Msg = ite_cond_cannot_succeed,
ContextMsg = context_det_msg(Context, Msg),
@@ -997,7 +1004,7 @@
goal_to_conj_list(Cond0, CondList),
goal_to_conj_list(Then0, ThenList),
list__append(CondList, ThenList, List),
- simplify_goal(conj(List) - GoalInfo0, Goal - GoalInfo, !Info),
+ simplify_goal(conj(List) - GoalInfo0, Goal - GoalInfo, !Info, !IO),
simplify_info_set_requantify(!Info),
simplify_info_set_rerun_det(!Info)
;
@@ -1007,11 +1014,11 @@
%
Info0 = !.Info,
simplify_info_get_instmap(!.Info, InstMap0),
- simplify_goal(Cond0, Cond, !Info),
+ simplify_goal(Cond0, Cond, !Info, !IO),
simplify_info_update_instmap(Cond, !Info),
- simplify_goal(Then0, Then, !Info),
+ simplify_goal(Then0, Then, !Info, !IO),
simplify_info_post_branch_update(Info0, !Info),
- simplify_goal(Else0, Else, !Info),
+ simplify_goal(Else0, Else, !Info, !IO),
simplify_info_post_branch_update(Info0, !Info),
Cond = _ - CondInfo,
goal_info_get_instmap_delta(CondInfo, CondDelta),
@@ -1048,7 +1055,8 @@
)
->
simplify_info_undo_goal_updates(Info0, !Info),
- simplify_goal_2(IfThenElse, Goal, GoalInfo1, GoalInfo, !Info)
+ simplify_goal_2(IfThenElse, Goal, GoalInfo1, GoalInfo, !Info,
+ !IO)
;
(
% If-then-elses that are det or semidet may nevertheless
@@ -1073,11 +1081,11 @@
)
).
-simplify_goal_2(not(Goal0), Goal, GoalInfo0, GoalInfo, !Info) :-
+simplify_goal_2(not(Goal0), Goal, GoalInfo0, GoalInfo, !Info, !IO) :-
% Can't use calls or unifications seen within a negation,
% since non-local variables may not be bound within the negation.
simplify_info_get_common_info(!.Info, Common),
- simplify_goal(Goal0, Goal1, !Info),
+ simplify_goal(Goal0, Goal1, !Info, !IO),
simplify_info_set_common_info(Common, !Info),
Goal1 = _ - GoalInfo1,
goal_info_get_determinism(GoalInfo1, Detism),
@@ -1120,9 +1128,9 @@
).
simplify_goal_2(scope(Reason0, Goal1), GoalExpr, SomeInfo, GoalInfo,
- !Info) :-
+ !Info, !IO) :-
simplify_info_get_common_info(!.Info, Common),
- simplify_goal(Goal1, Goal2, !Info),
+ simplify_goal(Goal1, Goal2, !Info, !IO),
nested_scopes(Reason0, Goal2, SomeInfo, Goal),
Goal = GoalExpr - GoalInfo,
( Goal = scope(FinalReason, _) - _ ->
@@ -1168,7 +1176,7 @@
true
).
-simplify_goal_2(Goal0, Goal, GoalInfo, GoalInfo, !Info) :-
+simplify_goal_2(Goal0, Goal, GoalInfo, GoalInfo, !Info, !IO) :-
Goal0 = foreign_proc(_, PredId, ProcId, Args, ExtraArgs, _),
(
simplify_do_calls(!.Info),
@@ -1182,7 +1190,7 @@
Goal = Goal0
).
-simplify_goal_2(shorthand(_), _, _, _, !Info) :-
+simplify_goal_2(shorthand(_), _, _, _, _, _, _, _) :-
% These should have been expanded out by now.
unexpected(this_file, "goal_2: unexpected shorthand").
@@ -1404,10 +1412,11 @@
:- pred process_compl_unify(prog_var::in, prog_var::in, uni_mode::in,
can_fail::in, list(prog_var)::in, unify_context::in, hlds_goal_info::in,
- hlds_goal::out, simplify_info::in, simplify_info::out) is det.
+ hlds_goal::out, simplify_info::in, simplify_info::out,
+ io::di, io::uo) is det.
process_compl_unify(XVar, YVar, UniMode, CanFail, _OldTypeInfoVars, Context,
- GoalInfo0, Goal, !Info) :-
+ GoalInfo0, Goal, !Info, !IO) :-
simplify_info_get_module_info(!.Info, ModuleInfo),
simplify_info_get_var_types(!.Info, VarTypes),
map__lookup(VarTypes, XVar, Type),
@@ -1430,7 +1439,7 @@
generate_simple_call(mercury_private_builtin_module,
"builtin_unify_pred", predicate, mode_no(0), semidet,
[XVar, YVar], [], [], ModuleInfo, GContext, Call0 - _),
- simplify_goal_2(Call0, Call1, GoalInfo0, GoalInfo, !Info),
+ simplify_goal_2(Call0, Call1, GoalInfo0, GoalInfo, !Info, !IO),
Call = Call1 - GoalInfo,
ExtraGoals = []
;
@@ -1476,7 +1485,8 @@
make_type_info_vars(TypeArgs, TypeInfoVars, ExtraGoals, !Info),
call_specific_unify(TypeCtor, TypeInfoVars, XVar, YVar, ProcId,
ModuleInfo, Context, GoalInfo0, Call0, CallGoalInfo0),
- simplify_goal_2(Call0, Call1, CallGoalInfo0, CallGoalInfo1, !Info),
+ simplify_goal_2(Call0, Call1, CallGoalInfo0, CallGoalInfo1, !Info,
+ !IO),
Call = Call1 - CallGoalInfo1
)
),
@@ -1736,25 +1746,25 @@
:- pred simplify_conj(list(hlds_goal)::in, list(hlds_goal)::in,
list(hlds_goal)::out, hlds_goal_info::in,
- simplify_info::in, simplify_info::out) is det.
+ simplify_info::in, simplify_info::out, io::di, io::uo) is det.
-simplify_conj([], RevGoals, Goals, _, !Info) :-
+simplify_conj([], RevGoals, Goals, _, !Info, !IO) :-
list__reverse(RevGoals, Goals).
-simplify_conj([Goal0 | Goals0], !.RevGoals, Goals, ConjInfo, !Info) :-
+simplify_conj([Goal0 | Goals0], !.RevGoals, Goals, ConjInfo, !Info, !IO) :-
Info0 = !.Info,
% Flatten conjunctions.
( Goal0 = conj(SubGoals) - _ ->
list__append(SubGoals, Goals0, Goals1),
- simplify_conj(Goals1, !.RevGoals, Goals, ConjInfo, !Info)
+ simplify_conj(Goals1, !.RevGoals, Goals, ConjInfo, !Info, !IO)
;
- simplify_goal(Goal0, Goal1, !Info),
+ simplify_goal(Goal0, Goal1, !Info, !IO),
(
% Flatten conjunctions.
Goal1 = conj(SubGoals1) - _
->
simplify_info_undo_goal_updates(Info0, !Info),
list__append(SubGoals1, Goals0, Goals1),
- simplify_conj(Goals1, !.RevGoals, Goals, ConjInfo, !Info)
+ simplify_conj(Goals1, !.RevGoals, Goals, ConjInfo, !Info, !IO)
;
% Delete unreachable goals.
(
@@ -1791,7 +1801,7 @@
;
conjoin_goal_and_rev_goal_list(Goal1, !RevGoals),
simplify_info_update_instmap(Goal1, !Info),
- simplify_conj(Goals0, !.RevGoals, Goals, ConjInfo, !Info)
+ simplify_conj(Goals0, !.RevGoals, Goals, ConjInfo, !Info, !IO)
)
).
@@ -1809,13 +1819,14 @@
%-----------------------------------------------------------------------------%
:- pred simplify_par_conj(list(hlds_goal)::in, list(hlds_goal)::out,
- simplify_info::in, simplify_info::in, simplify_info::out) is det.
+ simplify_info::in, simplify_info::in, simplify_info::out,
+ io::di, io::uo) is det.
-simplify_par_conj([], [], _, !Info).
-simplify_par_conj([Goal0 |Goals0], [Goal | Goals], Info0, !Info) :-
- simplify_goal(Goal0, Goal, !Info),
+simplify_par_conj([], [], _, !Info, !IO).
+simplify_par_conj([Goal0 |Goals0], [Goal | Goals], Info0, !Info, !IO) :-
+ simplify_goal(Goal0, Goal, !Info, !IO),
simplify_info_post_branch_update(Info0, !Info),
- simplify_par_conj(Goals0, Goals, Info0, !Info).
+ simplify_par_conj(Goals0, Goals, Info0, !Info, !IO).
%-----------------------------------------------------------------------------%
@@ -1954,12 +1965,12 @@
:- pred simplify_switch(prog_var::in, list(case)::in, list(case)::in,
list(case)::out, list(instmap_delta)::in, list(instmap_delta)::out,
can_fail::in, can_fail::out, simplify_info::in,
- simplify_info::in, simplify_info::out) is det.
+ simplify_info::in, simplify_info::out, io::di, io::uo) is det.
-simplify_switch(_, [], RevCases, Cases, !InstMaps, !CanFail, _, !Info) :-
+simplify_switch(_, [], RevCases, Cases, !InstMaps, !CanFail, _, !Info, !IO) :-
list__reverse(RevCases, Cases).
simplify_switch(Var, [Case0 | Cases0], RevCases0, Cases, !InstMaps,
- !CanFail, Info0, !Info) :-
+ !CanFail, Info0, !Info, !IO) :-
simplify_info_get_instmap(Info0, InstMap0),
Case0 = case(ConsId, Goal0),
simplify_info_get_module_info(!.Info, ModuleInfo0),
@@ -1969,7 +1980,7 @@
ModuleInfo0, ModuleInfo1),
simplify_info_set_module_info(ModuleInfo1, !Info),
simplify_info_set_instmap(InstMap1, !Info),
- simplify_goal(Goal0, Goal, !Info),
+ simplify_goal(Goal0, Goal, !Info, !IO),
% Remove failing branches.
( Goal = disj([]) - _ ->
@@ -1998,7 +2009,7 @@
simplify_info_post_branch_update(Info0, !Info),
simplify_switch(Var, Cases0, RevCases, Cases, !InstMaps, !CanFail, Info0,
- !Info).
+ !Info, !IO).
% Create a semidet unification at the start of a singleton case
% in a can_fail switch.
@@ -2053,13 +2064,14 @@
:- pred simplify_disj(list(hlds_goal)::in, list(hlds_goal)::in,
list(hlds_goal)::out,
list(instmap_delta)::in, list(instmap_delta)::out,
- simplify_info::in, simplify_info::in, simplify_info::out) is det.
+ simplify_info::in, simplify_info::in, simplify_info::out,
+ io::di, io::uo) is det.
-simplify_disj([], RevGoals, Goals, !PostBranchInstMaps, _, !Info) :-
+simplify_disj([], RevGoals, Goals, !PostBranchInstMaps, _, !Info, !IO) :-
list__reverse(RevGoals, Goals).
simplify_disj([Goal0 | Goals0], RevGoals0, Goals, !PostBranchInstMaps,
- Info0, !Info) :-
- simplify_goal(Goal0, Goal, !Info),
+ Info0, !Info, !IO) :-
+ simplify_goal(Goal0, Goal, !Info, !IO),
Goal = _ - GoalInfo,
(
@@ -2108,7 +2120,8 @@
),
simplify_info_post_branch_update(Info0, !Info),
- simplify_disj(Goals0, RevGoals1, Goals, !PostBranchInstMaps, Info0, !Info).
+ simplify_disj(Goals0, RevGoals1, Goals, !PostBranchInstMaps, Info0, !Info,
+ !IO).
% Disjunctions that cannot succeed more than once when viewed from the
% outside generally need some fixing up, and/or some warnings to be issued.
@@ -2140,11 +2153,11 @@
%
:- pred fixup_disj(list(hlds_goal)::in, determinism::in, bool::in,
hlds_goal_info::in, hlds_goal_expr::out,
- simplify_info::in, simplify_info::out) is det.
+ simplify_info::in, simplify_info::out, io::di, io::uo) is det.
-fixup_disj(Disjuncts, _, _OutputVars, GoalInfo, Goal, !Info) :-
+fixup_disj(Disjuncts, _, _OutputVars, GoalInfo, Goal, !Info, !IO) :-
det_disj_to_ite(Disjuncts, GoalInfo, IfThenElse),
- simplify_goal(IfThenElse, Simplified, !Info),
+ simplify_goal(IfThenElse, Simplified, !Info, !IO),
Simplified = Goal - _.
% det_disj_to_ite is used to transform disjunctions that occur
Index: compiler/size_prof.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/size_prof.m,v
retrieving revision 1.30
diff -u -r1.30 size_prof.m
--- compiler/size_prof.m 28 Nov 2005 04:11:54 -0000 1.30
+++ compiler/size_prof.m 15 Feb 2006 08:06:12 -0000
@@ -221,22 +221,22 @@
hlds_out__write_pred_proc_id(!.ModuleInfo, PredId, ProcId, !IO),
io__write_string(": ", !IO),
process_proc(Transform, PredId, ProcId, ProcInfo0, ProcInfo,
- !ModuleInfo),
+ !ModuleInfo, !IO),
io__write_string("done.\n", !IO)
;
VeryVerbose = no,
process_proc(Transform, PredId, ProcId, ProcInfo0, ProcInfo,
- !ModuleInfo)
+ !ModuleInfo, !IO)
).
:- pred process_proc(construct_transform::in, pred_id::in, proc_id::in,
- proc_info::in, proc_info::out, module_info::in, module_info::out)
- is det.
+ proc_info::in, proc_info::out, module_info::in, module_info::out,
+ io::di, io::uo) is det.
-process_proc(Transform, PredId, ProcId, !ProcInfo, !ModuleInfo) :-
+process_proc(Transform, PredId, ProcId, !ProcInfo, !ModuleInfo, !IO) :-
Simplifications = [],
simplify_proc_return_msgs(Simplifications, PredId, ProcId,
- !ModuleInfo, !ProcInfo, _Msgs),
+ !ModuleInfo, !ProcInfo, _Msgs, !IO),
proc_info_goal(!.ProcInfo, Goal0),
proc_info_varset(!.ProcInfo, VarSet0),
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list