[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