Files
mercury/tests/valid/static.m
Fergus Henderson e823aa5838 Fix some bugs in the static ground term optimization for the MLDS
Estimated hours taken: 20

Fix some bugs in the static ground term optimization for the MLDS
back-end.

compiler/ml_code_util.m:
compiler/ml_code_gen.m:
	Ensure that declarations for a goal are generated in such a
	way that they scope over the C code generated for any
	following goals.  This is needed to ensure that we don't
	generate references to undeclared names in static constants.

compiler/ml_unify_gen.m:
compiler/ml_code_util.m:
	Ensure that all static consts get unique names, so that
	ml_elim_nested.m can hoist them to the top level.
	Also move ml_gen_static_const_decl_flags from ml_unify_gen.m
	to ml_code_util.m, for use by ml_code_gen.m.

compiler/ml_elim_nested.m:
	Hoist out the definitions of static constants to the top level
	in cases where they might be referenced from nested functions.
	Also change the name of the local_vars field of the ml_elim_info
	to local_data, to make it clear that it can hold constants too.

compiler/mark_static_terms.m:
	Fix some typos in the comments.

compiler/mlds_to_c.m:
	Fix an XXX: it was not outputting `static' in the right places.

tests/valid/Mmakefile:
tests/valid/static.m:
	Add some regression tests.
2000-10-22 13:57:55 +00:00

107 lines
2.2 KiB
Mathematica

% mmc -c --grade hlc.gc static.c
% static.c(455) : error C2065: 'static__const_Result_5' : undeclared identifier
:- module static.
:- interface.
:- type t.
:- type t4.
:- type t5.
:- pred q(t::in, t5::out) is det.
:- pred r(t::in, t5::out, int::out) is multi.
:- pred s(int::in, t5::out) is cc_nondet.
:- pred t(t::in, t4::out, t5::out) is semidet.
:- pred u(t4::out, t5::out, int::out) is nondet.
:- pred v(t4::out, t5::out, int::out) is nondet.
:- implementation.
:- import_module int, list.
:- type t ---> a ; b ; c.
:- type t4 ---> f(string, int).
:- type t5 ---> g(t4, t4) ; i.
% Test for ordinary if-then-else
q(X, Y) :-
(
X = a,
% This line causes the problem. Move it into
% the then to avoid the above code gen problem.
% We can move it into the then because this line
% isn't part of the test.
Result = f("hello", 0)
->
Y = g(Result, Result)
;
Y = i
).
% Test for if-then-else with nondet condition
r(X, Y, Z) :-
(
X = a,
(Z0 = 1 ; Z0 = 2),
% This line causes the problem. Move it into
% the then to avoid the above code gen problem.
% We can move it into the then because this line
% isn't part of the test.
Result = f("hello", 0)
->
Z = Z0,
Y = g(Result, Result)
;
Z = 0,
Y = i
).
% Test for commit
s(X, Y) :-
some [Z] (
(Z = 1 ; Z = 2),
X = Z * Z,
Result = f("hello", 0)
),
Y = g(Result, Result).
% Test same variable having different constant values in different branches (semidet)
t(X, Result, Y) :-
(
X = a,
Result = f("hello", 0),
Y = g(Result, Result)
;
X = b,
Result = f("goodbye", 0),
Y = g(Result, Result)
).
% Test same variable having different constant values in different branches (nondet)
u(Result, Y, Z) :-
(
Result = f("hello", 0),
list__member(Z, [1,2]),
Y = g(Result, Result)
;
Result = f("hello again", 0),
Result2 = f("GoodBye", 0),
list__member(Z, [3,4]),
Y = g(Result, Result2)
).
% Exactly the same as u/3, but with different constants;
% this tests to ensure that any constant values hoisted
% out to the top level are given distinct names.
v(Result, Y, Z) :-
(
Result = f("xxxxx", 0),
list__member(Z, [1,2]),
Y = g(Result, Result)
;
Result = f("yyyyyyyyyyy", 0),
Result2 = f("zzzzzzz", 0),
list__member(Z, [3,4]),
Y = g(Result, Result2)
).