diff options
author | Pavel Iliin <Pavel.Iliin@arm.com> | 2020-11-19 19:52:46 +0000 |
---|---|---|
committer | Pavel Iliin <Pavel.Iliin@arm.com> | 2020-11-20 13:30:12 +0000 |
commit | 4d7df43ffdb460dddb2877a886f75f45c3fee188 (patch) | |
tree | e49c230a3c04869ae0b3c942d6e67cf64bb0ab36 /llvm/lib/CodeGen/TargetLoweringBase.cpp | |
parent | 1285781fc5a42ad4712ac4866a219c40e3c3d860 (diff) | |
download | llvm-4d7df43ffdb460dddb2877a886f75f45c3fee188.zip llvm-4d7df43ffdb460dddb2877a886f75f45c3fee188.tar.gz llvm-4d7df43ffdb460dddb2877a886f75f45c3fee188.tar.bz2 |
[AArch64] Out-of-line atomics (-moutline-atomics) implementation.
This patch implements out of line atomics for LSE deployment
mechanism. Details how it works can be found in llvm/docs/Atomics.rst
Options -moutline-atomics and -mno-outline-atomics to enable and disable it
were added to clang driver. This is clang and llvm part of out-of-line atomics
interface, library part is already supported by libgcc. Compiler-rt
support is provided in separate patch.
Differential Revision: https://reviews.llvm.org/D91157
Diffstat (limited to 'llvm/lib/CodeGen/TargetLoweringBase.cpp')
-rw-r--r-- | llvm/lib/CodeGen/TargetLoweringBase.cpp | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp index 8b44885..e4d9b468 100644 --- a/llvm/lib/CodeGen/TargetLoweringBase.cpp +++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -448,6 +448,83 @@ RTLIB::Libcall RTLIB::getUINTTOFP(EVT OpVT, EVT RetVT) { return UNKNOWN_LIBCALL; } +RTLIB::Libcall RTLIB::getOUTLINE_ATOMIC(unsigned Opc, AtomicOrdering Order, + MVT VT) { + unsigned ModeN, ModelN; + switch (VT.SimpleTy) { + case MVT::i8: + ModeN = 0; + break; + case MVT::i16: + ModeN = 1; + break; + case MVT::i32: + ModeN = 2; + break; + case MVT::i64: + ModeN = 3; + break; + case MVT::i128: + ModeN = 4; + break; + default: + return UNKNOWN_LIBCALL; + } + + switch (Order) { + case AtomicOrdering::Monotonic: + ModelN = 0; + break; + case AtomicOrdering::Acquire: + ModelN = 1; + break; + case AtomicOrdering::Release: + ModelN = 2; + break; + case AtomicOrdering::AcquireRelease: + case AtomicOrdering::SequentiallyConsistent: + ModelN = 3; + break; + default: + return UNKNOWN_LIBCALL; + } + +#define LCALLS(A, B) \ + { A##B##_RELAX, A##B##_ACQ, A##B##_REL, A##B##_ACQ_REL } +#define LCALL5(A) \ + LCALLS(A, 1), LCALLS(A, 2), LCALLS(A, 4), LCALLS(A, 8), LCALLS(A, 16) + switch (Opc) { + case ISD::ATOMIC_CMP_SWAP: { + const Libcall LC[5][4] = {LCALL5(OUTLINE_ATOMIC_CAS)}; + return LC[ModeN][ModelN]; + } + case ISD::ATOMIC_SWAP: { + const Libcall LC[5][4] = {LCALL5(OUTLINE_ATOMIC_SWP)}; + return LC[ModeN][ModelN]; + } + case ISD::ATOMIC_LOAD_ADD: { + const Libcall LC[5][4] = {LCALL5(OUTLINE_ATOMIC_LDADD)}; + return LC[ModeN][ModelN]; + } + case ISD::ATOMIC_LOAD_OR: { + const Libcall LC[5][4] = {LCALL5(OUTLINE_ATOMIC_LDSET)}; + return LC[ModeN][ModelN]; + } + case ISD::ATOMIC_LOAD_CLR: { + const Libcall LC[5][4] = {LCALL5(OUTLINE_ATOMIC_LDCLR)}; + return LC[ModeN][ModelN]; + } + case ISD::ATOMIC_LOAD_XOR: { + const Libcall LC[5][4] = {LCALL5(OUTLINE_ATOMIC_LDEOR)}; + return LC[ModeN][ModelN]; + } + default: + return UNKNOWN_LIBCALL; + } +#undef LCALLS +#undef LCALL5 +} + RTLIB::Libcall RTLIB::getSYNC(unsigned Opc, MVT VT) { #define OP_TO_LIBCALL(Name, Enum) \ case Name: \ |