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