summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Target/TargetSelectionDAG.td86
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.cpp43
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.h2
3 files changed, 83 insertions, 48 deletions
diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td
index 511b7655e50..386cb4e6d63 100644
--- a/include/llvm/Target/TargetSelectionDAG.td
+++ b/include/llvm/Target/TargetSelectionDAG.td
@@ -659,6 +659,8 @@ class PatFrag<dag ops, dag frag, code pred = [{}],
bit IsLoad = ?;
// Is the desired pre-packaged predicate for a store?
bit IsStore = ?;
+ // Is the desired pre-packaged predicate for an atomic?
+ bit IsAtomic = ?;
// cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
// cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
@@ -1181,21 +1183,25 @@ multiclass ternary_atomic_op_ord<SDNode atomic_op> {
multiclass binary_atomic_op<SDNode atomic_op> {
def _8 : PatFrag<(ops node:$ptr, node:$val),
- (atomic_op node:$ptr, node:$val), [{
- return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i8;
- }]>;
+ (atomic_op node:$ptr, node:$val)> {
+ let IsAtomic = 1;
+ let MemoryVT = i8;
+ }
def _16 : PatFrag<(ops node:$ptr, node:$val),
- (atomic_op node:$ptr, node:$val), [{
- return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i16;
- }]>;
+ (atomic_op node:$ptr, node:$val)> {
+ let IsAtomic = 1;
+ let MemoryVT = i16;
+ }
def _32 : PatFrag<(ops node:$ptr, node:$val),
- (atomic_op node:$ptr, node:$val), [{
- return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i32;
- }]>;
+ (atomic_op node:$ptr, node:$val)> {
+ let IsAtomic = 1;
+ let MemoryVT = i32;
+ }
def _64 : PatFrag<(ops node:$ptr, node:$val),
- (atomic_op node:$ptr, node:$val), [{
- return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i64;
- }]>;
+ (atomic_op node:$ptr, node:$val)> {
+ let IsAtomic = 1;
+ let MemoryVT = i64;
+ }
defm NAME#_8 : binary_atomic_op_ord<atomic_op>;
defm NAME#_16 : binary_atomic_op_ord<atomic_op>;
@@ -1205,21 +1211,25 @@ multiclass binary_atomic_op<SDNode atomic_op> {
multiclass ternary_atomic_op<SDNode atomic_op> {
def _8 : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
- (atomic_op node:$ptr, node:$cmp, node:$val), [{
- return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i8;
- }]>;
+ (atomic_op node:$ptr, node:$cmp, node:$val)> {
+ let IsAtomic = 1;
+ let MemoryVT = i8;
+ }
def _16 : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
- (atomic_op node:$ptr, node:$cmp, node:$val), [{
- return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i16;
- }]>;
+ (atomic_op node:$ptr, node:$cmp, node:$val)> {
+ let IsAtomic = 1;
+ let MemoryVT = i16;
+ }
def _32 : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
- (atomic_op node:$ptr, node:$cmp, node:$val), [{
- return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i32;
- }]>;
+ (atomic_op node:$ptr, node:$cmp, node:$val)> {
+ let IsAtomic = 1;
+ let MemoryVT = i32;
+ }
def _64 : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
- (atomic_op node:$ptr, node:$cmp, node:$val), [{
- return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i64;
- }]>;
+ (atomic_op node:$ptr, node:$cmp, node:$val)> {
+ let IsAtomic = 1;
+ let MemoryVT = i64;
+ }
defm NAME#_8 : ternary_atomic_op_ord<atomic_op>;
defm NAME#_16 : ternary_atomic_op_ord<atomic_op>;
@@ -1243,24 +1253,28 @@ defm atomic_cmp_swap : ternary_atomic_op<atomic_cmp_swap>;
def atomic_load_8 :
PatFrag<(ops node:$ptr),
- (atomic_load node:$ptr), [{
- return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i8;
-}]>;
+ (atomic_load node:$ptr)> {
+ let IsAtomic = 1;
+ let MemoryVT = i8;
+}
def atomic_load_16 :
PatFrag<(ops node:$ptr),
- (atomic_load node:$ptr), [{
- return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i16;
-}]>;
+ (atomic_load node:$ptr)> {
+ let IsAtomic = 1;
+ let MemoryVT = i16;
+}
def atomic_load_32 :
PatFrag<(ops node:$ptr),
- (atomic_load node:$ptr), [{
- return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i32;
-}]>;
+ (atomic_load node:$ptr)> {
+ let IsAtomic = 1;
+ let MemoryVT = i32;
+}
def atomic_load_64 :
PatFrag<(ops node:$ptr),
- (atomic_load node:$ptr), [{
- return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i64;
-}]>;
+ (atomic_load node:$ptr)> {
+ let IsAtomic = 1;
+ let MemoryVT = i64;
+}
//===----------------------------------------------------------------------===//
// Selection DAG Pattern Support.
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index c07a7267bbe..b8ba5db6ef4 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -818,32 +818,36 @@ TreePredicateFn::TreePredicateFn(TreePattern *N) : PatFragRec(N) {
}
bool TreePredicateFn::hasPredCode() const {
- return isLoad() || isStore() ||
+ return isLoad() || isStore() || isAtomic() ||
!PatFragRec->getRecord()->getValueAsString("PredicateCode").empty();
}
std::string TreePredicateFn::getPredCode() const {
std::string Code = "";
+ if (!isLoad() && !isStore() && !isAtomic()) {
+ Record *MemoryVT = getMemoryVT();
+
+ if (MemoryVT)
+ PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
+ "MemoryVT requires IsLoad or IsStore");
+ }
+
if (!isLoad() && !isStore()) {
if (isUnindexed())
PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
"IsUnindexed requires IsLoad or IsStore");
- Record *MemoryVT = getMemoryVT();
Record *ScalarMemoryVT = getScalarMemoryVT();
- if (MemoryVT)
- PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
- "MemoryVT requires IsLoad or IsStore");
if (ScalarMemoryVT)
PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
"ScalarMemoryVT requires IsLoad or IsStore");
}
- if (isLoad() && isStore())
+ if (isLoad() + isStore() + isAtomic() > 1)
PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
- "IsLoad and IsStore are mutually exclusive");
+ "IsLoad, IsStore, and IsAtomic are mutually exclusive");
if (isLoad()) {
if (!isUnindexed() && !isNonExtLoad() && !isAnyExtLoad() &&
@@ -880,6 +884,23 @@ std::string TreePredicateFn::getPredCode() const {
"IsTruncStore requires IsStore");
}
+ if (isAtomic()) {
+ if (getMemoryVT() == nullptr)
+ PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
+ "IsAtomic cannot be used by itself");
+ }
+ if (isLoad() || isStore() || isAtomic()) {
+ StringRef SDNodeName =
+ isLoad() ? "LoadSDNode" : isStore() ? "StoreSDNode" : "AtomicSDNode";
+
+ Record *MemoryVT = getMemoryVT();
+
+ if (MemoryVT)
+ Code += ("if (cast<" + SDNodeName + ">(N)->getMemoryVT() != MVT::" +
+ MemoryVT->getName() + ") return false;\n")
+ .str();
+ }
+
if (isLoad() || isStore()) {
StringRef SDNodeName = isLoad() ? "LoadSDNode" : "StoreSDNode";
@@ -920,13 +941,8 @@ std::string TreePredicateFn::getPredCode() const {
" if (!cast<StoreSDNode>(N)->isTruncatingStore()) return false;\n";
}
- Record *MemoryVT = getMemoryVT();
Record *ScalarMemoryVT = getScalarMemoryVT();
- if (MemoryVT)
- Code += ("if (cast<" + SDNodeName + ">(N)->getMemoryVT() != MVT::" +
- MemoryVT->getName() + ") return false;\n")
- .str();
if (ScalarMemoryVT)
Code += ("if (cast<" + SDNodeName +
">(N)->getMemoryVT().getScalarType() != MVT::" +
@@ -978,6 +994,9 @@ bool TreePredicateFn::isLoad() const {
bool TreePredicateFn::isStore() const {
return isPredefinedPredicateEqualTo("IsStore", true);
}
+bool TreePredicateFn::isAtomic() const {
+ return isPredefinedPredicateEqualTo("IsAtomic", true);
+}
bool TreePredicateFn::isUnindexed() const {
return isPredefinedPredicateEqualTo("IsUnindexed", true);
}
diff --git a/utils/TableGen/CodeGenDAGPatterns.h b/utils/TableGen/CodeGenDAGPatterns.h
index d3bb99a5a8f..3a76ab25ea7 100644
--- a/utils/TableGen/CodeGenDAGPatterns.h
+++ b/utils/TableGen/CodeGenDAGPatterns.h
@@ -486,6 +486,8 @@ public:
bool isLoad() const;
// Is the desired predefined predicate for a store?
bool isStore() const;
+ // Is the desired predefined predicate for an atomic?
+ bool isAtomic() const;
/// Is this predicate the predefined unindexed load predicate?
/// Is this predicate the predefined unindexed store predicate?