[m-rev.] diff: add builtin 64-bit ineger types -- Part 3
Julien Fischer
jfischer at opturion.com
Sun Feb 4 16:00:10 AEDT 2018
Hi all,
Could everyone please make sure they have updated to rotd-2018-02-03 or
later, which will be required once this is committed. I will hold off
committing this one until Wednesday in order to give everyone an
opportunity to update.
Julien.
--------------------
Add builtin 64-bit integer types -- Part 3.
Use 64-bit integer literals throughout the system.
Implement simplification of calls to int64 and uint64 library predicates.
configure.ac:
Require the bootstrap compiler to support 64-bit integer literals.
library/int64.m:
library/uint64.m:
compiler/builtin_ops.m:
compiler/lookup_switch.m:
Use 64-bit integer literals in spots where we are currently converting
the values from int.
compiler/llds_out_util.m:
compiler/llds_out_data.m:
Use 64-bit integers instead of strings for decl_id labels corresponding
to symbols for 64-bit integers.
compiler/simplify_goal_call.m:
Implement compile time simplification of 64-bit integer operations.
diff --git a/compiler/builtin_ops.m b/compiler/builtin_ops.m
index 691aac2..c252d92 100644
--- a/compiler/builtin_ops.m
+++ b/compiler/builtin_ops.m
@@ -230,11 +230,6 @@
:- import_module require.
:- import_module string.
-% XXX INT64 - this are only required until 64-bit integer literals are
-% bootstrapped.
-:- import_module int64.
-:- import_module uint64.
-
%-----------------------------------------------------------------------------%
test_if_builtin(FullyQualifiedModule, PredName, ProcId, Args) :-
@@ -473,12 +468,12 @@ make_int_zero_const(int_type_int) = int_const(0).
make_int_zero_const(int_type_int8) = int8_const(0i8).
make_int_zero_const(int_type_int16) = int16_const(0i16).
make_int_zero_const(int_type_int32) = int32_const(0i32).
-make_int_zero_const(int_type_int64) = int64_const(from_int(0)).
+make_int_zero_const(int_type_int64) = int64_const(0i64).
make_int_zero_const(int_type_uint) = uint_const(0u).
make_int_zero_const(int_type_uint8) = uint8_const(0u8).
make_int_zero_const(int_type_uint16) = uint16_const(0u16).
make_int_zero_const(int_type_uint32) = uint32_const(0u32).
-make_int_zero_const(int_type_uint64) = uint64_const(cast_from_int(0)).
+make_int_zero_const(int_type_uint64) = uint64_const(0u64).
%-----------------------------------------------------------------------------%
:- end_module backend_libs.builtin_ops.
diff --git a/compiler/llds_out_data.m b/compiler/llds_out_data.m
index 1cf47c3..2311669 100644
--- a/compiler/llds_out_data.m
+++ b/compiler/llds_out_data.m
@@ -756,12 +756,12 @@ output_record_rval_decls_format(Info, Rval, FirstIndent, LaterIndent,
UnboxedInt64s = no,
StaticGroundInt64s = yes
then
- int64_literal_name(Int64Val, Int64Name),
- Int64Label = decl_int64_label(Int64Name),
+ Int64Label = decl_int64_label(Int64Val),
( if decl_set_is_member(Int64Label, !.DeclSet) then
true
else
decl_set_insert(Int64Label, !DeclSet),
+ int64_literal_name(Int64Val, Int64Name),
Int64String = c_util.make_int64_literal(Int64Val),
output_indent(FirstIndent, LaterIndent, !.N, !IO),
!:N = !.N + 1,
@@ -781,12 +781,12 @@ output_record_rval_decls_format(Info, Rval, FirstIndent, LaterIndent,
UnboxedInt64s = no,
StaticGroundInt64s = yes
then
- uint64_literal_name(UInt64Val, UInt64Name),
- UInt64Label = decl_uint64_label(UInt64Name),
+ UInt64Label = decl_uint64_label(UInt64Val),
( if decl_set_is_member(UInt64Label, !.DeclSet) then
true
else
decl_set_insert(UInt64Label, !DeclSet),
+ uint64_literal_name(UInt64Val, UInt64Name),
UInt64String = c_util.make_uint64_literal(UInt64Val),
output_indent(FirstIndent, LaterIndent, !.N, !IO),
!:N = !.N + 1,
diff --git a/compiler/llds_out_util.m b/compiler/llds_out_util.m
index 1ff4bfb..4af8920 100644
--- a/compiler/llds_out_util.m
+++ b/compiler/llds_out_util.m
@@ -1,7 +1,8 @@
%----------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%----------------------------------------------------------------------------%
-% Copyright (C) 2009 The University of Melbourne.
+% Copyright (C) 2009, 2011 The University of Melbourne.
+% Copyright (C) 2013-2016, 2018 The Mercury team.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%----------------------------------------------------------------------------%
@@ -81,8 +82,8 @@
:- type decl_id
---> decl_float_label(string)
- ; decl_int64_label(string) % XXX INT64 - use int64 here.
- ; decl_uint64_label(string) % XXX INT64 - use uint64 here.
+ ; decl_int64_label(int64)
+ ; decl_uint64_label(uint64)
; decl_common_type(type_num)
; decl_code_addr(code_addr)
; decl_rtti_id(rtti_id)
diff --git a/compiler/lookup_switch.m b/compiler/lookup_switch.m
index a667569..18cc3b0 100644
--- a/compiler/lookup_switch.m
+++ b/compiler/lookup_switch.m
@@ -178,8 +178,6 @@
:- import_module bool.
:- import_module cord.
:- import_module int.
-:- import_module int64. % XXX INT64 - remove once int64 literals bootstrapped.
-:- import_module uint64. % XXX INT64 - ditto for uint64 literals.
:- import_module map.
:- import_module maybe.
:- import_module pair.
@@ -964,10 +962,8 @@ default_value_for_type(lt_int(int_type_int16)) = const(llconst_int16(0i16)).
default_value_for_type(lt_int(int_type_uint16)) = const(llconst_uint16(0u16)).
default_value_for_type(lt_int(int_type_int32)) = const(llconst_int32(0i32)).
default_value_for_type(lt_int(int_type_uint32)) = const(llconst_uint32(0u32)).
-% XXX INT64.
-default_value_for_type(lt_int(int_type_int64)) = const(llconst_int64(int64.from_int(0))).
-% XXX INT64.
-default_value_for_type(lt_int(int_type_uint64)) = const(llconst_uint64(uint64.cast_from_int(0))).
+default_value_for_type(lt_int(int_type_int64)) = const(llconst_int64(0i64)).
+default_value_for_type(lt_int(int_type_uint64)) = const(llconst_uint64(0u64)).
default_value_for_type(lt_float) = const(llconst_float(0.0)).
default_value_for_type(lt_string) = const(llconst_string("")).
default_value_for_type(lt_data_ptr) = const(llconst_int(0)).
diff --git a/compiler/simplify_goal_call.m b/compiler/simplify_goal_call.m
index 60b33bd..be09c82 100644
--- a/compiler/simplify_goal_call.m
+++ b/compiler/simplify_goal_call.m
@@ -703,6 +703,14 @@ simplify_improve_library_call(InstMap0, ModuleName, PredName, ModeNum, Args,
ModuleName = "uint32",
simplify_improve_uint32_call(InstMap0, ModuleName, PredName, ModeNum,
Args, ImprovedGoalExpr, GoalInfo0, ImprovedGoalInfo, !Info)
+ ;
+ ModuleName = "int64",
+ simplify_improve_int64_call(InstMap0, ModuleName, PredName, ModeNum,
+ Args, ImprovedGoalExpr, GoalInfo0, ImprovedGoalInfo, !Info)
+ ;
+ ModuleName = "uint64",
+ simplify_improve_uint64_call(InstMap0, ModuleName, PredName, ModeNum,
+ Args, ImprovedGoalExpr, GoalInfo0, ImprovedGoalInfo, !Info)
),
simplify_info_set_should_requantify(!Info).
@@ -1280,6 +1288,92 @@ simplify_improve_uint32_call(InstMap0, ModuleName, PredName, _ModeNum, Args,
simplify_make_binary_op_goal_expr(!.Info, ModuleName, Op,
inline_builtin, X, Y, Z, ImprovedGoalExpr).
+:- pred simplify_improve_int64_call(instmap::in, string::in, string::in,
+ int::in, list(prog_var)::in, hlds_goal_expr::out,
+ hlds_goal_info::in, hlds_goal_info::out,
+ simplify_info::in, simplify_info::out) is semidet.
+
+simplify_improve_int64_call(InstMap0, ModuleName, PredName, _ModeNum, Args,
+ ImprovedGoalExpr, !GoalInfo, !Info) :-
+ (
+ ( PredName = "/"
+ ; PredName = "//"
+ ),
+ Args = [X, Y, Z],
+ instmap_lookup_var(InstMap0, Y, InstY),
+ InstY = bound(_, _, [bound_functor(int64_const(YVal), [])]),
+ YVal \= 0i64,
+ Op = "unchecked_quotient"
+ ;
+ PredName = "rem",
+ Args = [X, Y, Z],
+ instmap_lookup_var(InstMap0, Y, InstY),
+ InstY = bound(_, _, [bound_functor(int64_const(YVal), [])]),
+ YVal \= 0i64,
+ Op = "unchecked_rem"
+ ;
+ PredName = "<<",
+ Args = [X, Y, Z],
+ instmap_lookup_var(InstMap0, Y, InstY),
+ InstY = bound(_, _, [bound_functor(int_const(YVal), [])]),
+ YVal >= 0,
+ YVal < 64,
+ Op = "unchecked_left_shift"
+ ;
+ PredName = ">>",
+ Args = [X, Y, Z],
+ instmap_lookup_var(InstMap0, Y, InstY),
+ InstY = bound(_, _, [bound_functor(int_const(YVal), [])]),
+ YVal >= 0,
+ YVal < 64,
+ Op = "unchecked_right_shift"
+ ),
+ simplify_make_binary_op_goal_expr(!.Info, ModuleName, Op,
+ inline_builtin, X, Y, Z, ImprovedGoalExpr).
+
+:- pred simplify_improve_uint64_call(instmap::in, string::in, string::in,
+ int::in, list(prog_var)::in, hlds_goal_expr::out,
+ hlds_goal_info::in, hlds_goal_info::out,
+ simplify_info::in, simplify_info::out) is semidet.
+
+simplify_improve_uint64_call(InstMap0, ModuleName, PredName, _ModeNum, Args,
+ ImprovedGoalExpr, !GoalInfo, !Info) :-
+ (
+ ( PredName = "/"
+ ; PredName = "//"
+ ),
+ Args = [X, Y, Z],
+ instmap_lookup_var(InstMap0, Y, InstY),
+ InstY = bound(_, _, [bound_functor(uint64_const(YVal), [])]),
+ YVal \= 0u64,
+ Op = "unchecked_quotient"
+ ;
+ PredName = "rem",
+ Args = [X, Y, Z],
+ instmap_lookup_var(InstMap0, Y, InstY),
+ InstY = bound(_, _, [bound_functor(uint64_const(YVal), [])]),
+ YVal \= 0u64,
+ Op = "unchecked_rem"
+ ;
+ PredName = "<<",
+ Args = [X, Y, Z],
+ instmap_lookup_var(InstMap0, Y, InstY),
+ InstY = bound(_, _, [bound_functor(int_const(YVal), [])]),
+ YVal >= 0,
+ YVal < 64,
+ Op = "unchecked_left_shift"
+ ;
+ PredName = ">>",
+ Args = [X, Y, Z],
+ instmap_lookup_var(InstMap0, Y, InstY),
+ InstY = bound(_, _, [bound_functor(int_const(YVal), [])]),
+ YVal >= 0,
+ YVal < 64,
+ Op = "unchecked_right_shift"
+ ),
+ simplify_make_binary_op_goal_expr(!.Info, ModuleName, Op,
+ inline_builtin, X, Y, Z, ImprovedGoalExpr).
+
%---------------------------------------------------------------------------%
:- end_module check_hlds.simplify.simplify_goal_call.
%---------------------------------------------------------------------------%
diff --git a/configure.ac b/configure.ac
index 24d4d17..a47734d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -406,9 +406,9 @@ then
:- type bear ---> brown ; black ; teddy.
:- pragma foreign_export_enum("Java", bear/0).
- :- pred check_int64(int64::in, int64::out) is det.
+ :- pred check_int64(int64::out) is det.
- check_int64(X, X).
+ check_int64(561i64).
:- pred my_uint_xor(uint32::in, uint32::out) is det.
diff --git a/library/int64.m b/library/int64.m
index 4206761..fabfae4 100644
--- a/library/int64.m
+++ b/library/int64.m
@@ -315,14 +315,14 @@ abs(Num) = Abs :-
).
unchecked_abs(Num) =
- ( if Num < from_int(0) then
- from_int(0) - Num
+ ( if Num < 0i64 then
+ 0i64 - Num
else
Num
).
nabs(Num) =
- ( if Num > from_int(0) then
+ ( if Num > 0i64 then
-Num
else
Num
@@ -333,19 +333,19 @@ nabs(Num) =
X div Y = Div :-
Trunc = X // Y,
( if
- ( X >= from_int(0), Y >= from_int(0)
- ; X < from_int(0), Y < from_int(0)
- ; X rem Y = from_int(0)
+ ( X >= 0i64, Y >= 0i64
+ ; X < 0i64, Y < 0i64
+ ; X rem Y = 0i64
)
then
Div = Trunc
else
- Div = Trunc - from_int(1)
+ Div = Trunc - 1i64
).
:- pragma inline('//'/2).
X // Y = Div :-
- ( if Y = from_int(0) then
+ ( if Y = 0i64 then
throw(math.domain_error("int64.'//': division by zero"))
else
Div = unchecked_quotient(X, Y)
@@ -358,7 +358,7 @@ X mod Y = X - (X div Y) * Y.
:- pragma inline(rem/2).
X rem Y = Rem :-
- ( if Y = from_int(0) then
+ ( if Y = 0i64 then
throw(math.domain_error("int64.rem: division by zero"))
else
Rem = unchecked_rem(X, Y)
@@ -394,65 +394,17 @@ min(X, Y) =
:- pragma inline(even/1).
even(X) :-
- (X /\ from_int(1)) = from_int(0).
+ (X /\ 1i64) = 0i64.
:- pragma inline(odd/1).
odd(X) :-
- (X /\ from_int(1)) \= from_int(0).
+ (X /\ 1i64) \= 0i64.
%---------------------------------------------------------------------------%
-:- pragma foreign_proc("C",
- min_int64 = (I64::out),
- [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
-"
- I64 = INT64_MIN;
-").
-
-:- pragma foreign_proc("C#",
- min_int64 = (I64::out),
- [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
-"
- I64 = System.Int64.MinValue;
-").
-
-:- pragma foreign_proc("Java",
- min_int64 = (I64::out),
- [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
-"
- I64 = java.lang.Long.MIN_VALUE;
-").
-
-:- pragma no_determinism_warning(min_int64/0).
-min_int64 = _ :-
- sorry($module, "NYI min_int64/9 for Erlang").
-
-%---------------------------------------------------------------------------%
-
-:- pragma foreign_proc("C",
- max_int64 = (I64::out),
- [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
-"
- I64 = INT64_MAX;
-").
-
-:- pragma foreign_proc("C#",
- max_int64 = (I64::out),
- [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
-"
- I64 = System.Int64.MaxValue;
-").
-
-:- pragma foreign_proc("Java",
- max_int64 = (I64::out),
- [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
-"
- I64 = java.lang.Long.MAX_VALUE;
-").
+min_int64 = -9_223_372_036_854_775_808_i64.
-:- pragma no_determinism_warning(max_int64/0).
-max_int64 = _ :-
- sorry($module, "NYI max_int64/9 for Erlang").
+max_int64 = 9_223_372_036_854_775_807_i64.
%---------------------------------------------------------------------------%
diff --git a/library/uint64.m b/library/uint64.m
index 4ca9877..88bef0e 100644
--- a/library/uint64.m
+++ b/library/uint64.m
@@ -297,7 +297,7 @@ X div Y = X // Y.
:- pragma inline('//'/2).
X // Y = Div :-
- ( if Y = cast_from_int(0) then
+ ( if Y = 0u64 then
throw(math.domain_error("uint64.'//': division by zero"))
else
Div = unchecked_quotient(X, Y)
@@ -310,7 +310,7 @@ X mod Y = X rem Y.
:- pragma inline(rem/2).
X rem Y = Rem :-
- ( if Y = cast_from_int(0) then
+ ( if Y = 0u64 then
throw(math.domain_error("uint64.rem: division by zero"))
else
Rem = unchecked_rem(X, Y)
@@ -346,38 +346,15 @@ min(X, Y) =
:- pragma inline(even/1).
even(X) :-
- (X /\ cast_from_int(1)) = cast_from_int(0).
+ (X /\ 1u64) = 0u64.
:- pragma inline(odd/1).
odd(X) :-
- (X /\ cast_from_int(1)) \= cast_from_int(0).
+ (X /\ 1u64) \= 0u64.
%---------------------------------------------------------------------------%
-:- pragma foreign_proc("C",
- max_uint64 = (U64::out),
- [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
-"
- U64 = UINT64_MAX;
-").
-
-:- pragma foreign_proc("C#",
- max_uint64 = (U64::out),
- [will_not_call_mercury, promise_pure, thread_safe],
-"
- U64 = ulong.MaxValue;
-").
-
-:- pragma foreign_proc("Java",
- max_uint64 = (U64::out),
- [will_not_call_mercury, promise_pure, thread_safe],
-"
- U64 = 0xffffffffffffffffL;
-").
-
-:- pragma no_determinism_warning(max_uint64/0).
-max_uint64 = _ :-
- sorry($module, "uint64.max_uint64/1 NYI for Erlang").
+max_uint64 = 18_446_744_073_709_551_615_u64.
%---------------------------------------------------------------------------%
More information about the reviews
mailing list