diff: inlining.m bug fix
Fergus Henderson
fjh at hydra.cs.mu.oz.au
Wed Jul 9 18:20:15 AEST 1997
Hi,
Can someone (Andrew? Tom?) please review this one?
compiler/inlining.m:
When inlining calls, use the goalinfo from the body of
the callee rather than the goalinfo from the call.
This avoids some bugs which resulted from mismatches
between the goal and its goalinfo; for example, the
old code could lead to nondet unifications, or to calls
to error/1 that don't have instmap delta going to unreachable.
tests/hard_coded/Mmake:
tests/hard_coded/error_func.m:
tests/hard_coded/error_func.exp:
Regression test for the above change.
Index: inlining.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/inlining.m,v
retrieving revision 1.66
diff -u -r1.66 inlining.m
--- inlining.m 1997/06/29 23:10:45 1.66
+++ inlining.m 1997/07/09 08:01:22
@@ -364,7 +364,10 @@
map__det_update(PredTable0, PredId, PredInfo, PredTable),
module_info_set_preds(ModuleInfo0, PredTable, ModuleInfo1),
- % Re-run determinism analysis if we have to.
+ % If the determinism of some sub-goals has changed,
+ % then we re-run determinism analysis, because
+ % propagating the determinism information through
+ % the procedure may lead to more efficient code.
( DetChanged = yes,
globals__io_get_globals(Globals, IoState0, IoState),
det_infer_proc(PredId, ProcId, ModuleInfo1, ModuleInfo,
@@ -380,41 +383,33 @@
inline_info).
:- mode inlining__inlining_in_goal(in, out, in, out) is det.
-inlining__inlining_in_goal(Goal0 - GoalInfo, Goal - GoalInfo) -->
- inlining__inlining_in_goal_2(Goal0, GoalInfo, Goal).
-
-%-----------------------------------------------------------------------------%
-
-:- pred inlining__inlining_in_goal_2(hlds_goal_expr, hlds_goal_info,
- hlds_goal_expr, inline_info, inline_info).
-:- mode inlining__inlining_in_goal_2(in, in, out, in, out) is det.
-
-inlining__inlining_in_goal_2(conj(Goals0), _GoalInfo, conj(Goals)) -->
+inlining__inlining_in_goal(conj(Goals0) - GoalInfo, conj(Goals) - GoalInfo) -->
inlining__inlining_in_conj(Goals0, Goals).
-inlining__inlining_in_goal_2(disj(Goals0, SM), _GoalInfo, disj(Goals, SM)) -->
+inlining__inlining_in_goal(disj(Goals0, SM) - GoalInfo,
+ disj(Goals, SM) - GoalInfo) -->
inlining__inlining_in_disj(Goals0, Goals).
-inlining__inlining_in_goal_2(switch(Var, Det, Cases0, SM), _GoalInfo,
- switch(Var, Det, Cases, SM)) -->
+inlining__inlining_in_goal(switch(Var, Det, Cases0, SM) - GoalInfo,
+ switch(Var, Det, Cases, SM) - GoalInfo) -->
inlining__inlining_in_cases(Cases0, Cases).
-inlining__inlining_in_goal_2(
- if_then_else(Vars, Cond0, Then0, Else0, SM), _GoalInfo,
- if_then_else(Vars, Cond, Then, Else, SM)) -->
+inlining__inlining_in_goal(
+ if_then_else(Vars, Cond0, Then0, Else0, SM) - GoalInfo,
+ if_then_else(Vars, Cond, Then, Else, SM) - GoalInfo) -->
inlining__inlining_in_goal(Cond0, Cond),
inlining__inlining_in_goal(Then0, Then),
inlining__inlining_in_goal(Else0, Else).
-inlining__inlining_in_goal_2(not(Goal0), _GoalInfo, not(Goal)) -->
+inlining__inlining_in_goal(not(Goal0) - GoalInfo, not(Goal) - GoalInfo) -->
inlining__inlining_in_goal(Goal0, Goal).
-inlining__inlining_in_goal_2(some(Vars, Goal0), _GoalInfo, some(Vars, Goal)) -->
+inlining__inlining_in_goal(some(Vars, Goal0) - GoalInfo,
+ some(Vars, Goal) - GoalInfo) -->
inlining__inlining_in_goal(Goal0, Goal).
-inlining__inlining_in_goal_2(
- call(PredId, ProcId, ArgVars, Builtin, Context, Sym),
- GoalInfo0, Goal, InlineInfo0, InlineInfo) :-
+inlining__inlining_in_goal(call(PredId, ProcId, ArgVars, Builtin, Context,
+ Sym) - GoalInfo0, Goal - GoalInfo, InlineInfo0, InlineInfo) :-
InlineInfo0 = inline_info(VarThresh, InlinedProcs, ModuleInfo,
VarSet0, VarTypes0, TypeVarSet0, TypeInfoVarMap0,
@@ -493,15 +488,15 @@
VarTypes0, Subn0, CalleeVarTypes, CalleeVarset,
VarSet, VarTypes, Subn),
goal_util__must_rename_vars_in_goal(CalledGoal, Subn,
- Goal - GoalInfo1),
+ Goal - GoalInfo),
% If the inferred determinism of the called
% goal differs from the declared determinism,
- % flag that we must re-run determinism checking
+ % flag that we should re-run determinism analysis
% on this proc.
goal_info_get_determinism(GoalInfo0, Determinism0),
- goal_info_get_determinism(GoalInfo1, Determinism1),
- ( Determinism0 = Determinism1 ->
+ goal_info_get_determinism(GoalInfo, Determinism),
+ ( Determinism0 = Determinism ->
DetChanged = DetChanged0
;
DetChanged = yes
@@ -513,6 +508,7 @@
TypeInfoVarMap)
;
Goal = call(PredId, ProcId, ArgVars, Builtin, Context, Sym),
+ GoalInfo = GoalInfo0,
VarSet = VarSet0,
VarTypes = VarTypes0,
TypeVarSet = TypeVarSet0,
@@ -522,14 +518,14 @@
InlineInfo = inline_info(VarThresh, InlinedProcs, ModuleInfo,
VarSet, VarTypes, TypeVarSet, TypeInfoVarMap, DetChanged).
-inlining__inlining_in_goal_2(higher_order_call(A, B, C, D, E), _GoalInfo,
- higher_order_call(A, B, C, D, E)) --> [].
+inlining__inlining_in_goal(higher_order_call(A, B, C, D, E) - GoalInfo,
+ higher_order_call(A, B, C, D, E) - GoalInfo) --> [].
-inlining__inlining_in_goal_2(unify(A, B, C, D, E), _GoalInfo,
- unify(A, B, C, D, E)) --> [].
+inlining__inlining_in_goal(unify(A, B, C, D, E) - GoalInfo,
+ unify(A, B, C, D, E) - GoalInfo) --> [].
-inlining__inlining_in_goal_2(pragma_c_code(A, B, C, D, E, F, G, H), _GoalInfo,
- pragma_c_code(A, B, C, D, E, F, G, H)) --> [].
+inlining__inlining_in_goal(pragma_c_code(A, B, C, D, E, F, G, H) - GoalInfo,
+ pragma_c_code(A, B, C, D, E, F, G, H) - GoalInfo) --> [].
%-----------------------------------------------------------------------------%
cvs diff: Diffing .
Index: Mmake
===================================================================
RCS file: /home/staff/zs/imp/tests/hard_coded/Mmake,v
retrieving revision 1.49
diff -u -r1.49 Mmake
--- Mmake 1997/07/09 05:45:34 1.49
+++ Mmake 1997/07/09 08:13:35
@@ -21,6 +21,7 @@
det_in_semidet_cntxt \
division_test \
elim_special_pred \
+ error_func \
expand \
float_reg \
float_rounding_bug \
Index: error_func.exp
===================================================================
RCS file: error_func.exp
diff -N error_func.exp
--- /dev/null Tue Jan 1 15:00:00 1980
+++ error_func.exp Wed Jul 9 18:16:16 1997
@@ -0,0 +1 @@
+Answer = 16472
Index: error_func.m
===================================================================
RCS file: error_func.m
diff -N error_func.m
--- /dev/null Tue Jan 1 15:00:00 1980
+++ error_func.m Wed Jul 9 18:16:46 1997
@@ -0,0 +1,74 @@
+/*
+$ mc bug2
+bug2.m:009: Warning: incorrect module name in `:- module' declaration.
+bug2.m:034: In `error(in) = out':
+bug2.m:034: warning: determinism declaration could be tighter.
+bug2.m:034: Declared `det', inferred `erroneous'.
+Software error: variable V_32 not found
+*/
+:- module error_func.
+:- interface.
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+:- import_module list, int, require, time, string.
+
+:- func first_denomination(int) = int.
+first_denomination(Kinds_of_coins) =
+ (if (Kinds_of_coins = 1) then
+ 1
+ else if (Kinds_of_coins = 2) then
+ 5
+ else if (Kinds_of_coins = 3) then
+ 10
+ else if (Kinds_of_coins = 4) then
+ 25
+ else if (Kinds_of_coins = 5) then
+ 50
+ else
+ error("wrong kind of coin")
+ ).
+
+:- func error(string) = _.
+error(S) = _ :-
+ error(S).
+
+:- func cc_tail(int, int, int) = int.
+cc_tail(Amount, Kinds_of_coins, Count) =
+ (if (Amount = 0) then
+ Count + 1
+ else if (Amount < 0 ; Kinds_of_coins = 0) then
+ Count
+ else
+ cc_tail(Amount - first_denomination(Kinds_of_coins),
+ Kinds_of_coins,
+ cc_tail(Amount, Kinds_of_coins - 1, Count))
+ ).
+
+:- func count_change(int) = int.
+count_change(Amount) =
+ cc_tail(Amount, 5, 0).
+
+:- pred do_count_change(int::in, int::out) is det.
+do_count_change(Amount, Result) :- Result = count_change(Amount).
+
+main -->
+ io__command_line_arguments(Args),
+ (if { Args = [] } then
+ { N = 350 },
+ { do_count_change(N, Answer) },
+ io__format("Answer = %d\n", [i(Answer)])
+ else if { Args = [Num] } then
+ (if { string__to_int(Num, N), N >= 0 } then
+ { benchmark_det(do_count_change, N, Answer, 1, Time) },
+ { string__format("Answer = %d, Time = %d milliseconds\n",
+ [i(Answer),i(Time)], Message) },
+ io__write_string(Message)
+ else
+ io__write_string("invalid argument\n")
+ )
+ else
+ io__write_string("wrong number of arguments\n")
+ ).
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3 | -- the last words of T. S. Garp.
More information about the developers
mailing list