llvm.org GIT mirror llvm / 22434af
[tablegen] Handle atomic predicates for ordering inside tablegen. NFC. Similar to r315841, GlobalISel and SelectionDAG require different code for the common atomic predicates due to differences in the representation. Even without that, differences in the IR (SDNode vs MachineInstr) require differences in the C++ predicate. This patch moves the implementation of the common atomic predicates related to ordering into tablegen so that it can handle these differences. It's NFC for SelectionDAG since it emits equivalent code and it's NFC for GlobalISel since the rules involving the relevant predicates are still rejected by the importer. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@318102 91177308-0d34-0410-b5e6-96231b3b80d8 Daniel Sanders 1 year, 11 months ago
3 changed file(s) with 116 addition(s) and 32 deletion(s). Raw diff Collapse all Expand all
677677 // cast(N)->isTruncatingStore();
678678 bit IsTruncStore = ?;
679679
680 // cast(N)->getOrdering() == AtomicOrdering::Monotonic
681 bit IsAtomicOrderingMonotonic = ?;
682 // cast(N)->getOrdering() == AtomicOrdering::Acquire
683 bit IsAtomicOrderingAcquire = ?;
684 // cast(N)->getOrdering() == AtomicOrdering::Release
685 bit IsAtomicOrderingRelease = ?;
686 // cast(N)->getOrdering() == AtomicOrdering::AcquireRelease
687 bit IsAtomicOrderingAcquireRelease = ?;
688 // cast(N)->getOrdering() == AtomicOrdering::SequentiallyConsistent
689 bit IsAtomicOrderingSequentiallyConsistent = ?;
690
680691 // cast(N)->getMemoryVT() == MVT::;
681692 // cast(N)->getMemoryVT() == MVT::;
682693 ValueType MemoryVT = ?;
11361147
11371148 multiclass binary_atomic_op_ord {
11381149 def #NAME#_monotonic : PatFrag<(ops node:$ptr, node:$val),
1139 (!cast(#NAME) node:$ptr, node:$val), [{
1140 return cast(N)->getOrdering() == AtomicOrdering::Monotonic;
1141 }]>;
1150 (!cast(#NAME) node:$ptr, node:$val)> {
1151 let IsAtomic = 1;
1152 let IsAtomicOrderingMonotonic = 1;
1153 }
11421154 def #NAME#_acquire : PatFrag<(ops node:$ptr, node:$val),
1143 (!cast(#NAME) node:$ptr, node:$val), [{
1144 return cast(N)->getOrdering() == AtomicOrdering::Acquire;
1145 }]>;
1155 (!cast(#NAME) node:$ptr, node:$val)> {
1156 let IsAtomic = 1;
1157 let IsAtomicOrderingAcquire = 1;
1158 }
11461159 def #NAME#_release : PatFrag<(ops node:$ptr, node:$val),
1147 (!cast(#NAME) node:$ptr, node:$val), [{
1148 return cast(N)->getOrdering() == AtomicOrdering::Release;
1149 }]>;
1160 (!cast(#NAME) node:$ptr, node:$val)> {
1161 let IsAtomic = 1;
1162 let IsAtomicOrderingRelease = 1;
1163 }
11501164 def #NAME#_acq_rel : PatFrag<(ops node:$ptr, node:$val),
1151 (!cast(#NAME) node:$ptr, node:$val), [{
1152 return cast(N)->getOrdering() == AtomicOrdering::AcquireRelease;
1153 }]>;
1165 (!cast(#NAME) node:$ptr, node:$val)> {
1166 let IsAtomic = 1;
1167 let IsAtomicOrderingAcquireRelease = 1;
1168 }
11541169 def #NAME#_seq_cst : PatFrag<(ops node:$ptr, node:$val),
1155 (!cast(#NAME) node:$ptr, node:$val), [{
1156 return cast(N)->getOrdering() == AtomicOrdering::SequentiallyConsistent;
1157 }]>;
1170 (!cast(#NAME) node:$ptr, node:$val)> {
1171 let IsAtomic = 1;
1172 let IsAtomicOrderingSequentiallyConsistent = 1;
1173 }
11581174 }
11591175
11601176 multiclass ternary_atomic_op_ord {
11611177 def #NAME#_monotonic : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
1162 (!cast(#NAME) node:$ptr, node:$cmp, node:$val), [{
1163 return cast(N)->getOrdering() == AtomicOrdering::Monotonic;
1164 }]>;
1178 (!cast(#NAME) node:$ptr, node:$cmp, node:$val)> {
1179 let IsAtomic = 1;
1180 let IsAtomicOrderingMonotonic = 1;
1181 }
11651182 def #NAME#_acquire : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
1166 (!cast(#NAME) node:$ptr, node:$cmp, node:$val), [{
1167 return cast(N)->getOrdering() == AtomicOrdering::Acquire;
1168 }]>;
1183 (!cast(#NAME) node:$ptr, node:$cmp, node:$val)> {
1184 let IsAtomic = 1;
1185 let IsAtomicOrderingAcquire = 1;
1186 }
11691187 def #NAME#_release : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
1170 (!cast(#NAME) node:$ptr, node:$cmp, node:$val), [{
1171 return cast(N)->getOrdering() == AtomicOrdering::Release;
1172 }]>;
1188 (!cast(#NAME) node:$ptr, node:$cmp, node:$val)> {
1189 let IsAtomic = 1;
1190 let IsAtomicOrderingRelease = 1;
1191 }
11731192 def #NAME#_acq_rel : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
1174 (!cast(#NAME) node:$ptr, node:$cmp, node:$val), [{
1175 return cast(N)->getOrdering() == AtomicOrdering::AcquireRelease;
1176 }]>;
1193 (!cast(#NAME) node:$ptr, node:$cmp, node:$val)> {
1194 let IsAtomic = 1;
1195 let IsAtomicOrderingAcquireRelease = 1;
1196 }
11771197 def #NAME#_seq_cst : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
1178 (!cast(#NAME) node:$ptr, node:$cmp, node:$val), [{
1179 return cast(N)->getOrdering() == AtomicOrdering::SequentiallyConsistent;
1180 }]>;
1198 (!cast(#NAME) node:$ptr, node:$cmp, node:$val)> {
1199 let IsAtomic = 1;
1200 let IsAtomicOrderingSequentiallyConsistent = 1;
1201 }
11811202 }
11821203
11831204 multiclass binary_atomic_op {
884884 }
885885
886886 if (isAtomic()) {
887 if (getMemoryVT() == nullptr)
887 if (getMemoryVT() == nullptr && !isAtomicOrderingMonotonic() &&
888 !isAtomicOrderingAcquire() && !isAtomicOrderingRelease() &&
889 !isAtomicOrderingAcquireRelease() &&
890 !isAtomicOrderingSequentiallyConsistent())
888891 PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
889892 "IsAtomic cannot be used by itself");
890 }
893 } else {
894 if (isAtomicOrderingMonotonic())
895 PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
896 "IsAtomicOrderingMonotonic requires IsAtomic");
897 if (isAtomicOrderingAcquire())
898 PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
899 "IsAtomicOrderingAcquire requires IsAtomic");
900 if (isAtomicOrderingRelease())
901 PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
902 "IsAtomicOrderingRelease requires IsAtomic");
903 if (isAtomicOrderingAcquireRelease())
904 PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
905 "IsAtomicOrderingAcquireRelease requires IsAtomic");
906 if (isAtomicOrderingSequentiallyConsistent())
907 PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
908 "IsAtomicOrderingSequentiallyConsistent requires IsAtomic");
909 }
910
891911 if (isLoad() || isStore() || isAtomic()) {
892912 StringRef SDNodeName =
893913 isLoad() ? "LoadSDNode" : isStore() ? "StoreSDNode" : "AtomicSDNode";
899919 MemoryVT->getName() + ") return false;\n")
900920 .str();
901921 }
922
923 if (isAtomic() && isAtomicOrderingMonotonic())
924 Code += "if (cast(N)->getOrdering() != "
925 "AtomicOrdering::Monotonic) return false;\n";
926 if (isAtomic() && isAtomicOrderingAcquire())
927 Code += "if (cast(N)->getOrdering() != "
928 "AtomicOrdering::Acquire) return false;\n";
929 if (isAtomic() && isAtomicOrderingRelease())
930 Code += "if (cast(N)->getOrdering() != "
931 "AtomicOrdering::Release) return false;\n";
932 if (isAtomic() && isAtomicOrderingAcquireRelease())
933 Code += "if (cast(N)->getOrdering() != "
934 "AtomicOrdering::AcquireRelease) return false;\n";
935 if (isAtomic() && isAtomicOrderingSequentiallyConsistent())
936 Code += "if (cast(N)->getOrdering() != "
937 "AtomicOrdering::SequentiallyConsistent) return false;\n";
902938
903939 if (isLoad() || isStore()) {
904940 StringRef SDNodeName = isLoad() ? "LoadSDNode" : "StoreSDNode";
10161052 }
10171053 bool TreePredicateFn::isTruncStore() const {
10181054 return isPredefinedPredicateEqualTo("IsTruncStore", true);
1055 }
1056 bool TreePredicateFn::isAtomicOrderingMonotonic() const {
1057 return isPredefinedPredicateEqualTo("IsAtomicOrderingMonotonic", true);
1058 }
1059 bool TreePredicateFn::isAtomicOrderingAcquire() const {
1060 return isPredefinedPredicateEqualTo("IsAtomicOrderingAcquire", true);
1061 }
1062 bool TreePredicateFn::isAtomicOrderingRelease() const {
1063 return isPredefinedPredicateEqualTo("IsAtomicOrderingRelease", true);
1064 }
1065 bool TreePredicateFn::isAtomicOrderingAcquireRelease() const {
1066 return isPredefinedPredicateEqualTo("IsAtomicOrderingAcquireRelease", true);
1067 }
1068 bool TreePredicateFn::isAtomicOrderingSequentiallyConsistent() const {
1069 return isPredefinedPredicateEqualTo("IsAtomicOrderingSequentiallyConsistent",
1070 true);
10191071 }
10201072 Record *TreePredicateFn::getMemoryVT() const {
10211073 Record *R = getOrigPatFragRecord()->getRecord();
504504 /// Is this predicate the predefined truncating store predicate?
505505 bool isTruncStore() const;
506506
507 /// Is this predicate the predefined monotonic atomic predicate?
508 bool isAtomicOrderingMonotonic() const;
509 /// Is this predicate the predefined acquire atomic predicate?
510 bool isAtomicOrderingAcquire() const;
511 /// Is this predicate the predefined release atomic predicate?
512 bool isAtomicOrderingRelease() const;
513 /// Is this predicate the predefined acquire-release atomic predicate?
514 bool isAtomicOrderingAcquireRelease() const;
515 /// Is this predicate the predefined sequentially consistent atomic predicate?
516 bool isAtomicOrderingSequentiallyConsistent() const;
517
507518 /// If non-null, indicates that this predicate is a predefined memory VT
508519 /// predicate for a load/store and returns the ValueType record for the memory VT.
509520 Record *getMemoryVT() const;