public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Could __builtin_printf parameters be optimized when being compiled
@ 2023-02-15 14:18 Jonny Grant
  2023-02-15 14:30 ` Richard Earnshaw
  0 siblings, 1 reply; 8+ messages in thread
From: Jonny Grant @ 2023-02-15 14:18 UTC (permalink / raw)
  To: gcc-help

Hi
Has GCC considered an improvement to "compile out" from the builtin printf the strings? That being to change it to just be something like puts("file /app/example.cpp:4")
I had a look, but couldn't find it being asked before.

This is just a short example to demonstrate.
It would be useful to see the exact string in the debugger "file /app/example.cpp:4", also it saves a few lines of asm.

https://godbolt.org/z/aKz3o6aPd


int main()
{
    __builtin_printf("file %s:%d", __FILE__, __LINE__);
}


.LC0:
        .string "/app/example.cpp"
.LC1:
        .string "file %s:%d"
main:
        subq    $8, %rsp
        movl    $4, %edx
        movl    $.LC0, %esi
        xorl    %eax, %eax
        movl    $.LC1, %edi
        call    printf
        xorl    %eax, %eax
        addq    $8, %rsp
        ret

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Could __builtin_printf parameters be optimized when being compiled
  2023-02-15 14:18 Could __builtin_printf parameters be optimized when being compiled Jonny Grant
@ 2023-02-15 14:30 ` Richard Earnshaw
  2023-02-15 15:10   ` Jonny Grant
  0 siblings, 1 reply; 8+ messages in thread
From: Richard Earnshaw @ 2023-02-15 14:30 UTC (permalink / raw)
  To: Jonny Grant, gcc-help



On 15/02/2023 14:18, Jonny Grant wrote:
> Hi
> Has GCC considered an improvement to "compile out" from the builtin printf the strings? That being to change it to just be something like puts("file /app/example.cpp:4")
> I had a look, but couldn't find it being asked before.
> 
> This is just a short example to demonstrate.
> It would be useful to see the exact string in the debugger "file /app/example.cpp:4", also it saves a few lines of asm.
> 
> https://godbolt.org/z/aKz3o6aPd
> 
> 
> int main()
> {
>      __builtin_printf("file %s:%d", __FILE__, __LINE__);
> }
> 
> 
> .LC0:
>          .string "/app/example.cpp"
> .LC1:
>          .string "file %s:%d"
> main:
>          subq    $8, %rsp
>          movl    $4, %edx
>          movl    $.LC0, %esi
>          xorl    %eax, %eax
>          movl    $.LC1, %edi
>          call    printf
>          xorl    %eax, %eax
>          addq    $8, %rsp
>          ret

We already do when the printf contains simply the format string and no 
additional arguments.

I guess it might be possible to handle cases where all the arguments are 
constant, but even that has its problems, eg:

- can we guarantee identical output to the platform printf?
- does it cause string bloat (what if there were 30 or so such 
statements in your program all identical except for the line number)?
- does it even happen often enough to be worth adding (and maintaining) 
support?  Nothing comes for free in a compiler and the optimisations 
have to be worth-while in the real world.

R.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Could __builtin_printf parameters be optimized when being compiled
  2023-02-15 14:30 ` Richard Earnshaw
