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