diff options
-rw-r--r-- | include/llvm/Target/TargetSelectionDAG.td | 86 | ||||
-rw-r--r-- | utils/TableGen/CodeGenDAGPatterns.cpp | 43 | ||||
-rw-r--r-- | utils/TableGen/CodeGenDAGPatterns.h | 2 |
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? |