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
Profile(FoldingSetNodeID & ID) const15 void GIMatchDagOperand::Profile(FoldingSetNodeID &ID) const {
16 Profile(ID, Idx, Name, IsDef);
17 }
18
Profile(FoldingSetNodeID & ID,size_t Idx,StringRef Name,bool IsDef)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
add(StringRef Name,unsigned Idx,bool IsDef)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
Profile(FoldingSetNodeID & ID) const32 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
print(raw_ostream & OS) const38 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::
operator [](StringRef K) const53 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 &
makeEmptyOperandList()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 &
makeOperandList(const CodeGenInstruction & I)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 &
makeMIPredicateOperandList()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 &
makeTwoMOPredicateOperandList()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
print(raw_ostream & OS) const143 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