Live data from Hacker News

Understanding GCC Builtins to Develop Better Tools [pdf]

manuelrigger.at

11–20 of 28 posts

Re: Understanding GCC Builtins to Develop Better Tools [pdf]

#11
post #8

It'd be great if the GCC devs adopted a process for introducing new builtins, that required code review, unit testing, and justification of use-cases. Some of the GCC builtin wrappers are outstanding, e.g. __builtin_memcpy on two-power sizes, since it can do things that wouldn't be possible otherwise. Some GCC builtins, e.g. __builtin_va_start, can take away flexibility since it locks into the core codebase nontrivia…

The main problem with assembly, afaik, is that gcc doesn't know how to optimize even very simple assembly.

Re: Understanding GCC Builtins to Develop Better Tools [pdf]

#12
post #6
post #4

Earlier quoted context omitted.

I write in C only when I need to; in my case I have a limited runtime environment available, so I can't use some other language (which I might otherwise prefer) with a larger runtime requirement, and I also already know C, but not C++. Also, none of the libraries I have to use have C++ APIs. Had I already known C++, and if there were C++ APIs available for the libraries I need, then sure, I might have used C++, but a…

Your other points are valid, but you can use C++ without any more of a runtime than C needs. The main feature that needs runtime support is exceptions, but it’s common enough to use C++ with exceptions disabled even outside embedded. There’s also global constructors, if you’re not already using them from C with GNU extensions; those can be disabled too if needed, but it’s easy enough to make sure the constructors get…

Yes, the limited runtime is what is prohibiting me from using, say, Python. Runtime-wise, C++ would be fine. It’s the other reasons I listed which makes me not use C++ in this case.

Re: Understanding GCC Builtins to Develop Better Tools [pdf]

#13
post #7
post #4

Earlier quoted context omitted.

I write in C only when I need to; in my case I have a limited runtime environment available, so I can't use some other language (which I might otherwise prefer) with a larger runtime requirement, and I also already know C, but not C++. Also, none of the libraries I have to use have C++ APIs. Had I already known C++, and if there were C++ APIs available for the libraries I need, then sure, I might have used C++, but a…

Learning C++ is easy. What's hard is being able to afford a computer that can compile it in a reasonable amount of time. I've seen projects written in C / Assembly that build over 9,000 objects in about 20 seconds on just one PC, whereas more than a few C++ codebases I've seen in the past couple years, that can be about as long as it takes to build just one file. I honestly suspect the only folks really writing C++ c…

Visual C++ with pre-compiled headers, incremental compilation and linking turned on, does a pretty good job.

https://devblogs.microsoft.com/cppblog/improved-linker-funda...

Another tip, use binary libraries and don't build everything from scratch. Modularize the application into their own libraries as well.

Speaking of modules, they are part of C++20, with VC++ and clang adapting their implementations, gcc ramping up its implementation, and everyone else that cares about ISO C++20 also ramping up theirs.

Fun fact, Swift and Rust codebases aren't that fast to compile when compared against C++ code that isn't doing any crazy template metaprogramming.

Re: Understanding GCC Builtins to Develop Better Tools [pdf]

#14
post #8

It'd be great if the GCC devs adopted a process for introducing new builtins, that required code review, unit testing, and justification of use-cases. Some of the GCC builtin wrappers are outstanding, e.g. __builtin_memcpy on two-power sizes, since it can do things that wouldn't be possible otherwise. Some GCC builtins, e.g. __builtin_va_start, can take away flexibility since it locks into the core codebase nontrivia…

> It'd be great if the GCC devs adopted a process for introducing new builtins, that required code review, unit testing, and justification of use-cases

I am not sure how your suggestion differs from how GCC is already being developed.

Re: Understanding GCC Builtins to Develop Better Tools [pdf]

#15
post #12
post #6

Earlier quoted context omitted.

Your other points are valid, but you can use C++ without any more of a runtime than C needs. The main feature that needs runtime support is exceptions, but it’s common enough to use C++ with exceptions disabled even outside embedded. There’s also global constructors, if you’re not already using them from C with GNU extensions; those can be disabled too if needed, but it’s easy enough to make sure the constructors get…

Yes, the limited runtime is what is prohibiting me from using, say, Python. Runtime-wise, C++ would be fine. It’s the other reasons I listed which makes me not use C++ in this case.

Is C++ -> C interop your only reason for avoiding C++? If it is then you might reconsider C++, because calling C code from C++ is usually as easy as wrapping the #include in an extern "C" block.

Re: Understanding GCC Builtins to Develop Better Tools [pdf]

#16
post #8

It'd be great if the GCC devs adopted a process for introducing new builtins, that required code review, unit testing, and justification of use-cases. Some of the GCC builtin wrappers are outstanding, e.g. __builtin_memcpy on two-power sizes, since it can do things that wouldn't be possible otherwise. Some GCC builtins, e.g. __builtin_va_start, can take away flexibility since it locks into the core codebase nontrivia…

The main problem with assembly, afaik, is that gcc doesn't know how to optimize even very simple assembly.

