diff mbox

[Ada] Get rid of useless index checks generated for modular types

Message ID 1494598.EMFIPyuDMi@polaris
State New
Headers show

Commit Message

Eric Botcazou Jan. 21, 2017, 11:10 a.m. UTC
This fixes the pessimization introduced by yesterday's change to the function,
which resulted in useless index checks generated for simple loops running over 
modular types and the couple of regressions in the gnat.dg testsuite.

Tested on x86_64-suse-linux, applied on the mainline.


2017-01-21  Eric Botcazou  <ebotcazou@adacore.com>

	* sem_eval.adb (Compile_Time_Compare): Reinstate the expr+literal
	optimizations when the type is modular and the offsets are equal.
diff mbox

Patch

Index: sem_eval.adb
===================================================================
--- sem_eval.adb	(revision 244741)
+++ sem_eval.adb	(working copy)
@@ -1329,26 +1329,29 @@  package body Sem_Eval is
          --  J .. J + 1. This code can conclude LT with a difference of 1,
          --  even if the range of J is not known.
 
-         --  This would be wrong for modular types (e.g. X < X + 1 is False if
-         --  X is the largest number).
+         declare
+            Lnode : Node_Id;
+            Loffs : Uint;
+            Rnode : Node_Id;
+            Roffs : Uint;
+
+         begin
+            Compare_Decompose (L, Lnode, Loffs);
+            Compare_Decompose (R, Rnode, Roffs);
+
+            if Is_Same_Value (Lnode, Rnode) then
+               if Loffs = Roffs then
+                  return EQ;
+               end if;
 
-         if not Is_Modular_Integer_Type (Ltyp)
-           and then not Is_Modular_Integer_Type (Rtyp)
-         then
-            declare
-               Lnode : Node_Id;
-               Loffs : Uint;
-               Rnode : Node_Id;
-               Roffs : Uint;
-
-            begin
-               Compare_Decompose (L, Lnode, Loffs);
-               Compare_Decompose (R, Rnode, Roffs);
-
-               if Is_Same_Value (Lnode, Rnode) then
-                  if Loffs = Roffs then
-                     return EQ;
-                  elsif Loffs < Roffs then
+               --  When the offsets are not equal, we can go farther only if
+               --  the types are not modular (e.g. X < X + 1 is False if X is
+               --  the largest number).
+
+               if not Is_Modular_Integer_Type (Ltyp)
+                 and then not Is_Modular_Integer_Type (Rtyp)
+               then
+                  if Loffs < Roffs then
                      Diff.all := Roffs - Loffs;
                      return LT;
                   else
@@ -1356,8 +1359,8 @@  package body Sem_Eval is
                      return GT;
                   end if;
                end if;
-            end;
-         end if;
+            end if;
+         end;
 
          --  Next, try range analysis and see if operand ranges are disjoint