[m-rev.] diff: fix stack overflow with mmc --make

Julien Fischer juliensf at cs.mu.OZ.AU
Tue Feb 21 17:01:02 AEDT 2006


On Mon, 20 Feb 2006, Zoltan Somogyi wrote:

> On 20-Feb-2006, Julien Fischer <juliensf at cs.mu.OZ.AU> wrote:
> > -        GoalCannotLoopOrThrow = no
> > +        GoalCannotLoopOrThrow = yes
>
> I suggest you reformulate your code to use a variable named GoalCanLoopOrThrow,
> since it is always easier to work with variables whose semantics doesn't
> require you to think in terms of double negatives. Further, the two values
> of this variable shouldn't be yes and no, but can_loop_or_throw and
> cannot_loop_or_throw.

Ok, I've made the changes you suggested.

Estimated hours taken: 1
Branches: main

Address review comments from Zoltan.

compiler/goal_form.m:
	Rename the predicate goal_cannot_loop_or_throw/6 to
	goal_can_loop_or_throw/6 and similarly for related predicates.

	Add types to represent whether goals loop or throw exceptions and use
	these in place of booleans.

compiler/constraint.m:
compiler/goal_util.m:
compiler/simplify.m:
	Conform to the above changes and rename some variables in or to
	simplify the code.

Index: compiler/constraint.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/constraint.m,v
retrieving revision 1.69
diff -u -r1.69 constraint.m
--- compiler/constraint.m	20 Feb 2006 07:40:26 -0000	1.69
+++ compiler/constraint.m	21 Feb 2006 04:53:32 -0000
@@ -410,7 +410,7 @@
     Goal = GoalExpr - GoalInfo,
     goal_info_get_nonlocals(GoalInfo, NonLocals),
     CI_ModuleInfo0 = !.Info ^ module_info,
