[m-rev.] For post-commit review: Loop control scope reason.

Paul Bone pbone at csse.unimelb.edu.au
Tue Sep 13 16:08:54 AEST 2011


For post-commit review by Zoltan.

This will be easier to review once it is commited,
Additionally the extra code paths introduced here are currently unused.

---

Propose changes to the HLDS that are needed by the loop control transformation.

The loop control transformation will introduce code that needs to be executed
by a different context, This code will need to communicate with the context
that created it, for parallel conjunctions this is done using an extra stack
pointer, the parent stack pointer.  We've chosen to use the same communication
mechanism for loop control, this means that the code generator must generate
instructions that use the parent stack pointer instead of the normal stack
pointer.  A extra labels and a join_and_terminate call must also be inserted by
the code generator.

So that the code generator can do this we've introduced a new scope reason,
code that would be forked off will be contained within such a scope, informing
the code generator that special code needs to be generated.  The scope reason
also contains two variables, the loop control and loop control slot variables.
These variables are needed by the join and terminate code.

compiler/hlds_goal.m:
    Introduce new scope reason that marks code that must be handled differently
    during code generation Such code has had the loop control transformation
    applied to it and must be forked off to be executed on a different context.

compiler/constraint.m:
compiler/det_analysis.m:
compiler/det_report.m:
compiler/erl_code_gen.m:
compiler/goal_util.m:
compiler/hlds_desc.m:
compiler/hlds_out_goal.m:
compiler/interval.m:
compiler/lambda.m:
compiler/make_hlds_warn.m:
compiler/modecheck_goal.m:
compiler/polymorphism.m:
compiler/saved_vars.m:
compiler/simplify.m:
compiler/stm_expand.m:
compiler/try_expand.m:
compiler/typecheck.m:
compiler/unique_modes.m:
    Conform to changes in hlds_goal.m

compiler/purity.m:
    Merge switch alternatives that perform the same actions.

    Conform to changes in hlds_goal.m

compiler/quantification.m:
    Remove a complete switch whose branches are all no-ops.

    Conform to changes in hlds_goal.m