@ 2023-02-15 15:10   ` Jonny Grant
  2023-02-15 15:27     ` Richard Earnshaw
  2023-02-15 15:49     ` Segher Boessenkool
  0 siblings, 2 replies; 8+ messages in thread
From: Jonny Grant @ 2023-02-15 15:10 UTC (permalink / raw)
  To: Richard Earnshaw, gcc-help

Thank you for your quick reply Richard.

On 15/02/2023 14:30, Richard Earnshaw wrote:
> 
> 
> On 15/02/2023 14:18, Jonny Grant wrote:
>> Hi
>> Has GCC considered an improvement to "compile out" from the builtin printf the strings? That being to change it to just be something like puts("file /app/example.cpp:4")
>> I had a look, but couldn't find it being asked before.
>>
>> This is just a short example to demonstrate.
>> It would be useful to see the exact string in the debugger "file /app/example.cpp:4", also it saves a few lines of asm.
>>
>> https://godbolt.org/z/aKz3o6aPd
>>
>>
>> int main()
>> {
>>      __builtin_printf("file %s:%d", __FILE__, __LINE__);
>> }
>>
>>
>> .LC0:
>>          .string "/app/example.cpp"
>> .LC1:
>>          .string "file %s:%d"
>> main:
>>          subq    $8, %rsp
>>          movl    $4, %edx
>>          movl    $.LC0, %esi
>>          xorl    %eax, %eax
>>          movl    $.LC1, %edi
>>          call    printf
>>          xorl    %eax, %eax
>>          addq    $8, %rsp
>>          ret
> 
> We already do when the printf contains simply the format string and no additional arguments.
> 
> I guess it might be possible to handle cases where all the arguments are constant, but even that has its problems, eg:
> 
> - can we guarantee identical output to the platform printf?

That's a good question. I was using __builtin_printf so that should be GCC I expect.

> - does it cause string bloat (what if there were 30 or so such statements in your program all identical except for the line number)?

That's probably what I am expecting, to see those 30 different formatted strings.

> - does it even happen often enough to be worth adding (and maintaining) support?  Nothing comes for free in a compiler and the optimisations have to be worth-while in the real world.
> 
> R.

You're completely right, it could bloat the file with strings.

I can do some with multi-line literals, to get "file /app/example.cpp compiled Feb 15 2023"
__FILE__ and __DATE__ worked ok.

but it didn't like me putting __PRETTY_FUNCTION__ in the middle. Maybe I'm missing something obvious. Likewise I can't use __builtin_LINE() as that is a function rather than a string. Maybe __PRETTY_FUNCTION__ and __FUNCTION__ are calls to  __builtin_FUNCTION().

int main()
{
    const char * s = "file " \
        __FILE__ \
        " compiled " \
        __DATE__ \
        "\n";

    __builtin_printf("%s", s);
    __builtin_printf("%s\n", __PRETTY_FUNCTION__);  // didn't work when I put in the middle.


https://godbolt.org/z/xso9soWaf

Regards
Jonny

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Could __builtin_printf parameters be optimized when being compiled
  2023-02-15 15:10   ` Jonny Grant
