]> granicus.if.org Git - llvm/commitdiff
[llvm-exegesis][X86] Handle CMOVcc/SETcc OPERAND_COND_CODE OperandType
authorRoman Lebedev <lebedev.ri@gmail.com>
Sat, 6 Apr 2019 14:16:26 +0000 (14:16 +0000)
committerRoman Lebedev <lebedev.ri@gmail.com>
Sat, 6 Apr 2019 14:16:26 +0000 (14:16 +0000)
Summary:
D60041 / D60138 refactoring changed how CMOV/SETcc opcodes
are handled. concode is now an immediate, with it's own operand type.

This at least allows to not crash on the opcode.
However, this still won't generate all the snippets
with all the condcode enumerators. D60066 does that.

Reviewers: courbet, gchatelet

Reviewed By: gchatelet

Subscribers: tschuett, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D60057

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@357841 91177308-0d34-0410-b5e6-96231b3b80d8

test/tools/llvm-exegesis/X86/latency-CMOV32rr.s [new file with mode: 0644]
tools/llvm-exegesis/lib/SnippetGenerator.cpp
tools/llvm-exegesis/lib/SnippetGenerator.h
tools/llvm-exegesis/lib/Target.cpp
tools/llvm-exegesis/lib/Target.h
tools/llvm-exegesis/lib/X86/Target.cpp

diff --git a/test/tools/llvm-exegesis/X86/latency-CMOV32rr.s b/test/tools/llvm-exegesis/X86/latency-CMOV32rr.s
new file mode 100644 (file)
index 0000000..d983c2b
--- /dev/null
@@ -0,0 +1,9 @@
+# RUN: llvm-exegesis -mode=latency -opcode-name=CMOV32rr | FileCheck %s
+
+CHECK:      ---
+CHECK-NEXT: mode: latency
+CHECK-NEXT: key:
+CHECK-NEXT:   instructions:
+CHECK-NEXT:     CMOV32rr
+CHECK-NEXT: config: ''
+CHECK-LAST: ...
index 44592fd89a3f4c97d0b24fe33960e4d317d13460..8cbde9f0186c6e9c9c7357f356d8c0254c20d29a 100644 (file)
@@ -12,6 +12,7 @@
 #include "Assembler.h"
 #include "MCInstrDescView.h"
 #include "SnippetGenerator.h"
