LLVM 20.0.0git
ScalarEvolutionPatternMatch.h
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3// See https://llvm.org/LICENSE.txt for license information.
4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5//
6//===----------------------------------------------------------------------===//
7//
8// This file provides a simple and efficient mechanism for performing general
9// tree-based pattern matches on SCEVs, based on LLVM's IR pattern matchers.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_ANALYSIS_SCALAREVOLUTIONPATTERNMATCH_H
14#define LLVM_ANALYSIS_SCALAREVOLUTIONPATTERNMATCH_H
15
17
18namespace llvm {
19namespace SCEVPatternMatch {
20
21template <typename Val, typename Pattern>
22bool match(const SCEV *S, const Pattern &P) {
23 return P.match(S);
24}
25
26template <typename Predicate> struct cst_pred_ty : public Predicate {
27 bool match(const SCEV *S) {
28 assert((isa<SCEVCouldNotCompute>(S) || !S->getType()->isVectorTy()) &&
29 "no vector types expected from SCEVs");
30 auto *C = dyn_cast<SCEVConstant>(S);
31 return C && this->isValue(C->getAPInt());
32 }
33};
34
35struct is_zero {
36 bool isValue(const APInt &C) { return C.isZero(); }
37};
38/// Match an integer 0.
40
41struct is_one {
42 bool isValue(const APInt &C) { return C.isOne(); }
43};
44/// Match an integer 1.
46
48 bool isValue(const APInt &C) { return C.isAllOnes(); }
49};
50/// Match an integer with all bits set.
53}
54
55template <typename Class> struct class_match {
56 template <typename ITy> bool match(ITy *V) const { return isa<Class>(V); }
57};
58
59template <typename Class> struct bind_ty {
60 Class *&VR;
61
62 bind_ty(Class *&V) : VR(V) {}
63
64 template <typename ITy> bool match(ITy *V) const {
65 if (auto *CV = dyn_cast<Class>(V)) {
66 VR = CV;
67 return true;
68 }
69 return false;
70 }
71};
72
73/// Match a SCEV, capturing it if we match.
74inline bind_ty<const SCEV> m_SCEV(const SCEV *&V) { return V; }
76 return V;
77}
79 return V;
80}
81
82/// Match a specified const SCEV *.
84 const SCEV *Expr;
85
87
88 template <typename ITy> bool match(ITy *S) { return S == Expr; }
89};
90
91/// Match if we have a specific specified SCEV.
92inline specificscev_ty m_Specific(const SCEV *S) { return S; }
93
94/// Match a unary SCEV.
95template <typename SCEVTy, typename Op0_t> struct SCEVUnaryExpr_match {
96 Op0_t Op0;
97
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
106template <typename SCEVTy, typename Op0_t>
109}
110
111template <typename Op0_t>
112inline SCEVUnaryExpr_match<SCEVSignExtendExpr, Op0_t>
113m_scev_SExt(const Op0_t &Op0) {
114 return m_scev_Unary<SCEVSignExtendExpr>(Op0);
115}
116
117template <typename Op0_t>
118inline SCEVUnaryExpr_match<SCEVZeroExtendExpr, Op0_t>
119m_scev_ZExt(const Op0_t &Op0) {
120 return m_scev_Unary<SCEVZeroExtendExpr>(Op0);
121}
122
123/// Match a binary SCEV.
124template <typename SCEVTy, typename Op0_t, typename Op1_t>
126 Op0_t Op0;
127 Op1_t Op1;
128
129 SCEVBinaryExpr_match(Op0_t Op0, Op1_t Op1) : Op0(Op0), Op1(Op1) {}
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));
135 }
136};
137
138template <typename SCEVTy, typename Op0_t, typename Op1_t>
139inline SCEVBinaryExpr_match<SCEVTy, Op0_t, Op1_t>
140m_scev_Binary(const Op0_t &Op0, const Op1_t &Op1) {
142}
143
144template <typename Op0_t, typename Op1_t>
145inline SCEVBinaryExpr_match<SCEVAddExpr, Op0_t, Op1_t>
146m_scev_Add(const Op0_t &Op0, const Op1_t &Op1) {
147 return m_scev_Binary<SCEVAddExpr>(Op0, Op1);
148}
149
150} // namespace SCEVPatternMatch
151} // namespace llvm
152
153#endif
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define P(N)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Class for arbitrary precision integers.
Definition: APInt.h:78
This class represents a constant integer value.
This means that we are dealing with an entirely unknown SCEV value, and only represent it as its LLVM...
This class represents an analyzed expression in the program.
Type * getType() const
Return the LLVM type of this SCEV expression.
bool isVectorTy() const
True if this is an instance of VectorType.
Definition: Type.h:270
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
cst_pred_ty< is_all_ones > m_scev_AllOnes()
Match an integer with all bits set.
SCEVUnaryExpr_match< SCEVZeroExtendExpr, Op0_t > m_scev_ZExt(const Op0_t &Op0)
cst_pred_ty< is_one > m_scev_One()
Match an integer 1.
SCEVUnaryExpr_match< SCEVTy, Op0_t > m_scev_Unary(const Op0_t &Op0)
SCEVUnaryExpr_match< SCEVSignExtendExpr, Op0_t > m_scev_SExt(const Op0_t &Op0)
cst_pred_ty< is_zero > m_scev_Zero()
Match an integer 0.
SCEVBinaryExpr_match< SCEVTy, Op0_t, Op1_t > m_scev_Binary(const Op0_t &Op0, const Op1_t &Op1)
bind_ty< const SCEVConstant > m_SCEVConstant(const SCEVConstant *&V)
bind_ty< const SCEV > m_SCEV(const SCEV *&V)
Match a SCEV, capturing it if we match.
SCEVBinaryExpr_match< SCEVAddExpr, Op0_t, Op1_t > m_scev_Add(const Op0_t &Op0, const Op1_t &Op1)
bool match(const SCEV *S, const Pattern &P)
bind_ty< const SCEVUnknown > m_SCEVUnknown(const SCEVUnknown *&V)
specificscev_ty m_Specific(const SCEV *S)
Match if we have a specific specified SCEV.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18