diff options
author | Daniel Sanders <daniel_l_sanders@apple.com> | 2017-11-30 21:05:59 +0000 |
---|---|---|
committer | Daniel Sanders <daniel_l_sanders@apple.com> | 2017-11-30 21:05:59 +0000 |
commit | 053346db8cecee4da27aba2d9ed54b2ef351e960 (patch) | |
tree | c119cf4824338839c60ef736fee855f51c3081f0 /utils | |
parent | ca2b4f3e054d795465478ef06ada892f58863783 (diff) |
[globalisel][tablegen] Add support for relative AtomicOrderings
No test yet because the relevant rules are blocked on the atomic_load,
and atomic_store nodes.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@319475 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r-- | utils/TableGen/CodeGenDAGPatterns.cpp | 41 | ||||
-rw-r--r-- | utils/TableGen/CodeGenDAGPatterns.h | 10 | ||||
-rw-r--r-- | utils/TableGen/GlobalISelEmitter.cpp | 63 |
3 files changed, 107 insertions, 7 deletions
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index 65b35623681..51473f06da7 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -888,7 +888,11 @@ std::string TreePredicateFn::getPredCode() const { if (getMemoryVT() == nullptr && !isAtomicOrderingMonotonic() && !isAtomicOrderingAcquire() && !isAtomicOrderingRelease() && !isAtomicOrderingAcquireRelease() && - !isAtomicOrderingSequentiallyConsistent()) + !isAtomicOrderingSequentiallyConsistent() && + !isAtomicOrderingAcquireOrStronger() && + !isAtomicOrderingReleaseOrStronger() && + !isAtomicOrderingWeakerThanAcquire() && + !isAtomicOrderingWeakerThanRelease()) PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(), "IsAtomic cannot be used by itself"); } else { @@ -907,6 +911,15 @@ std::string TreePredicateFn::getPredCode() const { if (isAtomicOrderingSequentiallyConsistent()) PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(), "IsAtomicOrderingSequentiallyConsistent requires IsAtomic"); + if (isAtomicOrderingAcquireOrStronger()) + PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(), + "IsAtomicOrderingAcquireOrStronger requires IsAtomic"); + if (isAtomicOrderingReleaseOrStronger()) + PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(), + "IsAtomicOrderingReleaseOrStronger requires IsAtomic"); + if (isAtomicOrderingWeakerThanAcquire()) + PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(), + "IsAtomicOrderingWeakerThanAcquire requires IsAtomic"); } if (isLoad() || isStore() || isAtomic()) { @@ -937,6 +950,20 @@ std::string TreePredicateFn::getPredCode() const { Code += "if (cast<AtomicSDNode>(N)->getOrdering() != " "AtomicOrdering::SequentiallyConsistent) return false;\n"; + if (isAtomic() && isAtomicOrderingAcquireOrStronger()) + Code += "if (!isAcquireOrStronger(cast<AtomicSDNode>(N)->getOrdering())) " + "return false;\n"; + if (isAtomic() && isAtomicOrderingWeakerThanAcquire()) + Code += "if (isAcquireOrStronger(cast<AtomicSDNode>(N)->getOrdering())) " + "return false;\n"; + + if (isAtomic() && isAtomicOrderingReleaseOrStronger()) + Code += "if (!isReleaseOrStronger(cast<AtomicSDNode>(N)->getOrdering())) " + "return false;\n"; + if (isAtomic() && isAtomicOrderingWeakerThanRelease()) + Code += "if (isReleaseOrStronger(cast<AtomicSDNode>(N)->getOrdering())) " + "return false;\n"; + if (isLoad() || isStore()) { StringRef SDNodeName = isLoad() ? "LoadSDNode" : "StoreSDNode"; @@ -1070,6 +1097,18 @@ bool TreePredicateFn::isAtomicOrderingSequentiallyConsistent() const { return isPredefinedPredicateEqualTo("IsAtomicOrderingSequentiallyConsistent", true); } +bool TreePredicateFn::isAtomicOrderingAcquireOrStronger() const { + return isPredefinedPredicateEqualTo("IsAtomicOrderingAcquireOrStronger", true); +} +bool TreePredicateFn::isAtomicOrderingWeakerThanAcquire() const { + return isPredefinedPredicateEqualTo("IsAtomicOrderingAcquireOrStronger", false); +} +bool TreePredicateFn::isAtomicOrderingReleaseOrStronger() const { + return isPredefinedPredicateEqualTo("IsAtomicOrderingReleaseOrStronger", true); +} +bool TreePredicateFn::isAtomicOrderingWeakerThanRelease() const { + return isPredefinedPredicateEqualTo("IsAtomicOrderingReleaseOrStronger", false); +} Record *TreePredicateFn::getMemoryVT() const { Record *R = getOrigPatFragRecord()->getRecord(); if (R->isValueUnset("MemoryVT")) diff --git a/utils/TableGen/CodeGenDAGPatterns.h b/utils/TableGen/CodeGenDAGPatterns.h index 8b72bd6d90b..afbcb10a4b6 100644 --- a/utils/TableGen/CodeGenDAGPatterns.h +++ b/utils/TableGen/CodeGenDAGPatterns.h @@ -516,6 +516,16 @@ public: /// Is this predicate the predefined sequentially consistent atomic predicate? bool isAtomicOrderingSequentiallyConsistent() const; + /// Is this predicate the predefined acquire-or-stronger atomic predicate? + bool isAtomicOrderingAcquireOrStronger() const; + /// Is this predicate the predefined weaker-than-acquire atomic predicate? + bool isAtomicOrderingWeakerThanAcquire() const; + + /// Is this predicate the predefined release-or-stronger atomic predicate? + bool isAtomicOrderingReleaseOrStronger() const; + /// Is this predicate the predefined weaker-than-release atomic predicate? + bool isAtomicOrderingWeakerThanRelease() const; + /// If non-null, indicates that this predicate is a predefined memory VT /// predicate for a load/store and returns the ValueType record for the memory VT. Record *getMemoryVT() const; diff --git a/utils/TableGen/GlobalISelEmitter.cpp b/utils/TableGen/GlobalISelEmitter.cpp index d9048c231c2..062fe59d820 100644 --- a/utils/TableGen/GlobalISelEmitter.cpp +++ b/utils/TableGen/GlobalISelEmitter.cpp @@ -230,6 +230,14 @@ static std::string explainPredicates(const TreePatternNode *N) { Explanation += " acq_rel"; if (P.isAtomicOrderingSequentiallyConsistent()) Explanation += " seq_cst"; + if (P.isAtomicOrderingAcquireOrStronger()) + Explanation += " >=acquire"; + if (P.isAtomicOrderingWeakerThanAcquire()) + Explanation += " <acquire"; + if (P.isAtomicOrderingReleaseOrStronger()) + Explanation += " >=release"; + if (P.isAtomicOrderingWeakerThanRelease()) + Explanation += " <release"; } return Explanation; } @@ -285,7 +293,11 @@ static Error isTrivialOperatorNode(const TreePatternNode *N) { Predicate.isAtomicOrderingAcquire() || Predicate.isAtomicOrderingRelease() || Predicate.isAtomicOrderingAcquireRelease() || - Predicate.isAtomicOrderingSequentiallyConsistent())) + Predicate.isAtomicOrderingSequentiallyConsistent() || + Predicate.isAtomicOrderingAcquireOrStronger() || + Predicate.isAtomicOrderingWeakerThanAcquire() || + Predicate.isAtomicOrderingReleaseOrStronger() || + Predicate.isAtomicOrderingWeakerThanRelease())) continue; HasUnsupportedPredicate = true; @@ -1327,11 +1339,22 @@ public: /// Generates code to check that a memory instruction has a atomic ordering /// MachineMemoryOperand. class AtomicOrderingMMOPredicateMatcher : public InstructionPredicateMatcher { +public: + enum AOComparator { + AO_Exactly, + AO_OrStronger, + AO_WeakerThan, + }; + +protected: StringRef Order; + AOComparator Comparator; public: - AtomicOrderingMMOPredicateMatcher(StringRef Order) - : InstructionPredicateMatcher(IPM_AtomicOrderingMMO), Order(Order) {} + AtomicOrderingMMOPredicateMatcher(StringRef Order, + AOComparator Comparator = AO_Exactly) + : InstructionPredicateMatcher(IPM_AtomicOrderingMMO), Order(Order), + Comparator(Comparator) {} static bool classof(const InstructionPredicateMatcher *P) { return P->getKind() == IPM_AtomicOrderingMMO; @@ -1339,9 +1362,15 @@ public: void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule, unsigned InsnVarID) const override { - Table << MatchTable::Opcode("GIM_CheckAtomicOrdering") - << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID) - << MatchTable::Comment("Order") + StringRef Opcode = "GIM_CheckAtomicOrdering"; + + if (Comparator == AO_OrStronger) + Opcode = "GIM_CheckAtomicOrderingOrStrongerThan"; + if (Comparator == AO_WeakerThan) + Opcode = "GIM_CheckAtomicOrderingWeakerThan"; + + Table << MatchTable::Opcode(Opcode) << MatchTable::Comment("MI") + << MatchTable::IntValue(InsnVarID) << MatchTable::Comment("Order") << MatchTable::NamedValue(("(int64_t)AtomicOrdering::" + Order).str()) << MatchTable::LineBreak; } @@ -2554,6 +2583,28 @@ Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher( "SequentiallyConsistent"); continue; } + + if (Predicate.isAtomicOrderingAcquireOrStronger()) { + InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>( + "Acquire", AtomicOrderingMMOPredicateMatcher::AO_OrStronger); + continue; + } + if (Predicate.isAtomicOrderingWeakerThanAcquire()) { + InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>( + "Acquire", AtomicOrderingMMOPredicateMatcher::AO_WeakerThan); + continue; + } + + if (Predicate.isAtomicOrderingReleaseOrStronger()) { + InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>( + "Release", AtomicOrderingMMOPredicateMatcher::AO_OrStronger); + continue; + } + if (Predicate.isAtomicOrderingWeakerThanRelease()) { + InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>( + "Release", AtomicOrderingMMOPredicateMatcher::AO_WeakerThan); + continue; + } } return failedImport("Src pattern child has predicate (" + |