1 //===- GIMatchDagPredicate - Represent a predicate to check ---------------===// 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_GIMATCHDAGPREDICATE_H 10 #define LLVM_UTILS_TABLEGEN_GIMATCHDAGPREDICATE_H 11 12 #include "llvm/ADT/SmallVector.h" 13 #include "llvm/ADT/StringRef.h" 14 15 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 16 #include "llvm/Support/raw_ostream.h" 17 #endif 18 19 namespace llvm { 20 class CodeExpansions; 21 class CodeGenInstruction; 22 class GIMatchDagOperandList; 23 class GIMatchDagContext; 24 class raw_ostream; 25 26 /// Represents a predicate on the match DAG. This records the details of the 27 /// predicate. The dependencies are stored in the GIMatchDag as edges. 28 /// 29 /// Instances of this class objects are owned by the GIMatchDag and are not 30 /// shareable between instances of GIMatchDag. 31 class GIMatchDagPredicate { 32 public: 33 enum GIMatchDagPredicateKind { 34 GIMatchDagPredicateKind_Opcode, 35 GIMatchDagPredicateKind_OneOfOpcodes, 36 GIMatchDagPredicateKind_SameMO, 37 }; 38 39 protected: 40 const GIMatchDagPredicateKind Kind; 41 42 /// The name of the predicate. For example: 43 /// (FOO $a:s32, $b, $c) 44 /// will cause 's32' to be assigned to this member for the $a predicate. 45 /// Similarly, the opcode predicate will cause 'FOO' to be assigned to this 46 /// member. Anonymous instructions will have a name assigned for debugging 47 /// purposes. 48 StringRef Name; 49 50 /// The operand list for this predicate. This object may be shared with 51 /// other predicates of a similar 'shape'. 52 const GIMatchDagOperandList &OperandInfo; 53 54 public: GIMatchDagPredicate(GIMatchDagPredicateKind Kind,StringRef Name,const GIMatchDagOperandList & OperandInfo)55 GIMatchDagPredicate(GIMatchDagPredicateKind Kind, StringRef Name, 56 const GIMatchDagOperandList &OperandInfo) 57 : Kind(Kind), Name(Name), OperandInfo(OperandInfo) {} ~GIMatchDagPredicate()58 virtual ~GIMatchDagPredicate() {} 59 getKind()60 GIMatchDagPredicateKind getKind() const { return Kind; } 61 getName()62 StringRef getName() const { return Name; } getOperandInfo()63 const GIMatchDagOperandList &getOperandInfo() const { return OperandInfo; } 64 65 // Generate C++ code to check this predicate. If a partitioner has already 66 // tested this predicate then this function won't be called. If this function 67 // is called, it must emit code and return true to indicate that it did so. If 68 // it ever returns false, then the caller will abort due to an untested 69 // predicate. generateCheckCode(raw_ostream & OS,StringRef Indent,const CodeExpansions & Expansions)70 virtual bool generateCheckCode(raw_ostream &OS, StringRef Indent, 71 const CodeExpansions &Expansions) const { 72 return false; 73 } 74 75 virtual void print(raw_ostream &OS) const; 76 virtual void printDescription(raw_ostream &OS) const; 77 78 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) dump()79 virtual LLVM_DUMP_METHOD void dump() const { print(errs()); } 80 #endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 81 }; 82 83 class GIMatchDagOpcodePredicate : public GIMatchDagPredicate { 84 const CodeGenInstruction &Instr; 85 86 public: 87 GIMatchDagOpcodePredicate(GIMatchDagContext &Ctx, StringRef Name, 88 const CodeGenInstruction &Instr); 89 classof(const GIMatchDagPredicate * P)90 static bool classof(const GIMatchDagPredicate *P) { 91 return P->getKind() == GIMatchDagPredicateKind_Opcode; 92 } 93 getInstr()94 const CodeGenInstruction *getInstr() const { return &Instr; } 95 96 void printDescription(raw_ostream &OS) const override; 97 98 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) dump()99 LLVM_DUMP_METHOD void dump() const override { print(errs()); } 100 #endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 101 }; 102 103 class GIMatchDagOneOfOpcodesPredicate : public GIMatchDagPredicate { 104 SmallVector<const CodeGenInstruction *, 4> Instrs; 105 106 public: 107 GIMatchDagOneOfOpcodesPredicate(GIMatchDagContext &Ctx, StringRef Name); 108 addOpcode(const CodeGenInstruction * Instr)109 void addOpcode(const CodeGenInstruction *Instr) { Instrs.push_back(Instr); } 110 classof(const GIMatchDagPredicate * P)111 static bool classof(const GIMatchDagPredicate *P) { 112 return P->getKind() == GIMatchDagPredicateKind_OneOfOpcodes; 113 } 114 getInstrs()115 const SmallVectorImpl<const CodeGenInstruction *> &getInstrs() const { 116 return Instrs; 117 } 118 119 void printDescription(raw_ostream &OS) const override; 120 121 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) dump()122 LLVM_DUMP_METHOD void dump() const override { print(errs()); } 123 #endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 124 }; 125 126 class GIMatchDagSameMOPredicate : public GIMatchDagPredicate { 127 public: 128 GIMatchDagSameMOPredicate(GIMatchDagContext &Ctx, StringRef Name); 129 classof(const GIMatchDagPredicate * P)130 static bool classof(const GIMatchDagPredicate *P) { 131 return P->getKind() == GIMatchDagPredicateKind_SameMO; 132 } 133 134 void printDescription(raw_ostream &OS) const override; 135 136 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) dump()137 LLVM_DUMP_METHOD void dump() const override { print(errs()); } 138 #endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 139 }; 140 141 raw_ostream &operator<<(raw_ostream &OS, const GIMatchDagPredicate &N); 142 raw_ostream &operator<<(raw_ostream &OS, const GIMatchDagOpcodePredicate &N); 143 144 } // end namespace llvm 145 #endif // ifndef LLVM_UTILS_TABLEGEN_GIMATCHDAGPREDICATE_H 146