Eleftherios Ioannidis via llvm-dev
2018-May-29 17:52 UTC
[llvm-dev] Inline constant std::function parameter
Hey LLVM-dev, I'm trying to inline the following C++ code: __attribute__((always_inline)) static void inline compose(const char* s, std::function<void(const char *)> f) { std::cout << s << std::endl; f(s); } // --------------- Main --------------- int main() { // Nest three things compose("hello world", [](const char *s) { compose("hello again", [](const char *s) { compose("hello third time", [](const char *s) { return; }); }); }); return 0; } Here my continuations are of type `std::function<void(const char*)>` and what I wanted from LLVM with the `always_inline` option was to transform it to a single call-site that looks like this: // --------------- Main --------------- int main() { // Nest three things std::cout << "hello world" << std::endl; std::cout << "hello again" << std::endl; std::cout << "hello third time" << std::endl; return 0; } However that doesn't seem to be the case, does the inliner not get triggered if the functions are passed as objects (std::function) or am I using the wrong `opt` invokation? OPT=opt-6.0 OPTFLAGS?=-O3 -always-inline -dot-callgraph Thanks! -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 1854 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180529/b977e342/attachment-0001.bin>
Friedman, Eli via llvm-dev
2018-May-29 18:53 UTC
[llvm-dev] Inline constant std::function parameter
On 5/29/2018 10:52 AM, Eleftherios Ioannidis via llvm-dev wrote:> However that doesn't seem to be the case, does the inliner not get triggered if the functions are passed as objects (std::function) or am I using the wrong `opt` invokation?In general, the inliner can only inline direct function calls (not virtual calls, or calls through a function pointer or std::function); otherwise, it doesn't know what to inline. In some cases, optimizations can prove that an indirect call actually calls some specific function, but your testcase isn't one of those cases. In particular, the implementation of std::function is kind of hard for the optimizer to deal with. This could probably be improved. -Eli -- Employee of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
Eleftherios Ioannidis via llvm-dev
2018-May-29 19:44 UTC
[llvm-dev] Inline constant std::function parameter
I was afraid that was the case, since std::function is not a first-class object of LLVM. Every implementation that I can think of that inlines std::function intrinsically seems a bit awkward, in the way that it will be along the lines: “Treat this class (std::function) in a special way” A better way would be to generalize for all callables, and say something along the lines of “If a class has the () operator, see if you can inline that method” But that too is too specific to C++ and I’m afraid high-level operator semantics will be lost by the time it turns to byte code. Seems to me, the sane solution would be for clang++ to treat std::function as an LLVM function type (https://llvm.org/docs/LangRef.html#function-type <https://llvm.org/docs/LangRef.html#function-type>) instead of a class object and then the road to these optimizations will open. But I have not looked at the gritty details of the clang implementation, so I could be way off. Anybody willing to step in and fill the blanks would be appreciated. Regards, Lef> On May 29, 2018, at 2:53 PM, Friedman, Eli <efriedma at codeaurora.org> wrote: > > On 5/29/2018 10:52 AM, Eleftherios Ioannidis via llvm-dev wrote: >> However that doesn't seem to be the case, does the inliner not get triggered if the functions are passed as objects (std::function) or am I using the wrong `opt` invokation? > > In general, the inliner can only inline direct function calls (not virtual calls, or calls through a function pointer or std::function); otherwise, it doesn't know what to inline. > > In some cases, optimizations can prove that an indirect call actually calls some specific function, but your testcase isn't one of those cases. In particular, the implementation of std::function is kind of hard for the optimizer to deal with. This could probably be improved. > > -Eli > > -- > Employee of Qualcomm Innovation Center, Inc. > Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180529/52d65f6f/attachment.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 1854 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180529/52d65f6f/attachment.bin>