[m-rev.] diff: four-space switch_detection.m
Zoltan Somogyi
zs at cs.mu.OZ.AU
Fri Sep 2 10:34:41 AEST 2005
compiler/switch_detection.m:
Convert to four-space indentation.
Zoltan.
cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/switch_detection.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/switch_detection.m,v
retrieving revision 1.110
diff -u -b -r1.110 switch_detection.m
--- compiler/switch_detection.m 24 Mar 2005 05:34:15 -0000 1.110
+++ compiler/switch_detection.m 1 Sep 2005 13:56:37 -0000
@@ -1,4 +1,6 @@
%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
% Copyright (C) 1994-2005 The University of Melbourne.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
@@ -60,6 +62,7 @@
:- import_module hlds__hlds_goal.
:- import_module hlds__instmap.
:- import_module hlds__passes_aux.
+:- import_module parse_tree__error_util.
:- import_module parse_tree__prog_data.
:- import_module parse_tree__prog_mode.
@@ -74,10 +77,9 @@
%-----------------------------------------------------------------------------%
+detect_switches(!ModuleInfo, !IO) :-
% Traverse the module structure, calling `detect_switches_in_goal'
% for each procedure body.
-
-detect_switches(!ModuleInfo, !IO) :-
module_info_predids(!.ModuleInfo, PredIds),
detect_switches_in_preds(PredIds, !ModuleInfo, !IO).
@@ -119,9 +121,9 @@
pred_info_procedures(PredInfo0, ProcTable0),
map__lookup(ProcTable0, ProcId, ProcInfo0),
- % To process each ProcInfo, we get the goal,
- % initialize the instmap based on the modes of the head vars,
- % and pass these to `detect_switches_in_goal'.
+ % To process each ProcInfo, we get the goal, initialize the instmap
+ % based on the modes of the head vars, and pass these to
+ % `detect_switches_in_goal'.
proc_info_goal(ProcInfo0, Goal0),
proc_info_vartypes(ProcInfo0, VarTypes),
proc_info_get_initial_instmap(ProcInfo0, !.ModuleInfo, InstMap0),
@@ -137,7 +139,7 @@
% Given a goal, and the instmap on entry to that goal,
% replace disjunctions with switches whereever possible.
-
+ %
:- pred detect_switches_in_goal(module_info::in, vartypes::in,
instmap::in, hlds_goal::in, hlds_goal::out) is det.
@@ -145,11 +147,10 @@
detect_switches_in_goal_1(ModuleInfo, VarTypes, InstMap0, _InstMap,
!Goal).
- % This version is the same as the above except that it returns
- % the resulting instmap on exit from the goal, which is
- % computed by applying the instmap delta specified in the
- % goal's goalinfo.
-
+ % This version is the same as the above except that it returns the
+ % resulting instmap on exit from the goal, which is computed by applying
+ % the instmap delta specified in the goal's goalinfo.
+ %
:- pred detect_switches_in_goal_1(module_info::in, vartypes::in,
instmap::in, instmap::out, hlds_goal::in, hlds_goal::out) is det.
@@ -160,7 +161,7 @@
update_instmap(Goal0 - GoalInfo, !InstMap).
% Here we process each of the different sorts of goals.
-
+ %
:- pred detect_switches_in_goal_2(module_info::in, vartypes::in, instmap::in,
hlds_goal_info::in, hlds_goal_expr::in, hlds_goal_expr::out) is det.
@@ -174,8 +175,7 @@
goal_info_get_nonlocals(GoalInfo, NonLocals),
set__to_sorted_list(NonLocals, NonLocalsList),
detect_switches_in_disj(NonLocalsList, Goals0, GoalInfo,
- InstMap0, VarTypes, NonLocalsList, ModuleInfo,
- [], Goal)
+ InstMap0, VarTypes, NonLocalsList, ModuleInfo, [], Goal)
).
detect_switches_in_goal_2(ModuleInfo, VarTypes, InstMap0, _GoalInfo,
@@ -230,18 +230,11 @@
detect_switches_in_goal_2(_, _, _, _, Goal @ foreign_proc(_, _, _, _, _, _),
Goal).
detect_switches_in_goal_2(_, _, _, _, shorthand(_), _) :-
- % these should have been expanded out by now
- error("detect_switches_in_goal_2: unexpected shorthand").
+ % These should have been expanded out by now.
+ unexpected(this_file, "detect_switches_in_goal_2: unexpected shorthand").
%-----------------------------------------------------------------------------%
- % This is the interesting bit - we've found a non-empty
- % disjunction, and we've got a list of the non-local variables
- % of that disjunction. Now for each non-local variable, we
- % check whether there is a partition of the disjuncts such that
- % each group of disjunctions can only succeed if the variable
- % is bound to a different functor.
-
:- type cases == map(cons_id, list(hlds_goal)).
:- type sorted_case_list == list(case).
@@ -250,6 +243,12 @@
:- type again ---> again(prog_var, list(hlds_goal), sorted_case_list).
+ % This is the interesting bit - we've found a non-empty disjunction,
+ % and we've got a list of the non-local variables of that disjunction.
+ % Now for each non-local variable, we check whether there is a partition
+ % of the disjuncts such that each group of disjunctions can only succeed
+ % if the variable is bound to a different functor.
+ %
:- pred detect_switches_in_disj(list(prog_var)::in, list(hlds_goal)::in,
hlds_goal_info::in, instmap::in, vartypes::in,
list(prog_var)::in, module_info::in, list(again)::in,
@@ -257,28 +256,22 @@
detect_switches_in_disj([Var | Vars], Goals0, GoalInfo, InstMap,
VarTypes, AllVars, ModuleInfo, Again0, Goal) :-
- % can we do at least a partial switch on this variable?
+ % Can we do at least a partial switch on this variable?
(
instmap__lookup_var(InstMap, Var, VarInst0),
inst_is_bound(ModuleInfo, VarInst0),
partition_disj(Goals0, Var, GoalInfo, Left, CasesList)
->
- %
% A switch needs to have at least two cases.
%
- % But, if there is a complete one-case switch
- % for a goal, we must leave it as a disjunction
- % rather than doing an incomplete switch on a
- % different variable, because otherwise we might
- % get determinism analysis wrong. (The complete
- % one-case switch may be decomposable into other
- % complete sub-switches on the functor's arguments)
- %
+ % But, if there is a complete one-case switch for a goal, we must leave
+ % it as a disjunction rather than doing an incomplete switch on a
+ % different variable, because otherwise we might get determinism
+ % analysis wrong. (The complete one-case switch may be decomposable
+ % into other complete sub-switches on the functor's arguments)
(
- % are there any disjuncts that are not part of the
- % switch?
- Left = []
- ->
+ % Are there any disjuncts that are not part of the switch? No.
+ Left = [],
( CasesList = [_, _ | _] ->
cases_to_switch(CasesList, Var, VarTypes,
GoalInfo, InstMap, ModuleInfo, Goal)
@@ -288,18 +281,18 @@
Goal = disj(Goals)
)
;
- % insert this switch into the list of incomplete
- % switches only if it has at least two cases
- %
+ % Are there any disjuncts that are not part of the switch? Yes.
+ Left = [_ | _],
+ % Insert this switch into the list of incomplete switches
+ % only if it has at least two cases.
( CasesList = [_, _ | _] ->
Again1 = [again(Var, Left, CasesList) | Again0]
;
Again1 = Again0
),
- % try to find a switch
- detect_switches_in_disj(Vars, Goals0, GoalInfo,
- InstMap, VarTypes, AllVars, ModuleInfo,
- Again1, Goal)
+ % Try to find a switch.
+ detect_switches_in_disj(Vars, Goals0, GoalInfo, InstMap, VarTypes,
+ AllVars, ModuleInfo, Again1, Goal)
)
;
detect_switches_in_disj(Vars, Goals0, GoalInfo, InstMap,
@@ -383,19 +376,19 @@
%-----------------------------------------------------------------------------%
- % partition_disj(Goals, Var, GoalInfo, VarTypes, ModuleInfo,
- % Left, Cases):
+ % partition_disj(Goals, Var, GoalInfo, VarTypes, ModuleInfo, Left, Cases):
+ %
% Attempts to partition the disjunction `Goals' into a switch on `Var'.
% If at least partially successful, returns the resulting `Cases', with
% any disjunction goals not fitting into the switch in Left.
-
- % Given the list of goals in a disjunction, and an input variable
- % to switch on, we attempt to partition the goals into a switch.
- % For each constructor id, we record the list of disjuncts
- % which unify the variable with that constructor.
- % We partition the goals by abstractly interpreting the unifications
- % at the start of each disjunction, to build up a substitution.
-
+ %
+ % Given the list of goals in a disjunction, and an input variable to switch
+ % on, we attempt to partition the goals into a switch. For each constructor
+ % id, we record the list of disjuncts which unify the variable with that
+ % constructor. We partition the goals by abstractly interpreting the
+ % unifications at the start of each disjunction, to build up a
+ % substitution.
+ %
:- pred partition_disj(list(hlds_goal)::in, prog_var::in, hlds_goal_info::in,
list(hlds_goal)::out, sorted_case_list::out) is semidet.
@@ -407,8 +400,7 @@
fix_case_list(CasesAssocList, GoalInfo, CasesList).
:- pred partition_disj_trial(list(hlds_goal)::in, prog_var::in,
- list(hlds_goal)::in, list(hlds_goal)::out, cases::in, cases::out)
- is det.
+ list(hlds_goal)::in, list(hlds_goal)::out, cases::in, cases::out) is det.
partition_disj_trial([], _Var, !Left, !Cases).
partition_disj_trial([Goal0 | Goals], Var, !Left, !Cases) :-
@@ -441,15 +433,14 @@
UnifyInfo0 = deconstruct(_, Functor, _, _, _, _)
->
Result = yes(Functor),
- % The deconstruction unification now becomes
- % deterministic, since the test will get
- % carried out in the switch.
+ % The deconstruction unification now becomes deterministic, since
+ % the test will get carried out in the switch.
UnifyInfo = UnifyInfo0 ^ deconstruct_can_fail := cannot_fail,
GoalExpr = GoalExpr0 ^ unify_kind := UnifyInfo,
Goal = GoalExpr - GoalInfo,
Goals = [Goal]
;
- error("find_bind_var_for_switch_in_deconstruct")
+ unexpected(this_file, "find_bind_var_for_switch_in_deconstruct")
).
%-----------------------------------------------------------------------------%
@@ -493,15 +484,14 @@
FoundDeconstruct = before_deconstruct
;
SubGoals0 = [_ | _],
- conj_find_bind_var(Var, ProcessUnify,
- SubGoals0, SubGoals, !Subst, !Result, !Info,
- FoundDeconstruct),
+ conj_find_bind_var(Var, ProcessUnify, SubGoals0, SubGoals,
+ !Subst, !Result, !Info, FoundDeconstruct),
Goal = conj(SubGoals) - GoalInfo
)
; Goal0 = unify(LHS, RHS, _, UnifyInfo0, _) ->
(
- % check whether the unification is a deconstruction
- % unification on Var or a variable aliased to Var
+ % Check whether the unification is a deconstruction unification
+ % on either Var or on a variable aliased to Var.
UnifyInfo0 = deconstruct(UnifyVar, _, _, _, _, _),
term__apply_rec_substitution(term__variable(Var),
!.Subst, term__variable(Var1)),
@@ -509,18 +499,17 @@
!.Subst, term__variable(UnifyVar1)),
Var1 = UnifyVar1
->
- call(ProcessUnify, Var, Goal0 - GoalInfo, Goals,
- !Result, !Info),
+ call(ProcessUnify, Var, Goal0 - GoalInfo, Goals, !Result, !Info),
conj_list_to_goal(Goals, GoalInfo, Goal),
FoundDeconstruct = found_deconstruct
;
Goal = Goal0 - GoalInfo,
FoundDeconstruct = before_deconstruct,
- % otherwise abstractly interpret the unification
+ % Otherwise abstractly interpret the unification.
( interpret_unify(LHS, RHS, !.Subst, NewSubst) ->
!:Subst = NewSubst
;
- % the unification must fail - just ignore it
+ % The unification must fail - just ignore it.
true
)
)
@@ -597,9 +586,9 @@
Goal = switch(Var, CanFail, Cases)
).
- % check whether a switch handles all the possible
- % constants/functors for the type
-
+ % Check whether a switch handles all the possible constants/functors
+ % for the type.
+ %
:- pred switch_covers_all_cases(module_info::in, (type)::in,
sorted_case_list::in) is semidet.
@@ -608,9 +597,9 @@
list__length(CasesList, NumCases),
NumCases = NumFunctors.
- % convert the assoc_list(cons_id, list(hlds_goal) back into
- % a plain list(case).
-
+ % Convert the assoc_list(cons_id, list(hlds_goal)) back into a plain
+ % list(case).
+ %
:- pred fix_case_list(assoc_list(cons_id, list(hlds_goal))::in,
hlds_goal_info::in, list(case)::out) is det.
@@ -621,5 +610,11 @@
list__reverse(DisjList0, DisjList),
disj_list_to_goal(DisjList, GoalInfo, Goal),
fix_case_list(Cases0, GoalInfo, Cases).
+
+%-----------------------------------------------------------------------------%
+
+:- func this_file = string.
+
+this_file = "switch_detection.m".
%-----------------------------------------------------------------------------%
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/aditi
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/stream
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing mdbcomp
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
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