Index: compiler/constraint.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/constraint.m,v
retrieving revision 1.103
diff -u -p -b -r1.103 constraint.m
--- compiler/constraint.m	31 Aug 2011 07:59:31 -0000	1.103
+++ compiler/constraint.m	13 Sep 2011 06:05:28 -0000
@@ -174,6 +174,7 @@ propagate_conj_sub_goal_2(hlds_goal(Goal
             ; Reason = commit(_)
             ; Reason = barrier(_)
             ; Reason = trace_goal(_, _, _, _, _)
+            ; Reason = loop_control(_, _)
             ),
             % We can't safely propagate constraints into one of these scopes.
             % However, we can propagate constraints inside the scope goal.
Index: compiler/det_analysis.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/det_analysis.m,v
retrieving revision 1.234
diff -u -p -b -r1.234 det_analysis.m
--- compiler/det_analysis.m	31 Aug 2011 07:59:31 -0000	1.234
+++ compiler/det_analysis.m	13 Sep 2011 06:05:28 -0000
@@ -1779,6 +1779,30 @@ det_infer_scope(Reason, Goal0, Goal, Goa
             RightFailingContexts, MaybePromiseEqvSolutionSets0,
             Detism, GoalFailingContexts, !DetInfo)
     ;
+        Reason = loop_control(_, _),
+        det_infer_goal(Goal0, Goal, InstMap0, SolnContext,
+            RightFailingContexts, MaybePromiseEqvSolutionSets0,
+            Detism, GoalFailingContexts, !DetInfo),
+        (
+            ( Detism = detism_det
+            ; Detism = detism_cc_multi
+            )
+        ;
+            ( Detism = detism_semi
+            ; Detism = detism_multi
+            ; Detism = detism_non
+            ; Detism = detism_cc_non
+            ; Detism = detism_failure
+            % Note: One day we should make exceptions in parallel
+            % conjunctions work.
+            ; Detism = detism_erroneous
+            ),
+            % Since loop control structures are generated only by the
+            % compiler it is reasonable to abort here.
+            unexpected($module, $pred,
+                "Loop control scope with strange determinism")
+        )
+    ;
         Reason = from_ground_term(_, FromGroundTermKind),
         (
             FromGroundTermKind = from_ground_term_construct,
Index: compiler/det_report.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/det_report.m,v
retrieving revision 1.156
diff -u -p -b -r1.156 det_report.m
--- compiler/det_report.m	16 Aug 2011 03:26:30 -0000	1.156
+++ compiler/det_report.m	13 Sep 2011 06:05:28 -0000
@@ -1129,6 +1129,30 @@ reqscope_check_scope(Reason, SubGoal, Sc
             true
         )
     ;
+        Reason = loop_control(_, _),
+        SubGoal = hlds_goal(_, SubGoalInfo),
+        Detism = goal_info_get_determinism(SubGoalInfo),
+        (
+            ( Detism = detism_det
+            ; Detism = detism_cc_multi
+            )
+        ;
+            ( Detism = detism_semi
+            ; Detism = detism_multi
+            ; Detism = detism_non
+            ; Detism = detism_cc_non
+            ; Detism = detism_failure
+            % Note: One day we should make exceptions in parallel
+            % conjunctions work.
+            ; Detism = detism_erroneous
+            ),
+            % Since loop control structures are generated only by the
+            % compiler it is reasonable to abort here rather than present the
+            % user with an error.
+            unexpected($module, $pred,
+                "Loop control scope with strange determinism")
+        )
+    ;
         ( Reason = exist_quant(_)
         ; Reason = commit(_)
         ; Reason = barrier(_)
Index: compiler/erl_code_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/erl_code_gen.m,v
retrieving revision 1.41
diff -u -p -b -r1.41 erl_code_gen.m
--- compiler/erl_code_gen.m	16 Aug 2011 03:26:30 -0000	1.41
+++ compiler/erl_code_gen.m	13 Sep 2011 06:05:28 -0000
@@ -631,6 +631,9 @@ erl_gen_goal_expr(GoalExpr, CodeModel, D
             erl_gen_commit(SubGoal, CodeModel, Detism, InstMap, Context,
                 MaybeSuccessExpr, Statement, !Info)
         ;
+            Reason = loop_control(_, _),
+            unexpected($module, $pred, "loop_control")
+        ;
             Reason = require_detism(_),
             unexpected($module, $pred, "require_detism")
         ;
Index: compiler/goal_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/goal_util.m,v
retrieving revision 1.188
diff -u -p -b -r1.188 goal_util.m
--- compiler/goal_util.m	31 Aug 2011 07:59:32 -0000	1.188
+++ compiler/goal_util.m	13 Sep 2011 06:05:28 -0000
@@ -597,6 +597,10 @@ goal_vars_2(Goal, !Set) :-
             Reason = require_complete_switch(Var),
             set_of_var.insert(Var, !Set)
         ;
+            Reason = loop_control(LCVar, LCSVar),
+            set_of_var.insert(LCVar, !Set),
+            set_of_var.insert(LCSVar, !Set)
+        ;
             ( Reason = promise_purity(_)
             ; Reason = require_detism(_)
             ; Reason = commit(_)
Index: compiler/hlds_desc.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_desc.m,v
retrieving revision 1.8
diff -u -p -b -r1.8 hlds_desc.m
--- compiler/hlds_desc.m	23 May 2011 05:08:03 -0000	1.8
+++ compiler/hlds_desc.m	13 Sep 2011 06:05:28 -0000
@@ -156,6 +156,9 @@ describe_goal(ModuleInfo, VarSet, Goal) 
         ;
             Reason = trace_goal(_, _, _, _, _),
             Desc = "scope trace goal"
+        ;
+            Reason = loop_control(_, _),
+            Desc = "scope loop control goal"
         )
     ;
         GoalExpr = if_then_else(_, _, _, _),
Index: compiler/hlds_goal.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_goal.m,v
retrieving revision 1.229
diff -u -p -b -r1.229 hlds_goal.m
--- compiler/hlds_goal.m	2 Sep 2011 06:44:26 -0000	1.229
+++ compiler/hlds_goal.m	13 Sep 2011 06:05:28 -0000
@@ -522,7 +522,7 @@
                 trace_maybe_io      :: maybe(string),
                 trace_mutable_vars  :: list(trace_mutable_var_hlds),
                 trace_quant_vars    :: list(prog_var)
-            ).
+            )
             % The goal inside the scope is trace code that is executed only
             % conditionally, and should have no effect on the semantics of
             % the program even if executed.
@@ -536,6 +536,24 @@
             % HLDS, since they are fully processed when the corresponding goal
             % in the parse tree is converted to HLDS.
 
+    ;       loop_control(
+                lc_lc_var           :: prog_var,
+                lc_lcs_var          :: prog_var
+            ).
+            % The goal inside the scope will be spawned off because the loop
+            % control transformation has been applied to this predicate.
+            %
+            % The goal will be executed by a different context, and the code
+            % generator must use the parent stack pointer to communicate with
+            % the parent.
+            %
+            % lc_lc_var identifies the variable that points to the loop
+            % control structure.
+            %
+            % lc_lcs_var identifies the variable that points to the slot in the
+            % loop control structure that should be used to spawn of the work
+            % within this scope.
+
 :- type promise_solutions_kind
     --->    equivalent_solutions
     ;       equivalent_solution_sets
@@ -2556,6 +2574,11 @@ rename_vars_in_goal_expr(Must, Subn, Exp
             Reason0 = trace_goal(Flag, Grade, Env, Vars, QuantVars0),
             rename_var_list(Must, Subn, QuantVars0, QuantVars),
             Reason = trace_goal(Flag, Grade, Env, Vars, QuantVars)
+        ;
+            Reason0 = loop_control(LCVar0, LCSVar0),
+            rename_var(Must, Subn, LCVar0, LCVar),
+            rename_var(Must, Subn, LCSVar0, LCSVar),
+            Reason = loop_control(LCVar, LCSVar)
         ),
         rename_vars_in_goal(Must, Subn, Goal0, Goal),
         Expr = scope(Reason, Goal)
@@ -2789,6 +2812,11 @@ incremental_rename_vars_in_goal_expr(Sub
             Reason0 = trace_goal(Flag, Grade, Env, Vars, QuantVars0),
             rename_var_list(need_not_rename, Subn, QuantVars0, QuantVars),
             Reason = trace_goal(Flag, Grade, Env, Vars, QuantVars)
+        ;
+            Reason0 = loop_control(LCVar0, LCSVar0),
+            rename_var(need_not_rename, Subn, LCVar0, LCVar),
+            rename_var(need_not_rename, Subn, LCSVar0, LCSVar),
+            Reason = loop_control(LCVar, LCSVar)
         ),
         incremental_rename_vars_in_goal(Subn, SubnUpdates, Goal0, Goal),
         Expr = scope(Reason, Goal)
Index: compiler/hlds_out_goal.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_out_goal.m,v
retrieving revision 1.10
diff -u -p -b -r1.10 hlds_out_goal.m
--- compiler/hlds_out_goal.m	31 Aug 2011 07:59:32 -0000	1.10
+++ compiler/hlds_out_goal.m	13 Sep 2011 06:05:28 -0000
@@ -1964,6 +1964,11 @@ write_goal_scope(Info, GoalExpr, ModuleI
         io.write_string("% quantified vars ", !IO),
         mercury_output_vars(VarSet, AppendVarNums, QuantVars, !IO),
         io.nl(!IO)
+    ;
+        Reason = loop_control(LCVar, LCSVar),
+        io.write_string("loop_control_spawn_off(", !IO),
+        mercury_output_vars(VarSet, AppendVarNums, [LCVar, LCSVar], !IO),
+        io.write_string(") (\n", !IO)
     ),
     do_write_goal(Info, Goal, ModuleInfo, VarSet, AppendVarNums,
         Indent + 1, "\n", TypeQual, !IO),
Index: compiler/interval.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/interval.m,v
retrieving revision 1.53
diff -u -p -b -r1.53 interval.m
--- compiler/interval.m	31 Aug 2011 07:59:32 -0000	1.53
+++ compiler/interval.m	13 Sep 2011 06:05:28 -0000
@@ -962,6 +962,7 @@ record_decisions_in_goal(Goal0, Goal, !V
             ; Reason0 = commit(_)
             ; Reason0 = barrier(_)
             ; Reason0 = trace_goal(_, _, _, _, _)
+            ; Reason0 = loop_control(_, _)
             ),
             Reason = Reason0
         ),
Index: compiler/lambda.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/lambda.m,v
retrieving revision 1.153
diff -u -p -b -r1.153 lambda.m
--- compiler/lambda.m	31 Aug 2011 07:59:32 -0000	1.153
+++ compiler/lambda.m	13 Sep 2011 06:05:28 -0000
@@ -752,6 +752,10 @@ find_used_vars_in_goal(Goal, !VarUses) :
             Reason = from_ground_term(Var, _),
             mark_var_as_used(Var, !VarUses)
         ;
+            Reason = loop_control(LCVar, LCSVar),
+            mark_var_as_used(LCVar, !VarUses),
+            mark_var_as_used(LCSVar, !VarUses)
+        ;
             ( Reason = promise_purity(_)
             ; Reason = barrier(_)
             ; Reason = commit(_)
Index: compiler/make_hlds_warn.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make_hlds_warn.m,v
retrieving revision 1.41
diff -u -p -b -r1.41 make_hlds_warn.m
--- compiler/make_hlds_warn.m	16 Aug 2011 03:26:31 -0000	1.41
+++ compiler/make_hlds_warn.m	13 Sep 2011 06:05:28 -0000
@@ -80,6 +80,7 @@
 
 :- import_module bool.
 :- import_module char.
+:- import_module require.
 :- import_module string.
 :- import_module varset.
 
@@ -250,6 +251,22 @@ warn_singletons_in_goal(Goal, QuantVars,
             NonLocals = goal_info_get_nonlocals(GoalInfo),
             warn_singletons_goal_vars([TermVar], GoalInfo, NonLocals,
                 QuantVars, !Info)
+        ;
+            Reason = loop_control(_, _),
+            % XXX I understand what this code should do but I don't
+            % understand how it does it.  Therefore I don't know how to
+            % implement this branch.
+            %
+            % The variables used for loop control (LC and LCS) will not be
+            % mentioned by the code within this scope (the call that
+            % eventually uses them is introduced during HLDS->LLDS
+            % translation.
+            %
+            % However, the LCS will be incorrectly considered a singleton
+            % variable because the compiler cannot see its use within this
+            % scope.  Therefore I have to do something to tell the compiler
+            % that it is not a singleton (it has been seen a second time).
+            sorry($module, $pred, "loop_control")
         )
     ;
         GoalExpr = if_then_else(Vars, Cond, Then, Else),
Index: compiler/modecheck_goal.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modecheck_goal.m,v
retrieving revision 1.12
diff -u -p -b -r1.12 modecheck_goal.m
--- compiler/modecheck_goal.m	31 Aug 2011 07:59:33 -0000	1.12
+++ compiler/modecheck_goal.m	13 Sep 2011 06:05:28 -0000
@@ -529,6 +529,7 @@ goal_large_flat_constructs(Goal) = Large
             ; Reason = commit(_)
             ; Reason = barrier(_)
             ; Reason = trace_goal(_, _, _, _, _)
+            ; Reason = loop_control(_, _)
             ),
             LargeFlatConstructs = set_of_var.init
         )
@@ -605,6 +606,7 @@ set_large_flat_constructs_to_ground_in_g
             ; Reason = commit(_)
             ; Reason = barrier(_)
             ; Reason = trace_goal(_, _, _, _, _)
+            ; Reason = loop_control(_, _)
             ),
             Goal = Goal0
         )