@ 2023-02-15 15:27     ` Richard Earnshaw
  2023-02-16 13:47       ` Jonny Grant
  2023-02-15 15:49     ` Segher Boessenkool
  1 sibling, 1 reply; 8+ messages in thread
From: Richard Earnshaw @ 2023-02-15 15:27 UTC (permalink / raw)
  To: Jonny Grant, gcc-help



On 15/02/2023 15:10, Jonny Grant wrote:
> Thank you for your quick reply Richard.
> 
> On 15/02/2023 14:30, Richard Earnshaw wrote:
>>
>>
>> On 15/02/2023 14:18, Jonny Grant wrote:
>>> Hi
>>> Has GCC considered an improvement to "compile out" from the builtin printf the strings? That being to change it to just be something like puts("file /app/example.cpp:4")
>>> I had a look, but couldn't find it being asked before.
>>>
>>> This is just a short example to demonstrate.
>>> It would be useful to see the exact string in the debugger "file /app/example.cpp:4", also it saves a few lines of asm.
>>>
>>> https://godbolt.org/z/aKz3o6aPd
>>>
>>>
>>> int main()
>>> {
>>>       __builtin_printf("file %s:%d", __FILE__, __LINE__);
>>> }
>>>
>>>
>>> .LC0:
>>>           .string "/app/example.cpp"
>>> .LC1:
>>>           .string "file %s:%d"
>>> main:
>>>           subq    $8, %rsp
>>>           movl    $4, %edx
>>>           movl    $.LC0, %esi
>>>           xorl    %eax, %eax
>>>           movl    $.LC1, %edi
>>>           call    printf
>>>           xorl    %eax, %eax
>>>           addq    $8, %rsp
>>>           ret
>>
>> We already do when the printf contains simply the format string and no additional arguments.
>>
>> I guess it might be possible to handle cases where all the arguments are constant, but even that has its problems, eg:
>>
>> - can we guarantee identical output to the platform printf?
> 
> That's a good question. I was using __builtin_printf so that should be GCC I expect.
> 

No, __builtin_printf is really just an internal hook that is used to 
handle optimisations of printf - if you look at your assembly output 
you'll see it is translated back to printf for the C library to handle.

>> - does it cause string bloat (what if there were 30 or so such statements in your program all identical except for the line number)?
> 
> That's probably what I am expecting, to see those 30 different formatted strings.
> 
>> - does it even happen often enough to be worth adding (and maintaining) support?  Nothing comes for free in a compiler and the optimisations have to be worth-while in the real world.
>>
>> R.
> 
> You're completely right, it could bloat the file with strings.
> 
> I can do some with multi-line literals, to get "file /app/example.cpp compiled Feb 15 2023"
> __FILE__ and __DATE__ worked ok.
> 
> but it didn't like me putting __PRETTY_FUNCTION__ in the middle. Maybe I'm missing something obvious. Likewise I can't use __builtin_LINE() as that is a function rather than a string. Maybe __PRETTY_FUNCTION__ and __FUNCTION__ are calls to  __builtin_FUNCTION().
> 
> int main()
> {
>      const char * s = "file " \
>          __FILE__ \
>          " compiled " \
>          __DATE__ \
>          "\n";
> 
>      __builtin_printf("%s", s);
>      __builtin_printf("%s\n", __PRETTY_FUNCTION__);  // didn't work when I put in the middle.
> 

That's because __func__, __FUNCTION__ and __PRETTY_FUNCTION__ are not 
string literals but implicitly declared identifies containing a constant 
string literal as the initializer - you can't therefore combine them 
with string literals by simple concatenation.  See

https://gcc.gnu.org/onlinedocs/gcc/Function-Names.html

which clearly states this.

R.
> 
> https://godbolt.org/z/xso9soWaf
> 
> Regards
> Jonny

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Could __builtin_printf parameters be optimized when being compiled
  2023-02-15 15:10   ` Jonny Grant
  2023-02-15 15:27     ` Richard Earnshaw
@ 2023-02-15 15:49     ` Segher Boessenkool
  2023-02-15 16:42       ` Richard Earnshaw
  2023-02-16 13:48       ` Jonny Grant
  1 sibling, 2 replies; 8+ messages in thread
From: Segher Boessenkool @ 2023-02-15 15:49 UTC (permalink / raw)
  To: Jonny Grant; +Cc: Richard Earnshaw, gcc-help

On Wed, Feb 15, 2023 at 03:10:15PM +0000, Jonny Grant wrote:
> On 15/02/2023 14:30, Richard Earnshaw wrote:
> >> int main()
> >> {
> >>      __builtin_printf("file %s:%d", __FILE__, __LINE__);
> >> }

