Quick summary
Trying to summarise the feedback, there seem to be two major trends in this thread:
- There’s good support for splitting
builtinsfrom the rest ofcompiler-rt. Supporting arguments were mostly in the build side, and range from simplifying the build system, decoupling it from the requirements of the more complex runtimes in RT, inter-dependencies creating bootstrapping problems, etc. - There’s a split between carrying runtime library information across the toolchain and linking (at least parts) of the builtins by default, with technical arguments on both sides.
These concerns could be seen as orthogonal, so I think we should (at least try to) treat them separately.
My view is that how we split this will have to take more than just individual pros and cons technical arguments and venture into usability and “least surprise” principles. It also can’t be based on “what GCC does” (or doesn’t do). LLVM is not a compiler, but a lot of compilers are built on top of it, so we need to at least provide the ability of toolchain builders (including upstream Clang/LLVM) to provide users with reasonable functionality.
Split builtins
I think there’s enough support to do this, mostly due to build issues, and there should be little to no issues to the rest of the compiler, including the issue that created this proposal. Splitting it won’t force us to include it by default on any target, it’ll just simplify the build system.
@compnerd @petrhosek (and others interested), we should discuss next steps towards an actual RFC on the final structure.
The key issues in this thread need to be addressed, as well as the potential of linking with parts of the builtins (ex. 128-bit arithmetic) but not the whole, for specific targets.
Note: The runtime library’s name should still continue to be compiler-rt (because of --rtlib) and so we may keep the builtins in compiler-rt and move the rest somewhere else, which is the same thing.
Link builtins by default or not (or parts)
This is less clear, and I see three options:
- Always link
builtinsand default--rtlib=compiler-rton targets (CPU+OS+ABI) that we support all Clang generated functions. Other targets just do what we “know” the target runtime supports. - Split
builtinsinto “generic support for the targets” and “Clang-specific things” and always link the latter, keeping the former in the same way we do today with--rtlib. - Try to propagate options through driver, front-end, IR, MIR, objects, linker, libraries, etc. This is a non-trivial amount of work, involving a non-trivial number of RFCs on almost all stages of the compilation process, and will probably need to be agreed in full before anything starts to happen.
As is probably clear by my wording above, I’m ok with the first two, but I think the third option is a recipe for never finishing and being blocked by future changes to the GNU toolchain (who usually ignore our decisions and do their stuff regardless).
If my count is right, in this thread (which is no proof of consensus), there’s more support for 1 and 2 than 3. But of course, this will depend on how we implement them in the long run.
Note: if we make compiler-rt the default runtime for specific platforms, we have to emit build warnings when the compiler-rt project is not chosen. And we’ll start getting issues open on that…
Discarded ideas
There are, of course, many more ideas, but they were discarded due to not being practical.
For example, relying on incomplete information to drive the compiler. Taking a driver triple to assume support, but not knowing what the linker will do (because we forgot to add -Wl options).
Or assuming we’re linking with the compiler driver and pass the triple to the linker flags, only the linker ends up being bfd who has no idea what that is and will ignore.
Also linking the builtins as well as the system’s runtime (ex. libgcc) seems frail. Sure, there are options on symbols (like COMDAT) that help making the decision of which one to take, and there’s ordering of library that we can control.
But there’s always tools that don’t quite support what we need, and argument ordering can always be broken by a system-wide CXXFLAGS or users adding stuff to the end of the command line on a script.
Next steps
I’d like to propose some next steps, so that we’re clear on where we stand.
Builtins split
There were enough details on this thread to form a good technical proposal, so we should make a concrete RFC and start discussing actual technical details.
This doesn’t mean consensus has formed, just that there’s enough support to spend time on an actual RFC. The decision to continue with the split should be made there, not here.
Linking rt-lib
Before we decide how we’ll link what we need when, we need some information from people using compiler-rt in different ways.
Already using compiler-rt as default builtin library
For folks already using it (FreeBSD, Mandriva, Apple), what would simplify your build system?
I imagine there are hacks to pretend to be libgcc in places, but it would be nice if one of those places isn’t LLVM. If we split the builtins, what would be an easy way to make that the default for your platform without the need of hacks?
Able to use compiler-rt but problems with system runtime
For Win/GNU-based environments, libgcc is still there. Are there any tools, code size, special requirements that stop you linking compiler-rt by default with Clang on your system?
Think about compiling objects with different compilers (Clang and GCC) and linking them together. Also, linking GCC compiled static/dynamic system libraries with Clang compiled user programs. Weird system requirements around import/export symbols, system linker oddities, etc.
If not, could you do a comprehensive build with --rtlib=compiler-rt today and see if all works? If it does, I guess we can “just turn it on by default” on the affected triples and we’d have less problems.
If so, would linking just the shim delta (ex. 128-bit) as a separate library name be a reasonable alternative solution?
Unable to use compiler-rt due to support quality
If your target (mostly new architecture I guess) doesn’t have full support in compiler-tr (both C and asm functions) for the functionality your system needs, we should not be generating calls to compiler-rt only functions in the first place.
The issue reported was on AArch64, but that’s a back-end decision, and your target shouldn’t make that call legal, and you’ll have no problems.
But as soon as you want to use those functions, you’ll be in the same place and will have to make a decision.
Anything else I forgot…
Please include your case here.
Thanks!