Introducing clang-cl as an alternative MSBuild backend

Proposal

I propose to introduce clang-cl for the MSBuild backend in CPython. I also propose to use this new clang-cl backend for python.org Windows releases (Removed due to ABI considerations). I am not proposing to remove the MSVC backend altogether. The clang-cl backend will coexist with the MSVC backend as a separate option we can pass to PCBuild/build.bat. The default backend without any options passed to build.bat will still be MSVC.

Why

Performance

Clang-19 no PGO with the new tail calling interpreter outperforms MSVC with PGO by 3% on pyperformance (results obtained by looking at the faster-cpython benchmarking results), This means even without PGO, Clang-19 already generally performs better than MSVC that has PGO. This figure will only increase once we have PGO working for clang-19 on MSVC.

CPython contributor productivity

We’ve had to revert PRs multiple times because MSVC have been unable to properly inline/PGO a certain part of the interpreter loop. This is blocking things like using static inline functions for StackRefs in CPython, which is currently required by free-threading, and also required if we want to turn on StackRefs in the default build. See more examples and discussions in this thread Change MSBuild to use the Clang backend · Issue #690 · faster-cpython/ideas · GitHub

Proof of Concept & Addressing Maintainability Concerns

Changing MSBuild to use clang-cl is a one or two line change (though we still need a few more lines for the build.bat changes). Enabling PGO is a little harder, but thanks to contributor Chris Eibl, a proof-of-concept PR is up that requires 21 lines of code change Support PGO for clang-cl by chris-eibl · Pull Request #129907 · python/cpython · GitHub

Concerns

Performance

Already addressed above. Previously clang-cl apparently regressed perf, but now it’s fine, and in fact perf is positive.

ABI compatibility

This is the main concern. AFAIK, there is no ABI breakage according to Clang’s website MSVC compatibility — Clang 19.1.0 documentation . CPython AFAIK doesn’t expose any of the features that Clang has only partial/no ABI compatibility for in our public ABI.

Downstream breakage

Since we are keeping MSVC as the default, downstream packagers who use our build script won’t suddenly get whiplashed. There is thus very low likelihood of us breaking downstream packagers.

Implementation plan

  • Before 3.14a6: Land PRs to add an option for the build.bat script. Keep MSVC as the default still. PRs will require either additional CI job or buildbot to be accepted.
  • 3.14a6 release: nicely ask (pretty please) the Windows RMs to build the Python binaries with clang-cl mode turned on.
  • 3.14a6-rc1: ask people to test and observe if there’s anything amiss. Revert if it’s something that we can’t fix.
  • 3.14.0: Windows users get better perf, CPython devs get a nicer dev experience. Yay!

CC @steve.dower @colesbury

9 Likes

Holy cow! This is big.

A naive question — you seem to imply that this is (or will soon be) required to build the free-threading version. Assuming that is to become the default build in 3-5 years and the only build soon after, I infer that at that point the MSVC backend will then become obsolete, and this will be the backend?

Separately, would it be a terrible burden to make this a PEP? You already mostly follow the PEP format.

2 Likes

you seem to imply that this is (or will soon be) required to build the free-threading version.

Sorry that wasn’t my intention. This is just one example I brought up off the top of my head. The free-threading version can still build with MSVC, it just won’t perform as well I believe (though I can’t verify this, as we haven’t been running free-threading builds on the benchmarking infra on Windows). Separately, Mark (Shannon) is trying to get the StackRef stuff on the default build as well for perf reasons. So even if not for free-threading, we would still use this.

I infer that at that point the MSVC backend will then become obsolete, and this will be the backend?

Sorry again, I can’t really predict that far out.

Separately, would it be a terrible burden to make this a PEP? You already mostly follow the PEP format.

Sure. Though I think the part that actually needs a PEP is switching the python org binaries to use clang-cl. The rest don’t involve any significant implementation effort nor potential breakage. Do you think if it would be okay if we landed the 30-line change to the build script first to allow clang-cl with PGO, but leave it off and only test it in CI? I’ll definitely leave this post up for 2 weeks to observe consensus first. I think it would be nice if we could let downstream packagers, like uv (Astral), test it out.

2 Likes

What will be required to make clang-cl available on Windows GHA runners and buildbots?
Is there a difference in Windows versions range that supports clang-cl 19+ vs MSVC toolchains?

1 Like

One small question here. What precisely is clang-cl? I’m aware of clang as a compiler (I use it occasionally) but I get it from a 3rd party build. Looking at the llvm/clang website, it’s not immediately obvious to me what I’d need to download to get clang-cl.

I assume there will be clear instructions provided somewhere in the CPython source tree as to how developers should get the correct clang build(s), but right now it’s not at all clear.

1 Like

“clang-cl is an alternative command-line interface to Clang, designed for compatibility with the Visual C++ compiler, cl.exe.”

3 Likes

What precisely is clang-cl

IIRC, it tries to be the clang version of cl.exe.

