summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorDaniel Sanders <daniel_l_sanders@apple.com>2017-11-30 21:05:59 +0000
committerDaniel Sanders <daniel_l_sanders@apple.com>2017-11-30 21:05:59 +0000
commit053346db8cecee4da27aba2d9ed54b2ef351e960 (patch)
treec119cf4824338839c60ef736fee855f51c3081f0 /utils
parentca2b4f3e054d795465478ef06ada892f58863783 (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.cpp41
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.h10
-rw-r--r--utils/TableGen/GlobalISelEmitter.cpp63
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 (" +