diff options
| author | Daniel Sanders <daniel_l_sanders@apple.com> | 2017-10-15 02:41:12 +0000 |
|---|---|---|
| committer | Daniel Sanders <daniel_l_sanders@apple.com> | 2017-10-15 02:41:12 +0000 |
| commit | 39690bdf429bc4aa0fb70ee454e6d602a77d0a39 (patch) | |
| tree | f8d919028078cacc1cd69362fde65e7b1cde98a0 /llvm/include | |
| parent | b7c0b089f26af8150209af173af4c199b9e13531 (diff) | |
| download | bcm5719-llvm-39690bdf429bc4aa0fb70ee454e6d602a77d0a39.tar.gz bcm5719-llvm-39690bdf429bc4aa0fb70ee454e6d602a77d0a39.zip | |
[globalisel][tablegen] Map ld and st to G_LOAD and G_STORE. NFC
Summary:
There is an important mismatch between ISD::LOAD and G_LOAD (and likewise for
ISD::STORE and G_STORE). In SelectionDAG, ISD::LOAD is a non-atomic load
and atomic loads are handled by a separate node. However, this is not true of
GlobalISel's G_LOAD. For G_LOAD, the MachineMemOperand indicates the atomicity
of the operation. As a result, this mapping must also add a predicate that
checks for non-atomic MachineMemOperands.
This is NFC since these nodes always have predicates in practice and are
therefore always rejected at the moment.
Depends on D37443
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: kristof.beyls, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37445
llvm-svn: 315843
Diffstat (limited to 'llvm/include')
3 files changed, 44 insertions, 0 deletions
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h b/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h index db9c5b713b7..3cc1d35cc5c 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h @@ -107,6 +107,9 @@ enum { /// - InsnID - Instruction ID /// - The predicate to test GIM_CheckAPFloatImmPredicate, + /// Check a memory operation is non-atomic. + /// - InsnID - Instruction ID + GIM_CheckNonAtomic, /// Check the type for the specified operand /// - InsnID - Instruction ID diff --git a/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h b/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h index f1bc8484096..d4cb1326fb8 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h @@ -209,6 +209,25 @@ bool InstructionSelector::executeMatchTable( return false; break; } + case GIM_CheckNonAtomic: { + int64_t InsnID = MatchTable[CurrentIdx++]; + DEBUG(dbgs() << CurrentIdx << ": GIM_CheckNonAtomic(MIs[" << InsnID + << "])\n"); + assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); + assert((State.MIs[InsnID]->getOpcode() == TargetOpcode::G_LOAD || + State.MIs[InsnID]->getOpcode() == TargetOpcode::G_STORE) && + "Expected G_LOAD/G_STORE"); + + if (!State.MIs[InsnID]->hasOneMemOperand()) + if (handleReject() == RejectAndGiveUp) + return false; + + for (const auto &MMO : State.MIs[InsnID]->memoperands()) + if (MMO->getOrdering() != AtomicOrdering::NotAtomic) + if (handleReject() == RejectAndGiveUp) + return false; + break; + } case GIM_CheckType: { int64_t InsnID = MatchTable[CurrentIdx++]; diff --git a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td index 96245b251f9..c012b20fd7b 100644 --- a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td +++ b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td @@ -23,6 +23,11 @@ class GINodeEquiv<Instruction i, SDNode node> { Instruction I = i; SDNode Node = node; + + // SelectionDAG has separate nodes for atomic and non-atomic memory operations + // (ISD::LOAD, ISD::ATOMIC_LOAD, ISD::STORE, ISD::ATOMIC_STORE) but GlobalISel + // stores this information in the MachineMemoryOperand. + bit CheckMMOIsNonAtomic = 0; } // These are defined in the same order as the G_* instructions. @@ -72,6 +77,23 @@ def : GINodeEquiv<G_INTRINSIC_W_SIDE_EFFECTS, intrinsic_w_chain>; def : GINodeEquiv<G_BR, br>; def : GINodeEquiv<G_BSWAP, bswap>; +// Broadly speaking G_LOAD is equivalent to ISD::LOAD but there are some +// complications that tablegen must take care of. For example, Predicates such +// as isSignExtLoad require that this is not a perfect 1:1 mapping since a +// sign-extending load is (G_SEXT (G_LOAD x)) in GlobalISel. Additionally, +// G_LOAD handles both atomic and non-atomic loads where as SelectionDAG had +// separate nodes for them. This GINodeEquiv maps the non-atomic loads to +// G_LOAD with a non-atomic MachineMemOperand. +def : GINodeEquiv<G_LOAD, ld> { let CheckMMOIsNonAtomic = 1; } +// Broadly speaking G_STORE is equivalent to ISD::STORE but there are some +// complications that tablegen must take care of. For example, predicates such +// as isTruncStore require that this is not a perfect 1:1 mapping since a +// truncating store is (G_STORE (G_TRUNCATE x)) in GlobalISel. Additionally, +// G_STORE handles both atomic and non-atomic stores where as SelectionDAG had +// separate nodes for them. This GINodeEquiv maps the non-atomic stores to +// G_STORE with a non-atomic MachineMemOperand. +def : GINodeEquiv<G_STORE, st> { let CheckMMOIsNonAtomic = 1; } + // Specifies the GlobalISel equivalents for SelectionDAG's ComplexPattern. // Should be used on defs that subclass GIComplexOperandMatcher<>. class GIComplexPatternEquiv<ComplexPattern seldag> { |

