[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