1 //===- GIMatchDagOperands.cpp - 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 #include "GIMatchDagOperands.h" 10 11 #include "../CodeGenInstruction.h" 12 13 using namespace llvm; 14 15 void GIMatchDagOperand::Profile(FoldingSetNodeID &ID) const { 16 Profile(ID, Idx, Name, IsDef); 17 } 18 19 void GIMatchDagOperand::Profile(FoldingSetNodeID &ID, size_t Idx, 20 StringRef Name, bool IsDef) { 21 ID.AddInteger(Idx); 22 ID.AddString(Name); 23 ID.AddBoolean(IsDef); 24 } 25 26 void GIMatchDagOperandList::add(StringRef Name, unsigned Idx, bool IsDef) { 27 assert(Idx == Operands.size() && "Operands added in wrong order"); 28 Operands.emplace_back(Operands.size(), Name, IsDef); 29 OperandsByName.try_emplace(Operands.back().getName(), Operands.size() - 1); 30 } 31 32 void GIMatchDagOperandList::Profile(FoldingSetNodeID &ID) const { 33 for (const auto &I : enumerate(Operands)) 34 GIMatchDagOperand::Profile(ID, I.index(), I.value().getName(), 35 I.value().isDef()); 36 } 37 38 void GIMatchDagOperandList::print(raw_ostream &OS) const { 39 if (Operands.empty()) { 40 OS << "<empty>"; 41 return; 42 } 43 StringRef Separator = ""; 44 for (const auto &I : Operands) { 45 OS << Separator << I.getIdx() << ":" << I.getName(); 46 if (I.isDef()) 47 OS << "<def>"; 48 Separator = ", "; 49 } 50 } 51 52 const GIMatchDagOperandList::value_type &GIMatchDagOperandList:: 53 operator[](StringRef K) const { 54 const auto &I = OperandsByName.find(K); 55 assert(I != OperandsByName.end() && "Operand not found by name"); 56 return Operands[I->second]; 57 } 58 59 const GIMatchDagOperandList & 60 GIMatchDagOperandListContext::makeEmptyOperandList() { 61 FoldingSetNodeID ID; 62 63 void *InsertPoint; 64 GIMatchDagOperandList *Value = 65 OperandLists.FindNodeOrInsertPos(ID, InsertPoint); 66 if (Value) 67 return *Value; 68 69 std::unique_ptr<GIMatchDagOperandList> NewValue = 70 std::make_unique<GIMatchDagOperandList>(); 71 OperandLists.InsertNode(NewValue.get(), InsertPoint); 72 OperandListsOwner.push_back(std::move(NewValue)); 73 return *OperandListsOwner.back().get(); 74 } 75 76 const GIMatchDagOperandList & 77 GIMatchDagOperandListContext::makeOperandList(const CodeGenInstruction &I) { 78 FoldingSetNodeID ID; 79 for (unsigned i = 0; i < I.Operands.size(); ++i) 80 GIMatchDagOperand::Profile(ID, i, I.Operands[i].Name, 81 i < I.Operands.NumDefs); 82 83 void *InsertPoint; 84 GIMatchDagOperandList *Value = 85 OperandLists.FindNodeOrInsertPos(ID, InsertPoint); 86 if (Value) 87 return *Value; 88 89 std::unique_ptr<GIMatchDagOperandList> NewValue = 90 std::make_unique<GIMatchDagOperandList>(); 91 for (unsigned i = 0; i < I.Operands.size(); ++i) 92 NewValue->add(I.Operands[i].Name, i, i < I.Operands.NumDefs); 93 OperandLists.InsertNode(NewValue.get(), InsertPoint); 94 OperandListsOwner.push_back(std::move(NewValue)); 95 return *OperandListsOwner.back().get(); 96 } 97 98 const GIMatchDagOperandList & 99 GIMatchDagOperandListContext::makeMIPredicateOperandList() { 100 FoldingSetNodeID ID; 101 GIMatchDagOperand::Profile(ID, 0, "$", true); 102 GIMatchDagOperand::Profile(ID, 1, "mi", false); 103 104 void *InsertPoint; 105 GIMatchDagOperandList *Value = 106 OperandLists.FindNodeOrInsertPos(ID, InsertPoint); 107 if (Value) 108 return *Value; 109 110 std::unique_ptr<GIMatchDagOperandList> NewValue = 111 std::make_unique<GIMatchDagOperandList>(); 112 NewValue->add("$", 0, true); 113 NewValue->add("mi", 1, false); 114 OperandLists.InsertNode(NewValue.get(), InsertPoint); 115 OperandListsOwner.push_back(std::move(NewValue)); 116 return *OperandListsOwner.back().get(); 117 } 118 119 120 const GIMatchDagOperandList & 121 GIMatchDagOperandListContext::makeTwoMOPredicateOperandList() { 122 FoldingSetNodeID ID; 123 GIMatchDagOperand::Profile(ID, 0, "$", true); 124 GIMatchDagOperand::Profile(ID, 1, "mi0", false); 125 GIMatchDagOperand::Profile(ID, 2, "mi1", false); 126 127 void *InsertPoint; 128 GIMatchDagOperandList *Value = 129 OperandLists.FindNodeOrInsertPos(ID, InsertPoint); 130 if (Value) 131 return *Value; 132 133 std::unique_ptr<GIMatchDagOperandList> NewValue = 134 std::make_unique<GIMatchDagOperandList>(); 135 NewValue->add("$", 0, true); 136 NewValue->add("mi0", 1, false); 137 NewValue->add("mi1", 2, false); 138 OperandLists.InsertNode(NewValue.get(), InsertPoint); 139 OperandListsOwner.push_back(std::move(NewValue)); 140 return *OperandListsOwner.back().get(); 141 } 142 143 void GIMatchDagOperandListContext::print(raw_ostream &OS) const { 144 OS << "GIMatchDagOperandListContext {\n" 145 << " OperandLists {\n"; 146 for (const auto &I : OperandListsOwner) { 147 OS << " "; 148 I->print(OS); 149 OS << "\n"; 150 } 151 OS << " }\n" 152 << "}\n"; 153 } 154