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 15namespace llvm { 16class CodeExpansions; 17class CodeGenInstruction; 18class GIMatchDagOperandList; 19class GIMatchDagContext; 20class 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. 27class GIMatchDagPredicate { 28public: 29 enum GIMatchDagPredicateKind { 30 GIMatchDagPredicateKind_Opcode, 31 GIMatchDagPredicateKind_OneOfOpcodes, 32 GIMatchDagPredicateKind_SameMO, 33 }; 34 35protected: 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 50public: 51 GIMatchDagPredicate(GIMatchDagPredicateKind Kind, StringRef Name, 52 const GIMatchDagOperandList &OperandInfo) 53 : Kind(Kind), Name(Name), OperandInfo(OperandInfo) {} 54 virtual ~GIMatchDagPredicate() {} 55 56 GIMatchDagPredicateKind getKind() const { return Kind; } 57 58 StringRef getName() const { return Name; } 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. 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) 75 virtual LLVM_DUMP_METHOD void dump() const { print(errs()); } 76#endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 77}; 78 79class GIMatchDagOpcodePredicate : public GIMatchDagPredicate { 80 const CodeGenInstruction &Instr; 81 82public: 83 GIMatchDagOpcodePredicate(GIMatchDagContext &Ctx, StringRef Name, 84 const CodeGenInstruction &Instr); 85 86 static bool classof(const GIMatchDagPredicate *P) { 87 return P->getKind() == GIMatchDagPredicateKind_Opcode; 88 } 89 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) 95 virtual LLVM_DUMP_METHOD void dump() const override { print(errs()); } 96#endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 97}; 98 99class GIMatchDagOneOfOpcodesPredicate : public GIMatchDagPredicate { 100 SmallVector<const CodeGenInstruction *, 4> Instrs; 101 102public: 103 GIMatchDagOneOfOpcodesPredicate(GIMatchDagContext &Ctx, StringRef Name); 104 105 void addOpcode(const CodeGenInstruction *Instr) { Instrs.push_back(Instr); } 106 107 static bool classof(const GIMatchDagPredicate *P) { 108 return P->getKind() == GIMatchDagPredicateKind_OneOfOpcodes; 109 } 110 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) 118 virtual LLVM_DUMP_METHOD void dump() const override { print(errs()); } 119#endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 120}; 121 122class GIMatchDagSameMOPredicate : public GIMatchDagPredicate { 123public: 124 GIMatchDagSameMOPredicate(GIMatchDagContext &Ctx, StringRef Name); 125 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) 133 virtual LLVM_DUMP_METHOD void dump() const override { print(errs()); } 134#endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 135}; 136 137raw_ostream &operator<<(raw_ostream &OS, const GIMatchDagPredicate &N); 138raw_ostream &operator<<(raw_ostream &OS, const GIMatchDagOpcodePredicate &N); 139 140} // end namespace llvm 141#endif // ifndef LLVM_UTILS_TABLEGEN_GIMATCHDAGPREDICATE_H 142