[m-rev.] for review: fix a bug in untupling transformation
Peter Wang
wangp at students.cs.mu.OZ.AU
Fri Feb 11 14:50:42 AEDT 2005
On Friday 11 February 2005 02:02 pm, Ralph Becket wrote:
> Peter Wang, Friday, 11 February 2005:
> > Ralph, I don't know if the fix below is necessary for loop_inv.m, but
> > it looks like it wouldn't hurt.
>
> No, that looks good! Ta.
Great. The previous diff wasn't quite enough for the untupling transformation
though.
Estimated hours taken: 2
Branches: main
Predicates generated by the untupling transformation were being given the
same forms of names, no matter if the original procedure being transformed
was a predicate or a function. If a module had a predicate and a function
with the same name and arity, and tracing was enabled, and a low enough
optimisation level was being used, this would result in an exception being
thrown.
A similar nameclash happened when two procedures of the same name but
different arities were expanded into procedures of the same arity.
compiler/untupling.m:
Give generated procedures different names depending on whether the
proc being transformed was a predicate or function.
Keep more goal context information when transforming procedures;
the line number becomes part of the generated procedure's name.
Use a counter for generating procedure names to catch the
pathological case where the name, pred-or-func, arity and line
numbers of two generated procs are all the same.
compiler/loop_inv.m:
Give generated procedures different names depending on whether the
proc being transformed was a predicate or function.
tests/valid/Mercury.options:
tests/valid/Mmakefile:
tests/valid/untuple_bug.m:
Add a test case.
Index: compiler/loop_inv.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/loop_inv.m,v
retrieving revision 1.16
diff -u -r1.16 loop_inv.m
--- compiler/loop_inv.m 28 Jan 2005 01:03:18 -0000 1.16
+++ compiler/loop_inv.m 10 Feb 2005 06:43:00 -0000
@@ -769,12 +769,13 @@
hlds_pred__pred_info_get_origin(PredInfo, OrigOrigin),
PredName = hlds_pred__pred_info_name(PredInfo),
+ PredOrFunc = hlds_pred__pred_info_is_pred_or_func(PredInfo),
hlds_goal__goal_info_get_context(GoalInfo, Context),
term__context_line(Context, Line),
hlds_pred__proc_id_to_int(ProcId, ProcNo),
AuxNamePrefix = string__format("loop_inv_%d", [i(ProcNo)]),
prog_util__make_pred_name_with_context(ModuleName, AuxNamePrefix,
- predicate, PredName, Line, 1, AuxPredSymName),
+ PredOrFunc, PredName, Line, 1, AuxPredSymName),
(
AuxPredSymName = unqualified(AuxPredName)
;
Index: compiler/untupling.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/untupling.m,v
retrieving revision 1.1
diff -u -r1.1 untupling.m
--- compiler/untupling.m 2 Feb 2005 02:58:43 -0000 1.1
+++ compiler/untupling.m 11 Feb 2005 03:37:57 -0000
@@ -114,7 +114,7 @@
:- import_module parse_tree__prog_type.
:- import_module parse_tree__prog_util.
-:- import_module bool, list, map, require, std_util, string, svmap.
+:- import_module bool, counter, list, map, require, std_util, string, svmap.
:- import_module svvarset, term, varset.
% The transform_map structure records which procedures were
@@ -152,13 +152,14 @@
expand_args_in_module(!ModuleInfo, TransformMap) :-
module_info_predids(!.ModuleInfo, PredIds),
- list__foldl2(expand_args_in_pred, PredIds,
- !ModuleInfo, map__init, TransformMap).
+ list__foldl3(expand_args_in_pred, PredIds,
+ !ModuleInfo, map__init, TransformMap, counter__init(0), _).
:- pred expand_args_in_pred(pred_id::in, module_info::in, module_info::out,
- transform_map::in, transform_map::out) is det.
+ transform_map::in, transform_map::out, counter::in, counter::out)
+ is det.
-expand_args_in_pred(PredId, !ModuleInfo, !TransformMap) :-
+expand_args_in_pred(PredId, !ModuleInfo, !TransformMap, !Counter) :-
module_info_types(!.ModuleInfo, TypeTable),
module_info_pred_info(!.ModuleInfo, PredId, PredInfo),
(
@@ -180,8 +181,8 @@
at_least_one_expandable_type(ArgTypes, TypeTable)
->
ProcIds = pred_info_non_imported_procids(PredInfo),
- list__foldl2(expand_args_in_proc(PredId), ProcIds,
- !ModuleInfo, !TransformMap)
+ list__foldl3(expand_args_in_proc(PredId), ProcIds,
+ !ModuleInfo, !TransformMap, !Counter)
;
true
).
@@ -205,9 +206,10 @@
:- type untuple_map == map(prog_var, prog_vars).
:- pred expand_args_in_proc(pred_id::in, proc_id::in, module_info::in,
- module_info::out, transform_map::in, transform_map::out) is det.
+ module_info::out, transform_map::in, transform_map::out,
+ counter::in, counter::out) is det.
-expand_args_in_proc(PredId, ProcId, !ModuleInfo, !TransformMap) :-
+expand_args_in_proc(PredId, ProcId, !ModuleInfo, !TransformMap, !Counter) :-
some [!ProcInfo] (
module_info_types(!.ModuleInfo, TypeTable),
module_info_pred_proc_info(!.ModuleInfo, PredId, ProcId,
@@ -231,7 +233,8 @@
requantify_proc(!ProcInfo),
recompute_instmap_delta_proc(yes, !ProcInfo, !ModuleInfo),
- create_aux_pred(PredId, ProcId, PredInfo0, !.ProcInfo,
+ counter__allocate(Num, !Counter),
+ create_aux_pred(PredId, ProcId, PredInfo0, !.ProcInfo, Num,
AuxPredId, AuxProcId, CallAux,
AuxPredInfo, AuxProcInfo0, !ModuleInfo),
proc_info_set_maybe_untuple_info(
@@ -250,9 +253,13 @@
type_table::in, untuple_map::out) is det.
expand_args_in_proc_2(HeadVars0, ArgModes0, HeadVars, ArgModes,
- !Goal, !VarSet, !VarTypes, TypeTable, UntupleMap) :-
+ Goal0, Goal - GoalInfo, !VarSet, !VarTypes, TypeTable,
+ UntupleMap) :-
expand_args_in_proc_3(HeadVars0, ArgModes0, ListOfHeadVars,
- ListOfArgModes, !Goal, !VarSet, !VarTypes, [], TypeTable),
+ ListOfArgModes, Goal0, Goal - GoalInfo1, !VarSet,
+ !VarTypes, [], TypeTable),
+ goal_info_get_context(snd(Goal0), Context),
+ goal_info_set_context(GoalInfo1, Context, GoalInfo),
list__condense(ListOfHeadVars, HeadVars),
list__condense(ListOfArgModes, ArgModes),
build_untuple_map(HeadVars0, ListOfHeadVars, map__init, UntupleMap).
@@ -379,11 +386,11 @@
% See also create_aux_pred in loop_inv.m.
%
:- pred create_aux_pred(pred_id::in, proc_id::in, pred_info::in,
- proc_info::in, pred_id::out, proc_id::out, hlds_goal::out,
+ proc_info::in, int::in, pred_id::out, proc_id::out, hlds_goal::out,
pred_info::out, proc_info::out, module_info::in, module_info::out)
is det.
-create_aux_pred(PredId, ProcId, PredInfo, ProcInfo,
+create_aux_pred(PredId, ProcId, PredInfo, ProcInfo, Counter,
AuxPredId, AuxProcId, CallAux, AuxPredInfo, AuxProcInfo,
ModuleInfo0, ModuleInfo) :-
module_info_name(ModuleInfo0, ModuleName),
@@ -404,12 +411,13 @@
pred_info_get_origin(PredInfo, OrigOrigin),
PredName = pred_info_name(PredInfo),
+ PredOrFunc = pred_info_is_pred_or_func(PredInfo),
goal_info_get_context(GoalInfo, Context),
term__context_line(Context, Line),
proc_id_to_int(ProcId, ProcNo),
AuxNamePrefix = string__format("untupling_%d", [i(ProcNo)]),
make_pred_name_with_context(ModuleName, AuxNamePrefix,
- predicate, PredName, Line, 1, AuxPredSymName),
+ PredOrFunc, PredName, Line, Counter, AuxPredSymName),
(
AuxPredSymName = unqualified(AuxPredName)
;
Index: tests/valid/Mercury.options
===================================================================
RCS file: /home/mercury1/repository/tests/valid/Mercury.options,v
retrieving revision 1.15
diff -u -r1.15 Mercury.options
--- tests/valid/Mercury.options 7 Feb 2005 07:56:53 -0000 1.15
+++ tests/valid/Mercury.options 10 Feb 2005 12:50:46 -0000
@@ -94,6 +94,7 @@
MCFLAGS-type_inf_ambig_test = --infer-all
MCFLAGS-unify_typeinfo_bug = -O3 --no-special-preds
MCFLAGS-uniq_mode_inf_bug = --infer-all
+MCFLAGS-untuple_bug = -O0 --untuple --trace deep --trace-optimized
MCFLAGS-vn_float = -O5
MCFLAGS-zero_arity = --infer-modes
MGNUCFLAGS-reg_bug = --no-ansi
Index: tests/valid/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/valid/Mmakefile,v
retrieving revision 1.147
diff -u -r1.147 Mmakefile
--- tests/valid/Mmakefile 7 Feb 2005 07:56:54 -0000 1.147
+++ tests/valid/Mmakefile 10 Feb 2005 12:43:38 -0000
@@ -194,6 +194,7 @@
uniq_mode_inf_bug \
uniq_unify \
unreachable_code \
+ untuple_bug \
unused_args_test2 \
vn_float \
zero_arity
Index: tests/valid/untuple_bug.m
===================================================================
RCS file: tests/valid/untuple_bug.m
diff -N tests/valid/untuple_bug.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/valid/untuple_bug.m 11 Feb 2005 03:41:56 -0000
@@ -0,0 +1,51 @@
+% Predicates generated by the untupling transformation were being given the
+% same forms of names, no matter if the original procedure being transformed
+% was a predicate or a function. If a module had a predicate and a function
+% with the same name and arity, and tracing was enabled, and a low enough
+% optimisation level was being used, this would result in an exception being
+% thrown.
+%
+% mmc -C -O0 --untuple --trace deep --trace-optimized untuple_bug.m
+%
+% Uncaught Mercury exception:
+% Software Error: map__det_insert: key already present
+% Key Type: ll_backend.llds.label
+% Key Value: internal(2, proc(unqualified("untuple_bug"), predicate,
+% unqualified("untuple_bug"), "untupling_0__pred__f__0__1", 1, 0))
+% Value Type: ll_backend.llds.data_addr
+%
+% A similar nameclash happened when two procedures of the same name but
+% different arities were expanded into procedures of the same arity.
+%
+
+:- module untuple_bug.
+
+:- interface.
+
+:- type t ---> t(int).
+:- type tt ---> tt(int, int).
+
+% A function and predicate of the same name and arity.
+
+:- func f = t.
+:- pred f(t::out) is det.
+
+% Two predicates that expand into the same name and arity.
+
+:- pred g(t::in, t::in) is semidet.
+:- pred g(tt::in) is semidet.
+
+:- pred h(t::in, t::in) is semidet.
+:- pred h(tt::in) is semidet.
+
+:- implementation.
+
+f = t(0).
+f(t(0)).
+
+g(t(T), t(T)).
+g(tt(T, T)).
+
+% These are on the same line to make sure that a counter is being used
+% properly when generating names.
+h(t(T), t(T)). h(tt(T, T)).
--------------------------------------------------------------------------
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