[m-dev.] diff: fix aborts during deforestation
Simon Taylor
stayl at cs.mu.OZ.AU
Fri Sep 1 21:31:49 AEDT 2000
Estimated hours taken: 2
Fix bugs which caused compilation of Tom Conway's XML parser
to fail during deforestation.
compiler/inlining.m:
If some of the output variables of an inlined call are not
used by the caller, run quantification on the goal
to push that information into the inlined goal.
compiler/modes.m:
compiler/unique_modes.m:
When a unification with a dead variable is replaced with
`true', make sure the instmap_delta of the goal is empty.
tests/valid/Mmakefile:
tests/valid/deforest_bug.m:
Test case.
Index: compiler/inlining.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/inlining.m,v
retrieving revision 1.87
diff -u -u -r1.87 inlining.m
--- compiler/inlining.m 2000/08/09 07:46:45 1.87
+++ compiler/inlining.m 2000/08/26 07:48:01
@@ -388,6 +388,8 @@
% type variables to variables
% where their type_info is
% stored.
+ bool, % Does the goal need to be
+ % requantified?
bool % Did we change the determinism
% of any subgoal?
).
@@ -417,24 +419,37 @@
proc_info_vartypes(ProcInfo0, VarTypes0),
proc_info_typeinfo_varmap(ProcInfo0, TypeInfoVarMap0),
+ Requantify0 = no,
DetChanged0 = no,
InlineInfo0 = inline_info(VarThresh, HighLevelCode,
InlinedProcs, ModuleInfo0, UnivQTVars, Markers,
- VarSet0, VarTypes0, TypeVarSet0, TypeInfoVarMap0, DetChanged0),
+ VarSet0, VarTypes0, TypeVarSet0, TypeInfoVarMap0,
+ Requantify0, DetChanged0),
inlining__inlining_in_goal(Goal0, Goal, InlineInfo0, InlineInfo),
- InlineInfo = inline_info(_, _, _, _, _, _, VarSet, VarTypes, TypeVarSet,
- TypeInfoVarMap, DetChanged),
+ InlineInfo = inline_info(_, _, _, _, _, _, VarSet, VarTypes,
+ TypeVarSet, TypeInfoVarMap, Requantify, DetChanged),
pred_info_set_typevarset(PredInfo0, TypeVarSet, PredInfo1),
proc_info_set_varset(ProcInfo0, VarSet, ProcInfo1),
proc_info_set_vartypes(ProcInfo1, VarTypes, ProcInfo2),
proc_info_set_typeinfo_varmap(ProcInfo2, TypeInfoVarMap, ProcInfo3),
- proc_info_set_goal(ProcInfo3, Goal, ProcInfo),
+ proc_info_set_goal(ProcInfo3, Goal, ProcInfo4),
+ globals__io_get_globals(Globals, IoState0, IoState),
+ (
+ Requantify = yes,
+ body_should_use_typeinfo_liveness(PredInfo1, Globals,
+ TypeInfoLiveness),
+ requantify_proc(TypeInfoLiveness, ProcInfo4, ProcInfo)
+ ;
+ Requantify = no,
+ ProcInfo = ProcInfo4
+ ),
+
map__det_update(ProcTable0, ProcId, ProcInfo, ProcTable),
pred_info_set_procedures(PredInfo1, ProcTable, PredInfo),
map__det_update(PredTable0, PredId, PredInfo, PredTable),
@@ -444,13 +459,13 @@
% 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),
+ (
+ DetChanged = yes,
det_infer_proc(PredId, ProcId, ModuleInfo1, ModuleInfo,
Globals, _, _, _)
- ; DetChanged = no,
- ModuleInfo = ModuleInfo1,
- IoState = IoState0
+ ;
+ DetChanged = no,
+ ModuleInfo = ModuleInfo1
).
%-----------------------------------------------------------------------------%
@@ -493,7 +508,8 @@
InlineInfo0 = inline_info(VarThresh, HighLevelCode,
InlinedProcs, ModuleInfo, HeadTypeParams, Markers,
- VarSet0, VarTypes0, TypeVarSet0, TypeInfoVarMap0, DetChanged0),
+ VarSet0, VarTypes0, TypeVarSet0, TypeInfoVarMap0,
+ Requantify0, DetChanged0),
% should we inline this call?
(
@@ -518,6 +534,17 @@
TypeVarSet0, TypeVarSet, TypeInfoVarMap0,
TypeInfoVarMap, Goal - GoalInfo),
+ %
+ % If some of the output variables are not used in
+ % the calling procedure, requantify the procedure.
+ %
+ goal_info_get_nonlocals(GoalInfo0, NonLocals),
+ ( set__list_to_set(ArgVars) = NonLocals ->
+ Requantify = Requantify0
+ ;
+ Requantify = yes
+ ),
+
% If the inferred determinism of the called
% goal differs from the declared determinism,
% flag that we should re-run determinism analysis
@@ -536,11 +563,13 @@
VarTypes = VarTypes0,
TypeVarSet = TypeVarSet0,
TypeInfoVarMap = TypeInfoVarMap0,
+ Requantify = Requantify0,
DetChanged = DetChanged0
),
InlineInfo = inline_info(VarThresh, HighLevelCode,
InlinedProcs, ModuleInfo, HeadTypeParams, Markers,
- VarSet, VarTypes, TypeVarSet, TypeInfoVarMap, DetChanged).
+ VarSet, VarTypes, TypeVarSet, TypeInfoVarMap,
+ Requantify, DetChanged).
inlining__inlining_in_goal(generic_call(A, B, C, D) - GoalInfo,
generic_call(A, B, C, D) - GoalInfo) --> [].
@@ -558,7 +587,7 @@
%-----------------------------------------------------------------------------%
-inlining__do_inline_call(HeadTypeParams, ArgVars, PredInfo, ProcInfo,
+inlining__do_inline_call(_, ArgVars, PredInfo, ProcInfo,
VarSet0, VarSet, VarTypes0, VarTypes, TypeVarSet0, TypeVarSet,
TypeInfoVarMap0, TypeInfoVarMap, Goal) :-
@@ -610,6 +639,12 @@
map__apply_to_list(ArgVars, VarTypes0, ArgTypes),
pred_info_get_exist_quant_tvars(PredInfo, CalleeExistQVars),
+
+ % Typechecking has already succeeded, so we don't need
+ % to check for binding of head type parameters.
+ % Also, existentially-typed head type parameters
+ % may be bound by inlining.
+ HeadTypeParams = [],
inlining__get_type_substitution(HeadTypes, ArgTypes, HeadTypeParams,
CalleeExistQVars, TypeSubn),
Index: compiler/modes.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modes.m,v
retrieving revision 1.244
diff -u -u -r1.244 modes.m
--- compiler/modes.m 2000/08/09 07:47:22 1.244
+++ compiler/modes.m 2000/08/26 07:50:54
@@ -253,6 +253,16 @@
:- pred modecheck_functor_test(prog_var, cons_id, mode_info, mode_info).
:- mode modecheck_functor_test(in, in, mode_info_di, mode_info_uo) is det.
+ % compute_goal_instmap_delta(InstMap0, Goal,
+ % GoalInfo0, GoalInfo, ModeInfo0, ModeInfo).
+ %
+ % Work out the instmap_delta for a goal from
+ % the instmaps before and after the goal.
+:- pred compute_goal_instmap_delta(instmap, hlds_goal_expr,
+ hlds_goal_info, hlds_goal_info, mode_info, mode_info).
+:- mode compute_goal_instmap_delta(in, in, in, out,
+ mode_info_di, mode_info_uo) is det.
+
%-----------------------------------------------------------------------------%
% The following predicates are used by modecheck_unify.m.
@@ -972,11 +982,22 @@
mode_info_get_instmap(ModeInfo1, InstMap0),
modecheck_goal_expr(Goal0, GoalInfo0, Goal, ModeInfo1, ModeInfo2),
+
+ compute_goal_instmap_delta(InstMap0, Goal, GoalInfo0, GoalInfo,
+ ModeInfo2, ModeInfo).
- mode_info_get_instmap(ModeInfo, InstMap),
- mode_info_get_completed_nonlocals(GoalInfo0, NonLocals,
- ModeInfo2, ModeInfo),
- compute_instmap_delta(InstMap0, InstMap, NonLocals, DeltaInstMap),
+compute_goal_instmap_delta(InstMap0, Goal,
+ GoalInfo0, GoalInfo, ModeInfo0, ModeInfo) :-
+ ( Goal = conj([]) ->
+ instmap_delta_init_reachable(DeltaInstMap),
+ mode_info_set_instmap(InstMap0, ModeInfo0, ModeInfo)
+ ;
+ mode_info_get_completed_nonlocals(GoalInfo0, NonLocals,
+ ModeInfo0, ModeInfo),
+ mode_info_get_instmap(ModeInfo, InstMap),
+ compute_instmap_delta(InstMap0, InstMap,
+ NonLocals, DeltaInstMap)
+ ),
goal_info_set_instmap_delta(GoalInfo0, DeltaInstMap, GoalInfo).
modecheck_goal_expr(conj(List0), GoalInfo0, Goal) -->
Index: compiler/unique_modes.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/unique_modes.m,v
retrieving revision 1.63
diff -u -u -r1.63 unique_modes.m
--- compiler/unique_modes.m 2000/08/09 07:48:03 1.63
+++ compiler/unique_modes.m 2000/08/26 07:32:18
@@ -134,11 +134,8 @@
% Grab the final instmap, compute the change in insts
% over this goal, and save that instmap_delta in the goal_info.
%
- mode_info_get_instmap(ModeInfo, InstMap),
- mode_info_get_completed_nonlocals(GoalInfo0, NonLocals,
- ModeInfo4, ModeInfo),
- compute_instmap_delta(InstMap0, InstMap, NonLocals, DeltaInstMap),
- goal_info_set_instmap_delta(GoalInfo0, DeltaInstMap, GoalInfo),
+ compute_goal_instmap_delta(InstMap0, GoalExpr,
+ GoalInfo0, GoalInfo, ModeInfo4, ModeInfo),
Goal = GoalExpr - GoalInfo.
Index: tests/valid/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/valid/Mmakefile,v
retrieving revision 1.72
diff -u -u -r1.72 Mmakefile
--- tests/valid/Mmakefile 2000/09/01 09:51:40 1.72
+++ tests/valid/Mmakefile 2000/09/01 09:54:11
@@ -44,6 +44,7 @@
complicated_unify.m \
constructor_arg_names.m \
dcg_test.m \
+ deforest_bug.m \
deforest_loop.m \
deforest_rerun_det.m \
det_condition.m \
@@ -214,6 +215,7 @@
MCFLAGS-base_relation2 = --aditi
MCFLAGS-compl_unify_bug = -O3
MCFLAGS-context_anc = --aditi
+MCFLAGS-deforest_bug = -O3
MCFLAGS-deforest_loop = -O3 --intermodule-optimization
MCFLAGS-deforest_rerun_det = -O3 --check-termination
MCFLAGS-double_vn = -O4
Index: tests/valid/deforest_bug.m
===================================================================
RCS file: deforest_bug.m
diff -N deforest_bug.m
--- /dev/null Fri Sep 1 21:05:00 2000
+++ deforest_bug.m Fri Sep 1 21:09:55 2000
@@ -0,0 +1,90 @@
+:- module deforest_bug.
+
+:- interface.
+
+:- type catalog ---> catalog(publicId -> systemId).
+
+:- type [] ---> [].
+:- type [T1|T2] == list(T1).
+:- type (A -> B) == map(A, B).
+
+:- type dirs == [path].
+
+:- type publicId == string.
+
+:- type systemId == string.
+
+:- type path == string.
+
+:- type catRes(T)
+ ---> ok(T)
+ ; error(string)
+ .
+
+:- pred deforest_load([(int, [char])], [string], catalog).
+:- mode deforest_load(in, out, out) is det.
+
+:- implementation.
+
+:- import_module char, int, list, map, std_util, string.
+
+:- type entry
+ ---> dtd(publicId, systemId)
+ ; none
+ .
+
+:- pragma no_inline(deforest_load/3).
+deforest_load(CatLines, Errors, Cat) :-
+ parse(Entries, Errors, CatLines),
+ init(Cat0),
+ my_foldl(addEntry, Entries, catalog(Cat0), Cat).
+
+:- type (A, B) ---> (A, B).
+
+:- pred parse([entry], [string], [(int, [char])]).
+:- mode parse(out, out, in) is det.
+
+parse([], [], []).
+parse(Entries, Errors, [Line|Lines]) :-
+ Line = (N, Cs),
+ ( parseEntry(Entry, Cs, _) ->
+ Entries = [Entry|Entries0],
+ parse(Entries0, Errors, Lines)
+ ;
+ format("%d: syntax error", [i(N)], Msg),
+ Errors = [Msg|Errors0],
+ parse(Entries, Errors0, Lines)
+ ).
+
+:- pred addEntry(entry, catalog, catalog).
+:- mode addEntry(in, in, out) is det.
+
+addEntry(none, Cat, Cat).
+addEntry(dtd(PublicId, SystemId), catalog(Cat0), catalog(Cat)) :-
+ det_insert(Cat0, PublicId, SystemId, Cat).
+
+:- pred parseEntry(entry, [char], [char]).
+:- mode parseEntry(out, in, out) is semidet.
+
+parseEntry(Entry) -->
+ ( ['P'], string(PublicId), string(SystemId) ->
+ { Entry = dtd(PublicId, SystemId) }
+ ; =([]) ->
+ { Entry = none }
+ ;
+ { fail }
+ ).
+
+:- pred string(string, [char], [char]).
+:- mode string(out, in, out) is semidet.
+:- pragma no_inline(string/3).
+
+string("") --> { semidet_succeed }.
+
+:- pred my_foldl(pred(T, U, U), list(T), U, U).
+:- mode my_foldl(pred(in, in, out) is det, in, in, out) is det.
+
+my_foldl(_, [], A, A).
+my_foldl(P, [Head | Tail], A0, A) :-
+ P(Head, A0, A1),
+ my_foldl(P, Tail, A1, A).
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to: mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions: mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------
More information about the developers
mailing list