Set setMaxAtomicSizeInBitsSupported for Mips. Set the value as appropriate for 64-bit MIPS vs 32-bit and take MIPS-I into consideration.
I am not quite sure if I used the appropriate Subtarget checks.
Differential D141189
[Mips] Set setMaxAtomicSizeInBitsSupported brad on Jan 7 2023, 12:56 AM. Authored by
Details Set setMaxAtomicSizeInBitsSupported for Mips. Set the value as appropriate for 64-bit MIPS vs 32-bit and take MIPS-I into consideration. I am not quite sure if I used the appropriate Subtarget checks.
Diff Detail
Unit Tests Event Timeline
Comment Actions Makes sense to me. For MIPS 1, we have essentially two choices: either we use setMaxAtomicSizeInBitsSupported(0), and generate __atomic_* calls, or we set setMaxAtomicSizeInBitsSupported(32), and generate native load/store with __sync_* calls for cmpxchg/atomicrmw. Either way, we can't actually provide implementations; the user has to make it work somehow. See D137980 for a similar discussion... but generating __sync_* calls seems to cause less trouble. (Not sure if anyone cares about MIPS 1 these days, though.) Comment Actions Hi! Sorry to jump in randomly, but it just so happens that I was working on a very similar patch right now. Funnily enough I need to make everything work on MIPS I, because there are still people caring for that target, mainly in the homebrew scene as the CPU for the Playstation 1 and coprocessor of the Playstation 2 both are MIPS I targets. Wouldn't it be more correct to set atomic widths to 0 and generate __atomic_* calls? As just emitting sync fences on CAS/RMW operations break with multithreading/preemption? I'm not so sure about the Playstation 1 but I'm pretty sure the Playstation 2 has multithreading support on the coprocessor. Also, as it has already been pointed out, MIPS I doesn't even support sync operations, so relying on some implementation of them, to me, seems more complicated to achieve. Comment Actions
You need some sort of operating-system level magic to make atomicrmw/cmpxchg work without ll/sc. Disabling interrupts, or a restartable sequence, or something along those lines. Most of the ways you'd implement that end up being compatible with lowering atomic load/store to plain load/store operations. Granted, other implementations are possible. Comment Actions Yes exactly, what I'm saying is that if we just emit sync fences (in the form of libcalls) for CAS/RMW operations it might become impossible to target systems that have some sort of preemption. So I personally would prefer to set atomic width to 0 and generate libcalls for all atomic operations, so implementors for specific environments can do the right thing for the platform. Comment Actions Baremetal Playstation 1 is likely the only MIPS1 target anyone will ever use with LLVM, so we should do whatever makes sense there. I don't think it makes sense to theorycraft configurations that don't exist. (If MIPS1 Linux were a thing, it would probably do something like https://www.kernel.org/doc/Documentation/arm/kernel_user_helpers.txt .) Comment Actions Fair enough. Looking more in detail at Playstation 1 and 2, they both use cooperative multithreading so preemption is not an issue. So for these targets it doesn't really make a difference. Comment Actions In fact, I don't think that it is a good idea to support MIPS I with degrading the performance of MIPS2+. Comment Actions In fact, here we have more than 1 problems:
Comment Actions To work with MIPS1, I guess if (!Subtarget.hasMips2()) setMaxAtomicSizeInBitsSupported(0); Should be enough. Comment Actions LGTM. (I was sort of hoping for someone with Mips expertise to show up to approve this, but lacking that, I don't see any issues here.) This comment was removed by wzssyqa. This comment was removed by wzssyqa. Comment Actions Sorry. It is my fault. With some dig, I know that some microarchitectures may split one ldc1/sdc1 to 2 micro-ops. So, I agree with Brad's patch now. Maybe, in future we can determine which core won't split it. |
Else case doesn't make sense to me but I know nothing about mips