[llvm] 079cd4a - [NFC][Exegesis] Don't recompute opcode/reg names on each YAML write (-38% runtime)

Roman Lebedev via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 12 14:04:04 PST 2022


Author: Roman Lebedev
Date: 2022-12-13T01:03:38+03:00
New Revision: 079cd4a52f398ccf4a04cf47f2c3c536a5011585

URL: https://github.com/llvm/llvm-project/commit/079cd4a52f398ccf4a04cf47f2c3c536a5011585
DIFF: https://github.com/llvm/llvm-project/commit/079cd4a52f398ccf4a04cf47f2c3c536a5011585.diff

LOG: [NFC][Exegesis] Don't recompute opcode/reg names on each YAML write (-38% runtime)

This reducer runtime of
```
$ ./bin/llvm-exegesis -mode=inverse_throughput --opcode-index=-1 --benchmarks-file=/dev/null --dump-object-to-disk=0 --measurements-print-progress --skip-measurements
```
from 3m44s to 2m17s, aka -38%.
But more importantly, we go from 400 *million* memory allocations
down to just 100 million, aka -75%.

But really, the big missing thing is doing everything in a single thread.
Sure, we can't do anything when measuring, but when we are not measuring,
we should just prepare (codegen) everything via all threads.
That should parallelize quite well.

Added: 
    

Modified: 
    llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
    llvm/tools/llvm-exegesis/lib/LlvmState.cpp
    llvm/tools/llvm-exegesis/lib/LlvmState.h

Removed: 
    


################################################################################
diff  --git a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
index 99c6567457bf5..81adaf02ec06e 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
@@ -23,7 +23,6 @@
 static constexpr const char kIntegerPrefix[] = "i_0x";
 static constexpr const char kDoublePrefix[] = "f_";
 static constexpr const char kInvalidOperand[] = "INVALID";
