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

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to