utils2.c (build_binary_op): Add a NO_FOLD argument.
authorPierre-Marie de Rodat <derodat@adacore.com>
Tue, 11 Oct 2016 10:19:39 +0000 (10:19 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 11 Oct 2016 10:19:39 +0000 (10:19 +0000)
* gcc-interface/utils2.c (build_binary_op): Add a NO_FOLD
argument.  Disable folding when true.
* gcc-interface/gigi.h (choices_to_gnu): Remove declaration.
(build_binary_op): Update signature and comment.
* gcc-interface/decl.c (choices_to_gnu): Make static.  Disable
folding for all calls to build_binary_op.

From-SVN: r240978

gcc/ada/ChangeLog
gcc/ada/gcc-interface/decl.c
gcc/ada/gcc-interface/gigi.h
gcc/ada/gcc-interface/utils2.c

index d73db7bec6e5ea9ad120019f9f0861e6cd09d1ed..6b3b9e069742347f0c54c90bfa71a17a3fd17a8a 100644 (file)
@@ -1,3 +1,12 @@
+2016-10-11  Pierre-Marie de Rodat  <derodat@adacore.com>
+
+       * gcc-interface/utils2.c (build_binary_op): Add a NO_FOLD
+       argument.  Disable folding when true.
+       * gcc-interface/gigi.h (choices_to_gnu): Remove declaration.
+       (build_binary_op): Update signature and comment.
+       * gcc-interface/decl.c (choices_to_gnu): Make static.  Disable
+       folding for all calls to build_binary_op.
+
 2016-10-11  Tristan Gingold  <gingold@adacore.com>
 
        * fe.h (Constant_Value): Declare.
index 58d6625dcaa2f649c79a75370cb33db895c0a84c..3aaaaca73eda5109d8f9e3e6fba366b0d5f36857 100644 (file)
@@ -6832,7 +6832,7 @@ elaborate_reference (tree ref, Entity_Id gnat_entity, bool definition,
 /* Given a GNU tree and a GNAT list of choices, generate an expression to test
    the value passed against the list of choices.  */
 
-tree
+static tree
 choices_to_gnu (tree operand, Node_Id choices)
 {
   Node_Id choice;
@@ -6851,9 +6851,10 @@ choices_to_gnu (tree operand, Node_Id choices)
          this_test
            = build_binary_op (TRUTH_ANDIF_EXPR, boolean_type_node,
                               build_binary_op (GE_EXPR, boolean_type_node,
-                                               operand, low),
+                                               operand, low, true),
                               build_binary_op (LE_EXPR, boolean_type_node,
-                                               operand, high));
+                                               operand, high, true),
+                              true);
 
          break;
 
@@ -6865,9 +6866,10 @@ choices_to_gnu (tree operand, Node_Id choices)
          this_test
            = build_binary_op (TRUTH_ANDIF_EXPR, boolean_type_node,
                               build_binary_op (GE_EXPR, boolean_type_node,
-                                               operand, low),
+                                               operand, low, true),
                               build_binary_op (LE_EXPR, boolean_type_node,
-                                               operand, high));
+                                               operand, high, true),
+                              true);
          break;
 
        case N_Identifier:
@@ -6886,9 +6888,10 @@ choices_to_gnu (tree operand, Node_Id choices)
              this_test
                = build_binary_op (TRUTH_ANDIF_EXPR, boolean_type_node,
                                   build_binary_op (GE_EXPR, boolean_type_node,
-                                                   operand, low),
+                                                   operand, low, true),
                                   build_binary_op (LE_EXPR, boolean_type_node,
-                                                   operand, high));
+                                                   operand, high, true),
+                                  true);
              break;
            }
 
@@ -6898,7 +6901,7 @@ choices_to_gnu (tree operand, Node_Id choices)
        case N_Integer_Literal:
          single = gnat_to_gnu (choice);
          this_test = build_binary_op (EQ_EXPR, boolean_type_node, operand,
-                                      single);
+                                      single, true);
          break;
 
        case N_Others_Choice:
@@ -6909,8 +6912,11 @@ choices_to_gnu (tree operand, Node_Id choices)
          gcc_unreachable ();
        }
 
-      result = build_binary_op (TRUTH_ORIF_EXPR, boolean_type_node, result,
-                               this_test);
+      if (result == boolean_false_node)
+       result = this_test;
+      else
+       result = build_binary_op (TRUTH_ORIF_EXPR, boolean_type_node, result,
+                                 this_test, true);
     }
 
   return result;