@@ -800,12 +802,26 @@ modecheck_goal_scope(Reason, SubGoal0, G
         GoalExpr = scope(Reason, SubGoal),
         mode_checkpoint(exit, "trace scope", !ModeInfo)
     ;
+        (
         ( Reason = exist_quant(_)
         ; Reason = promise_solutions(_, _)
         ; Reason = require_detism(_)
         ; Reason = require_complete_switch(_)
         ; Reason = commit(_)
         ; Reason = barrier(_)
+            )
+        ;
+            Reason = loop_control(LCVar, LCSVar),
+            % Here I can double-check that the variables for the loop
+            % control are ground.  XXX Is this the right thing to do?
+            mode_info_get_instmap(!.ModeInfo, InstMap),
+            mode_info_get_module_info(!.ModeInfo, ModuleInfo),
+            % Note that these errors are thrown for unreachable code since
+            % the loop control scope must be det or cc_multi.
+            expect(var_is_ground_in_instmap(ModuleInfo, InstMap, LCVar),
+                $module, $pred, "Loop control variable is not ground"),
+            expect(var_is_ground_in_instmap(ModuleInfo, InstMap, LCSVar),
+                $module, $pred, "Loop control slot variable is not ground")
         ),
         mode_checkpoint(enter, "scope", !ModeInfo),
         modecheck_goal(SubGoal0, SubGoal, !ModeInfo),
Index: compiler/polymorphism.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/polymorphism.m,v
retrieving revision 1.369
diff -u -p -b -r1.369 polymorphism.m
--- compiler/polymorphism.m	31 Aug 2011 07:59:33 -0000	1.369
+++ compiler/polymorphism.m	13 Sep 2011 06:05:28 -0000
@@ -1166,6 +1166,7 @@ polymorphism_process_goal_expr(GoalExpr0
                 ; Reason0 = require_complete_switch(_)
                 ; Reason0 = commit(_)
                 ; Reason0 = barrier(_)
+                ; Reason0 = loop_control(_, _)
                 ),
                 polymorphism_process_goal(SubGoal0, SubGoal, !Info),
                 Reason = Reason0
Index: compiler/purity.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/purity.m,v
retrieving revision 1.148
diff -u -p -b -r1.148 purity.m
--- compiler/purity.m	31 Aug 2011 07:59:34 -0000	1.148
+++ compiler/purity.m	13 Sep 2011 06:05:28 -0000
@@ -645,11 +645,6 @@ compute_expr_purity(GoalExpr0, GoalExpr,
     ;
         GoalExpr0 = scope(Reason0, SubGoal0),
         (
-            Reason0 = exist_quant(_),
-            compute_goal_purity(SubGoal0, SubGoal, Purity, ContainsTrace,
-                !Info),
-            Reason = Reason0
-        ;
             Reason0 = promise_purity(PromisedPurity),
             compute_goal_purity(SubGoal0, SubGoal, _, ContainsTrace, !Info),
             Purity = PromisedPurity,
@@ -682,6 +677,7 @@ compute_expr_purity(GoalExpr0, GoalExpr,
             ; Reason0 = require_complete_switch(_)
             ; Reason0 = commit(_)
             ; Reason0 = barrier(_)
+            ; Reason0 = exist_quant(_)
             ),
             compute_goal_purity(SubGoal0, SubGoal, Purity, ContainsTrace,
                 !Info),
@@ -692,6 +688,14 @@ compute_expr_purity(GoalExpr0, GoalExpr,
             Purity = purity_pure,
             ContainsTrace = contains_trace_goal,
             Reason = Reason0
+        ;
+            % XXX: Revisit this after writing the loop control
+            % transformation, the transformation and primitives will affect
+            % purity and it will be easier to consider what to do here
+            % _after_ that code has been written.
+            Reason0 = loop_control(_, _),
+            sorry($module, $pred,
+                "Revisit purity checking of loop control scopes")
         ),
         GoalExpr = scope(Reason, SubGoal)
     ;
Index: compiler/quantification.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/quantification.m,v
retrieving revision 1.147
diff -u -p -b -r1.147 quantification.m
--- compiler/quantification.m	31 Aug 2011 07:59:34 -0000	1.147
+++ compiler/quantification.m	13 Sep 2011 06:05:28 -0000
@@ -731,6 +731,7 @@ implicitly_quantify_goal_quant_info_scop
         ; Reason0 = require_complete_switch(_)
         ; Reason0 = commit(_)
         ; Reason0 = barrier(_)
+        ; Reason0 = loop_control(_, _)
         ),
         Reason = Reason0,
         goal_expr_vars_bitset(NonLocalsToRecompute, GoalExpr0,
@@ -801,6 +802,7 @@ implicitly_quantify_goal_quant_info_scop
             ; Reason0 = commit(_)
             ; Reason0 = barrier(_)
             ; Reason0 = from_ground_term(_, _)
+            ; Reason0 = loop_control(_, _)
             ),
             % We shouldn't invoke this predicate for these kinds of scopes.
             unexpected($module, $pred, "unexpected scope")
@@ -1824,12 +1826,7 @@ goal_expr_vars_maybe_lambda_2(NonLocalsT
         list.append(Vars, ExtraVars, AllVars),
         set_of_var.insert_list(AllVars, !Set)
     ;
-        GoalExpr = conj(ConjType, Goals),
-        (
-            ConjType = plain_conj
-        ;
-            ConjType = parallel_conj
-        ),
+        GoalExpr = conj(_, Goals),
         conj_vars_maybe_lambda(NonLocalsToRecompute, Goals, !Set, !LambdaSet)
     ;
         GoalExpr = disj(Goals),
@@ -1912,6 +1909,12 @@ goal_expr_vars_maybe_lambda_2(NonLocalsT
                 % TermVar should have been put into the relevant sets when we
                 % processed SubGoal, since it should appear in SubGoal.
             )
+        ;
+            Reason = loop_control(LCVar, LCSVar),
+            goal_vars_both_maybe_lambda(NonLocalsToRecompute, SubGoal,
+                !:Set, !:LambdaSet),
+            set_of_var.insert(LCVar, !Set),
+            set_of_var.insert(LCSVar, !Set)
         ),
         set_of_var.union(Set0, !Set),
         set_of_var.union(LambdaSet0, !LambdaSet)
@@ -2064,6 +2067,12 @@ goal_expr_vars_maybe_lambda_and_bi_impl_
                 !:Set, !:LambdaSet)
             % TermVar should have been put into the relevant sets when we
             % processed SubGoal, since it should appear in SubGoal.
+        ;
+            Reason = loop_control(LCVar, LCSVar),
+            goal_vars_both_maybe_lambda_and_bi_impl(SubGoal,
+                !:Set, !:LambdaSet),
+            set_of_var.insert(LCVar, !Set),
+            set_of_var.insert(LCSVar, !Set)
         ),
         set_of_var.union(Set0, !Set),
         set_of_var.union(LambdaSet0, !LambdaSet)
