1 //===- GIMatchDagOperands.h - Represent a shared operand list for nodes ---===// 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 // 10 //===----------------------------------------------------------------------===// 11 12 #ifndef LLVM_UTILS_TABLEGEN_GIMATCHDAGOPERANDS_H 13 #define LLVM_UTILS_TABLEGEN_GIMATCHDAGOPERANDS_H 14 15 #include "llvm/ADT/FoldingSet.h" 16 #include "llvm/ADT/StringMap.h" 17 #include "llvm/ADT/StringRef.h" 18 #include "llvm/Support/raw_ostream.h" 19 20 #include <vector> 21 22 namespace llvm { 23 class CodeGenInstruction; 24 /// Describes an operand of a MachineInstr w.r.t the DAG Matching. This 25 /// information is derived from CodeGenInstruction::Operands but is more 26 /// readily available for context-less access as we don't need to know which 27 /// instruction it's used with or know how many defs that instruction had. 28 /// 29 /// There may be multiple GIMatchDagOperand's with the same contents. However, 30 /// they are uniqued within the set of instructions that have the same overall 31 /// operand list. For example, given: 32 /// Inst1 operands ($dst:<def>, $src1, $src2) 33 /// Inst2 operands ($dst:<def>, $src1, $src2) 34 /// Inst3 operands ($dst:<def>, $src) 35 /// $src1 will have a single instance of GIMatchDagOperand shared by Inst1 and 36 /// Inst2, as will $src2. $dst however, will have two instances one shared 37 /// between Inst1 and Inst2 and one unique to Inst3. We could potentially 38 /// fully de-dupe the GIMatchDagOperand instances but the saving is not expected 39 /// to be worth the overhead. 40 /// 41 /// The result of this is that the address of the object can be relied upon to 42 /// trivially identify commonality between two instructions which will be useful 43 /// when generating the matcher. When the pointers differ, the contents can be 44 /// inspected instead. 45 class GIMatchDagOperand { 46 unsigned Idx; 47 StringRef Name; 48 bool IsDef; 49 50 public: GIMatchDagOperand(unsigned Idx,StringRef Name,bool IsDef)51 GIMatchDagOperand(unsigned Idx, StringRef Name, bool IsDef) 52 : Idx(Idx), Name(Name), IsDef(IsDef) {} 53 getIdx()54 unsigned getIdx() const { return Idx; } getName()55 StringRef getName() const { return Name; } isDef()56 bool isDef() const { return IsDef; } 57 58 /// This object isn't a FoldingSetNode but it's part of one. See FoldingSet 59 /// for details on the Profile function. 60 void Profile(FoldingSetNodeID &ID) const; 61 62 /// A helper that behaves like Profile() but is also usable without the object. 63 /// We use size_t here to match enumerate<...>::index(). If we don't match 64 /// that the hashes won't be equal. 65 static void Profile(FoldingSetNodeID &ID, size_t Idx, StringRef Name, 66 bool IsDef); 67 }; 68 69 /// A list of GIMatchDagOperands for an instruction without any association with 70 /// a particular instruction. 71 /// 72 /// An important detail to be aware of with this class is that they are shared 73 /// with other instructions of a similar 'shape'. For example, all the binary 74 /// instructions are likely to share a single GIMatchDagOperandList. This is 75 /// primarily a memory optimization as it's fairly common to have a large number 76 /// of instructions but only a few 'shapes'. 77 /// 78 /// See GIMatchDagOperandList::Profile() for the details on how they are folded. 79 class GIMatchDagOperandList : public FoldingSetNode { 80 public: 81 using value_type = GIMatchDagOperand; 82 83 protected: 84 using vector_type = SmallVector<GIMatchDagOperand, 3>; 85 86 public: 87 using iterator = vector_type::iterator; 88 using const_iterator = vector_type::const_iterator; 89 90 protected: 91 vector_type Operands; 92 StringMap<unsigned> OperandsByName; 93 94 public: 95 void add(StringRef Name, unsigned Idx, bool IsDef); 96 97 /// See FoldingSet for details. 98 void Profile(FoldingSetNodeID &ID) const; 99 begin()100 iterator begin() { return Operands.begin(); } begin()101 const_iterator begin() const { return Operands.begin(); } end()102 iterator end() { return Operands.end(); } end()103 const_iterator end() const { return Operands.end(); } 104 105 const value_type &operator[](unsigned I) const { return Operands[I]; } 106 const value_type &operator[](StringRef K) const; 107 108 void print(raw_ostream &OS) const; 109 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) dump()110 LLVM_DUMP_METHOD void dump() const { print(errs()); } 111 #endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 112 }; 113 114 /// This is the portion of GIMatchDagContext that directly relates to 115 /// GIMatchDagOperandList and GIMatchDagOperandList. 116 class GIMatchDagOperandListContext { 117 FoldingSet<GIMatchDagOperandList> OperandLists; 118 std::vector<std::unique_ptr<GIMatchDagOperandList>> OperandListsOwner; 119 120 public: 121 const GIMatchDagOperandList &makeEmptyOperandList(); 122 const GIMatchDagOperandList &makeOperandList(const CodeGenInstruction &I); 123 const GIMatchDagOperandList &makeMIPredicateOperandList(); 124 const GIMatchDagOperandList &makeTwoMOPredicateOperandList(); 125 126 void print(raw_ostream &OS) const; 127 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) dump()128 LLVM_DUMP_METHOD void dump() const { print(errs()); } 129 #endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 130 }; 131 132 } // end namespace llvm 133 #endif // ifndef LLVM_UTILS_TABLEGEN_GIMATCHDAGOPERANDS_H 134