[m-rev.] diff: optimise comparisons involving unsigned zero
Julien Fischer
jfischer at opturion.com
Sat Dec 29 19:23:03 AEDT 2018
Optimise comparisons involving unsigned zero.
compiler/const_prop.m:
Optimise away comparisons involving unsigned zeros that are
tautologies or contradictions.
Julien.
diff --git a/compiler/const_prop.m b/compiler/const_prop.m
index 13c6056..cf57260 100644
--- a/compiler/const_prop.m
+++ b/compiler/const_prop.m
@@ -1030,195 +1030,295 @@ evaluate_test("int64", ">=", 0, Args, Result) :-
evaluate_test("uint", "<", 0, Args, Result) :-
Args = [X, Y],
- X ^ arg_inst = bound(_, _, [bound_functor(uint_const(XVal), [])]),
Y ^ arg_inst = bound(_, _, [bound_functor(uint_const(YVal), [])]),
- ( if XVal < YVal then
- Result = yes
- else
+ ( if YVal = 0u then
+ % Special case: there are no uints that are < 0u.
Result = no
+ else
+ X ^ arg_inst = bound(_, _, [bound_functor(uint_const(XVal), [])]),
+ ( if XVal < YVal then
+ Result = yes
+ else
+ Result = no
+ )
).
evaluate_test("uint", "=<", 0, Args, Result) :-
Args = [X, Y],
X ^ arg_inst = bound(_, _, [bound_functor(uint_const(XVal), [])]),
- Y ^ arg_inst = bound(_, _, [bound_functor(uint_const(YVal), [])]),
- ( if XVal =< YVal then
+ ( if XVal = 0u then
+ % Special case: 0u =< all uints.
Result = yes
else
- Result = no
+ Y ^ arg_inst = bound(_, _, [bound_functor(uint_const(YVal), [])]),
+ ( if XVal =< YVal then
+ Result = yes
+ else
+ Result = no
+ )
).
evaluate_test("uint", ">", 0, Args, Result) :-
Args = [X, Y],
X ^ arg_inst = bound(_, _, [bound_functor(uint_const(XVal), [])]),
- Y ^ arg_inst = bound(_, _, [bound_functor(uint_const(YVal), [])]),
- ( if XVal > YVal then
- Result = yes
- else
+ ( if XVal = 0u then
+ % Special case: 0u > than no uints.
Result = no
+ else
+ Y ^ arg_inst = bound(_, _, [bound_functor(uint_const(YVal), [])]),
+ ( if XVal > YVal then
+ Result = yes
+ else
+ Result = no
+ )
).
evaluate_test("uint", ">=", 0, Args, Result) :-
Args = [X, Y],
- X ^ arg_inst = bound(_, _, [bound_functor(uint_const(XVal), [])]),
Y ^ arg_inst = bound(_, _, [bound_functor(uint_const(YVal), [])]),
- ( if XVal >= YVal then
+ ( if YVal = 0u then
+ % Special case: all uints are >= 0u.
Result = yes
else
- Result = no
+ X ^ arg_inst = bound(_, _, [bound_functor(uint_const(XVal), [])]),
+ ( if XVal >= YVal then
+ Result = yes
+ else
+ Result = no
+ )
).
% 8-bit unsigned integer comparisons.
evaluate_test("uint8", "<", 0, Args, Result) :-
Args = [X, Y],
- X ^ arg_inst = bound(_, _, [bound_functor(uint8_const(XVal), [])]),
Y ^ arg_inst = bound(_, _, [bound_functor(uint8_const(YVal), [])]),
- ( if XVal < YVal then
- Result = yes
- else
+ ( if YVal = 0u8 then
+ % Special case: there are no uint8s that are < 0u8.
Result = no
+ else
+ X ^ arg_inst = bound(_, _, [bound_functor(uint8_const(XVal), [])]),
+ ( if XVal < YVal then
+ Result = yes
+ else
+ Result = no
+ )
).
evaluate_test("uint8", "=<", 0, Args, Result) :-
Args = [X, Y],
X ^ arg_inst = bound(_, _, [bound_functor(uint8_const(XVal), [])]),
- Y ^ arg_inst = bound(_, _, [bound_functor(uint8_const(YVal), [])]),
- ( if XVal =< YVal then
+ ( if XVal = 0u8 then
+ % Special case: 0u8 =< all uint8s.
Result = yes
else
- Result = no
+ Y ^ arg_inst = bound(_, _, [bound_functor(uint8_const(YVal), [])]),
+ ( if XVal =< YVal then
+ Result = yes
+ else
+ Result = no
+ )
).
evaluate_test("uint8", ">", 0, Args, Result) :-
Args = [X, Y],
X ^ arg_inst = bound(_, _, [bound_functor(uint8_const(XVal), [])]),
- Y ^ arg_inst = bound(_, _, [bound_functor(uint8_const(YVal), [])]),
- ( if XVal > YVal then
- Result = yes
- else
+ ( if XVal = 0u8 then
+ % Special case: 0u8 > than no uint8s.
Result = no
+ else
+ Y ^ arg_inst = bound(_, _, [bound_functor(uint8_const(YVal), [])]),
+ ( if XVal > YVal then
+ Result = yes
+ else
+ Result = no
+ )
).
evaluate_test("uint8", ">=", 0, Args, Result) :-
Args = [X, Y],
- X ^ arg_inst = bound(_, _, [bound_functor(uint8_const(XVal), [])]),
Y ^ arg_inst = bound(_, _, [bound_functor(uint8_const(YVal), [])]),
- ( if XVal >= YVal then
+ ( if YVal = 0u8 then
+ % Special case: all uint8s are >= 0u8.
Result = yes
else
- Result = no
+ X ^ arg_inst = bound(_, _, [bound_functor(uint8_const(XVal), [])]),
+ ( if XVal >= YVal then
+ Result = yes
+ else
+ Result = no
+ )
).
% 16-bit unsigned integer comparisons.
evaluate_test("uint16", "<", 0, Args, Result) :-
Args = [X, Y],
- X ^ arg_inst = bound(_, _, [bound_functor(uint16_const(XVal), [])]),
Y ^ arg_inst = bound(_, _, [bound_functor(uint16_const(YVal), [])]),
- ( if XVal < YVal then
- Result = yes
- else
+ ( if YVal = 0u16 then
+ % Special case: there are no uint16s that are < 0u16.
Result = no
+ else
+ X ^ arg_inst = bound(_, _, [bound_functor(uint16_const(XVal), [])]),
+ ( if XVal < YVal then
+ Result = yes
+ else
+ Result = no
+ )
).
evaluate_test("uint16", "=<", 0, Args, Result) :-
Args = [X, Y],
X ^ arg_inst = bound(_, _, [bound_functor(uint16_const(XVal), [])]),
- Y ^ arg_inst = bound(_, _, [bound_functor(uint16_const(YVal), [])]),
- ( if XVal =< YVal then
+ ( if XVal = 0u16 then
+ % Special case: 0u16 =< all uint16s.
Result = yes
else
- Result = no
+ Y ^ arg_inst = bound(_, _, [bound_functor(uint16_const(YVal), [])]),
+ ( if XVal =< YVal then
+ Result = yes
+ else
+ Result = no
+ )
).
evaluate_test("uint16", ">", 0, Args, Result) :-
Args = [X, Y],
X ^ arg_inst = bound(_, _, [bound_functor(uint16_const(XVal), [])]),
- Y ^ arg_inst = bound(_, _, [bound_functor(uint16_const(YVal), [])]),
- ( if XVal > YVal then
- Result = yes
- else
+ ( if XVal = 0u16 then
+ % Special case: 0u16 > than no uint16s.
Result = no
+ else
+ Y ^ arg_inst = bound(_, _, [bound_functor(uint16_const(YVal), [])]),
+ ( if XVal > YVal then
+ Result = yes
+ else
+ Result = no
+ )
).
evaluate_test("uint16", ">=", 0, Args, Result) :-
Args = [X, Y],
- X ^ arg_inst = bound(_, _, [bound_functor(uint16_const(XVal), [])]),
Y ^ arg_inst = bound(_, _, [bound_functor(uint16_const(YVal), [])]),
- ( if XVal >= YVal then
+ ( if YVal = 0u16 then
+ % Special case: all uint16s are >= 0u16.
Result = yes
else
- Result = no
+ X ^ arg_inst = bound(_, _, [bound_functor(uint16_const(XVal), [])]),
+ ( if XVal >= YVal then
+ Result = yes
+ else
+ Result = no
+ )
).
% 32-bit unsigned integer comparisons.
evaluate_test("uint32", "<", 0, Args, Result) :-
Args = [X, Y],
- X ^ arg_inst = bound(_, _, [bound_functor(uint32_const(XVal), [])]),
Y ^ arg_inst = bound(_, _, [bound_functor(uint32_const(YVal), [])]),
- ( if XVal < YVal then
- Result = yes
- else
+ ( if YVal = 0u32 then
+ % Special case: there are no uint32s that are < 0u32.
Result = no
+ else
+ X ^ arg_inst = bound(_, _, [bound_functor(uint32_const(XVal), [])]),
+ ( if XVal < YVal then
+ Result = yes
+ else
+ Result = no
+ )
).
evaluate_test("uint32", "=<", 0, Args, Result) :-
Args = [X, Y],
X ^ arg_inst = bound(_, _, [bound_functor(uint32_const(XVal), [])]),
- Y ^ arg_inst = bound(_, _, [bound_functor(uint32_const(YVal), [])]),
- ( if XVal =< YVal then
+ ( if XVal = 0u32 then
+ % Special case: 0u32 =< all uint32s.
Result = yes
else
- Result = no
+ Y ^ arg_inst = bound(_, _, [bound_functor(uint32_const(YVal), [])]),
+ ( if XVal =< YVal then
+ Result = yes
+ else
+ Result = no
+ )
).
evaluate_test("uint32", ">", 0, Args, Result) :-
Args = [X, Y],
X ^ arg_inst = bound(_, _, [bound_functor(uint32_const(XVal), [])]),
- Y ^ arg_inst = bound(_, _, [bound_functor(uint32_const(YVal), [])]),
- ( if XVal > YVal then
- Result = yes
- else
+ ( if XVal = 0u32 then
+ % Special case: 0u32 > than no uint32s.
Result = no
+ else
+ Y ^ arg_inst = bound(_, _, [bound_functor(uint32_const(YVal), [])]),
+ ( if XVal > YVal then
+ Result = yes
+ else
+ Result = no
+ )
).
evaluate_test("uint32", ">=", 0, Args, Result) :-
Args = [X, Y],
- X ^ arg_inst = bound(_, _, [bound_functor(uint32_const(XVal), [])]),
Y ^ arg_inst = bound(_, _, [bound_functor(uint32_const(YVal), [])]),
- ( if XVal >= YVal then
+ ( if YVal = 0u32 then
+ % Special case: all uint32s are >= 0u32.
Result = yes
else
- Result = no
+ X ^ arg_inst = bound(_, _, [bound_functor(uint32_const(XVal), [])]),
+ ( if XVal >= YVal then
+ Result = yes
+ else
+ Result = no
+ )
).
% 64-bit unsigned integer comparisons.
evaluate_test("uint64", "<", 0, Args, Result) :-
Args = [X, Y],
- X ^ arg_inst = bound(_, _, [bound_functor(uint64_const(XVal), [])]),
Y ^ arg_inst = bound(_, _, [bound_functor(uint64_const(YVal), [])]),
- ( if XVal < YVal then
- Result = yes
- else
+ ( if YVal = 0u64 then
+ % Special case: there are no uint64s that are < 0u64.
Result = no
+ else
+ X ^ arg_inst = bound(_, _, [bound_functor(uint64_const(XVal), [])]),
+ ( if XVal < YVal then
+ Result = yes
+ else
+ Result = no
+ )
).
evaluate_test("uint64", "=<", 0, Args, Result) :-
Args = [X, Y],
X ^ arg_inst = bound(_, _, [bound_functor(uint64_const(XVal), [])]),
- Y ^ arg_inst = bound(_, _, [bound_functor(uint64_const(YVal), [])]),
- ( if XVal =< YVal then
+ ( if XVal = 0u64 then
+ % Special case: 0u64 =< all uint64s.
Result = yes
else
- Result = no
+ Y ^ arg_inst = bound(_, _, [bound_functor(uint64_const(YVal), [])]),
+ ( if XVal =< YVal then
+ Result = yes
+ else
+ Result = no
+ )
).
evaluate_test("uint64", ">", 0, Args, Result) :-
Args = [X, Y],
X ^ arg_inst = bound(_, _, [bound_functor(uint64_const(XVal), [])]),
- Y ^ arg_inst = bound(_, _, [bound_functor(uint64_const(YVal), [])]),
- ( if XVal > YVal then
- Result = yes
- else
+ ( if XVal = 0u64 then
+ % Special case: 0u64 > than no uint64s.
Result = no
+ else
+ Y ^ arg_inst = bound(_, _, [bound_functor(uint64_const(YVal), [])]),
+ ( if XVal > YVal then
+ Result = yes
+ else
+ Result = no
+ )
).
evaluate_test("uint64", ">=", 0, Args, Result) :-
Args = [X, Y],
- X ^ arg_inst = bound(_, _, [bound_functor(uint64_const(XVal), [])]),
Y ^ arg_inst = bound(_, _, [bound_functor(uint64_const(YVal), [])]),
- ( if XVal >= YVal then
+ ( if YVal = 0u64 then
+ % Special case: all uint64s are >= 0u64.
Result = yes
else
- Result = no
+ X ^ arg_inst = bound(_, _, [bound_functor(uint64_const(XVal), [])]),
+ ( if XVal >= YVal then
+ Result = yes
+ else
+ Result = no
+ )
).
% Float comparisons
@@ -1274,6 +1374,8 @@ evaluate_test("private_builtin", "typed_unify", Mode, Args, Result) :-
eval_unify(X, Y, Result)
).
+%---------------------------------------------------------------------------%
+
% evaluate_semidet_call(ModuleName, ProcName, ModeNum, Args, Result):
%
% This attempts to evaluate a call to
More information about the reviews
mailing list