-static constexpr llvm::StringLiteral kNoRegister("%noreg");
 
 namespace llvm {
 
@@ -34,29 +33,8 @@ namespace {
 struct YamlContext {
   YamlContext(const exegesis::LLVMState &State)
       : State(&State), ErrorStream(LastError),
-        OpcodeNameToOpcodeIdx(
-            generateOpcodeNameToOpcodeIdxMapping(State.getInstrInfo())),
-        RegNameToRegNo(generateRegNameToRegNoMapping(State.getRegInfo())) {}
-
-  static StringMap<unsigned>
-  generateOpcodeNameToOpcodeIdxMapping(const MCInstrInfo &InstrInfo) {
-    StringMap<unsigned> Map(InstrInfo.getNumOpcodes());
-    for (unsigned I = 0, E = InstrInfo.getNumOpcodes(); I < E; ++I)
-      Map[InstrInfo.getName(I)] = I;
-    assert(Map.size() == InstrInfo.getNumOpcodes() && "Size prediction failed");
-    return Map;
-  };
-
-  StringMap<unsigned>
-  generateRegNameToRegNoMapping(const MCRegisterInfo &RegInfo) {
-    StringMap<unsigned> Map(RegInfo.getNumRegs());
-    // Special-case RegNo 0, which would otherwise be spelled as ''.
-    Map[kNoRegister] = 0;
-    for (unsigned I = 1, E = RegInfo.getNumRegs(); I < E; ++I)
-      Map[RegInfo.getName(I)] = I;
-    assert(Map.size() == RegInfo.getNumRegs() && "Size prediction failed");
-    return Map;
-  };
+        OpcodeNameToOpcodeIdx(State.getOpcodeNameToOpcodeIdxMapping()),
+        RegNameToRegNo(State.getRegNameToRegNoMapping()) {}
 
   void serializeMCInst(const MCInst &MCInst, raw_ostream &OS) {
     OS << getInstrName(MCInst.getOpcode());
@@ -174,8 +152,8 @@ struct YamlContext {
   const exegesis::LLVMState *State;
   std::string LastError;
   raw_string_ostream ErrorStream;
-  const StringMap<unsigned> OpcodeNameToOpcodeIdx;
-  const StringMap<unsigned> RegNameToRegNo;
+  const StringMap<unsigned> &OpcodeNameToOpcodeIdx;
+  const StringMap<unsigned> &RegNameToRegNo;
 };
 } // namespace
 

diff  --git a/llvm/tools/llvm-exegesis/lib/LlvmState.cpp b/llvm/tools/llvm-exegesis/lib/LlvmState.cpp
index 5239e824a79fe..363ef82858f45 100644
--- a/llvm/tools/llvm-exegesis/lib/LlvmState.cpp
+++ b/llvm/tools/llvm-exegesis/lib/LlvmState.cpp
@@ -78,7 +78,9 @@ Expected<LLVMState> LLVMState::Create(std::string TripleName,
 
 LLVMState::LLVMState(std::unique_ptr<const TargetMachine> TM,
                      const ExegesisTarget *ET, const StringRef CpuName)
-    : TheExegesisTarget(ET), TheTargetMachine(std::move(TM)) {
+    : TheExegesisTarget(ET), TheTargetMachine(std::move(TM)),
+      OpcodeNameToOpcodeIdxMapping(createOpcodeNameToOpcodeIdxMapping()),
+      RegNameToRegNoMapping(createRegNameToRegNoMapping()) {
   PfmCounters = &TheExegesisTarget->getPfmCounters(CpuName);
 
   BitVector ReservedRegs = getFunctionReservedRegs(getTargetMachine());
@@ -98,6 +100,28 @@ std::unique_ptr<LLVMTargetMachine> LLVMState::createTargetMachine() const {
           Reloc::Model::Static)));
 }
 
+std::unique_ptr<const StringMap<unsigned>>
+LLVMState::createOpcodeNameToOpcodeIdxMapping() const {
+  const MCInstrInfo &InstrInfo = getInstrInfo();
+  auto Map = std::make_unique<StringMap<unsigned>>(InstrInfo.getNumOpcodes());
+  for (unsigned I = 0, E = InstrInfo.getNumOpcodes(); I < E; ++I)
+    (*Map)[InstrInfo.getName(I)] = I;
+  assert(Map->size() == InstrInfo.getNumOpcodes() && "Size prediction failed");
+  return std::move(Map);
+}
+
+std::unique_ptr<const StringMap<unsigned>>
+LLVMState::createRegNameToRegNoMapping() const {
+  const MCRegisterInfo &RegInfo = getRegInfo();
+  auto Map = std::make_unique<StringMap<unsigned>>(RegInfo.getNumRegs());
+  // Special-case RegNo 0, which would otherwise be spelled as ''.
+  (*Map)[kNoRegister] = 0;
+  for (unsigned I = 1, E = RegInfo.getNumRegs(); I < E; ++I)
+    (*Map)[RegInfo.getName(I)] = I;
+  assert(Map->size() == RegInfo.getNumRegs() && "Size prediction failed");
+  return std::move(Map);
+}
+
 bool LLVMState::canAssemble(const MCInst &Inst) const {
   MCContext Context(TheTargetMachine->getTargetTriple(),
                     TheTargetMachine->getMCAsmInfo(),

diff  --git a/llvm/tools/llvm-exegesis/lib/LlvmState.h b/llvm/tools/llvm-exegesis/lib/LlvmState.h
index 2651a85eb3e13..f504e025772b8 100644
--- a/llvm/tools/llvm-exegesis/lib/LlvmState.h
+++ b/llvm/tools/llvm-exegesis/lib/LlvmState.h
@@ -16,6 +16,7 @@
 
 #include "MCInstrDescView.h"
 #include "RegisterAliasing.h"
+#include "llvm/ADT/StringMap.h"
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/MCInst.h"
 #include "llvm/MC/MCInstrInfo.h"
@@ -25,6 +26,8 @@
 #include <memory>
 #include <string>
 
+static constexpr llvm::StringLiteral kNoRegister("%noreg");
+
 namespace llvm {
 namespace exegesis {
 
@@ -65,7 +68,23 @@ class LLVMState {
 
   const PfmCountersInfo &getPfmCounters() const { return *PfmCounters; }
 
+  const StringMap<unsigned> &getOpcodeNameToOpcodeIdxMapping() const {
+    assert(OpcodeNameToOpcodeIdxMapping);
+    return *OpcodeNameToOpcodeIdxMapping;
+  };
+
+  const StringMap<unsigned> &getRegNameToRegNoMapping() const {
+    assert(RegNameToRegNoMapping);
+    return *RegNameToRegNoMapping;
+  }
+
 private:
+  std::unique_ptr<const StringMap<unsigned>>
+  createOpcodeNameToOpcodeIdxMapping() const;
+
+  std::unique_ptr<const StringMap<unsigned>>
+  createRegNameToRegNoMapping() const;
+
   LLVMState(std::unique_ptr<const TargetMachine> TM, const ExegesisTarget *ET,
             StringRef CpuName);
 
@@ -74,6 +93,8 @@ class LLVMState {
   std::unique_ptr<const RegisterAliasingTrackerCache> RATC;
   std::unique_ptr<const InstructionsCache> IC;
   const PfmCountersInfo *PfmCounters;
+  std::unique_ptr<const StringMap<unsigned>> OpcodeNameToOpcodeIdxMapping;
+  std::unique_ptr<const StringMap<unsigned>> RegNameToRegNoMapping;
 };
 
 } // namespace exegesis


        


More information about the llvm-commits mailing list