Skip to content

Commit 5823ac0

Browse files
[llvm-exegesis] Refactor getting register number from name to LLVMState (#107895)
This patch refactors the procedure of getting the register number from a register name to LLVMState rather than having individual users get the values themselves by getting a reference to the map from LLVMState. This is primarily intended to make some downstream usage in Gematria simpler, but also cleans up a little bit upstream by pulling the actual map searching out and just leaving error handling to the clients. The original getter is left to enable downstream migration in Gematria, particularly before it gets imported into google internal.
1 parent 53b5902 commit 5823ac0

File tree

4 files changed

+48
-44
lines changed

4 files changed

+48
-44
lines changed

llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp

Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ namespace {
3434
struct YamlContext {
3535
YamlContext(const exegesis::LLVMState &State)
3636
: State(&State), ErrorStream(LastError),
37-
OpcodeNameToOpcodeIdx(State.getOpcodeNameToOpcodeIdxMapping()),
38-
RegNameToRegNo(State.getRegNameToRegNoMapping()) {}
37+
OpcodeNameToOpcodeIdx(State.getOpcodeNameToOpcodeIdxMapping()) {}
3938

4039
void serializeMCInst(const MCInst &MCInst, raw_ostream &OS) {
4140
OS << getInstrName(MCInst.getOpcode());
@@ -77,11 +76,11 @@ struct YamlContext {
7776
}
7877

7978
std::optional<unsigned> getRegNo(StringRef RegName) {
80-
auto Iter = RegNameToRegNo.find(RegName);
81-
if (Iter != RegNameToRegNo.end())
82-
return Iter->second;
83-
ErrorStream << "No register with name '" << RegName << "'\n";
84-
return std::nullopt;
79+
std::optional<MCRegister> RegisterNumber =
80+
State->getRegisterNumberFromName(RegName);
81+
if (!RegisterNumber.has_value())
82+
ErrorStream << "No register with name '" << RegName << "'\n";
83+
return RegisterNumber;
8584
}
8685

8786
private:
@@ -154,7 +153,6 @@ struct YamlContext {
154153
std::string LastError;
155154
raw_string_ostream ErrorStream;
156155
const DenseMap<StringRef, unsigned> &OpcodeNameToOpcodeIdx;
157-
const DenseMap<StringRef, MCRegister> &RegNameToRegNo;
158156
};
159157
} // namespace
160158

@@ -231,10 +229,8 @@ template <> struct MappingTraits<exegesis::BenchmarkMeasure> {
231229
static const bool flow = true;
232230
};
233231

234-
template <>
235-
struct ScalarEnumerationTraits<exegesis::Benchmark::ModeE> {
236-
static void enumeration(IO &Io,
237-
exegesis::Benchmark::ModeE &Value) {
232+
template <> struct ScalarEnumerationTraits<exegesis::Benchmark::ModeE> {
233+
static void enumeration(IO &Io, exegesis::Benchmark::ModeE &Value) {
238234
Io.enumCase(Value, "", exegesis::Benchmark::Unknown);
239235
Io.enumCase(Value, "latency", exegesis::Benchmark::Latency);
240236
Io.enumCase(Value, "uops", exegesis::Benchmark::Uops);
@@ -282,8 +278,7 @@ template <> struct ScalarTraits<exegesis::RegisterValue> {
282278
static const bool flow = true;
283279
};
284280

285-
template <>
286-
struct MappingContextTraits<exegesis::BenchmarkKey, YamlContext> {
281+
template <> struct MappingContextTraits<exegesis::BenchmarkKey, YamlContext> {
287282
static void mapping(IO &Io, exegesis::BenchmarkKey &Obj,
288283
YamlContext &Context) {
289284
Io.setContext(&Context);
@@ -293,8 +288,7 @@ struct MappingContextTraits<exegesis::BenchmarkKey, YamlContext> {
293288
}
294289
};
295290

296-
template <>
297-
struct MappingContextTraits<exegesis::Benchmark, YamlContext> {
291+
template <> struct MappingContextTraits<exegesis::Benchmark, YamlContext> {
298292
struct NormalizedBinary {
299293
NormalizedBinary(IO &io) {}
300294
NormalizedBinary(IO &, std::vector<uint8_t> &Data) : Binary(Data) {}
@@ -311,8 +305,7 @@ struct MappingContextTraits<exegesis::Benchmark, YamlContext> {
311305
BinaryRef Binary;
312306
};
313307

314-
static void mapping(IO &Io, exegesis::Benchmark &Obj,
315-
YamlContext &Context) {
308+
static void mapping(IO &Io, exegesis::Benchmark &Obj, YamlContext &Context) {
316309
Io.mapRequired("mode", Obj.Mode);
317310
Io.mapRequired("key", Obj.Key, Context);
318311
Io.mapRequired("cpu_name", Obj.CpuName);
@@ -339,8 +332,7 @@ struct MappingContextTraits<exegesis::Benchmark, YamlContext> {
339332
};
340333

341334
template <> struct MappingTraits<exegesis::Benchmark::TripleAndCpu> {
342-
static void mapping(IO &Io,
343-
exegesis::Benchmark::TripleAndCpu &Obj) {
335+
static void mapping(IO &Io, exegesis::Benchmark::TripleAndCpu &Obj) {
344336
assert(!Io.outputting() && "can only read TripleAndCpu");
345337
// Read triple.
346338
Io.mapRequired("llvm_triple", Obj.LLVMTriple);
@@ -357,8 +349,7 @@ Expected<std::set<Benchmark::TripleAndCpu>>
357349
Benchmark::readTriplesAndCpusFromYamls(MemoryBufferRef Buffer) {
358350
// We're only mapping a field, drop other fields and silence the corresponding
359351
// warnings.
360-
yaml::Input Yin(
361-
Buffer, nullptr, +[](const SMDiagnostic &, void *Context) {});
352+
yaml::Input Yin(Buffer, nullptr, +[](const SMDiagnostic &, void *Context) {});
362353
Yin.setAllowUnknownKeys(true);
363354
std::set<TripleAndCpu> Result;
364355
yaml::EmptyContext Context;
@@ -373,8 +364,8 @@ Benchmark::readTriplesAndCpusFromYamls(MemoryBufferRef Buffer) {
373364
return Result;
374365
}
375366

376-
Expected<Benchmark>
377-
Benchmark::readYaml(const LLVMState &State, MemoryBufferRef Buffer) {
367+
Expected<Benchmark> Benchmark::readYaml(const LLVMState &State,
368+
MemoryBufferRef Buffer) {
378369
yaml::Input Yin(Buffer);
379370
YamlContext Context(State);
380371
Benchmark Benchmark;
@@ -385,9 +376,8 @@ Benchmark::readYaml(const LLVMState &State, MemoryBufferRef Buffer) {
385376
return std::move(Benchmark);
386377
}
387378

388-
Expected<std::vector<Benchmark>>
389-
Benchmark::readYamls(const LLVMState &State,
390-
MemoryBufferRef Buffer) {
379+
Expected<std::vector<Benchmark>> Benchmark::readYamls(const LLVMState &State,
380+
MemoryBufferRef Buffer) {
391381
yaml::Input Yin(Buffer);
392382
YamlContext Context(State);
393383
std::vector<Benchmark> Benchmarks;
@@ -403,8 +393,7 @@ Benchmark::readYamls(const LLVMState &State,
403393
return std::move(Benchmarks);
404394
}
405395

406-
Error Benchmark::writeYamlTo(const LLVMState &State,
407-
raw_ostream &OS) {
396+
Error Benchmark::writeYamlTo(const LLVMState &State, raw_ostream &OS) {
408397
auto Cleanup = make_scope_exit([&] { OS.flush(); });
409398
yaml::Output Yout(OS, nullptr /*Ctx*/, 200 /*WrapColumn*/);
410399
YamlContext Context(State);
@@ -416,8 +405,7 @@ Error Benchmark::writeYamlTo(const LLVMState &State,
416405
return Error::success();
417406
}
418407

419-
Error Benchmark::readYamlFrom(const LLVMState &State,
420-
StringRef InputContent) {
408+
Error Benchmark::readYamlFrom(const LLVMState &State, StringRef InputContent) {
421409
yaml::Input Yin(InputContent);
422410
YamlContext Context(State);
423411
if (Yin.setCurrentDocument())

llvm/tools/llvm-exegesis/lib/LlvmState.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,14 @@ std::unique_ptr<LLVMTargetMachine> LLVMState::createTargetMachine() const {
100100
Reloc::Model::Static)));
101101
}
102102

103+
std::optional<MCRegister>
104+
LLVMState::getRegisterNumberFromName(StringRef RegisterName) const {
105+
auto RegisterIt = RegNameToRegNoMapping->find(RegisterName);
106+
if (RegisterIt == RegNameToRegNoMapping->end())
107+
return std::nullopt;
108+
return RegisterIt->second;
109+
}
110+
103111
std::unique_ptr<const DenseMap<StringRef, unsigned>>
104112
LLVMState::createOpcodeNameToOpcodeIdxMapping() const {
105113
const MCInstrInfo &InstrInfo = getInstrInfo();

llvm/tools/llvm-exegesis/lib/LlvmState.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,17 @@ class LLVMState {
7676
return *OpcodeNameToOpcodeIdxMapping;
7777
};
7878

79+
// TODO(boomanaiden154): We are keeping this getter around to enable internal
80+
// migration to getRegisterNumberFromName. Once that is complete and
81+
// the changes have been pulled, we can remove this.
7982
const DenseMap<StringRef, MCRegister> &getRegNameToRegNoMapping() const {
8083
assert(RegNameToRegNoMapping);
8184
return *RegNameToRegNoMapping;
8285
}
8386

87+
std::optional<MCRegister>
88+
getRegisterNumberFromName(StringRef RegisterName) const;
89+
8490
private:
8591
std::unique_ptr<const DenseMap<StringRef, unsigned>>
8692
createOpcodeNameToOpcodeIdxMapping() const;

llvm/tools/llvm-exegesis/lib/SnippetFile.cpp

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@
99
#include "SnippetFile.h"
1010
#include "BenchmarkRunner.h"
1111
#include "Error.h"
12+
#include "LlvmState.h"
1213
#include "Target.h"
1314
#include "llvm/MC/MCContext.h"
1415
#include "llvm/MC/MCInstPrinter.h"
1516
#include "llvm/MC/MCObjectFileInfo.h"
1617
#include "llvm/MC/MCParser/MCAsmLexer.h"
1718
#include "llvm/MC/MCParser/MCAsmParser.h"
1819
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
20+
#include "llvm/MC/MCRegister.h"
1921
#include "llvm/MC/MCRegisterInfo.h"
2022
#include "llvm/MC/MCStreamer.h"
2123
#include "llvm/MC/TargetRegistry.h"
@@ -35,10 +37,9 @@ namespace {
3537
// An MCStreamer that reads a BenchmarkCode definition from a file.
3638
class BenchmarkCodeStreamer : public MCStreamer, public AsmCommentConsumer {
3739
public:
38-
explicit BenchmarkCodeStreamer(
39-
MCContext *Context, const DenseMap<StringRef, MCRegister> &RegNameToRegNo,
40-
BenchmarkCode *Result)
41-
: MCStreamer(*Context), RegNameToRegNo(RegNameToRegNo), Result(Result) {}
40+
explicit BenchmarkCodeStreamer(MCContext *Context, const LLVMState &State,
41+
BenchmarkCode *Result)
42+
: MCStreamer(*Context), State(State), Result(Result) {}
4243

4344
// Implementation of the MCStreamer interface. We only care about
4445
// instructions.
@@ -207,15 +208,17 @@ class BenchmarkCodeStreamer : public MCStreamer, public AsmCommentConsumer {
207208
Align ByteAlignment, SMLoc Loc) override {}
208209

209210
unsigned findRegisterByName(const StringRef RegName) const {
210-
auto Iter = RegNameToRegNo.find(RegName);
211-
if (Iter != RegNameToRegNo.end())
212-
return Iter->second;
213-
errs() << "'" << RegName
214-
<< "' is not a valid register name for the target\n";
215-
return 0;
211+
std::optional<MCRegister> RegisterNumber =
212+
State.getRegisterNumberFromName(RegName);
213+
if (!RegisterNumber.has_value()) {
214+
errs() << "'" << RegName
215+
<< "' is not a valid register name for the target\n";
216+
return MCRegister::NoRegister;
217+
}
218+
return *RegisterNumber;
216219
}
217220

218-
const DenseMap<StringRef, MCRegister> &RegNameToRegNo;
221+
const LLVMState &State;
219222
BenchmarkCode *const Result;
220223
unsigned InvalidComments = 0;
221224
};
@@ -248,8 +251,7 @@ Expected<std::vector<BenchmarkCode>> readSnippets(const LLVMState &State,
248251
TM.getTarget().createMCObjectFileInfo(Context, /*PIC=*/false));
249252
Context.setObjectFileInfo(ObjectFileInfo.get());
250253
Context.initInlineSourceManager();
251-
BenchmarkCodeStreamer Streamer(&Context, State.getRegNameToRegNoMapping(),
252-
&Result);
254+
BenchmarkCodeStreamer Streamer(&Context, State, &Result);
253255

254256
std::string Error;
255257
raw_string_ostream ErrorStream(Error);

0 commit comments

Comments
 (0)