digitalmars.D.learn - __FILE__ and __LINE__ again...
- Paolo Invernizzi (13/24) Sep 10 2013 I'm trying something like that, but with __LINE__ in addition to
- Dicebot (12/38) Sep 10 2013 Johannes was wrong. DMD will always emit template symbols, even
- H. S. Teoh (31/60) Sep 10 2013 [...]
- Dicebot (4/11) Sep 10 2013 Using `--gc-sections` requires each function and data item to be
- H. S. Teoh (5/14) Sep 10 2013 Hmm. Does that mean gdc supports that, then?
- Dicebot (3/21) Sep 10 2013 Well, it definitely _can_ support it, but we should ask Iain if
- Dicebot (4/21) Sep 12 2013 Actually I was wrong, looks like DMD does section differentiation
- H. S. Teoh (10/28) Sep 12 2013 Interesting. However, I ran into some runtime segfaults caused by
- Dicebot (12/22) Sep 12 2013 Actually, nevermind, dmd only does it for small portion of the
- Paolo Invernizzi (6/70) Sep 10 2013 Thank you to everybody,
Johannes Pfau wrote something like this, in the logger thread:If you write code like this: void log(string file = __FILE__)() //A template { logImpl(file); } void logImpl(string file){} //Not a template The compiler can always inline the log template. So there's no template bloat as there will be effectively no instances of log. Instead it will be inlined and logImpl will be called directly just as if you manually called logImpl(__FILE__).I'm trying something like that, but with __LINE__ in addition to put a little more pressure: void log(string file = __FILE__, int line = __LINE__)(){ logImpl(file, line); } void logImpl(string file, int line){} I've then compiled a single file filled with 'log()', but I've found from 'nm' that the text section is still full of templated functions. So the question is: is Johannes trick supposed to work, or there's something I don't understand well about template expansion and inlining? Thanks, Paolo
Sep 10 2013
On Tuesday, 10 September 2013 at 16:00:55 UTC, Paolo Invernizzi wrote:Johannes Pfau wrote something like this, in the logger thread:Johannes was wrong. DMD will always emit template symbols, even if those are completely inlined. Basically, anything that is somehow referenced in D modules gets into object file. Why won't you use default parameters in normal functions: void log(string file = __FILE__, int line = __LINE) { // ... } It uses caller context for token substitution, not declaration one.If you write code like this: void log(string file = __FILE__)() //A template { logImpl(file); } void logImpl(string file){} //Not a template The compiler can always inline the log template. So there's no template bloat as there will be effectively no instances of log. Instead it will be inlined and logImpl will be called directly just as if you manually called logImpl(__FILE__).I'm trying something like that, but with __LINE__ in addition to put a little more pressure: void log(string file = __FILE__, int line = __LINE__)(){ logImpl(file, line); } void logImpl(string file, int line){} I've then compiled a single file filled with 'log()', but I've found from 'nm' that the text section is still full of templated functions. So the question is: is Johannes trick supposed to work, or there's something I don't understand well about template expansion and inlining? Thanks, Paolo
Sep 10 2013
On Tue, Sep 10, 2013 at 06:00:53PM +0200, Paolo Invernizzi wrote:Johannes Pfau wrote something like this, in the logger thread:[...] Did you compile with dmd -inline? Having said that, if you don't have variadic arguments, __FILE__ and __LINE__ should be default arguments at the end of the *runtime* argument list. Runtime arguments should be used to prevent template bloat: void log(/* other arguments here */, string file=__FILE__, int line=__LINE__) { ... } If you have variadic arguments, though, this wouldn't work. In any case, if the template function is just a thin wrapper around logImpl, and you're compiling with -inline, then there should be no runtime overhead. The compiler will still emit template instantiations for each call to log(), but you can get rid of this with link-time optimization (on Posix, you'd add -L-gc-sections to your dmd command-line: this will cause ld to delete code sections that are never referenced, which includes the log() instantiations if indeed they have been inlined). T -- Arise, you prisoners of Windows Arise, you slaves of Redmond, Wash, The day and hour soon are coming When all the IT folks say "Gosh!" It isn't from a clever lawsuit That Windowsland will finally fall, But thousands writing open source code Like mice who nibble through a wall. -- The Linux-nationale by Greg BakerIf you write code like this: void log(string file = __FILE__)() //A template { logImpl(file); } void logImpl(string file){} //Not a template The compiler can always inline the log template. So there's no template bloat as there will be effectively no instances of log. Instead it will be inlined and logImpl will be called directly just as if you manually called logImpl(__FILE__).I'm trying something like that, but with __LINE__ in addition to put a little more pressure: void log(string file = __FILE__, int line = __LINE__)(){ logImpl(file, line); } void logImpl(string file, int line){} I've then compiled a single file filled with 'log()', but I've found from 'nm' that the text section is still full of templated functions. So the question is: is Johannes trick supposed to work, or there's something I don't understand well about template expansion and inlining?
Sep 10 2013
On Tuesday, 10 September 2013 at 16:45:33 UTC, H. S. Teoh wrote:but you can get rid of this with link-time optimization (on Posix, you'd add -L-gc-sections to your dmd command-line: this will cause ld to delete code sections that are never referenced, which includes the log() instantiations if indeed they have been inlined).Using `--gc-sections` requires each function and data item to be placed into its own section (-fdata-sections and -ffunction-sections in gcc). AFAIK dmd does not do it.
Sep 10 2013
On Tue, Sep 10, 2013 at 06:50:03PM +0200, Dicebot wrote:On Tuesday, 10 September 2013 at 16:45:33 UTC, H. S. Teoh wrote:Hmm. Does that mean gdc supports that, then? T -- People tell me I'm stubborn, but I refuse to accept it!but you can get rid of this with link-time optimization (on Posix, you'd add -L-gc-sections to your dmd command-line: this will cause ld to delete code sections that are never referenced, which includes the log() instantiations if indeed they have been inlined).Using `--gc-sections` requires each function and data item to be placed into its own section (-fdata-sections and -ffunction-sections in gcc). AFAIK dmd does not do it.
Sep 10 2013
On Tuesday, 10 September 2013 at 16:58:54 UTC, H. S. Teoh wrote:On Tue, Sep 10, 2013 at 06:50:03PM +0200, Dicebot wrote:Well, it definitely _can_ support it, but we should ask Iain if it actually supports it :) Gonna try and experiment with it a bit.On Tuesday, 10 September 2013 at 16:45:33 UTC, H. S. Teoh wrote:Hmm. Does that mean gdc supports that, then? Tbut you can get rid of this with link-time optimization (on Posix, you'd add -L-gc-sections to your dmd command-line: this will cause ld to delete code sections that are never referenced, which includes the log() instantiations if indeed they have been inlined).Using `--gc-sections` requires each function and data item to be placed into its own section (-fdata-sections and -ffunction-sections in gcc). AFAIK dmd does not do it.
Sep 10 2013
On Tuesday, 10 September 2013 at 16:58:54 UTC, H. S. Teoh wrote:On Tue, Sep 10, 2013 at 06:50:03PM +0200, Dicebot wrote:Actually I was wrong, looks like DMD does section differentiation by default. I am wondering if --gc-sections should be made default on Linux targets...On Tuesday, 10 September 2013 at 16:45:33 UTC, H. S. Teoh wrote:Hmm. Does that mean gdc supports that, then?but you can get rid of this with link-time optimization (on Posix, you'd add -L-gc-sections to your dmd command-line: this will cause ld to delete code sections that are never referenced, which includes the log() instantiations if indeed they have been inlined).Using `--gc-sections` requires each function and data item to be placed into its own section (-fdata-sections and -ffunction-sections in gcc). AFAIK dmd does not do it.
Sep 12 2013
On Thu, Sep 12, 2013 at 03:37:58PM +0200, Dicebot wrote:On Tuesday, 10 September 2013 at 16:58:54 UTC, H. S. Teoh wrote:Interesting. However, I ran into some runtime segfaults caused by --gc-sections yesterday. I didn't investigate further, but that makes me hesitant to make --gc-sections the default. Something, somewhere, is being broken by --gc-sections. It doesn't happen in all cases, though. Only some of my programs are affected by it. I should investigate this when I get some time. T -- Let's call it an accidental feature. -- Larry WallOn Tue, Sep 10, 2013 at 06:50:03PM +0200, Dicebot wrote:Actually I was wrong, looks like DMD does section differentiation by default. I am wondering if --gc-sections should be made default on Linux targets...On Tuesday, 10 September 2013 at 16:45:33 UTC, H. S. Teoh wrote:Hmm. Does that mean gdc supports that, then?but you can get rid of this with link-time optimization (on Posix, you'd add -L-gc-sections to your dmd command-line: this will cause ld to delete code sections that are never referenced, which includes the log() instantiations if indeed they have been inlined).Using `--gc-sections` requires each function and data item to be placed into its own section (-fdata-sections and -ffunction-sections in gcc). AFAIK dmd does not do it.
Sep 12 2013
On Thursday, 12 September 2013 at 13:58:03 UTC, H. S. Teoh wrote:Interesting. However, I ran into some runtime segfaults caused by --gc-sections yesterday. I didn't investigate further, but that makes me hesitant to make --gc-sections the default. Something, somewhere, is being broken by --gc-sections. It doesn't happen in all cases, though. Only some of my programs are affected by it. I should investigate this when I get some time.Actually, nevermind, dmd only does it for small portion of the code :) However, I have tested -ffunction-sections + -fdata-sections + --gc-sections on gdc and have reduced binary size _twice_ for a simple `writeln(arr.map(a => a*2)())` snippet. Which is only partially cool because gdc binary is more than twice larger than dmd one for same code :D Problem with --gc-sections is that it can't be used when building libraries and any with executable that expose parts of own code to shared libraries. It is essentially a whole program optimization and it can't be done without compiler support in cases where binary is _not_ the whole program.
Sep 12 2013
On Tuesday, 10 September 2013 at 16:45:33 UTC, H. S. Teoh wrote:On Tue, Sep 10, 2013 at 06:00:53PM +0200, Paolo Invernizzi wrote:Thank you to everybody, As you can guess, I would like to have variadic arguments: I'll try to investigate if some mixin syntax is not too horrible to be use... /PaoloJohannes Pfau wrote something like this, in the logger thread:[...] Did you compile with dmd -inline? Having said that, if you don't have variadic arguments, __FILE__ and __LINE__ should be default arguments at the end of the *runtime* argument list. Runtime arguments should be used to prevent template bloat: void log(/* other arguments here */, string file=__FILE__, int line=__LINE__) { ... } If you have variadic arguments, though, this wouldn't work. In any case, if the template function is just a thin wrapper around logImpl, and you're compiling with -inline, then there should be no runtime overhead. The compiler will still emit template instantiations for each call to log(), but you can get rid of this with link-time optimization (on Posix, you'd add -L-gc-sections to your dmd command-line: this will cause ld to delete code sections that are never referenced, which includes the log() instantiations if indeed they have been inlined). TIf you write code like this: void log(string file = __FILE__)() //A template { logImpl(file); } void logImpl(string file){} //Not a template The compiler can always inline the log template. So there's no template bloat as there will be effectively no instances of log. Instead it will be inlined and logImpl will be called directly just as if you manually called logImpl(__FILE__).I'm trying something like that, but with __LINE__ in addition to put a little more pressure: void log(string file = __FILE__, int line = __LINE__)(){ logImpl(file, line); } void logImpl(string file, int line){} I've then compiled a single file filled with 'log()', but I've found from 'nm' that the text section is still full of templated functions. So the question is: is Johannes trick supposed to work, or there's something I don't understand well about template expansion and inlining?
Sep 10 2013