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