index b4fa83f28c282b5d4be1bcbf193589a6f7c6268b..b001b405fe07fa9b5e9965f5f396a11385e18750 100644 (file)
@@ -174,10 +174,6 @@ enum alias_set_op
 extern void relate_alias_sets (tree gnu_new_type, tree gnu_old_type,
                               enum alias_set_op op);
 
-/* Given a GNU tree and a GNAT list of choices, generate an expression to test
-   the value passed against the list of choices.  */
-extern tree choices_to_gnu (tree operand, Node_Id choices);
-
 /* Given GNAT_ENTITY, an object (constant, variable, parameter, exception)
    and GNU_TYPE, its corresponding GCC type, set Esize and Alignment to the
    size and alignment used by Gigi.  Prefer SIZE over TYPE_SIZE if non-null.
@@ -860,9 +856,11 @@ extern tree build_load_modify_store (tree dest, tree src, Node_Id gnat_node);
 /* Make a binary operation of kind OP_CODE.  RESULT_TYPE is the type
    desired for the result.  Usually the operation is to be performed
    in that type.  For MODIFY_EXPR and ARRAY_REF, RESULT_TYPE may be 0
-   in which case the type to be used will be derived from the operands.  */
+   in which case the type to be used will be derived from the operands.
+   Don't fold the result if NO_FOLD is true.  */
 extern tree build_binary_op (enum tree_code op_code, tree result_type,
-                             tree left_operand, tree right_operand);
+                            tree left_operand, tree right_operand,
+                            bool no_fold=false);
 
 /* Similar, but make unary operation.  */
 extern tree build_unary_op (enum tree_code op_code, tree result_type,
index b820fea28b75d752b389d3f771382c3da763ee91..9ace387b85aa19f5df39762f3cf652c7528a4a6f 100644 (file)
@@ -834,6 +834,7 @@ build_load_modify_store (tree dest, tree src, Node_Id gnat_node)
    in that type.  For INIT_EXPR and MODIFY_EXPR, RESULT_TYPE must be
    NULL_TREE.  For ARRAY_REF, RESULT_TYPE may be NULL_TREE, in which
    case the type to be used will be derived from the operands.
+   Don't fold the result if NO_FOLD is true.
 
    This function is very much unlike the ones for C and C++ since we
    have already done any type conversion and matching required.  All we
@@ -841,7 +842,8 @@ build_load_modify_store (tree dest, tree src, Node_Id gnat_node)
 
 tree
 build_binary_op (enum tree_code op_code, tree result_type,
-                 tree left_operand, tree right_operand)
+                tree left_operand, tree right_operand,
+                bool no_fold)
 {
   tree left_type = TREE_TYPE (left_operand);
   tree right_type = TREE_TYPE (right_operand);
@@ -1283,10 +1285,16 @@ build_binary_op (enum tree_code op_code, tree result_type,
   else if (TREE_CODE (right_operand) == NULL_EXPR)
     return build1 (NULL_EXPR, operation_type, TREE_OPERAND (right_operand, 0));
   else if (op_code == ARRAY_REF || op_code == ARRAY_RANGE_REF)
-    result = fold (build4 (op_code, operation_type, left_operand,
-                          right_operand, NULL_TREE, NULL_TREE));
+    {
+      result = build4 (op_code, operation_type, left_operand, right_operand,
+                      NULL_TREE, NULL_TREE);
+      if (!no_fold)
+       result = fold (result);
+    }
   else if (op_code == INIT_EXPR || op_code == MODIFY_EXPR)
     result = build2 (op_code, void_type_node, left_operand, right_operand);
+  else if (no_fold)
+    result = build2 (op_code, operation_type, left_operand, right_operand);
   else
     result
       = fold_build2 (op_code, operation_type, left_operand, right_operand);
@@ -1307,8 +1315,13 @@ build_binary_op (enum tree_code op_code, tree result_type,
   /* If we are working with modular types, perform the MOD operation
      if something above hasn't eliminated the need for it.  */
   if (modulus)
-    result = fold_build2 (FLOOR_MOD_EXPR, operation_type, result,
-                         convert (operation_type, modulus));
+    {
+      modulus = convert (operation_type, modulus);
+      if (no_fold)
+       result = build2 (FLOOR_MOD_EXPR, operation_type, result, modulus);
+      else
+       result = fold_build2 (FLOOR_MOD_EXPR, operation_type, result, modulus);
+    }
 
   if (result_type && result_type != operation_type)
     result = convert (result_type, result);