@@ -2210,6 +2219,11 @@ goal_expr_vars_no_lambda_2(NonLocalsToRe
             goal_vars_both_no_lambda(NonLocalsToRecompute, SubGoal, !:Set)
             % _TermVar should have been put into the relevant sets when we
             % processed SubGoal, since it should appear in SubGoal.
+        ;
+            Reason = loop_control(LCVar, LCSVar),
+            goal_vars_both_no_lambda(NonLocalsToRecompute, SubGoal, !:Set),
+            set_of_var.insert(LCVar, !Set),
+            set_of_var.insert(LCSVar, !Set)
         ),
         set_of_var.union(Set0, !Set)
     ;
Index: compiler/saved_vars.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/saved_vars.m,v
retrieving revision 1.93
diff -u -p -b -r1.93 saved_vars.m
--- compiler/saved_vars.m	31 Aug 2011 07:59:34 -0000	1.93
+++ compiler/saved_vars.m	13 Sep 2011 06:05:28 -0000
@@ -277,6 +277,8 @@ skip_constant_constructs([Goal0 | Goals0
     %
     % NOTE: the logic of this predicate must match the logic of
     % saved_vars_delay_goal.
+    % XXX: I went to update saved_vars_delay_goal after changing this
+    % predicate and it already diverges from the algorithm here!
     %
 :- func can_push(prog_var, hlds_goal) = bool.
 
@@ -314,6 +316,7 @@ can_push(Var, Goal) = CanPush :-
                 ; Reason = commit(_)
                 ; Reason = barrier(_)
                 ; Reason = trace_goal(_, _, _, _, _)
+                ; Reason = loop_control(_, _)
                 ),
                 CanPush = no
             ;
Index: compiler/simplify.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/simplify.m,v
retrieving revision 1.270
diff -u -p -b -r1.270 simplify.m
--- compiler/simplify.m	31 Aug 2011 07:59:34 -0000	1.270
+++ compiler/simplify.m	13 Sep 2011 06:05:28 -0000
@@ -1949,6 +1949,9 @@ simplify_goal_scope(GoalExpr0, GoalExpr,
                 ( FinalReason = promise_purity(_)
                 ; FinalReason = from_ground_term(_, _)
                 ; FinalReason = barrier(removable)
+                % XXX: I don't want anything inside the scope moved out of
+                % it or vice versa.  Is this the correct way to ensure this?
+                ; FinalReason = loop_control(_, _)
                 ),
                 Goal = Goal1
             ;
@@ -3775,6 +3778,7 @@ goal_contains_trace(hlds_goal(GoalExpr0,
             ; Reason = require_complete_switch(_)
             ; Reason = commit(_)
             ; Reason = barrier(_)
+            ; Reason = loop_control(_, _)
             ),
             goal_contains_trace(SubGoal0, SubGoal, ContainsTrace)
         ),
Index: compiler/stm_expand.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/stm_expand.m,v
retrieving revision 1.24
diff -u -p -b -r1.24 stm_expand.m
--- compiler/stm_expand.m	31 Aug 2011 07:59:34 -0000	1.24
+++ compiler/stm_expand.m	13 Sep 2011 06:05:28 -0000
@@ -354,6 +354,7 @@ stm_process_goal(Instmap, Goal0, Goal, !
             ; Reason = commit(_)
             ; Reason = barrier(_)
             ; Reason = trace_goal(_, _, _, _, _)
+            ; Reason = loop_control(_, _)
             ),
             stm_process_goal(Instmap, InnerGoal0, InnerGoal, !Info),
             GoalExpr = scope(Reason, InnerGoal),
Index: compiler/try_expand.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/try_expand.m,v
retrieving revision 1.19
diff -u -p -b -r1.19 try_expand.m
--- compiler/try_expand.m	31 Aug 2011 07:59:35 -0000	1.19
+++ compiler/try_expand.m	13 Sep 2011 06:05:28 -0000
@@ -386,6 +386,7 @@ expand_try_goals_in_goal(Instmap, Goal0,
             ; Reason = from_ground_term(_, from_ground_term_deconstruct)
             ; Reason = from_ground_term(_, from_ground_term_other)
             ; Reason = trace_goal(_, _, _, _, _)
+            ; Reason = loop_control(_, _)
             ),
             expand_try_goals_in_goal(Instmap, InnerGoal0, InnerGoal, !Info),
             GoalExpr = scope(Reason, InnerGoal),
Index: compiler/typecheck.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/typecheck.m,v
retrieving revision 1.462
diff -u -p -b -r1.462 typecheck.m
--- compiler/typecheck.m	31 Aug 2011 07:59:35 -0000	1.462
+++ compiler/typecheck.m	13 Sep 2011 06:05:28 -0000
@@ -1284,10 +1284,16 @@ typecheck_goal_2(GoalExpr0, GoalExpr, Go
         ),
         typecheck_goal(SubGoal0, SubGoal, !Info),
         (
-            Reason = exist_quant(Vars),
-            ensure_vars_have_a_type(Vars, !Info)
+            (
+                ( Reason = exist_quant(Vars)
+                ; Reason = promise_solutions(Vars, _)
+                )
         ;
-            Reason = promise_solutions(Vars, _),
+                % These variables are introduced by the compiler and may
+                % only have a single, specific type.
+                Reason = loop_control(LCVar, LCSVar),
+                Vars = [LCVar, LCSVar]
+            ),
             ensure_vars_have_a_type(Vars, !Info)
         ;
             ( Reason = promise_purity(_)
Index: compiler/unique_modes.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/unique_modes.m,v
retrieving revision 1.140
diff -u -p -b -r1.140 unique_modes.m
--- compiler/unique_modes.m	31 Aug 2011 07:59:35 -0000	1.140
+++ compiler/unique_modes.m	13 Sep 2011 06:05:28 -0000
@@ -567,6 +567,7 @@ unique_modes_check_goal_scope(Reason, Su
         ; Reason = require_complete_switch(_)
         ; Reason = commit(_)
         ; Reason = barrier(_)
+        ; Reason = loop_control(_, _)
         ),
         mode_checkpoint(enter, "scope", !ModeInfo),
         unique_modes_check_goal(SubGoal0, SubGoal, !ModeInfo),
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 489 bytes
Desc: Digital signature
URL: <http://lists.mercurylang.org/archives/reviews/attachments/20110913/dc378374/attachment.sig>


More information about the reviews mailing list