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