code PredicateCode = pred;
code ImmediateCode = [{}];
SDNodeXForm OperandTransform = xform;
+
+ // Define a few pre-packaged predicates. This helps GlobalISel import
+ // existing rules from SelectionDAG for many common cases.
+ // They will be tested prior to the code in pred and must not be used in
+ // ImmLeaf and its subclasses.
+
+ // Is the desired pre-packaged predicate for a load?
+ bit IsLoad = ?;
+ // Is the desired pre-packaged predicate for a store?
+ bit IsStore = ?;
+
+ // cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
+ // cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
+ bit IsUnindexed = ?;
+
+ // cast<LoadSDNode>(N)->getExtensionType() != ISD::NON_EXTLOAD
+ bit IsNonExtLoad = ?;
+ // cast<LoadSDNode>(N)->getExtensionType() == ISD::EXTLOAD;
+ bit IsAnyExtLoad = ?;
+ // cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD;
+ bit IsSignExtLoad = ?;
+ // cast<LoadSDNode>(N)->getExtensionType() == ISD::ZEXTLOAD;
+ bit IsZeroExtLoad = ?;
+ // !cast<StoreSDNode>(N)->isTruncatingStore();
+ // cast<StoreSDNode>(N)->isTruncatingStore();
+ bit IsTruncStore = ?;
+
+ // cast<LoadSDNode>(N)->getMemoryVT() == MVT::<VT>;
+ // cast<StoreSDNode>(N)->getMemoryVT() == MVT::<VT>;
+ ValueType MemoryVT = ?;
+ // cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::<VT>;
+ // cast<StoreSDNode>(N)->getMemoryVT().getScalarType() == MVT::<VT>;
+ ValueType ScalarMemoryVT = ?;
}
// OutPatFrag is a pattern fragment that is used as part of an output pattern
def null_frag : SDPatternOperator;
// load fragments.
-def unindexedload : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
- return cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
-}]>;
-def load : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{
- return cast<LoadSDNode>(N)->getExtensionType() == ISD::NON_EXTLOAD;
-}]>;
+def unindexedload : PatFrag<(ops node:$ptr), (ld node:$ptr)> {
+ let IsLoad = 1;
+ let IsUnindexed = 1;
+}
+def load : PatFrag<(ops node:$ptr), (unindexedload node:$ptr)> {
+ let IsLoad = 1;
+ let IsNonExtLoad = 1;
+}
// extending load fragments.
-def extload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{
- return cast<LoadSDNode>(N)->getExtensionType() == ISD::EXTLOAD;
-}]>;
-def sextload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{
- return cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD;
-}]>;
-def zextload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{
- return cast<LoadSDNode>(N)->getExtensionType() == ISD::ZEXTLOAD;
-}]>;
+def extload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr)> {
+ let IsLoad = 1;
+ let IsAnyExtLoad = 1;
+}
+def sextload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr)> {
+ let IsLoad = 1;
+ let IsSignExtLoad = 1;
+}
+def zextload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr)> {
+ let IsLoad = 1;
+ let IsZeroExtLoad = 1;
+}
-def extloadi1 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
- return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i1;
-}]>;
-def extloadi8 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
- return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;
-}]>;
-def extloadi16 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
- return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;
-}]>;
-def extloadi32 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
- return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32;
-}]>;
-def extloadf32 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
- return cast<LoadSDNode>(N)->getMemoryVT() == MVT::f32;
-}]>;
-def extloadf64 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
- return cast<LoadSDNode>(N)->getMemoryVT() == MVT::f64;
-}]>;
+def extloadi1 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
+ let IsLoad = 1;
+ let MemoryVT = i1;
+}
+def extloadi8 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
+ let IsLoad = 1;
+ let MemoryVT = i8;
+}
+def extloadi16 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
+ let IsLoad = 1;
+ let MemoryVT = i16;
+}
+def extloadi32 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
+ let IsLoad = 1;
+ let MemoryVT = i32;
+}
+def extloadf32 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
+ let IsLoad = 1;
+ let MemoryVT = f32;
+}
+def extloadf64 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
+ let IsLoad = 1;
+ let MemoryVT = f64;
+}
-def sextloadi1 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
- return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i1;
-}]>;
-def sextloadi8 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
- return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;
-}]>;
-def sextloadi16 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
- return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;
-}]>;
-def sextloadi32 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
- return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32;
-}]>;
+def sextloadi1 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> {
+ let IsLoad = 1;
+ let MemoryVT = i1;
+}
+def sextloadi8 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> {
+ let IsLoad = 1;
+ let MemoryVT = i8;
+}
+def sextloadi16 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> {
+ let IsLoad = 1;
+ let MemoryVT = i16;
+}
+def sextloadi32 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> {
+ let IsLoad = 1;
+ let MemoryVT = i32;
+}
-def zextloadi1 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
- return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i1;
-}]>;
-def zextloadi8 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
- return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;
-}]>;
-def zextloadi16 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
- return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;
-}]>;
-def zextloadi32 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
- return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32;
-}]>;
+def zextloadi1 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> {
+ let IsLoad = 1;
+ let MemoryVT = i1;
+}
+def zextloadi8 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> {
+ let IsLoad = 1;
+ let MemoryVT = i8;
+}
+def zextloadi16 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> {
+ let IsLoad = 1;
+ let MemoryVT = i16;
+}
+def zextloadi32 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> {
+ let IsLoad = 1;
+ let MemoryVT = i32;
+}
-def extloadvi1 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
- return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i1;
-}]>;
-def extloadvi8 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
- return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i8;
-}]>;
-def extloadvi16 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
- return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i16;
-}]>;
-def extloadvi32 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
- return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i32;
-}]>;
-def extloadvf32 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
- return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::f32;
-}]>;
-def extloadvf64 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
- return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::f64;
-}]>;
+def extloadvi1 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
+ let IsLoad = 1;
+ let ScalarMemoryVT = i1;
+}
+def extloadvi8 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
+ let IsLoad = 1;
+ let ScalarMemoryVT = i8;
+}
+def extloadvi16 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
+ let IsLoad = 1;
+ let ScalarMemoryVT = i16;
+}
+def extloadvi32 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
+ let IsLoad = 1;
+ let ScalarMemoryVT = i32;
+}
+def extloadvf32 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
+ let IsLoad = 1;
+ let ScalarMemoryVT = f32;
+}
+def extloadvf64 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
+ let IsLoad = 1;
+ let ScalarMemoryVT = f64;
+}
-def sextloadvi1 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
- return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i1;
-}]>;
-def sextloadvi8 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
- return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i8;
-}]>;
-def sextloadvi16 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
- return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i16;
-}]>;
-def sextloadvi32 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
- return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i32;
-}]>;
+def sextloadvi1 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> {
+ let IsLoad = 1;
+ let ScalarMemoryVT = i1;
+}
+def sextloadvi8 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> {
+ let IsLoad = 1;
+ let ScalarMemoryVT = i8;
+}
+def sextloadvi16 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> {
+ let IsLoad = 1;
+ let ScalarMemoryVT = i16;
+}
+def sextloadvi32 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> {
+ let IsLoad = 1;
+ let ScalarMemoryVT = i32;
+}
-def zextloadvi1 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
- return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i1;
-}]>;
-def zextloadvi8 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
- return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i8;
-}]>;
-def zextloadvi16 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
- return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i16;
-}]>;
-def zextloadvi32 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
- return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i32;
-}]>;
+def zextloadvi1 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> {
+ let IsLoad = 1;
+ let ScalarMemoryVT = i1;
+}
+def zextloadvi8 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> {
+ let IsLoad = 1;
+ let ScalarMemoryVT = i8;
+}
+def zextloadvi16 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> {
+ let IsLoad = 1;
+ let ScalarMemoryVT = i16;
+}
+def zextloadvi32 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> {
+ let IsLoad = 1;
+ let ScalarMemoryVT = i32;
+}
// store fragments.
def unindexedstore : PatFrag<(ops node:$val, node:$ptr),
- (st node:$val, node:$ptr), [{
- return cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
-}]>;
+ (st node:$val, node:$ptr)> {
+ let IsStore = 1;
+ let IsUnindexed = 1;
+}
def store : PatFrag<(ops node:$val, node:$ptr),
- (unindexedstore node:$val, node:$ptr), [{
- return !cast<StoreSDNode>(N)->isTruncatingStore();
-}]>;
+ (unindexedstore node:$val, node:$ptr)> {
+ let IsStore = 1;
+ let IsTruncStore = 0;
+}
// truncstore fragments.
def truncstore : PatFrag<(ops node:$val, node:$ptr),
- (unindexedstore node:$val, node:$ptr), [{
- return cast<StoreSDNode>(N)->isTruncatingStore();
-}]>;
+ (unindexedstore node:$val, node:$ptr)> {
+ let IsStore = 1;
+ let IsTruncStore = 1;
+}
def truncstorei8 : PatFrag<(ops node:$val, node:$ptr),
- (truncstore node:$val, node:$ptr), [{
- return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i8;
-}]>;
+ (truncstore node:$val, node:$ptr)> {
+ let IsStore = 1;
+ let MemoryVT = i8;
+}
def truncstorei16 : PatFrag<(ops node:$val, node:$ptr),
- (truncstore node:$val, node:$ptr), [{
- return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i16;
-}]>;
+ (truncstore node:$val, node:$ptr)> {
+ let IsStore = 1;
+ let MemoryVT = i16;
+}
def truncstorei32 : PatFrag<(ops node:$val, node:$ptr),
- (truncstore node:$val, node:$ptr), [{
- return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i32;
-}]>;
+ (truncstore node:$val, node:$ptr)> {
+ let IsStore = 1;
+ let MemoryVT = i32;
+}
def truncstoref32 : PatFrag<(ops node:$val, node:$ptr),
- (truncstore node:$val, node:$ptr), [{
- return cast<StoreSDNode>(N)->getMemoryVT() == MVT::f32;
-}]>;
+ (truncstore node:$val, node:$ptr)> {
+ let IsStore = 1;
+ let MemoryVT = f32;
+}
def truncstoref64 : PatFrag<(ops node:$val, node:$ptr),
- (truncstore node:$val, node:$ptr), [{
- return cast<StoreSDNode>(N)->getMemoryVT() == MVT::f64;
-}]>;
+ (truncstore node:$val, node:$ptr)> {
+ let IsStore = 1;
+ let MemoryVT = f64;
+}
def truncstorevi8 : PatFrag<(ops node:$val, node:$ptr),
- (truncstore node:$val, node:$ptr), [{
- return cast<StoreSDNode>(N)->getMemoryVT().getScalarType() == MVT::i8;
-}]>;
+ (truncstore node:$val, node:$ptr)> {
+ let IsStore = 1;
+ let ScalarMemoryVT = i8;
+}
def truncstorevi16 : PatFrag<(ops node:$val, node:$ptr),
- (truncstore node:$val, node:$ptr), [{
- return cast<StoreSDNode>(N)->getMemoryVT().getScalarType() == MVT::i16;
-}]>;
+ (truncstore node:$val, node:$ptr)> {
+ let IsStore = 1;
+ let ScalarMemoryVT = i16;
+}
def truncstorevi32 : PatFrag<(ops node:$val, node:$ptr),
- (truncstore node:$val, node:$ptr), [{
- return cast<StoreSDNode>(N)->getMemoryVT().getScalarType() == MVT::i32;
-}]>;
+ (truncstore node:$val, node:$ptr)> {
+ let IsStore = 1;
+ let ScalarMemoryVT = i32;
+}
// indexed store fragments.
def istore : PatFrag<(ops node:$val, node:$base, node:$offset),
- (ist node:$val, node:$base, node:$offset), [{
- return !cast<StoreSDNode>(N)->isTruncatingStore();
-}]>;
+ (ist node:$val, node:$base, node:$offset)> {
+ let IsStore = 1;
+ let IsTruncStore = 0;
+}
def pre_store : PatFrag<(ops node:$val, node:$base, node:$offset),
(istore node:$val, node:$base, node:$offset), [{
}]>;
def itruncstore : PatFrag<(ops node:$val, node:$base, node:$offset),
- (ist node:$val, node:$base, node:$offset), [{
- return cast<StoreSDNode>(N)->isTruncatingStore();
-}]>;
+ (ist node:$val, node:$base, node:$offset)> {
+ let IsStore = 1;
+ let IsTruncStore = 1;
+}
def pre_truncst : PatFrag<(ops node:$val, node:$base, node:$offset),
(itruncstore node:$val, node:$base, node:$offset), [{
ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode();
return AM == ISD::PRE_INC || AM == ISD::PRE_DEC;
}]>;
def pre_truncsti1 : PatFrag<(ops node:$val, node:$base, node:$offset),
- (pre_truncst node:$val, node:$base, node:$offset), [{
- return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i1;
-}]>;
+ (pre_truncst node:$val, node:$base, node:$offset)> {
+ let IsStore = 1;
+ let MemoryVT = i1;
+}
def pre_truncsti8 : PatFrag<(ops node:$val, node:$base, node:$offset),
- (pre_truncst node:$val, node:$base, node:$offset), [{
- return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i8;
-}]>;
+ (pre_truncst node:$val, node:$base, node:$offset)> {
+ let IsStore = 1;
+ let MemoryVT = i8;
+}
def pre_truncsti16 : PatFrag<(ops node:$val, node:$base, node:$offset),
- (pre_truncst node:$val, node:$base, node:$offset), [{
- return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i16;
-}]>;
+ (pre_truncst node:$val, node:$base, node:$offset)> {
+ let IsStore = 1;
+ let MemoryVT = i16;
+}
def pre_truncsti32 : PatFrag<(ops node:$val, node:$base, node:$offset),
- (pre_truncst node:$val, node:$base, node:$offset), [{
- return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i32;
-}]>;
+ (pre_truncst node:$val, node:$base, node:$offset)> {
+ let IsStore = 1;
+ let MemoryVT = i32;
+}
def pre_truncstf32 : PatFrag<(ops node:$val, node:$base, node:$offset),
- (pre_truncst node:$val, node:$base, node:$offset), [{
- return cast<StoreSDNode>(N)->getMemoryVT() == MVT::f32;
-}]>;
+ (pre_truncst node:$val, node:$base, node:$offset)> {
+ let IsStore = 1;
+ let MemoryVT = f32;
+}
def post_store : PatFrag<(ops node:$val, node:$ptr, node:$offset),
(istore node:$val, node:$ptr, node:$offset), [{
return AM == ISD::POST_INC || AM == ISD::POST_DEC;
}]>;
def post_truncsti1 : PatFrag<(ops node:$val, node:$base, node:$offset),
- (post_truncst node:$val, node:$base, node:$offset), [{
- return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i1;
-}]>;
+ (post_truncst node:$val, node:$base, node:$offset)> {
+ let IsStore = 1;
+ let MemoryVT = i1;
+}
def post_truncsti8 : PatFrag<(ops node:$val, node:$base, node:$offset),
- (post_truncst node:$val, node:$base, node:$offset), [{
- return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i8;
-}]>;
+ (post_truncst node:$val, node:$base, node:$offset)> {
+ let IsStore = 1;
+ let MemoryVT = i8;
+}
def post_truncsti16 : PatFrag<(ops node:$val, node:$base, node:$offset),
- (post_truncst node:$val, node:$base, node:$offset), [{
- return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i16;
-}]>;
+ (post_truncst node:$val, node:$base, node:$offset)> {
+ let IsStore = 1;
+ let MemoryVT = i16;
+}
def post_truncsti32 : PatFrag<(ops node:$val, node:$base, node:$offset),
- (post_truncst node:$val, node:$base, node:$offset), [{
- return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i32;
-}]>;
+ (post_truncst node:$val, node:$base, node:$offset)> {
+ let IsStore = 1;
+ let MemoryVT = i32;
+}
def post_truncstf32 : PatFrag<(ops node:$val, node:$base, node:$offset),
- (post_truncst node:$val, node:$base, node:$offset), [{
- return cast<StoreSDNode>(N)->getMemoryVT() == MVT::f32;
-}]>;
+ (post_truncst node:$val, node:$base, node:$offset)> {
+ let IsStore = 1;
+ let MemoryVT = f32;
+}
// nontemporal store fragments.
def nontemporalstore : PatFrag<(ops node:$val, node:$ptr),
".td file corrupt: can't have a node predicate *and* an imm predicate");
}
-StringRef TreePredicateFn::getPredCode() const {
- return PatFragRec->getRecord()->getValueAsString("PredicateCode");
+std::string TreePredicateFn::getPredCode() const {
+ std::string Code = "";
+
+ 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())
+ PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
+ "IsLoad and IsStore are mutually exclusive");
+
+ if (isLoad()) {
+ if (!isUnindexed() && !isNonExtLoad() && !isAnyExtLoad() &&
+ !isSignExtLoad() && !isZeroExtLoad() && getMemoryVT() == nullptr &&
+ getScalarMemoryVT() == nullptr)
+ PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
+ "IsLoad cannot be used by itself");
+ } else {
+ if (isNonExtLoad())
+ PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
+ "IsNonExtLoad requires IsLoad");
+ if (isAnyExtLoad())
+ PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
+ "IsAnyExtLoad requires IsLoad");
+ if (isSignExtLoad())
+ PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
+ "IsSignExtLoad requires IsLoad");
+ if (isZeroExtLoad())
+ PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
+ "IsZeroExtLoad requires IsLoad");
+ }
+
+ if (isStore()) {
+ if (!isUnindexed() && !isTruncStore() && !isNonTruncStore() &&
+ getMemoryVT() == nullptr && getScalarMemoryVT() == nullptr)
+ PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
+ "IsStore cannot be used by itself");
+ } else {
+ if (isNonTruncStore())
+ PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
+ "IsNonTruncStore requires IsStore");
+ if (isTruncStore())
+ PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
+ "IsTruncStore requires IsStore");
+ }
+
+ if (isLoad() || isStore()) {
+ StringRef SDNodeName = isLoad() ? "LoadSDNode" : "StoreSDNode";
+
+ if (isUnindexed())
+ Code += ("if (cast<" + SDNodeName +
+ ">(N)->getAddressingMode() != ISD::UNINDEXED) "
+ "return false;\n")
+ .str();
+
+ if (isLoad()) {
+ if ((isNonExtLoad() + isAnyExtLoad() + isSignExtLoad() +
+ isZeroExtLoad()) > 1)
+ PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
+ "IsNonExtLoad, IsAnyExtLoad, IsSignExtLoad, and "
+ "IsZeroExtLoad are mutually exclusive");
+ if (isNonExtLoad())
+ Code += "if (cast<LoadSDNode>(N)->getExtensionType() != "
+ "ISD::NON_EXTLOAD) return false;\n";
+ if (isAnyExtLoad())
+ Code += "if (cast<LoadSDNode>(N)->getExtensionType() != ISD::EXTLOAD) "
+ "return false;\n";
+ if (isSignExtLoad())
+ Code += "if (cast<LoadSDNode>(N)->getExtensionType() != ISD::SEXTLOAD) "
+ "return false;\n";
+ if (isZeroExtLoad())
+ Code += "if (cast<LoadSDNode>(N)->getExtensionType() != ISD::ZEXTLOAD) "
+ "return false;\n";
+ } else {
+ if ((isNonTruncStore() + isTruncStore()) > 1)
+ PrintFatalError(
+ getOrigPatFragRecord()->getRecord()->getLoc(),
+ "IsNonTruncStore, and IsTruncStore are mutually exclusive");
+ if (isNonTruncStore())
+ Code +=
+ " if (cast<StoreSDNode>(N)->isTruncatingStore()) return false;\n";
+ if (isTruncStore())
+ Code +=
+ " 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::" +
+ ScalarMemoryVT->getName() + ") return false;\n")
+ .str();
+ }
+
+ std::string PredicateCode = PatFragRec->getRecord()->getValueAsString("PredicateCode");
+
+ Code += PredicateCode;
+
+ if (PredicateCode.empty() && !Code.empty())
+ Code += "return true;\n";
+
+ return Code;
}
-StringRef TreePredicateFn::getImmCode() const {
+std::string TreePredicateFn::getImmCode() const {
return PatFragRec->getRecord()->getValueAsString("ImmediateCode");
}
Unset);
}
+bool TreePredicateFn::isPredefinedPredicateEqualTo(StringRef Field,
+ bool Value) const {
+ bool Unset;
+ bool Result =
+ getOrigPatFragRecord()->getRecord()->getValueAsBitOrUnset(Field, Unset);
+ if (Unset)
+ return false;
+ return Result == Value;
+}
+bool TreePredicateFn::isLoad() const {
+ return isPredefinedPredicateEqualTo("IsLoad", true);
+}
+bool TreePredicateFn::isStore() const {
+ return isPredefinedPredicateEqualTo("IsStore", true);
+}
+bool TreePredicateFn::isUnindexed() const {
+ return isPredefinedPredicateEqualTo("IsUnindexed", true);
+}
+bool TreePredicateFn::isNonExtLoad() const {
+ return isPredefinedPredicateEqualTo("IsNonExtLoad", true);
+}
+bool TreePredicateFn::isAnyExtLoad() const {
+ return isPredefinedPredicateEqualTo("IsAnyExtLoad", true);
+}
+bool TreePredicateFn::isSignExtLoad() const {
+ return isPredefinedPredicateEqualTo("IsSignExtLoad", true);
+}
+bool TreePredicateFn::isZeroExtLoad() const {
+ return isPredefinedPredicateEqualTo("IsZeroExtLoad", true);
+}
+bool TreePredicateFn::isNonTruncStore() const {
+ return isPredefinedPredicateEqualTo("IsTruncStore", false);
+}
+bool TreePredicateFn::isTruncStore() const {
+ return isPredefinedPredicateEqualTo("IsTruncStore", true);
+}
+Record *TreePredicateFn::getMemoryVT() const {
+ Record *R = getOrigPatFragRecord()->getRecord();
+ if (R->isValueUnset("MemoryVT"))
+ return nullptr;
+ return R->getValueAsDef("MemoryVT");
+}
+Record *TreePredicateFn::getScalarMemoryVT() const {
+ Record *R = getOrigPatFragRecord()->getRecord();
+ if (R->isValueUnset("ScalarMemoryVT"))
+ return nullptr;
+ return R->getValueAsDef("ScalarMemoryVT");
+}
+
StringRef TreePredicateFn::getImmType() const {
if (immCodeUsesAPInt())
return "const APInt &";
/// appropriate.
std::string TreePredicateFn::getCodeToRunOnSDNode() const {
// Handle immediate predicates first.
- StringRef ImmCode = getImmCode();
+ std::string ImmCode = getImmCode();
if (!ImmCode.empty()) {
- std::string Result = " " + getImmType().str() + " Imm = ";
+ if (isLoad())
+ PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
+ "IsLoad cannot be used with ImmLeaf or its subclasses");
+ if (isStore())
+ PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
+ "IsStore cannot be used with ImmLeaf or its subclasses");
+ if (isUnindexed())
+ PrintFatalError(
+ getOrigPatFragRecord()->getRecord()->getLoc(),
+ "IsUnindexed cannot be used with ImmLeaf or its subclasses");
+ if (isNonExtLoad())
+ PrintFatalError(
+ getOrigPatFragRecord()->getRecord()->getLoc(),
+ "IsNonExtLoad cannot be used with ImmLeaf or its subclasses");
+ if (isAnyExtLoad())
+ PrintFatalError(
+ getOrigPatFragRecord()->getRecord()->getLoc(),
+ "IsAnyExtLoad cannot be used with ImmLeaf or its subclasses");
+ if (isSignExtLoad())
+ PrintFatalError(
+ getOrigPatFragRecord()->getRecord()->getLoc(),
+ "IsSignExtLoad cannot be used with ImmLeaf or its subclasses");
+ if (isZeroExtLoad())
+ PrintFatalError(
+ getOrigPatFragRecord()->getRecord()->getLoc(),
+ "IsZeroExtLoad cannot be used with ImmLeaf or its subclasses");
+ if (isNonTruncStore())
+ PrintFatalError(
+ getOrigPatFragRecord()->getRecord()->getLoc(),
+ "IsNonTruncStore cannot be used with ImmLeaf or its subclasses");
+ if (isTruncStore())
+ PrintFatalError(
+ getOrigPatFragRecord()->getRecord()->getLoc(),
+ "IsTruncStore cannot be used with ImmLeaf or its subclasses");
+ if (getMemoryVT())
+ PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
+ "MemoryVT cannot be used with ImmLeaf or its subclasses");
+ if (getScalarMemoryVT())
+ PrintFatalError(
+ getOrigPatFragRecord()->getRecord()->getLoc(),
+ "ScalarMemoryVT cannot be used with ImmLeaf or its subclasses");
+
+ std::string Result = (" " + getImmType() + " Imm = ").str();
if (immCodeUsesAPFloat())
Result += "cast<ConstantFPSDNode>(Node)->getValueAPF();\n";
else if (immCodeUsesAPInt())
Result += "cast<ConstantSDNode>(Node)->getAPIntValue();\n";
else
Result += "cast<ConstantSDNode>(Node)->getSExtValue();\n";
- return Result + ImmCode.str();
+ return Result + ImmCode;
}
// Handle arbitrary node predicates.
else
Result = " auto *N = cast<" + ClassName.str() + ">(Node);\n";
- return Result + getPredCode().str();
+ return Result + getPredCode();
}
//===----------------------------------------------------------------------===//