summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorDaniel Sanders <daniel_l_sanders@apple.com>2017-11-28 22:07:05 +0000
committerDaniel Sanders <daniel_l_sanders@apple.com>2017-11-28 22:07:05 +0000
commit7f3e660b838376ca17c7902d12d5d5d305932616 (patch)
tree73f70204c5d4b9275f9491f1d8eec6f665e759b1 /utils
parentee2e970651e392df519e2173b98b916b90a64b04 (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.cpp120
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();