Files
mercury/tests/invalid/actual_expected.m
Zoltan Somogyi 3dc4babb24 Update the style of more test cases.
And update expected output files for changes in line numbers.
2021-07-27 13:29:46 +10:00

143 lines
4.5 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ts=4 sw=4 et ft=mercury
%---------------------------------------------------------------------------%
:- module actual_expected.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.
%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
:- implementation.
:- import_module bool.
:- import_module int.
:- import_module list.
:- import_module map.
:- import_module maybe.
:- import_module require.
:- import_module set.
:- import_module string.
main(!IO) :-
find_compulsory_lvals([], no, no, no, MaybeCompulsoryLvals),
io.write(MaybeCompulsoryLvals, !IO).
:- type instruction
---> llcall(int, int)
; goto(code_addr)
; livevals(set(lval)).
:- type lval
---> reg(int).
:- type rval
---> rvalconst(int).
:- type code_addr
---> code_addr_label(label)
; code_addr_do_fail.
:- type label
---> label(string).
:- type maybe_compulsory_lvals
---> known(set(lval))
; unknown_must_assume_all.
:- type livemap == map(label, set(lval)).
:- pred find_compulsory_lvals(list(instruction)::in, maybe(livemap)::in,
maybe(label)::in, bool::in, maybe_compulsory_lvals::out) is det.
find_compulsory_lvals([], MaybeLiveMap, MaybeFallThrough,
_PrevLivevals, MaybeCompulsoryLvals) :-
(
MaybeFallThrough = yes(FallThrough),
(
MaybeLiveMap = yes(LiveMap),
map.lookup(LiveMap, FallThrough, CompulsoryLvals),
MaybeCompulsoryLvals = known(CompulsoryLvals)
;
MaybeLiveMap = no,
MaybeCompulsoryLvals = unknown_must_assume_all
)
;
MaybeFallThrough = no,
MaybeCompulsoryLvals = unknown_must_assume_all
).
find_compulsory_lvals([Instr | Instrs], MaybeLiveMap, MaybeFallThrough,
PrevLivevals, !:MaybeCompulsoryLvals) :-
( if
Instr = livevals(LiveLvals)
then
find_compulsory_lvals(Instrs, MaybeLiveMap, MaybeFallThrough,
yes, !:MaybeCompulsoryLvals),
union_maybe_compulsory_lvals(LiveLvals, !MaybeCompulsoryLvals)
else if
Instr = llcall(_, _)
then
require(unify(PrevLivevals, yes),
"find_compulsory_lvals: call without livevals"),
% The livevals instruction will include all the live lvals
% in MaybeCompulsoryLvals after we return.
!:MaybeCompulsoryLvals = known(set.init)
else if
Instr = goto(_Target)
then
% The livevals instruction will include all the live lvals
% in MaybeCompulsoryLvals after we return.
!:MaybeCompulsoryLvals = known(set.init)
else
possible_targets(Instr, Labels, NonLabelCodeAddrs),
(
NonLabelCodeAddrs = [],
(
Labels = [],
% Optimize the common case
find_compulsory_lvals(Instrs, MaybeLiveMap, MaybeFallThrough,
no, !:MaybeCompulsoryLvals)
;
Labels = [_ | _],
(
MaybeLiveMap = yes(LiveMap),
list.map(map.lookup(LiveMap), Labels, LabelsLiveLvals),
AllLabelsLiveLvals = set.union_list(LabelsLiveLvals),
find_compulsory_lvals(Instrs, LiveMap,
MaybeFallThrough, no, !:MaybeCompulsoryLvals),
union_maybe_compulsory_lvals(AllLabelsLiveLvals,
!MaybeCompulsoryLvals)
;
MaybeLiveMap = no,
!:MaybeCompulsoryLvals = unknown_must_assume_all
)
)
;
NonLabelCodeAddrs = [_ | _],
!:MaybeCompulsoryLvals = unknown_must_assume_all
)
).
:- pred union_maybe_compulsory_lvals(set(lval)::in,
maybe_compulsory_lvals::in, maybe_compulsory_lvals::out) is det.
union_maybe_compulsory_lvals(New, !MaybeCompulsoryLvals) :-
(
!.MaybeCompulsoryLvals = known(OldCompulsoryLvals),
set.union(New, OldCompulsoryLvals, AllCompulsoryLvals),
!:MaybeCompulsoryLvals = known(AllCompulsoryLvals)
;
!.MaybeCompulsoryLvals = unknown_must_assume_all
).
:- pred possible_targets(instruction::in, list(label)::out,
list(code_addr)::out) is det.
possible_targets(llcall(_, _), [], []).
possible_targets(goto(code_addr_label(Label)), [Label], []).
possible_targets(goto(code_addr_do_fail), [], [code_addr_do_fail]).