//===- GIMatchDagOperands.cpp - A shared operand list for nodes -----------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "GIMatchDagOperands.h" #include "../CodeGenInstruction.h" using namespace llvm; void GIMatchDagOperand::Profile(FoldingSetNodeID &ID) const { Profile(ID, Idx, Name, IsDef); } void GIMatchDagOperand::Profile(FoldingSetNodeID &ID, size_t Idx, StringRef Name, bool IsDef) { ID.AddInteger(Idx); ID.AddString(Name); ID.AddBoolean(IsDef); } void GIMatchDagOperandList::add(StringRef Name, unsigned Idx, bool IsDef) { assert(Idx == Operands.size() && "Operands added in wrong order"); Operands.emplace_back(Operands.size(), Name, IsDef); OperandsByName.try_emplace(Operands.back().getName(), Operands.size() - 1); } void GIMatchDagOperandList::Profile(FoldingSetNodeID &ID) const { for (const auto &I : enumerate(Operands)) GIMatchDagOperand::Profile(ID, I.index(), I.value().getName(), I.value().isDef()); } void GIMatchDagOperandList::print(raw_ostream &OS) const { if (Operands.empty()) { OS << ""; return; } StringRef Separator = ""; for (const auto &I : Operands) { OS << Separator << I.getIdx() << ":" << I.getName(); if (I.isDef()) OS << ""; Separator = ", "; } } const GIMatchDagOperandList::value_type &GIMatchDagOperandList:: operator[](StringRef K) const { const auto &I = OperandsByName.find(K); assert(I != OperandsByName.end() && "Operand not found by name"); return Operands[I->second]; } const GIMatchDagOperandList & GIMatchDagOperandListContext::makeEmptyOperandList() { FoldingSetNodeID ID; void *InsertPoint; GIMatchDagOperandList *Value = OperandLists.FindNodeOrInsertPos(ID, InsertPoint); if (Value) return *Value; std::unique_ptr NewValue = std::make_unique(); OperandLists.InsertNode(NewValue.get(), InsertPoint); OperandListsOwner.push_back(std::move(NewValue)); return *OperandListsOwner.back().get(); } const GIMatchDagOperandList & GIMatchDagOperandListContext::makeOperandList(const CodeGenInstruction &I) { FoldingSetNodeID ID; for (unsigned i = 0; i < I.Operands.size(); ++i) GIMatchDagOperand::Profile(ID, i, I.Operands[i].Name, i < I.Operands.NumDefs); void *InsertPoint; GIMatchDagOperandList *Value = OperandLists.FindNodeOrInsertPos(ID, InsertPoint); if (Value) return *Value; std::unique_ptr NewValue = std::make_unique(); for (unsigned i = 0; i < I.Operands.size(); ++i) NewValue->add(I.Operands[i].Name, i, i < I.Operands.NumDefs); OperandLists.InsertNode(NewValue.get(), InsertPoint); OperandListsOwner.push_back(std::move(NewValue)); return *OperandListsOwner.back().get(); } const GIMatchDagOperandList & GIMatchDagOperandListContext::makeMIPredicateOperandList() { FoldingSetNodeID ID; GIMatchDagOperand::Profile(ID, 0, "$", true); GIMatchDagOperand::Profile(ID, 1, "mi", false); void *InsertPoint; GIMatchDagOperandList *Value = OperandLists.FindNodeOrInsertPos(ID, InsertPoint); if (Value) return *Value; std::unique_ptr NewValue = std::make_unique(); NewValue->add("$", 0, true); NewValue->add("mi", 1, false); OperandLists.InsertNode(NewValue.get(), InsertPoint); OperandListsOwner.push_back(std::move(NewValue)); return *OperandListsOwner.back().get(); } const GIMatchDagOperandList & GIMatchDagOperandListContext::makeTwoMOPredicateOperandList() { FoldingSetNodeID ID; GIMatchDagOperand::Profile(ID, 0, "$", true); GIMatchDagOperand::Profile(ID, 1, "mi0", false); GIMatchDagOperand::Profile(ID, 2, "mi1", false); void *InsertPoint; GIMatchDagOperandList *Value = OperandLists.FindNodeOrInsertPos(ID, InsertPoint); if (Value) return *Value; std::unique_ptr NewValue = std::make_unique(); NewValue->add("$", 0, true); NewValue->add("mi0", 1, false); NewValue->add("mi1", 2, false); OperandLists.InsertNode(NewValue.get(), InsertPoint); OperandListsOwner.push_back(std::move(NewValue)); return *OperandListsOwner.back().get(); } void GIMatchDagOperandListContext::print(raw_ostream &OS) const { OS << "GIMatchDagOperandListContext {\n" << " OperandLists {\n"; for (const auto &I : OperandListsOwner) { OS << " "; I->print(OS); OS << "\n"; } OS << " }\n" << "}\n"; }