Note that the format needs to end in "\n" if you want this to be
converted to a puts() call.  Without it it strangely doesn't seem to
be optimised, although fprintf() is converted to fwrite() in such cases.
This could be done for printf() as well: you are guaranteed to have
access to stdout as well, at least if you use printf() instead of the
builtin (I'm not sure if we do then).

> > I guess it might be possible to handle cases where all the arguments are constant, but even that has its problems, eg:
> > 
> > - can we guarantee identical output to the platform printf?
> 
> That's a good question. I was using __builtin_printf so that should be GCC I expect.

Not every printf() implementation has exactly the same output in all
cases.

Another practically important consideration is what it does to i18n.
You really need to leave the format string unmodified for that to be
able to work.


Segher

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Could __builtin_printf parameters be optimized when being compiled
  2023-02-15 15:49     ` Segher Boessenkool
@ 2023-02-15 16:42       ` Richard Earnshaw
  2023-02-16 13:48       ` Jonny Grant
  1 sibling, 0 replies; 8+ messages in thread
From: Richard Earnshaw @ 2023-02-15 16:42 UTC (permalink / raw)
  To: Segher Boessenkool, Jonny Grant; +Cc: gcc-help



On 15/02/2023 15:49, Segher Boessenkool wrote:
> On Wed, Feb 15, 2023 at 03:10:15PM +0000, Jonny Grant wrote:
>> On 15/02/2023 14:30, Richard Earnshaw wrote:
>>>> int main()
>>>> {
>>>>       __builtin_printf("file %s:%d", __FILE__, __LINE__);
>>>> }
> 
> Note that the format needs to end in "\n" if you want this to be
> converted to a puts() call.  Without it it strangely doesn't seem to
> be optimised, although fprintf() is converted to fwrite() in such cases.
> This could be done for printf() as well: you are guaranteed to have
> access to stdout as well, at least if you use printf() instead of the
> builtin (I'm not sure if we do then).

Well it should do, but unless you've #included stdio.h (which you should 
have done, but not every program is 100% conforming) you might not have 
a definition of it and the compiler can't know how to magic up a correct 
definition of it for your system (c89 said that stdin/out/err are 
macros, so they might expand to almost anything - in freebsd, for 
example they expand to __std<in|out|err>p).

> 
>>> I guess it might be possible to handle cases where all the arguments are constant, but even that has its problems, eg:
>>>
>>> - can we guarantee identical output to the platform printf?
>>
>> That's a good question. I was using __builtin_printf so that should be GCC I expect.
> 
> Not every printf() implementation has exactly the same output in all
> cases.
> 
> Another practically important consideration is what it does to i18n.
> You really need to leave the format string unmodified for that to be
> able to work.
> 
> 
> Segher

R.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Could __builtin_printf parameters be optimized when being compiled
  2023-02-15 15:27     ` Richard Earnshaw
@ 2023-02-16 13:47       ` Jonny Grant
  0 siblings, 0 replies; 8+ messages in thread
From: Jonny Grant @ 2023-02-16 13:47 UTC (permalink / raw)
  To: Richard Earnshaw, gcc-help



On 15/02/2023 15:27, Richard Earnshaw wrote:
> 
> 
> On 15/02/2023 15:10, Jonny Grant wrote:
>> Thank you for your quick reply Richard.
>>
>> On 15/02/2023 14:30, Richard Earnshaw wrote:
>>>
>>>
>>> On 15/02/2023 14:18, Jonny Grant wrote:
>>>> Hi
>>>> Has GCC considered an improvement to "compile out" from the builtin printf the strings? That being to change it to just be something like puts("file /app/example.cpp:4")
>>>> I had a look, but couldn't find it being asked before.
>>>>
>>>> This is just a short example to demonstrate.
>>>> It would be useful to see the exact string in the debugger "file /app/example.cpp:4", also it saves a few lines of asm.
>>>>
>>>> https://godbolt.org/z/aKz3o6aPd
>>>>
>>>>
>>>> int main()
>>>> {
>>>>       __builtin_printf("file %s:%d", __FILE__, __LINE__);
>>>> }
>>>>
>>>>
>>>> .LC0:
>>>>           .string "/app/example.cpp"
>>>> .LC1:
>>>>           .string "file %s:%d"
>>>> main:
>>>>           subq    $8, %rsp
>>>>           movl    $4, %edx
>>>>           movl    $.LC0, %esi
>>>>           xorl    %eax, %eax
>>>>           movl    $.LC1, %edi
>>>>           call    printf
>>>>           xorl    %eax, %eax
>>>>           addq    $8, %rsp
>>>>           ret
>>>
>>> We already do when the printf contains simply the format string and no additional arguments.
>>>
>>> I guess it might be possible to handle cases where all the arguments are constant, but even that has its problems, eg:
>>>
>>> - can we guarantee identical output to the platform printf?
>>
>> That's a good question. I was using __builtin_printf so that should be GCC I expect.
>>
> 
> No, __builtin_printf is really just an internal hook that is used to handle optimisations of printf - if you look at your assembly output you'll see it is translated back to printf for the C library to handle.

ok I see. I changed the example to take off the end "\n" and it goes back to printf (otherwise it is puts() )
https://godbolt.org/z/W46esaWKd

> 
>>> - does it cause string bloat (what if there were 30 or so such statements in your program all identical except for the line number)?
>>
>> That's probably what I am expecting, to see those 30 different formatted strings.
>>
>>> - does it even happen often enough to be worth adding (and maintaining) support?  Nothing comes for free in a compiler and the optimisations have to be worth-while in the real world.
>>>
>>> R.
>>
>> You're completely right, it could bloat the file with strings.
>>
>> I can do some with multi-line literals, to get "file /app/example.cpp compiled Feb 15 2023"
>> __FILE__ and __DATE__ worked ok.
>>
>> but it didn't like me putting __PRETTY_FUNCTION__ in the middle. Maybe I'm missing something obvious. Likewise I can't use __builtin_LINE() as that is a function rather than a string. Maybe __PRETTY_FUNCTION__ and __FUNCTION__ are calls to  __builtin_FUNCTION().
>>
>> int main()
>> {
>>      const char * s = "file " \
>>          __FILE__ \
>>          " compiled " \
>>          __DATE__ \
>>          "\n";
>>
>>      __builtin_printf("%s", s);
>>      __builtin_printf("%s\n", __PRETTY_FUNCTION__);  // didn't work when I put in the middle.
>>
> 
> That's because __func__, __FUNCTION__ and __PRETTY_FUNCTION__ are not string literals but implicitly declared identifies containing a constant string literal as the initializer - you can't therefore combine them with string literals by simple concatenation.  See
> 
> https://gcc.gnu.org/onlinedocs/gcc/Function-Names.html
> 
> which clearly states this.
> 

Ok, thank you for the link, I understand it wouldn't support simple concatenation of __func__ etc the way __DATE__ works.

I remembered I could convert macro arguments in into a string constant. So could get the __LINE__ which is enough with the file name into one string with GCC.

#define xto_str(s) to_str(s)
#define to_str(s) #s

int main()
{
    const char * s = __FILE__ ":" xto_str(__LINE__);
    __builtin_printf(s);
}


.LC0:
        .string "/app/example.cpp:6"
main:
        subq    $8, %rsp
        movl    $.LC0, %edi
        xorl    %eax, %eax
        call    printf
        xorl    %eax, %eax
        addq    $8, %rsp
        ret

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Could __builtin_printf parameters be optimized when being compiled
  2023-02-15 15:49     ` Segher Boessenkool
  2023-02-15 16:42       ` Richard Earnshaw
@ 2023-02-16 13:48       ` Jonny Grant
  1 sibling, 0 replies; 8+ messages in thread
From: Jonny Grant @ 2023-02-16 13:48 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: Richard Earnshaw, gcc-help



On 15/02/2023 15:49, Segher Boessenkool wrote:
> On Wed, Feb 15, 2023 at 03:10:15PM +0000, Jonny Grant wrote:
>> On 15/02/2023 14:30, Richard Earnshaw wrote:
>>>> int main()
>>>> {
>>>>      __builtin_printf("file %s:%d", __FILE__, __LINE__);
>>>> }
> 
> Note that the format needs to end in "\n" if you want this to be
> converted to a puts() call.  Without it it strangely doesn't seem to
> be optimised, although fprintf() is converted to fwrite() in such cases.
> This could be done for printf() as well: you are guaranteed to have
> access to stdout as well, at least if you use printf() instead of the
> builtin (I'm not sure if we do then).
> 
>>> I guess it might be possible to handle cases where all the arguments are constant, but even that has its problems, eg:
>>>
>>> - can we guarantee identical output to the platform printf?
>>
>> That's a good question. I was using __builtin_printf so that should be GCC I expect.
> 
> Not every printf() implementation has exactly the same output in all
> cases.
> 
> Another practically important consideration is what it does to i18n.
> You really need to leave the format string unmodified for that to be
> able to work.
Thank you for your reply. i18n is a good point. At the moment I was just trying to get some strings for debugging in.

Kind regards
Jonny

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2023-02-16 13:48 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-15 14:18 Could __builtin_printf parameters be optimized when being compiled Jonny Grant
2023-02-15 14:30 ` Richard Earnshaw
2023-02-15 15:10   ` Jonny Grant
2023-02-15 15:27     ` Richard Earnshaw
2023-02-16 13:47       ` Jonny Grant
2023-02-15 15:49     ` Segher Boessenkool
2023-02-15 16:42       ` Richard Earnshaw
2023-02-16 13:48       ` Jonny Grant

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).