154 lines
4.7 KiB
C++
154 lines
4.7 KiB
C++
//===- 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 << "<empty>";
|
|
return;
|
|
}
|
|
StringRef Separator = "";
|
|
for (const auto &I : Operands) {
|
|
OS << Separator << I.getIdx() << ":" << I.getName();
|
|
if (I.isDef())
|
|
OS << "<def>";
|
|
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<GIMatchDagOperandList> NewValue =
|
|
std::make_unique<GIMatchDagOperandList>();
|
|
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<GIMatchDagOperandList> NewValue =
|
|
std::make_unique<GIMatchDagOperandList>();
|
|
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<GIMatchDagOperandList> NewValue =
|
|
std::make_unique<GIMatchDagOperandList>();
|
|
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<GIMatchDagOperandList> NewValue =
|
|
std::make_unique<GIMatchDagOperandList>();
|
|
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";
|
|
}
|