[Ada] Enhance constraints propagation to ease the work of optimizers
authorEd Schonberg <schonberg@adacore.com>
Wed, 14 Nov 2018 11:41:30 +0000 (11:41 +0000)
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>
Wed, 14 Nov 2018 11:41:30 +0000 (11:41 +0000)
commit43018f5892ff43551abad3f339bcb55cf74c89cf
tree6bddd0ffa47a3dedf019d429021686a9e9e10bbd
parentc786216724918a454ed4634031f69efd275b963e
[Ada] Enhance constraints propagation to ease the work of optimizers

This patch recognizes additional object declarations whose defining
identifier is known statically to be valid. This allows additional
optimizations to be performed by the front-end.

Executing:

   gcc -c -gnatDG p.ads

On the following sources:

----
with G;
With Q;

package P is

  Val : constant Positive := Q.Config_Value ("Size");

  package My_G is new G (Val);

end P;
----
generic

  Num : Natural := 0;

package G is

  Multi : constant Boolean := Num > 0;

  type Info is array (True .. Multi) of Integer;

  type Arr is array (Natural range <>) of Boolean;

  type Rec (D : Natural) is record
    C : character;
    I : Info;
    E : Arr (0 .. D);
  end record;

end G;
----
package Q is

  function Config_Value (S : String) return Integer;

end Q;
----

Must yield (note that variable Multi has been statically optimized to
true):

----
with g;
with q;
p_E : short_integer := 0;

package p is
   p__R2s : constant integer := q.q__config_value ("Size");
   [constraint_error when
     not (p__R2s >= 1)
     "range check failed"]
   p__val : constant positive := p__R2s;

   package p__my_g is
      p__my_g__num : constant natural := p__val;
      package p__my_g__g renames p__my_g;
      package p__my_g__gGH renames p__my_g__g;
      p__my_g__multi : constant boolean := true;
      type p__my_g__info is array (true .. p__my_g__multi) of integer;
      type p__my_g__arr is array (0 .. 16#7FFF_FFFF# range <>) of
        boolean;
      type p__my_g__rec (d : natural) is record
         c : character;
         i : p__my_g__info;
         e : p__my_g__arr (0 .. d);
      end record;
      [type p__my_g__TinfoB is array (true .. p__my_g__multi range <>) of
        integer]
      freeze p__my_g__TinfoB [
         procedure p__my_g__TinfoBIP (_init : in out p__my_g__TinfoB) is
         begin
            null;
            return;
         end p__my_g__TinfoBIP;
      ]
      freeze p__my_g__info []
      freeze p__my_g__arr [
         procedure p__my_g__arrIP (_init : in out p__my_g__arr) is
         begin
            null;
            return;
         end p__my_g__arrIP;
      ]
      freeze p__my_g__rec [
         procedure p__my_g__recIP (_init : in out p__my_g__rec; d :
           natural) is
         begin
            _init.d := d;
            null;
            return;
         end p__my_g__recIP;
      ]
   end p__my_g;

   package my_g is new g (p__val);
end p;

freeze_generic info
[subtype TinfoD1 is boolean range true .. multi]
freeze_generic TinfoD1
[type TinfoB is array (true .. multi range <>) of integer]
freeze_generic TinfoB
freeze_generic arr
freeze_generic rec
----

2018-11-14  Ed Schonberg  <schonberg@adacore.com>

gcc/ada/

* sem_ch3.adb (Analyze_Object_Declaration): Use the
Actual_Subtype to preserve information about a constant
initialized with a non-static entity that is known to be valid,
when the type of the entity has a narrower range than that of
the nominal subtype of the constant.
* checks.adb (Determine_Range): If the expression is a constant
entity that is known-valid and has a defined Actual_Subtype, use
it to determine the actual bounds of the value, to enable
additional optimizations.

From-SVN: r266123
gcc/ada/ChangeLog
gcc/ada/checks.adb
gcc/ada/sem_ch3.adb