Commit 08ef2c16 by Pierre-Marie de Rodat Committed by Eric Botcazou

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
parent abb3ea16
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> 2016-10-11 Tristan Gingold <gingold@adacore.com>
* fe.h (Constant_Value): Declare. * fe.h (Constant_Value): Declare.
......
...@@ -6832,7 +6832,7 @@ elaborate_reference (tree ref, Entity_Id gnat_entity, bool definition, ...@@ -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 /* Given a GNU tree and a GNAT list of choices, generate an expression to test
the value passed against the list of choices. */ the value passed against the list of choices. */
tree static tree
choices_to_gnu (tree operand, Node_Id choices) choices_to_gnu (tree operand, Node_Id choices)
{ {
Node_Id choice; Node_Id choice;
...@@ -6851,9 +6851,10 @@ choices_to_gnu (tree operand, Node_Id choices) ...@@ -6851,9 +6851,10 @@ choices_to_gnu (tree operand, Node_Id choices)
this_test this_test
= build_binary_op (TRUTH_ANDIF_EXPR, boolean_type_node, = build_binary_op (TRUTH_ANDIF_EXPR, boolean_type_node,
build_binary_op (GE_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, build_binary_op (LE_EXPR, boolean_type_node,
operand, high)); operand, high, true),
true);
break; break;
...@@ -6865,9 +6866,10 @@ choices_to_gnu (tree operand, Node_Id choices) ...@@ -6865,9 +6866,10 @@ choices_to_gnu (tree operand, Node_Id choices)
this_test this_test
= build_binary_op (TRUTH_ANDIF_EXPR, boolean_type_node, = build_binary_op (TRUTH_ANDIF_EXPR, boolean_type_node,
build_binary_op (GE_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, build_binary_op (LE_EXPR, boolean_type_node,
operand, high)); operand, high, true),
true);
break; break;
case N_Identifier: case N_Identifier:
...@@ -6886,9 +6888,10 @@ choices_to_gnu (tree operand, Node_Id choices) ...@@ -6886,9 +6888,10 @@ choices_to_gnu (tree operand, Node_Id choices)
this_test this_test
= build_binary_op (TRUTH_ANDIF_EXPR, boolean_type_node, = build_binary_op (TRUTH_ANDIF_EXPR, boolean_type_node,
build_binary_op (GE_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, build_binary_op (LE_EXPR, boolean_type_node,
operand, high)); operand, high, true),
true);
break; break;
} }
...@@ -6898,7 +6901,7 @@ choices_to_gnu (tree operand, Node_Id choices) ...@@ -6898,7 +6901,7 @@ choices_to_gnu (tree operand, Node_Id choices)
case N_Integer_Literal: case N_Integer_Literal:
single = gnat_to_gnu (choice); single = gnat_to_gnu (choice);
this_test = build_binary_op (EQ_EXPR, boolean_type_node, operand, this_test = build_binary_op (EQ_EXPR, boolean_type_node, operand,
single); single, true);
break; break;
case N_Others_Choice: case N_Others_Choice:
...@@ -6909,8 +6912,11 @@ choices_to_gnu (tree operand, Node_Id choices) ...@@ -6909,8 +6912,11 @@ choices_to_gnu (tree operand, Node_Id choices)
gcc_unreachable (); gcc_unreachable ();
} }
if (result == boolean_false_node)
result = this_test;
else
result = build_binary_op (TRUTH_ORIF_EXPR, boolean_type_node, result, result = build_binary_op (TRUTH_ORIF_EXPR, boolean_type_node, result,
this_test); this_test, true);
} }
return result; return result;
......
...@@ -174,10 +174,6 @@ enum alias_set_op ...@@ -174,10 +174,6 @@ enum alias_set_op
extern void relate_alias_sets (tree gnu_new_type, tree gnu_old_type, extern void relate_alias_sets (tree gnu_new_type, tree gnu_old_type,
enum alias_set_op op); 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) /* Given GNAT_ENTITY, an object (constant, variable, parameter, exception)
and GNU_TYPE, its corresponding GCC type, set Esize and Alignment to the 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. 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); ...@@ -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 /* Make a binary operation of kind OP_CODE. RESULT_TYPE is the type
desired for the result. Usually the operation is to be performed 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 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, 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. */ /* Similar, but make unary operation. */
extern tree build_unary_op (enum tree_code op_code, tree result_type, extern tree build_unary_op (enum tree_code op_code, tree result_type,
......
...@@ -834,6 +834,7 @@ build_load_modify_store (tree dest, tree src, Node_Id gnat_node) ...@@ -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 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 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. 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 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 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) ...@@ -841,7 +842,8 @@ build_load_modify_store (tree dest, tree src, Node_Id gnat_node)
tree tree
build_binary_op (enum tree_code op_code, tree result_type, 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 left_type = TREE_TYPE (left_operand);
tree right_type = TREE_TYPE (right_operand); tree right_type = TREE_TYPE (right_operand);
...@@ -1283,10 +1285,16 @@ build_binary_op (enum tree_code op_code, tree result_type, ...@@ -1283,10 +1285,16 @@ build_binary_op (enum tree_code op_code, tree result_type,
else if (TREE_CODE (right_operand) == NULL_EXPR) else if (TREE_CODE (right_operand) == NULL_EXPR)
return build1 (NULL_EXPR, operation_type, TREE_OPERAND (right_operand, 0)); return build1 (NULL_EXPR, operation_type, TREE_OPERAND (right_operand, 0));
else if (op_code == ARRAY_REF || op_code == ARRAY_RANGE_REF) 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) else if (op_code == INIT_EXPR || op_code == MODIFY_EXPR)
result = build2 (op_code, void_type_node, left_operand, right_operand); 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 else
result result
= fold_build2 (op_code, operation_type, left_operand, right_operand); = 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, ...@@ -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 we are working with modular types, perform the MOD operation
if something above hasn't eliminated the need for it. */ if something above hasn't eliminated the need for it. */
if (modulus) 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) if (result_type && result_type != operation_type)
result = convert (result_type, result); result = convert (result_type, result);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment