[PHP-DEV] Re: [INTERNALS-WIN] Re: [PHP-DEV] Windows (Visual Studio) compiler stuff
Hi Anatol, - Original Message - From: "Anatol Belski" Sent: Wednesday, November 25, 2015 Hi Matt, -Original Message- From: Matt Wilmas [mailto:php_li...@realplain.com] Sent: Monday, November 23, 2015 8:15 AM To: Anatol Belski <anatol@belski.net>; internals@lists.php.net; internals- w...@lists.php.net Cc: 'Dmitry Stogov' <dmi...@zend.com>; 'Pierre Joye' <pierre@gmail.com> Subject: Re: [INTERNALS-WIN] Re: [PHP-DEV] Windows (Visual Studio) compiler stuff Hi Anatol, all, - Original Message - From: "Anatol Belski" Sent: Monday, November 16, 2015 [...] noinline did have an effect -- 12 KB smaller php7.dll. So, obviously it's preventing those zend_never_inline functions from being inlined when they currently are. Dmitry surely had reason to make them that way -- cache-related, I assume. Any difference, however "minor," is the same as other compilers, so it's nice to know this can be used, with so many of the other GCC/Clang "tricks" missing... I wasn't telling it wouldn't work. We should check for possible implications. If there's nothing negative, so we can add this into master. It always depends, smaller image size vs. function call. It works and I don't see how there could be implications, so "do it" I say. ;-) It doesn't really depend in the case of zend_never_inline -- the *point* is to ensure a function call (and smaller code size). Question/take it up with Dmitry otherwise. :-P BTW, something "big" not getting inlined even when forced? I know the "rules" about what can't be [force] inlined (basically same as GCC) and size isn't one of them. :-) (I hope not.) As I've mentioned a bit, to be seen soon, my "compile- time" param parsing optimization will have the "hugest" inline function, but it compiles down to literally nothing, which I finally got to work with MSVC as well. That's why I wasn't liking the idea of a standalone copy of that stuff adding several KB to each module... Size is one of the factors, the concrete code and usage, too. Despite that, any compiler doc says that inline is just a suggestion. This is unrelated to anything anyway, but... We're not talking about "just inline" here, but always/force. Much more than "just a suggestion." At least when optimization is enabled, it WILL be inlined provided it doesn't contain one of the things that makes it ineligible for inlining. So it's more like Arnold in T2: "I insist." Or, a very strong suggestion. > I guess I've understood what you're talking about - abut unreferenced > COMDATs (or maybe also duplicated COMDATs). There is a variety of > situations for that, not possibly only inlining. Fixing it is done in > PHP when building with --enable-debug-pack, that is on in release > builds. In your experiments, if you add /Zi CFLAG (or explicitly /Gy) > and /OPT:REF,ICF LDFLAG - that will solve it for yur other project. > You can read more about COMDAT on MSDN. Yeah, I know about the COMDAT stuff. And I thought I had tried the /OPT:REF, etc. on a standalone test a while ago and it didn't do anything... I just now tried --enable-debug-pack, and as I was thinking, it had no effect. What do you mean with "no effect"? Don't reduce size? The compiler/linker options I've mentioned are about removing identical or unreferenced COMDATS, and they do that. BTW how do you check it? I would like you to be more precise at this point, please. Did you use link /map or disasm? No effect meaning it didn't do anything at all. So no, they didn't remove the, what, 220 KB+ worth of code... File size identical, so I assume all contents as well (except image headers, etc.). I've always been checking file size (for quick answer) and disassembly... I don't need to solve anything on the other project since I didn't use static there. :-P > Hm, probably these options could be revisited, as since 2013 there's > also /Gw and /Zc:inline switches which is not implied by /Zi. But have > to do more checks, for now the release build options are good enough. > >> Again, I'll try to compile PHP with those static's removed and report >> the > effect >> later. >> > Yes, thanks for your effort. I actually didn't check what gcc does for > such cases, so curious. But "static" in "static inline" forces every > translation unit to have even the same function to have different > address, thus eliminating the "one definition" rule for inline. We > anyway need "static inline" best compatibility, the compilers handle > the rest :) First, the report: Removing all the static's with zend_always_inline works fine (since the __forceinline seems to "imply" static, no duplicate symbols). It makes php7.
Re: [PHP-DEV] Windows (Visual Studio) compiler stuff
Hi Anatol, all, CFG's effect on Wordpress at the end... :-/ - Original Message - From: "Anatol Belski" Sent: Wednesday, November 25, 2015 Hi Matt, I wonder really how much research you do :) Not much on this... Hope there aren't major inaccuracies. I just came across stuff while doing other things, otherwise maybe I would have discovered this sooner! -Original Message- From: Matt Wilmas [mailto:php_li...@realplain.com] Sent: Monday, November 23, 2015 2:28 AM To: internals@lists.php.net; internals-...@lists.php.net Cc: Dmitry Stogov <dmi...@zend.com>; Anatol Belski <anatol@belski.net>; Pierre Joye <pierre@gmail.com>; Matt Tait <matt.t...@gmail.com>; Nikita Popov <nikita....@gmail.com> Subject: Re: [PHP-DEV] Windows (Visual Studio) compiler stuff Hi Anatol, Dmitry, all, Will reply about the original subject issues soon, but this is about new stuff I noticed the other day... Adding Matt Tait and Nikita because of PR #1418 and comments. Anyway, the new Control Flow Guard (/guard:cf) is causing a big slowdown on bench.php. :-( 14% on a Yorkfield (Q9400) and 19% on a Sandy Bridge (Celeron G530). Ouch. Did anyone else check the performance impact? Is this acceptable? On any other platform...? I'll definitely remove that from my builds (Elephpant Sanctuary, coming soon) since it's useless on all but the latest Windows versions anyway. But if that "feature" must remain enabled otherwise, I think we can eliminate most of the performance hit. As Nikita wondered about, I first wanted to look at the indirect calls to the opcode handlers. I tried separating out zend_execute.c in the Makefile and added /guard:cf- Bingo! That restored about 98% of the speed on bench.php. It reduced the --disable-all NTS DLL by 13.5 KB (of the 67 KB added by full CFG). Or could maybe change back to the old SWITCH executor? I didn't try that. It seems like it would be a good "rule" to not use any MS stuff that isn't done on other compilers/platforms. :-) /GS [1] is another that is/was starting to get annoying (function prolog/epilog); luckily I was able to suppress it in most cases with changes I'm making. It's enabled by default, of course, although I see it's commented out in a line (old?) of confutils.js. /GS- ;-) I really hope there aren't places where we are not doing range checks, etc. ourselves (that the compiler can't see). So, either /GS is a waste, or it's only a matter of time with other compilers?! [1] http://stackoverflow.com/questions/6607410/understanding-buffer-security- check-gs-compiler-option-in-msvc We're unlikely to remove the security options in favor of performance. But that's for one. I didn't expect that it would be totally removed (though I will since I consider it a useless MS "feature" *when applied to PHP*; again, to not use anything that doesn't exist for other platform builds). It'd be a different story if it didn't kill performance. That's why I pointed out that removing it from zend_execute.c ONLY eliminates most of the penalty. Doesn't look like many indirect calls there to worry about besides the executor. Are we saying that an exploit is going to modify the opcodes, etc.? Has that ever happened (serious question)? And since I mentioned using the old SWITCH executor, I checked and it's no good. The specialized version is ~2.3x slower than CALL! :-O The --without-specializer version takes *forever* to compile (10x longer) and is much faster, but about ~2% slower than CALL with CFG... /guard:cf is documented to have possible performance impact on systems that don't support it. Why only on systems that don't support it? That doesn't make any sense. If anything, I'd expect the opposite. I didn't try to check the code, but wonder why it's not more nop-ish on unsupported systems... And I don't know if it's just extra instructions slowing things down, or if a lookup table or whatever for valid targets is destroying the cache. However no such side effects was noticed even on win7. So what did you see...? I said 19% slowdown on bench.php, Sandy Bridge, Win 7 x64, 32-bit. Have since checked 64-bit build and that's 20%. There was also no bug reports in this regard. Bug reports against what...? Probably nobody was looking, and first it was VS 2012 before 2015 and then enabling CFG. I guess I could file one now since testing Wordpress? We definitely can't test any possible HW, but it's more about OS, not HW. I'd wager the opposite... It's affecting CPU stuff, after all. Is win7 your case? Then just upgrade :) Yeah, on the one system. The Yorkfield is Windows XP *gasp*. Definitely won't just "upgrade" any system unless desired for reasons overall. And as long as I'm not satisfied with desktop Linux, Hackintosh, Anyway, I *need* XP, and there's really no legitimate r
[PHP-DEV] RE: [INTERNALS-WIN] Re: [PHP-DEV] Windows (Visual Studio) compiler stuff
Hi Matt, > -Original Message- > From: Matt Wilmas [mailto:php_li...@realplain.com] > Sent: Monday, November 23, 2015 8:15 AM > To: Anatol Belski <anatol@belski.net>; internals@lists.php.net; internals- > w...@lists.php.net > Cc: 'Dmitry Stogov' <dmi...@zend.com>; 'Pierre Joye' <pierre@gmail.com> > Subject: Re: [INTERNALS-WIN] Re: [PHP-DEV] Windows (Visual Studio) compiler > stuff > > Hi Anatol, all, > > - Original Message - > From: "Anatol Belski" > Sent: Monday, November 16, 2015 > > > Hi Matt, > > > >> -Original Message- > >> From: Matt Wilmas [mailto:php_li...@realplain.com] > >> Sent: Monday, November 16, 2015 2:59 PM > >> To: Anatol Belski <anatol@belski.net>; internals@lists.php.net; > > internals- > >> w...@lists.php.net > >> Cc: 'Dmitry Stogov' <dmi...@zend.com>; 'Pierre Joye' > > <pierre@gmail.com> > >> Subject: [INTERNALS-WIN] Re: [PHP-DEV] Windows (Visual Studio) > >> compiler stuff > >> > >> > According to the docs __declspec(noinline) is specific to C++. Also > >> > with VS it's always much more tedious to inline something than the > >> > opposite. These are the main two reasons it's disregarded ATM. We > >> > can add it for compliance with C++, but it'll in best case have no > >> > effect in the PHP core. Should be tested before, though. > >> > >> Yeah, I know what the docs imply ("member function"), which is why I > > tested it. > >> I guess you missed my "works as expected" part. :-P > >> > >> A test function that just returns a number was automatically inlined > > (plain C). > >> Using __declspec(noinline) it was call'ed instead. > >> > >> Not sure if any of the "zend_never_inline" PHP stuff is getting > >> inlined > > when it's > >> desired not to be -- I'll compile PHP in a bit and see what it looks > >> like > > with > >> "noinline." > >> > > Yeah, I knew it could work, just that it's undocumented so preferred > > not even to start with it because I haven't expect much gain from it. > > The functions I've seen with zend_never_inline are rather big and > > wouldn't get inlined even when forced. > > noinline did have an effect -- 12 KB smaller php7.dll. So, obviously it's > preventing those zend_never_inline functions from being inlined when they > currently are. Dmitry surely had reason to make them that way -- cache-related, > I assume. Any difference, however "minor," is the same as other compilers, so > it's nice to know this can be used, with so many of the other GCC/Clang "tricks" > missing... > I wasn't telling it wouldn't work. We should check for possible implications. If there's nothing negative, so we can add this into master. It always depends, smaller image size vs. function call. > BTW, something "big" not getting inlined even when forced? I know the "rules" > about what can't be [force] inlined (basically same as GCC) and size isn't one of > them. :-) (I hope not.) As I've mentioned a bit, to be seen soon, my "compile- > time" param parsing optimization will have the "hugest" > inline function, but it compiles down to literally nothing, which I finally got to > work with MSVC as well. That's why I wasn't liking the idea of a standalone copy > of that stuff adding several KB to each module... > Size is one of the factors, the concrete code and usage, too. Despite that, any compiler doc says that inline is just a suggestion. > >> > I'd ask you for some concrete case for this, as I'm not sure to > >> > understand exactly what you mean. The only case where an extra code > >> > would be generated is with "__declspec(export) inline", but that's > >> > not the case anywhere within PHP. > >> > >> My concrete case is checking tons of generated code! ;-) > >> > >> It's simple: useless standalone functions are created for every > >> "static __forceinline" definition... Not having static makes it act > >> like > > GCC/Clang. > >> > > I guess I've understood what you're talking about - abut unreferenced > > COMDATs (or maybe also duplicated COMDATs). There is a variety of > > situations for that, not possibly only inlining. Fixing it is done in > > PHP when building with --enable-debug-pack, that is on in release > > builds. In your experiments, if you add /Zi CFLAG (or explicitly /Gy) > > and /OPT
RE: [PHP-DEV] Windows (Visual Studio) compiler stuff
Hi Matt, I wonder really how much research you do :) > -Original Message- > From: Matt Wilmas [mailto:php_li...@realplain.com] > Sent: Monday, November 23, 2015 2:28 AM > To: internals@lists.php.net; internals-...@lists.php.net > Cc: Dmitry Stogov <dmi...@zend.com>; Anatol Belski <anatol@belski.net>; > Pierre Joye <pierre@gmail.com>; Matt Tait <matt.t...@gmail.com>; Nikita > Popov <nikita....@gmail.com> > Subject: Re: [PHP-DEV] Windows (Visual Studio) compiler stuff > > Hi Anatol, Dmitry, all, > > Will reply about the original subject issues soon, but this is about new stuff I > noticed the other day... Adding Matt Tait and Nikita because of PR > #1418 and comments. > > Anyway, the new Control Flow Guard (/guard:cf) is causing a big slowdown on > bench.php. :-( 14% on a Yorkfield (Q9400) and 19% on a Sandy Bridge (Celeron > G530). Ouch. Did anyone else check the performance impact? Is this > acceptable? On any other platform...? > > I'll definitely remove that from my builds (Elephpant Sanctuary, coming > soon) since it's useless on all but the latest Windows versions anyway. > > But if that "feature" must remain enabled otherwise, I think we can eliminate > most of the performance hit. As Nikita wondered about, I first wanted to look > at the indirect calls to the opcode handlers. I tried > separating out zend_execute.c in the Makefile and added /guard:cf- Bingo! > That restored about 98% of the speed on bench.php. It reduced the --disable-all > NTS DLL by 13.5 KB (of the 67 KB added by full CFG). > > Or could maybe change back to the old SWITCH executor? I didn't try that. > > > It seems like it would be a good "rule" to not use any MS stuff that isn't done on > other compilers/platforms. :-) > > /GS [1] is another that is/was starting to get annoying (function prolog/epilog); > luckily I was able to suppress it in most cases with changes I'm making. It's > enabled by default, of course, although I see it's > commented out in a line (old?) of confutils.js. /GS- ;-) I really hope > there aren't places where we are not doing range checks, etc. ourselves (that > the compiler can't see). So, either /GS is a waste, or it's only a matter of time > with other compilers?! > > [1] > http://stackoverflow.com/questions/6607410/understanding-buffer-security- > check-gs-compiler-option-in-msvc > We're unlikely to remove the security options in favor of performance. But that's for one. /guard:cf is documented to have possible performance impact on systems that don't support it. However no such side effects was noticed even on win7. There was also no bug reports in this regard. We definitely can't test any possible HW, but it's more about OS, not HW. Is win7 your case? Then just upgrade :) With /GS is basically same. It's not supposed to fix the programmer mistakes, but to add protection against exploits. Stability and compatibility matters more than a performance trade off. Another thing is that just one synthetic test is unlikely to reveal the big picture. You should probably also test on some real apps, that will bring more realistic results. Thanks for your work. Regards Anatol -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Windows (Visual Studio) compiler stuff
Hi Anatol, Dmitry, all, Will reply about the original subject issues soon, but this is about new stuff I noticed the other day... Adding Matt Tait and Nikita because of PR #1418 and comments. Anyway, the new Control Flow Guard (/guard:cf) is causing a big slowdown on bench.php. :-( 14% on a Yorkfield (Q9400) and 19% on a Sandy Bridge (Celeron G530). Ouch. Did anyone else check the performance impact? Is this acceptable? On any other platform...? I'll definitely remove that from my builds (Elephpant Sanctuary, coming soon) since it's useless on all but the latest Windows versions anyway. But if that "feature" must remain enabled otherwise, I think we can eliminate most of the performance hit. As Nikita wondered about, I first wanted to look at the indirect calls to the opcode handlers. I tried separating out zend_execute.c in the Makefile and added /guard:cf- Bingo! That restored about 98% of the speed on bench.php. It reduced the --disable-all NTS DLL by 13.5 KB (of the 67 KB added by full CFG). Or could maybe change back to the old SWITCH executor? I didn't try that. It seems like it would be a good "rule" to not use any MS stuff that isn't done on other compilers/platforms. :-) /GS [1] is another that is/was starting to get annoying (function prolog/epilog); luckily I was able to suppress it in most cases with changes I'm making. It's enabled by default, of course, although I see it's commented out in a line (old?) of confutils.js. /GS- ;-) I really hope there aren't places where we are not doing range checks, etc. ourselves (that the compiler can't see). So, either /GS is a waste, or it's only a matter of time with other compilers?! [1] http://stackoverflow.com/questions/6607410/understanding-buffer-security-check-gs-compiler-option-in-msvc - Matt -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] Re: [INTERNALS-WIN] Re: [PHP-DEV] Windows (Visual Studio) compiler stuff
Hi Anatol, all, - Original Message - From: "Anatol Belski" Sent: Monday, November 16, 2015 Hi Matt, -Original Message- From: Matt Wilmas [mailto:php_li...@realplain.com] Sent: Monday, November 16, 2015 2:59 PM To: Anatol Belski <anatol@belski.net>; internals@lists.php.net; internals- w...@lists.php.net Cc: 'Dmitry Stogov' <dmi...@zend.com>; 'Pierre Joye' <pierre@gmail.com> Subject: [INTERNALS-WIN] Re: [PHP-DEV] Windows (Visual Studio) compiler stuff > According to the docs __declspec(noinline) is specific to C++. Also > with VS it's always much more tedious to inline something than the > opposite. These are the main two reasons it's disregarded ATM. We can > add it for compliance with C++, but it'll in best case have no effect > in the PHP core. Should be tested before, though. Yeah, I know what the docs imply ("member function"), which is why I tested it. I guess you missed my "works as expected" part. :-P A test function that just returns a number was automatically inlined (plain C). Using __declspec(noinline) it was call'ed instead. Not sure if any of the "zend_never_inline" PHP stuff is getting inlined when it's desired not to be -- I'll compile PHP in a bit and see what it looks like with "noinline." Yeah, I knew it could work, just that it's undocumented so preferred not even to start with it because I haven't expect much gain from it. The functions I've seen with zend_never_inline are rather big and wouldn't get inlined even when forced. noinline did have an effect -- 12 KB smaller php7.dll. So, obviously it's preventing those zend_never_inline functions from being inlined when they currently are. Dmitry surely had reason to make them that way -- cache-related, I assume. Any difference, however "minor," is the same as other compilers, so it's nice to know this can be used, with so many of the other GCC/Clang "tricks" missing... BTW, something "big" not getting inlined even when forced? I know the "rules" about what can't be [force] inlined (basically same as GCC) and size isn't one of them. :-) (I hope not.) As I've mentioned a bit, to be seen soon, my "compile-time" param parsing optimization will have the "hugest" inline function, but it compiles down to literally nothing, which I finally got to work with MSVC as well. That's why I wasn't liking the idea of a standalone copy of that stuff adding several KB to each module... > I'd ask you for some concrete case for this, as I'm not sure to > understand exactly what you mean. The only case where an extra code > would be generated is with "__declspec(export) inline", but that's not > the case anywhere within PHP. My concrete case is checking tons of generated code! ;-) It's simple: useless standalone functions are created for every "static __forceinline" definition... Not having static makes it act like GCC/Clang. I guess I've understood what you're talking about - abut unreferenced COMDATs (or maybe also duplicated COMDATs). There is a variety of situations for that, not possibly only inlining. Fixing it is done in PHP when building with --enable-debug-pack, that is on in release builds. In your experiments, if you add /Zi CFLAG (or explicitly /Gy) and /OPT:REF,ICF LDFLAG - that will solve it for yur other project. You can read more about COMDAT on MSDN. Yeah, I know about the COMDAT stuff. And I thought I had tried the /OPT:REF, etc. on a standalone test awhile ago and it didn't do anything... I just now tried --enable-debug-pack, and as I was thinking, it had no effect. I don't need to solve anything on the other project since I didn't use static there. :-P Hm, probably these options could be revisited, as since 2013 there's also /Gw and /Zc:inline switches which is not implied by /Zi. But have to do more checks, for now the release build options are good enough. Again, I'll try to compile PHP with those static's removed and report the effect later. Yes, thanks for your effort. I actually didn't check what gcc does for such cases, so curious. But "static" in "static inline" forces every translation unit to have even the same function to have different address, thus eliminating the "one definition" rule for inline. We anyway need "static inline" best compatibility, the compilers handle the rest :) First, the report: Removing all the static's with zend_always_inline works fine (since the __forceinline seems to "imply" static, no duplicate symbols). It makes php7.dll 91 KB smaller (NTS --disable-all). But then when I tried the /Zc:inline option (really sounds like C++ on MSDN) the other day, I was pleasantly surprised! "You da man!" :-) That saved over 220 KB, without removing static's. I verifi
RE: [PHP-DEV] Windows (Visual Studio) compiler stuff
Hello Matt, > -Original Message- > From: Matt Wilmas [mailto:php_li...@realplain.com] > Sent: Sunday, November 15, 2015 11:31 PM > To: internals@lists.php.net; internals-...@lists.php.net > Cc: Dmitry Stogov; Anatol Belski ; > Pierre Joye > Subject: [PHP-DEV] Windows (Visual Studio) compiler stuff > > Hi Dmitry, Anatol, Pierre (etc.), and all, > > I'm back now, I think, after a much longer (unintentional) break than I expected. > Be coming very soon with what I was doing in the summer (param parsing stuff) > -- *now* it works with MSVC too, barring any fragility, as I accidentally > discovered last month... > > I've been "discovering" a lot with the wacky Visual Studio compiler! :-) This > message is about the 2 I found today. > > The first simple thing was probably just overlooked, but noticed it while looking > up __declspec. zend_never_inline has always been empty (I guess) for MSVC, > but there's actually a __declspec(noinline) that can be used (and works as > expected). A simple and obvious change to bring it in line with the other > compilers? > According to the docs __declspec(noinline) is specific to C++. Also with VS it's always much more tedious to inline something than the opposite. These are the main two reasons it's disregarded ATM. We can add it for compliance with C++, but it'll in best case have no effect in the PHP core. Should be tested before, though. > > The second "issue" is with the zend_always_inline functions, I noticed this > summer. Did anyone else know that MSVC leaves a *copy* of those functions in > the output files (DLLs)? What's the point of that? When they've been inlined, > and not referenced otherwise, there should be no reason to emit code for a > standalone function! > > I remembered after seeing that behavior that a bit of my own __forceinline'd > code did NOT have extra function code, but forgot to investigate until today. > What's different about my function definition? No "static" > specifier! So that's the key. :-) > > But... non-static would create duplicate symbols, I thought. But no, it works! > With just __forceinline, there's no errors. :^) > > Can something be done about this? It would cut the binary size down a bit. > A zend_static macro to be used with zend_always_inline...? > I'd ask you for some concrete case for this, as I'm not sure to understand exactly what you mean. The only case where an extra code would be generated is with "__declspec(export) inline", but that's not the case anywhere within PHP. Regards Anatol -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Windows (Visual Studio) compiler stuff
Hi Anatol, - Original Message - From: "Anatol Belski" Sent: Monday, November 16, 2015 Hello Matt, -Original Message- From: Matt Wilmas [mailto:php_li...@realplain.com] Sent: Sunday, November 15, 2015 11:31 PM To: internals@lists.php.net; internals-...@lists.php.net Cc: Dmitry Stogov; Anatol Belski ; Pierre Joye Subject: [PHP-DEV] Windows (Visual Studio) compiler stuff Hi Dmitry, Anatol, Pierre (etc.), and all, I'm back now, I think, after a much longer (unintentional) break than I expected. Be coming very soon with what I was doing in the summer (param parsing stuff) -- *now* it works with MSVC too, barring any fragility, as I accidentally discovered last month... I've been "discovering" a lot with the wacky Visual Studio compiler! :-) This message is about the 2 I found today. The first simple thing was probably just overlooked, but noticed it while looking up __declspec. zend_never_inline has always been empty (I guess) for MSVC, but there's actually a __declspec(noinline) that can be used (and works as expected). A simple and obvious change to bring it in line with the other compilers? According to the docs __declspec(noinline) is specific to C++. Also with VS it's always much more tedious to inline something than the opposite. These are the main two reasons it's disregarded ATM. We can add it for compliance with C++, but it'll in best case have no effect in the PHP core. Should be tested before, though. Yeah, I know what the docs imply ("member function"), which is why I tested it. I guess you missed my "works as expected" part. :-P A test function that just returns a number was automatically inlined (plain C). Using __declspec(noinline) it was call'ed instead. Not sure if any of the "zend_never_inline" PHP stuff is getting inlined when it's desired not to be -- I'll compile PHP in a bit and see what it looks like with "noinline." The second "issue" is with the zend_always_inline functions, I noticed this summer. Did anyone else know that MSVC leaves a *copy* of those functions in the output files (DLLs)? What's the point of that? When they've been inlined, and not referenced otherwise, there should be no reason to emit code for a standalone function! I remembered after seeing that behavior that a bit of my own __forceinline'd code did NOT have extra function code, but forgot to investigate until today. What's different about my function definition? No "static" specifier! So that's the key. :-) But... non-static would create duplicate symbols, I thought. But no, it works! With just __forceinline, there's no errors. :^) Can something be done about this? It would cut the binary size down a bit. A zend_static macro to be used with zend_always_inline...? I'd ask you for some concrete case for this, as I'm not sure to understand exactly what you mean. The only case where an extra code would be generated is with "__declspec(export) inline", but that's not the case anywhere within PHP. My concrete case is checking tons of generated code! ;-) It's simple: useless standalone functions are created for every "static __forceinline" definition... Not having static makes it act like GCC/Clang. Again, I'll try to compile PHP with those static's removed and report the effect later. Regards Anatol - Matt -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] RE: [INTERNALS-WIN] Re: [PHP-DEV] Windows (Visual Studio) compiler stuff
Hi Matt, > -Original Message- > From: Matt Wilmas [mailto:php_li...@realplain.com] > Sent: Monday, November 16, 2015 2:59 PM > To: Anatol Belski <anatol@belski.net>; internals@lists.php.net; internals- > w...@lists.php.net > Cc: 'Dmitry Stogov' <dmi...@zend.com>; 'Pierre Joye' <pierre@gmail.com> > Subject: [INTERNALS-WIN] Re: [PHP-DEV] Windows (Visual Studio) compiler > stuff > > > According to the docs __declspec(noinline) is specific to C++. Also > > with VS it's always much more tedious to inline something than the > > opposite. These are the main two reasons it's disregarded ATM. We can > > add it for compliance with C++, but it'll in best case have no effect > > in the PHP core. Should be tested before, though. > > Yeah, I know what the docs imply ("member function"), which is why I tested it. > I guess you missed my "works as expected" part. :-P > > A test function that just returns a number was automatically inlined (plain C). > Using __declspec(noinline) it was call'ed instead. > > Not sure if any of the "zend_never_inline" PHP stuff is getting inlined when it's > desired not to be -- I'll compile PHP in a bit and see what it looks like with > "noinline." > Yeah, I knew it could work, just that it's undocumented so preferred not even to start with it because I haven't expect much gain from it. The functions I've seen with zend_never_inline are rather big and wouldn't get inlined even when forced. > > I'd ask you for some concrete case for this, as I'm not sure to > > understand exactly what you mean. The only case where an extra code > > would be generated is with "__declspec(export) inline", but that's not > > the case anywhere within PHP. > > My concrete case is checking tons of generated code! ;-) > > It's simple: useless standalone functions are created for every "static > __forceinline" definition... Not having static makes it act like GCC/Clang. > I guess I've understood what you're talking about - abut unreferenced COMDATs (or maybe also duplicated COMDATs). There is a variety of situations for that, not possibly only inlining. Fixing it is done in PHP when building with --enable-debug-pack, that is on in release builds. In your experiments, if you add /Zi CFLAG (or explicitly /Gy) and /OPT:REF,ICF LDFLAG - that will solve it for yur other project. You can read more about COMDAT on MSDN. Hm, probably these options could be revisited, as since 2013 there's also /Gw and /Zc:inline switches which is not implied by /Zi. But have to do more checks, for now the release build options are good enough. > Again, I'll try to compile PHP with those static's removed and report the effect > later. > Yes, thanks for your effort. I actually didn't check what gcc does for such cases, so curious. But "static" in "static inline" forces every translation unit to have even the same function to have different address, thus eliminating the "one definition" rule for inline. We anyway need "static inline" best compatibility, the compilers handle the rest :) Regards Anatol -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php