[Bug ipa/59948] Optimize std::function
hubicka at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Fri Sep 26 16:54:00 GMT 2014
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59948
Jan Hubicka <hubicka at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |mjambor at suse dot cz
--- Comment #6 from Jan Hubicka <hubicka at gcc dot gnu.org> ---
The nonzero check rewrite is already in tree, so .optimized dump is now better:
int m() ()
{
struct function h;
int _23;
<bb 2>:
MEM[(int (*<T5861>) (int) *)&h] = f;
h._M_invoker = _M_invoke;
h.D.26130._M_manager = _M_manager;
_23 = f (1);
std::_Function_base::_Base_manager<int (*)(int)>::_M_manager (&MEM[(struct
_Function_base *)&h]._M_functor, &MEM[(struct _Function_base *)&h]._M_functor,
3);
h ={v} {CLOBBER};
return _23;
}
We fail to inline f because at .release_ssa time it is still passed via memory:
int m() ()
{
struct function h;
bool (*<T5408>) (union _Any_data &, const union _Any_data &,
_Manager_operation) _2;
int _4;
bool (*<T5408>) (union _Any_data &, const union _Any_data &,
_Manager_operation) _5;
<bb 2>:
MEM[(struct _Function_base *)&h]._M_manager = 0B;
MEM[(int (*<T5861>) (int) *)&h] = f;
h._M_invoker = _M_invoke;
h.D.26130._M_manager = _M_manager;
_4 = std::function<int(int)>::operator() (&h, 1);
Where operator () is:
_Res std::function<_Res(_ArgTypes ...)>::operator()(_ArgTypes ...) const [with
_Res = int; _ArgTypes = {int}] (const struct function * const this, int
__args#0)
{
bool (*<T543f>) (union _Any_data &, const union _Any_data &,
_Manager_operation) _3;
int (*<T585d>) (const union _Any_data &, int) _4;
const union _Any_data * _5;
int _7;
<bb 2>:
_3 = MEM[(bool (*<T5408>) (union _Any_data &, const union _Any_data &,
_Manager_operation) *)this_1(D) + 16B];
...
We have
Jump functions of caller int m()/290:
callsite int m()/290 -> _Res std::function<_Res(_ArgTypes
...)>::operator()(_ArgTypes ...) const [with _Res = int; _ArgTypes = {int}]/361
:
param 0: UNKNOWN
Aggregate passed by reference:
offset: 0, cst: f
offset: 128, cst: _M_manager
offset: 192, cst: _M_invoke
param 1: CONST: 1
So we know that f is passed in the aggregate.
We also know operator () is using it:
Jump functions of caller _Res std::function<_Res(_ArgTypes
...)>::operator()(_ArgTypes ...) const [with _Res = int; _ArgTypes =
{int}]/361:
callsite _Res std::function<_Res(_ArgTypes ...)>::operator()(_ArgTypes
...) const [with _Res = int; _ArgTypes = {int}]/361 -> void
std::__throw_bad_function_call()/539 :
indirect aggregate callsite, calling param 0, offset 192, by reference, for
stmt _7 = _4 (_5, __args#0_9(D));
param 0: UNKNOWN
param 1: PASS THROUGH: 1, op nop_expr
Later we propagate this call into _M_invoke and we lost track of f() that is
invoked by it. We do have jump functoin here too:
Jump functions of caller static _Res std::_Function_handler<_Res(_ArgTypes
...), _Functor>::_M_invoke(const std::_Any_data&, _ArgTypes ...) [with _Res =
int; _Functor = int (*)(int); _A
indirect aggregate callsite, calling param 0, offset 0, by reference, for
stmt _5 = _3 (__args#0_6(D));
param 0: PASS THROUGH: 1, op nop_expr
Martin, what is going wrong here?
More information about the Gcc-bugs
mailing list