mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-22 12:53:47 +00:00
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.
107 lines
2.2 KiB
Mathematica
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)
|
|
).
|