Skip to content

Commit e3eb094

Browse files
committed
Use function of static tables instead of lambda
1 parent 3a8b95f commit e3eb094

File tree

2 files changed

+58
-52
lines changed

2 files changed

+58
-52
lines changed

llvm/test/TableGen/DecoderEmitterLambda.td renamed to llvm/test/TableGen/DecoderEmitterFnTable.td

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: llvm-tblgen -gen-disassembler -use-lambda-in-decode-to-mcinst -I %p/../../include %s | FileCheck %s
1+
// RUN: llvm-tblgen -gen-disassembler -use-fn-table-in-decode-to-mcinst -I %p/../../include %s | FileCheck %s
22

33
include "llvm/Target/Target.td"
44

@@ -71,14 +71,14 @@ def Inst3 : TestInstruction {
7171
let AsmString = "Inst3";
7272
}
7373

74+
// CHECK-LABEL: decodeFn0
75+
// CHECK-LABEL: decodeFn1
76+
// CHECK-LABEL: decodeFn2
77+
// CHECK-LABEL: decodeFn3
7478
// CHECK-LABEL: decodeToMCInst
75-
// CHECK: decodeLambda0 =
76-
// CHECK: decodeLambda1 =
77-
// CHECK: decodeLambda2 =
78-
// CHECK: decodeLambda3 =
79-
// CHECK: decodeLambdaTable[]
80-
// CHECK-NEXT: decodeLambda0
81-
// CHECK-NEXT: decodeLambda1
82-
// CHECK-NEXT: decodeLambda2
83-
// CHECK-NEXT: decodeLambda3
84-
// CHECK: return decodeLambdaTable[Idx]
79+
// CHECK: static constexpr DecodeFnTy decodeFnTable[]
80+
// CHECK-NEXT: decodeFn0,
81+
// CHECK-NEXT: decodeFn1,
82+
// CHECK-NEXT: decodeFn2,
83+
// CHECK-NEXT: decodeFn3,
84+
// CHECK: return decodeFnTable[Idx]

llvm/utils/TableGen/DecoderEmitter.cpp

Lines changed: 47 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,12 @@ static cl::opt<bool> LargeTable(
8383
"in the table instead of the default 16 bits."),
8484
cl::init(false), cl::cat(DisassemblerEmitterCat));
8585

