Diff: bug fix in inlining.m
Andrew Bromage
bromage at cs.mu.OZ.AU
Fri Jun 6 06:03:57 AEST 1997
G'day all.
Could someone review this please?
(And thanks Tyson for writing the cool scripts.)
Cheers,
Andrew Bromage
--------8<---CUT HERE---8<--------
Estimated hours taken: 2
Bug fix to inlining.m.
When you inline a proc whose inferred determinism differs from the
declared determinism, re-run determinism analysis to ensure that
they are not misleading. This caused the code generator to abort
on the regression test included.
compiler/inlining.m:
Changes outlined above.
tests/general/Mmake:
tests/general/determinism_inlining.exp:
tests/general/determinism_inlining.m:
Regression test.
Index: compiler/inlining.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/inlining.m,v
retrieving revision 1.63
diff -u -r1.63 inlining.m
--- inlining.m 1997/06/03 06:22:31 1.63
+++ inlining.m 1997/06/05 07:57:26
@@ -94,7 +94,7 @@
:- import_module hlds_pred, hlds_goal, globals, options, llds.
:- import_module dead_proc_elim, type_util, mode_util, goal_util.
-:- import_module passes_aux, code_aux, quantification.
+:- import_module passes_aux, code_aux, quantification, det_analysis.
:- import_module bool, int, list, assoc_list, map, set, std_util.
:- import_module term, varset, require, hlds_data, dependency_graph.
@@ -172,7 +172,7 @@
inlining__do_inlining([], _Needed, _Params, _Inlined, Module, Module) --> [].
inlining__do_inlining([PPId|PPIds], Needed, Params, Inlined0,
Module0, Module) -->
- { inlining__in_predproc(PPId, Inlined0, Params, Module0, Module1) },
+ inlining__in_predproc(PPId, Inlined0, Params, Module0, Module1),
inlining__mark_predproc(PPId, Needed, Params, Module1,
Inlined0, Inlined1),
inlining__do_inlining(PPIds, Needed, Params, Inlined1, Module1, Module).
@@ -309,18 +309,20 @@
varset, % varset
map(var, type), % variable types
tvarset, % type variables
- map(tvar, var) % type_info varset, a mapping from
+ map(tvar, var), % type_info varset, a mapping from
% type variables to variables
% where their type_info is
% stored.
+ bool % Did we change the determinism
+ % of any subgoal?
).
-:- pred inlining__in_predproc(pred_proc_id, set(pred_proc_id),
- inline_params, module_info, module_info).
-:- mode inlining__in_predproc(in, in, in, in, out) is det.
+:- pred inlining__in_predproc(pred_proc_id, set(pred_proc_id), inline_params,
+ module_info, module_info, io__state, io__state).
+:- mode inlining__in_predproc(in, in, in, in, out, di, uo) is det.
inlining__in_predproc(PredProcId, InlinedProcs, Params,
- ModuleInfo0, ModuleInfo) :-
+ ModuleInfo0, ModuleInfo, IoState0, IoState) :-
Params = params(_Simple, _SingleUse, _CompoundThreshold,
_SimpleThreshold, VarThresh),
PredProcId = proc(PredId, ProcId),
@@ -337,13 +339,15 @@
proc_info_vartypes(ProcInfo0, VarTypes0),
proc_info_typeinfo_varmap(ProcInfo0, TypeInfoVarMap0),
+ DetChanged0 = no,
+
InlineInfo0 = inline_info(VarThresh, InlinedProcs, ModuleInfo0,
- VarSet0, VarTypes0, TypeVarSet0, TypeInfoVarMap0),
+ VarSet0, VarTypes0, TypeVarSet0, TypeInfoVarMap0, DetChanged0),
inlining__inlining_in_goal(Goal0, Goal, InlineInfo0, InlineInfo),
InlineInfo = inline_info(_, _, _, VarSet, VarTypes, TypeVarSet,
- TypeInfoVarMap),
+ TypeInfoVarMap, DetChanged),
pred_info_set_typevarset(PredInfo0, TypeVarSet, PredInfo1),
@@ -355,7 +359,16 @@
map__det_update(ProcTable0, ProcId, ProcInfo, ProcTable),
pred_info_set_procedures(PredInfo1, ProcTable, PredInfo),
map__det_update(PredTable0, PredId, PredInfo, PredTable),
- module_info_set_preds(ModuleInfo0, PredTable, ModuleInfo).
+ module_info_set_preds(ModuleInfo0, PredTable, ModuleInfo1),
+
+ % Re-run determinism analysis if we have to.
+ ( DetChanged = yes,
+ determinism_check_proc(ProcId, PredId, ModuleInfo1, ModuleInfo,
+ IoState0, IoState)
+ ; DetChanged = no,
+ ModuleInfo = ModuleInfo1,
+ IoState = IoState0
+ ).
%-----------------------------------------------------------------------------%
@@ -364,42 +377,44 @@
:- 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, Goal).
+ inlining__inlining_in_goal_2(Goal0, GoalInfo, Goal).
%-----------------------------------------------------------------------------%
-:- pred inlining__inlining_in_goal_2(hlds_goal_expr, hlds_goal_expr,
- inline_info, inline_info).
-:- mode inlining__inlining_in_goal_2(in, out, in, out) is det.
+:- 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), conj(Goals)) -->
+inlining__inlining_in_goal_2(conj(Goals0), _GoalInfo, conj(Goals)) -->
inlining__inlining_in_conj(Goals0, Goals).
-inlining__inlining_in_goal_2(disj(Goals0, SM), disj(Goals, SM)) -->
+inlining__inlining_in_goal_2(disj(Goals0, SM), _GoalInfo, disj(Goals, SM)) -->
inlining__inlining_in_disj(Goals0, Goals).
-inlining__inlining_in_goal_2(switch(Var, Det, Cases0, SM),
+inlining__inlining_in_goal_2(switch(Var, Det, Cases0, SM), _GoalInfo,
switch(Var, Det, Cases, SM)) -->
inlining__inlining_in_cases(Cases0, Cases).
-inlining__inlining_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0, SM),
+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(Cond0, Cond),
inlining__inlining_in_goal(Then0, Then),
inlining__inlining_in_goal(Else0, Else).
-inlining__inlining_in_goal_2(not(Goal0), not(Goal)) -->
+inlining__inlining_in_goal_2(not(Goal0), _GoalInfo, not(Goal)) -->
inlining__inlining_in_goal(Goal0, Goal).
-inlining__inlining_in_goal_2(some(Vars, Goal0), some(Vars, Goal)) -->
+inlining__inlining_in_goal_2(some(Vars, Goal0), _GoalInfo, some(Vars, Goal)) -->
inlining__inlining_in_goal(Goal0, Goal).
inlining__inlining_in_goal_2(
call(PredId, ProcId, ArgVars, Builtin, Context, Sym),
- Goal, InlineInfo0, InlineInfo) :-
+ GoalInfo0, Goal, InlineInfo0, InlineInfo) :-
InlineInfo0 = inline_info(VarThresh, InlinedProcs, ModuleInfo,
- VarSet0, VarTypes0, TypeVarSet0, TypeInfoVarMap0),
+ VarSet0, VarTypes0, TypeVarSet0, TypeInfoVarMap0,
+ DetChanged0),
% should we inline this call?
(
@@ -474,7 +489,20 @@
VarTypes0, Subn0, CalleeVarTypes, CalleeVarset,
VarSet, VarTypes, Subn),
goal_util__must_rename_vars_in_goal(CalledGoal, Subn,
- Goal - _GInfo),
+ Goal - GoalInfo1),
+
+ % If the inferred determinism of the called
+ % goal differs from the declared determinism,
+ % flag that we must re-run determinism checking
+ % on this proc.
+ goal_info_get_determinism(GoalInfo0, Determinism0),
+ goal_info_get_determinism(GoalInfo1, Determinism1),
+ ( Determinism0 = Determinism1 ->
+ DetChanged = DetChanged0
+ ;
+ DetChanged = yes
+ ),
+
apply_substitutions_to_var_map(CalledTypeInfoVarMap0,
TypeRenaming, Subn, CalledTypeInfoVarMap1),
map__merge(TypeInfoVarMap0, CalledTypeInfoVarMap1,
@@ -484,17 +512,19 @@
VarSet = VarSet0,
VarTypes = VarTypes0,
TypeVarSet = TypeVarSet0,
- TypeInfoVarMap = TypeInfoVarMap0
+ TypeInfoVarMap = TypeInfoVarMap0,
+ DetChanged = DetChanged0
),
InlineInfo = inline_info(VarThresh, InlinedProcs, ModuleInfo,
- VarSet, VarTypes, TypeVarSet, TypeInfoVarMap).
+ VarSet, VarTypes, TypeVarSet, TypeInfoVarMap, DetChanged).
-inlining__inlining_in_goal_2(higher_order_call(A, B, C, D, E),
+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_2(unify(A, B, C, D, E), unify(A, B, C, D, E)) --> [].
+inlining__inlining_in_goal_2(unify(A, B, C, D, E), _GoalInfo,
+ unify(A, B, C, D, E)) --> [].
-inlining__inlining_in_goal_2(pragma_c_code(A, B, C, D, E, F, G, H),
+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)) --> [].
%-----------------------------------------------------------------------------%
Index: tests/general/Mmake
===================================================================
RCS file: /home/staff/zs/imp/tests/general/Mmake,v
retrieving revision 1.41
diff -u -r1.41 Mmake
--- Mmake 1997/05/20 04:09:57 1.41
+++ Mmake 1997/05/30 07:47:32
@@ -30,6 +30,7 @@
DETPROGS= arithmetic \
det_complicated_unify \
+ determinism_inlining \
double_error \
double_error2 \
duplicate_label \
New File: tests/general/determinism_inlining.exp
===================================================================
42
New File: tests/general/determinism_inlining.m
===================================================================
% This is a regression test. The compiler inlined foo/1 without
% inlining the correct determinism, and the result was a nondet
% unification. -- bromage 30/5/1997
:- module determinism_inlining.
:- interface.
:- import_module io.
:- pred main(io__state :: di, io__state :: uo) is cc_multi.
:- implementation.
:- import_module int.
main -->
{ foo(X) },
io__write_int(X),
io__nl.
:- pred foo(int :: out) is multi.
foo(42).
More information about the developers
mailing list