Patchwork [Ada] Remove Dint (code cleanup)

login
register
mail settings
Submitter Arnaud Charlet
Date June 22, 2010, 1:54 p.m.
Message ID <20100622135409.GA3512@adacore.com>
Download mbox | patch
Permalink /patch/56502/
State New
Headers show

Comments

Arnaud Charlet - June 22, 2010, 1:54 p.m.
This patch removes the type Dint from types.ads, which was only
used in UI_From_Dint, which was itself only used internally in
Uintp, and easily eliminated. This cleanup seems appropriate
given that Dint was not really used, and general convention is
to avoid the requirement for 64-bit host integers in C, so it
seems reasonable to follow this convention in Ada as well, and
this was the only violation. No test needed, since no functional
behavior change from this patch.

Tested on x86_64-pc-linux-gnu, committed on trunk

2010-06-22  Robert Dewar  <dewar@adacore.com>

	* types.ads: (Dint): Removed, no longer used anywhere.
	* uintp.adb (UI_From_CC): Use UI_From_Int, range is sufficient.
	(UI_Mul): Avoid use of UI_From_Dint.
	(UI_From_Dint): Removed, not used.
	* uintp.ads (UI_From_Dint): Removed, not used.
	(Uint_Min/Max_Simple_Mul): New constants.

Patch

Index: types.ads
===================================================================
--- types.ads	(revision 161073)
+++ types.ads	(working copy)
@@ -59,9 +59,6 @@  package Types is
    type Int is range -2 ** 31 .. +2 ** 31 - 1;
    --  Signed 32-bit integer
 
-   type Dint is range -2 ** 63 .. +2 ** 63 - 1;
-   --  Double length (64-bit) integer
-
    subtype Nat is Int range 0 .. Int'Last;
    --  Non-negative Int values
 
@@ -506,7 +503,7 @@  package Types is
    --  The type Char is used for character data internally in the compiler, but
    --  character codes in the source are represented by the Char_Code type.
    --  Each character literal in the source is interpreted as being one of the
-   --  16#8000_0000 possible Wide_Wide_Character codes, and a unique Integer
+   --  16#7FFF_FFFF possible Wide_Wide_Character codes, and a unique Integer
    --  Value is assigned, corresponding to the UTF_32 value, which also
    --  corresponds to the POS value in the Wide_Wide_Character type, and also
    --  corresponds to the POS value in the Wide_Character and Character types
Index: uintp.adb
===================================================================
--- uintp.adb	(revision 161179)
+++ uintp.adb	(working copy)
@@ -168,13 +168,15 @@  package body Uintp is
      (Left, Right       : Uint;
       Quotient          : out Uint;
       Remainder         : out Uint;
-      Discard_Quotient  : Boolean;
-      Discard_Remainder : Boolean);
-   --  Compute Euclidean division of Left by Right, and return Quotient and
-   --  signed Remainder (Left rem Right).
+      Discard_Quotient  : Boolean := False;
+      Discard_Remainder : Boolean := False);
+   --  Compute Euclidean division of Left by Right. If Discard_Quotient is
+   --  False then the quotient is returned in Quotient (otherwise Quotient is
+   --  set to No_Uint). If Discard_Remainder is False, then the remainder is
+   --  returned in Remainder (otherwise Remainder is set to No_Uint).
    --
-   --    If Discard_Quotient is True, Quotient is left unchanged.
-   --    If Discard_Remainder is True, Remainder is left unchanged.
+   --  If Discard_Quotient is True, Quotient is set to No_Uint
+   --  If Discard_Remainder is True, Remainder is set to No_Uint
 
    function Vector_To_Uint
      (In_Vec   : UI_Vector;
@@ -1253,7 +1255,6 @@  package body Uintp is
       UI_Div_Rem
         (Left, Right,
          Quotient, Remainder,
-         Discard_Quotient  => False,
          Discard_Remainder => True);
       return Quotient;
    end UI_Div;
@@ -1266,14 +1267,17 @@  package body Uintp is
      (Left, Right       : Uint;
       Quotient          : out Uint;
       Remainder         : out Uint;
-      Discard_Quotient  : Boolean;
-      Discard_Remainder : Boolean)
+      Discard_Quotient  : Boolean := False;
+      Discard_Remainder : Boolean := False)
    is
       pragma Warnings (Off, Quotient);
       pragma Warnings (Off, Remainder);
    begin
       pragma Assert (Right /= Uint_0);
 
+      Quotient  := No_Uint;
+      Remainder := No_Uint;
+
       --  Cases where both operands are represented directly
 
       if Direct (Left) and then Direct (Right) then
@@ -1682,43 +1686,9 @@  package body Uintp is
 
    function UI_From_CC (Input : Char_Code) return Uint is
    begin
