That copy can often be avoided by directly constructing the return value
into the final destination mandated by the target's ABI.
- This is basically a generic equivalent to the C++ front-end's
+ This is basically a generic equivalent to the C++ front-end's
Named Return Value optimization. */
struct nrv_data
ever encounter languages which prevent this kind of optimization,
then we could either have the languages register the optimization or
we could change the gating function to check the current language. */
-
+
static unsigned int
tree_nrv (void)
{
if (DECL_NAME (result))
return 0;
+ /* If the result has its address taken then it might be modified
+ by means not detected in the following loop. Bail out in this
+ case. */
+ if (TREE_ADDRESSABLE (result))
+ return 0;
+
/* Look through each block for assignments to the RESULT_DECL. */
FOR_EACH_BB (bb)
{
|| TREE_ADDRESSABLE (found)
|| DECL_ALIGN (found) > DECL_ALIGN (result)
|| !useless_type_conversion_p (result_type,
- TREE_TYPE (found)))
+ TREE_TYPE (found)))
return 0;
}
else if (gimple_has_lhs (stmt))
{
tree addr = get_base_address (gimple_get_lhs (stmt));
- /* If there's any MODIFY of component of RESULT,
+ /* If there's any MODIFY of component of RESULT,
then bail out. */
if (addr && addr == result)
return 0;
DECL_ABSTRACT_ORIGIN (result) = DECL_ABSTRACT_ORIGIN (found);
}
- TREE_ADDRESSABLE (result) = TREE_ADDRESSABLE (found);
+ TREE_ADDRESSABLE (result) |= TREE_ADDRESSABLE (found);
/* Now walk through the function changing all references to VAR to be
RESULT. */
return optimize > 0;
}
-struct gimple_opt_pass pass_nrv =
+struct gimple_opt_pass pass_nrv =
{
{
GIMPLE_PASS,
return 0;
}
-struct gimple_opt_pass pass_return_slot =
+struct gimple_opt_pass pass_return_slot =
{
{
GIMPLE_PASS,