Because variable-sized types are first-class citizens in Ada, the compiler
factors out size (and offset) computations into size functions in order to
make these types less heavyweight to manipulate. The counterpart is that it
needs to inline back these size functions into regular expressions in some
cases, for example when it constrains an originally unconstrained type.
This patch makes the compiler inline these functions in a little more cases.
Tested on x86_64-suse-linux, applied on the mainline (it only affects Ada).
2017-05-01 Eric Botcazou <ebotca...@adacore.com>
* tree.c (substitute_in_expr) <tcc_vl_exp>: Also inline a call if the
replacement expression is another instance of one of its arguments.
--
Eric Botcazou
Index: tree.c
===================================================================
--- tree.c (revision 247405)
+++ tree.c (working copy)
@@ -3886,15 +3886,29 @@ substitute_in_expr (tree exp, tree f, tr
new_tree = NULL_TREE;
- /* If we are trying to replace F with a constant, inline back
+ /* If we are trying to replace F with a constant or with another
+ instance of one of the arguments of the call, inline back
functions which do nothing else than computing a value from
the arguments they are passed. This makes it possible to
fold partially or entirely the replacement expression. */
- if (CONSTANT_CLASS_P (r) && code == CALL_EXPR)
+ if (code == CALL_EXPR)
{
- tree t = maybe_inline_call_in_expr (exp);
- if (t)
- return SUBSTITUTE_IN_EXPR (t, f, r);
+ bool maybe_inline = false;
+ if (CONSTANT_CLASS_P (r))
+ maybe_inline = true;
+ else
+ for (i = 3; i < TREE_OPERAND_LENGTH (exp); i++)
+ if (operand_equal_p (TREE_OPERAND (exp, i), r, 0))
+ {
+ maybe_inline = true;
+ break;
+ }
+ if (maybe_inline)
+ {
+ tree t = maybe_inline_call_in_expr (exp);
+ if (t)
+ return SUBSTITUTE_IN_EXPR (t, f, r);
+ }
}
for (i = 1; i < TREE_OPERAND_LENGTH (exp); i++)