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