13#ifndef LLVM_CODEGEN_SDPATTERNMATCH_H
14#define LLVM_CODEGEN_SDPATTERNMATCH_H
23namespace SDPatternMatch {
35 : DAG(DAG), TLI(DAG ? &DAG->getTargetLoweringInfo() : nullptr) {}
38 : DAG(nullptr), TLI(TLI) {}
48 return N->getOpcode() == Opcode;
54template <
typename Pattern,
typename MatchContext>
57 return P.match(Ctx,
N);
60template <
typename Pattern,
typename MatchContext>
66template <
typename Pattern>
71template <
typename Pattern>
76template <
typename Pattern>
81template <
typename Pattern>
94 template <
typename MatchContext>
bool match(
const MatchContext &,
SDValue N) {
114 template <
typename MatchContext>
bool match(
const MatchContext &,
SDValue N) {
133 template <
typename MatchContext>
146 template <
typename MatchContext>
151 return P.
match(Ctx,
N) &&
N->hasNUsesOfValue(NumUses,
N.getResNo());
155template <
typename Pattern>
159template <
unsigned N,
typename Pattern>
176 template <
typename MatchContext>
bool match(
const MatchContext &,
SDValue N) {
191 template <
typename MatchContext>
193 assert(Ctx.getTLI() &&
"TargetLowering is required for this pattern.");
199template <
typename PredFuncT,
typename Pattern>
214 const NewMatchContext &
Ctx;
217 template <
typename OrigMatchContext>
223template <
typename MatchContext,
typename Pattern>
235 template <
typename MatchContext>
bool match(
const MatchContext &,
SDValue N) {
251 template <
typename MatchContext>
258template <
typename PredFuncT,
typename Pattern>
263template <
typename Pattern>
326template <
typename... Preds>
struct And {
327 template <
typename MatchContext>
bool match(
const MatchContext &,
SDValue N) {
332template <
typename Pred,
typename... Preds>
333struct And<Pred, Preds...> :
And<Preds...> {
335 And(
const Pred &p,
const Preds &...preds) :
And<Preds...>(preds...),
P(p) {}
337 template <
typename MatchContext>
343template <
typename... Preds>
struct Or {
344 template <
typename MatchContext>
bool match(
const MatchContext &,
SDValue N) {
349template <
typename Pred,
typename... Preds>
350struct Or<Pred, Preds...> :
Or<Preds...> {
352 Or(
const Pred &p,
const Preds &...preds) :
Or<Preds...>(preds...),
P(p) {}
354 template <
typename MatchContext>
360template <
typename Pred>
struct Not {
365 template <
typename MatchContext>
367 return !
P.match(Ctx,
N);
378template <
typename... Preds>
And<Preds...>
m_AllOf(
const Preds &...preds) {
379 return And<Preds...>(preds...);
382template <
typename... Preds>
Or<Preds...>
m_AnyOf(
const Preds &...preds) {
383 return Or<Preds...>(preds...);
386template <
typename... Preds>
auto m_NoneOf(
const Preds &...preds) {
392 template <
typename MatchContext>
396 return Ctx.getNumOperands(
N) == OpIdx;
400template <
unsigned OpIdx,
typename OpndPred,
typename... OpndPreds>
408 template <
typename MatchContext>
410 if (OpIdx < N->getNumOperands())
411 return P.match(Ctx,
N->getOperand(OpIdx)) &&
419template <
typename... OpndPreds>
420auto m_Node(
unsigned Opcode,
const OpndPreds &...preds) {
430 template <
typename MatchContext>
432 const unsigned TotalNumOps = Ctx.getNumOperands(
N);
434 for (
unsigned I = 0;
I < TotalNumOps; ++
I) {
437 EVT VT =
N->getOperand(
I).getValueType();
438 if (VT != MVT::Glue && VT != MVT::Other) {
451 template <
typename MatchContext>
453 :
Size(Ctx.getNumOperands(
N)) {}
457template <
typename T0_P,
typename T1_P,
typename T2_P,
bool Commutable =
false,
458 bool ExcludeChain =
false>
469 template <
typename MatchContext>
476 (Commutable &&
Op0.match(Ctx,
N->getOperand(EO.
FirstIndex + 1)) &&
485template <
typename T0_P,
typename T1_P,
typename T2_P>
486inline TernaryOpc_match<T0_P, T1_P, T2_P>
491template <
typename T0_P,
typename T1_P,
typename T2_P>
492inline TernaryOpc_match<T0_P, T1_P, T2_P, true, false>
498template <
typename T0_P,
typename T1_P,
typename T2_P>
499inline TernaryOpc_match<T0_P, T1_P, T2_P>
504template <
typename T0_P,
typename T1_P,
typename T2_P>
505inline TernaryOpc_match<T0_P, T1_P, T2_P>
511template <
typename LHS_P,
typename RHS_P,
bool Commutable =
false,
512 bool ExcludeChain =
false>
519 std::optional<SDNodeFlags> Flgs = std::nullopt)
522 template <
typename MatchContext>
529 (Commutable &&
LHS.match(Ctx,
N->getOperand(EO.
FirstIndex + 1)) &&
533 if (!
Flags.has_value())
538 return TmpFlags == *
Flags;
545template <
typename LHS,
typename RHS>
550template <
typename LHS,
typename RHS>
556template <
typename LHS,
typename RHS>
557inline BinaryOpc_match<LHS, RHS, false, true>
561template <
typename LHS,
typename RHS>
562inline BinaryOpc_match<LHS, RHS, true, true>
568template <
typename LHS,
typename RHS>
573template <
typename LHS,
typename RHS>
578template <
typename LHS,
typename RHS>
583template <
typename LHS,
typename RHS>
588template <
typename LHS,
typename RHS>
593template <
typename LHS,
typename RHS>
597 Flags.setDisjoint(
true);
601template <
typename LHS,
typename RHS>
606template <
typename LHS,
typename RHS>
611template <
typename LHS,
typename RHS>
616template <
typename LHS,
typename RHS>
621template <
typename LHS,
typename RHS>
626template <
typename LHS,
typename RHS>
631template <
typename LHS,
typename RHS>
635template <
typename LHS,
typename RHS>
640template <
typename LHS,
typename RHS>
644template <
typename LHS,
typename RHS>
649template <
typename LHS,
typename RHS>
654template <
typename LHS,
typename RHS>
658template <
typename LHS,
typename RHS>
663template <
typename LHS,
typename RHS>
668template <
typename LHS,
typename RHS>
673template <
typename LHS,
typename RHS>
678template <
typename LHS,
typename RHS>
683template <
typename LHS,
typename RHS>
694 std::optional<SDNodeFlags> Flgs = std::nullopt)
697 template <
typename MatchContext>
704 if (!
Flags.has_value())
709 return TmpFlags == *
Flags;
716template <
typename Opnd>
720template <
typename Opnd>
726template <
typename Opnd>
735template <
typename Opnd>
738 Flags.setNonNeg(
true);
742template <
typename Opnd>
inline auto m_SExt(
const Opnd &
Op) {
772template <
typename Opnd>
779template <
typename Opnd>
802 template <
typename MatchContext>
bool match(
const MatchContext &,
SDValue N) {
807 if (
auto *
C = dyn_cast_or_null<ConstantSDNode>(
N.getNode())) {
829 template <
typename MatchContext>
853 template <
typename MatchContext>
bool match(
const MatchContext &,
SDValue N) {
869 return ConstVal.
isOne();
873 return (ConstVal & 0x01) == 1;
892 return (ConstVal & 0x01) == 0;
908 template <
typename MatchContext>
bool match(
const MatchContext &,
SDValue N) {
909 if (
auto *
CC = dyn_cast<CondCodeSDNode>(
N.getNode())) {
934template <
typename ValTy>
940template <
typename ValTy>
This file implements a class to represent arbitrary precision integral constant values and operations...
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file describes how to lower LLVM code to machine code.
Class for arbitrary precision integers.
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
static bool isSameValue(const APInt &I1, const APInt &I2)
Determine if two APInts have the same value, after zero-extending one of them (if needed!...
bool isOne() const
Determine if this is a value of 1.
This class represents an Operation in the Expression.
MatchResult match(StringRef Buffer, const SourceMgr &SM) const
Matches the pattern string against the input buffer Buffer.
Represents one node in the SelectionDAG.
MatchContext can repurpose existing patterns to behave differently under a certain context.
const TargetLowering * getTLI() const
const SelectionDAG * getDAG() const
BasicMatchContext(const TargetLowering *TLI)
BasicMatchContext(const SelectionDAG *DAG)
bool match(SDValue N, unsigned Opcode) const
Return true if N effectively has opcode Opcode.
unsigned getNumOperands(SDValue N) const
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
BooleanContent getBooleanContents(bool isVec, bool isFloat) const
For targets without i1 registers, this gives the nature of the high-bits of boolean values held in ty...
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
@ ZeroOrOneBooleanContent
@ UndefinedBooleanContent
@ ZeroOrNegativeOneBooleanContent
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
@ C
The default llvm calling convention, compatible with C.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ ADD
Simple integer binary arithmetic operators.
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FADD
Simple binary floating point operators.
@ SIGN_EXTEND
Conversion operators.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ SHL
Shift and rotation operations.
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ VSCALE
VSCALE(IMM) - Returns the runtime scaling factor used to calculate the number of elements within a sc...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
class_match< BinaryOperator > m_BinOp()
Match an arbitrary binary operation and ignore it.
VScaleVal_match m_VScale()
Opcode_match m_Opc(unsigned Opcode)
BinaryOpc_match< LHS, RHS > m_Srl(const LHS &L, const RHS &R)
auto m_SExtLike(const Opnd &Op)
auto m_SpecificVT(EVT RefVT, const Pattern &P)
Match a specific ValueType.
BinaryOpc_match< LHS, RHS > m_Sra(const LHS &L, const RHS &R)
BinaryOpc_match< LHS, RHS > m_FRem(const LHS &L, const RHS &R)
BinaryOpc_match< LHS, RHS, true > m_Mul(const LHS &L, const RHS &R)
BinaryOpc_match< LHS, RHS, true > m_Or(const LHS &L, const RHS &R)
BinaryOpc_match< LHS, RHS, false, true > m_ChainedBinOp(unsigned Opc, const LHS &L, const RHS &R)
BinaryOpc_match< LHS, RHS, true > m_SMin(const LHS &L, const RHS &R)
UnaryOpc_match< Opnd > m_Trunc(const Opnd &Op)
BinaryOpc_match< LHS, RHS > m_FSub(const LHS &L, const RHS &R)
auto m_AddLike(const LHS &L, const RHS &R)
BinaryOpc_match< LHS, RHS > m_URem(const LHS &L, const RHS &R)
Or< Preds... > m_AnyOf(const Preds &...preds)
BinaryOpc_match< LHS, RHS, true, true > m_c_ChainedBinOp(unsigned Opc, const LHS &L, const RHS &R)
Or< UnaryOpc_match< Opnd >, Opnd > m_TruncOrSelf(const Opnd &Op)
Match a trunc or identity Allows to peek through optional truncations.
UnaryOpc_match< Opnd > m_NNegZExt(const Opnd &Op)
And< Preds... > m_AllOf(const Preds &...preds)
auto m_ScalableVectorVT()
BinaryOpc_match< LHS, RHS > m_FDiv(const LHS &L, const RHS &R)
auto m_LegalType(const Pattern &P)
Match legal ValueTypes based on the information provided by TargetLowering.
BinaryOpc_match< LHS, RHS, true > m_UMin(const LHS &L, const RHS &R)
Not< Pred > m_Unless(const Pred &P)
Match if the inner pattern does NOT match.
BinaryOpc_match< LHS, RHS, true > m_SMax(const LHS &L, const RHS &R)
NUses_match< N, Value_match > m_NUses()
UnaryOpc_match< Opnd, true > m_ChainedUnaryOp(unsigned Opc, const Opnd &Op)
SpecificInt_match m_SpecificInt(APInt V)
Match a specific integer constant or constant splat value.
UnaryOpc_match< Opnd > m_FPToUI(const Opnd &Op)
Value_match m_Specific(SDValue N)
UnaryOpc_match< Opnd > m_BitReverse(const Opnd &Op)
BinaryOpc_match< LHS, RHS, true > m_And(const LHS &L, const RHS &R)
ValueType_bind m_VT(EVT &VT)
Retreive the ValueType of the current SDValue.
BinaryOpc_match< LHS, RHS > m_Sub(const LHS &L, const RHS &R)
TernaryOpc_match< T0_P, T1_P, T2_P > m_SetCC(const T0_P &LHS, const T1_P &RHS, const T2_P &CC)
BinaryOpc_match< ValTy, AllOnes_match, true > m_Not(const ValTy &V)
Match a Not as a xor(v, -1) or xor(-1, v)
SpecificInt_match m_One()
SpecificInt_match m_Zero()
UnaryOpc_match< Opnd > m_AnyExt(const Opnd &Op)
auto m_Node(unsigned Opcode, const OpndPreds &...preds)
BinaryOpc_match< LHS, RHS, true > m_DisjointOr(const LHS &L, const RHS &R)
TernaryOpc_match< T0_P, T1_P, T2_P > m_Select(const T0_P &Cond, const T1_P &T, const T2_P &F)
BinaryOpc_match< LHS, RHS > m_UDiv(const LHS &L, const RHS &R)
BinaryOpc_match< SpecificInt_match, ValTy > m_Neg(const ValTy &V)
Match a negate as a sub(0, v)
BinaryOpc_match< LHS, RHS > m_SDiv(const LHS &L, const RHS &R)
SwitchContext< MatchContext, Pattern > m_Context(const MatchContext &Ctx, Pattern &&P)
BinaryOpc_match< LHS, RHS, true > m_FAdd(const LHS &L, const RHS &R)
Or< UnaryOpc_match< Opnd >, Opnd > m_AExtOrSelf(const Opnd &Op)
Match a aext or identity Allows to peek through optional extensions.
BinaryOpc_match< LHS, RHS, true > m_UMax(const LHS &L, const RHS &R)
TernaryOpc_match< T0_P, T1_P, T2_P > m_VSelect(const T0_P &Cond, const T1_P &T, const T2_P &F)
bool sd_match(SDNode *N, const SelectionDAG *DAG, Pattern &&P)
UnaryOpc_match< Opnd > m_UnaryOp(unsigned Opc, const Opnd &Op)
auto m_SExt(const Opnd &Op)
BinaryOpc_match< LHS, RHS, true > m_Xor(const LHS &L, const RHS &R)
BinaryOpc_match< LHS, RHS > m_SRem(const LHS &L, const RHS &R)
auto m_NoneOf(const Preds &...preds)
CondCode_match m_SpecificCondCode(ISD::CondCode CC)
Match a conditional code SDNode with a specific ISD::CondCode.
UnaryOpc_match< Opnd > m_ZExt(const Opnd &Op)
Value_match m_Value()
Match any valid SDValue.
BinaryOpc_match< LHS, RHS, true > m_Add(const LHS &L, const RHS &R)
BinaryOpc_match< LHS, RHS > m_Shl(const LHS &L, const RHS &R)
auto m_LegalOp(const Pattern &P)
Match legal SDNodes based on the information provided by TargetLowering.
auto m_True()
Match true boolean value based on the information provided by TargetLowering.
UnaryOpc_match< Opnd > m_FPToSI(const Opnd &Op)
NUses_match< 1, Value_match > m_OneUse()
auto m_False()
Match false boolean value based on the information provided by TargetLowering.
auto m_SExtOrSelf(const Opnd &Op)
Match a sext or identity Allows to peek through optional extensions.
CondCode_match m_CondCode()
Match any conditional code SDNode.
BinaryOpc_match< LHS, RHS, true > m_c_BinOp(unsigned Opc, const LHS &L, const RHS &R)
DeferredValue_match m_Deferred(SDValue &V)
Similar to m_Specific, but the specific value to match is determined by another sub-pattern in the sa...
TernaryOpc_match< T0_P, T1_P, T2_P, true, false > m_c_SetCC(const T0_P &LHS, const T1_P &RHS, const T2_P &CC)
AllOnes_match m_AllOnes()
bool sd_context_match(SDValue N, const MatchContext &Ctx, Pattern &&P)
BinaryOpc_match< LHS, RHS, true > m_FMul(const LHS &L, const RHS &R)
ConstantInt_match m_ConstInt()
Match any interger constants or splat of an integer constant.
auto m_ZExtOrSelf(const Opnd &Op)
Match a zext or identity Allows to peek through optional extensions.
This is an optimization pass for GlobalISel generic memory operations.
bool isAllOnesOrAllOnesSplat(const MachineInstr &MI, const MachineRegisterInfo &MRI, bool AllowUndefs=false)
Return true if the value is a constant -1 integer or a splatted vector of a constant -1 integer (with...
DWARFExpression::Operation Op
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Implement std::hash so that hash_code can be used in STL containers.
These are IR-level optimization flags that may be propagated to SDNodes.
void intersectWith(const SDNodeFlags Flags)
Clear any flags in this flag set that aren't also set in Flags.
bool match(const MatchContext &, SDValue N)
And(const Pred &p, const Preds &...preds)
bool match(const MatchContext &Ctx, SDValue N)
bool match(const MatchContext &, SDValue N)
bool match(const MatchContext &Ctx, SDValue N)
std::optional< SDNodeFlags > Flags
BinaryOpc_match(unsigned Opc, const LHS_P &L, const RHS_P &R, std::optional< SDNodeFlags > Flgs=std::nullopt)
CondCode_match(ISD::CondCode CC)
bool match(const MatchContext &, SDValue N)
CondCode_match(ISD::CondCode *CC)
std::optional< ISD::CondCode > CCToMatch
ConstantInt_match(APInt *V)
bool match(const MatchContext &, SDValue N)
bool match(const MatchContext &, SDValue N)
DeferredValue_match(SDValue &Match)
EffectiveOperands(SDValue N, const MatchContext &Ctx)
Provide number of operands that are not chain or glue, as well as the first index of such operand.
EffectiveOperands(SDValue N, const MatchContext &Ctx)
bool match(const MatchContext &Ctx, SDValue N)
NUses_match(const Pattern &P)
bool match(const MatchContext &Ctx, SDValue N)
bool match(const MatchContext &Ctx, SDValue N)
Opcode_match(unsigned Opc)
Operands_match(const OpndPred &p, const OpndPreds &...preds)
bool match(const MatchContext &Ctx, SDValue N)
bool match(const MatchContext &Ctx, SDValue N)
Or(const Pred &p, const Preds &...preds)
bool match(const MatchContext &Ctx, SDValue N)
bool match(const MatchContext &, SDValue N)
SpecificInt_match(APInt APV)
bool match(const MatchContext &Ctx, SDValue N)
Switch to a different MatchContext for subsequent patterns.
const NewMatchContext & Ctx
bool match(const OrigMatchContext &, SDValue N)
bool match(const MatchContext &Ctx, SDValue N)
TLI_pred_match(const PredFuncT &Pred, const Pattern &P)
bool match(const MatchContext &Ctx, SDValue N)
TernaryOpc_match(unsigned Opc, const T0_P &Op0, const T1_P &Op1, const T2_P &Op2)
std::optional< SDNodeFlags > Flags
UnaryOpc_match(unsigned Opc, const Opnd_P &Op, std::optional< SDNodeFlags > Flgs=std::nullopt)
bool match(const MatchContext &Ctx, SDValue N)
bool match(const MatchContext &, SDValue N)
ValueType_bind(EVT &Bind)
ValueType_match(const PredFuncT &Pred, const Pattern &P)
bool match(const MatchContext &Ctx, SDValue N)
bool match(const MatchContext &, SDValue N)
bool match(const MatchContext &, SDValue N)
Value_match(SDValue Match)