[llvm-exegesis][NFC] Pass Instruction instead of bare Opcode
authorGuillaume Chatelet <gchatelet@google.com>
Wed, 10 Oct 2018 14:57:32 +0000 (14:57 +0000)
committerGuillaume Chatelet <gchatelet@google.com>
Wed, 10 Oct 2018 14:57:32 +0000 (14:57 +0000)
llvm-svn: 344145

llvm/tools/llvm-exegesis/lib/Latency.cpp
llvm/tools/llvm-exegesis/lib/Latency.h
llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp
llvm/tools/llvm-exegesis/lib/MCInstrDescView.h
llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp
llvm/tools/llvm-exegesis/lib/SnippetGenerator.h
llvm/tools/llvm-exegesis/lib/Uops.cpp
llvm/tools/llvm-exegesis/lib/Uops.h
llvm/tools/llvm-exegesis/lib/X86/Target.cpp
llvm/tools/llvm-exegesis/llvm-exegesis.cpp
llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp

index ea646f4..f6786b1 100644 (file)
@@ -57,8 +57,7 @@ LatencySnippetGenerator::generateTwoInstructionPrototype(
 }
 
 llvm::Expected<CodeTemplate>
-LatencySnippetGenerator::generateCodeTemplate(unsigned Opcode) const {
-  const Instruction Instr(State, Opcode);
+LatencySnippetGenerator::generateCodeTemplate(const Instruction &Instr) const {
   if (Instr.hasMemoryOperands())
     return llvm::make_error<BenchmarkFailure>(
         "Infeasible : has memory operands");
index 37feb62..83c798f 100644 (file)
@@ -27,7 +27,7 @@ public:
   ~LatencySnippetGenerator() override;
 
   llvm::Expected<CodeTemplate>
-  generateCodeTemplate(unsigned Opcode) const override;
+  generateCodeTemplate(const Instruction &Instr) const override;
 
 private:
   llvm::Expected<CodeTemplate>
index d54f3ca..fa93788 100644 (file)
@@ -88,7 +88,8 @@ const llvm::MCOperandInfo &Operand::getExplicitOperandInfo() const {
 }
 
 Instruction::Instruction(const LLVMState &State, unsigned Opcode)
-    : Description(&State.getInstrInfo().get(Opcode)) {
+    : Description(&State.getInstrInfo().get(Opcode)),
+      Name(State.getInstrInfo().getName(Opcode)) {
   const auto &RATC = State.getRATC();
   unsigned OpIndex = 0;
   for (; OpIndex < Description->getNumOperands(); ++OpIndex) {
@@ -198,6 +199,7 @@ bool Instruction::hasAliasingRegisters() const {
 
 void Instruction::dump(const llvm::MCRegisterInfo &RegInfo,
                        llvm::raw_ostream &Stream) const {
+  Stream << "- " << Name << "\n";
   for (const auto &Op : Operands) {
     Stream << "- Op" << Op.getIndex();
     if (Op.isExplicit())
@@ -227,10 +229,15 @@ void Instruction::dump(const llvm::MCRegisterInfo &RegInfo,
   }
   for (const auto &Var : Variables) {
     Stream << "- Var" << Var.getIndex();
-    Stream << " (";
-    for (auto OperandIndex : Var.TiedOperands)
+    Stream << " [";
+    bool IsFirst = true;
+    for (auto OperandIndex : Var.TiedOperands) {
+      if (!IsFirst)
+        Stream << ",";
       Stream << "Op" << OperandIndex;
-    Stream << ")";
+      IsFirst = false;
+    }
+    Stream << "]";
     Stream << "\n";
   }
   if (hasMemoryOperands())
index 914bf51..265476a 100644 (file)
@@ -130,6 +130,7 @@ struct Instruction {
             llvm::raw_ostream &Stream) const;
 
   const llvm::MCInstrDesc *Description; // Never nullptr.
+  llvm::StringRef Name;                 // The name of this instruction.
   llvm::SmallVector<Operand, 8> Operands;
   llvm::SmallVector<Variable, 4> Variables;
   llvm::BitVector ImplDefRegs; // The set of aliased implicit def registers.
index 16dbd21..f7a76d8 100644 (file)
@@ -30,8 +30,8 @@ SnippetGenerator::SnippetGenerator(const LLVMState &State) : State(State) {}
 SnippetGenerator::~SnippetGenerator() = default;
 
 llvm::Expected<std::vector<BenchmarkCode>>
-SnippetGenerator::generateConfigurations(unsigned Opcode) const {
-  if (auto E = generateCodeTemplate(Opcode)) {
+SnippetGenerator::generateConfigurations(const Instruction &Instr) const {
+  if (auto E = generateCodeTemplate(Instr)) {
     CodeTemplate &CT = E.get();
     const auto &RATC = State.getRATC();
     const llvm::BitVector &ForbiddenRegs =
index 24afe95..c9a19cd 100644 (file)
@@ -46,7 +46,7 @@ public:
 
   // Calls generateCodeTemplate and expands it into one or more BenchmarkCode.
   llvm::Expected<std::vector<BenchmarkCode>>
-  generateConfigurations(unsigned Opcode) const;
+  generateConfigurations(const Instruction &Instr) const;
 
   // Given a snippet, computes which registers the setup code needs to define.
   std::vector<RegisterValue> computeRegisterInitialValues(
@@ -66,7 +66,7 @@ protected:
 private:
   // API to be implemented by subclasses.
   virtual llvm::Expected<CodeTemplate>
-  generateCodeTemplate(unsigned Opcode) const = 0;
+  generateCodeTemplate(const Instruction &Instr) const = 0;
 };
 
 // A global Random Number Generator to randomize configurations.
index fdb6a27..1a701d1 100644 (file)
@@ -125,13 +125,11 @@ void UopsSnippetGenerator::instantiateMemoryOperands(
 }
 
 llvm::Expected<CodeTemplate>
-UopsSnippetGenerator::generateCodeTemplate(unsigned Opcode) const {
-  const auto &ET = State.getExegesisTarget();
+UopsSnippetGenerator::generateCodeTemplate(const Instruction &Instr) const {
   CodeTemplate CT;
-
   const llvm::BitVector *ScratchSpaceAliasedRegs = nullptr;
-  const Instruction Instr(State, Opcode);
   if (Instr.hasMemoryOperands()) {
+    const auto &ET = State.getExegesisTarget();
     CT.ScratchSpacePointerInReg =
         ET.getScratchMemoryRegister(State.getTargetMachine().getTargetTriple());
     if (CT.ScratchSpacePointerInReg == 0)
index 33d0d8b..1cfa824 100644 (file)
@@ -26,7 +26,7 @@ public:
   ~UopsSnippetGenerator() override;
 
   llvm::Expected<CodeTemplate>
-  generateCodeTemplate(unsigned Opcode) const override;
+  generateCodeTemplate(const Instruction &Instr) const override;
 
   static constexpr const size_t kMinNumDifferentAddresses = 6;
 
index 8c03f1a..440996a 100644 (file)
@@ -26,10 +26,9 @@ template <typename Impl> class X86SnippetGenerator : public Impl {
   using Impl::Impl;
 
   llvm::Expected<CodeTemplate>
-  generateCodeTemplate(unsigned Opcode) const override {
+  generateCodeTemplate(const Instruction &Instr) const override {
     // Test whether we can generate a snippet for this instruction.
-    const auto &InstrInfo = this->State.getInstrInfo();
-    const auto OpcodeName = InstrInfo.getName(Opcode);
+    const auto OpcodeName = Instr.Name;
     if (OpcodeName.startswith("POPF") || OpcodeName.startswith("PUSHF") ||
         OpcodeName.startswith("ADJCALLSTACK")) {
       return llvm::make_error<BenchmarkFailure>(
@@ -38,8 +37,7 @@ template <typename Impl> class X86SnippetGenerator : public Impl {
 
     // Handle X87.
     const unsigned FPInstClass =
-        InstrInfo.get(Opcode).TSFlags & llvm::X86II::FPTypeMask;
-    const Instruction Instr(this->State, Opcode);
+        Instr.Description->TSFlags & llvm::X86II::FPTypeMask;
     switch (FPInstClass) {
     case llvm::X86II::NotFP:
       break;
@@ -67,7 +65,7 @@ template <typename Impl> class X86SnippetGenerator : public Impl {
     }
 
     // Fallback to generic implementation.
-    return Impl::Base::generateCodeTemplate(Opcode);
+    return Impl::Base::generateCodeTemplate(Instr);
   }
 };
 
index 8fed137..b4891f1 100644 (file)
@@ -124,12 +124,8 @@ static unsigned getOpcodeOrDie(const llvm::MCInstrInfo &MCInstrInfo) {
 // Generates code snippets for opcode `Opcode`.
 static llvm::Expected<std::vector<BenchmarkCode>>
 generateSnippets(const LLVMState &State, unsigned Opcode) {
-  const std::unique_ptr<SnippetGenerator> Generator =
-      State.getExegesisTarget().createSnippetGenerator(BenchmarkMode, State);
-  if (!Generator)
-    llvm::report_fatal_error("cannot create snippet generator");
-
-  const llvm::MCInstrDesc &InstrDesc = State.getInstrInfo().get(Opcode);
+  const Instruction Instr(State, Opcode);
+  const llvm::MCInstrDesc &InstrDesc = *Instr.Description;
   // Ignore instructions that we cannot run.
   if (InstrDesc.isPseudo())
     return llvm::make_error<BenchmarkFailure>("Unsupported opcode: isPseudo");
@@ -140,7 +136,11 @@ generateSnippets(const LLVMState &State, unsigned Opcode) {
     return llvm::make_error<BenchmarkFailure>(
         "Unsupported opcode: isCall/isReturn");
 
-  return Generator->generateConfigurations(Opcode);
+  const std::unique_ptr<SnippetGenerator> Generator =
+      State.getExegesisTarget().createSnippetGenerator(BenchmarkMode, State);
+  if (!Generator)
+    llvm::report_fatal_error("cannot create snippet generator");
+  return Generator->generateConfigurations(Instr);
 }
 
 namespace {
index f2539aa..4df489d 100644 (file)
@@ -59,7 +59,8 @@ protected:
 
   CodeTemplate checkAndGetCodeTemplate(unsigned Opcode) {
     randomGenerator().seed(0); // Initialize seed.
-    auto CodeTemplateOrError = Generator.generateCodeTemplate(Opcode);
+    const Instruction Instr(State, Opcode);
+    auto CodeTemplateOrError = Generator.generateCodeTemplate(Instr);
     EXPECT_FALSE(CodeTemplateOrError.takeError()); // Valid configuration.
     return std::move(CodeTemplateOrError.get());
   }
@@ -238,7 +239,8 @@ TEST_F(UopsSnippetGeneratorTest, MemoryUse) {
 TEST_F(UopsSnippetGeneratorTest, MemoryUse_Movsb) {
   // MOVSB writes to scratch memory register.
   const unsigned Opcode = llvm::X86::MOVSB;
-  auto Error = Generator.generateCodeTemplate(Opcode).takeError();
+  const Instruction Instr(State, Opcode);
+  auto Error = Generator.generateCodeTemplate(Instr).takeError();
   EXPECT_TRUE((bool)Error);
   llvm::consumeError(std::move(Error));
 }
@@ -253,7 +255,7 @@ public:
 
 private:
   llvm::Expected<CodeTemplate>
-  generateCodeTemplate(unsigned Opcode) const override {
+  generateCodeTemplate(const Instruction &Instr) const override {
     return llvm::make_error<llvm::StringError>("not implemented",
                                                llvm::inconvertibleErrorCode());
   }