Skip to content

Commit a3d8065

Browse files
committedSep 12, 2018
[PatternMatch] Use generic One,Two,ThreeOps_match classes (NFC).
Currently we have a few duplicated matcher classes, which all do pretty much the same thing. This patch introduces generic One,Tow,ThreeOps_match classes which take the opcode the match as template argument. Reviewers: SjoerdMeijer, dneilson, spatel, arsenm Reviewed By: SjoerdMeijer Differential Revision: https://reviews.llvm.org/D51044 llvm-svn: 342058
1 parent ebff312 commit a3d8065

File tree

1 file changed

+75
-128
lines changed

1 file changed

+75
-128
lines changed
 

‎llvm/include/llvm/IR/PatternMatch.h

+75-128
Original file line numberDiff line numberDiff line change
@@ -991,116 +991,111 @@ m_FCmp(FCmpInst::Predicate &Pred, const LHS &L, const RHS &R) {
991991
}
992992

993993
//===----------------------------------------------------------------------===//
994-
// Matchers for SelectInst classes
994+
// Matchers for instructions with a given opcode and number of operands.
995995
//
996996

997-
template <typename Cond_t, typename LHS_t, typename RHS_t>
998-
struct SelectClass_match {
999-
Cond_t C;
1000-
LHS_t L;
1001-
RHS_t R;
997+
/// Matches instructions with Opcode and three operands.
998+
template <typename T0, unsigned Opcode> struct OneOps_match {
999+
T0 Op1;
1000+
1001+
OneOps_match(const T0 &Op1) : Op1(Op1) {}
1002+
1003+
template <typename OpTy> bool match(OpTy *V) {
1004+
if (V->getValueID() == Value::InstructionVal + Opcode) {
1005+
auto *I = cast<Instruction>(V);
1006+
return Op1.match(I->getOperand(0));
1007+
}
1008+
return false;
1009+
}
1010+
};
1011+
1012+
/// Matches instructions with Opcode and three operands.
1013+
template <typename T0, typename T1, unsigned Opcode> struct TwoOps_match {
1014+
T0 Op1;
1015+
T1 Op2;
10021016

1003-
SelectClass_match(const Cond_t &Cond, const LHS_t &LHS, const RHS_t &RHS)
1004-
: C(Cond), L(LHS), R(RHS) {}
1017+
TwoOps_match(const T0 &Op1, const T1 &Op2) : Op1(Op1), Op2(Op2) {}
10051018

10061019
template <typename OpTy> bool match(OpTy *V) {
1007-
if (auto *I = dyn_cast<SelectInst>(V))
1008-
return C.match(I->getOperand(0)) && L.match(I->getOperand(1)) &&
1009-
R.match(I->getOperand(2));
1020+
if (V->getValueID() == Value::InstructionVal + Opcode) {
1021+
auto *I = cast<Instruction>(V);
1022+
return Op1.match(I->getOperand(0)) && Op2.match(I->getOperand(1));
1023+
}
1024+
return false;
1025+
}
1026+
};
1027+
1028+
/// Matches instructions with Opcode and three operands.
1029+
template <typename T0, typename T1, typename T2, unsigned Opcode>
1030+
struct ThreeOps_match {
1031+
T0 Op1;
1032+
T1 Op2;
1033+
T2 Op3;
1034+
1035+
ThreeOps_match(const T0 &Op1, const T1 &Op2, const T2 &Op3)
1036+
: Op1(Op1), Op2(Op2), Op3(Op3) {}
1037+
1038+
template <typename OpTy> bool match(OpTy *V) {
1039+
if (V->getValueID() == Value::InstructionVal + Opcode) {
1040+
auto *I = cast<Instruction>(V);
1041+
return Op1.match(I->getOperand(0)) && Op2.match(I->getOperand(1)) &&
1042+
Op3.match(I->getOperand(2));
1043+
}
10101044
return false;
10111045
}
10121046
};
10131047

1048+
/// Matches SelectInst.
10141049
template <typename Cond, typename LHS, typename RHS>
1015-
inline SelectClass_match<Cond, LHS, RHS> m_Select(const Cond &C, const LHS &L,
1016-
const RHS &R) {
1017-
return SelectClass_match<Cond, LHS, RHS>(C, L, R);
1050+
inline ThreeOps_match<Cond, LHS, RHS, Instruction::Select>
1051+
m_Select(const Cond &C, const LHS &L, const RHS &R) {
1052+
return ThreeOps_match<Cond, LHS, RHS, Instruction::Select>(C, L, R);
10181053
}
10191054

10201055
/// This matches a select of two constants, e.g.:
10211056
/// m_SelectCst<-1, 0>(m_Value(V))
10221057
template <int64_t L, int64_t R, typename Cond>
1023-
inline SelectClass_match<Cond, constantint_match<L>, constantint_match<R>>
1058+
inline ThreeOps_match<Cond, constantint_match<L>, constantint_match<R>,
1059+
Instruction::Select>
10241060
m_SelectCst(const Cond &C) {
10251061
return m_Select(C, m_ConstantInt<L>(), m_ConstantInt<R>());
10261062
}
10271063

1028-
//===----------------------------------------------------------------------===//
1029-
// Matchers for InsertElementInst classes
1030-
//
1031-
1064+
/// Matches InsertElementInst.
10321065
template <typename Val_t, typename Elt_t, typename Idx_t>
1033-
struct InsertElementClass_match {
1034-
Val_t V;
1035-
Elt_t E;
1036-
Idx_t I;
1037-
1038-
InsertElementClass_match(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx)
1039-
: V(Val), E(Elt), I(Idx) {}
1040-
1041-
template <typename OpTy> bool match(OpTy *VV) {
1042-
if (auto *II = dyn_cast<InsertElementInst>(VV))
1043-
return V.match(II->getOperand(0)) && E.match(II->getOperand(1)) &&
1044-
I.match(II->getOperand(2));
1045-
return false;
1046-
}
1047-
};
1048-
1049-
template <typename Val_t, typename Elt_t, typename Idx_t>
1050-
inline InsertElementClass_match<Val_t, Elt_t, Idx_t>
1066+
inline ThreeOps_match<Val_t, Elt_t, Idx_t, Instruction::InsertElement>
10511067
m_InsertElement(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx) {
1052-
return InsertElementClass_match<Val_t, Elt_t, Idx_t>(Val, Elt, Idx);
1068+
return ThreeOps_match<Val_t, Elt_t, Idx_t, Instruction::InsertElement>(
1069+
Val, Elt, Idx);
10531070
}
10541071

1055-
//===----------------------------------------------------------------------===//
1056-
// Matchers for ExtractElementInst classes
1057-
//
1058-
1059-
template <typename Val_t, typename Idx_t> struct ExtractElementClass_match {
1060-
Val_t V;
1061-
Idx_t I;
1062-
1063-
ExtractElementClass_match(const Val_t &Val, const Idx_t &Idx)
1064-
: V(Val), I(Idx) {}
1065-
1066-
template <typename OpTy> bool match(OpTy *VV) {
1067-
if (auto *II = dyn_cast<ExtractElementInst>(VV))
1068-
return V.match(II->getOperand(0)) && I.match(II->getOperand(1));
1069-
return false;
1070-
}
1071-
};
1072-
1072+
/// Matches ExtractElementInst.
10731073
template <typename Val_t, typename Idx_t>
1074-
inline ExtractElementClass_match<Val_t, Idx_t>
1074+
inline TwoOps_match<Val_t, Idx_t, Instruction::ExtractElement>
10751075
m_ExtractElement(const Val_t &Val, const Idx_t &Idx) {
1076-
return ExtractElementClass_match<Val_t, Idx_t>(Val, Idx);
1076+
return TwoOps_match<Val_t, Idx_t, Instruction::ExtractElement>(Val, Idx);
10771077
}
10781078

1079-
//===----------------------------------------------------------------------===//
1080-
// Matchers for ShuffleVectorInst classes
1081-
//
1082-
1079+
/// Matches ShuffleVectorInst.
10831080
template <typename V1_t, typename V2_t, typename Mask_t>
1084-
struct ShuffleVectorClass_match {
1085-
V1_t V1;
1086-
V2_t V2;
1087-
Mask_t M;
1088-
1089-
ShuffleVectorClass_match(const V1_t &v1, const V2_t &v2, const Mask_t &m)
1090-
: V1(v1), V2(v2), M(m) {}
1081+
inline ThreeOps_match<V1_t, V2_t, Mask_t, Instruction::ShuffleVector>
1082+
m_ShuffleVector(const V1_t &v1, const V2_t &v2, const Mask_t &m) {
1083+
return ThreeOps_match<V1_t, V2_t, Mask_t, Instruction::ShuffleVector>(v1, v2,
1084+
m);
1085+
}
10911086

1092-
template <typename OpTy> bool match(OpTy *V) {
1093-
if (auto *SI = dyn_cast<ShuffleVectorInst>(V))
1094-
return V1.match(SI->getOperand(0)) && V2.match(SI->getOperand(1)) &&
1095-
M.match(SI->getOperand(2));
1096-
return false;
1097-
}
1098-
};
1087+
/// Matches LoadInst.
1088+
template <typename OpTy>
1089+
inline OneOps_match<OpTy, Instruction::Load> m_Load(const OpTy &Op) {
1090+
return OneOps_match<OpTy, Instruction::Load>(Op);
1091+
}
10991092

1100-
template <typename V1_t, typename V2_t, typename Mask_t>
1101-
inline ShuffleVectorClass_match<V1_t, V2_t, Mask_t>
1102-
m_ShuffleVector(const V1_t &v1, const V2_t &v2, const Mask_t &m) {
1103-
return ShuffleVectorClass_match<V1_t, V2_t, Mask_t>(v1, v2, m);
1093+
/// Matches StoreInst.
1094+
template <typename ValueOpTy, typename PointerOpTy>
1095+
inline TwoOps_match<ValueOpTy, PointerOpTy, Instruction::Store>
1096+
m_Store(const ValueOpTy &ValueOp, const PointerOpTy &PointerOp) {
1097+
return TwoOps_match<ValueOpTy, PointerOpTy, Instruction::Store>(ValueOp,
1098+
PointerOp);
11041099
}
11051100

11061101
//===----------------------------------------------------------------------===//
@@ -1180,54 +1175,6 @@ inline CastClass_match<OpTy, Instruction::FPExt> m_FPExt(const OpTy &Op) {
11801175
return CastClass_match<OpTy, Instruction::FPExt>(Op);
11811176
}
11821177

1183-
//===----------------------------------------------------------------------===//
1184-
// Matcher for LoadInst classes
1185-
//
1186-
1187-
template <typename Op_t> struct LoadClass_match {
1188-
Op_t Op;
1189-
1190-
LoadClass_match(const Op_t &OpMatch) : Op(OpMatch) {}
1191-
1192-
template <typename OpTy> bool match(OpTy *V) {
1193-
if (auto *LI = dyn_cast<LoadInst>(V))
1194-
return Op.match(LI->getPointerOperand());
1195-
return false;
1196-
}
1197-
};
1198-
1199-
/// Matches LoadInst.
1200-
template <typename OpTy> inline LoadClass_match<OpTy> m_Load(const OpTy &Op) {
1201-
return LoadClass_match<OpTy>(Op);
1202-
}
1203-
1204-
//===----------------------------------------------------------------------===//
1205-
// Matcher for StoreInst classes
1206-
//
1207-
1208-
template <typename ValueOp_t, typename PointerOp_t> struct StoreClass_match {
1209-
ValueOp_t ValueOp;
1210-
PointerOp_t PointerOp;
1211-
1212-
StoreClass_match(const ValueOp_t &ValueOpMatch,
1213-
const PointerOp_t &PointerOpMatch) :
1214-
ValueOp(ValueOpMatch), PointerOp(PointerOpMatch) {}
1215-
1216-
template <typename OpTy> bool match(OpTy *V) {
1217-
if (auto *LI = dyn_cast<StoreInst>(V))
1218-
return ValueOp.match(LI->getValueOperand()) &&
1219-
PointerOp.match(LI->getPointerOperand());
1220-
return false;
1221-
}
1222-
};
1223-
1224-
/// Matches StoreInst.
1225-
template <typename ValueOpTy, typename PointerOpTy>
1226-
inline StoreClass_match<ValueOpTy, PointerOpTy>
1227-
m_Store(const ValueOpTy &ValueOp, const PointerOpTy &PointerOp) {
1228-
return StoreClass_match<ValueOpTy, PointerOpTy>(ValueOp, PointerOp);
1229-
}
1230-
12311178
//===----------------------------------------------------------------------===//
12321179
// Matchers for control flow.
12331180
//

0 commit comments

Comments
 (0)
Please sign in to comment.