-    goal_cannot_loop_or_throw(Goal, GoalCannotLoopOrThrow,
+    goal_can_loop_or_throw(Goal, GoalCanLoopOrThrow,
         CI_ModuleInfo0, CI_ModuleInfo, !IO),
     !:Info = !.Info ^ module_info := CI_ModuleInfo,
     (
@@ -434,8 +434,8 @@
         % Don't propagate impure goals.
         goal_info_is_pure(GoalInfo),

-        % Don't propagate goals that can loop or throw exceptions.
-        GoalCannotLoopOrThrow = yes
+        % Only propagate goals that cannot loop or throw exceptions.
+        GoalCanLoopOrThrow = cannot_loop_or_throw
     ->
         % It's a constraint, add it to the list of constraints
         % to be attached to goals earlier in the conjunction.
Index: compiler/goal_form.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/goal_form.m,v
retrieving revision 1.25
diff -u -r1.25 goal_form.m
--- compiler/goal_form.m	16 Feb 2006 05:48:29 -0000	1.25
+++ compiler/goal_form.m	21 Feb 2006 05:32:21 -0000
@@ -21,10 +21,29 @@
 :- import_module hlds.hlds_module.
 :- import_module hlds.hlds_pred.

-:- import_module bool.
 :- import_module io.

 %-----------------------------------------------------------------------------%
+
+    % An indication of whether a goal can loop forever.
+    %
+:- type goal_loop_status
+    --->    can_loop
+    ;       cannot_loop.
+
+    % An indication of whether a goal can throw an exception.
+    %
+:- type goal_throw_status
+    --->    can_throw
+    ;       cannot_throw.
+
+    % An indication of whether a goal can loop forever or throw an exception.
+    %
+:- type goal_loop_or_throw_status
+    --->    can_loop_or_throw
+    ;       cannot_loop_or_throw.
+
+%-----------------------------------------------------------------------------%
 %
 % These versions use information from the intermodule-analysis framework
 %
@@ -32,22 +51,22 @@
 % 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.
+    % Return `goal_can_throw' if the given goal may throw an exception; return
+    % `goal_cannot_throw' 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,
+:- pred goal_can_throw(hlds_goal::in, goal_throw_status::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.
+    % Return `can_loop_or_throw' if the goal may loop forever or throw an
+    % exception and return `cannot_loop_or_throw' otherwise.
     %
-:- pred goal_cannot_loop_or_throw(hlds_goal::in, bool::out, module_info::in,
-    module_info::out, io::di, io::uo) is det.
+:- pred goal_can_loop_or_throw(hlds_goal::in, goal_loop_or_throw_status::out,
+    module_info::in, module_info::out, io::di, io::uo) is det.

 %-----------------------------------------------------------------------------%

@@ -159,6 +178,7 @@
 :- 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.
@@ -170,18 +190,19 @@
 % intermodule-analysis framework
 %

-goal_cannot_throw(GoalExpr - GoalInfo, Result, !ModuleInfo, !IO) :-
+goal_can_throw(GoalExpr - GoalInfo, Result, !ModuleInfo, !IO) :-
     goal_info_get_determinism(GoalInfo, Determinism),
     ( Determinism \= erroneous ->
-        goal_cannot_throw_2(GoalExpr, GoalInfo, Result, !ModuleInfo, !IO)
+        goal_can_throw_2(GoalExpr, GoalInfo, Result, !ModuleInfo, !IO)
     ;
-        Result = no
+        Result = can_throw
     ).

-:- 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.
+:- pred goal_can_throw_2(hlds_goal_expr::in, hlds_goal_info::in,
+    goal_throw_status::out, module_info::in, module_info::out,
+    io::di, io::uo) is det.

-goal_cannot_throw_2(Goal, _GoalInfo, Result, !ModuleInfo, !IO) :-
+goal_can_throw_2(Goal, _GoalInfo, Result, !ModuleInfo, !IO) :-
     (
         Goal = conj(Goals)
     ;
@@ -192,39 +213,39 @@
         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) :-
+    goals_can_throw(Goals, Result, !ModuleInfo, !IO).
+goal_can_throw_2(Goal, _GoalInfo, Result, !ModuleInfo, !IO) :-
     Goal = call(PredId, ProcId, _, _, _, _),
-    lookup_exception_analysis_result(proc(PredId, ProcId),
-        Status, !ModuleInfo, !IO),
+    lookup_exception_analysis_result(proc(PredId, ProcId), Status,
+        !ModuleInfo, !IO),
     ( Status = will_not_throw ->
-        Result = yes
+        Result = cannot_throw
     ;
-        Result = no
+        Result = can_throw
     ).
-goal_cannot_throw_2(Goal, _GoalInfo, Result, !ModuleInfo, !IO) :-
+goal_can_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) :-
+    Result = can_throw.
+goal_can_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) :-
+    cases_can_throw(Cases, Result, !ModuleInfo, !IO).
+goal_can_throw_2(Goal, _GoalInfo, Result, !ModuleInfo, !IO) :-
     Goal = unify(_, _, _, Uni, _),
     % Complicated unifies are _non_builtin_
     ( Uni = complicated_unify(_, _, _) ->
-        Result = no
+        Result = can_throw
     ;
-        Result = yes
+        Result = cannot_throw
     ).
-goal_cannot_throw_2(OuterGoal, _, Result, !ModuleInfo, !IO) :-
+goal_can_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_can_throw(InnerGoal, Result, !ModuleInfo, !IO).
+goal_can_throw_2(Goal, _, Result, !ModuleInfo, !IO) :-
     Goal = foreign_proc(Attributes, _, _, _, _, _),
     ExceptionStatus = may_throw_exception(Attributes),
     (
@@ -235,49 +256,56 @@
             may_call_mercury(Attributes) = will_not_call_mercury
         )
     ->
-        Result = yes
+        Result = cannot_throw
     ;
-        Result = no
+        Result = can_throw
     ).
-goal_cannot_throw_2(Goal, _, yes, !ModuleInfo, !IO) :-
+goal_can_throw_2(Goal, _, can_throw, !ModuleInfo, !IO) :-
     Goal = shorthand(_).    % XXX maybe call unexpected/2 here.