+#include "Target.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Twine.h"
@@ -50,7 +51,7 @@ SnippetGenerator::generateConfigurations(const Instruction &Instr) const {
         BenchmarkCode BC;
         BC.Info = CT.Info;
         for (InstructionTemplate &IT : CT.Instructions) {
-          randomizeUnsetVariables(ForbiddenRegs, IT);
+          randomizeUnsetVariables(State.getExegesisTarget(), ForbiddenRegs, IT);
           BC.Instructions.push_back(IT.build());
         }
         if (CT.ScratchSpacePointerInReg)
@@ -156,29 +157,6 @@ static auto randomElement(const C &Container) -> decltype(Container[0]) {
   return Container[randomIndex(Container.size())];
 }
 
-static void randomize(const Instruction &Instr, const Variable &Var,
-                      llvm::MCOperand &AssignedValue,
-                      const llvm::BitVector &ForbiddenRegs) {
-  const Operand &Op = Instr.getPrimaryOperand(Var);
-  switch (Op.getExplicitOperandInfo().OperandType) {
-  case llvm::MCOI::OperandType::OPERAND_IMMEDIATE:
-    // FIXME: explore immediate values too.
-    AssignedValue = llvm::MCOperand::createImm(1);
-    break;
-  case llvm::MCOI::OperandType::OPERAND_REGISTER: {
-    assert(Op.isReg());
-    auto AllowedRegs = Op.getRegisterAliasing().sourceBits();
-    assert(AllowedRegs.size() == ForbiddenRegs.size());
-    for (auto I : ForbiddenRegs.set_bits())
-      AllowedRegs.reset(I);
-    AssignedValue = llvm::MCOperand::createReg(randomBit(AllowedRegs));
-    break;
-  }
-  default:
-    break;
-  }
-}
-
 static void setRegisterOperandValue(const RegisterOperandAssignment &ROV,
                                     InstructionTemplate &IB) {
   assert(ROV.Op);
@@ -212,12 +190,13 @@ void setRandomAliasing(const AliasingConfigurations &AliasingConfigurations,
   setRegisterOperandValue(randomElement(RandomConf.Uses), UseIB);
 }
 
-void randomizeUnsetVariables(const llvm::BitVector &ForbiddenRegs,
+void randomizeUnsetVariables(const ExegesisTarget &Target,
+                             const llvm::BitVector &ForbiddenRegs,
                              InstructionTemplate &IT) {
   for (const Variable &Var : IT.Instr.Variables) {
     llvm::MCOperand &AssignedValue = IT.getValueFor(Var);
     if (!AssignedValue.isValid())
-      randomize(IT.Instr, Var, AssignedValue, ForbiddenRegs);
+      Target.randomizeMCOperand(IT.Instr, Var, AssignedValue, ForbiddenRegs);
   }
 }
 
index a07bc6981aeb69e39ae64bbe7e9258c673994a71..289fa02096a59d2ab259a44f33d483749ec5d994 100644 (file)
@@ -88,7 +88,8 @@ void setRandomAliasing(const AliasingConfigurations &AliasingConfigurations,
 
 // Assigns a Random Value to all Variables in IT that are still Invalid.
 // Do not use any of the registers in `ForbiddenRegs`.
-void randomizeUnsetVariables(const llvm::BitVector &ForbiddenRegs,
+void randomizeUnsetVariables(const ExegesisTarget &Target,
+                             const llvm::BitVector &ForbiddenRegs,
                              InstructionTemplate &IT);
 
 } // namespace exegesis
index c662f1f5566fe18803813c5e932232434757bf2c..945aabb8a3f635efe2e2b4077d2817aeaae7f5d6 100644 (file)
@@ -86,6 +86,30 @@ ExegesisTarget::createUopsBenchmarkRunner(const LLVMState &State) const {
   return llvm::make_unique<UopsBenchmarkRunner>(State);
 }
 
+void ExegesisTarget::randomizeMCOperand(
+    const Instruction &Instr, const Variable &Var,
+    llvm::MCOperand &AssignedValue,
+    const llvm::BitVector &ForbiddenRegs) const {
+  const Operand &Op = Instr.getPrimaryOperand(Var);
+  switch (Op.getExplicitOperandInfo().OperandType) {
+  case llvm::MCOI::OperandType::OPERAND_IMMEDIATE:
+    // FIXME: explore immediate values too.
+    AssignedValue = llvm::MCOperand::createImm(1);
+    break;
+  case llvm::MCOI::OperandType::OPERAND_REGISTER: {
+    assert(Op.isReg());
+    auto AllowedRegs = Op.getRegisterAliasing().sourceBits();
+    assert(AllowedRegs.size() == ForbiddenRegs.size());
+    for (auto I : ForbiddenRegs.set_bits())
+      AllowedRegs.reset(I);
+    AssignedValue = llvm::MCOperand::createReg(randomBit(AllowedRegs));
+    break;
+  }
+  default:
+    break;
+  }
+}
+
 static_assert(std::is_pod<PfmCountersInfo>::value,
               "We shouldn't have dynamic initialization here");
 const PfmCountersInfo PfmCountersInfo::Default = {nullptr, nullptr, nullptr,
index ab760bfa820b42f07bdbea3e230a0d32cb636d88..0c5747808650a6419fb45062b5a41ac1a3bca9bd 100644 (file)
@@ -102,6 +102,14 @@ public:
   // matter as long as it's large enough.
   virtual unsigned getMaxMemoryAccessSize() const { return 0; }
 
+  // Assigns a random operand of the right type to variable Var.
+  // The default implementation only handles generic operand types.
+  // The target is responsible for handling any operand
+  // starting from OPERAND_FIRST_TARGET.
+  virtual void randomizeMCOperand(const Instruction &Instr, const Variable &Var,
+                                  llvm::MCOperand &AssignedValue,
+                                  const llvm::BitVector &ForbiddenRegs) const;
+
   // Creates a snippet generator for the given mode.
   std::unique_ptr<SnippetGenerator>
   createSnippetGenerator(InstructionBenchmark::ModeE Mode,
index 6ef1953352f9208140f97d12e2e5935aa167c5c7..01e3589cc2dee62f5709c54d9f329fc73c37e89a 100644 (file)
@@ -433,6 +433,10 @@ private:
 
   unsigned getMaxMemoryAccessSize() const override { return 64; }
 
+  void randomizeMCOperand(const Instruction &Instr, const Variable &Var,
+                          llvm::MCOperand &AssignedValue,
+                          const llvm::BitVector &ForbiddenRegs) const override;
+
   void fillMemoryOperands(InstructionTemplate &IT, unsigned Reg,
                           unsigned Offset) const override;
 
@@ -485,6 +489,23 @@ ExegesisX86Target::getScratchMemoryRegister(const llvm::Triple &TT) const {
   return TT.isOSWindows() ? llvm::X86::RCX : llvm::X86::RDI;
 }
 
+void ExegesisX86Target::randomizeMCOperand(
+    const Instruction &Instr, const Variable &Var,
+    llvm::MCOperand &AssignedValue,
+    const llvm::BitVector &ForbiddenRegs) const {
+  ExegesisTarget::randomizeMCOperand(Instr, Var, AssignedValue, ForbiddenRegs);
+
+  const Operand &Op = Instr.getPrimaryOperand(Var);
+  switch (Op.getExplicitOperandInfo().OperandType) {
+  case llvm::X86::OperandType::OPERAND_COND_CODE:
+    // FIXME: explore all CC variants.
+    AssignedValue = llvm::MCOperand::createImm(1);
+    break;
+  default:
+    break;
+  }
+}
+
 void ExegesisX86Target::fillMemoryOperands(InstructionTemplate &IT,
                                            unsigned Reg,
                                            unsigned Offset) const {