Re: [INTERNALS-WIN] Re: [PHP-DEV] Windows (Visual Studio) compiler stuff
[email protected] ("Matt Wilmas") Mon, 7 Dec 2015 10:40:00 -0600
| Newsgroups | php.internals,php.internals.win |
|---|---|
| Message-ID | <8DC68003ACDC4E8B84B0CECC2AB93C10@pc1> |
Hi Anatol, ----- Original Message ----- From: "Anatol Belski" Sent: Wednesday, November 25, 2015 > Hi Matt, > >> -----Original Message----- >> From: Matt Wilmas [mailto:[email protected]] >> Sent: Monday, November 23, 2015 8:15 AM >> To: Anatol Belski <[email protected]>; [email protected]; > internals- >> [email protected] >> Cc: 'Dmitry Stogov' <[email protected]>; 'Pierre Joye' > <[email protected]> >> 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.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 verified that the > standalone >> functions (from static's) were gone, but obviously it also removed a lot > more. >> Thank you! >> >> Hopefully that's a switch that can be taken advantage of? >> > /Zc:inline is documented as C++11 feature. Still it is about enforcing the > definition within the same translation unit, so basically kind of > synonymous > to the cl/link options we have. It doesn't enforce C++11, just one that > rule. Whether it'd break some C++ extensions - well, should check. It sounded to me (haven't checked docs again) like it's something that sets whether old, MS-specific behavior is disallowed...? e.g. nothing to break if it didn't [already] break with other compilers. > But about the "static inline", it is really something that should be kept > everywhere. It is the most convenient option for the compiler/linker > compatibility. A global function is allowed to be defined only once. Since > those functions are in defined in the headers, chances are to see the > duplicated symbol errors which will prevent compilation. VC should > actually > should do same. I'm no longer asking about removing the "static" part anywhere, like original message, since extra junk can be removed with /Zc:inline. :-) I get how the function definition stuff works, but VC doesn't seem to! As I've already said, by default (e.g. without /Zc:inline): *) __forceinline already seems to imply "static" by itself. Everything works as expected, all compilation works fine, and there are never the would-be-expected duplicate symbol errors. *) adding "static" to __forceinline, again, by default, seems to make it "super static" and create separate standalone versions even though they are never referenced. Seems there's a bug there somewhere... > The option using "extern inline" and splitting declaration > and definition are unusable, because those functions have to be usable in > external modules. > > In general, if testing goes good, we could add these options > (__declspec(noinline), /Zc:inline and maybe /Gw) to master to release > builds > for further observation. But it should be really good tested. We'll check > it > in our labs as well. I'll be able to come to this topic either at the end > of > this or early next year. MSVC really has problems if the options mess anything up ;-), so I'm making the changes as I find them, hehe. > Regards > > Anatol - Matt