Skip to content

Commit f75c6ed

Browse files
authored
[TableGen] Efficiency improvements for encoding HwMode collection. (#82902)
Currently the DecoderEmitter spends a fair amount of cycles performing repeated linear walks over the entire instruction list. This patch eliminates one such walk during HwMode collection for EncodingInfos. The eliminated traversal visits every instruction and then every EncodingInfos entry for that instruction merely to collect all referenced HwModes. That information already happens to be present in the HwModeSelects created during the one-time construction of CodeGenHwModes. We instead traverse the HwModeSelects, collecting each one referenced as an encoding select. This set is a small constant in size and does not generally grow with the size of the instruction set.
1 parent e533248 commit f75c6ed

File tree

2 files changed

+28
-20
lines changed

2 files changed

+28
-20
lines changed

llvm/utils/TableGen/CodeGenHwModes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ struct CodeGenHwModes {
5353
return Modes[Id - 1];
5454
}
5555
const HwModeSelect &getHwModeSelect(Record *R) const;
56+
const std::map<Record *, HwModeSelect> &getHwModeSelects() const {
57+
return ModeSelects;
58+
}
5659
unsigned getNumModeIds() const { return Modes.size() + 1; }
5760
void dump() const;
5861

llvm/utils/TableGen/DecoderEmitter.cpp

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "llvm/ADT/CachedHashString.h"
2323
#include "llvm/ADT/STLExtras.h"
2424
#include "llvm/ADT/SetVector.h"
25+
#include "llvm/ADT/SmallBitVector.h"
2526
#include "llvm/ADT/SmallString.h"
2627
#include "llvm/ADT/Statistic.h"
2728
#include "llvm/ADT/StringExtras.h"
@@ -2448,6 +2449,22 @@ static void emitCheck(formatted_raw_ostream &OS) {
24482449
<< "}\n\n";
24492450
}
24502451

2452+
// Collect all HwModes referenced by the target for encoding purposes,
2453+
// returning a vector of corresponding names.
2454+
static void
2455+
collectHwModesReferencedForEncodings(const CodeGenHwModes &HWM,
2456+
std::vector<StringRef> &Names) {
2457+
SmallBitVector BV(HWM.getNumModeIds());
2458+
for (const auto &MS : HWM.getHwModeSelects()) {
2459+
for (const HwModeSelect::PairType &P : MS.second.Items) {
2460+
if (P.second->isSubClassOf("InstructionEncoding"))
2461+
BV.set(P.first);
2462+
}
2463+
}
2464+
transform(BV.set_bits(), std::back_inserter(Names),
2465+
[&HWM](const int &M) { return HWM.getMode(M).Name; });
2466+
}
2467+
24512468
// Emits disassembler code for instruction decoding.
24522469
void DecoderEmitter::run(raw_ostream &o) {
24532470
formatted_raw_ostream OS(o);
@@ -2469,37 +2486,25 @@ void DecoderEmitter::run(raw_ostream &o) {
24692486
Target.reverseBitsForLittleEndianEncoding();
24702487

24712488
// Parameterize the decoders based on namespace and instruction width.
2472-
std::set<StringRef> HwModeNames;
2473-
const auto &NumberedInstructions = Target.getInstructionsByEnumValue();
2474-
NumberedEncodings.reserve(NumberedInstructions.size());
2475-
// First, collect all HwModes referenced by the target.
2476-
for (const auto &NumberedInstruction : NumberedInstructions) {
2477-
if (const RecordVal *RV =
2478-
NumberedInstruction->TheDef->getValue("EncodingInfos")) {
2479-
if (auto *DI = dyn_cast_or_null<DefInit>(RV->getValue())) {
2480-
const CodeGenHwModes &HWM = Target.getHwModes();
2481-
EncodingInfoByHwMode EBM(DI->getDef(), HWM);
2482-
for (auto &KV : EBM)
2483-
HwModeNames.insert(HWM.getMode(KV.first).Name);
2484-
}
2485-
}
2486-
}
24872489

2490+
// First, collect all encoding-related HwModes referenced by the target.
24882491
// If HwModeNames is empty, add the empty string so we always have one HwMode.
2492+
const CodeGenHwModes &HWM = Target.getHwModes();
2493+
std::vector<StringRef> HwModeNames;
2494+
collectHwModesReferencedForEncodings(HWM, HwModeNames);
24892495
if (HwModeNames.empty())
2490-
HwModeNames.insert("");
2496+
HwModeNames.push_back("");
24912497

2498+
const auto &NumberedInstructions = Target.getInstructionsByEnumValue();
2499+
NumberedEncodings.reserve(NumberedInstructions.size());
24922500
for (const auto &NumberedInstruction : NumberedInstructions) {
24932501
if (const RecordVal *RV =
24942502
NumberedInstruction->TheDef->getValue("EncodingInfos")) {
24952503
if (DefInit *DI = dyn_cast_or_null<DefInit>(RV->getValue())) {
2496-
const CodeGenHwModes &HWM = Target.getHwModes();
24972504
EncodingInfoByHwMode EBM(DI->getDef(), HWM);
2498-
for (auto &KV : EBM) {
2505+
for (auto &KV : EBM)
24992506
NumberedEncodings.emplace_back(KV.second, NumberedInstruction,
25002507
HWM.getMode(KV.first).Name);
2501-
HwModeNames.insert(HWM.getMode(KV.first).Name);
2502-
}
25032508
continue;
25042509
}
25052510
}

0 commit comments

Comments
 (0)