CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
254 lines
9.0 KiB
C++
254 lines
9.0 KiB
C++
//===- MatchTable.cpp -----------------------------------------------------===//
|
|
//
|
|
// 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 "MatchTable.h"
|
|
#include "llvm/ADT/Twine.h"
|
|
#include "llvm/Support/LEB128.h"
|
|
#include "llvm/Support/ScopedPrinter.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
#include "llvm/TableGen/Record.h"
|
|
|
|
#define DEBUG_TYPE "gi-match-table"
|
|
|
|
namespace llvm {
|
|
namespace gi {
|
|
// GIMT_Encode2/4/8
|
|
constexpr StringLiteral EncodeMacroName = "GIMT_Encode";
|
|
|
|
//===- Helpers ------------------------------------------------------------===//
|
|
|
|
void emitEncodingMacrosDef(raw_ostream &OS) {
|
|
OS << "#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__\n"
|
|
<< "#define " << EncodeMacroName << "2(Val)"
|
|
<< " uint8_t(Val), uint8_t((Val) >> 8)\n"
|
|
<< "#define " << EncodeMacroName << "4(Val)"
|
|
<< " uint8_t(Val), uint8_t((Val) >> 8), "
|
|
"uint8_t((Val) >> 16), uint8_t((Val) >> 24)\n"
|
|
<< "#define " << EncodeMacroName << "8(Val)"
|
|
<< " uint8_t(Val), uint8_t((Val) >> 8), "
|
|
"uint8_t((Val) >> 16), uint8_t((Val) >> 24), "
|
|
"uint8_t(uint64_t(Val) >> 32), uint8_t(uint64_t(Val) >> 40), "
|
|
"uint8_t(uint64_t(Val) >> 48), uint8_t(uint64_t(Val) >> 56)\n"
|
|
<< "#else\n"
|
|
<< "#define " << EncodeMacroName << "2(Val)"
|
|
<< " uint8_t((Val) >> 8), uint8_t(Val)\n"
|
|
<< "#define " << EncodeMacroName << "4(Val)"
|
|
<< " uint8_t((Val) >> 24), uint8_t((Val) >> 16), "
|
|
"uint8_t((Val) >> 8), uint8_t(Val)\n"
|
|
<< "#define " << EncodeMacroName << "8(Val)"
|
|
<< " uint8_t(uint64_t(Val) >> 56), uint8_t(uint64_t(Val) >> 48), "
|
|
"uint8_t(uint64_t(Val) >> 40), uint8_t(uint64_t(Val) >> 32), "
|
|
"uint8_t((Val) >> 24), uint8_t((Val) >> 16), "
|
|
"uint8_t((Val) >> 8), uint8_t(Val)\n"
|
|
<< "#endif\n";
|
|
}
|
|
|
|
void emitEncodingMacrosUndef(raw_ostream &OS) {
|
|
OS << "#undef " << EncodeMacroName << "2\n"
|
|
<< "#undef " << EncodeMacroName << "4\n"
|
|
<< "#undef " << EncodeMacroName << "8\n";
|
|
}
|
|
|
|
std::string getNameForFeatureBitset(ArrayRef<const Record *> FeatureBitset,
|
|
int HwModeIdx) {
|
|
std::string Name = "GIFBS";
|
|
for (const Record *Feature : FeatureBitset)
|
|
Name += ("_" + Feature->getName()).str();
|
|
if (HwModeIdx >= 0)
|
|
Name += ("_HwMode" + std::to_string(HwModeIdx));
|
|
return Name;
|
|
}
|
|
|
|
static std::string getEncodedEmitStr(StringRef NamedValue, unsigned NumBytes) {
|
|
if (NumBytes == 2 || NumBytes == 4 || NumBytes == 8)
|
|
return (EncodeMacroName + Twine(NumBytes) + "(" + NamedValue + ")").str();
|
|
llvm_unreachable("Unsupported number of bytes!");
|
|
}
|
|
|
|
//===- MatchTableRecord ---------------------------------------------------===//
|
|
|
|
void MatchTableRecord::emit(raw_ostream &OS, bool LineBreakIsNextAfterThis,
|
|
const MatchTable &Table) const {
|
|
bool UseLineComment =
|
|
LineBreakIsNextAfterThis || (Flags & MTRF_LineBreakFollows);
|
|
if (Flags & (MTRF_JumpTarget | MTRF_CommaFollows))
|
|
UseLineComment = false;
|
|
|
|
if (Flags & MTRF_Comment)
|
|
OS << (UseLineComment ? "// " : "/*");
|
|
|
|
if (NumElements > 1 && !(Flags & (MTRF_PreEncoded | MTRF_Comment)))
|
|
OS << getEncodedEmitStr(EmitStr, NumElements);
|
|
else
|
|
OS << EmitStr;
|
|
|
|
if (Flags & MTRF_Label)
|
|
OS << ": @" << Table.getLabelIndex(LabelID);
|
|
|
|
if ((Flags & MTRF_Comment) && !UseLineComment)
|
|
OS << "*/";
|
|
|
|
if (Flags & MTRF_JumpTarget) {
|
|
if (Flags & MTRF_Comment)
|
|
OS << " ";
|
|
// TODO: Could encode this AOT to speed up build of generated file
|
|
OS << getEncodedEmitStr(llvm::to_string(Table.getLabelIndex(LabelID)),
|
|
NumElements);
|
|
}
|
|
|
|
if (Flags & MTRF_CommaFollows) {
|
|
OS << ",";
|
|
if (!LineBreakIsNextAfterThis && !(Flags & MTRF_LineBreakFollows))
|
|
OS << " ";
|
|
}
|
|
|
|
if (Flags & MTRF_LineBreakFollows)
|
|
OS << "\n";
|
|
}
|
|
|
|
//===- MatchTable ---------------------------------------------------------===//
|
|
|
|
MatchTableRecord MatchTable::LineBreak = {
|
|
std::nullopt, "" /* Emit String */, 0 /* Elements */,
|
|
MatchTableRecord::MTRF_LineBreakFollows};
|
|
|
|
MatchTableRecord MatchTable::Comment(StringRef Comment) {
|
|
return MatchTableRecord(std::nullopt, Comment, 0,
|
|
MatchTableRecord::MTRF_Comment);
|
|
}
|
|
|
|
MatchTableRecord MatchTable::Opcode(StringRef Opcode, int IndentAdjust) {
|
|
unsigned ExtraFlags = 0;
|
|
if (IndentAdjust > 0)
|
|
ExtraFlags |= MatchTableRecord::MTRF_Indent;
|
|
if (IndentAdjust < 0)
|
|
ExtraFlags |= MatchTableRecord::MTRF_Outdent;
|
|
|
|
return MatchTableRecord(std::nullopt, Opcode, 1,
|
|
MatchTableRecord::MTRF_CommaFollows | ExtraFlags);
|
|
}
|
|
|
|
MatchTableRecord MatchTable::NamedValue(unsigned NumBytes,
|
|
StringRef NamedValue) {
|
|
return MatchTableRecord(std::nullopt, NamedValue, NumBytes,
|
|
MatchTableRecord::MTRF_CommaFollows);
|
|
}
|
|
|
|
MatchTableRecord MatchTable::NamedValue(unsigned NumBytes, StringRef Namespace,
|
|
StringRef NamedValue) {
|
|
return MatchTableRecord(std::nullopt, (Namespace + "::" + NamedValue).str(),
|
|
NumBytes, MatchTableRecord::MTRF_CommaFollows);
|
|
}
|
|
|
|
MatchTableRecord MatchTable::IntValue(unsigned NumBytes, int64_t IntValue) {
|
|
assert(isUIntN(NumBytes * 8, IntValue) || isIntN(NumBytes * 8, IntValue));
|
|
uint64_t UIntValue = IntValue;
|
|
if (NumBytes < 8)
|
|
UIntValue &= (UINT64_C(1) << NumBytes * 8) - 1;
|
|
std::string Str = llvm::to_string(UIntValue);
|
|
if (UIntValue > INT64_MAX)
|
|
Str += 'u';
|
|
// TODO: Could optimize this directly to save the compiler some work when
|
|
// building the file
|
|
return MatchTableRecord(std::nullopt, Str, NumBytes,
|
|
MatchTableRecord::MTRF_CommaFollows);
|
|
}
|
|
|
|
MatchTableRecord MatchTable::ULEB128Value(uint64_t IntValue) {
|
|
uint8_t Buffer[10];
|
|
unsigned Len = encodeULEB128(IntValue, Buffer);
|
|
|
|
// Simple case (most common)
|
|
if (Len == 1) {
|
|
return MatchTableRecord(std::nullopt, llvm::to_string((unsigned)Buffer[0]),
|
|
1, MatchTableRecord::MTRF_CommaFollows);
|
|
}
|
|
|
|
// Print it as, e.g. /* -123456 (*/, 0xC0, 0xBB, 0x78 /*)*/
|
|
std::string Str;
|
|
raw_string_ostream OS(Str);
|
|
OS << "/* " << llvm::to_string(IntValue) << "(*/";
|
|
for (unsigned K = 0; K < Len; ++K) {
|
|
if (K)
|
|
OS << ", ";
|
|
OS << "0x" << llvm::toHex({Buffer[K]});
|
|
}
|
|
OS << "/*)*/";
|
|
return MatchTableRecord(std::nullopt, Str, Len,
|
|
MatchTableRecord::MTRF_CommaFollows |
|
|
MatchTableRecord::MTRF_PreEncoded);
|
|
}
|
|
|
|
MatchTableRecord MatchTable::Label(unsigned LabelID) {
|
|
return MatchTableRecord(LabelID, "Label " + llvm::to_string(LabelID), 0,
|
|
MatchTableRecord::MTRF_Label |
|
|
MatchTableRecord::MTRF_Comment |
|
|
MatchTableRecord::MTRF_LineBreakFollows);
|
|
}
|
|
|
|
MatchTableRecord MatchTable::JumpTarget(unsigned LabelID) {
|
|
return MatchTableRecord(LabelID, "Label " + llvm::to_string(LabelID), 4,
|
|
MatchTableRecord::MTRF_JumpTarget |
|
|
MatchTableRecord::MTRF_Comment |
|
|
MatchTableRecord::MTRF_CommaFollows);
|
|
}
|
|
|
|
void MatchTable::emitUse(raw_ostream &OS) const { OS << "MatchTable" << ID; }
|
|
|
|
void MatchTable::emitDeclaration(raw_ostream &OS) const {
|
|
static constexpr unsigned BaseIndent = 4;
|
|
unsigned Indentation = 0;
|
|
OS << " constexpr static uint8_t MatchTable" << ID << "[] = {";
|
|
LineBreak.emit(OS, true, *this);
|
|
|
|
// We want to display the table index of each line in a consistent
|
|
// manner. It has to appear as a column on the left side of the table.
|
|
// To determine how wide the column needs to be, check how many characters
|
|
// we need to fit the largest possible index in the current table.
|
|
const unsigned NumColsForIdx = llvm::to_string(CurrentSize).size();
|
|
|
|
unsigned CurIndex = 0;
|
|
const auto BeginLine = [&]() {
|
|
OS.indent(BaseIndent);
|
|
std::string IdxStr = llvm::to_string(CurIndex);
|
|
// Pad the string with spaces to keep the size of the prefix consistent.
|
|
OS << " /* ";
|
|
OS.indent(NumColsForIdx - IdxStr.size()) << IdxStr << " */ ";
|
|
OS.indent(Indentation);
|
|
};
|
|
|
|
BeginLine();
|
|
for (auto I = Contents.begin(), E = Contents.end(); I != E; ++I) {
|
|
bool LineBreakIsNext = false;
|
|
const auto &NextI = std::next(I);
|
|
|
|
if (NextI != E) {
|
|
if (NextI->EmitStr == "" &&
|
|
NextI->Flags == MatchTableRecord::MTRF_LineBreakFollows)
|
|
LineBreakIsNext = true;
|
|
}
|
|
|
|
if (I->Flags & MatchTableRecord::MTRF_Indent)
|
|
Indentation += 2;
|
|
|
|
I->emit(OS, LineBreakIsNext, *this);
|
|
if (I->Flags & MatchTableRecord::MTRF_LineBreakFollows)
|
|
BeginLine();
|
|
|
|
if (I->Flags & MatchTableRecord::MTRF_Outdent)
|
|
Indentation -= 2;
|
|
|
|
CurIndex += I->size();
|
|
}
|
|
assert(CurIndex == CurrentSize);
|
|
OS << "}; // Size: " << CurrentSize << " bytes\n";
|
|
}
|
|
|
|
} // namespace gi
|
|
} // namespace llvm
|