DAGISelMatcher.h revision 12a667c1e8fa57a13ae751164b6dd4412a62dc5d
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/CodeGen/ValueTypes.h" 14#include "llvm/ADT/OwningPtr.h" 15#include "llvm/ADT/StringRef.h" 16#include "llvm/ADT/SmallVector.h" 17#include "llvm/Support/Casting.h" 18 19namespace llvm { 20 class CodeGenDAGPatterns; 21 class MatcherNode; 22 class PatternToMatch; 23 class raw_ostream; 24 class ComplexPattern; 25 class Record; 26 27MatcherNode *ConvertPatternToMatcher(const PatternToMatch &Pattern, 28 const CodeGenDAGPatterns &CGP); 29 30void EmitMatcherTable(const MatcherNode *Matcher, raw_ostream &OS); 31 32 33/// MatcherNode - Base class for all the the DAG ISel Matcher representation 34/// nodes. 35class MatcherNode { 36 // The next matcher node that is executed after this one. Null if this is the 37 // last stage of a match. 38 OwningPtr<MatcherNode> Next; 39public: 40 enum KindTy { 41 // Matcher state manipulation. 42 Push, // Push a checking scope. 43 RecordNode, // Record the current node. 44 RecordMemRef, // Record the memref in the current node. 45 CaptureFlagInput, // If the current node has an input flag, save it. 46 MoveChild, // Move current node to specified child. 47 MoveParent, // Move current node to parent. 48 49 // Predicate checking. 50 CheckSame, // Fail if not same as prev match. 51 CheckPatternPredicate, 52 CheckPredicate, // Fail if node predicate fails. 53 CheckOpcode, // Fail if not opcode. 54 CheckMultiOpcode, // Fail if not in opcode list. 55 CheckType, // Fail if not correct type. 56 CheckInteger, // Fail if wrong val. 57 CheckCondCode, // Fail if not condcode. 58 CheckValueType, 59 CheckComplexPat, 60 CheckAndImm, 61 CheckOrImm, 62 CheckFoldableChainNode, 63 CheckChainCompatible, 64 65 // Node creation/emisssion. 66 EmitInteger, // Create a TargetConstant 67 EmitStringInteger, // Create a TargetConstant from a string. 68 EmitRegister, // Create a register. 69 EmitConvertToTarget, // Convert a imm/fpimm to target imm/fpimm 70 EmitMergeInputChains, // Merge together a chains for an input. 71 EmitCopyToReg, // Emit a copytoreg into a physreg. 72 EmitNode, // Create a DAG node 73 EmitNodeXForm, // Run a SDNodeXForm 74 CompleteMatch // Finish a match and update the results. 75 }; 76 const KindTy Kind; 77 78protected: 79 MatcherNode(KindTy K) : Kind(K) {} 80public: 81 virtual ~MatcherNode() {} 82 83 KindTy getKind() const { return Kind; } 84 85 MatcherNode *getNext() { return Next.get(); } 86 const MatcherNode *getNext() const { return Next.get(); } 87 void setNext(MatcherNode *C) { Next.reset(C); } 88 89 static inline bool classof(const MatcherNode *) { return true; } 90 91 virtual void print(raw_ostream &OS, unsigned indent = 0) const = 0; 92 void dump() const; 93protected: 94 void printNext(raw_ostream &OS, unsigned indent) const; 95}; 96 97/// PushMatcherNode - This pushes a failure scope on the stack and evaluates 98/// 'Next'. If 'Next' fails to match, it pops its scope and attempts to 99/// match 'Failure'. 100class PushMatcherNode : public MatcherNode { 101 OwningPtr<MatcherNode> Failure; 102public: 103 PushMatcherNode(MatcherNode *next = 0, MatcherNode *failure = 0) 104 : MatcherNode(Push), Failure(failure) { 105 setNext(next); 106 } 107 108 MatcherNode *getFailure() { return Failure.get(); } 109 const MatcherNode *getFailure() const { return Failure.get(); } 110 void setFailure(MatcherNode *N) { Failure.reset(N); } 111 112 static inline bool classof(const MatcherNode *N) { 113 return N->getKind() == Push; 114 } 115 116 virtual void print(raw_ostream &OS, unsigned indent = 0) const; 117}; 118 119/// RecordMatcherNode - Save the current node in the operand list. 120class RecordMatcherNode : public MatcherNode { 121 /// WhatFor - This is a string indicating why we're recording this. This 122 /// should only be used for comment generation not anything semantic. 123 std::string WhatFor; 124public: 125 RecordMatcherNode(const std::string &whatfor) 126 : MatcherNode(RecordNode), WhatFor(whatfor) {} 127 128 const std::string &getWhatFor() const { return WhatFor; } 129 130 static inline bool classof(const MatcherNode *N) { 131 return N->getKind() == RecordNode; 132 } 133 134 virtual void print(raw_ostream &OS, unsigned indent = 0) const; 135}; 136 137/// RecordMemRefMatcherNode - Save the current node's memref. 138class RecordMemRefMatcherNode : public MatcherNode { 139public: 140 RecordMemRefMatcherNode() : MatcherNode(RecordMemRef) {} 141 142 static inline bool classof(const MatcherNode *N) { 143 return N->getKind() == RecordMemRef; 144 } 145 146 virtual void print(raw_ostream &OS, unsigned indent = 0) const; 147}; 148 149 150/// CaptureFlagInputMatcherNode - If the current record has a flag input, record 151/// it so that it is used as an input to the generated code. 152class CaptureFlagInputMatcherNode : public MatcherNode { 153public: 154 CaptureFlagInputMatcherNode() 155 : MatcherNode(CaptureFlagInput) {} 156 157 static inline bool classof(const MatcherNode *N) { 158 return N->getKind() == CaptureFlagInput; 159 } 160 161 virtual void print(raw_ostream &OS, unsigned indent = 0) const; 162}; 163 164/// MoveChildMatcherNode - This tells the interpreter to move into the 165/// specified child node. 166class MoveChildMatcherNode : public MatcherNode { 167 unsigned ChildNo; 168public: 169 MoveChildMatcherNode(unsigned childNo) 170 : MatcherNode(MoveChild), ChildNo(childNo) {} 171 172 unsigned getChildNo() const { return ChildNo; } 173 174 static inline bool classof(const MatcherNode *N) { 175 return N->getKind() == MoveChild; 176 } 177 178 virtual void print(raw_ostream &OS, unsigned indent = 0) const; 179}; 180 181/// MoveParentMatcherNode - This tells the interpreter to move to the parent 182/// of the current node. 183class MoveParentMatcherNode : public MatcherNode { 184public: 185 MoveParentMatcherNode() 186 : MatcherNode(MoveParent) {} 187 188 static inline bool classof(const MatcherNode *N) { 189 return N->getKind() == MoveParent; 190 } 191 192 virtual void print(raw_ostream &OS, unsigned indent = 0) const; 193}; 194 195/// CheckSameMatcherNode - This checks to see if this node is exactly the same 196/// node as the specified match that was recorded with 'Record'. This is used 197/// when patterns have the same name in them, like '(mul GPR:$in, GPR:$in)'. 198class CheckSameMatcherNode : public MatcherNode { 199 unsigned MatchNumber; 200public: 201 CheckSameMatcherNode(unsigned matchnumber) 202 : MatcherNode(CheckSame), MatchNumber(matchnumber) {} 203 204 unsigned getMatchNumber() const { return MatchNumber; } 205 206 static inline bool classof(const MatcherNode *N) { 207 return N->getKind() == CheckSame; 208 } 209 210 virtual void print(raw_ostream &OS, unsigned indent = 0) const; 211}; 212 213/// CheckPatternPredicateMatcherNode - This checks the target-specific predicate 214/// to see if the entire pattern is capable of matching. This predicate does 215/// not take a node as input. This is used for subtarget feature checks etc. 216class CheckPatternPredicateMatcherNode : public MatcherNode { 217 std::string Predicate; 218public: 219 CheckPatternPredicateMatcherNode(StringRef predicate) 220 : MatcherNode(CheckPatternPredicate), Predicate(predicate) {} 221 222 StringRef getPredicate() const { return Predicate; } 223 224 static inline bool classof(const MatcherNode *N) { 225 return N->getKind() == CheckPatternPredicate; 226 } 227 228 virtual void print(raw_ostream &OS, unsigned indent = 0) const; 229}; 230 231/// CheckPredicateMatcherNode - This checks the target-specific predicate to 232/// see if the node is acceptable. 233class CheckPredicateMatcherNode : public MatcherNode { 234 StringRef PredName; 235public: 236 CheckPredicateMatcherNode(StringRef predname) 237 : MatcherNode(CheckPredicate), PredName(predname) {} 238 239 StringRef getPredicateName() const { return PredName; } 240 241 static inline bool classof(const MatcherNode *N) { 242 return N->getKind() == CheckPredicate; 243 } 244 245 virtual void print(raw_ostream &OS, unsigned indent = 0) const; 246}; 247 248 249/// CheckOpcodeMatcherNode - This checks to see if the current node has the 250/// specified opcode, if not it fails to match. 251class CheckOpcodeMatcherNode : public MatcherNode { 252 StringRef OpcodeName; 253public: 254 CheckOpcodeMatcherNode(StringRef opcodename) 255 : MatcherNode(CheckOpcode), OpcodeName(opcodename) {} 256 257 StringRef getOpcodeName() const { return OpcodeName; } 258 259 static inline bool classof(const MatcherNode *N) { 260 return N->getKind() == CheckOpcode; 261 } 262 263 virtual void print(raw_ostream &OS, unsigned indent = 0) const; 264}; 265 266/// CheckMultiOpcodeMatcherNode - This checks to see if the current node has one 267/// of the specified opcode, if not it fails to match. 268class CheckMultiOpcodeMatcherNode : public MatcherNode { 269 SmallVector<StringRef, 4> OpcodeNames; 270public: 271 CheckMultiOpcodeMatcherNode(const StringRef *opcodes, unsigned numops) 272 : MatcherNode(CheckMultiOpcode), OpcodeNames(opcodes, opcodes+numops) {} 273 274 unsigned getNumOpcodeNames() const { return OpcodeNames.size(); } 275 StringRef getOpcodeName(unsigned i) const { return OpcodeNames[i]; } 276 277 static inline bool classof(const MatcherNode *N) { 278 return N->getKind() == CheckMultiOpcode; 279 } 280 281 virtual void print(raw_ostream &OS, unsigned indent = 0) const; 282}; 283 284 285 286/// CheckTypeMatcherNode - This checks to see if the current node has the 287/// specified type, if not it fails to match. 288class CheckTypeMatcherNode : public MatcherNode { 289 MVT::SimpleValueType Type; 290public: 291 CheckTypeMatcherNode(MVT::SimpleValueType type) 292 : MatcherNode(CheckType), Type(type) {} 293 294 MVT::SimpleValueType getType() const { return Type; } 295 296 static inline bool classof(const MatcherNode *N) { 297 return N->getKind() == CheckType; 298 } 299 300 virtual void print(raw_ostream &OS, unsigned indent = 0) const; 301}; 302 303/// CheckIntegerMatcherNode - This checks to see if the current node is a 304/// ConstantSDNode with the specified integer value, if not it fails to match. 305class CheckIntegerMatcherNode : public MatcherNode { 306 int64_t Value; 307public: 308 CheckIntegerMatcherNode(int64_t value) 309 : MatcherNode(CheckInteger), Value(value) {} 310 311 int64_t getValue() const { return Value; } 312 313 static inline bool classof(const MatcherNode *N) { 314 return N->getKind() == CheckInteger; 315 } 316 317 virtual void print(raw_ostream &OS, unsigned indent = 0) const; 318}; 319 320/// CheckCondCodeMatcherNode - This checks to see if the current node is a 321/// CondCodeSDNode with the specified condition, if not it fails to match. 322class CheckCondCodeMatcherNode : public MatcherNode { 323 StringRef CondCodeName; 324public: 325 CheckCondCodeMatcherNode(StringRef condcodename) 326 : MatcherNode(CheckCondCode), CondCodeName(condcodename) {} 327 328 StringRef getCondCodeName() const { return CondCodeName; } 329 330 static inline bool classof(const MatcherNode *N) { 331 return N->getKind() == CheckCondCode; 332 } 333 334 virtual void print(raw_ostream &OS, unsigned indent = 0) const; 335}; 336 337/// CheckValueTypeMatcherNode - This checks to see if the current node is a 338/// VTSDNode with the specified type, if not it fails to match. 339class CheckValueTypeMatcherNode : public MatcherNode { 340 StringRef TypeName; 341public: 342 CheckValueTypeMatcherNode(StringRef type_name) 343 : MatcherNode(CheckValueType), TypeName(type_name) {} 344 345 StringRef getTypeName() const { return TypeName; } 346 347 static inline bool classof(const MatcherNode *N) { 348 return N->getKind() == CheckValueType; 349 } 350 351 virtual void print(raw_ostream &OS, unsigned indent = 0) const; 352}; 353 354 355 356/// CheckComplexPatMatcherNode - This node runs the specified ComplexPattern on 357/// the current node. 358class CheckComplexPatMatcherNode : public MatcherNode { 359 const ComplexPattern &Pattern; 360public: 361 CheckComplexPatMatcherNode(const ComplexPattern &pattern) 362 : MatcherNode(CheckComplexPat), Pattern(pattern) {} 363 364 const ComplexPattern &getPattern() const { return Pattern; } 365 366 static inline bool classof(const MatcherNode *N) { 367 return N->getKind() == CheckComplexPat; 368 } 369 370 virtual void print(raw_ostream &OS, unsigned indent = 0) const; 371}; 372 373/// CheckAndImmMatcherNode - This checks to see if the current node is an 'and' 374/// with something equivalent to the specified immediate. 375class CheckAndImmMatcherNode : public MatcherNode { 376 int64_t Value; 377public: 378 CheckAndImmMatcherNode(int64_t value) 379 : MatcherNode(CheckAndImm), Value(value) {} 380 381 int64_t getValue() const { return Value; } 382 383 static inline bool classof(const MatcherNode *N) { 384 return N->getKind() == CheckAndImm; 385 } 386 387 virtual void print(raw_ostream &OS, unsigned indent = 0) const; 388}; 389 390/// CheckOrImmMatcherNode - This checks to see if the current node is an 'and' 391/// with something equivalent to the specified immediate. 392class CheckOrImmMatcherNode : public MatcherNode { 393 int64_t Value; 394public: 395 CheckOrImmMatcherNode(int64_t value) 396 : MatcherNode(CheckOrImm), Value(value) {} 397 398 int64_t getValue() const { return Value; } 399 400 static inline bool classof(const MatcherNode *N) { 401 return N->getKind() == CheckOrImm; 402 } 403 404 virtual void print(raw_ostream &OS, unsigned indent = 0) const; 405}; 406 407/// CheckFoldableChainNodeMatcherNode - This checks to see if the current node 408/// (which defines a chain operand) is safe to fold into a larger pattern. 409class CheckFoldableChainNodeMatcherNode : public MatcherNode { 410public: 411 CheckFoldableChainNodeMatcherNode() 412 : MatcherNode(CheckFoldableChainNode) {} 413 414 static inline bool classof(const MatcherNode *N) { 415 return N->getKind() == CheckFoldableChainNode; 416 } 417 418 virtual void print(raw_ostream &OS, unsigned indent = 0) const; 419}; 420 421/// CheckChainCompatibleMatcherNode - Verify that the current node's chain 422/// operand is 'compatible' with the specified recorded node's. 423class CheckChainCompatibleMatcherNode : public MatcherNode { 424 unsigned PreviousOp; 425public: 426 CheckChainCompatibleMatcherNode(unsigned previousop) 427 : MatcherNode(CheckChainCompatible), PreviousOp(previousop) {} 428 429 unsigned getPreviousOp() const { return PreviousOp; } 430 431 static inline bool classof(const MatcherNode *N) { 432 return N->getKind() == CheckChainCompatible; 433 } 434 435 virtual void print(raw_ostream &OS, unsigned indent = 0) const; 436}; 437 438/// EmitIntegerMatcherNode - This creates a new TargetConstant. 439class EmitIntegerMatcherNode : public MatcherNode { 440 int64_t Val; 441 MVT::SimpleValueType VT; 442public: 443 EmitIntegerMatcherNode(int64_t val, MVT::SimpleValueType vt) 444 : MatcherNode(EmitInteger), Val(val), VT(vt) {} 445 446 int64_t getValue() const { return Val; } 447 MVT::SimpleValueType getVT() const { return VT; } 448 449 static inline bool classof(const MatcherNode *N) { 450 return N->getKind() == EmitInteger; 451 } 452 453 virtual void print(raw_ostream &OS, unsigned indent = 0) const; 454}; 455 456/// EmitStringIntegerMatcherNode - A target constant whose value is represented 457/// by a string. 458class EmitStringIntegerMatcherNode : public MatcherNode { 459 std::string Val; 460 MVT::SimpleValueType VT; 461public: 462 EmitStringIntegerMatcherNode(const std::string &val, MVT::SimpleValueType vt) 463 : MatcherNode(EmitStringInteger), Val(val), VT(vt) {} 464 465 const std::string &getValue() const { return Val; } 466 MVT::SimpleValueType getVT() const { return VT; } 467 468 static inline bool classof(const MatcherNode *N) { 469 return N->getKind() == EmitStringInteger; 470 } 471 472 virtual void print(raw_ostream &OS, unsigned indent = 0) const; 473}; 474 475/// EmitRegisterMatcherNode - This creates a new TargetConstant. 476class EmitRegisterMatcherNode : public MatcherNode { 477 /// Reg - The def for the register that we're emitting. If this is null, then 478 /// this is a reference to zero_reg. 479 Record *Reg; 480 MVT::SimpleValueType VT; 481public: 482 EmitRegisterMatcherNode(Record *reg, MVT::SimpleValueType vt) 483 : MatcherNode(EmitRegister), Reg(reg), VT(vt) {} 484 485 Record *getReg() const { return Reg; } 486 MVT::SimpleValueType getVT() const { return VT; } 487 488 static inline bool classof(const MatcherNode *N) { 489 return N->getKind() == EmitRegister; 490 } 491 492 virtual void print(raw_ostream &OS, unsigned indent = 0) const; 493}; 494 495/// EmitConvertToTargetMatcherNode - Emit an operation that reads a specified 496/// recorded node and converts it from being a ISD::Constant to 497/// ISD::TargetConstant, likewise for ConstantFP. 498class EmitConvertToTargetMatcherNode : public MatcherNode { 499 unsigned Slot; 500public: 501 EmitConvertToTargetMatcherNode(unsigned slot) 502 : MatcherNode(EmitConvertToTarget), Slot(slot) {} 503 504 unsigned getSlot() const { return Slot; } 505 506 static inline bool classof(const MatcherNode *N) { 507 return N->getKind() == EmitConvertToTarget; 508 } 509 510 virtual void print(raw_ostream &OS, unsigned indent = 0) const; 511}; 512 513/// EmitMergeInputChainsMatcherNode - Emit a node that merges a list of input 514/// chains together with a token factor. The list of nodes are the nodes in the 515/// matched pattern that have chain input/outputs. This node adds all input 516/// chains of these nodes if they are not themselves a node in the pattern. 517class EmitMergeInputChainsMatcherNode : public MatcherNode { 518 SmallVector<unsigned, 3> ChainNodes; 519public: 520 EmitMergeInputChainsMatcherNode(const unsigned *nodes, unsigned NumNodes) 521 : MatcherNode(EmitMergeInputChains), ChainNodes(nodes, nodes+NumNodes) {} 522 523 unsigned getNumNodes() const { return ChainNodes.size(); } 524 525 unsigned getNode(unsigned i) const { 526 assert(i < ChainNodes.size()); 527 return ChainNodes[i]; 528 } 529 530 static inline bool classof(const MatcherNode *N) { 531 return N->getKind() == EmitMergeInputChains; 532 } 533 534 virtual void print(raw_ostream &OS, unsigned indent = 0) const; 535}; 536 537/// EmitCopyToRegMatcherNode - Emit a CopyToReg node from a value to a physreg, 538/// pushing the chain and flag results. 539/// 540class EmitCopyToRegMatcherNode : public MatcherNode { 541 unsigned SrcSlot; // Value to copy into the physreg. 542 Record *DestPhysReg; 543public: 544 EmitCopyToRegMatcherNode(unsigned srcSlot, Record *destPhysReg) 545 : MatcherNode(EmitCopyToReg), SrcSlot(srcSlot), DestPhysReg(destPhysReg) {} 546 547 unsigned getSrcSlot() const { return SrcSlot; } 548 Record *getDestPhysReg() const { return DestPhysReg; } 549 550 static inline bool classof(const MatcherNode *N) { 551 return N->getKind() == EmitCopyToReg; 552 } 553 554 virtual void print(raw_ostream &OS, unsigned indent = 0) const; 555}; 556 557 558 559/// EmitNodeXFormMatcherNode - Emit an operation that runs an SDNodeXForm on a 560/// recorded node and records the result. 561class EmitNodeXFormMatcherNode : public MatcherNode { 562 unsigned Slot; 563 Record *NodeXForm; 564public: 565 EmitNodeXFormMatcherNode(unsigned slot, Record *nodeXForm) 566 : MatcherNode(EmitNodeXForm), Slot(slot), NodeXForm(nodeXForm) {} 567 568 unsigned getSlot() const { return Slot; } 569 Record *getNodeXForm() const { return NodeXForm; } 570 571 static inline bool classof(const MatcherNode *N) { 572 return N->getKind() == EmitNodeXForm; 573 } 574 575 virtual void print(raw_ostream &OS, unsigned indent = 0) const; 576}; 577 578/// EmitNodeMatcherNode - This signals a successful match and generates a node. 579class EmitNodeMatcherNode : public MatcherNode { 580 std::string OpcodeName; 581 const SmallVector<MVT::SimpleValueType, 3> VTs; 582 const SmallVector<unsigned, 6> Operands; 583 bool HasChain, HasFlag, HasMemRefs; 584 585 /// NumFixedArityOperands - If this is a fixed arity node, this is set to -1. 586 /// If this is a varidic node, this is set to the number of fixed arity 587 /// operands in the root of the pattern. The rest are appended to this node. 588 int NumFixedArityOperands; 589public: 590 EmitNodeMatcherNode(const std::string &opcodeName, 591 const MVT::SimpleValueType *vts, unsigned numvts, 592 const unsigned *operands, unsigned numops, 593 bool hasChain, bool hasFlag, bool hasmemrefs, 594 int numfixedarityoperands) 595 : MatcherNode(EmitNode), OpcodeName(opcodeName), 596 VTs(vts, vts+numvts), Operands(operands, operands+numops), 597 HasChain(hasChain), HasFlag(hasFlag), HasMemRefs(hasmemrefs), 598 NumFixedArityOperands(numfixedarityoperands) {} 599 600 const std::string &getOpcodeName() const { return OpcodeName; } 601 602 unsigned getNumVTs() const { return VTs.size(); } 603 MVT::SimpleValueType getVT(unsigned i) const { 604 assert(i < VTs.size()); 605 return VTs[i]; 606 } 607 608 unsigned getNumOperands() const { return Operands.size(); } 609 unsigned getOperand(unsigned i) const { 610 assert(i < Operands.size()); 611 return Operands[i]; 612 } 613 614 bool hasChain() const { return HasChain; } 615 bool hasFlag() const { return HasFlag; } 616 bool hasMemRefs() const { return HasMemRefs; } 617 int getNumFixedArityOperands() const { return NumFixedArityOperands; } 618 619 static inline bool classof(const MatcherNode *N) { 620 return N->getKind() == EmitNode; 621 } 622 623 virtual void print(raw_ostream &OS, unsigned indent = 0) const; 624}; 625 626/// CompleteMatchMatcherNode - Complete a match by replacing the results of the 627/// pattern with the newly generated nodes. This also prints a comment 628/// indicating the source and dest patterns. 629class CompleteMatchMatcherNode : public MatcherNode { 630 SmallVector<unsigned, 2> Results; 631 const PatternToMatch &Pattern; 632public: 633 CompleteMatchMatcherNode(const unsigned *results, unsigned numresults, 634 const PatternToMatch &pattern) 635 : MatcherNode(CompleteMatch), Results(results, results+numresults), 636 Pattern(pattern) {} 637 638 unsigned getNumResults() const { return Results.size(); } 639 unsigned getResult(unsigned R) const { return Results[R]; } 640 const PatternToMatch &getPattern() const { return Pattern; } 641 642 static inline bool classof(const MatcherNode *N) { 643 return N->getKind() == CompleteMatch; 644 } 645 646 virtual void print(raw_ostream &OS, unsigned indent = 0) const; 647}; 648 649 650} // end namespace llvm 651 652#endif 653