@@ -91,79 +91,60 @@ struct specificscev_ty {
9191// / Match if we have a specific specified SCEV.
9292inline specificscev_ty m_Specific (const SCEV *S) { return S; }
9393
94- namespace detail {
94+ // / Match a unary SCEV.
95+ template <typename SCEVTy, typename Op0_t> struct SCEVUnaryExpr_match {
96+ Op0_t Op0;
9597
96- template <typename TupleTy, typename Fn, std::size_t ... Is>
97- bool CheckTupleElements (const TupleTy &Ops, Fn P, std::index_sequence<Is...>) {
98- return (P (std::get<Is>(Ops), Is) && ...);
98+ SCEVUnaryExpr_match (Op0_t Op0) : Op0(Op0) {}
99+
100+ bool match (const SCEV *S) {
101+ auto *E = dyn_cast<SCEVTy>(S);
102+ return E && E->getNumOperands () == 1 && Op0.match (E->getOperand (0 ));
103+ }
104+ };
105+
106+ template <typename SCEVTy, typename Op0_t>
107+ inline SCEVUnaryExpr_match<SCEVTy, Op0_t> m_scev_Unary (const Op0_t &Op0) {
108+ return SCEVUnaryExpr_match<SCEVTy, Op0_t>(Op0);
99109}
100110
101- // / Helper to check if predicate \p P holds on all tuple elements in \p Ops
102- template <typename TupleTy, typename Fn>
103- bool all_of_tuple_elements (const TupleTy &Ops, Fn P) {
104- return CheckTupleElements (
105- Ops, P, std::make_index_sequence<std::tuple_size<TupleTy>::value>{});
111+ template <typename Op0_t>
112+ inline SCEVUnaryExpr_match<SCEVSignExtendExpr, Op0_t>
113+ m_scev_SExt (const Op0_t &Op0) {
114+ return m_scev_Unary<SCEVSignExtendExpr>(Op0);
106115}
107116
108- } // namespace detail
117+ template <typename Op0_t>
118+ inline SCEVUnaryExpr_match<SCEVZeroExtendExpr, Op0_t>
119+ m_scev_ZExt (const Op0_t &Op0) {
120+ return m_scev_Unary<SCEVZeroExtendExpr>(Op0);
121+ }
109122
110- template <typename Ops_t, typename SCEVTy> struct SCEVExpr_match {
111- Ops_t Ops;
123+ // / Match a binary SCEV.
124+ template <typename SCEVTy, typename Op0_t, typename Op1_t>
125+ struct SCEVBinaryExpr_match {
126+ Op0_t Op0;
127+ Op1_t Op1;
112128
113- SCEVExpr_match () : Ops() {
114- static_assert (std::tuple_size<Ops_t>::value == 0 &&
115- " constructor can only be used with zero operands" );
116- }
117- SCEVExpr_match (Ops_t Ops) : Ops(Ops) {}
118- template <typename A_t, typename B_t>
119- SCEVExpr_match (A_t A, B_t B) : Ops({A, B}) {
120- static_assert (std::tuple_size<Ops_t>::value == 2 &&
121- " constructor can only be used for binary matcher" );
122- }
129+ SCEVBinaryExpr_match (Op0_t Op0, Op1_t Op1) : Op0(Op0), Op1(Op1) {}
123130
124- bool match (const SCEV *S) const {
125- auto *Cast = dyn_cast<SCEVTy>(S);
126- if (!Cast || Cast->getNumOperands () != std::tuple_size<Ops_t>::value)
127- return false ;
128- return detail::all_of_tuple_elements (Ops, [Cast](auto Op, unsigned Idx) {
129- return Op.match (Cast->getOperand (Idx));
130- });
131+ bool match (const SCEV *S) {
132+ auto *E = dyn_cast<SCEVTy>(S);
133+ return E && E->getNumOperands () == 2 && Op0.match (E->getOperand (0 )) &&
134+ Op1.match (E->getOperand (1 ));
131135 }
132136};
133137
134- template <typename Op0_t, typename Op1_t, typename SCEVTy>
135- using BinarySCEVExpr_match = SCEVExpr_match<std::tuple<Op0_t, Op1_t>, SCEVTy>;
136-
137- template <typename Op0_t, typename Op1_t, typename SCEVTy>
138- inline BinarySCEVExpr_match<Op0_t, Op1_t, SCEVTy>
138+ template <typename SCEVTy, typename Op0_t, typename Op1_t>
139+ inline SCEVBinaryExpr_match<SCEVTy, Op0_t, Op1_t>
139140m_scev_Binary (const Op0_t &Op0, const Op1_t &Op1) {
140- return BinarySCEVExpr_match<Op0_t, Op1_t, SCEVTy >(Op0, Op1);
141+ return SCEVBinaryExpr_match<SCEVTy, Op0_t, Op1_t >(Op0, Op1);
141142}
142143
143144template <typename Op0_t, typename Op1_t>
144- inline BinarySCEVExpr_match<Op0_t, Op1_t, SCEVAddExpr >
145+ inline SCEVBinaryExpr_match<SCEVAddExpr, Op0_t, Op1_t >
145146m_scev_Add (const Op0_t &Op0, const Op1_t &Op1) {
146- return BinarySCEVExpr_match<Op0_t, Op1_t, SCEVAddExpr>(Op0, Op1);
147- }
148-
149- template <typename Op0_t, typename SCEVTy>
150- using UnarySCEVExpr_match = SCEVExpr_match<std::tuple<Op0_t>, SCEVTy>;
151-
152- template <typename Op0_t, typename Op1_t, typename SCEVTy>
153- inline UnarySCEVExpr_match<Op0_t, SCEVTy> m_scev_Unary (const Op0_t &Op0) {
154- return UnarySCEVExpr_match<Op0_t, SCEVTy>(Op0);
155- }
156-
157- template <typename Op0_t>
158- inline UnarySCEVExpr_match<Op0_t, SCEVSignExtendExpr>
159- m_scev_SExt (const Op0_t &Op0) {
160- return UnarySCEVExpr_match<Op0_t, SCEVSignExtendExpr>(Op0);
161- }
162-
163- template <typename Op0_t>
164- inline UnarySCEVExpr_match<Op0_t, SCEVZeroExtendExpr>
165- m_scev_ZExt (const Op0_t &Op0) {
166- return UnarySCEVExpr_match<Op0_t, SCEVZeroExtendExpr>(Op0);
147+ return m_scev_Binary<SCEVAddExpr>(Op0, Op1);
167148}
168149
169150} // namespace SCEVPatternMatch
0 commit comments