diff options
author | Daniel Sanders <daniel_l_sanders@apple.com> | 2017-11-28 22:07:05 +0000 |
---|---|---|
committer | Daniel Sanders <daniel_l_sanders@apple.com> | 2017-11-28 22:07:05 +0000 |
commit | 7f3e660b838376ca17c7902d12d5d5d305932616 (patch) | |
tree | 73f70204c5d4b9275f9491f1d8eec6f665e759b1 /utils | |
parent | ee2e970651e392df519e2173b98b916b90a64b04 (diff) |
[globalisel][tablegen] Add support for importing G_ATOMIC_CMPXCHG, G_ATOMICRMW_* rules from SelectionDAG.
GIM_CheckNonAtomic has been replaced by GIM_CheckAtomicOrdering to allow it to support a wider
range of orderings. This has then been used to import patterns using nodes such
as atomic_cmp_swap, atomic_swap, and atomic_load_*.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@319232 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r-- | utils/TableGen/GlobalISelEmitter.cpp | 120 |
1 files changed, 82 insertions, 38 deletions
diff --git a/utils/TableGen/GlobalISelEmitter.cpp b/utils/TableGen/GlobalISelEmitter.cpp index 505864bb0d5..f82b2fd3e9b 100644 --- a/utils/TableGen/GlobalISelEmitter.cpp +++ b/utils/TableGen/GlobalISelEmitter.cpp @@ -191,6 +191,8 @@ static std::string explainPredicates(const TreePatternNode *N) { for (const auto &P : N->getPredicateFns()) { Explanation += (Separator + P.getOrigPatFragRecord()->getRecord()->getName()).str(); + Separator = ", "; + if (P.isAlwaysTrue()) Explanation += " always-true"; if (P.isImmediatePattern()) @@ -217,6 +219,17 @@ static std::string explainPredicates(const TreePatternNode *N) { Explanation += (" MemVT=" + VT->getName()).str(); if (Record *VT = P.getScalarMemoryVT()) Explanation += (" ScalarVT(MemVT)=" + VT->getName()).str(); + + if (P.isAtomicOrderingMonotonic()) + Explanation += " monotonic"; + if (P.isAtomicOrderingAcquire()) + Explanation += " acquire"; + if (P.isAtomicOrderingRelease()) + Explanation += " release"; + if (P.isAtomicOrderingAcquireRelease()) + Explanation += " acq_rel"; + if (P.isAtomicOrderingSequentiallyConsistent()) + Explanation += " seq_cst"; } return Explanation; } @@ -253,16 +266,26 @@ static Error isTrivialOperatorNode(const TreePatternNode *N) { if (Predicate.isImmediatePattern()) continue; - if (Predicate.isLoad() && Predicate.isUnindexed()) + if (Predicate.isNonExtLoad()) continue; - if (Predicate.isNonExtLoad()) + if (Predicate.isNonTruncStore()) continue; - if (Predicate.isStore() && Predicate.isUnindexed()) + if (Predicate.isLoad() || Predicate.isStore()) { + if (Predicate.isUnindexed()) + continue; + } + + if (Predicate.isAtomic() && Predicate.getMemoryVT()) continue; - if (Predicate.isNonTruncStore()) + if (Predicate.isAtomic() && + (Predicate.isAtomicOrderingMonotonic() || + Predicate.isAtomicOrderingAcquire() || + Predicate.isAtomicOrderingRelease() || + Predicate.isAtomicOrderingAcquireRelease() || + Predicate.isAtomicOrderingSequentiallyConsistent())) continue; HasUnsupportedPredicate = true; @@ -1172,7 +1195,7 @@ protected: enum PredicateKind { IPM_Opcode, IPM_ImmPredicate, - IPM_NonAtomicMMO, + IPM_AtomicOrderingMMO, }; PredicateKind Kind; @@ -1301,20 +1324,25 @@ public: } }; -/// Generates code to check that a memory instruction has a non-atomic MachineMemoryOperand. -class NonAtomicMMOPredicateMatcher : public InstructionPredicateMatcher { +/// Generates code to check that a memory instruction has a atomic ordering +/// MachineMemoryOperand. +class AtomicOrderingMMOPredicateMatcher : public InstructionPredicateMatcher { + StringRef Order; + public: - NonAtomicMMOPredicateMatcher() - : InstructionPredicateMatcher(IPM_NonAtomicMMO) {} + AtomicOrderingMMOPredicateMatcher(StringRef Order) + : InstructionPredicateMatcher(IPM_AtomicOrderingMMO), Order(Order) {} static bool classof(const InstructionPredicateMatcher *P) { - return P->getKind() == IPM_NonAtomicMMO; + return P->getKind() == IPM_AtomicOrderingMMO; } void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule, unsigned InsnVarID) const override { - Table << MatchTable::Opcode("GIM_CheckNonAtomic") + Table << MatchTable::Opcode("GIM_CheckAtomicOrdering") << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID) + << MatchTable::Comment("Order") + << MatchTable::NamedValue(("(int64_t)AtomicOrdering::" + Order).str()) << MatchTable::LineBreak; } }; @@ -2474,49 +2502,65 @@ Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher( continue; } - // No check required. A G_LOAD is an unindexed load. - if (Predicate.isLoad() && Predicate.isUnindexed()) - continue; - // No check required. G_LOAD by itself is a non-extending load. if (Predicate.isNonExtLoad()) continue; - if (Predicate.isLoad() && Predicate.getMemoryVT() != nullptr) { - Optional<LLTCodeGen> MemTyOrNone = - MVTToLLT(getValueType(Predicate.getMemoryVT())); - - if (!MemTyOrNone) - return failedImport("MemVT could not be converted to LLT"); - - InsnMatcher.getOperand(0).addPredicate<LLTOperandMatcher>(MemTyOrNone.getValue()); - continue; - } - - // No check required. A G_STORE is an unindexed store. - if (Predicate.isStore() && Predicate.isUnindexed()) - continue; - // No check required. G_STORE by itself is a non-extending store. if (Predicate.isNonTruncStore()) continue; - if (Predicate.isStore() && Predicate.getMemoryVT() != nullptr) { - Optional<LLTCodeGen> MemTyOrNone = - MVTToLLT(getValueType(Predicate.getMemoryVT())); + if (Predicate.isLoad() || Predicate.isStore() || Predicate.isAtomic()) { + if (Predicate.getMemoryVT() != nullptr) { + Optional<LLTCodeGen> MemTyOrNone = + MVTToLLT(getValueType(Predicate.getMemoryVT())); - if (!MemTyOrNone) - return failedImport("MemVT could not be converted to LLT"); + if (!MemTyOrNone) + return failedImport("MemVT could not be converted to LLT"); - InsnMatcher.getOperand(0).addPredicate<LLTOperandMatcher>(MemTyOrNone.getValue()); - continue; + InsnMatcher.getOperand(0).addPredicate<LLTOperandMatcher>( + MemTyOrNone.getValue()); + continue; + } + } + + if (Predicate.isLoad() || Predicate.isStore()) { + // No check required. A G_LOAD/G_STORE is an unindexed load. + if (Predicate.isUnindexed()) + continue; + } + + if (Predicate.isAtomic()) { + if (Predicate.isAtomicOrderingMonotonic()) { + InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>( + "Monotonic"); + continue; + } + if (Predicate.isAtomicOrderingAcquire()) { + InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("Acquire"); + continue; + } + if (Predicate.isAtomicOrderingRelease()) { + InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("Release"); + continue; + } + if (Predicate.isAtomicOrderingAcquireRelease()) { + InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>( + "AcquireRelease"); + continue; + } + if (Predicate.isAtomicOrderingSequentiallyConsistent()) { + InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>( + "SequentiallyConsistent"); + continue; + } } return failedImport("Src pattern child has predicate (" + explainPredicates(Src) + ")"); } if (SrcGIEquivOrNull && SrcGIEquivOrNull->getValueAsBit("CheckMMOIsNonAtomic")) - InsnMatcher.addPredicate<NonAtomicMMOPredicateMatcher>(); + InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("NotAtomic"); if (Src->isLeaf()) { Init *SrcInit = Src->getLeafValue(); |