-:- pred goals_cannot_throw(hlds_goals::in, bool::out,
+:- pred goals_can_throw(hlds_goals::in, goal_throw_status::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),
+goals_can_throw([], cannot_throw, !ModuleInfo, !IO).
+goals_can_throw([Goal | Goals], Result, !ModuleInfo, !IO) :-
+    goal_can_throw(Goal, Result0, !ModuleInfo, !IO),
     (
-        Result0 = yes,
-        goals_cannot_throw(Goals, Result, !ModuleInfo, !IO)
+        Result0 = cannot_throw,
+        goals_can_throw(Goals, Result, !ModuleInfo, !IO)
     ;
-        Result0 = no,
-        Result  = no
+        Result0 = can_throw,
+        Result  = can_throw
     ).

-:- pred cases_cannot_throw(list(case)::in, bool::out,
+:- pred cases_can_throw(list(case)::in, goal_throw_status::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) :-
+cases_can_throw([], cannot_throw, !ModuleInfo, !IO).
+cases_can_throw([Case | Cases], Result, !ModuleInfo, !IO) :-
     Case = case(_, Goal),
-    goal_cannot_throw(Goal, Result0, !ModuleInfo, !IO),
+    goal_can_throw(Goal, Result0, !ModuleInfo, !IO),
     (
-        Result0 = yes,
-        cases_cannot_throw(Cases, Result, !ModuleInfo, !IO)
+        Result0 = cannot_throw,
+        cases_can_throw(Cases, Result, !ModuleInfo, !IO)
     ;
-        Result0 = no,
-        Result  = no
+        Result0 = can_throw,
+        Result  = can_throw
     ).

-goal_cannot_loop_or_throw(Goal, Result, !ModuleInfo, !IO) :-
+goal_can_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)
+        goal_can_throw(Goal, ThrowResult, !ModuleInfo, !IO),
+        (
+            ThrowResult = can_throw,
+            Result = can_loop_or_throw
+        ;
+            ThrowResult = cannot_throw,
+            Result = cannot_loop_or_throw
+        )
     ;
-        Result = no
+        Result = can_loop_or_throw
     ).

 %-----------------------------------------------------------------------------%
Index: compiler/goal_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/goal_util.m,v
retrieving revision 1.122
diff -u -r1.122 goal_util.m
--- compiler/goal_util.m	16 Feb 2006 05:48:29 -0000	1.122
+++ compiler/goal_util.m	21 Feb 2006 04:52:44 -0000
@@ -1528,11 +1528,11 @@
     % 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),
+    goal_can_loop_or_throw(EarlierGoal, EarlierCanLoopOrThrow, !ModuleInfo,
+        !IO),
     (
         FullyStrict = yes,
-        EarlierCannotLoopOrThrow = no,
+        EarlierCanLoopOrThrow = can_loop_or_throw,
         LaterCanFail = can_fail
     ->
         MaintainsTermination = no
@@ -1540,11 +1540,11 @@
         % 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,
+        goal_can_loop_or_throw(LaterGoal, LaterCanLoopOrThrow,
             !ModuleInfo, !IO),
         (
             EarlierCanFail = can_fail,
-            LaterCannotLoopOrThrow = no
+            LaterCanLoopOrThrow = can_loop_or_throw
         ->
             MaintainsTermination = no
         ;
Index: compiler/simplify.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/simplify.m,v
retrieving revision 1.164
diff -u -r1.164 simplify.m
--- compiler/simplify.m	17 Feb 2006 04:10:25 -0000	1.164
+++ compiler/simplify.m	21 Feb 2006 04:49:18 -0000
@@ -402,7 +402,7 @@
     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,
+    goal_can_loop_or_throw(Goal0, Goal0CanLoopOrThrow, ModuleInfo0,
         ModuleInfo, !IO),
     simplify_info_set_module_info(ModuleInfo, !Info),
     (
@@ -414,7 +414,7 @@
         % ensure goal is pure or semipure
         \+ goal_info_is_impure(GoalInfo0),
         ( det_info_get_fully_strict(DetInfo, no)
-        ; Goal0CannotLoopOrThrow = yes
+        ; Goal0CanLoopOrThrow = cannot_loop_or_throw
         )
     ->
         % Warn about this, unless the goal was an explicit `fail', call to
@@ -464,7 +464,7 @@
         % ensure goal is pure or semipure
         \+ goal_info_is_impure(GoalInfo0),
         ( det_info_get_fully_strict(DetInfo, no)
-        ; Goal0CannotLoopOrThrow = yes
+        ; Goal0CanLoopOrThrow = cannot_loop_or_throw
         )
     ->
 % The following warning is disabled, because it often results in spurious
--------------------------------------------------------------------------
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