summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/tools/llvm-exegesis/lib/Latency.cpp2
-rw-r--r--llvm/tools/llvm-exegesis/lib/LlvmState.cpp1
-rw-r--r--llvm/tools/llvm-exegesis/lib/LlvmState.h3
-rw-r--r--llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp19
-rw-r--r--llvm/tools/llvm-exegesis/lib/MCInstrDescView.h21
-rw-r--r--llvm/tools/llvm-exegesis/llvm-exegesis.cpp2
-rw-r--r--llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp6
7 files changed, 43 insertions, 11 deletions
diff --git a/llvm/tools/llvm-exegesis/lib/Latency.cpp b/llvm/tools/llvm-exegesis/lib/Latency.cpp
index ec92d936de3..602b379faf3 100644
--- a/llvm/tools/llvm-exegesis/lib/Latency.cpp
+++ b/llvm/tools/llvm-exegesis/lib/Latency.cpp
@@ -49,7 +49,7 @@ computeAliasingInstructions(const LLVMState &State, const Instruction &Instr,
for (const unsigned OtherOpcode : Opcodes) {
if (OtherOpcode == Instr.Description->getOpcode())
continue;
- const Instruction OtherInstr(State, OtherOpcode);
+ const Instruction &OtherInstr = State.getIC().getInstr(OtherOpcode);
if (OtherInstr.hasMemoryOperands())
continue;
if (Instr.hasAliasingRegistersThrough(OtherInstr))
diff --git a/llvm/tools/llvm-exegesis/lib/LlvmState.cpp b/llvm/tools/llvm-exegesis/lib/LlvmState.cpp
index ba786cc97ce..58e9db315d5 100644
--- a/llvm/tools/llvm-exegesis/lib/LlvmState.cpp
+++ b/llvm/tools/llvm-exegesis/lib/LlvmState.cpp
@@ -38,6 +38,7 @@ LLVMState::LLVMState(const std::string &Triple, const std::string &CpuName) {
}
RATC.reset(new RegisterAliasingTrackerCache(
getRegInfo(), getFunctionReservedRegs(getTargetMachine())));
+ IC.reset(new InstructionsCache(getInstrInfo(), getRATC()));
}
LLVMState::LLVMState()
diff --git a/llvm/tools/llvm-exegesis/lib/LlvmState.h b/llvm/tools/llvm-exegesis/lib/LlvmState.h
index f8ef8665f44..918738551d0 100644
--- a/llvm/tools/llvm-exegesis/lib/LlvmState.h
+++ b/llvm/tools/llvm-exegesis/lib/LlvmState.h
@@ -15,6 +15,7 @@
#ifndef LLVM_TOOLS_LLVM_EXEGESIS_LLVMSTATE_H
#define LLVM_TOOLS_LLVM_EXEGESIS_LLVMSTATE_H
+#include "MCInstrDescView.h"
#include "RegisterAliasing.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCInst.h"
@@ -57,11 +58,13 @@ public:
return *TargetMachine->getMCSubtargetInfo();
}
const RegisterAliasingTrackerCache &getRATC() const { return *RATC; }
+ const InstructionsCache &getIC() const { return *IC; }
private:
const ExegesisTarget *TheExegesisTarget;
std::unique_ptr<const llvm::TargetMachine> TargetMachine;
std::unique_ptr<const RegisterAliasingTrackerCache> RATC;
+ std::unique_ptr<const InstructionsCache> IC;
};
} // namespace exegesis
diff --git a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp
index 2b4624b9b64..e0521af4d19 100644
--- a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp
+++ b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp
@@ -95,10 +95,10 @@ const llvm::MCOperandInfo &Operand::getExplicitOperandInfo() const {
return *Info;
}
-Instruction::Instruction(const LLVMState &State, unsigned Opcode)
- : Description(&State.getInstrInfo().get(Opcode)),
- Name(State.getInstrInfo().getName(Opcode)) {
- const auto &RATC = State.getRATC();
+Instruction::Instruction(const llvm::MCInstrInfo &InstrInfo,
+ const RegisterAliasingTrackerCache &RATC,
+ unsigned Opcode)
+ : Description(&InstrInfo.get(Opcode)), Name(InstrInfo.getName(Opcode)) {
unsigned OpIndex = 0;
for (; OpIndex < Description->getNumOperands(); ++OpIndex) {
const auto &OpInfo = Description->opInfo_begin()[OpIndex];
@@ -262,6 +262,17 @@ void Instruction::dump(const llvm::MCRegisterInfo &RegInfo,
Stream << "- hasAliasingRegisters\n";
}
+InstructionsCache::InstructionsCache(const llvm::MCInstrInfo &InstrInfo,
+ const RegisterAliasingTrackerCache &RATC)
+ : InstrInfo(InstrInfo), RATC(RATC) {}
+
+const Instruction &InstructionsCache::getInstr(unsigned Opcode) const {
+ auto &Found = Instructions[Opcode];
+ if (!Found)
+ Found.reset(new Instruction(InstrInfo, RATC, Opcode));
+ return *Found;
+}
+
bool RegisterOperandAssignment::
operator==(const RegisterOperandAssignment &Other) const {
return std::tie(Op, Reg) == std::tie(Other.Op, Other.Reg);
diff --git a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h
index 4e8278ba2b5..58efd2a4e41 100644
--- a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h
+++ b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h
@@ -20,8 +20,8 @@
#define LLVM_TOOLS_LLVM_EXEGESIS_MCINSTRDESCVIEW_H
#include <random>
+#include <unordered_map>
-#include "LlvmState.h"
#include "RegisterAliasing.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
@@ -94,7 +94,8 @@ struct Operand {
// A view over an MCInstrDesc offering a convenient interface to compute
// Register aliasing.
struct Instruction {
- Instruction(const LLVMState &State, unsigned Opcode);
+ Instruction(const llvm::MCInstrInfo &InstrInfo,
+ const RegisterAliasingTrackerCache &RATC, unsigned Opcode);
// Returns the Operand linked to this Variable.
// In case the Variable is tied, the primary (i.e. Def) Operand is returned.
@@ -145,6 +146,22 @@ struct Instruction {
llvm::BitVector AllUseRegs; // The set of all aliased use registers.
};
+// Instructions are expensive to instantiate. This class provides a cache of
+// Instructions with lazy construction.
+struct InstructionsCache {
+ InstructionsCache(const llvm::MCInstrInfo &InstrInfo,
+ const RegisterAliasingTrackerCache &RATC);
+
+ // Returns the Instruction object corresponding to this Opcode.
+ const Instruction &getInstr(unsigned Opcode) const;
+
+private:
+ const llvm::MCInstrInfo &InstrInfo;
+ const RegisterAliasingTrackerCache &RATC;
+ mutable std::unordered_map<unsigned, std::unique_ptr<Instruction>>
+ Instructions;
+};
+
// Represents the assignment of a Register to an Operand.
struct RegisterOperandAssignment {
RegisterOperandAssignment(const Operand *Operand, llvm::MCPhysReg Reg)
diff --git a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
index ea991420039..689a1e097c6 100644
--- a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
+++ b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
@@ -147,7 +147,7 @@ getOpcodesOrDie(const llvm::MCInstrInfo &MCInstrInfo) {
// Generates code snippets for opcode `Opcode`.
static llvm::Expected<std::vector<BenchmarkCode>>
generateSnippets(const LLVMState &State, unsigned Opcode) {
- const Instruction Instr(State, Opcode);
+ const Instruction &Instr = State.getIC().getInstr(Opcode);
const llvm::MCInstrDesc &InstrDesc = *Instr.Description;
// Ignore instructions that we cannot run.
if (InstrDesc.isPseudo())
diff --git a/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp b/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp
index 04517359d8a..1689defded8 100644
--- a/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp
+++ b/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp
@@ -61,7 +61,7 @@ protected:
std::vector<CodeTemplate> checkAndGetCodeTemplates(unsigned Opcode) {
randomGenerator().seed(0); // Initialize seed.
- const Instruction Instr(State, Opcode);
+ const Instruction &Instr = State.getIC().getInstr(Opcode);
auto CodeTemplateOrError = Generator.generateCodeTemplates(Instr);
EXPECT_FALSE(CodeTemplateOrError.takeError()); // Valid configuration.
return std::move(CodeTemplateOrError.get());
@@ -341,7 +341,7 @@ TEST_F(UopsSnippetGeneratorTest, MemoryUse_Movsb) {
// - hasAliasingImplicitRegisters (execution is always serial)
// - hasAliasingRegisters
const unsigned Opcode = llvm::X86::MOVSB;
- const Instruction Instr(State, Opcode);
+ const Instruction &Instr = State.getIC().getInstr(Opcode);
auto Error = Generator.generateCodeTemplates(Instr).takeError();
EXPECT_TRUE((bool)Error);
llvm::consumeError(std::move(Error));
@@ -352,7 +352,7 @@ public:
FakeSnippetGenerator(const LLVMState &State) : SnippetGenerator(State) {}
Instruction createInstruction(unsigned Opcode) {
- return Instruction(State, Opcode);
+ return State.getIC().getInstr(Opcode);
}
private:
OpenPOWER on IntegriCloud