GCC treats inline assembly as an opaque blob of text It knows nothing about, plus some register constraints it knows something about. It will “optimise” assembly if you’ve passed the right registers as input/output, and haven’t marked it volatile and memory clobbering. Simple things like eliminating it if it is dead code, but this probably isn’t the optimisation you were looking for!

Depending on who you ask, this is a feature, not a defect. Inline assembly is your last line of defence against a compiler which thinks it knows better than you.

Clang/llvm go a step further and do parse and optimize your inline assembly; that makes me uncomfortable, but I’ve always subscribed to the “don’t touch user asm” mindset for compiler development.

Your main benefit of builtins over assembly is that no matter how hard I tried I couldn’t get the suggested replacement given by the parent for __atomic_compare_exchange to assemble on my arm64 server!

Re: Understanding GCC Builtins to Develop Better Tools [pdf]

#17

Earlier quoted context omitted.

The main problem with assembly, afaik, is that gcc doesn't know how to optimize even very simple assembly.

GCC treats inline assembly as an opaque blob of text It knows nothing about, plus some register constraints it knows something about. It will “optimise” assembly if you’ve passed the right registers as input/output, and haven’t marked it volatile and memory clobbering. Simple things like eliminating it if it is dead code, but this probably isn’t the optimisation you were looking for! Depending on who you ask, this is…

I've never coded directly for ARM, but if it's anything like x86, then this example might help you (on GCC6+):

char DidIt; asm("lock cmpxchg" : "=@ccz"(DidIt), "+m"(IfThing), "+a"(IsEqualToMe) : "r"(ReplaceItWithMe) : "cc");

Re: Understanding GCC Builtins to Develop Better Tools [pdf]

#18
post #8

It'd be great if the GCC devs adopted a process for introducing new builtins, that required code review, unit testing, and justification of use-cases. Some of the GCC builtin wrappers are outstanding, e.g. __builtin_memcpy on two-power sizes, since it can do things that wouldn't be possible otherwise. Some GCC builtins, e.g. __builtin_va_start, can take away flexibility since it locks into the core codebase nontrivia…

The main problem with assembly, afaik, is that gcc doesn't know how to optimize even very simple assembly.

If GCC has a correctly defined DAG of asm() statements, it might not be able to apply things like De Morgan's Law, but it can do a lot.

Usually what gets optimized the most, counter-intuitively, is the adjacent code that the compiler generates itself, rather than the handwritten assembly you supply (which can in fact be empty string). This basically gives you a means of controlling the compiler's internal algorithms for performing register allocation.

Take for example foo(). If that were written as asm() it'd imply asm("call foo" ::: rax, rcx, rdx, r8, r9, r10, r11, r12, xmm0, xmm1, etc.). If you know ahead of time that foo won't clobber those million different things, then explicitly using asm() can have a wild impact. I've seen just one of those alone cut down the code size of large functions by a third.

Re: Understanding GCC Builtins to Develop Better Tools [pdf]

#19
post #17

Earlier quoted context omitted.

GCC treats inline assembly as an opaque blob of text It knows nothing about, plus some register constraints it knows something about. It will “optimise” assembly if you’ve passed the right registers as input/output, and haven’t marked it volatile and memory clobbering. Simple things like eliminating it if it is dead code, but this probably isn’t the optimisation you were looking for! Depending on who you ask, this is…

I've never coded directly for ARM, but if it's anything like x86, then this example might help you (on GCC6+): char DidIt; asm("lock cmpxchg" : "=@ccz"(DidIt), "+m"(IfThing), "+a"(IsEqualToMe) : "r"(ReplaceItWithMe) : "cc");

Thank you for assuming the best from me, and providing a genuine attempt at help in response to my much more bad-faith remark.

Two things complicate the AArch64 (Arm64) story for atomic builtins.

One is Arm’s weak memory model. This permits different, more efficient, implementations of compare exchange depending on which of the C++ ordering guarantees you need and ask for. A compiler will generate different code for the sequential consistent model than it will for acquire/release.

The other is that there are two ways to provide atomics on Arm, and which you have access to depends on the architecture revision implemented by your particular Arm hardware. If you have Armv8.1-A atomic operations available to you, you’ll use a similar interface to x86; a single instruction which looks like a cmpxchg. If you don’t have the atomic extension, you’ll instead be using a load-lock/store-conditional loop of ldrex/strex for all of your atomic operations.

Getting this exactly right is tricky, so where possible I’d encourage using the atomic builtins (or, of course, your language’s portable API, over assembly).

The biggest benefit is that if in future architecture technology moves forward again, the GCC and language built ins will let you move with it, while assembly leaves you relearning occasionally.

Re: Understanding GCC Builtins to Develop Better Tools [pdf]

#20
post #9
post #7

Earlier quoted context omitted.

Learning C++ is easy. What's hard is being able to afford a computer that can compile it in a reasonable amount of time. I've seen projects written in C / Assembly that build over 9,000 objects in about 20 seconds on just one PC, whereas more than a few C++ codebases I've seen in the past couple years, that can be about as long as it takes to build just one file. I honestly suspect the only folks really writing C++ c…

Maybe take a look at gg [0]? It seems to solve the problem of slow compilation quite nicely. [0] https://github.com/StanfordSNR/gg

Why should I have to outsource compilation to Someone Else's Computer?
Post reply on HN