How to enable new CPU architectures for Swift?

I am creating this post to document my experience trying to enable additional CPU architectures for Swift since 2022, and to request clarification or guidelines for future development.

Back in 2022, as part of my Swift Linux Buildroot GitHub - MillerTechnologyPeru/buildroot-swift: Buildroot external to support the Swift programming language · GitHub project, I started the process of adding support for compiling Swift for Linux Armv5, RISCV64, MIPS and PPC32, not as Swift embedded targets (I don't even think that existed back then), but for Linux. I was successfully able to compile for ARMV5TE, PowerPC 32-bit and RISCV64 (with soft float), but never got MIPS working. Given that Swift has so many compiler / tooling projects (swiftc, clang, llvm, swiftpm) and runtime libraries (StdLib, Dispatch, Foundation), I wanted to explain where to start patches to get an MVP working.

  1. Add Swift ABI support to LLVM. LLVM needs to be patched just to enable Swift calling convention as a target. While I have been able to get this working for swiftcc and swifterrorcc, I don't know where to start for swiftasynccc. This leads me to believe that currently RISCV is working for Embedded Swift, but might have issues compiling for Linux until the swift async calling convention is fully implemented in LLVM.
  2. Patch runtime libraries and standard libraries. I've had to made changes for Armv5TE in Syncronization module which caused compiler crashes, and for MIPS for some parts of the stdlib need to be aware of big endian. Big Endian in particular which right now does not seem to be targeted by CI so we are getting the same regressions I saw with Armv7 years ago.
  3. Add tuples to Swift's CMake files and SwiftPM. This is the simplest part, just make sure your tuples are recognized for Linux (usually just add option to long list), inform Cmake of 32-bit vs 64-bit, and optionally add to list of embedded stdlib targets to build.

In my experience, for the most part my patches for Swift and core libraries have been merged, with the exception of RISCV where I had all the changes ready, only to get rejected due to not measuring compile times, for an identical PR to be opened later Build LLVM with RISCV support by colemancda · Pull Request #61891 · swiftlang/swift · GitHub . However, for LLVM I have never successfully been able to get my changes merged. I started this before LLVM was on GitHub, so that also made the process harder. ⚙ D137512 [clang] Add Swift support for MIPS ⚙ D137309 [clang] Added Swift support for RISCV ⚙ D137510 [clang] Add SwiftABIInfo support for PPC32

Now a couple years later, I see that the maintainer adding AVR had similar issues getting LLVM to support his changes (which are very small), requesting unit tests and other changes [AVR] make the AVR ABI Swift compatible by carlos4242 · Pull Request #72298 · llvm/llvm-project · GitHub , however, his downstream PR was merged into Swift's fork nonetheless, even cherry-picked to make it into nightly builds. One thing I would repeat verbatim from @carlos42421:

I'm still nowhere near enough of an LLVM expert to follow all the aspects of the discussion

I think that for the tiny amount of changes he is proposing, the LLVM team is making things unnecessarily difficult, which is further complicated in my case since MIPS and PPC-32 is abandoned. Even the PPC64 / SystemZ support which IBM contributed seems abandoned and similar to RISCV doesn't support Swift Async calling convention.

Therefore my questions for the Swift compiler team are the following:

  1. Are changes which enable Swift for a CPU arch in LLVM required to be accepted by LLVM first, or does the Swift team have the ability to merge Swift-related code into their LLVM fork without that requirement?
  2. Are LLVM unit tests for codegen required if the changes only enable the Swift calling convention for an architecture.
  3. Is there any documentation on how to properly support the Swift Async CC?

I think the answers for these are going to determine whether the lower level parts of the Swift compiler are open to amateur / hobbyist changes or not. I openly admit that I am not an experienced LLVM contributor and writing those unit tests are going to be out of scope for something that is a hobby for me. In my case I just want to compile Swift for Nintendo 64, GameCube, old Macs and some old MIPS Linux hardware.

2 Likes

Have you seen this policy?

I am not asking for Swift to officially support MIPS, AVR or PowerPC. Or even add that to the CI. The ability to compile for old / non standard platforms can be merged and part of nightly builds or even custom builds you have to compile yourself. If anything that policy could be interpreted as: "we don't require you to write unit tests or change CI infrastructure to support your random obsolete CPU arch". In which case LLVM asking for swift codegen unit tests makes even less sense.

1 Like