From 08ef2c16779f0f1814cc1f49bf53e7504942f079 Mon Sep 17 00:00:00 2001 From: Pierre-Marie de Rodat Date: Tue, 11 Oct 2016 10:19:39 +0000 Subject: [PATCH] utils2.c (build_binary_op): Add a NO_FOLD argument. * 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 | 9 +++++++++ gcc/ada/gcc-interface/decl.c | 26 ++++++++++++++++---------- gcc/ada/gcc-interface/gigi.h | 10 ++++------ gcc/ada/gcc-interface/utils2.c | 23 ++++++++++++++++++----- 4 files changed, 47 insertions(+), 21 deletions(-) diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index d73db7bec6e..6b3b9e06974 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,12 @@ +2016-10-11 Pierre-Marie de Rodat + + * 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 * fe.h (Constant_Value): Declare. diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 58d6625dcaa..3aaaaca73ed 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -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; diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h index b4fa83f28c2..b001b405fe0 100644 --- a/gcc/ada/gcc-interface/gigi.h +++ b/gcc/ada/gcc-interface/gigi.h @@ -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, diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c index b820fea28b7..9ace387b85a 100644 --- a/gcc/ada/gcc-interface/utils2.c +++ b/gcc/ada/gcc-interface/utils2.c @@ -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); -- 2.30.2