mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-17 02:13:54 +00:00
70 lines
2.3 KiB
Mathematica
70 lines
2.3 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ts=4 sw=4 et ft=mercury
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% This code is a cut down version of merge_key_ranges_2 in rl_key.m.
|
|
% It is a regression test; the 21 June 2004 version of the compiler got
|
|
% a compiler abort when compiling this code with deep profiling enabled.
|
|
%
|
|
% The problem had several causes that had all to be present.
|
|
%
|
|
% 1. The inlined code of less_or_equal contains a call. Deep profiling inserts
|
|
% prepare_for_normal_call before that call, making it impure.
|
|
%
|
|
% 2. The body of less_or_equal isn't a complete switch in any argument, so
|
|
% switch detection leaves a disjunction in it.
|
|
%
|
|
% 3. The inlining of less_or_equal in merge_key_ranges_2 *after* the initial
|
|
% semantic checks causes the second run of simplify to modify the code,
|
|
% removing the redundant check of the second argument of less_or_equal in
|
|
% the second clause. This causes simplify to rerun determinism analysis.
|
|
% (If the inlining is done in the source code, the simplification will have
|
|
% been done in the first run of simplify, and simplify won't find any
|
|
% improvements to do after the deep profiling transformation.)
|
|
%
|
|
% 4. When determinism analysis looks at the inlined disjunction, it disregards
|
|
% the fact that it has no outputs because it is impure.
|
|
%
|
|
% The original symptom required -O5 to inline the relevant call in rl_key.m.
|
|
% We mark the predicate with pragma inline to force the problem, if present,
|
|
% to appear also at lower optimization levels.
|
|
|
|
:- module impure_detism.
|
|
|
|
:- interface.
|
|
|
|
:- import_module bool.
|
|
:- import_module list.
|
|
|
|
:- type bounding_tuple
|
|
---> infinity
|
|
; bound(list(int)).
|
|
|
|
:- pred merge_key_ranges_2(bounding_tuple::in,
|
|
bounding_tuple::in, bool::out) is det.
|
|
|
|
:- implementation.
|
|
|
|
:- import_module std_util.
|
|
|
|
:- type upper_lower
|
|
---> upper
|
|
; lower.
|
|
|
|
merge_key_ranges_2(Lower1, Upper2, IsNeeded) :-
|
|
( if less_or_equal(Lower1, upper, Upper2) then
|
|
IsNeeded = no
|
|
else
|
|
IsNeeded = yes
|
|
).
|
|
|
|
:- pragma inline(less_or_equal/3).
|
|
|
|
:- pred less_or_equal(bounding_tuple::in,
|
|
upper_lower::in, bounding_tuple::in) is semidet.
|
|
|
|
less_or_equal(infinity, _, _).
|
|
less_or_equal(_, upper, infinity).
|
|
less_or_equal(bound(_), _, bound(_)) :-
|
|
semidet_succeed.
|