Re: __FILE__ and __LINE__ again...

2013-09-12 Thread Dicebot

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:
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.


Hmm. Does that mean gdc supports that, then?


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...


Re: __FILE__ and __LINE__ again...

2013-09-12 Thread H. S. Teoh
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:
 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:
 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.
 
 Hmm. Does that mean gdc supports that, then?
 
 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...

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 Wall


Re: __FILE__ and __LINE__ again...

2013-09-12 Thread Dicebot

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.


__FILE__ and __LINE__ again...

2013-09-10 Thread Paolo Invernizzi

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


Re: __FILE__ and __LINE__ again...

2013-09-10 Thread Dicebot
On Tuesday, 10 September 2013 at 16:00:55 UTC, Paolo Invernizzi 
wrote:

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


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.


Re: __FILE__ and __LINE__ again...

2013-09-10 Thread Dicebot

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.


Re: __FILE__ and __LINE__ again...

2013-09-10 Thread H. S. Teoh
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:
 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.

Hmm. Does that mean gdc supports that, then?


T

-- 
People tell me I'm stubborn, but I refuse to accept it!


Re: __FILE__ and __LINE__ again...

2013-09-10 Thread H. S. Teoh
On Tue, Sep 10, 2013 at 06:00:53PM +0200, Paolo Invernizzi wrote:
 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?
[...]

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 Baker


Re: __FILE__ and __LINE__ again...

2013-09-10 Thread Dicebot

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:
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.


Hmm. Does that mean gdc supports that, then?


T


Well, it definitely _can_ support it, but we should ask Iain if 
it actually supports it :) Gonna try and experiment with it a bit.


Re: __FILE__ and __LINE__ again...

2013-09-10 Thread Paolo Invernizzi

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:

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?

[...]

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


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...


/Paolo