[Ada] Optimize magnitude of integer operations for fixed point
authorEric Botcazou <ebotcazou@adacore.com>
Sat, 31 Oct 2020 11:41:18 +0000 (12:41 +0100)
committerPierre-Marie de Rodat <derodat@adacore.com>
Fri, 27 Nov 2020 09:15:38 +0000 (04:15 -0500)
gcc/ada/

* exp_fixd.adb (Build_Double_Divide): Use the RM size of types and
a more precise estimate for the size of the denominator.
(Build_Double_Divide_Code): Likewise.
(Build_Multiply): Use a more precise estimate for the size of the
result.
(Build_Scaled_Divide):  Use the RM size of types and a more precise
estimate for the size of the numerator.
(Build_Scaled_Divide_Code): Likewise.

gcc/ada/exp_fixd.adb

index d6819699c0caeb7d208b5988d28a19232063d871..a3705694f559a7f87598b69a547769d3600cbc1b 100644 (file)
@@ -448,15 +448,15 @@ package body Exp_Fixd is
      (N       : Node_Id;
       X, Y, Z : Node_Id) return Node_Id
    is
-      Y_Size : constant Nat := UI_To_Int (Esize (Etype (Y)));
-      Z_Size : constant Nat := UI_To_Int (Esize (Etype (Z)));
+      Y_Size : constant Nat := UI_To_Int (RM_Size (Etype (Y)));
+      Z_Size : constant Nat := UI_To_Int (RM_Size (Etype (Z)));
       Expr   : Node_Id;
 
    begin
       --  If the denominator fits in Max_Integer_Size bits, we can build the
       --  operations directly without causing any intermediate overflow.
 
-      if 2 * Nat'Max (Y_Size, Z_Size) <= System_Max_Integer_Size then
+      if Y_Size + Z_Size <= System_Max_Integer_Size then
          return Build_Divide (N, X, Build_Multiply (N, Y, Z));
 
       --  Otherwise we use the runtime routine
@@ -516,9 +516,9 @@ package body Exp_Fixd is
    is
       Loc    : constant Source_Ptr := Sloc (N);
 
-      X_Size : constant Nat := UI_To_Int (Esize (Etype (X)));
-      Y_Size : constant Nat := UI_To_Int (Esize (Etype (Y)));
-      Z_Size : constant Nat := UI_To_Int (Esize (Etype (Z)));
+      X_Size : constant Nat := UI_To_Int (RM_Size (Etype (X)));
+      Y_Size : constant Nat := UI_To_Int (RM_Size (Etype (Y)));
+      Z_Size : constant Nat := UI_To_Int (RM_Size (Etype (Z)));
 
       QR_Id  : RE_Id;
       QR_Siz : Nat;
@@ -533,7 +533,7 @@ package body Exp_Fixd is
    begin
       --  Find type that will allow computation of denominator
 
-      QR_Siz := Nat'Max (X_Size, 2 * Nat'Max (Y_Size, Z_Size));
+      QR_Siz := Nat'Max (X_Size, Y_Size + Z_Size);
 
       if QR_Siz <= 16 then
          QR_Typ := Standard_Integer_16;
@@ -724,10 +724,10 @@ package body Exp_Fixd is
             end;
          end if;
 
-         --  Now the result size must be at least twice the longer of
-         --  the two sizes, to accommodate all possible results.
+         --  Now the result size must be at least the sum of the two sizes,
+         --  to accommodate all possible results.
 
-         Rsize := 2 * Int'Max (Left_Size, Right_Size);
+         Rsize := Left_Size + Right_Size;
 
          if Rsize <= 8 then
             Result_Type := Standard_Integer_8;
@@ -828,15 +828,15 @@ package body Exp_Fixd is
      (N       : Node_Id;
       X, Y, Z : Node_Id) return Node_Id
    is
-      X_Size : constant Nat := UI_To_Int (Esize (Etype (X)));
-      Y_Size : constant Nat := UI_To_Int (Esize (Etype (Y)));
+      X_Size : constant Nat := UI_To_Int (RM_Size (Etype (X)));
+      Y_Size : constant Nat := UI_To_Int (RM_Size (Etype (Y)));
       Expr   : Node_Id;
 
    begin
       --  If the numerator fits in Max_Integer_Size bits, we can build the
       --  operations directly without causing any intermediate overflow.
 
-      if 2 * Nat'Max (X_Size, Y_Size) <= System_Max_Integer_Size then
+      if X_Size + Y_Size <= System_Max_Integer_Size then
          return Build_Divide (N, Build_Multiply (N, X, Y), Z);
 
       --  Otherwise we use the runtime routine
@@ -893,9 +893,9 @@ package body Exp_Fixd is
    is
       Loc    : constant Source_Ptr := Sloc (N);
 
-      X_Size : constant Nat := UI_To_Int (Esize (Etype (X)));
-      Y_Size : constant Nat := UI_To_Int (Esize (Etype (Y)));
-      Z_Size : constant Nat := UI_To_Int (Esize (Etype (Z)));
+      X_Size : constant Nat := UI_To_Int (RM_Size (Etype (X)));
+      Y_Size : constant Nat := UI_To_Int (RM_Size (Etype (Y)));
+      Z_Size : constant Nat := UI_To_Int (RM_Size (Etype (Z)));
 
       QR_Id  : RE_Id;
       QR_Siz : Nat;
@@ -910,7 +910,7 @@ package body Exp_Fixd is
    begin
       --  Find type that will allow computation of numerator
 
-      QR_Siz := Nat'Max (2 * Nat'Max (X_Size, Y_Size), Z_Size);
+      QR_Siz := Nat'Max (X_Size + Y_Size, Z_Size);
 
       if QR_Siz <= 16 then
          QR_Typ := Standard_Integer_16;