1*0fca6ea1SDimitry Andric //===- DAGISelMatcher.h - Representation of DAG pattern matcher -*- C++ -*-===// 2*0fca6ea1SDimitry Andric // 3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0fca6ea1SDimitry Andric // 7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 8*0fca6ea1SDimitry Andric 9*0fca6ea1SDimitry Andric #ifndef LLVM_UTILS_TABLEGEN_DAGISELMATCHER_H 10*0fca6ea1SDimitry Andric #define LLVM_UTILS_TABLEGEN_DAGISELMATCHER_H 11*0fca6ea1SDimitry Andric 12*0fca6ea1SDimitry Andric #include "llvm/ADT/ArrayRef.h" 13*0fca6ea1SDimitry Andric #include "llvm/ADT/SmallVector.h" 14*0fca6ea1SDimitry Andric #include "llvm/ADT/StringRef.h" 15*0fca6ea1SDimitry Andric #include "llvm/CodeGenTypes/MachineValueType.h" 16*0fca6ea1SDimitry Andric #include "llvm/Support/Casting.h" 17*0fca6ea1SDimitry Andric #include <cassert> 18*0fca6ea1SDimitry Andric #include <cstddef> 19*0fca6ea1SDimitry Andric #include <memory> 20*0fca6ea1SDimitry Andric #include <string> 21*0fca6ea1SDimitry Andric #include <utility> 22*0fca6ea1SDimitry Andric 23*0fca6ea1SDimitry Andric namespace llvm { 24*0fca6ea1SDimitry Andric class CodeGenRegister; 25*0fca6ea1SDimitry Andric class CodeGenDAGPatterns; 26*0fca6ea1SDimitry Andric class CodeGenInstruction; 27*0fca6ea1SDimitry Andric class Matcher; 28*0fca6ea1SDimitry Andric class PatternToMatch; 29*0fca6ea1SDimitry Andric class raw_ostream; 30*0fca6ea1SDimitry Andric class ComplexPattern; 31*0fca6ea1SDimitry Andric class Record; 32*0fca6ea1SDimitry Andric class SDNodeInfo; 33*0fca6ea1SDimitry Andric class TreePredicateFn; 34*0fca6ea1SDimitry Andric class TreePattern; 35*0fca6ea1SDimitry Andric 36*0fca6ea1SDimitry Andric Matcher *ConvertPatternToMatcher(const PatternToMatch &Pattern, 37*0fca6ea1SDimitry Andric unsigned Variant, 38*0fca6ea1SDimitry Andric const CodeGenDAGPatterns &CGP); 39*0fca6ea1SDimitry Andric void OptimizeMatcher(std::unique_ptr<Matcher> &Matcher, 40*0fca6ea1SDimitry Andric const CodeGenDAGPatterns &CGP); 41*0fca6ea1SDimitry Andric void EmitMatcherTable(Matcher *Matcher, const CodeGenDAGPatterns &CGP, 42*0fca6ea1SDimitry Andric raw_ostream &OS); 43*0fca6ea1SDimitry Andric 44*0fca6ea1SDimitry Andric /// Matcher - Base class for all the DAG ISel Matcher representation 45*0fca6ea1SDimitry Andric /// nodes. 46*0fca6ea1SDimitry Andric class Matcher { 47*0fca6ea1SDimitry Andric // The next matcher node that is executed after this one. Null if this is 48*0fca6ea1SDimitry Andric // the last stage of a match. 49*0fca6ea1SDimitry Andric std::unique_ptr<Matcher> Next; 50*0fca6ea1SDimitry Andric size_t Size = 0; // Size in bytes of matcher and all its children (if any). 51*0fca6ea1SDimitry Andric virtual void anchor(); 52*0fca6ea1SDimitry Andric 53*0fca6ea1SDimitry Andric public: 54*0fca6ea1SDimitry Andric enum KindTy { 55*0fca6ea1SDimitry Andric // Matcher state manipulation. 56*0fca6ea1SDimitry Andric Scope, // Push a checking scope. 57*0fca6ea1SDimitry Andric RecordNode, // Record the current node. 58*0fca6ea1SDimitry Andric RecordChild, // Record a child of the current node. 59*0fca6ea1SDimitry Andric RecordMemRef, // Record the memref in the current node. 60*0fca6ea1SDimitry Andric CaptureGlueInput, // If the current node has an input glue, save it. 61*0fca6ea1SDimitry Andric MoveChild, // Move current node to specified child. 62*0fca6ea1SDimitry Andric MoveSibling, // Move current node to specified sibling. 63*0fca6ea1SDimitry Andric MoveParent, // Move current node to parent. 64*0fca6ea1SDimitry Andric 65*0fca6ea1SDimitry Andric // Predicate checking. 66*0fca6ea1SDimitry Andric CheckSame, // Fail if not same as prev match. 67*0fca6ea1SDimitry Andric CheckChildSame, // Fail if child not same as prev match. 68*0fca6ea1SDimitry Andric CheckPatternPredicate, 69*0fca6ea1SDimitry Andric CheckPredicate, // Fail if node predicate fails. 70*0fca6ea1SDimitry Andric CheckOpcode, // Fail if not opcode. 71*0fca6ea1SDimitry Andric SwitchOpcode, // Dispatch based on opcode. 72*0fca6ea1SDimitry Andric CheckType, // Fail if not correct type. 73*0fca6ea1SDimitry Andric SwitchType, // Dispatch based on type. 74*0fca6ea1SDimitry Andric CheckChildType, // Fail if child has wrong type. 75*0fca6ea1SDimitry Andric CheckInteger, // Fail if wrong val. 76*0fca6ea1SDimitry Andric CheckChildInteger, // Fail if child is wrong val. 77*0fca6ea1SDimitry Andric CheckCondCode, // Fail if not condcode. 78*0fca6ea1SDimitry Andric CheckChild2CondCode, // Fail if child is wrong condcode. 79*0fca6ea1SDimitry Andric CheckValueType, 80*0fca6ea1SDimitry Andric CheckComplexPat, 81*0fca6ea1SDimitry Andric CheckAndImm, 82*0fca6ea1SDimitry Andric CheckOrImm, 83*0fca6ea1SDimitry Andric CheckImmAllOnesV, 84*0fca6ea1SDimitry Andric CheckImmAllZerosV, 85*0fca6ea1SDimitry Andric CheckFoldableChainNode, 86*0fca6ea1SDimitry Andric 87*0fca6ea1SDimitry Andric // Node creation/emisssion. 88*0fca6ea1SDimitry Andric EmitInteger, // Create a TargetConstant 89*0fca6ea1SDimitry Andric EmitStringInteger, // Create a TargetConstant from a string. 90*0fca6ea1SDimitry Andric EmitRegister, // Create a register. 91*0fca6ea1SDimitry Andric EmitConvertToTarget, // Convert a imm/fpimm to target imm/fpimm 92*0fca6ea1SDimitry Andric EmitMergeInputChains, // Merge together a chains for an input. 93*0fca6ea1SDimitry Andric EmitCopyToReg, // Emit a copytoreg into a physreg. 94*0fca6ea1SDimitry Andric EmitNode, // Create a DAG node 95*0fca6ea1SDimitry Andric EmitNodeXForm, // Run a SDNodeXForm 96*0fca6ea1SDimitry Andric CompleteMatch, // Finish a match and update the results. 97*0fca6ea1SDimitry Andric MorphNodeTo, // Build a node, finish a match and update results. 98*0fca6ea1SDimitry Andric 99*0fca6ea1SDimitry Andric // Highest enum value; watch out when adding more. 100*0fca6ea1SDimitry Andric HighestKind = MorphNodeTo 101*0fca6ea1SDimitry Andric }; 102*0fca6ea1SDimitry Andric const KindTy Kind; 103*0fca6ea1SDimitry Andric 104*0fca6ea1SDimitry Andric protected: 105*0fca6ea1SDimitry Andric Matcher(KindTy K) : Kind(K) {} 106*0fca6ea1SDimitry Andric 107*0fca6ea1SDimitry Andric public: 108*0fca6ea1SDimitry Andric virtual ~Matcher() {} 109*0fca6ea1SDimitry Andric 110*0fca6ea1SDimitry Andric unsigned getSize() const { return Size; } 111*0fca6ea1SDimitry Andric void setSize(unsigned sz) { Size = sz; } 112*0fca6ea1SDimitry Andric KindTy getKind() const { return Kind; } 113*0fca6ea1SDimitry Andric 114*0fca6ea1SDimitry Andric Matcher *getNext() { return Next.get(); } 115*0fca6ea1SDimitry Andric const Matcher *getNext() const { return Next.get(); } 116*0fca6ea1SDimitry Andric void setNext(Matcher *C) { Next.reset(C); } 117*0fca6ea1SDimitry Andric Matcher *takeNext() { return Next.release(); } 118*0fca6ea1SDimitry Andric 119*0fca6ea1SDimitry Andric std::unique_ptr<Matcher> &getNextPtr() { return Next; } 120*0fca6ea1SDimitry Andric 121*0fca6ea1SDimitry Andric bool isEqual(const Matcher *M) const { 122*0fca6ea1SDimitry Andric if (getKind() != M->getKind()) 123*0fca6ea1SDimitry Andric return false; 124*0fca6ea1SDimitry Andric return isEqualImpl(M); 125*0fca6ea1SDimitry Andric } 126*0fca6ea1SDimitry Andric 127*0fca6ea1SDimitry Andric /// isSimplePredicateNode - Return true if this is a simple predicate that 128*0fca6ea1SDimitry Andric /// operates on the node or its children without potential side effects or a 129*0fca6ea1SDimitry Andric /// change of the current node. 130*0fca6ea1SDimitry Andric bool isSimplePredicateNode() const { 131*0fca6ea1SDimitry Andric switch (getKind()) { 132*0fca6ea1SDimitry Andric default: 133*0fca6ea1SDimitry Andric return false; 134*0fca6ea1SDimitry Andric case CheckSame: 135*0fca6ea1SDimitry Andric case CheckChildSame: 136*0fca6ea1SDimitry Andric case CheckPatternPredicate: 137*0fca6ea1SDimitry Andric case CheckPredicate: 138*0fca6ea1SDimitry Andric case CheckOpcode: 139*0fca6ea1SDimitry Andric case CheckType: 140*0fca6ea1SDimitry Andric case CheckChildType: 141*0fca6ea1SDimitry Andric case CheckInteger: 142*0fca6ea1SDimitry Andric case CheckChildInteger: 143*0fca6ea1SDimitry Andric case CheckCondCode: 144*0fca6ea1SDimitry Andric case CheckChild2CondCode: 145*0fca6ea1SDimitry Andric case CheckValueType: 146*0fca6ea1SDimitry Andric case CheckAndImm: 147*0fca6ea1SDimitry Andric case CheckOrImm: 148*0fca6ea1SDimitry Andric case CheckImmAllOnesV: 149*0fca6ea1SDimitry Andric case CheckImmAllZerosV: 150*0fca6ea1SDimitry Andric case CheckFoldableChainNode: 151*0fca6ea1SDimitry Andric return true; 152*0fca6ea1SDimitry Andric } 153*0fca6ea1SDimitry Andric } 154*0fca6ea1SDimitry Andric 155*0fca6ea1SDimitry Andric /// isSimplePredicateOrRecordNode - Return true if this is a record node or 156*0fca6ea1SDimitry Andric /// a simple predicate. 157*0fca6ea1SDimitry Andric bool isSimplePredicateOrRecordNode() const { 158*0fca6ea1SDimitry Andric return isSimplePredicateNode() || getKind() == RecordNode || 159*0fca6ea1SDimitry Andric getKind() == RecordChild; 160*0fca6ea1SDimitry Andric } 161*0fca6ea1SDimitry Andric 162*0fca6ea1SDimitry Andric /// unlinkNode - Unlink the specified node from this chain. If Other == 163*0fca6ea1SDimitry Andric /// this, we unlink the next pointer and return it. Otherwise we unlink 164*0fca6ea1SDimitry Andric /// Other from the list and return this. 165*0fca6ea1SDimitry Andric Matcher *unlinkNode(Matcher *Other); 166*0fca6ea1SDimitry Andric 167*0fca6ea1SDimitry Andric /// canMoveBefore - Return true if this matcher is the same as Other, or if 168*0fca6ea1SDimitry Andric /// we can move this matcher past all of the nodes in-between Other and this 169*0fca6ea1SDimitry Andric /// node. Other must be equal to or before this. 170*0fca6ea1SDimitry Andric bool canMoveBefore(const Matcher *Other) const; 171*0fca6ea1SDimitry Andric 172*0fca6ea1SDimitry Andric /// canMoveBeforeNode - Return true if it is safe to move the current 173*0fca6ea1SDimitry Andric /// matcher across the specified one. 174*0fca6ea1SDimitry Andric bool canMoveBeforeNode(const Matcher *Other) const; 175*0fca6ea1SDimitry Andric 176*0fca6ea1SDimitry Andric /// isContradictory - Return true of these two matchers could never match on 177*0fca6ea1SDimitry Andric /// the same node. 178*0fca6ea1SDimitry Andric bool isContradictory(const Matcher *Other) const { 179*0fca6ea1SDimitry Andric // Since this predicate is reflexive, we canonicalize the ordering so that 180*0fca6ea1SDimitry Andric // we always match a node against nodes with kinds that are greater or 181*0fca6ea1SDimitry Andric // equal to them. For example, we'll pass in a CheckType node as an 182*0fca6ea1SDimitry Andric // argument to the CheckOpcode method, not the other way around. 183*0fca6ea1SDimitry Andric if (getKind() < Other->getKind()) 184*0fca6ea1SDimitry Andric return isContradictoryImpl(Other); 185*0fca6ea1SDimitry Andric return Other->isContradictoryImpl(this); 186*0fca6ea1SDimitry Andric } 187*0fca6ea1SDimitry Andric 188*0fca6ea1SDimitry Andric void print(raw_ostream &OS, unsigned indent = 0) const; 189*0fca6ea1SDimitry Andric void printOne(raw_ostream &OS) const; 190*0fca6ea1SDimitry Andric void dump() const; 191*0fca6ea1SDimitry Andric 192*0fca6ea1SDimitry Andric protected: 193*0fca6ea1SDimitry Andric virtual void printImpl(raw_ostream &OS, unsigned indent) const = 0; 194*0fca6ea1SDimitry Andric virtual bool isEqualImpl(const Matcher *M) const = 0; 195*0fca6ea1SDimitry Andric virtual bool isContradictoryImpl(const Matcher *M) const { return false; } 196*0fca6ea1SDimitry Andric }; 197*0fca6ea1SDimitry Andric 198*0fca6ea1SDimitry Andric /// ScopeMatcher - This attempts to match each of its children to find the first 199*0fca6ea1SDimitry Andric /// one that successfully matches. If one child fails, it tries the next child. 200*0fca6ea1SDimitry Andric /// If none of the children match then this check fails. It never has a 'next'. 201*0fca6ea1SDimitry Andric class ScopeMatcher : public Matcher { 202*0fca6ea1SDimitry Andric SmallVector<Matcher *, 4> Children; 203*0fca6ea1SDimitry Andric 204*0fca6ea1SDimitry Andric public: 205*0fca6ea1SDimitry Andric ScopeMatcher(SmallVectorImpl<Matcher *> &&children) 206*0fca6ea1SDimitry Andric : Matcher(Scope), Children(std::move(children)) {} 207*0fca6ea1SDimitry Andric ~ScopeMatcher() override; 208*0fca6ea1SDimitry Andric 209*0fca6ea1SDimitry Andric unsigned getNumChildren() const { return Children.size(); } 210*0fca6ea1SDimitry Andric 211*0fca6ea1SDimitry Andric Matcher *getChild(unsigned i) { return Children[i]; } 212*0fca6ea1SDimitry Andric const Matcher *getChild(unsigned i) const { return Children[i]; } 213*0fca6ea1SDimitry Andric 214*0fca6ea1SDimitry Andric void resetChild(unsigned i, Matcher *N) { 215*0fca6ea1SDimitry Andric delete Children[i]; 216*0fca6ea1SDimitry Andric Children[i] = N; 217*0fca6ea1SDimitry Andric } 218*0fca6ea1SDimitry Andric 219*0fca6ea1SDimitry Andric Matcher *takeChild(unsigned i) { 220*0fca6ea1SDimitry Andric Matcher *Res = Children[i]; 221*0fca6ea1SDimitry Andric Children[i] = nullptr; 222*0fca6ea1SDimitry Andric return Res; 223*0fca6ea1SDimitry Andric } 224*0fca6ea1SDimitry Andric 225*0fca6ea1SDimitry Andric void setNumChildren(unsigned NC) { 226*0fca6ea1SDimitry Andric if (NC < Children.size()) { 227*0fca6ea1SDimitry Andric // delete any children we're about to lose pointers to. 228*0fca6ea1SDimitry Andric for (unsigned i = NC, e = Children.size(); i != e; ++i) 229*0fca6ea1SDimitry Andric delete Children[i]; 230*0fca6ea1SDimitry Andric } 231*0fca6ea1SDimitry Andric Children.resize(NC); 232*0fca6ea1SDimitry Andric } 233*0fca6ea1SDimitry Andric 234*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { return N->getKind() == Scope; } 235*0fca6ea1SDimitry Andric 236*0fca6ea1SDimitry Andric private: 237*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 238*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { return false; } 239*0fca6ea1SDimitry Andric }; 240*0fca6ea1SDimitry Andric 241*0fca6ea1SDimitry Andric /// RecordMatcher - Save the current node in the operand list. 242*0fca6ea1SDimitry Andric class RecordMatcher : public Matcher { 243*0fca6ea1SDimitry Andric /// WhatFor - This is a string indicating why we're recording this. This 244*0fca6ea1SDimitry Andric /// should only be used for comment generation not anything semantic. 245*0fca6ea1SDimitry Andric std::string WhatFor; 246*0fca6ea1SDimitry Andric 247*0fca6ea1SDimitry Andric /// ResultNo - The slot number in the RecordedNodes vector that this will be, 248*0fca6ea1SDimitry Andric /// just printed as a comment. 249*0fca6ea1SDimitry Andric unsigned ResultNo; 250*0fca6ea1SDimitry Andric 251*0fca6ea1SDimitry Andric public: 252*0fca6ea1SDimitry Andric RecordMatcher(const std::string &whatfor, unsigned resultNo) 253*0fca6ea1SDimitry Andric : Matcher(RecordNode), WhatFor(whatfor), ResultNo(resultNo) {} 254*0fca6ea1SDimitry Andric 255*0fca6ea1SDimitry Andric const std::string &getWhatFor() const { return WhatFor; } 256*0fca6ea1SDimitry Andric unsigned getResultNo() const { return ResultNo; } 257*0fca6ea1SDimitry Andric 258*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { return N->getKind() == RecordNode; } 259*0fca6ea1SDimitry Andric 260*0fca6ea1SDimitry Andric private: 261*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 262*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { return true; } 263*0fca6ea1SDimitry Andric }; 264*0fca6ea1SDimitry Andric 265*0fca6ea1SDimitry Andric /// RecordChildMatcher - Save a numbered child of the current node, or fail 266*0fca6ea1SDimitry Andric /// the match if it doesn't exist. This is logically equivalent to: 267*0fca6ea1SDimitry Andric /// MoveChild N + RecordNode + MoveParent. 268*0fca6ea1SDimitry Andric class RecordChildMatcher : public Matcher { 269*0fca6ea1SDimitry Andric unsigned ChildNo; 270*0fca6ea1SDimitry Andric 271*0fca6ea1SDimitry Andric /// WhatFor - This is a string indicating why we're recording this. This 272*0fca6ea1SDimitry Andric /// should only be used for comment generation not anything semantic. 273*0fca6ea1SDimitry Andric std::string WhatFor; 274*0fca6ea1SDimitry Andric 275*0fca6ea1SDimitry Andric /// ResultNo - The slot number in the RecordedNodes vector that this will be, 276*0fca6ea1SDimitry Andric /// just printed as a comment. 277*0fca6ea1SDimitry Andric unsigned ResultNo; 278*0fca6ea1SDimitry Andric 279*0fca6ea1SDimitry Andric public: 280*0fca6ea1SDimitry Andric RecordChildMatcher(unsigned childno, const std::string &whatfor, 281*0fca6ea1SDimitry Andric unsigned resultNo) 282*0fca6ea1SDimitry Andric : Matcher(RecordChild), ChildNo(childno), WhatFor(whatfor), 283*0fca6ea1SDimitry Andric ResultNo(resultNo) {} 284*0fca6ea1SDimitry Andric 285*0fca6ea1SDimitry Andric unsigned getChildNo() const { return ChildNo; } 286*0fca6ea1SDimitry Andric const std::string &getWhatFor() const { return WhatFor; } 287*0fca6ea1SDimitry Andric unsigned getResultNo() const { return ResultNo; } 288*0fca6ea1SDimitry Andric 289*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { return N->getKind() == RecordChild; } 290*0fca6ea1SDimitry Andric 291*0fca6ea1SDimitry Andric private: 292*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 293*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { 294*0fca6ea1SDimitry Andric return cast<RecordChildMatcher>(M)->getChildNo() == getChildNo(); 295*0fca6ea1SDimitry Andric } 296*0fca6ea1SDimitry Andric }; 297*0fca6ea1SDimitry Andric 298*0fca6ea1SDimitry Andric /// RecordMemRefMatcher - Save the current node's memref. 299*0fca6ea1SDimitry Andric class RecordMemRefMatcher : public Matcher { 300*0fca6ea1SDimitry Andric public: 301*0fca6ea1SDimitry Andric RecordMemRefMatcher() : Matcher(RecordMemRef) {} 302*0fca6ea1SDimitry Andric 303*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { return N->getKind() == RecordMemRef; } 304*0fca6ea1SDimitry Andric 305*0fca6ea1SDimitry Andric private: 306*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 307*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { return true; } 308*0fca6ea1SDimitry Andric }; 309*0fca6ea1SDimitry Andric 310*0fca6ea1SDimitry Andric /// CaptureGlueInputMatcher - If the current record has a glue input, record 311*0fca6ea1SDimitry Andric /// it so that it is used as an input to the generated code. 312*0fca6ea1SDimitry Andric class CaptureGlueInputMatcher : public Matcher { 313*0fca6ea1SDimitry Andric public: 314*0fca6ea1SDimitry Andric CaptureGlueInputMatcher() : Matcher(CaptureGlueInput) {} 315*0fca6ea1SDimitry Andric 316*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { 317*0fca6ea1SDimitry Andric return N->getKind() == CaptureGlueInput; 318*0fca6ea1SDimitry Andric } 319*0fca6ea1SDimitry Andric 320*0fca6ea1SDimitry Andric private: 321*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 322*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { return true; } 323*0fca6ea1SDimitry Andric }; 324*0fca6ea1SDimitry Andric 325*0fca6ea1SDimitry Andric /// MoveChildMatcher - This tells the interpreter to move into the 326*0fca6ea1SDimitry Andric /// specified child node. 327*0fca6ea1SDimitry Andric class MoveChildMatcher : public Matcher { 328*0fca6ea1SDimitry Andric unsigned ChildNo; 329*0fca6ea1SDimitry Andric 330*0fca6ea1SDimitry Andric public: 331*0fca6ea1SDimitry Andric MoveChildMatcher(unsigned childNo) : Matcher(MoveChild), ChildNo(childNo) {} 332*0fca6ea1SDimitry Andric 333*0fca6ea1SDimitry Andric unsigned getChildNo() const { return ChildNo; } 334*0fca6ea1SDimitry Andric 335*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { return N->getKind() == MoveChild; } 336*0fca6ea1SDimitry Andric 337*0fca6ea1SDimitry Andric private: 338*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 339*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { 340*0fca6ea1SDimitry Andric return cast<MoveChildMatcher>(M)->getChildNo() == getChildNo(); 341*0fca6ea1SDimitry Andric } 342*0fca6ea1SDimitry Andric }; 343*0fca6ea1SDimitry Andric 344*0fca6ea1SDimitry Andric /// MoveSiblingMatcher - This tells the interpreter to move into the 345*0fca6ea1SDimitry Andric /// specified sibling node. 346*0fca6ea1SDimitry Andric class MoveSiblingMatcher : public Matcher { 347*0fca6ea1SDimitry Andric unsigned SiblingNo; 348*0fca6ea1SDimitry Andric 349*0fca6ea1SDimitry Andric public: 350*0fca6ea1SDimitry Andric MoveSiblingMatcher(unsigned SiblingNo) 351*0fca6ea1SDimitry Andric : Matcher(MoveSibling), SiblingNo(SiblingNo) {} 352*0fca6ea1SDimitry Andric 353*0fca6ea1SDimitry Andric unsigned getSiblingNo() const { return SiblingNo; } 354*0fca6ea1SDimitry Andric 355*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { return N->getKind() == MoveSibling; } 356*0fca6ea1SDimitry Andric 357*0fca6ea1SDimitry Andric private: 358*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned Indent) const override; 359*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { 360*0fca6ea1SDimitry Andric return cast<MoveSiblingMatcher>(M)->getSiblingNo() == getSiblingNo(); 361*0fca6ea1SDimitry Andric } 362*0fca6ea1SDimitry Andric }; 363*0fca6ea1SDimitry Andric 364*0fca6ea1SDimitry Andric /// MoveParentMatcher - This tells the interpreter to move to the parent 365*0fca6ea1SDimitry Andric /// of the current node. 366*0fca6ea1SDimitry Andric class MoveParentMatcher : public Matcher { 367*0fca6ea1SDimitry Andric public: 368*0fca6ea1SDimitry Andric MoveParentMatcher() : Matcher(MoveParent) {} 369*0fca6ea1SDimitry Andric 370*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { return N->getKind() == MoveParent; } 371*0fca6ea1SDimitry Andric 372*0fca6ea1SDimitry Andric private: 373*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 374*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { return true; } 375*0fca6ea1SDimitry Andric }; 376*0fca6ea1SDimitry Andric 377*0fca6ea1SDimitry Andric /// CheckSameMatcher - This checks to see if this node is exactly the same 378*0fca6ea1SDimitry Andric /// node as the specified match that was recorded with 'Record'. This is used 379*0fca6ea1SDimitry Andric /// when patterns have the same name in them, like '(mul GPR:$in, GPR:$in)'. 380*0fca6ea1SDimitry Andric class CheckSameMatcher : public Matcher { 381*0fca6ea1SDimitry Andric unsigned MatchNumber; 382*0fca6ea1SDimitry Andric 383*0fca6ea1SDimitry Andric public: 384*0fca6ea1SDimitry Andric CheckSameMatcher(unsigned matchnumber) 385*0fca6ea1SDimitry Andric : Matcher(CheckSame), MatchNumber(matchnumber) {} 386*0fca6ea1SDimitry Andric 387*0fca6ea1SDimitry Andric unsigned getMatchNumber() const { return MatchNumber; } 388*0fca6ea1SDimitry Andric 389*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { return N->getKind() == CheckSame; } 390*0fca6ea1SDimitry Andric 391*0fca6ea1SDimitry Andric private: 392*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 393*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { 394*0fca6ea1SDimitry Andric return cast<CheckSameMatcher>(M)->getMatchNumber() == getMatchNumber(); 395*0fca6ea1SDimitry Andric } 396*0fca6ea1SDimitry Andric }; 397*0fca6ea1SDimitry Andric 398*0fca6ea1SDimitry Andric /// CheckChildSameMatcher - This checks to see if child node is exactly the same 399*0fca6ea1SDimitry Andric /// node as the specified match that was recorded with 'Record'. This is used 400*0fca6ea1SDimitry Andric /// when patterns have the same name in them, like '(mul GPR:$in, GPR:$in)'. 401*0fca6ea1SDimitry Andric class CheckChildSameMatcher : public Matcher { 402*0fca6ea1SDimitry Andric unsigned ChildNo; 403*0fca6ea1SDimitry Andric unsigned MatchNumber; 404*0fca6ea1SDimitry Andric 405*0fca6ea1SDimitry Andric public: 406*0fca6ea1SDimitry Andric CheckChildSameMatcher(unsigned childno, unsigned matchnumber) 407*0fca6ea1SDimitry Andric : Matcher(CheckChildSame), ChildNo(childno), MatchNumber(matchnumber) {} 408*0fca6ea1SDimitry Andric 409*0fca6ea1SDimitry Andric unsigned getChildNo() const { return ChildNo; } 410*0fca6ea1SDimitry Andric unsigned getMatchNumber() const { return MatchNumber; } 411*0fca6ea1SDimitry Andric 412*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { 413*0fca6ea1SDimitry Andric return N->getKind() == CheckChildSame; 414*0fca6ea1SDimitry Andric } 415*0fca6ea1SDimitry Andric 416*0fca6ea1SDimitry Andric private: 417*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 418*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { 419*0fca6ea1SDimitry Andric return cast<CheckChildSameMatcher>(M)->ChildNo == ChildNo && 420*0fca6ea1SDimitry Andric cast<CheckChildSameMatcher>(M)->MatchNumber == MatchNumber; 421*0fca6ea1SDimitry Andric } 422*0fca6ea1SDimitry Andric }; 423*0fca6ea1SDimitry Andric 424*0fca6ea1SDimitry Andric /// CheckPatternPredicateMatcher - This checks the target-specific predicate 425*0fca6ea1SDimitry Andric /// to see if the entire pattern is capable of matching. This predicate does 426*0fca6ea1SDimitry Andric /// not take a node as input. This is used for subtarget feature checks etc. 427*0fca6ea1SDimitry Andric class CheckPatternPredicateMatcher : public Matcher { 428*0fca6ea1SDimitry Andric std::string Predicate; 429*0fca6ea1SDimitry Andric 430*0fca6ea1SDimitry Andric public: 431*0fca6ea1SDimitry Andric CheckPatternPredicateMatcher(StringRef predicate) 432*0fca6ea1SDimitry Andric : Matcher(CheckPatternPredicate), Predicate(predicate) {} 433*0fca6ea1SDimitry Andric 434*0fca6ea1SDimitry Andric StringRef getPredicate() const { return Predicate; } 435*0fca6ea1SDimitry Andric 436*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { 437*0fca6ea1SDimitry Andric return N->getKind() == CheckPatternPredicate; 438*0fca6ea1SDimitry Andric } 439*0fca6ea1SDimitry Andric 440*0fca6ea1SDimitry Andric private: 441*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 442*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { 443*0fca6ea1SDimitry Andric return cast<CheckPatternPredicateMatcher>(M)->getPredicate() == Predicate; 444*0fca6ea1SDimitry Andric } 445*0fca6ea1SDimitry Andric }; 446*0fca6ea1SDimitry Andric 447*0fca6ea1SDimitry Andric /// CheckPredicateMatcher - This checks the target-specific predicate to 448*0fca6ea1SDimitry Andric /// see if the node is acceptable. 449*0fca6ea1SDimitry Andric class CheckPredicateMatcher : public Matcher { 450*0fca6ea1SDimitry Andric TreePattern *Pred; 451*0fca6ea1SDimitry Andric const SmallVector<unsigned, 4> Operands; 452*0fca6ea1SDimitry Andric 453*0fca6ea1SDimitry Andric public: 454*0fca6ea1SDimitry Andric CheckPredicateMatcher(const TreePredicateFn &pred, 455*0fca6ea1SDimitry Andric const SmallVectorImpl<unsigned> &Operands); 456*0fca6ea1SDimitry Andric 457*0fca6ea1SDimitry Andric TreePredicateFn getPredicate() const; 458*0fca6ea1SDimitry Andric unsigned getNumOperands() const; 459*0fca6ea1SDimitry Andric unsigned getOperandNo(unsigned i) const; 460*0fca6ea1SDimitry Andric 461*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { 462*0fca6ea1SDimitry Andric return N->getKind() == CheckPredicate; 463*0fca6ea1SDimitry Andric } 464*0fca6ea1SDimitry Andric 465*0fca6ea1SDimitry Andric private: 466*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 467*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { 468*0fca6ea1SDimitry Andric return cast<CheckPredicateMatcher>(M)->Pred == Pred; 469*0fca6ea1SDimitry Andric } 470*0fca6ea1SDimitry Andric }; 471*0fca6ea1SDimitry Andric 472*0fca6ea1SDimitry Andric /// CheckOpcodeMatcher - This checks to see if the current node has the 473*0fca6ea1SDimitry Andric /// specified opcode, if not it fails to match. 474*0fca6ea1SDimitry Andric class CheckOpcodeMatcher : public Matcher { 475*0fca6ea1SDimitry Andric const SDNodeInfo &Opcode; 476*0fca6ea1SDimitry Andric 477*0fca6ea1SDimitry Andric public: 478*0fca6ea1SDimitry Andric CheckOpcodeMatcher(const SDNodeInfo &opcode) 479*0fca6ea1SDimitry Andric : Matcher(CheckOpcode), Opcode(opcode) {} 480*0fca6ea1SDimitry Andric 481*0fca6ea1SDimitry Andric const SDNodeInfo &getOpcode() const { return Opcode; } 482*0fca6ea1SDimitry Andric 483*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { return N->getKind() == CheckOpcode; } 484*0fca6ea1SDimitry Andric 485*0fca6ea1SDimitry Andric private: 486*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 487*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override; 488*0fca6ea1SDimitry Andric bool isContradictoryImpl(const Matcher *M) const override; 489*0fca6ea1SDimitry Andric }; 490*0fca6ea1SDimitry Andric 491*0fca6ea1SDimitry Andric /// SwitchOpcodeMatcher - Switch based on the current node's opcode, dispatching 492*0fca6ea1SDimitry Andric /// to one matcher per opcode. If the opcode doesn't match any of the cases, 493*0fca6ea1SDimitry Andric /// then the match fails. This is semantically equivalent to a Scope node where 494*0fca6ea1SDimitry Andric /// every child does a CheckOpcode, but is much faster. 495*0fca6ea1SDimitry Andric class SwitchOpcodeMatcher : public Matcher { 496*0fca6ea1SDimitry Andric SmallVector<std::pair<const SDNodeInfo *, Matcher *>, 8> Cases; 497*0fca6ea1SDimitry Andric 498*0fca6ea1SDimitry Andric public: 499*0fca6ea1SDimitry Andric SwitchOpcodeMatcher( 500*0fca6ea1SDimitry Andric SmallVectorImpl<std::pair<const SDNodeInfo *, Matcher *>> &&cases) 501*0fca6ea1SDimitry Andric : Matcher(SwitchOpcode), Cases(std::move(cases)) {} 502*0fca6ea1SDimitry Andric ~SwitchOpcodeMatcher() override; 503*0fca6ea1SDimitry Andric 504*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { return N->getKind() == SwitchOpcode; } 505*0fca6ea1SDimitry Andric 506*0fca6ea1SDimitry Andric unsigned getNumCases() const { return Cases.size(); } 507*0fca6ea1SDimitry Andric 508*0fca6ea1SDimitry Andric const SDNodeInfo &getCaseOpcode(unsigned i) const { return *Cases[i].first; } 509*0fca6ea1SDimitry Andric Matcher *getCaseMatcher(unsigned i) { return Cases[i].second; } 510*0fca6ea1SDimitry Andric const Matcher *getCaseMatcher(unsigned i) const { return Cases[i].second; } 511*0fca6ea1SDimitry Andric 512*0fca6ea1SDimitry Andric private: 513*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 514*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { return false; } 515*0fca6ea1SDimitry Andric }; 516*0fca6ea1SDimitry Andric 517*0fca6ea1SDimitry Andric /// CheckTypeMatcher - This checks to see if the current node has the 518*0fca6ea1SDimitry Andric /// specified type at the specified result, if not it fails to match. 519*0fca6ea1SDimitry Andric class CheckTypeMatcher : public Matcher { 520*0fca6ea1SDimitry Andric MVT::SimpleValueType Type; 521*0fca6ea1SDimitry Andric unsigned ResNo; 522*0fca6ea1SDimitry Andric 523*0fca6ea1SDimitry Andric public: 524*0fca6ea1SDimitry Andric CheckTypeMatcher(MVT::SimpleValueType type, unsigned resno) 525*0fca6ea1SDimitry Andric : Matcher(CheckType), Type(type), ResNo(resno) {} 526*0fca6ea1SDimitry Andric 527*0fca6ea1SDimitry Andric MVT::SimpleValueType getType() const { return Type; } 528*0fca6ea1SDimitry Andric unsigned getResNo() const { return ResNo; } 529*0fca6ea1SDimitry Andric 530*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { return N->getKind() == CheckType; } 531*0fca6ea1SDimitry Andric 532*0fca6ea1SDimitry Andric private: 533*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 534*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { 535*0fca6ea1SDimitry Andric return cast<CheckTypeMatcher>(M)->Type == Type; 536*0fca6ea1SDimitry Andric } 537*0fca6ea1SDimitry Andric bool isContradictoryImpl(const Matcher *M) const override; 538*0fca6ea1SDimitry Andric }; 539*0fca6ea1SDimitry Andric 540*0fca6ea1SDimitry Andric /// SwitchTypeMatcher - Switch based on the current node's type, dispatching 541*0fca6ea1SDimitry Andric /// to one matcher per case. If the type doesn't match any of the cases, 542*0fca6ea1SDimitry Andric /// then the match fails. This is semantically equivalent to a Scope node where 543*0fca6ea1SDimitry Andric /// every child does a CheckType, but is much faster. 544*0fca6ea1SDimitry Andric class SwitchTypeMatcher : public Matcher { 545*0fca6ea1SDimitry Andric SmallVector<std::pair<MVT::SimpleValueType, Matcher *>, 8> Cases; 546*0fca6ea1SDimitry Andric 547*0fca6ea1SDimitry Andric public: 548*0fca6ea1SDimitry Andric SwitchTypeMatcher( 549*0fca6ea1SDimitry Andric SmallVectorImpl<std::pair<MVT::SimpleValueType, Matcher *>> &&cases) 550*0fca6ea1SDimitry Andric : Matcher(SwitchType), Cases(std::move(cases)) {} 551*0fca6ea1SDimitry Andric ~SwitchTypeMatcher() override; 552*0fca6ea1SDimitry Andric 553*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { return N->getKind() == SwitchType; } 554*0fca6ea1SDimitry Andric 555*0fca6ea1SDimitry Andric unsigned getNumCases() const { return Cases.size(); } 556*0fca6ea1SDimitry Andric 557*0fca6ea1SDimitry Andric MVT::SimpleValueType getCaseType(unsigned i) const { return Cases[i].first; } 558*0fca6ea1SDimitry Andric Matcher *getCaseMatcher(unsigned i) { return Cases[i].second; } 559*0fca6ea1SDimitry Andric const Matcher *getCaseMatcher(unsigned i) const { return Cases[i].second; } 560*0fca6ea1SDimitry Andric 561*0fca6ea1SDimitry Andric private: 562*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 563*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { return false; } 564*0fca6ea1SDimitry Andric }; 565*0fca6ea1SDimitry Andric 566*0fca6ea1SDimitry Andric /// CheckChildTypeMatcher - This checks to see if a child node has the 567*0fca6ea1SDimitry Andric /// specified type, if not it fails to match. 568*0fca6ea1SDimitry Andric class CheckChildTypeMatcher : public Matcher { 569*0fca6ea1SDimitry Andric unsigned ChildNo; 570*0fca6ea1SDimitry Andric MVT::SimpleValueType Type; 571*0fca6ea1SDimitry Andric 572*0fca6ea1SDimitry Andric public: 573*0fca6ea1SDimitry Andric CheckChildTypeMatcher(unsigned childno, MVT::SimpleValueType type) 574*0fca6ea1SDimitry Andric : Matcher(CheckChildType), ChildNo(childno), Type(type) {} 575*0fca6ea1SDimitry Andric 576*0fca6ea1SDimitry Andric unsigned getChildNo() const { return ChildNo; } 577*0fca6ea1SDimitry Andric MVT::SimpleValueType getType() const { return Type; } 578*0fca6ea1SDimitry Andric 579*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { 580*0fca6ea1SDimitry Andric return N->getKind() == CheckChildType; 581*0fca6ea1SDimitry Andric } 582*0fca6ea1SDimitry Andric 583*0fca6ea1SDimitry Andric private: 584*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 585*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { 586*0fca6ea1SDimitry Andric return cast<CheckChildTypeMatcher>(M)->ChildNo == ChildNo && 587*0fca6ea1SDimitry Andric cast<CheckChildTypeMatcher>(M)->Type == Type; 588*0fca6ea1SDimitry Andric } 589*0fca6ea1SDimitry Andric bool isContradictoryImpl(const Matcher *M) const override; 590*0fca6ea1SDimitry Andric }; 591*0fca6ea1SDimitry Andric 592*0fca6ea1SDimitry Andric /// CheckIntegerMatcher - This checks to see if the current node is a 593*0fca6ea1SDimitry Andric /// ConstantSDNode with the specified integer value, if not it fails to match. 594*0fca6ea1SDimitry Andric class CheckIntegerMatcher : public Matcher { 595*0fca6ea1SDimitry Andric int64_t Value; 596*0fca6ea1SDimitry Andric 597*0fca6ea1SDimitry Andric public: 598*0fca6ea1SDimitry Andric CheckIntegerMatcher(int64_t value) : Matcher(CheckInteger), Value(value) {} 599*0fca6ea1SDimitry Andric 600*0fca6ea1SDimitry Andric int64_t getValue() const { return Value; } 601*0fca6ea1SDimitry Andric 602*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { return N->getKind() == CheckInteger; } 603*0fca6ea1SDimitry Andric 604*0fca6ea1SDimitry Andric private: 605*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 606*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { 607*0fca6ea1SDimitry Andric return cast<CheckIntegerMatcher>(M)->Value == Value; 608*0fca6ea1SDimitry Andric } 609*0fca6ea1SDimitry Andric bool isContradictoryImpl(const Matcher *M) const override; 610*0fca6ea1SDimitry Andric }; 611*0fca6ea1SDimitry Andric 612*0fca6ea1SDimitry Andric /// CheckChildIntegerMatcher - This checks to see if the child node is a 613*0fca6ea1SDimitry Andric /// ConstantSDNode with a specified integer value, if not it fails to match. 614*0fca6ea1SDimitry Andric class CheckChildIntegerMatcher : public Matcher { 615*0fca6ea1SDimitry Andric unsigned ChildNo; 616*0fca6ea1SDimitry Andric int64_t Value; 617*0fca6ea1SDimitry Andric 618*0fca6ea1SDimitry Andric public: 619*0fca6ea1SDimitry Andric CheckChildIntegerMatcher(unsigned childno, int64_t value) 620*0fca6ea1SDimitry Andric : Matcher(CheckChildInteger), ChildNo(childno), Value(value) {} 621*0fca6ea1SDimitry Andric 622*0fca6ea1SDimitry Andric unsigned getChildNo() const { return ChildNo; } 623*0fca6ea1SDimitry Andric int64_t getValue() const { return Value; } 624*0fca6ea1SDimitry Andric 625*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { 626*0fca6ea1SDimitry Andric return N->getKind() == CheckChildInteger; 627*0fca6ea1SDimitry Andric } 628*0fca6ea1SDimitry Andric 629*0fca6ea1SDimitry Andric private: 630*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 631*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { 632*0fca6ea1SDimitry Andric return cast<CheckChildIntegerMatcher>(M)->ChildNo == ChildNo && 633*0fca6ea1SDimitry Andric cast<CheckChildIntegerMatcher>(M)->Value == Value; 634*0fca6ea1SDimitry Andric } 635*0fca6ea1SDimitry Andric bool isContradictoryImpl(const Matcher *M) const override; 636*0fca6ea1SDimitry Andric }; 637*0fca6ea1SDimitry Andric 638*0fca6ea1SDimitry Andric /// CheckCondCodeMatcher - This checks to see if the current node is a 639*0fca6ea1SDimitry Andric /// CondCodeSDNode with the specified condition, if not it fails to match. 640*0fca6ea1SDimitry Andric class CheckCondCodeMatcher : public Matcher { 641*0fca6ea1SDimitry Andric StringRef CondCodeName; 642*0fca6ea1SDimitry Andric 643*0fca6ea1SDimitry Andric public: 644*0fca6ea1SDimitry Andric CheckCondCodeMatcher(StringRef condcodename) 645*0fca6ea1SDimitry Andric : Matcher(CheckCondCode), CondCodeName(condcodename) {} 646*0fca6ea1SDimitry Andric 647*0fca6ea1SDimitry Andric StringRef getCondCodeName() const { return CondCodeName; } 648*0fca6ea1SDimitry Andric 649*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { 650*0fca6ea1SDimitry Andric return N->getKind() == CheckCondCode; 651*0fca6ea1SDimitry Andric } 652*0fca6ea1SDimitry Andric 653*0fca6ea1SDimitry Andric private: 654*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 655*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { 656*0fca6ea1SDimitry Andric return cast<CheckCondCodeMatcher>(M)->CondCodeName == CondCodeName; 657*0fca6ea1SDimitry Andric } 658*0fca6ea1SDimitry Andric bool isContradictoryImpl(const Matcher *M) const override; 659*0fca6ea1SDimitry Andric }; 660*0fca6ea1SDimitry Andric 661*0fca6ea1SDimitry Andric /// CheckChild2CondCodeMatcher - This checks to see if child 2 node is a 662*0fca6ea1SDimitry Andric /// CondCodeSDNode with the specified condition, if not it fails to match. 663*0fca6ea1SDimitry Andric class CheckChild2CondCodeMatcher : public Matcher { 664*0fca6ea1SDimitry Andric StringRef CondCodeName; 665*0fca6ea1SDimitry Andric 666*0fca6ea1SDimitry Andric public: 667*0fca6ea1SDimitry Andric CheckChild2CondCodeMatcher(StringRef condcodename) 668*0fca6ea1SDimitry Andric : Matcher(CheckChild2CondCode), CondCodeName(condcodename) {} 669*0fca6ea1SDimitry Andric 670*0fca6ea1SDimitry Andric StringRef getCondCodeName() const { return CondCodeName; } 671*0fca6ea1SDimitry Andric 672*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { 673*0fca6ea1SDimitry Andric return N->getKind() == CheckChild2CondCode; 674*0fca6ea1SDimitry Andric } 675*0fca6ea1SDimitry Andric 676*0fca6ea1SDimitry Andric private: 677*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 678*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { 679*0fca6ea1SDimitry Andric return cast<CheckChild2CondCodeMatcher>(M)->CondCodeName == CondCodeName; 680*0fca6ea1SDimitry Andric } 681*0fca6ea1SDimitry Andric bool isContradictoryImpl(const Matcher *M) const override; 682*0fca6ea1SDimitry Andric }; 683*0fca6ea1SDimitry Andric 684*0fca6ea1SDimitry Andric /// CheckValueTypeMatcher - This checks to see if the current node is a 685*0fca6ea1SDimitry Andric /// VTSDNode with the specified type, if not it fails to match. 686*0fca6ea1SDimitry Andric class CheckValueTypeMatcher : public Matcher { 687*0fca6ea1SDimitry Andric MVT::SimpleValueType VT; 688*0fca6ea1SDimitry Andric 689*0fca6ea1SDimitry Andric public: 690*0fca6ea1SDimitry Andric CheckValueTypeMatcher(MVT::SimpleValueType SimpleVT) 691*0fca6ea1SDimitry Andric : Matcher(CheckValueType), VT(SimpleVT) {} 692*0fca6ea1SDimitry Andric 693*0fca6ea1SDimitry Andric MVT::SimpleValueType getVT() const { return VT; } 694*0fca6ea1SDimitry Andric 695*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { 696*0fca6ea1SDimitry Andric return N->getKind() == CheckValueType; 697*0fca6ea1SDimitry Andric } 698*0fca6ea1SDimitry Andric 699*0fca6ea1SDimitry Andric private: 700*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 701*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { 702*0fca6ea1SDimitry Andric return cast<CheckValueTypeMatcher>(M)->VT == VT; 703*0fca6ea1SDimitry Andric } 704*0fca6ea1SDimitry Andric bool isContradictoryImpl(const Matcher *M) const override; 705*0fca6ea1SDimitry Andric }; 706*0fca6ea1SDimitry Andric 707*0fca6ea1SDimitry Andric /// CheckComplexPatMatcher - This node runs the specified ComplexPattern on 708*0fca6ea1SDimitry Andric /// the current node. 709*0fca6ea1SDimitry Andric class CheckComplexPatMatcher : public Matcher { 710*0fca6ea1SDimitry Andric const ComplexPattern &Pattern; 711*0fca6ea1SDimitry Andric 712*0fca6ea1SDimitry Andric /// MatchNumber - This is the recorded nodes slot that contains the node we 713*0fca6ea1SDimitry Andric /// want to match against. 714*0fca6ea1SDimitry Andric unsigned MatchNumber; 715*0fca6ea1SDimitry Andric 716*0fca6ea1SDimitry Andric /// Name - The name of the node we're matching, for comment emission. 717*0fca6ea1SDimitry Andric std::string Name; 718*0fca6ea1SDimitry Andric 719*0fca6ea1SDimitry Andric /// FirstResult - This is the first slot in the RecordedNodes list that the 720*0fca6ea1SDimitry Andric /// result of the match populates. 721*0fca6ea1SDimitry Andric unsigned FirstResult; 722*0fca6ea1SDimitry Andric 723*0fca6ea1SDimitry Andric public: 724*0fca6ea1SDimitry Andric CheckComplexPatMatcher(const ComplexPattern &pattern, unsigned matchnumber, 725*0fca6ea1SDimitry Andric const std::string &name, unsigned firstresult) 726*0fca6ea1SDimitry Andric : Matcher(CheckComplexPat), Pattern(pattern), MatchNumber(matchnumber), 727*0fca6ea1SDimitry Andric Name(name), FirstResult(firstresult) {} 728*0fca6ea1SDimitry Andric 729*0fca6ea1SDimitry Andric const ComplexPattern &getPattern() const { return Pattern; } 730*0fca6ea1SDimitry Andric unsigned getMatchNumber() const { return MatchNumber; } 731*0fca6ea1SDimitry Andric 732*0fca6ea1SDimitry Andric std::string getName() const { return Name; } 733*0fca6ea1SDimitry Andric unsigned getFirstResult() const { return FirstResult; } 734*0fca6ea1SDimitry Andric 735*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { 736*0fca6ea1SDimitry Andric return N->getKind() == CheckComplexPat; 737*0fca6ea1SDimitry Andric } 738*0fca6ea1SDimitry Andric 739*0fca6ea1SDimitry Andric private: 740*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 741*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { 742*0fca6ea1SDimitry Andric return &cast<CheckComplexPatMatcher>(M)->Pattern == &Pattern && 743*0fca6ea1SDimitry Andric cast<CheckComplexPatMatcher>(M)->MatchNumber == MatchNumber; 744*0fca6ea1SDimitry Andric } 745*0fca6ea1SDimitry Andric }; 746*0fca6ea1SDimitry Andric 747*0fca6ea1SDimitry Andric /// CheckAndImmMatcher - This checks to see if the current node is an 'and' 748*0fca6ea1SDimitry Andric /// with something equivalent to the specified immediate. 749*0fca6ea1SDimitry Andric class CheckAndImmMatcher : public Matcher { 750*0fca6ea1SDimitry Andric int64_t Value; 751*0fca6ea1SDimitry Andric 752*0fca6ea1SDimitry Andric public: 753*0fca6ea1SDimitry Andric CheckAndImmMatcher(int64_t value) : Matcher(CheckAndImm), Value(value) {} 754*0fca6ea1SDimitry Andric 755*0fca6ea1SDimitry Andric int64_t getValue() const { return Value; } 756*0fca6ea1SDimitry Andric 757*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { return N->getKind() == CheckAndImm; } 758*0fca6ea1SDimitry Andric 759*0fca6ea1SDimitry Andric private: 760*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 761*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { 762*0fca6ea1SDimitry Andric return cast<CheckAndImmMatcher>(M)->Value == Value; 763*0fca6ea1SDimitry Andric } 764*0fca6ea1SDimitry Andric }; 765*0fca6ea1SDimitry Andric 766*0fca6ea1SDimitry Andric /// CheckOrImmMatcher - This checks to see if the current node is an 'and' 767*0fca6ea1SDimitry Andric /// with something equivalent to the specified immediate. 768*0fca6ea1SDimitry Andric class CheckOrImmMatcher : public Matcher { 769*0fca6ea1SDimitry Andric int64_t Value; 770*0fca6ea1SDimitry Andric 771*0fca6ea1SDimitry Andric public: 772*0fca6ea1SDimitry Andric CheckOrImmMatcher(int64_t value) : Matcher(CheckOrImm), Value(value) {} 773*0fca6ea1SDimitry Andric 774*0fca6ea1SDimitry Andric int64_t getValue() const { return Value; } 775*0fca6ea1SDimitry Andric 776*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { return N->getKind() == CheckOrImm; } 777*0fca6ea1SDimitry Andric 778*0fca6ea1SDimitry Andric private: 779*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 780*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { 781*0fca6ea1SDimitry Andric return cast<CheckOrImmMatcher>(M)->Value == Value; 782*0fca6ea1SDimitry Andric } 783*0fca6ea1SDimitry Andric }; 784*0fca6ea1SDimitry Andric 785*0fca6ea1SDimitry Andric /// CheckImmAllOnesVMatcher - This checks if the current node is a build_vector 786*0fca6ea1SDimitry Andric /// or splat_vector of all ones. 787*0fca6ea1SDimitry Andric class CheckImmAllOnesVMatcher : public Matcher { 788*0fca6ea1SDimitry Andric public: 789*0fca6ea1SDimitry Andric CheckImmAllOnesVMatcher() : Matcher(CheckImmAllOnesV) {} 790*0fca6ea1SDimitry Andric 791*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { 792*0fca6ea1SDimitry Andric return N->getKind() == CheckImmAllOnesV; 793*0fca6ea1SDimitry Andric } 794*0fca6ea1SDimitry Andric 795*0fca6ea1SDimitry Andric private: 796*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 797*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { return true; } 798*0fca6ea1SDimitry Andric bool isContradictoryImpl(const Matcher *M) const override; 799*0fca6ea1SDimitry Andric }; 800*0fca6ea1SDimitry Andric 801*0fca6ea1SDimitry Andric /// CheckImmAllZerosVMatcher - This checks if the current node is a 802*0fca6ea1SDimitry Andric /// build_vector or splat_vector of all zeros. 803*0fca6ea1SDimitry Andric class CheckImmAllZerosVMatcher : public Matcher { 804*0fca6ea1SDimitry Andric public: 805*0fca6ea1SDimitry Andric CheckImmAllZerosVMatcher() : Matcher(CheckImmAllZerosV) {} 806*0fca6ea1SDimitry Andric 807*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { 808*0fca6ea1SDimitry Andric return N->getKind() == CheckImmAllZerosV; 809*0fca6ea1SDimitry Andric } 810*0fca6ea1SDimitry Andric 811*0fca6ea1SDimitry Andric private: 812*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 813*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { return true; } 814*0fca6ea1SDimitry Andric bool isContradictoryImpl(const Matcher *M) const override; 815*0fca6ea1SDimitry Andric }; 816*0fca6ea1SDimitry Andric 817*0fca6ea1SDimitry Andric /// CheckFoldableChainNodeMatcher - This checks to see if the current node 818*0fca6ea1SDimitry Andric /// (which defines a chain operand) is safe to fold into a larger pattern. 819*0fca6ea1SDimitry Andric class CheckFoldableChainNodeMatcher : public Matcher { 820*0fca6ea1SDimitry Andric public: 821*0fca6ea1SDimitry Andric CheckFoldableChainNodeMatcher() : Matcher(CheckFoldableChainNode) {} 822*0fca6ea1SDimitry Andric 823*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { 824*0fca6ea1SDimitry Andric return N->getKind() == CheckFoldableChainNode; 825*0fca6ea1SDimitry Andric } 826*0fca6ea1SDimitry Andric 827*0fca6ea1SDimitry Andric private: 828*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 829*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { return true; } 830*0fca6ea1SDimitry Andric }; 831*0fca6ea1SDimitry Andric 832*0fca6ea1SDimitry Andric /// EmitIntegerMatcher - This creates a new TargetConstant. 833*0fca6ea1SDimitry Andric class EmitIntegerMatcher : public Matcher { 834*0fca6ea1SDimitry Andric int64_t Val; 835*0fca6ea1SDimitry Andric MVT::SimpleValueType VT; 836*0fca6ea1SDimitry Andric 837*0fca6ea1SDimitry Andric public: 838*0fca6ea1SDimitry Andric EmitIntegerMatcher(int64_t val, MVT::SimpleValueType vt) 839*0fca6ea1SDimitry Andric : Matcher(EmitInteger), Val(val), VT(vt) {} 840*0fca6ea1SDimitry Andric 841*0fca6ea1SDimitry Andric int64_t getValue() const { return Val; } 842*0fca6ea1SDimitry Andric MVT::SimpleValueType getVT() const { return VT; } 843*0fca6ea1SDimitry Andric 844*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { return N->getKind() == EmitInteger; } 845*0fca6ea1SDimitry Andric 846*0fca6ea1SDimitry Andric private: 847*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 848*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { 849*0fca6ea1SDimitry Andric return cast<EmitIntegerMatcher>(M)->Val == Val && 850*0fca6ea1SDimitry Andric cast<EmitIntegerMatcher>(M)->VT == VT; 851*0fca6ea1SDimitry Andric } 852*0fca6ea1SDimitry Andric }; 853*0fca6ea1SDimitry Andric 854*0fca6ea1SDimitry Andric /// EmitStringIntegerMatcher - A target constant whose value is represented 855*0fca6ea1SDimitry Andric /// by a string. 856*0fca6ea1SDimitry Andric class EmitStringIntegerMatcher : public Matcher { 857*0fca6ea1SDimitry Andric std::string Val; 858*0fca6ea1SDimitry Andric MVT::SimpleValueType VT; 859*0fca6ea1SDimitry Andric 860*0fca6ea1SDimitry Andric public: 861*0fca6ea1SDimitry Andric EmitStringIntegerMatcher(const std::string &val, MVT::SimpleValueType vt) 862*0fca6ea1SDimitry Andric : Matcher(EmitStringInteger), Val(val), VT(vt) {} 863*0fca6ea1SDimitry Andric 864*0fca6ea1SDimitry Andric const std::string &getValue() const { return Val; } 865*0fca6ea1SDimitry Andric MVT::SimpleValueType getVT() const { return VT; } 866*0fca6ea1SDimitry Andric 867*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { 868*0fca6ea1SDimitry Andric return N->getKind() == EmitStringInteger; 869*0fca6ea1SDimitry Andric } 870*0fca6ea1SDimitry Andric 871*0fca6ea1SDimitry Andric private: 872*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 873*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { 874*0fca6ea1SDimitry Andric return cast<EmitStringIntegerMatcher>(M)->Val == Val && 875*0fca6ea1SDimitry Andric cast<EmitStringIntegerMatcher>(M)->VT == VT; 876*0fca6ea1SDimitry Andric } 877*0fca6ea1SDimitry Andric }; 878*0fca6ea1SDimitry Andric 879*0fca6ea1SDimitry Andric /// EmitRegisterMatcher - This creates a new TargetConstant. 880*0fca6ea1SDimitry Andric class EmitRegisterMatcher : public Matcher { 881*0fca6ea1SDimitry Andric /// Reg - The def for the register that we're emitting. If this is null, then 882*0fca6ea1SDimitry Andric /// this is a reference to zero_reg. 883*0fca6ea1SDimitry Andric const CodeGenRegister *Reg; 884*0fca6ea1SDimitry Andric MVT::SimpleValueType VT; 885*0fca6ea1SDimitry Andric 886*0fca6ea1SDimitry Andric public: 887*0fca6ea1SDimitry Andric EmitRegisterMatcher(const CodeGenRegister *reg, MVT::SimpleValueType vt) 888*0fca6ea1SDimitry Andric : Matcher(EmitRegister), Reg(reg), VT(vt) {} 889*0fca6ea1SDimitry Andric 890*0fca6ea1SDimitry Andric const CodeGenRegister *getReg() const { return Reg; } 891*0fca6ea1SDimitry Andric MVT::SimpleValueType getVT() const { return VT; } 892*0fca6ea1SDimitry Andric 893*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { return N->getKind() == EmitRegister; } 894*0fca6ea1SDimitry Andric 895*0fca6ea1SDimitry Andric private: 896*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 897*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { 898*0fca6ea1SDimitry Andric return cast<EmitRegisterMatcher>(M)->Reg == Reg && 899*0fca6ea1SDimitry Andric cast<EmitRegisterMatcher>(M)->VT == VT; 900*0fca6ea1SDimitry Andric } 901*0fca6ea1SDimitry Andric }; 902*0fca6ea1SDimitry Andric 903*0fca6ea1SDimitry Andric /// EmitConvertToTargetMatcher - Emit an operation that reads a specified 904*0fca6ea1SDimitry Andric /// recorded node and converts it from being a ISD::Constant to 905*0fca6ea1SDimitry Andric /// ISD::TargetConstant, likewise for ConstantFP. 906*0fca6ea1SDimitry Andric class EmitConvertToTargetMatcher : public Matcher { 907*0fca6ea1SDimitry Andric unsigned Slot; 908*0fca6ea1SDimitry Andric 909*0fca6ea1SDimitry Andric public: 910*0fca6ea1SDimitry Andric EmitConvertToTargetMatcher(unsigned slot) 911*0fca6ea1SDimitry Andric : Matcher(EmitConvertToTarget), Slot(slot) {} 912*0fca6ea1SDimitry Andric 913*0fca6ea1SDimitry Andric unsigned getSlot() const { return Slot; } 914*0fca6ea1SDimitry Andric 915*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { 916*0fca6ea1SDimitry Andric return N->getKind() == EmitConvertToTarget; 917*0fca6ea1SDimitry Andric } 918*0fca6ea1SDimitry Andric 919*0fca6ea1SDimitry Andric private: 920*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 921*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { 922*0fca6ea1SDimitry Andric return cast<EmitConvertToTargetMatcher>(M)->Slot == Slot; 923*0fca6ea1SDimitry Andric } 924*0fca6ea1SDimitry Andric }; 925*0fca6ea1SDimitry Andric 926*0fca6ea1SDimitry Andric /// EmitMergeInputChainsMatcher - Emit a node that merges a list of input 927*0fca6ea1SDimitry Andric /// chains together with a token factor. The list of nodes are the nodes in the 928*0fca6ea1SDimitry Andric /// matched pattern that have chain input/outputs. This node adds all input 929*0fca6ea1SDimitry Andric /// chains of these nodes if they are not themselves a node in the pattern. 930*0fca6ea1SDimitry Andric class EmitMergeInputChainsMatcher : public Matcher { 931*0fca6ea1SDimitry Andric SmallVector<unsigned, 3> ChainNodes; 932*0fca6ea1SDimitry Andric 933*0fca6ea1SDimitry Andric public: 934*0fca6ea1SDimitry Andric EmitMergeInputChainsMatcher(ArrayRef<unsigned> nodes) 935*0fca6ea1SDimitry Andric : Matcher(EmitMergeInputChains), ChainNodes(nodes.begin(), nodes.end()) {} 936*0fca6ea1SDimitry Andric 937*0fca6ea1SDimitry Andric unsigned getNumNodes() const { return ChainNodes.size(); } 938*0fca6ea1SDimitry Andric 939*0fca6ea1SDimitry Andric unsigned getNode(unsigned i) const { 940*0fca6ea1SDimitry Andric assert(i < ChainNodes.size()); 941*0fca6ea1SDimitry Andric return ChainNodes[i]; 942*0fca6ea1SDimitry Andric } 943*0fca6ea1SDimitry Andric 944*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { 945*0fca6ea1SDimitry Andric return N->getKind() == EmitMergeInputChains; 946*0fca6ea1SDimitry Andric } 947*0fca6ea1SDimitry Andric 948*0fca6ea1SDimitry Andric private: 949*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 950*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { 951*0fca6ea1SDimitry Andric return cast<EmitMergeInputChainsMatcher>(M)->ChainNodes == ChainNodes; 952*0fca6ea1SDimitry Andric } 953*0fca6ea1SDimitry Andric }; 954*0fca6ea1SDimitry Andric 955*0fca6ea1SDimitry Andric /// EmitCopyToRegMatcher - Emit a CopyToReg node from a value to a physreg, 956*0fca6ea1SDimitry Andric /// pushing the chain and glue results. 957*0fca6ea1SDimitry Andric /// 958*0fca6ea1SDimitry Andric class EmitCopyToRegMatcher : public Matcher { 959*0fca6ea1SDimitry Andric unsigned SrcSlot; // Value to copy into the physreg. 960*0fca6ea1SDimitry Andric const CodeGenRegister *DestPhysReg; 961*0fca6ea1SDimitry Andric 962*0fca6ea1SDimitry Andric public: 963*0fca6ea1SDimitry Andric EmitCopyToRegMatcher(unsigned srcSlot, const CodeGenRegister *destPhysReg) 964*0fca6ea1SDimitry Andric : Matcher(EmitCopyToReg), SrcSlot(srcSlot), DestPhysReg(destPhysReg) {} 965*0fca6ea1SDimitry Andric 966*0fca6ea1SDimitry Andric unsigned getSrcSlot() const { return SrcSlot; } 967*0fca6ea1SDimitry Andric const CodeGenRegister *getDestPhysReg() const { return DestPhysReg; } 968*0fca6ea1SDimitry Andric 969*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { 970*0fca6ea1SDimitry Andric return N->getKind() == EmitCopyToReg; 971*0fca6ea1SDimitry Andric } 972*0fca6ea1SDimitry Andric 973*0fca6ea1SDimitry Andric private: 974*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 975*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { 976*0fca6ea1SDimitry Andric return cast<EmitCopyToRegMatcher>(M)->SrcSlot == SrcSlot && 977*0fca6ea1SDimitry Andric cast<EmitCopyToRegMatcher>(M)->DestPhysReg == DestPhysReg; 978*0fca6ea1SDimitry Andric } 979*0fca6ea1SDimitry Andric }; 980*0fca6ea1SDimitry Andric 981*0fca6ea1SDimitry Andric /// EmitNodeXFormMatcher - Emit an operation that runs an SDNodeXForm on a 982*0fca6ea1SDimitry Andric /// recorded node and records the result. 983*0fca6ea1SDimitry Andric class EmitNodeXFormMatcher : public Matcher { 984*0fca6ea1SDimitry Andric unsigned Slot; 985*0fca6ea1SDimitry Andric Record *NodeXForm; 986*0fca6ea1SDimitry Andric 987*0fca6ea1SDimitry Andric public: 988*0fca6ea1SDimitry Andric EmitNodeXFormMatcher(unsigned slot, Record *nodeXForm) 989*0fca6ea1SDimitry Andric : Matcher(EmitNodeXForm), Slot(slot), NodeXForm(nodeXForm) {} 990*0fca6ea1SDimitry Andric 991*0fca6ea1SDimitry Andric unsigned getSlot() const { return Slot; } 992*0fca6ea1SDimitry Andric Record *getNodeXForm() const { return NodeXForm; } 993*0fca6ea1SDimitry Andric 994*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { 995*0fca6ea1SDimitry Andric return N->getKind() == EmitNodeXForm; 996*0fca6ea1SDimitry Andric } 997*0fca6ea1SDimitry Andric 998*0fca6ea1SDimitry Andric private: 999*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 1000*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { 1001*0fca6ea1SDimitry Andric return cast<EmitNodeXFormMatcher>(M)->Slot == Slot && 1002*0fca6ea1SDimitry Andric cast<EmitNodeXFormMatcher>(M)->NodeXForm == NodeXForm; 1003*0fca6ea1SDimitry Andric } 1004*0fca6ea1SDimitry Andric }; 1005*0fca6ea1SDimitry Andric 1006*0fca6ea1SDimitry Andric /// EmitNodeMatcherCommon - Common class shared between EmitNode and 1007*0fca6ea1SDimitry Andric /// MorphNodeTo. 1008*0fca6ea1SDimitry Andric class EmitNodeMatcherCommon : public Matcher { 1009*0fca6ea1SDimitry Andric const CodeGenInstruction &CGI; 1010*0fca6ea1SDimitry Andric const SmallVector<MVT::SimpleValueType, 3> VTs; 1011*0fca6ea1SDimitry Andric const SmallVector<unsigned, 6> Operands; 1012*0fca6ea1SDimitry Andric bool HasChain, HasInGlue, HasOutGlue, HasMemRefs; 1013*0fca6ea1SDimitry Andric 1014*0fca6ea1SDimitry Andric /// NumFixedArityOperands - If this is a fixed arity node, this is set to -1. 1015*0fca6ea1SDimitry Andric /// If this is a varidic node, this is set to the number of fixed arity 1016*0fca6ea1SDimitry Andric /// operands in the root of the pattern. The rest are appended to this node. 1017*0fca6ea1SDimitry Andric int NumFixedArityOperands; 1018*0fca6ea1SDimitry Andric 1019*0fca6ea1SDimitry Andric public: 1020*0fca6ea1SDimitry Andric EmitNodeMatcherCommon(const CodeGenInstruction &cgi, 1021*0fca6ea1SDimitry Andric ArrayRef<MVT::SimpleValueType> vts, 1022*0fca6ea1SDimitry Andric ArrayRef<unsigned> operands, bool hasChain, 1023*0fca6ea1SDimitry Andric bool hasInGlue, bool hasOutGlue, bool hasmemrefs, 1024*0fca6ea1SDimitry Andric int numfixedarityoperands, bool isMorphNodeTo) 1025*0fca6ea1SDimitry Andric : Matcher(isMorphNodeTo ? MorphNodeTo : EmitNode), CGI(cgi), 1026*0fca6ea1SDimitry Andric VTs(vts.begin(), vts.end()), Operands(operands.begin(), operands.end()), 1027*0fca6ea1SDimitry Andric HasChain(hasChain), HasInGlue(hasInGlue), HasOutGlue(hasOutGlue), 1028*0fca6ea1SDimitry Andric HasMemRefs(hasmemrefs), NumFixedArityOperands(numfixedarityoperands) {} 1029*0fca6ea1SDimitry Andric 1030*0fca6ea1SDimitry Andric const CodeGenInstruction &getInstruction() const { return CGI; } 1031*0fca6ea1SDimitry Andric 1032*0fca6ea1SDimitry Andric unsigned getNumVTs() const { return VTs.size(); } 1033*0fca6ea1SDimitry Andric MVT::SimpleValueType getVT(unsigned i) const { 1034*0fca6ea1SDimitry Andric assert(i < VTs.size()); 1035*0fca6ea1SDimitry Andric return VTs[i]; 1036*0fca6ea1SDimitry Andric } 1037*0fca6ea1SDimitry Andric 1038*0fca6ea1SDimitry Andric unsigned getNumOperands() const { return Operands.size(); } 1039*0fca6ea1SDimitry Andric unsigned getOperand(unsigned i) const { 1040*0fca6ea1SDimitry Andric assert(i < Operands.size()); 1041*0fca6ea1SDimitry Andric return Operands[i]; 1042*0fca6ea1SDimitry Andric } 1043*0fca6ea1SDimitry Andric 1044*0fca6ea1SDimitry Andric const SmallVectorImpl<MVT::SimpleValueType> &getVTList() const { return VTs; } 1045*0fca6ea1SDimitry Andric const SmallVectorImpl<unsigned> &getOperandList() const { return Operands; } 1046*0fca6ea1SDimitry Andric 1047*0fca6ea1SDimitry Andric bool hasChain() const { return HasChain; } 1048*0fca6ea1SDimitry Andric bool hasInGlue() const { return HasInGlue; } 1049*0fca6ea1SDimitry Andric bool hasOutGlue() const { return HasOutGlue; } 1050*0fca6ea1SDimitry Andric bool hasMemRefs() const { return HasMemRefs; } 1051*0fca6ea1SDimitry Andric int getNumFixedArityOperands() const { return NumFixedArityOperands; } 1052*0fca6ea1SDimitry Andric 1053*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { 1054*0fca6ea1SDimitry Andric return N->getKind() == EmitNode || N->getKind() == MorphNodeTo; 1055*0fca6ea1SDimitry Andric } 1056*0fca6ea1SDimitry Andric 1057*0fca6ea1SDimitry Andric private: 1058*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 1059*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override; 1060*0fca6ea1SDimitry Andric }; 1061*0fca6ea1SDimitry Andric 1062*0fca6ea1SDimitry Andric /// EmitNodeMatcher - This signals a successful match and generates a node. 1063*0fca6ea1SDimitry Andric class EmitNodeMatcher : public EmitNodeMatcherCommon { 1064*0fca6ea1SDimitry Andric void anchor() override; 1065*0fca6ea1SDimitry Andric unsigned FirstResultSlot; 1066*0fca6ea1SDimitry Andric 1067*0fca6ea1SDimitry Andric public: 1068*0fca6ea1SDimitry Andric EmitNodeMatcher(const CodeGenInstruction &cgi, 1069*0fca6ea1SDimitry Andric ArrayRef<MVT::SimpleValueType> vts, 1070*0fca6ea1SDimitry Andric ArrayRef<unsigned> operands, bool hasChain, bool hasInGlue, 1071*0fca6ea1SDimitry Andric bool hasOutGlue, bool hasmemrefs, int numfixedarityoperands, 1072*0fca6ea1SDimitry Andric unsigned firstresultslot) 1073*0fca6ea1SDimitry Andric : EmitNodeMatcherCommon(cgi, vts, operands, hasChain, hasInGlue, 1074*0fca6ea1SDimitry Andric hasOutGlue, hasmemrefs, numfixedarityoperands, 1075*0fca6ea1SDimitry Andric false), 1076*0fca6ea1SDimitry Andric FirstResultSlot(firstresultslot) {} 1077*0fca6ea1SDimitry Andric 1078*0fca6ea1SDimitry Andric unsigned getFirstResultSlot() const { return FirstResultSlot; } 1079*0fca6ea1SDimitry Andric 1080*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { return N->getKind() == EmitNode; } 1081*0fca6ea1SDimitry Andric }; 1082*0fca6ea1SDimitry Andric 1083*0fca6ea1SDimitry Andric class MorphNodeToMatcher : public EmitNodeMatcherCommon { 1084*0fca6ea1SDimitry Andric void anchor() override; 1085*0fca6ea1SDimitry Andric const PatternToMatch &Pattern; 1086*0fca6ea1SDimitry Andric 1087*0fca6ea1SDimitry Andric public: 1088*0fca6ea1SDimitry Andric MorphNodeToMatcher(const CodeGenInstruction &cgi, 1089*0fca6ea1SDimitry Andric ArrayRef<MVT::SimpleValueType> vts, 1090*0fca6ea1SDimitry Andric ArrayRef<unsigned> operands, bool hasChain, bool hasInGlue, 1091*0fca6ea1SDimitry Andric bool hasOutGlue, bool hasmemrefs, 1092*0fca6ea1SDimitry Andric int numfixedarityoperands, const PatternToMatch &pattern) 1093*0fca6ea1SDimitry Andric : EmitNodeMatcherCommon(cgi, vts, operands, hasChain, hasInGlue, 1094*0fca6ea1SDimitry Andric hasOutGlue, hasmemrefs, numfixedarityoperands, 1095*0fca6ea1SDimitry Andric true), 1096*0fca6ea1SDimitry Andric Pattern(pattern) {} 1097*0fca6ea1SDimitry Andric 1098*0fca6ea1SDimitry Andric const PatternToMatch &getPattern() const { return Pattern; } 1099*0fca6ea1SDimitry Andric 1100*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { return N->getKind() == MorphNodeTo; } 1101*0fca6ea1SDimitry Andric }; 1102*0fca6ea1SDimitry Andric 1103*0fca6ea1SDimitry Andric /// CompleteMatchMatcher - Complete a match by replacing the results of the 1104*0fca6ea1SDimitry Andric /// pattern with the newly generated nodes. This also prints a comment 1105*0fca6ea1SDimitry Andric /// indicating the source and dest patterns. 1106*0fca6ea1SDimitry Andric class CompleteMatchMatcher : public Matcher { 1107*0fca6ea1SDimitry Andric SmallVector<unsigned, 2> Results; 1108*0fca6ea1SDimitry Andric const PatternToMatch &Pattern; 1109*0fca6ea1SDimitry Andric 1110*0fca6ea1SDimitry Andric public: 1111*0fca6ea1SDimitry Andric CompleteMatchMatcher(ArrayRef<unsigned> results, 1112*0fca6ea1SDimitry Andric const PatternToMatch &pattern) 1113*0fca6ea1SDimitry Andric : Matcher(CompleteMatch), Results(results.begin(), results.end()), 1114*0fca6ea1SDimitry Andric Pattern(pattern) {} 1115*0fca6ea1SDimitry Andric 1116*0fca6ea1SDimitry Andric unsigned getNumResults() const { return Results.size(); } 1117*0fca6ea1SDimitry Andric unsigned getResult(unsigned R) const { return Results[R]; } 1118*0fca6ea1SDimitry Andric const PatternToMatch &getPattern() const { return Pattern; } 1119*0fca6ea1SDimitry Andric 1120*0fca6ea1SDimitry Andric static bool classof(const Matcher *N) { 1121*0fca6ea1SDimitry Andric return N->getKind() == CompleteMatch; 1122*0fca6ea1SDimitry Andric } 1123*0fca6ea1SDimitry Andric 1124*0fca6ea1SDimitry Andric private: 1125*0fca6ea1SDimitry Andric void printImpl(raw_ostream &OS, unsigned indent) const override; 1126*0fca6ea1SDimitry Andric bool isEqualImpl(const Matcher *M) const override { 1127*0fca6ea1SDimitry Andric return cast<CompleteMatchMatcher>(M)->Results == Results && 1128*0fca6ea1SDimitry Andric &cast<CompleteMatchMatcher>(M)->Pattern == &Pattern; 1129*0fca6ea1SDimitry Andric } 1130*0fca6ea1SDimitry Andric }; 1131*0fca6ea1SDimitry Andric 1132*0fca6ea1SDimitry Andric } // end namespace llvm 1133*0fca6ea1SDimitry Andric 1134*0fca6ea1SDimitry Andric #endif 1135