Skip to content

Conversation

ysbaddaden
Copy link
Contributor

@ysbaddaden ysbaddaden commented Sep 28, 2025

Adds support for the llvm::TargetOptions::EmulatedTLS setting that is only available through the C++ API. This patch implements a custom alternative to LLVMCreateTargetMachine which requires to always compile src/llvm/llvm_ext.o again 😞

Emulated TLS is now always set for Android, OpenBSD and MinGW, which should in turn make the @[ThreadLocal] annotation portable 🤞

TODO:

  • compilation with different LLVM versions
  • CI: MinGW/UCRT64
  • CI: MinGW/CLANGARM64

Closes #16176.

The implementation doesn't reuse LLVMTargetMachineOptions that is a
private type. It instead inlines the different setter methods and
directly calls `llvm::Target::createTargetMachine()`.
@HertzDevil
Copy link
Contributor

This must be added to LLVM upstream first. The most recent LLVM major release must never require llvm_ext.cc, our Windows releases more or less rely on this guarantee (older versions above LLVM 17 might start requiring this file if we determine that not supporting them on Windows for distribution is fine).

In this case the upstream C function signature would be void LLVMTargetMachineOptionsSetEmulatedTLS(LLVMTargetMachineOptionsRef, LLVMBool).

@ysbaddaden
Copy link
Contributor Author

ysbaddaden commented Sep 28, 2025

But then ThreadLocal will keep being broken until we eventually get something working, accepted and released in LLVM upstream, and I'm not willing to spend time trying to figure out how to get the LLVM project sources up and running to start hacking.

What's the problem with compiling crystal with a custom LLVM binding? I mean, both Rust and Zig do it, and we don't care about the missing llvm-config.exe, we just need the Makefile.win to know where the headers are supposed to be.

@straight-shoota
Copy link
Member

After many years we've finally be able to get rid of the llvm-ext dependency.

I wouldn't want to bring it back as an expected general build requirement just like that. It nullifies all the effort spent on simplifying the build process.
Reverting back to rely on llvm-ext for latest LLVM should require a dedicated discussion about all its effects.

@straight-shoota straight-shoota marked this pull request as draft September 29, 2025 08:50
@ysbaddaden
Copy link
Contributor Author

ysbaddaden commented Sep 29, 2025

I pushed a PR to LLVM: llvm/llvm-project#161155

Now we wait for someone in LLVM to notice 💤 (oh, lucky)
Nobody will, so next week I'll have to ping someone 🕙
Then we wait again 💤
Then we hope for it to be accepted and merged 🙏
Then we wait for release 💤
Then we'll have to switch to LLVMTargetMachineOptions 👨‍💻
Oh, and keep the current way for LLVM < X 😒

The feature also won't be available without LLVM X (while at least LLVM 13+ supports it).

I'm not fond of custom bindings, but truth is that the LLVM-C API is lagging by many years behind the C++ API. With a custom binding we'd enable the feature today and be compatible with LLVM 13+ (at least), and we can still push patches upstream in parallel.

We also never got rid of llvm ext: it's still required whenever compiling for LLVM < 18 (e.g. macOS) and the support is still there on every target with the exception of the CI configuration for Windows.

@ysbaddaden
Copy link
Contributor Author

Superseded by #16178.

@ysbaddaden ysbaddaden closed this Sep 29, 2025
@ysbaddaden ysbaddaden deleted the feature/llvm-target-machine-emulated-tls branch September 29, 2025 14:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

The ThreadLocal annotation isn't portable (but it could)
3 participants