llvm.org GIT mirror llvm / 438d60f
[tablegen] Handle atomic predicates for memory type 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 memory type 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@318095 91177308-0d34-0410-b5e6-96231b3b80d8 Daniel Sanders 1 year, 11 months ago
3 changed file(s) with 83 addition(s) and 48 deletion(s). Raw diff Collapse all Expand all
658658 bit IsLoad = ?;
659659 // Is the desired pre-packaged predicate for a store?
660660 bit IsStore = ?;
661 // Is the desired pre-packaged predicate for an atomic?
662 bit IsAtomic = ?;
661663
662664 // cast(N)->getAddressingMode() == ISD::UNINDEXED;
663665 // cast(N)->getAddressingMode() == ISD::UNINDEXED;
11801182
11811183 multiclass binary_atomic_op {
11821184 def _8 : PatFrag<(ops node:$ptr, node:$val),
1183 (atomic_op node:$ptr, node:$val), [{
1184 return cast(N)->getMemoryVT() == MVT::i8;
1185 }]>;
1185 (atomic_op node:$ptr, node:$val)> {
1186 let IsAtomic = 1;
1187 let MemoryVT = i8;
1188 }
11861189 def _16 : PatFrag<(ops node:$ptr, node:$val),
1187 (atomic_op node:$ptr, node:$val), [{
1188 return cast(N)->getMemoryVT() == MVT::i16;
1189 }]>;
1190 (atomic_op node:$ptr, node:$val)> {
1191 let IsAtomic = 1;
1192 let MemoryVT = i16;
1193 }
11901194 def _32 : PatFrag<(ops node:$ptr, node:$val),
1191 (atomic_op node:$ptr, node:$val), [{
1192 return cast(N)->getMemoryVT() == MVT::i32;
1193 }]>;
1195 (atomic_op node:$ptr, node:$val)> {
1196 let IsAtomic = 1;
1197 let MemoryVT = i32;
1198 }
11941199 def _64 : PatFrag<(ops node:$ptr, node:$val),
1195 (atomic_op node:$ptr, node:$val), [{
1196 return cast(N)->getMemoryVT() == MVT::i64;
1197 }]>;
1200 (atomic_op node:$ptr, node:$val)> {
1201 let IsAtomic = 1;
1202 let MemoryVT = i64;
1203 }
11981204
11991205 defm NAME#_8 : binary_atomic_op_ord;
12001206 defm NAME#_16 : binary_atomic_op_ord;
12041210
12051211 multiclass ternary_atomic_op {
12061212 def _8 : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
1207 (atomic_op node:$ptr, node:$cmp, node:$val), [{
1208 return cast(N)->getMemoryVT() == MVT::i8;
1209 }]>;
1213 (atomic_op node:$ptr, node:$cmp, node:$val)> {
1214 let IsAtomic = 1;
1215 let MemoryVT = i8;
1216 }
12101217 def _16 : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
1211 (atomic_op node:$ptr, node:$cmp, node:$val), [{
1212 return cast(N)->getMemoryVT() == MVT::i16;
1213 }]>;
1218 (atomic_op node:$ptr, node:$cmp, node:$val)> {
1219 let IsAtomic = 1;
1220 let MemoryVT = i16;
1221 }
12141222 def _32 : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
1215 (atomic_op node:$ptr, node:$cmp, node:$val), [{
1216 return cast(N)->getMemoryVT() == MVT::i32;
1217 }]>;
1223 (atomic_op node:$ptr, node:$cmp, node:$val)> {
1224 let IsAtomic = 1;
1225 let MemoryVT = i32;
1226 }
12181227 def _64 : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
1219 (atomic_op node:$ptr, node:$cmp, node:$val), [{
1220 return cast(N)->getMemoryVT() == MVT::i64;
1221 }]>;
1228 (atomic_op node:$ptr, node:$cmp, node:$val)> {
1229 let IsAtomic = 1;
1230 let MemoryVT = i64;
1231 }
12221232
12231233 defm NAME#_8 : ternary_atomic_op_ord;
12241234 defm NAME#_16 : ternary_atomic_op_ord;
12421252
12431253 def atomic_load_8 :
12441254 PatFrag<(ops node:$ptr),
1245 (atomic_load node:$ptr), [{
1246 return cast(N)->getMemoryVT() == MVT::i8;
1247 }]>;
1255 (atomic_load node:$ptr)> {
1256 let IsAtomic = 1;
1257 let MemoryVT = i8;
1258 }
12481259 def atomic_load_16 :
12491260 PatFrag<(ops node:$ptr),
1250 (atomic_load node:$ptr), [{
1251 return cast(N)->getMemoryVT() == MVT::i16;
1252 }]>;
1261 (atomic_load node:$ptr)> {
1262 let IsAtomic = 1;
1263 let MemoryVT = i16;
1264 }
12531265 def atomic_load_32 :
12541266 PatFrag<(ops node:$ptr),
1255 (atomic_load node:$ptr), [{
1256 return cast(N)->getMemoryVT() == MVT::i32;
1257 }]>;
1267 (atomic_load node:$ptr)> {
1268 let IsAtomic = 1;
1269 let MemoryVT = i32;
1270 }
12581271 def atomic_load_64 :
12591272 PatFrag<(ops node:$ptr),
1260 (atomic_load node:$ptr), [{
1261 return cast(N)->getMemoryVT() == MVT::i64;
1262 }]>;
1273 (atomic_load node:$ptr)> {
1274 let IsAtomic = 1;
1275 let MemoryVT = i64;
1276 }
12631277
12641278 //===----------------------------------------------------------------------===//
12651279 // Selection DAG Pattern Support.
817817 }
818818
819819 bool TreePredicateFn::hasPredCode() const {
820 return isLoad() || isStore() ||
820 return isLoad() || isStore() || isAtomic() ||
821821 !PatFragRec->getRecord()->getValueAsString("PredicateCode").empty();
822822 }
823823
824824 std::string TreePredicateFn::getPredCode() const {
825825 std::string Code = "";
826
827 if (!isLoad() && !isStore() && !isAtomic()) {
828 Record *MemoryVT = getMemoryVT();
829
830 if (MemoryVT)
831 PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
832 "MemoryVT requires IsLoad or IsStore");
833 }
826834
827835 if (!isLoad() && !isStore()) {
828836 if (isUnindexed())
829837 PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
830838 "IsUnindexed requires IsLoad or IsStore");
831839
832 Record *MemoryVT = getMemoryVT();
833840 Record *ScalarMemoryVT = getScalarMemoryVT();
834841
835 if (MemoryVT)
836 PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
837 "MemoryVT requires IsLoad or IsStore");
838842 if (ScalarMemoryVT)
839843 PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
840844 "ScalarMemoryVT requires IsLoad or IsStore");
841845 }
842846
843 if (isLoad() && isStore())
847 if (isLoad() + isStore() + isAtomic() > 1)
844848 PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
845 "IsLoad and IsStore are mutually exclusive");
849 "IsLoad, IsStore, and IsAtomic are mutually exclusive");
846850
847851 if (isLoad()) {
848852 if (!isUnindexed() && !isNonExtLoad() && !isAnyExtLoad() &&
877881 if (isTruncStore())
878882 PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
879883 "IsTruncStore requires IsStore");
884 }
885
886 if (isAtomic()) {
887 if (getMemoryVT() == nullptr)
888 PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
889 "IsAtomic cannot be used by itself");
890 }
891 if (isLoad() || isStore() || isAtomic()) {
892 StringRef SDNodeName =
893 isLoad() ? "LoadSDNode" : isStore() ? "StoreSDNode" : "AtomicSDNode";
894
895 Record *MemoryVT = getMemoryVT();
896
897 if (MemoryVT)
898 Code += ("if (cast<" + SDNodeName + ">(N)->getMemoryVT() != MVT::" +
899 MemoryVT->getName() + ") return false;\n")
900 .str();
880901 }
881902
882903 if (isLoad() || isStore()) {
919940 " if (!cast(N)->isTruncatingStore()) return false;\n";
920941 }
921942
922 Record *MemoryVT = getMemoryVT();
923943 Record *ScalarMemoryVT = getScalarMemoryVT();
924944
925 if (MemoryVT)
926 Code += ("if (cast<" + SDNodeName + ">(N)->getMemoryVT() != MVT::" +
927 MemoryVT->getName() + ") return false;\n")
928 .str();
929945 if (ScalarMemoryVT)
930946 Code += ("if (cast<" + SDNodeName +
931947 ">(N)->getMemoryVT().getScalarType() != MVT::" +
976992 }
977993 bool TreePredicateFn::isStore() const {
978994 return isPredefinedPredicateEqualTo("IsStore", true);
995 }
996 bool TreePredicateFn::isAtomic() const {
997 return isPredefinedPredicateEqualTo("IsAtomic", true);
979998 }
980999 bool TreePredicateFn::isUnindexed() const {
9811000 return isPredefinedPredicateEqualTo("IsUnindexed", true);
485485 bool isLoad() const;
486486 // Is the desired predefined predicate for a store?
487487 bool isStore() const;
488 // Is the desired predefined predicate for an atomic?
489 bool isAtomic() const;
488490
489491 /// Is this predicate the predefined unindexed load predicate?
490492 /// Is this predicate the predefined unindexed store predicate?