aboutsummaryrefslogtreecommitdiff
path: root/llvm/utils/TableGen/InstrInfoEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/utils/TableGen/InstrInfoEmitter.cpp')
-rw-r--r--llvm/utils/TableGen/InstrInfoEmitter.cpp191
1 files changed, 191 insertions, 0 deletions
diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp
index 9ff385faec56..aee887a906e5 100644
--- a/llvm/utils/TableGen/InstrInfoEmitter.cpp
+++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp
@@ -19,6 +19,7 @@
#include "SequenceToOffsetTable.h"
#include "TableGenBackends.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"
@@ -27,6 +28,7 @@
#include "llvm/TableGen/TableGenBackend.h"
#include <cassert>
#include <cstdint>
+#include <iterator>
#include <map>
#include <string>
#include <utility>
@@ -87,6 +89,13 @@ private:
void emitOperandNameMappings(raw_ostream &OS, const CodeGenTarget &Target,
ArrayRef<const CodeGenInstruction*> NumberedInstructions);
+ void emitLogicalOperandSizeMappings(
+ raw_ostream &OS, StringRef Namespace,
+ ArrayRef<const CodeGenInstruction *> NumberedInstructions);
+ void emitLogicalOperandTypeMappings(
+ raw_ostream &OS, StringRef Namespace,
+ ArrayRef<const CodeGenInstruction *> NumberedInstructions);
+
// Operand information.
void EmitOperandInfo(raw_ostream &OS, OperandInfoMapTy &OperandInfoIDs);
std::vector<std::string> GetOperandInfo(const CodeGenInstruction &Inst);
@@ -442,6 +451,182 @@ void InstrInfoEmitter::emitOperandTypeMappings(
OS << "#endif // GET_INSTRINFO_OPERAND_TYPE\n\n";
}
+void InstrInfoEmitter::emitLogicalOperandSizeMappings(
+ raw_ostream &OS, StringRef Namespace,
+ ArrayRef<const CodeGenInstruction *> NumberedInstructions) {
+ std::map<std::vector<unsigned>, unsigned> LogicalOpSizeMap;
+
+ std::map<unsigned, std::vector<std::string>> InstMap;
+
+ size_t LogicalOpListSize = 0U;
+ std::vector<unsigned> LogicalOpList;
+ for (const auto *Inst : NumberedInstructions) {
+ if (!Inst->TheDef->getValueAsBit("UseLogicalOperandMappings"))
+ continue;
+
+ LogicalOpList.clear();
+ llvm::transform(Inst->Operands, std::back_inserter(LogicalOpList),
+ [](const CGIOperandList::OperandInfo &Op) -> unsigned {
+ auto *MIOI = Op.MIOperandInfo;
+ if (!MIOI || MIOI->getNumArgs() == 0)
+ return 1;
+ return MIOI->getNumArgs();
+ });
+ LogicalOpListSize = std::max(LogicalOpList.size(), LogicalOpListSize);
+
+ auto I =
+ LogicalOpSizeMap.insert({LogicalOpList, LogicalOpSizeMap.size()}).first;
+ InstMap[I->second].push_back(
+ (Namespace + "::" + Inst->TheDef->getName()).str());
+ }
+
+ OS << "#ifdef GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n";
+ OS << "#undef GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n";
+ OS << "namespace llvm {\n";
+ OS << "namespace " << Namespace << " {\n";
+ OS << "LLVM_READONLY static unsigned\n";
+ OS << "getLogicalOperandSize(uint16_t Opcode, uint16_t LogicalOpIdx) {\n";
+ if (!InstMap.empty()) {
+ std::vector<const std::vector<unsigned> *> LogicalOpSizeList(
+ LogicalOpSizeMap.size());
+ for (auto &P : LogicalOpSizeMap) {
+ LogicalOpSizeList[P.second] = &P.first;
+ }
+ OS << " static const unsigned SizeMap[][" << LogicalOpListSize
+ << "] = {\n";
+ for (auto &R : LogicalOpSizeList) {
+ const auto &Row = *R;
+ OS << " {";
+ int i;
+ for (i = 0; i < static_cast<int>(Row.size()); ++i) {
+ OS << Row[i] << ", ";
+ }
+ for (; i < static_cast<int>(LogicalOpListSize); ++i) {
+ OS << "0, ";
+ }
+ OS << "}, ";
+ OS << "\n";
+ }
+ OS << " };\n";
+
+ OS << " switch (Opcode) {\n";
+ OS << " default: return LogicalOpIdx;\n";
+ for (auto &P : InstMap) {
+ auto OpMapIdx = P.first;
+ const auto &Insts = P.second;
+ for (const auto &Inst : Insts) {
+ OS << " case " << Inst << ":\n";
+ }
+ OS << " return SizeMap[" << OpMapIdx << "][LogicalOpIdx];\n";
+ }
+ OS << " }\n";
+ } else {
+ OS << " return LogicalOpIdx;\n";
+ }
+ OS << "}\n";
+
+ OS << "LLVM_READONLY static inline unsigned\n";
+ OS << "getLogicalOperandIdx(uint16_t Opcode, uint16_t LogicalOpIdx) {\n";
+ OS << " auto S = 0U;\n";
+ OS << " for (auto i = 0U; i < LogicalOpIdx; ++i)\n";
+ OS << " S += getLogicalOperandSize(Opcode, i);\n";
+ OS << " return S;\n";
+ OS << "}\n";
+
+ OS << "} // end namespace " << Namespace << "\n";
+ OS << "} // end namespace llvm\n";
+ OS << "#endif // GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n\n";
+}
+
+void InstrInfoEmitter::emitLogicalOperandTypeMappings(
+ raw_ostream &OS, StringRef Namespace,
+ ArrayRef<const CodeGenInstruction *> NumberedInstructions) {
+ std::map<std::vector<std::string>, unsigned> LogicalOpTypeMap;
+
+ std::map<unsigned, std::vector<std::string>> InstMap;
+
+ size_t OpTypeListSize = 0U;
+ std::vector<std::string> LogicalOpTypeList;
+ for (const auto *Inst : NumberedInstructions) {
+ if (!Inst->TheDef->getValueAsBit("UseLogicalOperandMappings"))
+ continue;
+
+ LogicalOpTypeList.clear();
+ for (const auto &Op : Inst->Operands) {
+ auto *OpR = Op.Rec;
+ if ((OpR->isSubClassOf("Operand") ||
+ OpR->isSubClassOf("RegisterOperand") ||
+ OpR->isSubClassOf("RegisterClass")) &&
+ !OpR->isAnonymous()) {
+ LogicalOpTypeList.push_back(
+ (Namespace + "::OpTypes::" + Op.Rec->getName()).str());
+ } else {
+ LogicalOpTypeList.push_back("-1");
+ }
+ }
+ OpTypeListSize = std::max(LogicalOpTypeList.size(), OpTypeListSize);
+
+ auto I =
+ LogicalOpTypeMap.insert({LogicalOpTypeList, LogicalOpTypeMap.size()})
+ .first;
+ InstMap[I->second].push_back(
+ (Namespace + "::" + Inst->TheDef->getName()).str());
+ }
+
+ OS << "#ifdef GET_INSTRINFO_LOGICAL_OPERAND_TYPE_MAP\n";
+ OS << "#undef GET_INSTRINFO_LOGICAL_OPERAND_TYPE_MAP\n";
+ OS << "namespace llvm {\n";
+ OS << "namespace " << Namespace << " {\n";
+ OS << "LLVM_READONLY static int\n";
+ OS << "getLogicalOperandType(uint16_t Opcode, uint16_t LogicalOpIdx) {\n";
+ if (!InstMap.empty()) {
+ std::vector<const std::vector<std::string> *> LogicalOpTypeList(
+ LogicalOpTypeMap.size());
+ for (auto &P : LogicalOpTypeMap) {
+ LogicalOpTypeList[P.second] = &P.first;
+ }
+ OS << " static const int TypeMap[][" << OpTypeListSize << "] = {\n";
+ for (int r = 0, rs = LogicalOpTypeList.size(); r < rs; ++r) {
+ const auto &Row = *LogicalOpTypeList[r];
+ OS << " {";
+ int i, s = Row.size();
+ for (i = 0; i < s; ++i) {
+ if (i > 0)
+ OS << ", ";
+ OS << Row[i];
+ }
+ for (; i < static_cast<int>(OpTypeListSize); ++i) {
+ if (i > 0)
+ OS << ", ";
+ OS << "-1";
+ }
+ OS << "}";
+ if (r != rs - 1)
+ OS << ",";
+ OS << "\n";
+ }
+ OS << " };\n";
+
+ OS << " switch (Opcode) {\n";
+ OS << " default: return -1;\n";
+ for (auto &P : InstMap) {
+ auto OpMapIdx = P.first;
+ const auto &Insts = P.second;
+ for (const auto &Inst : Insts) {
+ OS << " case " << Inst << ":\n";
+ }
+ OS << " return TypeMap[" << OpMapIdx << "][LogicalOpIdx];\n";
+ }
+ OS << " }\n";
+ } else {
+ OS << " return -1;\n";
+ }
+ OS << "}\n";
+ OS << "} // end namespace " << Namespace << "\n";
+ OS << "} // end namespace llvm\n";
+ OS << "#endif // GET_INSTRINFO_LOGICAL_OPERAND_TYPE_MAP\n\n";
+}
+
void InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS,
StringRef TargetName) {
RecVec TIIPredicates = Records.getAllDerivedDefinitions("TIIPredicate");
@@ -726,6 +911,12 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
Records.startTimer("Emit operand type mappings");
emitOperandTypeMappings(OS, Target, NumberedInstructions);
+ Records.startTimer("Emit logical operand size mappings");
+ emitLogicalOperandSizeMappings(OS, TargetName, NumberedInstructions);
+
+ Records.startTimer("Emit logical operand type mappings");
+ emitLogicalOperandTypeMappings(OS, TargetName, NumberedInstructions);
+
Records.startTimer("Emit helper methods");
emitMCIIHelperMethods(OS, TargetName);
}