86-
static cl::opt<bool> UseLambdaInDecodetoMCInst(
87-
"use-lambda-in-decode-to-mcinst",
88-
cl::desc("Use a table of lambdas instead of a switch case in the\n"
89-
"generated `decodeToMCInst` function. Helps improve compile time\n"
90-
"of the generated code."),
86+
static cl::opt<bool> UseFnTableInDecodetoMCInst(
87+
"use-fn-table-in-decode-to-mcinst",
88+
cl::desc(
89+
"Use a table of function pointers instead of a switch case in the\n"
90+
"generated `decodeToMCInst` function. Helps improve compile time\n"
91+
"of the generated code."),
9192
cl::init(false), cl::cat(DisassemblerEmitterCat));
9293

9394
STATISTIC(NumEncodings, "Number of encodings considered");
@@ -1073,53 +1074,57 @@ void DecoderEmitter::emitPredicateFunction(formatted_raw_ostream &OS,
10731074
void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS,
10741075
DecoderSet &Decoders,
10751076
indent Indent) const {
1076-
// The decoder function is just a big switch statement based on the
1077-
// input decoder index.
1078-
OS << Indent << "template <typename InsnType>\n";
1079-
OS << Indent << "static DecodeStatus decodeToMCInst(DecodeStatus S,"
1080-
<< " unsigned Idx, InsnType insn, MCInst &MI,\n";
1081-
OS << Indent << " uint64_t "
1082-
<< "Address, const MCDisassembler *Decoder, bool &DecodeComplete) {\n";
1083-
Indent += 2;
1084-
OS << Indent << "DecodeComplete = true;\n";
1077+
// The decoder function is just a big switch statement or a table of function
1078+
// pointers based on the input decoder index.
1079+
10851080
// TODO: When InsnType is large, using uint64_t limits all fields to 64 bits
10861081
// It would be better for emitBinaryParser to use a 64-bit tmp whenever
10871082
// possible but fall back to an InsnType-sized tmp for truly large fields.
1088-
OS << Indent
1089-
<< "using TmpType = "
1090-
"std::conditional_t<std::is_integral<InsnType>::"
1091-
"value, InsnType, uint64_t>;\n";
1092-
1093-
if (UseLambdaInDecodetoMCInst) {
1094-
// Emit one lambda for each case first.
1083+
StringRef TmpTypeDecl =
1084+
"using TmpType = std::conditional_t<std::is_integral<InsnType>::value, "
1085+
"InsnType, uint64_t>;\n";
1086+
StringRef DecodeParams =
1087+
"DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const "
1088+
"MCDisassembler *Decoder, bool &DecodeComplete";
1089+
1090+
if (UseFnTableInDecodetoMCInst) {
1091+
// Emit a function for each case first.
10951092
for (const auto &[Index, Decoder] : enumerate(Decoders)) {
1096-
OS << Indent << "auto decodeLambda" << Index << " = [](DecodeStatus S,\n"
1097-
<< Indent << " InsnType insn, MCInst &MI,\n"
1098-
<< Indent << " uint64_t Address, \n"
1099-
<< Indent << " const MCDisassembler *Decoder,\n"
1100-
<< Indent << " bool &DecodeComplete) {\n";
1101-
OS << Indent + 2 << "[[maybe_unused]] TmpType tmp;\n";
1093+
OS << Indent << "template <typename InsnType>\n";
1094+
OS << Indent << "DecodeStatus decodeFn" << Index << "(" << DecodeParams
1095+
<< ") {\n";
1096+
Indent += 2;
1097+
OS << Indent << TmpTypeDecl;
1098+
OS << Indent << "[[maybe_unused]] TmpType tmp;\n";
11021099
OS << Decoder;
1103-
OS << Indent + 2 << "return S;\n";
1104-
OS << Indent << "};\n";
1100+
OS << Indent << "return S;\n";
1101+
Indent -= 2;
1102+
OS << Indent << "}\n\n";
11051103
}
1106-
// Build a table of lambdas.
1104+
}
11071105

1108-
OS << R"(
1109-
using LambdaTy =
1110-
function_ref<DecodeStatus(DecodeStatus, InsnType, MCInst &, uint64_t,
1111-
const MCDisassembler *, bool &)>;
1112-
)";
1113-
OS << Indent << "const static LambdaTy decodeLambdaTable[] = {\n";
1106+
OS << Indent << "// Handling " << Decoders.size() << " cases.\n";
1107+
OS << Indent << "template <typename InsnType>\n";
1108+
OS << Indent << "static DecodeStatus decodeToMCInst(unsigned Idx, "
1109+
<< DecodeParams << ") {\n";
1110+
Indent += 2;
1111+
OS << Indent << "DecodeComplete = true;\n";
1112+
1113+
if (UseFnTableInDecodetoMCInst) {
1114+
// Build a table of function pointers.
1115+
OS << Indent << "using DecodeFnTy = DecodeStatus (*)(" << DecodeParams
1116+
<< ");\n";
1117+
OS << Indent << "static constexpr DecodeFnTy decodeFnTable[] = {\n";
11141118
for (size_t Index : llvm::seq(Decoders.size()))
1115-
OS << Indent + 2 << "decodeLambda" << Index << ",\n";
1119+
OS << Indent + 2 << "decodeFn" << Index << ",\n";
11161120
OS << Indent << "};\n";
11171121
OS << Indent << "if (Idx >= " << Decoders.size() << ")\n";
11181122
OS << Indent + 2 << "llvm_unreachable(\"Invalid index!\");\n";
11191123
OS << Indent
1120-
<< "return decodeLambdaTable[Idx](S, insn, MI, Address, Decoder, "
1124+
<< "return decodeFnTable[Idx](S, insn, MI, Address, Decoder, "
11211125
"DecodeComplete);\n";
11221126
} else {
1127+
OS << Indent << TmpTypeDecl;
11231128
OS << Indent << "TmpType tmp;\n";
11241129
OS << Indent << "switch (Idx) {\n";
11251130
OS << Indent << "default: llvm_unreachable(\"Invalid index!\");\n";
@@ -1306,7 +1311,8 @@ std::pair<unsigned, bool> FilterChooser::getDecoderIndex(DecoderSet &Decoders,
13061311
// FIXME: emitDecoder() function can take a buffer directly rather than
13071312
// a stream.
13081313
raw_svector_ostream S(Decoder);
1309-
bool HasCompleteDecoder = emitDecoder(S, indent(4), Opc);
1314+
indent Indent(UseFnTableInDecodetoMCInst ? 2 : 4);
1315+
bool HasCompleteDecoder = emitDecoder(S, Indent, Opc);
13101316

13111317
// Using the full decoder string as the key value here is a bit
13121318
// heavyweight, but is effective. If the string comparisons become a
@@ -2410,7 +2416,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
24102416
<< " makeUp(insn, Len);";
24112417
}
24122418
OS << R"(
2413-
S = decodeToMCInst(S, DecodeIdx, insn, MI, Address, DisAsm, DecodeComplete);
2419+
S = decodeToMCInst(DecodeIdx, S, insn, MI, Address, DisAsm, DecodeComplete);
24142420
assert(DecodeComplete);
24152421
24162422
LLVM_DEBUG(dbgs() << Loc << ": OPC_Decode: opcode " << Opc
@@ -2432,7 +2438,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
24322438
MCInst TmpMI;
24332439
TmpMI.setOpcode(Opc);
24342440
bool DecodeComplete;
2435-
S = decodeToMCInst(S, DecodeIdx, insn, TmpMI, Address, DisAsm, DecodeComplete);
2441+
S = decodeToMCInst(DecodeIdx, S, insn, TmpMI, Address, DisAsm, DecodeComplete);
24362442
LLVM_DEBUG(dbgs() << Loc << ": OPC_TryDecode: opcode " << Opc
24372443
<< ", using decoder " << DecodeIdx << ": ");
24382444

0 commit comments

Comments
 (0)