]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: decl.c (annotate_value): Tidy up.
authorEric Botcazou <ebotcazou@adacore.com>
Wed, 6 Feb 2019 23:28:34 +0000 (23:28 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Wed, 6 Feb 2019 23:28:34 +0000 (23:28 +0000)
Backport from mainline
2017-09-05  Eric Botcazou  <ebotcazou@adacore.com>

* gcc-interface/decl.c (annotate_value): Tidy up.
<INTEGER_CST>: Set TCODE instead of recursing.
<COMPONENT_REF>: Set TCODE instead of calling Create_Node manually.
<MULT_EXPR, PLUS_EXPR>: Fold conversions into inner operations.
<BIT_AND_EXPR>: Adjust.
<CALL_EXPR>: Do not fall through.

From-SVN: r268598

gcc/ada/ChangeLog
gcc/ada/gcc-interface/decl.c

index e5adc7f53e0eeb9710c361b0d9810e69ee5dd787..a0b7692fa41d95a70024a1a943b77135aaeafdef 100644 (file)
@@ -1,3 +1,15 @@
+2019-02-06  Eric Botcazou  <ebotcazou@adacore.com>
+
+       Backport from mainline
+       2017-09-05  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc-interface/decl.c (annotate_value): Tidy up.
+       <INTEGER_CST>: Set TCODE instead of recursing.
+       <COMPONENT_REF>: Set TCODE instead of calling Create_Node manually.
+       <MULT_EXPR, PLUS_EXPR>: Fold conversions into inner operations.
+       <BIT_AND_EXPR>: Adjust.
+       <CALL_EXPR>: Do not fall through.
+
 2019-01-27  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gcc-interface/decl.c (array_type_has_nonaliased_component): Return
index acd7fc5ddc88057b76a5e2ceb994822f42ef5394..ebc441ccc94be149f35444e229c2e818e3550ae5 100644 (file)
@@ -8048,9 +8048,8 @@ static Uint
 annotate_value (tree gnu_size)
 {
   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))
@@ -8067,9 +8066,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:
@@ -8079,37 +8076,46 @@ annotate_value (tree gnu_size)
       if (tree_int_cst_sign_bit (gnu_size))
        {
          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_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 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;
@@ -8140,11 +8146,39 @@ annotate_value (tree gnu_size)
          && tree_int_cst_sign_bit (TREE_OPERAND (gnu_size, 1)))
        {
          tcode = Minus_Expr;
+         ops[0] = annotate_value (TREE_OPERAND (gnu_size, 0));
          wide_int op1 = wi::neg (TREE_OPERAND (gnu_size, 1));
-         pre_op1 = annotate_value (wide_int_to_tree (sizetype, op1));
+         ops[1] = annotate_value (wide_int_to_tree (sizetype, op1));
+         break;
+       }
+
+      /* ... fall through ... */
+
+    case MULT_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)
+           {
+             ops[0] = annotate_value (TREE_OPERAND (inner_op, 0));
+             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);
+                 if (wi::zext (op1, TYPE_PRECISION (sizetype)) == 0)
+                   return ops[0];
+               }
+             ops[1] = annotate_value (wide_int_to_tree (sizetype, op1));
+           }
        }
-      else
-       tcode = Plus_Expr;
       break;
 
     case BIT_AND_EXPR:
@@ -8155,7 +8189,7 @@ annotate_value (tree gnu_size)
        {
          wide_int op1 = wi::sext (TREE_OPERAND (gnu_size, 1),
                                   TYPE_PRECISION (sizetype));
-         pre_op1 = annotate_value (wide_int_to_tree (sizetype, op1));
+         ops[1] = annotate_value (wide_int_to_tree (sizetype, op1));
        }
       break;
 
@@ -8166,34 +8200,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)
@@ -8206,7 +8232,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;
     }