On 15 March 2014 03:57, Jacob Carlborg <d...@me.com> wrote: > On 2014-03-14 07:21, Manu wrote: > >> So, I'm constantly running into issues with not having control over >> inline. >> I've run into it again doing experiments in preparation for my dconf >> talk... >> >> I have identified 2 cases which come up regularly: >> 1. A function that should always be inline unconditionally (std.simd >> is effectively blocked on this) >> 2. A particular invocation of a function should be inlined for this >> call only >> >> The first case it just about having control over code gen. Some >> functions should effectively be macros or pseudo-intrinsics (ie, >> intrinsic wrappers in std.simd, beauty wrappers around asm code, etc), >> and I don't ever want to see a symbol appear in the binary. >> >> My suggestion is introduction of __forceinline or something like it. We >> need this. >> > > Haven't we already agreed a pragma for force inline should be implemented. > Or is that something I have dreamed?
It's been discussed. I never agreed to it (I _really_ don't like it), but I'll take it if it's the best I'm gonna get. I don't like stateful attributes like that. I think it's error prone, especially when it's silent. 'private:' for instance will complain if you write a new function in an area influenced by the private state and try and call it from elsewhere; ie, you know you made the mistake. If you write a new function in an area influenced by the forceinline state which wasn't intended to be inlined, you won't know. I think that's dangerous. The second case is interesting, and I've found it comes up a few times >> on different occasions. >> In my current instance, I'm trying to build generic framework to perform >> efficient composable data processing, and a basic requirement is that >> the components are inlined, such that the optimiser can interleave the >> work properly. >> >> Let's imagine I have a template which implements a work loop, which >> wants to call a bunch of work elements it receives by alias. The issue >> is, each of those must be inlined, for this call instance only, and >> there's no way to do this. >> I'm gonna draw the line at stringified code to use with mixin; I hate >> that, and I don't want to encourage use of mixin or stringified code in >> user-facing API's as a matter of practise. Also, some of these work >> elements might be useful functions in their own right, which means they >> can indeed be a function existing somewhere else that shouldn't itself >> be attributed as __forceinline. >> >> What are the current options to force that some code is inlined? >> >> My feeling is that an ideal solution would be something like an >> enhancement which would allow the 'mixin' keyword to be used with >> regular function calls. >> What this would do is 'mix in' the function call at this location, ie, >> effectively inline that particular call, and it leverages a keyword and >> concept that we already have. It would obviously produce a compile error >> of the code is not available. >> >> I quite like this idea, but there is a potential syntactical problem; >> how to assign the return value? >> >> int func(int y) { return y*y+10; } >> >> int output = mixin func(10); // the 'mixin' keyword seems to kinda 'get >> > > I think this is the best syntax of these three alternatives. > > > in the way' if the output >> int output = mixin(func(10)); // now i feel paren spammy... >> > > This syntax can't work. It's already interpreted calling "func" and use > the result as a string mixin. > > > mixin(int output = func(10)); // this doesn't feel right... >> > > No. > > > My feeling is the first is the best, but I'm not sure about that >> grammatically. >> > > Yeah, I agree. So you think it's grammatically okay? The other thing that comes to mind is that it seems like this might make >> a case for AST macros... but I think that's probably overkill for this >> situation, and I'm not confident we're ever gonna attempt to crack that >> nut. I'd like to see something practical and unobjectionable preferably. >> > > AST macros would solve it. It could solve the first use case as well. I > would not implement AST macros just to support force inline but we have > many other uses cases as well. I would have implement AST macros a long > time ago. Hopefully this would avoid the need to create new language > features in some cases. > > First use case, just define a macro that returns the AST for the content > of the function you would create. > > macro func (Ast!(int) a) > { > return <[ $a * $a; ]>; > } > > int output = func(10); // always inlined > > Second use case, define a macro, "inline", that takes the function you > want to call as a parameter. The macro will basically inline the body. > > macro inline (T, U...) (Ast!(T function (U) func) > { > // this would probably be more complicated > return func.body; > } > > int output = func(10); // not inlined > int output = inline(func(10)); // always inlined > > > This problem is fairly far reaching; phobos receives a lot of lambdas >> these days, which I've found don't reliably inline and interfere with >> the optimisers ability to optimise the code. >> > > I thought since lambdas are passed as template parameters they would > always be inlined. Maybe... (and not in debug builds). Without explicit control of the inliner, you just never know.