This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Allow ipa-split to handle DECL_BY_REFERENCE retvals
- From: Jan Hubicka <hubicka at ucw dot cz>
- To: gcc-patches at gcc dot gnu dot org, rguenther at suse dot de
- Date: Thu, 1 Jul 2010 17:45:31 +0200
- Subject: Allow ipa-split to handle DECL_BY_REFERENCE retvals
Hi,
this patch enables handing of DECL_BY_REFERENCE in ipa-split. It is relative to ipa-split
with the patch allowing structure returns I posted earlier.
The problem here is that we need to enable return slot optimization for the call
and we need to produce *<retval> = fncall.part () since retval is pointer.
(I hope this is valid gimple as call is store to non-register)
Bootstrapped/regtested x86_64-linux, seems sane?
Honza
* ipa-split.c (split_function): For aggregate values set return_slot_opt;
when passing DECL_BY_REFERENCE produce *<retval> = fncall.part ()
(execute_split_functions): Do not care about DECL_BY_REFERENCE.
*** /home/jh/pretty-ipa2/gcc/ipa-split.c Thu Jul 1 16:09:51 2010
--- ipa-split.c Thu Jul 1 16:01:59 2010
*************** split_function (struct split_point *spli
*** 949,954 ****
--- 949,961 ----
call = gimple_build_call_vec (node->decl, args_to_pass);
gimple_set_block (call, DECL_INITIAL (current_function_decl));
+ /* We avoid address being taken on any variable used by split part,
+ so return slot optimization is always possible. Moreover this is
+ required to make DECL_BY_REFERENCE work. */
+ if (aggregate_value_p (DECL_RESULT (current_function_decl),
+ TREE_TYPE (current_function_decl)))
+ gimple_call_set_return_slot_opt (call, true);
+
/* Update return value. This is bit tricky. When we do not return,
do nothing. When we return we might need to update return_bb
or produce a new return statement. */
*************** split_function (struct split_point *spli
*** 1002,1008 ****
update_stmt (gsi_stmt (bsi));
}
}
! gimple_call_set_lhs (call, retval);
}
gsi_insert_after (&gsi, call, GSI_NEW_STMT);
}
--- 1010,1019 ----
update_stmt (gsi_stmt (bsi));
}
}
! if (DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)))
! gimple_call_set_lhs (call, build_simple_mem_ref (retval));
! else
! gimple_call_set_lhs (call, retval);
}
gsi_insert_after (&gsi, call, GSI_NEW_STMT);
}
*************** split_function (struct split_point *spli
*** 1021,1027 ****
retval = create_tmp_reg (TREE_TYPE (retval), NULL);
if (is_gimple_reg (retval))
retval = make_ssa_name (retval, call);
! gimple_call_set_lhs (call, retval);
}
gsi_insert_after (&gsi, call, GSI_NEW_STMT);
ret = gimple_build_return (retval);
--- 1032,1041 ----
retval = create_tmp_reg (TREE_TYPE (retval), NULL);
if (is_gimple_reg (retval))
retval = make_ssa_name (retval, call);
! if (DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)))
! gimple_call_set_lhs (call, build_simple_mem_ref (retval));
! else
! gimple_call_set_lhs (call, retval);
}
gsi_insert_after (&gsi, call, GSI_NEW_STMT);
ret = gimple_build_return (retval);
*************** execute_split_functions (void)
*** 1085,1097 ****
fprintf (dump_file, "Not splitting: nested function.\n");
return 0;
}
- /* FIXME: Should be easy to support. */
- if (DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)))
- {
- if (dump_file)
- fprintf (dump_file, "Not splitting: returns value by reference.\n");
- return 0;
- }
/* See if it makes sense to try to split.
It makes sense to split if we inline, that is if we have direct calls to
--- 1099,1104 ----