On Thu, Jul 9, 2015 at 7:52 PM, Hal Finkel <hfinkel at anl.gov> wrote:> ----- Original Message ----- > > From: "Hal Finkel" <hfinkel at anl.gov> > > To: "Richard Smith" <richard at metafoo.co.uk> > > Cc: "Xinliang David Li" <davidxl at google.com>, "cfe commits" < > cfe-commits at cs.uiuc.edu>, "List" <llvmdev at cs.uiuc.edu> > > Sent: Thursday, July 9, 2015 8:46:22 PM > > Subject: Re: [LLVMdev] Inline hint for methods defined in-class > > > > ----- Original Message ----- > > > From: "Richard Smith" <richard at metafoo.co.uk> > > > To: "Hal Finkel" <hfinkel at anl.gov> > > > Cc: "cfe commits" <cfe-commits at cs.uiuc.edu>, "List" > > > <llvmdev at cs.uiuc.edu>, "Xinliang David Li" <davidxl at google.com> > > > Sent: Thursday, July 9, 2015 8:08:38 PM > > > Subject: Re: [LLVMdev] Inline hint for methods defined in-class > > > > > > On Thu, Jul 9, 2015 at 4:30 PM, Hal Finkel < hfinkel at anl.gov > > > > wrote: > > > > > > > > > ----- Original Message ----- > > > > From: "Richard Smith" < richard at metafoo.co.uk > > > > > To: "Xinliang David Li" < davidxl at google.com > > > > > Cc: "cfe commits" < cfe-commits at cs.uiuc.edu >, "< > > > > llvmdev at cs.uiuc.edu > List" < llvmdev at cs.uiuc.edu > > > > > Sent: Thursday, July 9, 2015 3:40:54 PM > > > > Subject: Re: [LLVMdev] Inline hint for methods defined in-class > > > > > > > > > > > > > > On Tue, Jul 7, 2015 at 10:25 PM, Xinliang David Li < > > > > davidxl at google.com > wrote: > > > > > > > > > > > > On Tue, Jul 7, 2015 at 6:06 PM, Chandler Carruth < > > > > chandlerc at gmail.com > wrote: > > > > > On Tue, Jul 7, 2015 at 4:11 PM Easwaran Raman < > > > > > eraman at google.com > > > > > > > > > > > wrote: > > > > >> > > > > >> I'm reviving this thread after a while and CCing cfe-commits > > > > >> as > > > > >> suggested by David Blaikie. I've also collected numbers > > > > >> building > > > > >> chrome (from chromium, on Linux) with and without this patch > > > > >> as > > > > >> suggested by David. I've re-posted the proposed patch and > > > > >> performance/size numbers collected at the top to make it > > > > >> easily > > > > >> readable for those reading it through cfe-commits. > > > > > > > > > > > > > > > First off, thanks for collecting the numbers and broadening the > > > > > distribution. Also, sorry it took me so long to get over to > > > > > this > > > > > thread. > > > > > > > > > > I want to lay out my stance on this issue at a theoretical and > > > > > practical > > > > > level first. I'll follow up with thoughts on the numbers as > > > > > well > > > > > after that. > > > > > > > > > > I think that tying *any* optimizer behavior to the 'inline' > > > > > keyword > > > > > is > > > > > fundamentally the wrong direction. > > > > > > > > Chandler, thanks for sharing your thought -- however I don't > > > > think > > > > it > > > > is wrong, let alone 'fundamentally wrong'. Despite all the > > > > analysis > > > > that can be done, the inliner is in the end heuristic based. In > > > > lack > > > > of the profile data, when inlining two calls yield the same > > > > static > > > > benefit and size cost, it is reasonable for the inliner to think > > > > the > > > > call to the function with inline hint to yield more high > > > > dynamic/runtime benefit -- thus it has a higher static size > > > > budget > > > > to > > > > burn. > > > > > > > > >We have reasons why we have done this > > > > > historically, and we can't just do an immediate about face, but > > > > > we > > > > > should be > > > > > actively looking for ways to *reduce* the optimizer's reliance > > > > > on > > > > > this > > > > > keyword to convey any meaning whatsoever. > > > > > > > > yes those additional things will be done, but they are really > > > > orthogonal. > > > > > > > > > > > > > > The reason I think that is the correct direction is because, > > > > > for > > > > > better or > > > > > worse, the 'inline' keyword in C++ is not about optimization, > > > > > but > > > > > about > > > > > linkage. > > > > > > > > It is about both optimization and linkage. In fact the linkage > > > > simply > > > > serves as an implementation detail. In C++ standard 7.1.2, > > > > paragraph > > > > 2 says: > > > > > > > > "A function declaration (8.3.5, 9.3, 11.3) with an inline > > > > specifier > > > > declares an inline function. The inline specifier indicates to > > > > the > > > > implementation that inline substitution of the function body at > > > > the > > > > point of call is to be preferred to the usual function call > > > > mechanism. > > > > An implementation is not required to perform this inline > > > > substitution > > > > at the point of call; however, even if this inline substitution > > > > is > > > > omitted, the other rules for inline functions defined by 7.1.2 > > > > shall > > > > still be respected." > > > > > > > > > > > > > > > > This describes Clang's current behavior, not the behavior you > > > > propose. > > > > > > > > > > > > Note that there is a difference between an "inline specifier" > > > > (meaning that the inline keyword appeared in the declaration, see > > > > the grammar description in paragraph 1 of 7.1.2, and the > > > > introductory text in 7.1) and a function being an "inline > > > > function" > > > > (meaning that multiple definitions are permitted in different > > > > translation units, see 3.2/4 and /6). > > > > > > > > > > > > The above wording clearly says that the inline *specifier* is a > > > > hint > > > > that we should inline the function, and... > > > > > > Is it really that clear? > > > > > > 1.3p3 says, "Terms that are used only in a small portion of this > > > International Standard are defined where they > > > are used and italicized where they are defined.". > > > > > > 7.1.2p2 says, "A function declaration (8.3.5, 9.3, 11.3) with an > > > inline specifier declares an inline function." and "inline > > > function" > > > is italicized there. Thus, "inline function", as a term, is > > > *defined* to be a function declared with an inline specifier. > > > > > > > > > We "misuse" italics in this way in various places, > > > where we define a > > > term and then later give some exceptions. (See 8.4.3/1 for example; > > > there are deleted functions that do not have that syntactic form.) > > > > > > > > > 7.1.2p3 then also says that a "function defined within a class > > > definition is an inline function." I would read this to mean, "as > > > if > > > it had an inline specifier", because that is how the term is > > > defined > > > in the paragraph above it. > > > > > > Reading the words in that way results in rejecting valid code. > > > Consider this: > > > > > > > > > struct X { > > > > > > constexpr int f(); >Oops, missing 'friend' here.> > > }; > > > > > > > > > 7.1.2/3 says "If the inline specifier is used in a friend > > > declaration, that declaration shall be a definition or the function > > > shall have previously been declared inline." > > > > > > > > > Now, a function declared with the constexpr specifier is implicitly > > > an inline function, but it is not declared with the inline > > > specifier > > > , so this program is well-formed. > > > > > > > I disagree. The standard simply provides a set of constructs that are > > also inline functions as if they had been declared with an inline > > specifier. >It says they are implicitly inline, specifically to call out the fact that they are inline functions *despite* not having an inline specifier. I don't see how you can read "A function declaration (8.3.5, 9.3, 11.3) with an inline specifier declares an inline function." as saying "There is no other way to declare an inline function, even though we give three others later, and all other inline functions act as if they had an inline specifier", italics or not. A specifier is an element of the grammar, and is (sometimes) not present in the other cases.> > And, frankly, I don't think the intent of the drafting was to > > > create > > > a bifurcated system. If we're to read "inline function" as > > > something > > > other than, "a function intended to be inlined", it seems the > > > standard would have used a different term to indicate the linkage > > > effect from the hinting. > > > > > > > > > It does; > > Also, I'll refer to whoever wrote > https://isocpp.org/wiki/faq/inline-functions, which is quite clear on the > matter... >That is obviously not normative text, doesn't reflect the unanimous consensus of the committee, and -- most embarrassingly -- seems to completely miss out the *actual* semantic impact of inline functions. [Chandler, we should get that FAQ entry fixed.] And I think you're still missing the point: whether we agree that the standard says there's an inline hint here is not even relevant, in and of itself. We should base our inlining on whatever gives the best results (by whatever criteria we judge those results); the standard gives us no normative requirements in this regard. What’s the deal with inline functions: When the compiler inline-expands a> function call, the function’s code gets inserted... There are several ways > to designate that a function is inline, some of which involve the inline > keyword, others do not. No matter how you designate a function as inline, > it is a request that ... > > Is there another way to tell the compiler to make a member function > inline?: Yep: define the member function in the class body itself: ... This > is often more convenient than the alternative of defining your inline > functions outside the class body. However, although it is easier on the > person who writes the class, it is harder on all the readers since it mixes > what a class does (the external behavior) with how it does it ... > > -Hal > > > > the terms are "declared with an inline specifier" and > > > "inline function" > > > > > > > To be pedantic, "declared with an inline specifier" does not seem to > > occur in the standard. The closest thing I see is 7.1.2p2, "A > > function declaration (8.3.5, 9.3, 11.3) with an inline specifier > > declares an inline function.", and that *defines* the term "inline > > function". > > > > > > > > In any case, the point is: it is not reasonable to use the > > > standard's > > > wording to justify when to provide an inline hint. > > > > It is perfectly reasonable; the standard contains a facility designed > > explicitly for this purpose, and it happens to be the facility under > > discussion. > > > > > Even if we agreed > > > that it said that any inline function is intended to undergo inline > > > substitution, that is only a non-binding suggestion due to the > > > as-if > > > rule, and we are under no obligation to base our inlining decision > > > on it. > > > > > > > Agreed. > > > > > > > > > > > > > > > Developers see those and rely on those to give compiler the > > > > hints. > > > > > > > > > > > > Likewise here, different developers have different expectations, so > > > I > > > don't think we can use this argument to make the decision. > > > > > > > > > There seem to be two relevant factors that should affect our > > > decision: > > > > > > > > > 1) What signals best indicate that inlining is beneficial for > > > existing code? That is, which heuristics make us optimize better? > > > and > > > > It is not quite that simple. We also need to give a high-quality user > > experience, and that means taking advantage of language facilities > > designed to provide optimization hints in a consistent way. Now we > > can debate what consistent is... ;) > > > > > 2) Which signals are reasonable for us to use, given the current > > > and > > > expected future state of the C++ language? We don't want people > > > contorting their code in order to get it well-optimized (such as > > > moving functions out of their class definition because they turn > > > out > > > to be somewhat non-trivial, and inlining them is harmful), > > > and we > > > want to allow inline hints to be given in ways that are orthogonal > > > to program semantics (the inline specifier is not good for this, > > > because it also carries real language semantics, not just an > > > optimization hint). > > > > > > > I agree this is an unfortunate combination of properties for 'inline' > > to have. But it was not done by accident, and the intent of the > > language seems to be not to give us the option of treating them > > separately and still provide a consistent user experience. We > > certainly *can* and still have a conforming implementation... we > > could also only consider the first 100 inline specifiers for hinting > > and ignore the rest. But, in my experience, users have expectations > > that inline functions are (at least more likely) to be inlined than > > other functions of similar size, and this includes functions defined > > in the class definition. Furthermore, the data seems to indicate > > that this is the right approach. > > > > I also don't want users to burden their code with the 'inline' > > keyword on nearly every (or every) in-class function definition > > because, even though defining it there is supposed to make it an > > inline function, that will make it a 'really inline' inline > > function. > > > > Thanks again, > > Hal > > > > > > > > > > > > > > > > > > Most importantly, paragraph 3 says: > > > > > > > > "A function defined within a class definition is an inline > > > > function. > > > > > > > > > > > > > > > > ... the same is *not* true for a function definition that appears > > > > within a class definition. That is merely an inline function > > > > (that > > > > is, it can be defined in multiple translation units). > > > > > > > > > > > > The inline specifier shall not appear on a block scope function > > > > declaration.93 If the inline specifier is used in a friend > > > > declaration, that declaration shall be a definition or the > > > > function > > > > shall have previously been declared inline." > > > > > > > > Here we can see regardless of how optimizer will honor the hint > > > > and > > > > to > > > > what extent, and based on what analysis, > > > > it is basically incorrect to drop the attribute on the floor for > > > > in-class function definitions. Eswaran's fix is justified with > > > > this > > > > reason alone. The side effect of changing inliner behavior is > > > > irrelevant. > > > > > > > > > It has a functional impact and can be both necessary or > > > > > impossible > > > > > to use to meet those functional requirements. This in turn > > > > > leaves > > > > > programmers in a lurch if the functional requirements are ever > > > > > in > > > > > tension > > > > > with the optimizer requirements. > > > > > > > > Not sure what you mean. Performance conscious programmers use it > > > > all > > > > the time. > > > > > > > > > > > > > > We're also working really hard to get more widely deployed > > > > > cross-module > > > > > optimization strategies, in part to free programmers from the > > > > > requirement > > > > > that they put all their performance critical code in header > > > > > files. > > > > > That > > > > > makes compilation faster, and has lots of benefits to the > > > > > factoring > > > > > and > > > > > design of the code itself. We shouldn't then create an > > > > > incentive > > > > > to > > > > > keep > > > > > things in header files so that they pick up a hint to the > > > > > optimizer. > > > > > > > > > > > > > > Ultimately, the world will be a better place if we can > > > > > eventually > > > > > move code > > > > > away from relying on the hint provided by the 'inline' keyword > > > > > to > > > > > the > > > > > optimizer. > > > > > > > > > > > > > While I would like to see that happen some day, I do think it is > > > > an > > > > independent matter. > > > > > > > > > > > > > > That doesn't mean that the core concept of hinting to the > > > > > optimizer > > > > > that a > > > > > particular function is a particularly good candidate for > > > > > inlining > > > > > is without > > > > > value. > > > > > > > > yes. > > > > > > > > >While I think it is a bad practice that we shouldn't encourage > > > > >in > > > > > code (especially portable code) > > > > > > > > yes -- there are indeed programmers who use this casually without > > > > considering performance. > > > > > > > > > I can see the desire to at least have *some* > > > > > attribute which is nothing more or less than a hint to the > > > > > optimizer to > > > > > inline harder[1]. > > > > > > > > yes -- there are programmers who use the attribute consciously. > > > > > > > > > It would help people work around inliner bugs in the short > > > > > term, and even help debug inliner-rooted optimization problems. > > > > > > > > I think it is a good hint to the compiler even in the longer > > > > term. > > > > With PGO, we should minimize the reliance on the hint though. > > > > > > > > >Codebases > > > > > with strong portability requirements could still (and probably > > > > > should) > > > > > forbid or tightly control access to this kind of hint. I would > > > > > want > > > > > really > > > > > strong documentation about how this attribute *completely > > > > > voids* > > > > > your > > > > > performance warranty (if such a thing exists) as from version > > > > > to > > > > > version of > > > > > the compiler it may go from a helpful hint to a devastatingly > > > > > bad > > > > > hint. > > > > > > > > Why? If the compiler becomes smarter and smarter, the inline hint > > > > will > > > > become more and more irrelevant and eventually has no effect -- > > > > why > > > > would the performance warranty be voided? If the compiler is not > > > > yet > > > > smart enough, why would the compiler refuse to take the hint and > > > > forbid developer provide the hint? > > > > > > > > > But > > > > > I think I could be persuaded to live with such a hint existing. > > > > > But > > > > > I'm > > > > > *really* uncomfortable with it being tied to something that > > > > > also > > > > > impacts > > > > > linkage or other semantics of the program. > > > > > > > > For consistent with standard, we should pass the attribute. > > > > Linkage > > > > is > > > > not affected in anyway. > > > > > > > > > > > > > > [1]: Currently, the only other hint we have available is pretty > > > > > terrible as > > > > > it *also* has semantic effects: the always_inline attribute. > > > > > > > > > > > > > > >> > > > > >> The proposed patch will add InlineHint to methods defined > > > > >> inside > > > > >> a > > > > >> class: > > > > >> > > > > >> --- a/lib/CodeGen/CodeGenFunction.cpp > > > > >> +++ b/lib/CodeGen/CodeGenFunction.cpp > > > > >> @@ -630,7 +630,7 @@ void > > > > >> CodeGenFunction::StartFunction(GlobalDecl > > > > >> GD, > > > > >> if (const FunctionDecl *FD > > > > >> dyn_cast_or_null<FunctionDecl>(D)) > > > > >> { > > > > >> if (!CGM.getCodeGenOpts().NoInline) { > > > > >> for (auto RI : FD->redecls()) > > > > >> - if (RI->isInlineSpecified()) { > > > > >> + if (RI->isInlined()) { > > > > >> Fn->addFnAttr(llvm::Attribute::InlineHint); > > > > >> break; > > > > >> } > > > > >> > > > > >> Here are the performance and size numbers I've collected: > > > > >> > > > > >> > > > > >> - C++ subset of Spec: No performance effects, < 0.1% size > > > > >> increase > > > > >> (all size numbers are text sizes returned by 'size') > > > > >> - Clang: 0.9% performance improvement (both -O0 and -O2 on a > > > > >> large > > > > >> .ii > > > > >> file) , 4.1% size increase > > > > > > > > > > > > > > > FWIW, this size increase seems *really* bad. I think that kills > > > > > this > > > > > approach even in the short term. > > > > > > > > Re. size and performance trade-off -- 0.9% performance > > > > improvement > > > > should greatly win the size cost. Besides among all programs see, > > > > only > > > > clang sees this size increase with all the others seeing > > > > negligible > > > > size increase. > > > > > > > > This is not a short term vs long term situation. It is basically > > > > a > > > > bug > > > > fix that FE drops the attribute. If it exposes inliner heuristic > > > > bug, > > > > that should be fixed/tuned separately. With the hint correctly > > > > passed > > > > in, Easwaran will do further tuning including time based > > > > analysis. > > > > > > > > > > > > > >> > > > > >> - Chrome: no performance improvement, 0.24% size increase > > > > >> - Google internal benchmark suite (geomean of ~20 benchmarks): > > > > >> ~1.8% > > > > >> performance improvement, no size regression > > > > > > > > > > > > > > > I'm also somewhat worried about the lack of any performance > > > > > improvements > > > > > outside of the Google benchmarks. That somewhat strongly > > > > > suggests > > > > > that our > > > > > benchmarks are overly coupled to this hint already. The fact > > > > > that > > > > > neither > > > > > Chrome, Clang, nor SPEC improved is... not at all encouraging. > > > > > > > > Other than Google benchmarks, we do see Clang improve > > > > performance. > > > > Besides, current inliner needs to be further tuned in order to > > > > get > > > > more performance benefit. Passing the hint through is simply an > > > > enabler. Also remember that most of SPEC benchmarks are C > > > > programs. > > > > C++ programs with heavy use of virtual functions may not benefit > > > > a > > > > lot > > > > either. > > > > > > > > David > > > > > > > > > > > > > > > > > > -Chandler > > > > _______________________________________________ > > > > cfe-commits mailing list > > > > cfe-commits at cs.uiuc.edu > > > > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits > > > > > > > > > > > > _______________________________________________ > > > > cfe-commits mailing list > > > > cfe-commits at cs.uiuc.edu > > > > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits > > > > > > > > > > > > > > > > -- > > > Hal Finkel > > > Assistant Computational Scientist > > > Leadership Computing Facility > > > Argonne National Laboratory > > > > > > > > > > -- > > Hal Finkel > > Assistant Computational Scientist > > Leadership Computing Facility > > Argonne National Laboratory > > _______________________________________________ > > cfe-commits mailing list > > cfe-commits at cs.uiuc.edu > > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits > > > > -- > Hal Finkel > Assistant Computational Scientist > Leadership Computing Facility > Argonne National Laboratory >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150710/13e8eeb4/attachment.html>
----- Original Message -----> From: "Richard Smith" <richard at metafoo.co.uk> > To: "Hal Finkel" <hfinkel at anl.gov>, "Chandler Carruth" <chandlerc at google.com> > Cc: "Xinliang David Li" <davidxl at google.com>, "cfe commits" <cfe-commits at cs.uiuc.edu>, "List" <llvmdev at cs.uiuc.edu> > Sent: Friday, July 10, 2015 12:43:20 PM > Subject: Re: [LLVMdev] Inline hint for methods defined in-class > > On Thu, Jul 9, 2015 at 7:52 PM, Hal Finkel < hfinkel at anl.gov > wrote: > > ----- Original Message ----- > > From: "Hal Finkel" < hfinkel at anl.gov > > > To: "Richard Smith" < richard at metafoo.co.uk > > > Cc: "Xinliang David Li" < davidxl at google.com >, "cfe commits" < > > cfe-commits at cs.uiuc.edu >, "List" < llvmdev at cs.uiuc.edu > > > Sent: Thursday, July 9, 2015 8:46:22 PM > > Subject: Re: [LLVMdev] Inline hint for methods defined in-class > > > > ----- Original Message ----- > > > From: "Richard Smith" < richard at metafoo.co.uk > > > > To: "Hal Finkel" < hfinkel at anl.gov > > > > Cc: "cfe commits" < cfe-commits at cs.uiuc.edu >, "List" > > > < llvmdev at cs.uiuc.edu >, "Xinliang David Li" < davidxl at google.com > > > > > > > Sent: Thursday, July 9, 2015 8:08:38 PM > > > Subject: Re: [LLVMdev] Inline hint for methods defined in-class > > > > > > On Thu, Jul 9, 2015 at 4:30 PM, Hal Finkel < hfinkel at anl.gov > > > > wrote: > > > > > > > > > ----- Original Message ----- > > > > From: "Richard Smith" < richard at metafoo.co.uk > > > > > To: "Xinliang David Li" < davidxl at google.com > > > > > Cc: "cfe commits" < cfe-commits at cs.uiuc.edu >, "< > > > > llvmdev at cs.uiuc.edu > List" < llvmdev at cs.uiuc.edu > > > > > Sent: Thursday, July 9, 2015 3:40:54 PM > > > > Subject: Re: [LLVMdev] Inline hint for methods defined in-class > > > > > > > > > > > > > > On Tue, Jul 7, 2015 at 10:25 PM, Xinliang David Li < > > > > davidxl at google.com > wrote: > > > > > > > > > > > > On Tue, Jul 7, 2015 at 6:06 PM, Chandler Carruth < > > > > chandlerc at gmail.com > wrote: > > > > > On Tue, Jul 7, 2015 at 4:11 PM Easwaran Raman < > > > > > eraman at google.com > > > > > > > > > > > wrote: > > > > >> > > > > >> I'm reviving this thread after a while and CCing cfe-commits > > > > >> as > > > > >> suggested by David Blaikie. I've also collected numbers > > > > >> building > > > > >> chrome (from chromium, on Linux) with and without this patch > > > > >> as > > > > >> suggested by David. I've re-posted the proposed patch and > > > > >> performance/size numbers collected at the top to make it > > > > >> easily > > > > >> readable for those reading it through cfe-commits. > > > > > > > > > > > > > > > First off, thanks for collecting the numbers and broadening > > > > > the > > > > > distribution. Also, sorry it took me so long to get over to > > > > > this > > > > > thread. > > > > > > > > > > I want to lay out my stance on this issue at a theoretical > > > > > and > > > > > practical > > > > > level first. I'll follow up with thoughts on the numbers as > > > > > well > > > > > after that. > > > > > > > > > > I think that tying *any* optimizer behavior to the 'inline' > > > > > keyword > > > > > is > > > > > fundamentally the wrong direction. > > > > > > > > Chandler, thanks for sharing your thought -- however I don't > > > > think > > > > it > > > > is wrong, let alone 'fundamentally wrong'. Despite all the > > > > analysis > > > > that can be done, the inliner is in the end heuristic based. In > > > > lack > > > > of the profile data, when inlining two calls yield the same > > > > static > > > > benefit and size cost, it is reasonable for the inliner to > > > > think > > > > the > > > > call to the function with inline hint to yield more high > > > > dynamic/runtime benefit -- thus it has a higher static size > > > > budget > > > > to > > > > burn. > > > > > > > > >We have reasons why we have done this > > > > > historically, and we can't just do an immediate about face, > > > > > but > > > > > we > > > > > should be > > > > > actively looking for ways to *reduce* the optimizer's > > > > > reliance > > > > > on > > > > > this > > > > > keyword to convey any meaning whatsoever. > > > > > > > > yes those additional things will be done, but they are really > > > > orthogonal. > > > > > > > > > > > > > > The reason I think that is the correct direction is because, > > > > > for > > > > > better or > > > > > worse, the 'inline' keyword in C++ is not about optimization, > > > > > but > > > > > about > > > > > linkage. > > > > > > > > It is about both optimization and linkage. In fact the linkage > > > > simply > > > > serves as an implementation detail. In C++ standard 7.1.2, > > > > paragraph > > > > 2 says: > > > > > > > > "A function declaration (8.3.5, 9.3, 11.3) with an inline > > > > specifier > > > > declares an inline function. The inline specifier indicates to > > > > the > > > > implementation that inline substitution of the function body at > > > > the > > > > point of call is to be preferred to the usual function call > > > > mechanism. > > > > An implementation is not required to perform this inline > > > > substitution > > > > at the point of call; however, even if this inline substitution > > > > is > > > > omitted, the other rules for inline functions defined by 7.1.2 > > > > shall > > > > still be respected." > > > > > > > > > > > > > > > > This describes Clang's current behavior, not the behavior you > > > > propose. > > > > > > > > > > > > Note that there is a difference between an "inline specifier" > > > > (meaning that the inline keyword appeared in the declaration, > > > > see > > > > the grammar description in paragraph 1 of 7.1.2, and the > > > > introductory text in 7.1) and a function being an "inline > > > > function" > > > > (meaning that multiple definitions are permitted in different > > > > translation units, see 3.2/4 and /6). > > > > > > > > > > > > The above wording clearly says that the inline *specifier* is a > > > > hint > > > > that we should inline the function, and... > > > > > > Is it really that clear? > > > > > > 1.3p3 says, "Terms that are used only in a small portion of this > > > International Standard are defined where they > > > are used and italicized where they are defined.". > > > > > > 7.1.2p2 says, "A function declaration (8.3.5, 9.3, 11.3) with an > > > inline specifier declares an inline function." and "inline > > > function" > > > is italicized there. Thus, "inline function", as a term, is > > > *defined* to be a function declared with an inline specifier. > > > > > > > > > We "misuse" italics in this way in various places, > > > where we define a > > > term and then later give some exceptions. (See 8.4.3/1 for > > > example; > > > there are deleted functions that do not have that syntactic > > > form.) > > > > > > > > > 7.1.2p3 then also says that a "function defined within a class > > > definition is an inline function." I would read this to mean, "as > > > if > > > it had an inline specifier", because that is how the term is > > > defined > > > in the paragraph above it. > > > > > > Reading the words in that way results in rejecting valid code. > > > Consider this: > > > > > > > > > struct X { > > > > > > constexpr int f(); > > > > Oops, missing 'friend' here. > > > > > > > }; > > > > > > > > > 7.1.2/3 says "If the inline specifier is used in a friend > > > declaration, that declaration shall be a definition or the > > > function > > > shall have previously been declared inline." > > > > > > > > > Now, a function declared with the constexpr specifier is > > > implicitly > > > an inline function, but it is not declared with the inline > > > specifier > > > , so this program is well-formed. > > > > > > > I disagree. The standard simply provides a set of constructs that > > are > > also inline functions as if they had been declared with an inline > > specifier. > > It says they are implicitly inline, specifically to call out the fact > that they are inline functions *despite* not having an inline > specifier. I don't see how you can read "A function declaration > (8.3.5, 9.3, 11.3) with an inline specifier declares an inline > function." as saying "There is no other way to declare an inline > function, even though we give three others later, and all other > inline functions act as if they had an inline specifier", italics or > not. A specifier is an element of the grammar, and is (sometimes) > not present in the other cases. >I did not say I'm reading it to say that there's no other way to declare an inline function, as you point out, there are three others later. I'm saying that all of these ways of declaring an inline function have the same properties conferred upon them by being inline functions. They are, after all, called "inline" functions, where inlining is a preexisting term of art, and can be assumed to convey some meaning as such.> > > > > > > And, frankly, I don't think the intent of the drafting was to > > > create > > > a bifurcated system. If we're to read "inline function" as > > > something > > > other than, "a function intended to be inlined", it seems the > > > standard would have used a different term to indicate the linkage > > > effect from the hinting. > > > > > > > > > It does; > > Also, I'll refer to whoever wrote > https://isocpp.org/wiki/faq/inline-functions , which is quite clear > on the matter... > > That is obviously not normative text, doesn't reflect the unanimous > consensus of the committee,Evidently not, but I'm also not sure that 'unanimous consensus' is an appropriate standard.> and -- most embarrassingly -- seems to > completely miss out the *actual* semantic impact of inline > functions. [Chandler, we should get that FAQ entry fixed.]The problem is that it is not just *that* FAQ, Google also ranks this one pretty highly: http://www.cprogramming.com/tips/tip/member-functions-are-inline-by-default-cincrement The same is true in plenty of books too. For example, from the first book Google book search finds for "inline member function": "Object-oriented Programming: Using C++ for Engineering and Technology" by Goran Svenk (2003), says, "To create an inline member function, it is only necessary to place the function's definition inside the class. It is not necessary to use the inline keyword in this case, as is the case with non-member functions. Some functions -- long functions, recursive functions, ... -- cannot be expanded inline. If a member function falls into one of these categories and its definition is placed within the body of the class, the compiler will usually issue a warning message and process the function as a non-inline member function." I don't particularly like this explanation, and the last statement may not be entirely correct, but the point relevant to our discussion is clear. There is a significant portion of the skilled C++ programming community that shares the view for which I'm advocating. And to be clear, I'm advocating this viewpoint because I believe it is the prevailing viewpoint among C++ programmers. The fact that these FAQs, books, etc. agree with me I simply take as evidence that it is the prevailing viewpoint. As I've said, I don't particularly like the current state of affairs -- it is particularly problematic for the creation of header-only libraries: If you wish to create a header-only library, and you follow reasonable coding practices, the functions that you define in the class definitions are likely to be small and the functions you define outside the class definitions are likely to be larger. This, I think, is the most readable approach. However, even if you don't put the inline keyword on the in-class definitions, you do need to put it explicitly on the (larger) out-of-class definitions to avoid ODR violation. This is exactly the opposite of what you want: those larger functions are precisely the ones likely to be less suitable for inlining. However, if we're trying to fix that problem by not treating in-class functions definitions the same way we treat other functions with the inline keyword, we're missing most of the problem, and creating a quirky implementation in the process. The real problem is large functions that need the inline keyword to avoid ODR violation. But for that, we need a separate solution.> > > And I think you're still missing the point: whether we agree that the > standard says there's an inline hint here is not even relevant, in > and of itself. We should base our inlining on whatever gives the > best results (by whatever criteria we judge those results); the > standard gives us no normative requirements in this regard.I agree, but the standard does set a user expectation in this regard. And we should have a really good reason to violate that expectation, and we don't. The data seems to suggest that we're currently not doing the optimal thing, and that aligning our inlining heuristic with that expectation yields better performance results. That having been said, the fact that this expectation comes directly from the standard, gives it significantly more weight than it might have otherwise. That's my point: I'm not saying that our current implementation is not conforming, but I'm saying that it is providing a sub-optimal user experience by not satisfying the expectations that users have in this regard; expectations that come directly from the standard. Thanks again, Hal> > > What’s the deal with inline functions: When the compiler > inline-expands a function call, the function’s code gets inserted... > There are several ways to designate that a function is inline, some > of which involve the inline keyword, others do not. No matter how > you designate a function as inline, it is a request that ... > > Is there another way to tell the compiler to make a member function > inline?: Yep: define the member function in the class body itself: > ... This is often more convenient than the alternative of defining > your inline functions outside the class body. However, although it > is easier on the person who writes the class, it is harder on all > the readers since it mixes what a class does (the external behavior) > with how it does it ... > > -Hal > > > > > > the terms are "declared with an inline specifier" and > > > "inline function" > > > > > > > To be pedantic, "declared with an inline specifier" does not seem > > to > > occur in the standard. The closest thing I see is 7.1.2p2, "A > > function declaration (8.3.5, 9.3, 11.3) with an inline specifier > > declares an inline function.", and that *defines* the term "inline > > function". > > > > > > > > In any case, the point is: it is not reasonable to use the > > > standard's > > > wording to justify when to provide an inline hint. > > > > It is perfectly reasonable; the standard contains a facility > > designed > > explicitly for this purpose, and it happens to be the facility > > under > > discussion. > > > > > Even if we agreed > > > that it said that any inline function is intended to undergo > > > inline > > > substitution, that is only a non-binding suggestion due to the > > > as-if > > > rule, and we are under no obligation to base our inlining > > > decision > > > on it. > > > > > > > Agreed. > > > > > > > > > > > > > > > Developers see those and rely on those to give compiler the > > > > hints. > > > > > > > > > > > > Likewise here, different developers have different expectations, > > > so > > > I > > > don't think we can use this argument to make the decision. > > > > > > > > > There seem to be two relevant factors that should affect our > > > decision: > > > > > > > > > 1) What signals best indicate that inlining is beneficial for > > > existing code? That is, which heuristics make us optimize better? > > > and > > > > It is not quite that simple. We also need to give a high-quality > > user > > experience, and that means taking advantage of language facilities > > designed to provide optimization hints in a consistent way. Now we > > can debate what consistent is... ;) > > > > > 2) Which signals are reasonable for us to use, given the current > > > and > > > expected future state of the C++ language? We don't want people > > > contorting their code in order to get it well-optimized (such as > > > moving functions out of their class definition because they turn > > > out > > > to be somewhat non-trivial, and inlining them is harmful), > > > and we > > > want to allow inline hints to be given in ways that are > > > orthogonal > > > to program semantics (the inline specifier is not good for this, > > > because it also carries real language semantics, not just an > > > optimization hint). > > > > > > > I agree this is an unfortunate combination of properties for > > 'inline' > > to have. But it was not done by accident, and the intent of the > > language seems to be not to give us the option of treating them > > separately and still provide a consistent user experience. We > > certainly *can* and still have a conforming implementation... we > > could also only consider the first 100 inline specifiers for > > hinting > > and ignore the rest. But, in my experience, users have expectations > > that inline functions are (at least more likely) to be inlined than > > other functions of similar size, and this includes functions > > defined > > in the class definition. Furthermore, the data seems to indicate > > that this is the right approach. > > > > I also don't want users to burden their code with the 'inline' > > keyword on nearly every (or every) in-class function definition > > because, even though defining it there is supposed to make it an > > inline function, that will make it a 'really inline' inline > > function. > > > > Thanks again, > > Hal > > > > > > > > > > > > > > > > > > Most importantly, paragraph 3 says: > > > > > > > > "A function defined within a class definition is an inline > > > > function. > > > > > > > > > > > > > > > > ... the same is *not* true for a function definition that > > > > appears > > > > within a class definition. That is merely an inline function > > > > (that > > > > is, it can be defined in multiple translation units). > > > > > > > > > > > > The inline specifier shall not appear on a block scope function > > > > declaration.93 If the inline specifier is used in a friend > > > > declaration, that declaration shall be a definition or the > > > > function > > > > shall have previously been declared inline." > > > > > > > > Here we can see regardless of how optimizer will honor the hint > > > > and > > > > to > > > > what extent, and based on what analysis, > > > > it is basically incorrect to drop the attribute on the floor > > > > for > > > > in-class function definitions. Eswaran's fix is justified with > > > > this > > > > reason alone. The side effect of changing inliner behavior is > > > > irrelevant. > > > > > > > > > It has a functional impact and can be both necessary or > > > > > impossible > > > > > to use to meet those functional requirements. This in turn > > > > > leaves > > > > > programmers in a lurch if the functional requirements are > > > > > ever > > > > > in > > > > > tension > > > > > with the optimizer requirements. > > > > > > > > Not sure what you mean. Performance conscious programmers use > > > > it > > > > all > > > > the time. > > > > > > > > > > > > > > We're also working really hard to get more widely deployed > > > > > cross-module > > > > > optimization strategies, in part to free programmers from the > > > > > requirement > > > > > that they put all their performance critical code in header > > > > > files. > > > > > That > > > > > makes compilation faster, and has lots of benefits to the > > > > > factoring > > > > > and > > > > > design of the code itself. We shouldn't then create an > > > > > incentive > > > > > to > > > > > keep > > > > > things in header files so that they pick up a hint to the > > > > > optimizer. > > > > > > > > > > > > > > Ultimately, the world will be a better place if we can > > > > > eventually > > > > > move code > > > > > away from relying on the hint provided by the 'inline' > > > > > keyword > > > > > to > > > > > the > > > > > optimizer. > > > > > > > > > > > > > While I would like to see that happen some day, I do think it > > > > is > > > > an > > > > independent matter. > > > > > > > > > > > > > > That doesn't mean that the core concept of hinting to the > > > > > optimizer > > > > > that a > > > > > particular function is a particularly good candidate for > > > > > inlining > > > > > is without > > > > > value. > > > > > > > > yes. > > > > > > > > >While I think it is a bad practice that we shouldn't encourage > > > > >in > > > > > code (especially portable code) > > > > > > > > yes -- there are indeed programmers who use this casually > > > > without > > > > considering performance. > > > > > > > > > I can see the desire to at least have *some* > > > > > attribute which is nothing more or less than a hint to the > > > > > optimizer to > > > > > inline harder[1]. > > > > > > > > yes -- there are programmers who use the attribute consciously. > > > > > > > > > It would help people work around inliner bugs in the short > > > > > term, and even help debug inliner-rooted optimization > > > > > problems. > > > > > > > > I think it is a good hint to the compiler even in the longer > > > > term. > > > > With PGO, we should minimize the reliance on the hint though. > > > > > > > > >Codebases > > > > > with strong portability requirements could still (and > > > > > probably > > > > > should) > > > > > forbid or tightly control access to this kind of hint. I > > > > > would > > > > > want > > > > > really > > > > > strong documentation about how this attribute *completely > > > > > voids* > > > > > your > > > > > performance warranty (if such a thing exists) as from version > > > > > to > > > > > version of > > > > > the compiler it may go from a helpful hint to a devastatingly > > > > > bad > > > > > hint. > > > > > > > > Why? If the compiler becomes smarter and smarter, the inline > > > > hint > > > > will > > > > become more and more irrelevant and eventually has no effect -- > > > > why > > > > would the performance warranty be voided? If the compiler is > > > > not > > > > yet > > > > smart enough, why would the compiler refuse to take the hint > > > > and > > > > forbid developer provide the hint? > > > > > > > > > But > > > > > I think I could be persuaded to live with such a hint > > > > > existing. > > > > > But > > > > > I'm > > > > > *really* uncomfortable with it being tied to something that > > > > > also > > > > > impacts > > > > > linkage or other semantics of the program. > > > > > > > > For consistent with standard, we should pass the attribute. > > > > Linkage > > > > is > > > > not affected in anyway. > > > > > > > > > > > > > > [1]: Currently, the only other hint we have available is > > > > > pretty > > > > > terrible as > > > > > it *also* has semantic effects: the always_inline attribute. > > > > > > > > > > > > > > >> > > > > >> The proposed patch will add InlineHint to methods defined > > > > >> inside > > > > >> a > > > > >> class: > > > > >> > > > > >> --- a/lib/CodeGen/CodeGenFunction.cpp > > > > >> +++ b/lib/CodeGen/CodeGenFunction.cpp > > > > >> @@ -630,7 +630,7 @@ void > > > > >> CodeGenFunction::StartFunction(GlobalDecl > > > > >> GD, > > > > >> if (const FunctionDecl *FD > > > > >> dyn_cast_or_null<FunctionDecl>(D)) > > > > >> { > > > > >> if (!CGM.getCodeGenOpts().NoInline) { > > > > >> for (auto RI : FD->redecls()) > > > > >> - if (RI->isInlineSpecified()) { > > > > >> + if (RI->isInlined()) { > > > > >> Fn->addFnAttr(llvm::Attribute::InlineHint); > > > > >> break; > > > > >> } > > > > >> > > > > >> Here are the performance and size numbers I've collected: > > > > >> > > > > >> > > > > >> - C++ subset of Spec: No performance effects, < 0.1% size > > > > >> increase > > > > >> (all size numbers are text sizes returned by 'size') > > > > >> - Clang: 0.9% performance improvement (both -O0 and -O2 on a > > > > >> large > > > > >> .ii > > > > >> file) , 4.1% size increase > > > > > > > > > > > > > > > FWIW, this size increase seems *really* bad. I think that > > > > > kills > > > > > this > > > > > approach even in the short term. > > > > > > > > Re. size and performance trade-off -- 0.9% performance > > > > improvement > > > > should greatly win the size cost. Besides among all programs > > > > see, > > > > only > > > > clang sees this size increase with all the others seeing > > > > negligible > > > > size increase. > > > > > > > > This is not a short term vs long term situation. It is > > > > basically > > > > a > > > > bug > > > > fix that FE drops the attribute. If it exposes inliner > > > > heuristic > > > > bug, > > > > that should be fixed/tuned separately. With the hint correctly > > > > passed > > > > in, Easwaran will do further tuning including time based > > > > analysis. > > > > > > > > > > > > > >> > > > > >> - Chrome: no performance improvement, 0.24% size increase > > > > >> - Google internal benchmark suite (geomean of ~20 > > > > >> benchmarks): > > > > >> ~1.8% > > > > >> performance improvement, no size regression > > > > > > > > > > > > > > > I'm also somewhat worried about the lack of any performance > > > > > improvements > > > > > outside of the Google benchmarks. That somewhat strongly > > > > > suggests > > > > > that our > > > > > benchmarks are overly coupled to this hint already. The fact > > > > > that > > > > > neither > > > > > Chrome, Clang, nor SPEC improved is... not at all > > > > > encouraging. > > > > > > > > Other than Google benchmarks, we do see Clang improve > > > > performance. > > > > Besides, current inliner needs to be further tuned in order to > > > > get > > > > more performance benefit. Passing the hint through is simply an > > > > enabler. Also remember that most of SPEC benchmarks are C > > > > programs. > > > > C++ programs with heavy use of virtual functions may not > > > > benefit > > > > a > > > > lot > > > > either. > > > > > > > > David > > > > > > > > > > > > > > > > > > -Chandler > > > > _______________________________________________ > > > > cfe-commits mailing list > > > > cfe-commits at cs.uiuc.edu > > > > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits > > > > > > > > > > > > _______________________________________________ > > > > cfe-commits mailing list > > > > cfe-commits at cs.uiuc.edu > > > > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits > > > > > > > > > > > > > > > > -- > > > Hal Finkel > > > Assistant Computational Scientist > > > Leadership Computing Facility > > > Argonne National Laboratory > > > > > > > > > > -- > > Hal Finkel > > Assistant Computational Scientist > > Leadership Computing Facility > > Argonne National Laboratory > > _______________________________________________ > > cfe-commits mailing list > > cfe-commits at cs.uiuc.edu > > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits > > > > -- > Hal Finkel > Assistant Computational Scientist > Leadership Computing Facility > Argonne National Laboratory > >-- Hal Finkel Assistant Computational Scientist Leadership Computing Facility Argonne National Laboratory
Xinliang David Li
2015-Jul-10 19:42 UTC
[LLVMdev] Inline hint for methods defined in-class
> Evidently not, but I'm also not sure that 'unanimous consensus' is an appropriate standard. > >> and -- most embarrassingly -- seems to >> completely miss out the *actual* semantic impact of inline >> functions. [Chandler, we should get that FAQ entry fixed.] > > The problem is that it is not just *that* FAQ, Google also ranks this one pretty highly: > > http://www.cprogramming.com/tips/tip/member-functions-are-inline-by-default-cincrement > > The same is true in plenty of books too. For example, from the first book Google book search finds for "inline member function": "Object-oriented Programming: Using C++ for Engineering and Technology" by Goran Svenk (2003), says, "To create an inline member function, it is only necessary to place the function's definition inside the class. It is not necessary to use the inline keyword in this case, as is the case with non-member functions. Some functions -- long functions, recursive functions, ... -- cannot be expanded inline. If a member function falls into one of these categories and its definition is placed within the body of the class, the compiler will usually issue a warning message and process the function as a non-inline member function." > > I don't particularly like this explanation, and the last statement may not be entirely correct, but the point relevant to our discussion is clear. There is a significant portion of the skilled C++ programming community that shares the view for which I'm advocating. And to be clear, I'm advocating this viewpoint because I believe it is the prevailing viewpoint among C++ programmers. The fact that these FAQs, books, etc. agree with me I simply take as evidence that it is the prevailing viewpoint. >yes -- developers (except for compiler developers) won't know the differences between 'inline functions' vs 'inline specified functions', not to mention the exact intention of the standard is subject to debate. David> As I've said, I don't particularly like the current state of affairs -- it is particularly problematic for the creation of header-only libraries: If you wish to create a header-only library, and you follow reasonable coding practices, the functions that you define in the class definitions are likely to be small and the functions you define outside the class definitions are likely to be larger. This, I think, is the most readable approach. However, even if you don't put the inline keyword on the in-class definitions, you do need to put it explicitly on the (larger) out-of-class definitions to avoid ODR violation. This is exactly the opposite of what you want: those larger functions are precisely the ones likely to be less suitable for inlining. > > However, if we're trying to fix that problem by not treating in-class functions definitions the same way we treat other functions with the inline keyword, we're missing most of the problem, and creating a quirky implementation in the process. The real problem is large functions that need the inline keyword to avoid ODR violation. But for that, we need a separate solution. > >> >> >> And I think you're still missing the point: whether we agree that the >> standard says there's an inline hint here is not even relevant, in >> and of itself. We should base our inlining on whatever gives the >> best results (by whatever criteria we judge those results); the >> standard gives us no normative requirements in this regard. > > I agree, but the standard does set a user expectation in this regard. And we should have a really good reason to violate that expectation, and we don't. The data seems to suggest that we're currently not doing the optimal thing, and that aligning our inlining heuristic with that expectation yields better performance results. That having been said, the fact that this expectation comes directly from the standard, gives it significantly more weight than it might have otherwise. That's my point: I'm not saying that our current implementation is not conforming, but I'm saying that it is providing a sub-optimal user experience by not satisfying the expectations that users have in this regard; expectations that come directly from the standard. > > Thanks again, > Hal > >> >> >> What’s the deal with inline functions: When the compiler >> inline-expands a function call, the function’s code gets inserted... >> There are several ways to designate that a function is inline, some >> of which involve the inline keyword, others do not. No matter how >> you designate a function as inline, it is a request that ... >> >> Is there another way to tell the compiler to make a member function >> inline?: Yep: define the member function in the class body itself: >> ... This is often more convenient than the alternative of defining >> your inline functions outside the class body. However, although it >> is easier on the person who writes the class, it is harder on all >> the readers since it mixes what a class does (the external behavior) >> with how it does it ... >> >> -Hal >> >> >> >> >> > the terms are "declared with an inline specifier" and >> > > "inline function" >> > > >> > >> > To be pedantic, "declared with an inline specifier" does not seem >> > to >> > occur in the standard. The closest thing I see is 7.1.2p2, "A >> > function declaration (8.3.5, 9.3, 11.3) with an inline specifier >> > declares an inline function.", and that *defines* the term "inline >> > function". >> > >> > > >> > > In any case, the point is: it is not reasonable to use the >> > > standard's >> > > wording to justify when to provide an inline hint. >> > >> > It is perfectly reasonable; the standard contains a facility >> > designed >> > explicitly for this purpose, and it happens to be the facility >> > under >> > discussion. >> > >> > > Even if we agreed >> > > that it said that any inline function is intended to undergo >> > > inline >> > > substitution, that is only a non-binding suggestion due to the >> > > as-if >> > > rule, and we are under no obligation to base our inlining >> > > decision >> > > on it. >> > > >> > >> > Agreed. >> > >> > > >> > > >> > > >> > > > Developers see those and rely on those to give compiler the >> > > > hints. >> > > >> > > >> > > >> > > Likewise here, different developers have different expectations, >> > > so >> > > I >> > > don't think we can use this argument to make the decision. >> > > >> > > >> > > There seem to be two relevant factors that should affect our >> > > decision: >> > > >> > > >> > > 1) What signals best indicate that inlining is beneficial for >> > > existing code? That is, which heuristics make us optimize better? >> > > and >> > >> > It is not quite that simple. We also need to give a high-quality >> > user >> > experience, and that means taking advantage of language facilities >> > designed to provide optimization hints in a consistent way. Now we >> > can debate what consistent is... ;) >> > >> > > 2) Which signals are reasonable for us to use, given the current >> > > and >> > > expected future state of the C++ language? We don't want people >> > > contorting their code in order to get it well-optimized (such as >> > > moving functions out of their class definition because they turn >> > > out >> > > to be somewhat non-trivial, and inlining them is harmful), >> > > and we >> > > want to allow inline hints to be given in ways that are >> > > orthogonal >> > > to program semantics (the inline specifier is not good for this, >> > > because it also carries real language semantics, not just an >> > > optimization hint). >> > > >> > >> > I agree this is an unfortunate combination of properties for >> > 'inline' >> > to have. But it was not done by accident, and the intent of the >> > language seems to be not to give us the option of treating them >> > separately and still provide a consistent user experience. We >> > certainly *can* and still have a conforming implementation... we >> > could also only consider the first 100 inline specifiers for >> > hinting >> > and ignore the rest. But, in my experience, users have expectations >> > that inline functions are (at least more likely) to be inlined than >> > other functions of similar size, and this includes functions >> > defined >> > in the class definition. Furthermore, the data seems to indicate >> > that this is the right approach. >> > >> > I also don't want users to burden their code with the 'inline' >> > keyword on nearly every (or every) in-class function definition >> > because, even though defining it there is supposed to make it an >> > inline function, that will make it a 'really inline' inline >> > function. >> > >> > Thanks again, >> > Hal >> > >> > > >> > > >> > > >> > > >> > > > Most importantly, paragraph 3 says: >> > > > >> > > > "A function defined within a class definition is an inline >> > > > function. >> > > > >> > > > >> > > > >> > > > ... the same is *not* true for a function definition that >> > > > appears >> > > > within a class definition. That is merely an inline function >> > > > (that >> > > > is, it can be defined in multiple translation units). >> > > > >> > > > >> > > > The inline specifier shall not appear on a block scope function >> > > > declaration.93 If the inline specifier is used in a friend >> > > > declaration, that declaration shall be a definition or the >> > > > function >> > > > shall have previously been declared inline." >> > > > >> > > > Here we can see regardless of how optimizer will honor the hint >> > > > and >> > > > to >> > > > what extent, and based on what analysis, >> > > > it is basically incorrect to drop the attribute on the floor >> > > > for >> > > > in-class function definitions. Eswaran's fix is justified with >> > > > this >> > > > reason alone. The side effect of changing inliner behavior is >> > > > irrelevant. >> > > > >> > > > > It has a functional impact and can be both necessary or >> > > > > impossible >> > > > > to use to meet those functional requirements. This in turn >> > > > > leaves >> > > > > programmers in a lurch if the functional requirements are >> > > > > ever >> > > > > in >> > > > > tension >> > > > > with the optimizer requirements. >> > > > >> > > > Not sure what you mean. Performance conscious programmers use >> > > > it >> > > > all >> > > > the time. >> > > > >> > > > > >> > > > > We're also working really hard to get more widely deployed >> > > > > cross-module >> > > > > optimization strategies, in part to free programmers from the >> > > > > requirement >> > > > > that they put all their performance critical code in header >> > > > > files. >> > > > > That >> > > > > makes compilation faster, and has lots of benefits to the >> > > > > factoring >> > > > > and >> > > > > design of the code itself. We shouldn't then create an >> > > > > incentive >> > > > > to >> > > > > keep >> > > > > things in header files so that they pick up a hint to the >> > > > > optimizer. >> > > > >> > > > > >> > > > > Ultimately, the world will be a better place if we can >> > > > > eventually >> > > > > move code >> > > > > away from relying on the hint provided by the 'inline' >> > > > > keyword >> > > > > to >> > > > > the >> > > > > optimizer. >> > > > > >> > > > >> > > > While I would like to see that happen some day, I do think it >> > > > is >> > > > an >> > > > independent matter. >> > > > >> > > > > >> > > > > That doesn't mean that the core concept of hinting to the >> > > > > optimizer >> > > > > that a >> > > > > particular function is a particularly good candidate for >> > > > > inlining >> > > > > is without >> > > > > value. >> > > > >> > > > yes. >> > > > >> > > > >While I think it is a bad practice that we shouldn't encourage >> > > > >in >> > > > > code (especially portable code) >> > > > >> > > > yes -- there are indeed programmers who use this casually >> > > > without >> > > > considering performance. >> > > > >> > > > > I can see the desire to at least have *some* >> > > > > attribute which is nothing more or less than a hint to the >> > > > > optimizer to >> > > > > inline harder[1]. >> > > > >> > > > yes -- there are programmers who use the attribute consciously. >> > > > >> > > > > It would help people work around inliner bugs in the short >> > > > > term, and even help debug inliner-rooted optimization >> > > > > problems. >> > > > >> > > > I think it is a good hint to the compiler even in the longer >> > > > term. >> > > > With PGO, we should minimize the reliance on the hint though. >> > > > >> > > > >Codebases >> > > > > with strong portability requirements could still (and >> > > > > probably >> > > > > should) >> > > > > forbid or tightly control access to this kind of hint. I >> > > > > would >> > > > > want >> > > > > really >> > > > > strong documentation about how this attribute *completely >> > > > > voids* >> > > > > your >> > > > > performance warranty (if such a thing exists) as from version >> > > > > to >> > > > > version of >> > > > > the compiler it may go from a helpful hint to a devastatingly >> > > > > bad >> > > > > hint. >> > > > >> > > > Why? If the compiler becomes smarter and smarter, the inline >> > > > hint >> > > > will >> > > > become more and more irrelevant and eventually has no effect -- >> > > > why >> > > > would the performance warranty be voided? If the compiler is >> > > > not >> > > > yet >> > > > smart enough, why would the compiler refuse to take the hint >> > > > and >> > > > forbid developer provide the hint? >> > > > >> > > > > But >> > > > > I think I could be persuaded to live with such a hint >> > > > > existing. >> > > > > But >> > > > > I'm >> > > > > *really* uncomfortable with it being tied to something that >> > > > > also >> > > > > impacts >> > > > > linkage or other semantics of the program. >> > > > >> > > > For consistent with standard, we should pass the attribute. >> > > > Linkage >> > > > is >> > > > not affected in anyway. >> > > > >> > > > > >> > > > > [1]: Currently, the only other hint we have available is >> > > > > pretty >> > > > > terrible as >> > > > > it *also* has semantic effects: the always_inline attribute. >> > > > > >> > > > > >> > > > >> >> > > > >> The proposed patch will add InlineHint to methods defined >> > > > >> inside >> > > > >> a >> > > > >> class: >> > > > >> >> > > > >> --- a/lib/CodeGen/CodeGenFunction.cpp >> > > > >> +++ b/lib/CodeGen/CodeGenFunction.cpp >> > > > >> @@ -630,7 +630,7 @@ void >> > > > >> CodeGenFunction::StartFunction(GlobalDecl >> > > > >> GD, >> > > > >> if (const FunctionDecl *FD >> > > > >> dyn_cast_or_null<FunctionDecl>(D)) >> > > > >> { >> > > > >> if (!CGM.getCodeGenOpts().NoInline) { >> > > > >> for (auto RI : FD->redecls()) >> > > > >> - if (RI->isInlineSpecified()) { >> > > > >> + if (RI->isInlined()) { >> > > > >> Fn->addFnAttr(llvm::Attribute::InlineHint); >> > > > >> break; >> > > > >> } >> > > > >> >> > > > >> Here are the performance and size numbers I've collected: >> > > > >> >> > > > >> >> > > > >> - C++ subset of Spec: No performance effects, < 0.1% size >> > > > >> increase >> > > > >> (all size numbers are text sizes returned by 'size') >> > > > >> - Clang: 0.9% performance improvement (both -O0 and -O2 on a >> > > > >> large >> > > > >> .ii >> > > > >> file) , 4.1% size increase >> > > > > >> > > > > >> > > > > FWIW, this size increase seems *really* bad. I think that >> > > > > kills >> > > > > this >> > > > > approach even in the short term. >> > > > >> > > > Re. size and performance trade-off -- 0.9% performance >> > > > improvement >> > > > should greatly win the size cost. Besides among all programs >> > > > see, >> > > > only >> > > > clang sees this size increase with all the others seeing >> > > > negligible >> > > > size increase. >> > > > >> > > > This is not a short term vs long term situation. It is >> > > > basically >> > > > a >> > > > bug >> > > > fix that FE drops the attribute. If it exposes inliner >> > > > heuristic >> > > > bug, >> > > > that should be fixed/tuned separately. With the hint correctly >> > > > passed >> > > > in, Easwaran will do further tuning including time based >> > > > analysis. >> > > > >> > > > > >> > > > >> >> > > > >> - Chrome: no performance improvement, 0.24% size increase >> > > > >> - Google internal benchmark suite (geomean of ~20 >> > > > >> benchmarks): >> > > > >> ~1.8% >> > > > >> performance improvement, no size regression >> > > > > >> > > > > >> > > > > I'm also somewhat worried about the lack of any performance >> > > > > improvements >> > > > > outside of the Google benchmarks. That somewhat strongly >> > > > > suggests >> > > > > that our >> > > > > benchmarks are overly coupled to this hint already. The fact >> > > > > that >> > > > > neither >> > > > > Chrome, Clang, nor SPEC improved is... not at all >> > > > > encouraging. >> > > > >> > > > Other than Google benchmarks, we do see Clang improve >> > > > performance. >> > > > Besides, current inliner needs to be further tuned in order to >> > > > get >> > > > more performance benefit. Passing the hint through is simply an >> > > > enabler. Also remember that most of SPEC benchmarks are C >> > > > programs. >> > > > C++ programs with heavy use of virtual functions may not >> > > > benefit >> > > > a >> > > > lot >> > > > either. >> > > > >> > > > David >> > > > >> > > > >> > > > > >> > > > > -Chandler >> > > > _______________________________________________ >> > > > cfe-commits mailing list >> > > > cfe-commits at cs.uiuc.edu >> > > > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >> > > > >> > > > >> > > > _______________________________________________ >> > > > cfe-commits mailing list >> > > > cfe-commits at cs.uiuc.edu >> > > > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >> > > > >> > > >> > > >> > > >> > > -- >> > > Hal Finkel >> > > Assistant Computational Scientist >> > > Leadership Computing Facility >> > > Argonne National Laboratory >> > > >> > > >> > >> > -- >> > Hal Finkel >> > Assistant Computational Scientist >> > Leadership Computing Facility >> > Argonne National Laboratory >> > _______________________________________________ >> > cfe-commits mailing list >> > cfe-commits at cs.uiuc.edu >> > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >> > >> >> -- >> Hal Finkel >> Assistant Computational Scientist >> Leadership Computing Facility >> Argonne National Laboratory >> >> > > -- > Hal Finkel > Assistant Computational Scientist > Leadership Computing Facility > Argonne National Laboratory