repinfo.ads: Document new treatment of dynamic values.
authorEric Botcazou <ebotcazou@adacore.com>
Tue, 5 Sep 2017 08:40:09 +0000 (08:40 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 5 Sep 2017 08:40:09 +0000 (08:40 +0000)
* repinfo.ads: Document new treatment of dynamic values.
(TCode): Bump upper bound to 29.
(Dynamic_Val): New constant set to 29.
* repinfo.adb (Print_Expr) <Dynamic_Val>: New case.
(Rep_Value)  <Dynamic_Val>: Likewise.
* repinfo.h (Dynamic_Val): New macro.
* gcc-interface/decl.c (annotate_value): Tidy up and cache result for
DECL_P nodes too.
<INTEGER_CST>: Set TCODE instead of recursing.
<COMPONENT_REF>: Set TCODE instead of calling Create_Node manually.
<VAR_DECL>: New case.
<MULT_EXPR, PLUS_EXPR>: Fold conversions into inner operations.
<BIT_AND_EXPR>: Adjust.
<CALL_EXPR>: Do not fall through.

From-SVN: r251698

gcc/ada/ChangeLog
gcc/ada/gcc-interface/decl.c
gcc/ada/repinfo.adb
gcc/ada/repinfo.ads
gcc/ada/repinfo.h

index 9250acf0b9e6e8eeaaef631b22a9815c2cfe4890..40cc96557aa1a4c57f1384c407e1dc0b8ecf332a 100644 (file)
@@ -1,3 +1,20 @@
+2017-09-05  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * repinfo.ads: Document new treatment of dynamic values.
+       (TCode): Bump upper bound to 29.
+       (Dynamic_Val): New constant set to 29.
+       * repinfo.adb (Print_Expr) <Dynamic_Val>: New case.
+       (Rep_Value)  <Dynamic_Val>: Likewise.
+       * repinfo.h (Dynamic_Val): New macro.
+       * gcc-interface/decl.c (annotate_value): Tidy up and cache result for
+       DECL_P nodes too.
+       <INTEGER_CST>: Set TCODE instead of recursing.
+       <COMPONENT_REF>: Set TCODE instead of calling Create_Node manually.
+       <VAR_DECL>: New case.
+       <MULT_EXPR, PLUS_EXPR>: Fold conversions into inner operations.
+       <BIT_AND_EXPR>: Adjust.
+       <CALL_EXPR>: Do not fall through.
+
 2017-09-05  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gcc-interface/trans.c (Call_to_gnu): If this is a function call and
index ae4c6ec27b1774035d22aa9d9190e8e6c7f0cd6c..0a1796a6614b17e309ab2fe9c12ae85e99f305a3 100644 (file)
@@ -8047,13 +8047,13 @@ components_to_record (Node_Id gnat_component_list, Entity_Id gnat_record_type,
 static Uint
 annotate_value (tree gnu_size)
 {
+  static int var_count = 0;
   TCode tcode;
-  Node_Ref_Or_Val ops[3], ret, pre_op1 = No_Uint;
+  Node_Ref_Or_Val ops[3] = { No_Uint, No_Uint, No_Uint };
   struct tree_int_map in;
-  int i;
 
   /* See if we've already saved the value for this node.  */
-  if (EXPR_P (gnu_size))
+  if (EXPR_P (gnu_size) || DECL_P (gnu_size))
     {
       struct tree_int_map *e;
 
@@ -8067,9 +8067,7 @@ annotate_value (tree gnu_size)
     in.base.from = NULL_TREE;
 
   /* If we do not return inside this switch, TCODE will be set to the
-     code to use for a Create_Node operand and LEN (set above) will be
-     the number of recursive calls for us to make.  */
-
+     code to be used in a call to Create_Node.  */
   switch (TREE_CODE (gnu_size))
     {
     case INTEGER_CST:
@@ -8078,38 +8076,51 @@ annotate_value (tree gnu_size)
       if (tree_int_cst_sgn (gnu_size) < 0)
        {
          tree t = wide_int_to_tree (sizetype, wi::neg (gnu_size));
-         return annotate_value (build1 (NEGATE_EXPR, sizetype, t));
+         tcode = Negate_Expr;
+         ops[0] = UI_From_gnu (t);
        }
-
-      return TREE_OVERFLOW (gnu_size) ? No_Uint : UI_From_gnu (gnu_size);
+      else
+       return TREE_OVERFLOW (gnu_size) ? No_Uint : UI_From_gnu (gnu_size);
+      break;
 
     case COMPONENT_REF:
       /* The only case we handle here is a simple discriminant reference.  */
       if (DECL_DISCRIMINANT_NUMBER (TREE_OPERAND (gnu_size, 1)))
        {
-         tree n = DECL_DISCRIMINANT_NUMBER (TREE_OPERAND (gnu_size, 1));
+         tree ref = gnu_size;
+         gnu_size = TREE_OPERAND (ref, 1);
 
          /* Climb up the chain of successive extensions, if any.  */
-         while (TREE_CODE (TREE_OPERAND (gnu_size, 0)) == COMPONENT_REF
-                && DECL_NAME (TREE_OPERAND (TREE_OPERAND (gnu_size, 0), 1))
+         while (TREE_CODE (TREE_OPERAND (ref, 0)) == COMPONENT_REF
+                && DECL_NAME (TREE_OPERAND (TREE_OPERAND (ref, 0), 1))
                    == parent_name_id)
-           gnu_size = TREE_OPERAND (gnu_size, 0);
+           ref = TREE_OPERAND (ref, 0);
 
-         if (TREE_CODE (TREE_OPERAND (gnu_size, 0)) == PLACEHOLDER_EXPR)
-           return
-             Create_Node (Discrim_Val, annotate_value (n), No_Uint, No_Uint);
+         if (TREE_CODE (TREE_OPERAND (ref, 0)) == PLACEHOLDER_EXPR)
+           {
+             /* Fall through to common processing as a FIELD_DECL.  */
+             tcode = Discrim_Val;
+             ops[0] = UI_From_gnu (DECL_DISCRIMINANT_NUMBER (gnu_size));
+           }
+         else
+           return No_Uint;
        }
+      else
+       return No_Uint;
+      break;
 
-      return No_Uint;
+    case VAR_DECL:
+      tcode = Dynamic_Val;
+      ops[0] = UI_From_Int (++var_count);
+      break;
 
-    CASE_CONVERT:   case NON_LVALUE_EXPR:
+    CASE_CONVERT:
+    case NON_LVALUE_EXPR:
       return annotate_value (TREE_OPERAND (gnu_size, 0));
 
       /* Now just list the operations we handle.  */
     case COND_EXPR:            tcode = Cond_Expr; break;
-    case PLUS_EXPR:            tcode = Plus_Expr; break;
     case MINUS_EXPR:           tcode = Minus_Expr; break;
-    case MULT_EXPR:            tcode = Mult_Expr; break;
     case TRUNC_DIV_EXPR:       tcode = Trunc_Div_Expr; break;
     case CEIL_DIV_EXPR:                tcode = Ceil_Div_Expr; break;
     case FLOOR_DIV_EXPR:       tcode = Floor_Div_Expr; break;
@@ -8134,6 +8145,30 @@ annotate_value (tree gnu_size)
     case EQ_EXPR:              tcode = Eq_Expr; break;
     case NE_EXPR:              tcode = Ne_Expr; break;
 
+    case MULT_EXPR:
+    case PLUS_EXPR:
+      tcode = (TREE_CODE (gnu_size) == MULT_EXPR ? Mult_Expr : Plus_Expr);
+      /* Fold conversions from bytes to bits into inner operations.  */
+      if (TREE_CODE (TREE_OPERAND (gnu_size, 1)) == INTEGER_CST
+         && CONVERT_EXPR_P (TREE_OPERAND (gnu_size, 0)))
+       {
+         tree inner_op = TREE_OPERAND (TREE_OPERAND (gnu_size, 0), 0);
+         if (TREE_CODE (inner_op) == TREE_CODE (gnu_size)
+             && TREE_CODE (TREE_OPERAND (inner_op, 1)) == INTEGER_CST)
+           {
+             tree inner_op_op1 = TREE_OPERAND (inner_op, 1);
+             tree gnu_size_op1 = TREE_OPERAND (gnu_size, 1);
+             wide_int op1;
+             if (TREE_CODE (gnu_size) == MULT_EXPR)
+               op1 = wi::mul (inner_op_op1, gnu_size_op1);
+             else
+               op1 = wi::add (inner_op_op1, gnu_size_op1);
+             ops[1] = UI_From_gnu (wide_int_to_tree (sizetype, op1));
+             ops[0] = annotate_value (TREE_OPERAND (inner_op, 0));
+           }
+       }
+      break;
+
     case BIT_AND_EXPR:
       tcode = Bit_And_Expr;
       /* For negative values in sizetype, build NEGATE_EXPR of the opposite.
@@ -8146,7 +8181,7 @@ annotate_value (tree gnu_size)
          if (wi::neg_p (signed_op1))
            {
              op1 = wide_int_to_tree (sizetype, wi::neg (signed_op1));
-             pre_op1 = annotate_value (build1 (NEGATE_EXPR, sizetype, op1));
+             ops[1] = annotate_value (build1 (NEGATE_EXPR, sizetype, op1));
            }
        }
       break;
@@ -8158,34 +8193,26 @@ annotate_value (tree gnu_size)
       if (List_Representation_Info == 3 || type_annotate_only)
        {
          tree t = maybe_inline_call_in_expr (gnu_size);
-         if (t)
-           return annotate_value (t);
+         return t ? annotate_value (t) : No_Uint;
        }
       else
        return Uint_Minus_1;
 
-      /* Fall through... */
-
     default:
       return No_Uint;
     }
 
   /* Now get each of the operands that's relevant for this code.  If any
      cannot be expressed as a repinfo node, say we can't.  */
-  for (i = 0; i < 3; i++)
-    ops[i] = No_Uint;
-
-  for (i = 0; i < TREE_CODE_LENGTH (TREE_CODE (gnu_size)); i++)
-    {
-      if (i == 1 && pre_op1 != No_Uint)
-       ops[i] = pre_op1;
-      else
+  for (int i = 0; i < TREE_CODE_LENGTH (TREE_CODE (gnu_size)); i++)
+    if (ops[i] == No_Uint)
+      {
        ops[i] = annotate_value (TREE_OPERAND (gnu_size, i));
-      if (ops[i] == No_Uint)
-       return No_Uint;
-    }
+       if (ops[i] == No_Uint)
+         return No_Uint;
+      }
 
-  ret = Create_Node (tcode, ops[0], ops[1], ops[2]);
+  Node_Ref_Or_Val ret = Create_Node (tcode, ops[0], ops[1], ops[2]);
 
   /* Save the result in the cache.  */
   if (in.base.from)
@@ -8198,7 +8225,7 @@ annotate_value (tree gnu_size)
       h = annotate_value_cache->find_slot (&in, INSERT);
       gcc_assert (!*h);
       *h = ggc_alloc<tree_int_map> ();
-      (*h)->base.from = gnu_size;
+      (*h)->base.from = in.base.from;
       (*h)->to = ret;
     }
 
index 90bb6dacc23cec732cbff1ae522e89732beb8b2e..dbc5920566d4c7766ecd0cae6742aa2e2b348bab 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1999-2016, Free Software Foundation, Inc.         --
+--          Copyright (C) 1999-2017, 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- --
@@ -59,11 +59,11 @@ package body Repinfo is
    --  value is assumed to be 8 for the implementation of the DDA.
 
    ---------------------------------------
-   -- Representation of gcc Expressions --
+   -- Representation of GCC Expressions --
    ---------------------------------------
 
    --    This table is used only if Frontend_Layout_On_Target is False, so gigi
-   --    lays out dynamic size/offset fields using encoded gcc expressions.
+   --    lays out dynamic size/offset fields using encoded GCC expressions.
 
    --    A table internal to this unit is used to hold the values of back
    --    annotated expressions. This table is written out by -gnatt and read
@@ -643,6 +643,10 @@ package body Repinfo is
                   when Discrim_Val =>
                      Write_Char ('#');
                      UI_Write (Node.Op1);
+
+                  when Dynamic_Val =>
+                     Write_Str ("Var");
+                     UI_Write (Node.Op1);
                end case;
             end;
          end if;
@@ -1448,6 +1452,9 @@ package body Repinfo is
                         pragma Assert (Sub in D'Range);
                         return D (Sub);
                      end;
+
+                  when Dynamic_Val =>
+                     return No_Uint;
                end case;
             end;
          end if;
index 5654c1a0f300bd054a1658fdc4149864e8048b83..3dc48a013822734f06ff854ff43cccdd5991c308 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 S p e c                                  --
 --                                                                          --
---          Copyright (C) 1999-2014, Free Software Foundation, Inc.         --
+--          Copyright (C) 1999-2017, 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- --
@@ -83,7 +83,7 @@ package Repinfo is
    --    For E_Array_Type entities, the Component_Size field
 
    --    For all record and array types and subtypes, the Esize field,
-   --    which contains the Size (more accurately the Object_SIze) value
+   --    which contains the Size (more accurately the Object_Size) value
    --    for the type or subtype.
 
    --    For E_Component and E_Discriminant entities, the Esize (size
@@ -96,19 +96,19 @@ package Repinfo is
    --       by simply storing the non-negative universal integer value in
    --       the appropriate field corresponding to this constant size.
 
-   --    2. The value depends on variables other than discriminants of the
-   --       current record. In this case, the value is not known, even if
-   --       the complete data of the record is available, and gigi marks
-   --       this situation by storing the special value No_Uint.
-
-   --    3. The value depends on the discriminant values for the current
+   --    2. The value depends on the discriminant values for the current
    --       record. In this case, gigi back annotates the field with a
    --       representation of the expression for computing the value in
    --       terms of the discriminants. A negative Uint value is used to
    --       represent the value of such an expression, as explained in
    --       the following section.
 
-   --  Note: the extended back-annotation for the dynamic case is needed only
+   --    3. The value depends on variables other than discriminants of the
+   --       current record. In this case, gigi also back annotates the field
+   --       with a representation of the expression for computing the value
+   --       in terms of the variables represented symbolically.
+
+   --  Note: the extended back annotation for the dynamic case is needed only
    --  for -gnatR3 output, and for proper operation of the ASIS DDA. Since it
    --  can be expensive to do this back annotation (for discriminated records
    --  with many variable length arrays), we only do the full back annotation
@@ -136,7 +136,7 @@ package Repinfo is
    --  Subtype used for values that can either be a Node_Ref (negative)
    --  or a value (non-negative)
 
-   type TCode is range 0 .. 28;
+   type TCode is range 0 .. 29;
    --  Type used on Ada side to represent DEFTREECODE values defined in
    --  tree.def. Only a subset of these tree codes can actually appear.
    --  The names are the names from tree.def in Ada casing.
@@ -174,10 +174,17 @@ package Repinfo is
 
    --  The following entry is used to represent a discriminant value in
    --  the tree. It has a special tree code that does not correspond
-   --  directly to a gcc node. The single operand is the number of the
-   --  discriminant in the record (1 = first discriminant).
+   --  directly to a GCC node. The single operand is the index number
+   --  of the discriminant in the record (1 = first discriminant).
+
+   Discrim_Val      : constant TCode :=  0;  -- discriminant value      1
+
+   --  The following entry is used to represent a value not known at
+   --  compile time in the tree, other than a discriminant value. It
+   --  has a special tree code that does not correspond directly to
+   --  a GCC node. The single operand is an arbitrary index number.
 
-   Discrim_Val : constant TCode := 0;  -- discriminant value       1
+   Dynamic_Val      : constant TCode := 29;  -- dynamic value           1
 
    ------------------------
    -- The gigi Interface --
index 8d5ee6d652d9da15e83c9f8dda15437f50cb0727..7f1fdf6fd860315fe2d9d18e65540a8a208b28c1 100644 (file)
@@ -6,7 +6,7 @@
  *                                                                          *
  *                              C Header File                               *
  *                                                                          *
- *          Copyright (C) 1999-2011, Free Software Foundation, Inc.         *
+ *          Copyright (C) 1999-2017, 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- *
@@ -71,6 +71,7 @@ typedef char TCode;
 #define Eq_Expr          26
 #define Ne_Expr          27
 #define Bit_And_Expr     28
+#define Dynamic_Val      29
 
 /* Creates a node using the tree code defined by Expr and from 1-3
    operands as required (unused operands set as shown to No_Uint) Note