Ideally if we were to introduce this, we would provide an option to decouple the version of clang we use from Visual Studio, so that we don’t have to rely on the bundled one. You’d need to pass "/p:LLVMInstallDir=C:\Program Files\LLVM" to build.bat. In fact, if you want to try it out right now, after following the first 2 steps in that guide above to get clang-cl on your Visual Studio, you can just pass build.bat "/p:PlatformToolset=ClangCL" "/p:PreferredToolArchitecture=x64" and you will automatigically have a clang-built python.exe !

Also the link James provided above is a little outdated. clang-cl can be selected in the Visual Studio installer now as of VS2019.

What will be required to make clang-cl available on Windows GHA runners and buildbots?
Is there a difference in Windows versions range that supports clang-cl 19+ vs MSVC toolchains?

I’m not too clear on the buildbots and GHA right now. However, we ideally want the later versions of clang because they have better ABI compatibility. So we’d decouple it like what I replied to Paul above.

3 Likes

Thanks, I’ll take a look. I assume clang-cl is available in the free versions of Visual Studio, and that will be sufficient for developers?

1 Like

I dual-booted into my Windows machine to check: on VS2022 community edition (it says in the top left corner) I can find it:

2 Likes

yes, it’s a VS component option. I’m sure I’ve seen it at least as far
back as vs2019, available for build tools as well.

2 Likes

So clang-cl is already supported by the build, and we largely keep it running. There’s no question it’s technically possible.

My concern is that the ABI compatibility risks are being way undersold here. I don’t think we can reasonably change the default build (that is, the one we distribute ourselves) without a very loud and noisy deprecation period, and a lot of reaching out to build backends to start testing. And since the build backends don’t actually contain a lot of the code that could break, we need them to start reaching out to their users to rebuild with the new compiler and a new test build of CPython to ensure nothing breaks.

To summarise my concerns, I’m worried about interactions between existing users of the C runtime (i.e. if I change locale through C, will it affect Python? and so on for any other state stored by the CRT, such as file descriptors and stdio), existing users of C++ (who have already recently realised that they need to do MSVC-specific build steps to link/bundle the correct DLLs), and anyone who compiles specifically for Windows and is using MSVC-specific header files (such as pywin32, psutil IIRC, and anyone using COM).

I’m not personally convinced that CPython built with LLVM should use extension modules built with MSVC. I’d love someone to convince me, ideally on a technical level by showing that the ABIs, statically linked code and dependencies are identical.

In the meantime, I’ll also mention that we’ve asked the MSVC team to add the feature that Ken needs for the major speedup, and they are amenable to it. Also, my prior benchmarks have shown that clang-cl (without the new feature) was ~10% regression from MSVC. It’s possible that an upcoming MSVC will make the clang-cl build redundant (it aligns with my employer’s interests for me to keep pushing the MSVC team to make that true, so I’ll be trying to ensure that happens[1]) and I’d quite frankly prefer to burden the MSVC team with work than our community of package developers.


  1. It doesn’t necessarily require CPython to use MSVC. The only thing that happens if MSVCCPython switches is I lose some leverage over the MSVC team, and so they’ll stop making improvements for us :wink: ↩︎

7 Likes

Makes sense. Would you be amenable to us at least adding PGO support for clang-cl in Support PGO for clang-cl by chris-eibl · Pull Request #129907 · python/cpython · GitHub ?

I would like a future where we support both clang-cl and MSVC fully. Though like you said, changing the default definitely requires major disruption, and definitely requires a PEP as well.

2 Likes

Provided it doesn’t affect the default build.bat commands (including -d and --pgo options, on their own without any other options necessarily enabled), feel free to add any non-default builds you like.

2 Likes

So, for the record, are there actual reasons to believe that these interactions might be problematic? Is clang-cl merely another compiler backend, or does it replace other elements in the build stack?

1 Like

I’m not sure. Clearly it exposes features that don’t exist in MSVC, and presumably it must do something different or else nobody would want to use it. I don’t know exactly what those “somethings” are.

1 Like

It is merely a compiler that generates object code compatible for use with MSVC++ and Windows. Just as other widely used compiler toolchains for Windows do. (IIUC Intel and AMD ship a clang on windows rebranded as their own for this purpose already)

1 Like

After thinking more about this. I withdraw my second request on making it the default for the python org builds. However, I still think it’s good to introduce an alternative, and it seems Steve is agreeable to it.

2 Likes

Like gpshead already has written, it is a drop-in compiler for MSVC and brings also its own linker.
But it uses the MSVC headers and links to the MSVC (static/dynamic) libraries.

Chrome is using clang-cl already for quite some time: Clang is now used to build Chrome for Windows - The LLVM Project Blog. The link includes motivations and pros/cons.

I fully agree. Python has far more extensions than chrome :slight_smile:

Great to hear that!

I think so, too. Microsoft did a lot to use clang-cl so easily. And since @steve.dower’s PR in 2023, Python can be compiled with clang-cl without errors.

Let’s help those people who are eager to try out new things and take the risks for themselves (or a much smaller community).

5 Likes