diff options
author | Daniel Sanders <daniel_l_sanders@apple.com> | 2017-12-04 20:39:32 +0000 |
---|---|---|
committer | Daniel Sanders <daniel_l_sanders@apple.com> | 2017-12-04 20:39:32 +0000 |
commit | 04e4f47e93e2bc26a80bf738c3692846ca622230 (patch) | |
tree | 1e9395e834862e14ab18a434eee7da723e821f10 /llvm/lib/Target | |
parent | ef573fa073e3a4ed71679bc461c37720a34f9a51 (diff) | |
download | bcm5719-llvm-04e4f47e93e2bc26a80bf738c3692846ca622230.tar.gz bcm5719-llvm-04e4f47e93e2bc26a80bf738c3692846ca622230.zip |
[globalisel][tablegen] Split atomic load/store into separate opcode and enable for AArch64.
This patch splits atomics out of the generic G_LOAD/G_STORE and into their own
G_ATOMIC_LOAD/G_ATOMIC_STORE. This is a pragmatic decision rather than a
necessary one. Atomic load/store has little in implementation in common with
non-atomic load/store. They tend to be handled very differently throughout the
backend. It also has the nice side-effect of slightly improving the common-case
performance at ISel since there's no longer a need for an atomicity check in the
matcher table.
All targets have been updated to remove the atomic load/store check from the
G_LOAD/G_STORE path. AArch64 has also been updated to mark
G_ATOMIC_LOAD/G_ATOMIC_STORE legal.
There is one issue with this patch though which also affects the extending loads
and truncating stores. The rules only match when an appropriate G_ANYEXT is
present in the MIR. For example,
(G_ATOMIC_STORE (G_TRUNC:s16 (G_ANYEXT:s32 (G_ATOMIC_LOAD:s16 X))))
will match but:
(G_ATOMIC_STORE (G_ATOMIC_LOAD:s16 X))
will not. This shouldn't be a problem at the moment, but as we get better at
eliminating extends/truncates we'll likely start failing to match in some
cases. The current plan is to fix this in a patch that changes the
representation of extending-load/truncating-store to allow the MMO to describe
a different type to the operation.
llvm-svn: 319691
Diffstat (limited to 'llvm/lib/Target')
4 files changed, 8 insertions, 17 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp index c2d3ae31c62..6999721b626 100644 --- a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp @@ -889,12 +889,6 @@ bool AArch64InstructionSelector::select(MachineInstr &I, return false; } - auto &MemOp = **I.memoperands_begin(); - if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) { - DEBUG(dbgs() << "Atomic load/store not supported yet\n"); - return false; - } - const unsigned PtrReg = I.getOperand(1).getReg(); #ifndef NDEBUG const RegisterBank &PtrRB = *RBI.getRegBank(PtrReg, MRI, TRI); diff --git a/llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp index 05df5120222..6531d5ebe4c 100644 --- a/llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp @@ -231,6 +231,14 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST) { setAction({MemOp, 1, p0}, Legal); } + for (unsigned MemOp : {G_ATOMIC_LOAD, G_ATOMIC_STORE}) { + for (auto Ty : {s8, s16, s32, s64, p0}) + setAction({MemOp, Ty}, Legal); + + // And everything's fine in addrspace 0. + setAction({MemOp, 1, p0}, Legal); + } + // Constants for (auto Ty : {s32, s64}) { setAction({TargetOpcode::G_CONSTANT, Ty}, Legal); diff --git a/llvm/lib/Target/ARM/ARMInstructionSelector.cpp b/llvm/lib/Target/ARM/ARMInstructionSelector.cpp index 6bbeae2e115..b43faf4903a 100644 --- a/llvm/lib/Target/ARM/ARMInstructionSelector.cpp +++ b/llvm/lib/Target/ARM/ARMInstructionSelector.cpp @@ -801,12 +801,6 @@ bool ARMInstructionSelector::select(MachineInstr &I, return selectGlobal(MIB, MRI); case G_STORE: case G_LOAD: { - const auto &MemOp = **I.memoperands_begin(); - if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) { - DEBUG(dbgs() << "Atomic load/store not supported yet\n"); - return false; - } - unsigned Reg = I.getOperand(0).getReg(); unsigned RegBank = RBI.getRegBank(Reg, MRI, TRI)->getID(); diff --git a/llvm/lib/Target/X86/X86InstructionSelector.cpp b/llvm/lib/Target/X86/X86InstructionSelector.cpp index 44bbc3f1b3f..f6530c4eee2 100644 --- a/llvm/lib/Target/X86/X86InstructionSelector.cpp +++ b/llvm/lib/Target/X86/X86InstructionSelector.cpp @@ -484,11 +484,6 @@ bool X86InstructionSelector::selectLoadStoreOp(MachineInstr &I, const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI); auto &MemOp = **I.memoperands_begin(); - if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) { - DEBUG(dbgs() << "Atomic load/store not supported yet\n"); - return false; - } - unsigned NewOpc = getLoadStoreOp(Ty, RB, Opc, MemOp.getAlignment()); if (NewOpc == Opc) return false; |