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