-      return UI_From_Dint (Dint (Input));
+      return UI_From_Int (Int (Input));
    end UI_From_CC;
 
-   ------------------
-   -- UI_From_Dint --
-   ------------------
-
-   function UI_From_Dint (Input : Dint) return Uint is
-   begin
-
-      if Dint (Min_Direct) <= Input and then Input <= Dint (Max_Direct) then
-         return Uint (Dint (Uint_Direct_Bias) + Input);
-
-      --  For values of larger magnitude, compute digits into a vector and call
-      --  Vector_To_Uint.
-
-      else
-         declare
-            Max_For_Dint : constant := 5;
-            --  Base is defined so that 5 Uint digits is sufficient to hold the
-            --  largest possible Dint value.
-
-            V : UI_Vector (1 .. Max_For_Dint);
-
-            Temp_Integer : Dint := Input;
-
-         begin
-            for J in reverse V'Range loop
-               V (J) := Int (abs (Temp_Integer rem Dint (Base)));
-               Temp_Integer := Temp_Integer / Dint (Base);
-            end loop;
-
-            return Vector_To_Uint (V, Input < Dint'(0));
-         end;
-      end if;
-   end UI_From_Dint;
-
    -----------------
    -- UI_From_Int --
    -----------------
@@ -2191,11 +2161,7 @@  package body Uintp is
       Y := Uint_0;
 
       loop
-         UI_Div_Rem
-           (U, V,
-            Quotient => Q, Remainder => R,
-            Discard_Quotient  => False,
-            Discard_Remainder => False);
+         UI_Div_Rem (U, V, Quotient => Q, Remainder => R);
 
          U := V;
          V := R;
@@ -2232,12 +2198,15 @@  package body Uintp is
 
    function UI_Mul (Left : Uint; Right : Uint) return Uint is
    begin
-      --  Simple case of single length operands
+      --  Case where product fits in the range of a 32-bit integer
 
-      if Direct (Left) and then Direct (Right) then
+      if Int (Left)  <= Int (Uint_Max_Simple_Mul)
+           and then
+         Int (Right) <= Int (Uint_Max_Simple_Mul)
+      then
          return
-           UI_From_Dint
-             (Dint (Direct_Val (Left)) * Dint (Direct_Val (Right)));
+           UI_From_Int
+             (Int (Direct_Val (Left)) * Int (Direct_Val (Right)));
       end if;
 
       --  Otherwise we have the general case (Algorithm M in Knuth)
@@ -2560,9 +2529,7 @@  package body Uintp is
          pragma Warnings (Off, Quotient);
       begin
          UI_Div_Rem
-           (Left, Right, Quotient, Remainder,
-            Discard_Quotient  => True,
-            Discard_Remainder => False);
+           (Left, Right, Quotient, Remainder, Discard_Quotient  => True);
          return Remainder;
       end;
    end UI_Rem;
Index: uintp.ads
===================================================================
--- uintp.ads	(revision 161073)
+++ uintp.ads	(working copy)
@@ -6,7 +6,7 @@ 
 --                                                                          --
 --                                 S p e c                                  --
 --                                                                          --
---          Copyright (C) 1992-2009  Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2010, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -233,9 +233,6 @@  package Uintp is
    --  given Modulo (uses Euclid's algorithm). Note: the call is considered
    --  to be erroneous (and the behavior is undefined) if n is not invertible.
 
-   function UI_From_Dint (Input : Dint) return Uint;
-   --  Converts Dint value to universal integer form
-
    function UI_From_Int (Input : Int) return Uint;
    --  Converts Int value to universal integer form
 
@@ -404,7 +401,8 @@  private
    --  Base is defined to allow efficient execution of the primitive operations
    --  (a0, b0, c0) defined in the section "The Classical Algorithms"
    --  (sec. 4.3.1) of Donald Knuth's "The Art of Computer  Programming",
-   --  Vol. 2. These algorithms are used in this package.
+   --  Vol. 2. These algorithms are used in this package. In particular,
+   --  the product of two single digits in this base fits in a 32-bit integer.
 
    Base_Bits : constant := 15;
    --  Number of bits in base value
@@ -470,6 +468,11 @@  private
    Uint_Minus_80  : constant Uint := Uint (Uint_Direct_Bias - 80);
    Uint_Minus_128 : constant Uint := Uint (Uint_Direct_Bias - 128);
 
+   Uint_Max_Simple_Mul : constant := Uint_Direct_Bias + 2 ** 15;
+   --  If two values are directly represented and less than or equal to this
+   --  value, then we know the product fits in a 32-bit integer. This allows
+   --  UI_Mul to efficiently compute the product in this case.
+
    type Save_Mark is record
       Save_Uint   : Uint;
       Save_Udigit : Int;