// cast<StoreSDNode>(N)->isTruncatingStore();
bit IsTruncStore = ?;
+ // cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::Monotonic
+ bit IsAtomicOrderingMonotonic = ?;
+ // cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::Acquire
+ bit IsAtomicOrderingAcquire = ?;
+ // cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::Release
+ bit IsAtomicOrderingRelease = ?;
+ // cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::AcquireRelease
+ bit IsAtomicOrderingAcquireRelease = ?;
+ // cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::SequentiallyConsistent
+ bit IsAtomicOrderingSequentiallyConsistent = ?;
+
// cast<LoadSDNode>(N)->getMemoryVT() == MVT::<VT>;
// cast<StoreSDNode>(N)->getMemoryVT() == MVT::<VT>;
ValueType MemoryVT = ?;
multiclass binary_atomic_op_ord<SDNode atomic_op> {
def #NAME#_monotonic : PatFrag<(ops node:$ptr, node:$val),
- (!cast<SDNode>(#NAME) node:$ptr, node:$val), [{
- return cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::Monotonic;
- }]>;
+ (!cast<SDNode>(#NAME) node:$ptr, node:$val)> {
+ let IsAtomic = 1;
+ let IsAtomicOrderingMonotonic = 1;
+ }
def #NAME#_acquire : PatFrag<(ops node:$ptr, node:$val),
- (!cast<SDNode>(#NAME) node:$ptr, node:$val), [{
- return cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::Acquire;
- }]>;
+ (!cast<SDNode>(#NAME) node:$ptr, node:$val)> {
+ let IsAtomic = 1;
+ let IsAtomicOrderingAcquire = 1;
+ }
def #NAME#_release : PatFrag<(ops node:$ptr, node:$val),
- (!cast<SDNode>(#NAME) node:$ptr, node:$val), [{
- return cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::Release;
- }]>;
+ (!cast<SDNode>(#NAME) node:$ptr, node:$val)> {
+ let IsAtomic = 1;
+ let IsAtomicOrderingRelease = 1;
+ }
def #NAME#_acq_rel : PatFrag<(ops node:$ptr, node:$val),
- (!cast<SDNode>(#NAME) node:$ptr, node:$val), [{
- return cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::AcquireRelease;
- }]>;
+ (!cast<SDNode>(#NAME) node:$ptr, node:$val)> {
+ let IsAtomic = 1;
+ let IsAtomicOrderingAcquireRelease = 1;
+ }
def #NAME#_seq_cst : PatFrag<(ops node:$ptr, node:$val),
- (!cast<SDNode>(#NAME) node:$ptr, node:$val), [{
- return cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::SequentiallyConsistent;
- }]>;
+ (!cast<SDNode>(#NAME) node:$ptr, node:$val)> {
+ let IsAtomic = 1;
+ let IsAtomicOrderingSequentiallyConsistent = 1;
+ }
}
multiclass ternary_atomic_op_ord<SDNode atomic_op> {
def #NAME#_monotonic : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
- (!cast<SDNode>(#NAME) node:$ptr, node:$cmp, node:$val), [{
- return cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::Monotonic;
- }]>;
+ (!cast<SDNode>(#NAME) node:$ptr, node:$cmp, node:$val)> {
+ let IsAtomic = 1;
+ let IsAtomicOrderingMonotonic = 1;
+ }
def #NAME#_acquire : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
- (!cast<SDNode>(#NAME) node:$ptr, node:$cmp, node:$val), [{
- return cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::Acquire;
- }]>;
+ (!cast<SDNode>(#NAME) node:$ptr, node:$cmp, node:$val)> {
+ let IsAtomic = 1;
+ let IsAtomicOrderingAcquire = 1;
+ }
def #NAME#_release : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
- (!cast<SDNode>(#NAME) node:$ptr, node:$cmp, node:$val), [{
- return cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::Release;
- }]>;
+ (!cast<SDNode>(#NAME) node:$ptr, node:$cmp, node:$val)> {
+ let IsAtomic = 1;
+ let IsAtomicOrderingRelease = 1;
+ }
def #NAME#_acq_rel : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
- (!cast<SDNode>(#NAME) node:$ptr, node:$cmp, node:$val), [{
- return cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::AcquireRelease;
- }]>;
+ (!cast<SDNode>(#NAME) node:$ptr, node:$cmp, node:$val)> {
+ let IsAtomic = 1;
+ let IsAtomicOrderingAcquireRelease = 1;
+ }
def #NAME#_seq_cst : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
- (!cast<SDNode>(#NAME) node:$ptr, node:$cmp, node:$val), [{
- return cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::SequentiallyConsistent;
- }]>;
+ (!cast<SDNode>(#NAME) node:$ptr, node:$cmp, node:$val)> {
+ let IsAtomic = 1;
+ let IsAtomicOrderingSequentiallyConsistent = 1;
+ }
}
multiclass binary_atomic_op<SDNode atomic_op> {
}
if (isAtomic()) {
- if (getMemoryVT() == nullptr)
+ if (getMemoryVT() == nullptr && !isAtomicOrderingMonotonic() &&
+ !isAtomicOrderingAcquire() && !isAtomicOrderingRelease() &&
+ !isAtomicOrderingAcquireRelease() &&
+ !isAtomicOrderingSequentiallyConsistent())
PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
"IsAtomic cannot be used by itself");
+ } else {
+ if (isAtomicOrderingMonotonic())
+ PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
+ "IsAtomicOrderingMonotonic requires IsAtomic");
+ if (isAtomicOrderingAcquire())
+ PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
+ "IsAtomicOrderingAcquire requires IsAtomic");
+ if (isAtomicOrderingRelease())
+ PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
+ "IsAtomicOrderingRelease requires IsAtomic");
+ if (isAtomicOrderingAcquireRelease())
+ PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
+ "IsAtomicOrderingAcquireRelease requires IsAtomic");
+ if (isAtomicOrderingSequentiallyConsistent())
+ PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
+ "IsAtomicOrderingSequentiallyConsistent requires IsAtomic");
}
+
if (isLoad() || isStore() || isAtomic()) {
StringRef SDNodeName =
isLoad() ? "LoadSDNode" : isStore() ? "StoreSDNode" : "AtomicSDNode";
.str();
}
+ if (isAtomic() && isAtomicOrderingMonotonic())
+ Code += "if (cast<AtomicSDNode>(N)->getOrdering() != "
+ "AtomicOrdering::Monotonic) return false;\n";
+ if (isAtomic() && isAtomicOrderingAcquire())
+ Code += "if (cast<AtomicSDNode>(N)->getOrdering() != "
+ "AtomicOrdering::Acquire) return false;\n";
+ if (isAtomic() && isAtomicOrderingRelease())
+ Code += "if (cast<AtomicSDNode>(N)->getOrdering() != "
+ "AtomicOrdering::Release) return false;\n";
+ if (isAtomic() && isAtomicOrderingAcquireRelease())
+ Code += "if (cast<AtomicSDNode>(N)->getOrdering() != "
+ "AtomicOrdering::AcquireRelease) return false;\n";
+ if (isAtomic() && isAtomicOrderingSequentiallyConsistent())
+ Code += "if (cast<AtomicSDNode>(N)->getOrdering() != "
+ "AtomicOrdering::SequentiallyConsistent) return false;\n";
+
if (isLoad() || isStore()) {
StringRef SDNodeName = isLoad() ? "LoadSDNode" : "StoreSDNode";
bool TreePredicateFn::isTruncStore() const {
return isPredefinedPredicateEqualTo("IsTruncStore", true);
}
+bool TreePredicateFn::isAtomicOrderingMonotonic() const {
+ return isPredefinedPredicateEqualTo("IsAtomicOrderingMonotonic", true);
+}
+bool TreePredicateFn::isAtomicOrderingAcquire() const {
+ return isPredefinedPredicateEqualTo("IsAtomicOrderingAcquire", true);
+}
+bool TreePredicateFn::isAtomicOrderingRelease() const {
+ return isPredefinedPredicateEqualTo("IsAtomicOrderingRelease", true);
+}
+bool TreePredicateFn::isAtomicOrderingAcquireRelease() const {
+ return isPredefinedPredicateEqualTo("IsAtomicOrderingAcquireRelease", true);
+}
+bool TreePredicateFn::isAtomicOrderingSequentiallyConsistent() const {
+ return isPredefinedPredicateEqualTo("IsAtomicOrderingSequentiallyConsistent",
+ true);
+}
Record *TreePredicateFn::getMemoryVT() const {
Record *R = getOrigPatFragRecord()->getRecord();
if (R->isValueUnset("MemoryVT"))