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>
* fe.h (Constant_Value): Declare.
......
......@@ -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;
......
......@@ -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,
......
......@@ -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);
......
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