[llvm] 32d384c - [llvm-exegesis][NFC] internal changes

Guillaume Chatelet via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 18 08:24:33 PST 2019


Author: Guillaume Chatelet
Date: 2019-12-18T17:24:07+01:00
New Revision: 32d384c0200f2ffed396875b532ef3d286b2b2e4

URL: https://github.com/llvm/llvm-project/commit/32d384c0200f2ffed396875b532ef3d286b2b2e4
DIFF: https://github.com/llvm/llvm-project/commit/32d384c0200f2ffed396875b532ef3d286b2b2e4.diff

LOG: [llvm-exegesis][NFC] internal changes

Summary:
BitVectors are now cached to lower memory utilization.
Instructions have reference semantics.

Reviewers: courbet

Subscribers: sdardis, tschuett, jrtc27, atanasyan, llvm-commits

Tags: #llvm

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

Added: 
    

Modified: 
    llvm/tools/llvm-exegesis/lib/CodeTemplate.cpp
    llvm/tools/llvm-exegesis/lib/CodeTemplate.h
    llvm/tools/llvm-exegesis/lib/Latency.cpp
    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/Uops.cpp
    llvm/tools/llvm-exegesis/lib/X86/Target.cpp
    llvm/tools/llvm-exegesis/llvm-exegesis.cpp
    llvm/unittests/tools/llvm-exegesis/Mips/SnippetGeneratorTest.cpp
    llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp
    llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/tools/llvm-exegesis/lib/CodeTemplate.cpp b/llvm/tools/llvm-exegesis/lib/CodeTemplate.cpp
index 9d01c7d40b0d..9840a08c2536 100644
--- a/llvm/tools/llvm-exegesis/lib/CodeTemplate.cpp
+++ b/llvm/tools/llvm-exegesis/lib/CodeTemplate.cpp
@@ -15,8 +15,8 @@ CodeTemplate::CodeTemplate(CodeTemplate &&) = default;
 
 CodeTemplate &CodeTemplate::operator=(CodeTemplate &&) = default;
 
-InstructionTemplate::InstructionTemplate(const Instruction &Instr)
-    : Instr(Instr), VariableValues(Instr.Variables.size()) {}
+InstructionTemplate::InstructionTemplate(const Instruction *Instr)
+    : Instr(Instr), VariableValues(Instr->Variables.size()) {}
 
 InstructionTemplate::InstructionTemplate(InstructionTemplate &&) = default;
 
@@ -29,7 +29,7 @@ InstructionTemplate &InstructionTemplate::
 operator=(const InstructionTemplate &) = default;
 
 unsigned InstructionTemplate::getOpcode() const {
-  return Instr.Description->getOpcode();
+  return Instr->Description.getOpcode();
 }
 
 MCOperand &InstructionTemplate::getValueFor(const Variable &Var) {
@@ -41,23 +41,23 @@ const MCOperand &InstructionTemplate::getValueFor(const Variable &Var) const {
 }
 
 MCOperand &InstructionTemplate::getValueFor(const Operand &Op) {
-  return getValueFor(Instr.Variables[Op.getVariableIndex()]);
+  return getValueFor(Instr->Variables[Op.getVariableIndex()]);
 }
 
 const MCOperand &InstructionTemplate::getValueFor(const Operand &Op) const {
-  return getValueFor(Instr.Variables[Op.getVariableIndex()]);
+  return getValueFor(Instr->Variables[Op.getVariableIndex()]);
 }
 
 bool InstructionTemplate::hasImmediateVariables() const {
-  return any_of(Instr.Variables, [this](const Variable &Var) {
-    return Instr.getPrimaryOperand(Var).isImmediate();
+  return any_of(Instr->Variables, [this](const Variable &Var) {
+    return Instr->getPrimaryOperand(Var).isImmediate();
   });
 }
 
 MCInst InstructionTemplate::build() const {
   MCInst Result;
-  Result.setOpcode(Instr.Description->Opcode);
-  for (const auto &Op : Instr.Operands)
+  Result.setOpcode(Instr->Description.Opcode);
+  for (const auto &Op : Instr->Operands)
     if (Op.isExplicit())
       Result.addOperand(getValueFor(Op));
   return Result;

diff  --git a/llvm/tools/llvm-exegesis/lib/CodeTemplate.h b/llvm/tools/llvm-exegesis/lib/CodeTemplate.h
index 3556f6fe2ec2..51978147ba09 100644
--- a/llvm/tools/llvm-exegesis/lib/CodeTemplate.h
+++ b/llvm/tools/llvm-exegesis/lib/CodeTemplate.h
@@ -23,7 +23,7 @@ namespace exegesis {
 
 // A template for an Instruction holding values for each of its Variables.
 struct InstructionTemplate {
-  InstructionTemplate(const Instruction &Instr);
+  InstructionTemplate(const Instruction *Instr);
 
   InstructionTemplate(const InstructionTemplate &);            // default
   InstructionTemplate &operator=(const InstructionTemplate &); // default
@@ -36,13 +36,16 @@ struct InstructionTemplate {
   MCOperand &getValueFor(const Operand &Op);
   const MCOperand &getValueFor(const Operand &Op) const;
   bool hasImmediateVariables() const;
+  const Instruction &getInstr() const { return *Instr; }
+  ArrayRef<MCOperand> getVariableValues() const { return VariableValues; }
 
   // Builds an MCInst from this InstructionTemplate setting its operands
   // to the corresponding variable values. Precondition: All VariableValues must
   // be set.
   MCInst build() const;
 
-  Instruction Instr;
+private:
+  const Instruction *Instr;
   SmallVector<MCOperand, 4> VariableValues;
 };
 

diff  --git a/llvm/tools/llvm-exegesis/lib/Latency.cpp b/llvm/tools/llvm-exegesis/lib/Latency.cpp
index 45a0e7e362db..7030658a4603 100644
--- a/llvm/tools/llvm-exegesis/lib/Latency.cpp
+++ b/llvm/tools/llvm-exegesis/lib/Latency.cpp
@@ -37,8 +37,8 @@ struct ExecutionClass {
 
 static constexpr size_t kMaxAliasingInstructions = 10;
 
-static std::vector<Instruction>
-computeAliasingInstructions(const LLVMState &State, const Instruction &Instr,
+static std::vector<const Instruction *>
+computeAliasingInstructions(const LLVMState &State, const Instruction *Instr,
                             size_t MaxAliasingInstructions,
                             const BitVector &ForbiddenRegisters) {
   // Randomly iterate the set of instructions.
@@ -47,15 +47,15 @@ computeAliasingInstructions(const LLVMState &State, const Instruction &Instr,
   std::iota(Opcodes.begin(), Opcodes.end(), 0U);
   std::shuffle(Opcodes.begin(), Opcodes.end(), randomGenerator());
 
-  std::vector<Instruction> AliasingInstructions;
+  std::vector<const Instruction *> AliasingInstructions;
   for (const unsigned OtherOpcode : Opcodes) {
-    if (OtherOpcode == Instr.Description->getOpcode())
+    if (OtherOpcode == Instr->Description.getOpcode())
       continue;
     const Instruction &OtherInstr = State.getIC().getInstr(OtherOpcode);
     if (OtherInstr.hasMemoryOperands())
       continue;
-    if (Instr.hasAliasingRegistersThrough(OtherInstr, ForbiddenRegisters))
-      AliasingInstructions.push_back(OtherInstr);
+    if (Instr->hasAliasingRegistersThrough(OtherInstr, ForbiddenRegisters))
+      AliasingInstructions.push_back(&OtherInstr);
     if (AliasingInstructions.size() >= MaxAliasingInstructions)
       break;
   }
@@ -81,7 +81,7 @@ static ExecutionMode getExecutionModes(const Instruction &Instr,
 }
 
 static void appendCodeTemplates(const LLVMState &State,
-                                const Instruction &Instr,
+                                const Instruction *Instr,
                                 const BitVector &ForbiddenRegisters,
                                 ExecutionMode ExecutionModeBit,
                                 StringRef ExecutionClassDescription,
@@ -109,7 +109,7 @@ static void appendCodeTemplates(const LLVMState &State,
   case ExecutionMode::SERIAL_VIA_EXPLICIT_REGS: {
     // Making the execution of this instruction serial by selecting one def
     // register to alias with one use register.
-    const AliasingConfigurations SelfAliasing(Instr, Instr);
+    const AliasingConfigurations SelfAliasing(*Instr, *Instr);
     assert(!SelfAliasing.empty() && !SelfAliasing.hasImplicitAliasing() &&
            "Instr must alias itself explicitly");
     InstructionTemplate IT(Instr);
@@ -125,10 +125,10 @@ static void appendCodeTemplates(const LLVMState &State,
   }
   case ExecutionMode::SERIAL_VIA_NON_MEMORY_INSTR: {
     // Select back-to-back non-memory instruction.
-    for (const auto OtherInstr : computeAliasingInstructions(
+    for (const auto *OtherInstr : computeAliasingInstructions(
              State, Instr, kMaxAliasingInstructions, ForbiddenRegisters)) {
-      const AliasingConfigurations Forward(Instr, OtherInstr);
-      const AliasingConfigurations Back(OtherInstr, Instr);
+      const AliasingConfigurations Forward(*Instr, *OtherInstr);
+      const AliasingConfigurations Back(*OtherInstr, *Instr);
       InstructionTemplate ThisIT(Instr);
       InstructionTemplate OtherIT(OtherInstr);
       if (!Forward.hasImplicitAliasing())
@@ -158,7 +158,7 @@ LatencySnippetGenerator::generateCodeTemplates(
   const ExecutionMode EM = getExecutionModes(Instr, ForbiddenRegisters);
   for (const auto EC : kExecutionClasses) {
     for (const auto ExecutionModeBit : getExecutionModeBits(EM & EC.Mask))
-      appendCodeTemplates(State, Instr, ForbiddenRegisters, ExecutionModeBit,
+      appendCodeTemplates(State, &Instr, ForbiddenRegisters, ExecutionModeBit,
                           EC.Description, Results);
     if (!Results.empty())
       break;

diff  --git a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp
index 9b3c50f8d9ec..487f6641d507 100644
--- a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp
+++ b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp
@@ -17,10 +17,7 @@
 namespace llvm {
 namespace exegesis {
 
-unsigned Variable::getIndex() const {
-  assert(Index >= 0 && "Index must be set");
-  return Index;
-}
+unsigned Variable::getIndex() const { return *Index; }
 
 unsigned Variable::getPrimaryOperandIndex() const {
   assert(!TiedOperands.empty());
@@ -36,10 +33,7 @@ bool Variable::hasTiedOperands() const {
   return TiedOperands.size() > 1;
 }
 
-unsigned Operand::getIndex() const {
-  assert(Index >= 0 && "Index must be set");
-  return Index;
-}
+unsigned Operand::getIndex() const { return *Index; }
 
 bool Operand::isExplicit() const { return Info; }
 
@@ -53,9 +47,9 @@ bool Operand::isUse() const { return !IsDef; }
 
 bool Operand::isReg() const { return Tracker; }
 
-bool Operand::isTied() const { return TiedToIndex >= 0; }
+bool Operand::isTied() const { return TiedToIndex.hasValue(); }
 
-bool Operand::isVariable() const { return VariableIndex >= 0; }
+bool Operand::isVariable() const { return VariableIndex.hasValue(); }
 
 bool Operand::isMemory() const {
   return isExplicit() &&
@@ -67,17 +61,9 @@ bool Operand::isImmediate() const {
          getExplicitOperandInfo().OperandType == MCOI::OPERAND_IMMEDIATE;
 }
 
-unsigned Operand::getTiedToIndex() const {
-  assert(isTied() && "Operand must be tied to get the tied index");
-  assert(TiedToIndex >= 0 && "TiedToIndex must be set");
-  return TiedToIndex;
-}
+unsigned Operand::getTiedToIndex() const { return *TiedToIndex; }
 
-unsigned Operand::getVariableIndex() const {
-  assert(isVariable() && "Operand must be variable to get the Variable index");
-  assert(VariableIndex >= 0 && "VariableIndex must be set");
-  return VariableIndex;
-}
+unsigned Operand::getVariableIndex() const { return *VariableIndex; }
 
 unsigned Operand::getImplicitReg() const {
   assert(ImplicitReg);
@@ -94,11 +80,36 @@ const MCOperandInfo &Operand::getExplicitOperandInfo() const {
   return *Info;
 }
 
-Instruction::Instruction(const MCInstrInfo &InstrInfo,
-                         const RegisterAliasingTrackerCache &RATC,
-                         unsigned Opcode)
-    : Description(&InstrInfo.get(Opcode)), Name(InstrInfo.getName(Opcode)) {
+const BitVector *BitVectorCache::getUnique(BitVector &&BV) const {
+  for (const auto &Entry : Cache)
+    if (*Entry == BV)
+      return Entry.get();
+  Cache.push_back(std::make_unique<BitVector>());
+  auto &Entry = Cache.back();
+  Entry->swap(BV);
+  return Entry.get();
+}
+
+Instruction::Instruction(const MCInstrDesc *Description, StringRef Name,
+                         SmallVector<Operand, 8> Operands,
+                         SmallVector<Variable, 4> Variables,
+                         const BitVector *ImplDefRegs,
+                         const BitVector *ImplUseRegs,
+                         const BitVector *AllDefRegs,
+                         const BitVector *AllUseRegs)
+    : Description(*Description), Name(Name), Operands(std::move(Operands)),
+      Variables(std::move(Variables)), ImplDefRegs(*ImplDefRegs),
+      ImplUseRegs(*ImplUseRegs), AllDefRegs(*AllDefRegs),
+      AllUseRegs(*AllUseRegs) {}
+
+std::unique_ptr<Instruction>
+Instruction::create(const MCInstrInfo &InstrInfo,
+                    const RegisterAliasingTrackerCache &RATC,
+                    const BitVectorCache &BVC, unsigned Opcode) {
+  const llvm::MCInstrDesc *const Description = &InstrInfo.get(Opcode);
   unsigned OpIndex = 0;
+  SmallVector<Operand, 8> Operands;
+  SmallVector<Variable, 4> Variables;
   for (; OpIndex < Description->getNumOperands(); ++OpIndex) {
     const auto &OpInfo = Description->opInfo_begin()[OpIndex];
     Operand Operand;
@@ -107,8 +118,11 @@ Instruction::Instruction(const MCInstrInfo &InstrInfo,
     // TODO(gchatelet): Handle isLookupPtrRegClass.
     if (OpInfo.RegClass >= 0)
       Operand.Tracker = &RATC.getRegisterClass(OpInfo.RegClass);
-    Operand.TiedToIndex =
-        Description->getOperandConstraint(OpIndex, MCOI::TIED_TO);
+    int TiedToIndex = Description->getOperandConstraint(OpIndex, MCOI::TIED_TO);
+    assert(TiedToIndex == -1 ||
+           TiedToIndex < std::numeric_limits<uint8_t>::max());
+    if (TiedToIndex >= 0)
+      Operand.TiedToIndex = TiedToIndex;
     Operand.Info = &OpInfo;
     Operands.push_back(Operand);
   }
@@ -130,28 +144,29 @@ Instruction::Instruction(const MCInstrInfo &InstrInfo,
     Operand.ImplicitReg = MCPhysReg;
     Operands.push_back(Operand);
   }
-  // Assigning Variables to non tied explicit operands.
   Variables.reserve(Operands.size()); // Variables.size() <= Operands.size()
+  // Assigning Variables to non tied explicit operands.
   for (auto &Op : Operands)
     if (Op.isExplicit() && !Op.isTied()) {
       const size_t VariableIndex = Variables.size();
+      assert(VariableIndex < std::numeric_limits<uint8_t>::max());
       Op.VariableIndex = VariableIndex;
       Variables.emplace_back();
       Variables.back().Index = VariableIndex;
     }
   // Assigning Variables to tied operands.
   for (auto &Op : Operands)
-    if (Op.isTied())
+    if (Op.isExplicit() && Op.isTied())
       Op.VariableIndex = Operands[Op.getTiedToIndex()].getVariableIndex();
   // Assigning Operands to Variables.
   for (auto &Op : Operands)
     if (Op.isVariable())
       Variables[Op.getVariableIndex()].TiedOperands.push_back(Op.getIndex());
   // Processing Aliasing.
-  ImplDefRegs = RATC.emptyRegisters();
-  ImplUseRegs = RATC.emptyRegisters();
-  AllDefRegs = RATC.emptyRegisters();
-  AllUseRegs = RATC.emptyRegisters();
+  BitVector ImplDefRegs = RATC.emptyRegisters();
+  BitVector ImplUseRegs = RATC.emptyRegisters();
+  BitVector AllDefRegs = RATC.emptyRegisters();
+  BitVector AllUseRegs = RATC.emptyRegisters();
   for (const auto &Op : Operands) {
     if (Op.isReg()) {
       const auto &AliasingBits = Op.getRegisterAliasing().aliasedBits();
@@ -165,6 +180,13 @@ Instruction::Instruction(const MCInstrInfo &InstrInfo,
         ImplUseRegs |= AliasingBits;
     }
   }
+  // Can't use make_unique because constructor is private.
+  return std::unique_ptr<Instruction>(new Instruction(
+      Description, InstrInfo.getName(Opcode), std::move(Operands),
+      std::move(Variables), BVC.getUnique(std::move(ImplDefRegs)),
+      BVC.getUnique(std::move(ImplUseRegs)),
+      BVC.getUnique(std::move(AllDefRegs)),
+      BVC.getUnique(std::move(AllUseRegs))));
 }
 
 const Operand &Instruction::getPrimaryOperand(const Variable &Var) const {
@@ -284,7 +306,7 @@ InstructionsCache::InstructionsCache(const MCInstrInfo &InstrInfo,
 const Instruction &InstructionsCache::getInstr(unsigned Opcode) const {
   auto &Found = Instructions[Opcode];
   if (!Found)
-    Found.reset(new Instruction(InstrInfo, RATC, Opcode));
+    Found = Instruction::create(InstrInfo, RATC, BVC, Opcode);
   return *Found;
 }
 

diff  --git a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h
index 4455bbb396e7..8c7e0b2e01d3 100644
--- a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h
+++ b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h
@@ -18,6 +18,7 @@
 #ifndef LLVM_TOOLS_LLVM_EXEGESIS_MCINSTRDESCVIEW_H
 #define LLVM_TOOLS_LLVM_EXEGESIS_MCINSTRDESCVIEW_H
 
+#include <memory>
 #include <random>
 #include <unordered_map>
 
@@ -48,7 +49,7 @@ struct Variable {
 
   // The index of this Variable in Instruction.Variables and its associated
   // Value in InstructionBuilder.VariableValues.
-  int Index = -1;
+  Optional<uint8_t> Index;
 };
 
 // MCOperandInfo can only represents Explicit operands. This object gives a
@@ -81,20 +82,40 @@ struct Operand {
   const MCOperandInfo &getExplicitOperandInfo() const;
 
   // Please use the accessors above and not the following fields.
-  int Index = -1;
+  Optional<uint8_t> Index;
   bool IsDef = false;
   const RegisterAliasingTracker *Tracker = nullptr; // Set for Register Op.
   const MCOperandInfo *Info = nullptr;              // Set for Explicit Op.
-  int TiedToIndex = -1;                             // Set for Reg&Explicit Op.
+  Optional<uint8_t> TiedToIndex;                    // Set for Reg&Explicit Op.
   const MCPhysReg *ImplicitReg = nullptr;           // Set for Implicit Op.
-  int VariableIndex = -1;                           // Set for Explicit Op.
+  Optional<uint8_t> VariableIndex;                  // Set for Explicit Op.
+};
+
+/// A cache of BitVector to reuse between Instructions.
+/// The cache will only be exercised during Instruction initialization.
+/// For X86, this is ~160 unique vectors for all of the ~15K Instructions.
+struct BitVectorCache {
+  // Finds or allocates the provided BitVector in the cache and retrieves it's
+  // unique instance.
+  const BitVector *getUnique(BitVector &&BV) const;
+
+private:
+  mutable std::vector<std::unique_ptr<BitVector>> Cache;
 };
 
 // A view over an MCInstrDesc offering a convenient interface to compute
 // Register aliasing.
 struct Instruction {
-  Instruction(const MCInstrInfo &InstrInfo,
-              const RegisterAliasingTrackerCache &RATC, unsigned Opcode);
+  // Create an instruction for a particular Opcode.
+  static std::unique_ptr<Instruction>
+  create(const MCInstrInfo &InstrInfo, const RegisterAliasingTrackerCache &RATC,
+         const BitVectorCache &BVC, unsigned Opcode);
+
+  // Prevent copy or move, instructions are allocated once and cached.
+  Instruction(const Instruction &) = delete;
+  Instruction(Instruction &&) = delete;
+  Instruction &operator=(const Instruction &) = delete;
+  Instruction &operator=(Instruction &&) = delete;
 
   // Returns the Operand linked to this Variable.
   // In case the Variable is tied, the primary (i.e. Def) Operand is returned.
@@ -133,14 +154,20 @@ struct Instruction {
             const RegisterAliasingTrackerCache &RATC,
             raw_ostream &Stream) const;
 
-  const MCInstrDesc *Description; // Never nullptr.
-  StringRef Name;                 // The name of this instruction.
-  SmallVector<Operand, 8> Operands;
-  SmallVector<Variable, 4> Variables;
-  BitVector ImplDefRegs; // The set of aliased implicit def registers.
-  BitVector ImplUseRegs; // The set of aliased implicit use registers.
-  BitVector AllDefRegs;  // The set of all aliased def registers.
-  BitVector AllUseRegs;  // The set of all aliased use registers.
+  const MCInstrDesc &Description;
+  const StringRef Name; // The name of this instruction.
+  const SmallVector<Operand, 8> Operands;
+  const SmallVector<Variable, 4> Variables;
+  const BitVector &ImplDefRegs; // The set of aliased implicit def registers.
+  const BitVector &ImplUseRegs; // The set of aliased implicit use registers.
+  const BitVector &AllDefRegs;  // The set of all aliased def registers.
+  const BitVector &AllUseRegs;  // The set of all aliased use registers.
+private:
+  Instruction(const MCInstrDesc *Description, StringRef Name,
+              SmallVector<Operand, 8> Operands,
+              SmallVector<Variable, 4> Variables, const BitVector *ImplDefRegs,
+              const BitVector *ImplUseRegs, const BitVector *AllDefRegs,
+              const BitVector *AllUseRegs);
 };
 
 // Instructions are expensive to instantiate. This class provides a cache of
@@ -157,6 +184,7 @@ struct InstructionsCache {
   const RegisterAliasingTrackerCache &RATC;
   mutable std::unordered_map<unsigned, std::unique_ptr<Instruction>>
       Instructions;
+  const BitVectorCache BVC;
 };
 
 // Represents the assignment of a Register to an Operand.

diff  --git a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp
index 65cc954a4696..d1f168fe43bf 100644
--- a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp
+++ b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp
@@ -112,7 +112,7 @@ std::vector<RegisterValue> SnippetGenerator::computeRegisterInitialValues(
       return 0;
     };
     // Collect used registers that have never been def'ed.
-    for (const Operand &Op : IT.Instr.Operands) {
+    for (const Operand &Op : IT.getInstr().Operands) {
       if (Op.isUse()) {
         const unsigned Reg = GetOpReg(Op);
         if (Reg > 0 && !DefinedRegs.test(Reg)) {
@@ -122,7 +122,7 @@ std::vector<RegisterValue> SnippetGenerator::computeRegisterInitialValues(
       }
     }
     // Mark defs as having been def'ed.
-    for (const Operand &Op : IT.Instr.Operands) {
+    for (const Operand &Op : IT.getInstr().Operands) {
       if (Op.isDef()) {
         const unsigned Reg = GetOpReg(Op);
         if (Reg > 0)
@@ -141,7 +141,7 @@ generateSelfAliasingCodeTemplates(const Instruction &Instr) {
   std::vector<CodeTemplate> Result;
   Result.emplace_back();
   CodeTemplate &CT = Result.back();
-  InstructionTemplate IT(Instr);
+  InstructionTemplate IT(&Instr);
   if (SelfAliasing.hasImplicitAliasing()) {
     CT.Info = "implicit Self cycles, picking random values.";
   } else {
@@ -160,7 +160,7 @@ generateUnconstrainedCodeTemplates(const Instruction &Instr, StringRef Msg) {
   Result.emplace_back();
   CodeTemplate &CT = Result.back();
   CT.Info = formatv("{0}, repeating an unconstrained assignment", Msg);
-  CT.Instructions.emplace_back(Instr);
+  CT.Instructions.emplace_back(&Instr);
   return std::move(Result);
 }
 
@@ -218,10 +218,11 @@ void setRandomAliasing(const AliasingConfigurations &AliasingConfigurations,
 void randomizeUnsetVariables(const ExegesisTarget &Target,
                              const BitVector &ForbiddenRegs,
                              InstructionTemplate &IT) {
-  for (const Variable &Var : IT.Instr.Variables) {
+  for (const Variable &Var : IT.getInstr().Variables) {
     MCOperand &AssignedValue = IT.getValueFor(Var);
     if (!AssignedValue.isValid())
-      Target.randomizeMCOperand(IT.Instr, Var, AssignedValue, ForbiddenRegs);
+      Target.randomizeMCOperand(IT.getInstr(), Var, AssignedValue,
+                                ForbiddenRegs);
   }
 }
 

diff  --git a/llvm/tools/llvm-exegesis/lib/Uops.cpp b/llvm/tools/llvm-exegesis/lib/Uops.cpp
index db7dce897187..66319e37ce81 100644
--- a/llvm/tools/llvm-exegesis/lib/Uops.cpp
+++ b/llvm/tools/llvm-exegesis/lib/Uops.cpp
@@ -127,7 +127,7 @@ static std::vector<InstructionTemplate> generateSnippetUsingStaticRenaming(
   std::vector<BitVector> PossibleRegsForVar;
   for (const Variable *Var : TiedVariables) {
     assert(Var);
-    const Operand &Op = IT.Instr.getPrimaryOperand(*Var);
+    const Operand &Op = IT.getInstr().getPrimaryOperand(*Var);
     assert(Op.isReg());
     BitVector PossibleRegs = Op.getRegisterAliasing().sourceBits();
     remove(PossibleRegs, ForbiddenRegisters);
@@ -166,7 +166,7 @@ Expected<std::vector<CodeTemplate>> UopsSnippetGenerator::generateCodeTemplates(
                 State.getTargetMachine().getTargetTriple())
           : 0;
   const AliasingConfigurations SelfAliasing(Instr, Instr);
-  InstructionTemplate IT(Instr);
+  InstructionTemplate IT(&Instr);
   if (SelfAliasing.empty()) {
     CT.Info = "instruction is parallel, repeating a random one.";
     CT.Instructions.push_back(std::move(IT));

diff  --git a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
index 61da38e5f5dd..c67630fdebfc 100644
--- a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
@@ -25,7 +25,7 @@ namespace exegesis {
 // Returns an error if we cannot handle the memory references in this
 // instruction.
 static Error isInvalidMemoryInstr(const Instruction &Instr) {
-  switch (Instr.Description->TSFlags & X86II::FormMask) {
+  switch (Instr.Description.TSFlags & X86II::FormMask) {
   default:
     llvm_unreachable("Unknown FormMask value");
   // These have no memory access.
@@ -114,10 +114,10 @@ static Error isInvalidMemoryInstr(const Instruction &Instr) {
   case X86II::RawFrmImm8:
     return Error::success();
   case X86II::AddRegFrm:
-    return (Instr.Description->Opcode == X86::POP16r ||
-            Instr.Description->Opcode == X86::POP32r ||
-            Instr.Description->Opcode == X86::PUSH16r ||
-            Instr.Description->Opcode == X86::PUSH32r)
+    return (Instr.Description.Opcode == X86::POP16r ||
+            Instr.Description.Opcode == X86::POP32r ||
+            Instr.Description.Opcode == X86::PUSH16r ||
+            Instr.Description.Opcode == X86::PUSH32r)
                ? make_error<Failure>(
                      "unsupported opcode: unsupported memory access")
                : Error::success();
@@ -150,7 +150,7 @@ static Error isInvalidMemoryInstr(const Instruction &Instr) {
 
 static Error IsInvalidOpcode(const Instruction &Instr) {
   const auto OpcodeName = Instr.Name;
-  if ((Instr.Description->TSFlags & X86II::FormMask) == X86II::Pseudo)
+  if ((Instr.Description.TSFlags & X86II::FormMask) == X86II::Pseudo)
     return make_error<Failure>("unsupported opcode: pseudo instruction");
   if (OpcodeName.startswith("POPF") || OpcodeName.startswith("PUSHF") ||
       OpcodeName.startswith("ADJCALLSTACK"))
@@ -172,13 +172,13 @@ static Error IsInvalidOpcode(const Instruction &Instr) {
 }
 
 static unsigned getX86FPFlags(const Instruction &Instr) {
-  return Instr.Description->TSFlags & X86II::FPTypeMask;
+  return Instr.Description.TSFlags & X86II::FPTypeMask;
 }
 
 // Helper to fill a memory operand with a value.
 static void setMemOp(InstructionTemplate &IT, int OpIdx,
                      const MCOperand &OpVal) {
-  const auto Op = IT.Instr.Operands[OpIdx];
+  const auto Op = IT.getInstr().Operands[OpIdx];
   assert(Op.isExplicit() && "invalid memory pattern");
   IT.getValueFor(Op) = OpVal;
 }
@@ -190,7 +190,7 @@ static Expected<std::vector<CodeTemplate>> generateLEATemplatesCommon(
     const LLVMState &State, const SnippetGenerator::Options &Opts,
     std::function<unsigned(unsigned, unsigned)> GetDestReg) {
   assert(Instr.Operands.size() == 6 && "invalid LEA");
-  assert(X86II::getMemoryOperandNo(Instr.Description->TSFlags) == 1 &&
+  assert(X86II::getMemoryOperandNo(Instr.Description.TSFlags) == 1 &&
          "invalid LEA");
 
   constexpr const int kDestOp = 0;
@@ -213,7 +213,7 @@ static Expected<std::vector<CodeTemplate>> generateLEATemplatesCommon(
       for (int LogScale = 0; LogScale <= 3; ++LogScale) {
         // FIXME: Add an option for controlling how we explore immediates.
         for (const int Disp : {0, 42}) {
-          InstructionTemplate IT(Instr);
+          InstructionTemplate IT(&Instr);
           const int64_t Scale = 1ull << LogScale;
           setMemOp(IT, 1, MCOperand::createReg(BaseReg));
           setMemOp(IT, 2, MCOperand::createImm(Scale));
@@ -259,7 +259,7 @@ X86LatencySnippetGenerator::generateCodeTemplates(
     return std::move(E);
 
   // LEA gets special attention.
-  const auto Opcode = Instr.Description->getOpcode();
+  const auto Opcode = Instr.Description.getOpcode();
   if (Opcode == X86::LEA64r || Opcode == X86::LEA64_32r) {
     return generateLEATemplatesCommon(Instr, ForbiddenRegisters, State, Opts,
                                       [](unsigned BaseReg, unsigned IndexReg) {
@@ -310,7 +310,7 @@ X86UopsSnippetGenerator::generateCodeTemplates(
     return std::move(E);
 
   // LEA gets special attention.
-  const auto Opcode = Instr.Description->getOpcode();
+  const auto Opcode = Instr.Description.getOpcode();
   if (Opcode == X86::LEA64r || Opcode == X86::LEA64_32r) {
     // Any destination register that is not used for adddressing is fine.
     auto PossibleDestRegs =
@@ -648,13 +648,13 @@ void ExegesisX86Target::randomizeMCOperand(
 void ExegesisX86Target::fillMemoryOperands(InstructionTemplate &IT,
                                            unsigned Reg,
                                            unsigned Offset) const {
-  assert(!isInvalidMemoryInstr(IT.Instr) &&
+  assert(!isInvalidMemoryInstr(IT.getInstr()) &&
          "fillMemoryOperands requires a valid memory instruction");
-  int MemOpIdx = X86II::getMemoryOperandNo(IT.Instr.Description->TSFlags);
+  int MemOpIdx = X86II::getMemoryOperandNo(IT.getInstr().Description.TSFlags);
   assert(MemOpIdx >= 0 && "invalid memory operand index");
   // getMemoryOperandNo() ignores tied operands, so we have to add them back.
   for (unsigned I = 0; I <= static_cast<unsigned>(MemOpIdx); ++I) {
-    const auto &Op = IT.Instr.Operands[I];
+    const auto &Op = IT.getInstr().Operands[I];
     if (Op.isTied() && Op.getTiedToIndex() < I) {
       ++MemOpIdx;
     }

diff  --git a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
index d16f88e47370..45929fee5f76 100644
--- a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
+++ b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
@@ -208,7 +208,7 @@ static Expected<std::vector<BenchmarkCode>>
 generateSnippets(const LLVMState &State, unsigned Opcode,
                  const BitVector &ForbiddenRegs) {
   const Instruction &Instr = State.getIC().getInstr(Opcode);
-  const MCInstrDesc &InstrDesc = *Instr.Description;
+  const MCInstrDesc &InstrDesc = Instr.Description;
   // Ignore instructions that we cannot run.
   if (InstrDesc.isPseudo())
     return make_error<Failure>("Unsupported opcode: isPseudo");

diff  --git a/llvm/unittests/tools/llvm-exegesis/Mips/SnippetGeneratorTest.cpp b/llvm/unittests/tools/llvm-exegesis/Mips/SnippetGeneratorTest.cpp
index 79d0b708274c..b9280ab6d685 100644
--- a/llvm/unittests/tools/llvm-exegesis/Mips/SnippetGeneratorTest.cpp
+++ b/llvm/unittests/tools/llvm-exegesis/Mips/SnippetGeneratorTest.cpp
@@ -81,8 +81,8 @@ TEST_F(LatencySnippetGeneratorTest, ImplicitSelfDependencyThroughExplicitRegs) {
   ASSERT_THAT(CT.Instructions, SizeIs(1));
   const InstructionTemplate &IT = CT.Instructions[0];
   EXPECT_THAT(IT.getOpcode(), Opcode);
-  ASSERT_THAT(IT.VariableValues, SizeIs(3));
-  EXPECT_THAT(IT.VariableValues,
+  ASSERT_THAT(IT.getVariableValues(), SizeIs(3));
+  EXPECT_THAT(IT.getVariableValues(),
               AnyOf(ElementsAre(IsReg(), IsInvalid(), IsReg()),
                     ElementsAre(IsReg(), IsReg(), IsInvalid())))
       << "Op0 is either set to Op1 or to Op2";

diff  --git a/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp b/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp
index 463eec2c21dd..0f898d9d7bbe 100644
--- a/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp
+++ b/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp
@@ -86,8 +86,8 @@ TEST_F(LatencySnippetGeneratorTest, ImplicitSelfDependencyThroughImplicitReg) {
   ASSERT_THAT(CT.Instructions, SizeIs(1));
   const InstructionTemplate &IT = CT.Instructions[0];
   EXPECT_THAT(IT.getOpcode(), Opcode);
-  ASSERT_THAT(IT.VariableValues, SizeIs(1)); // Imm.
-  EXPECT_THAT(IT.VariableValues[0], IsInvalid()) << "Immediate is not set";
+  ASSERT_THAT(IT.getVariableValues(), SizeIs(1)); // Imm.
+  EXPECT_THAT(IT.getVariableValues()[0], IsInvalid()) << "Immediate is not set";
 }
 
 TEST_F(LatencySnippetGeneratorTest, ImplicitSelfDependencyThroughTiedRegs) {
@@ -109,9 +109,9 @@ TEST_F(LatencySnippetGeneratorTest, ImplicitSelfDependencyThroughTiedRegs) {
   ASSERT_THAT(CT.Instructions, SizeIs(1));
   const InstructionTemplate &IT = CT.Instructions[0];
   EXPECT_THAT(IT.getOpcode(), Opcode);
-  ASSERT_THAT(IT.VariableValues, SizeIs(2));
-  EXPECT_THAT(IT.VariableValues[0], IsInvalid()) << "Operand 1 is not set";
-  EXPECT_THAT(IT.VariableValues[1], IsInvalid()) << "Operand 2 is not set";
+  ASSERT_THAT(IT.getVariableValues(), SizeIs(2));
+  EXPECT_THAT(IT.getVariableValues()[0], IsInvalid()) << "Operand 1 is not set";
+  EXPECT_THAT(IT.getVariableValues()[1], IsInvalid()) << "Operand 2 is not set";
 }
 
 TEST_F(LatencySnippetGeneratorTest, ImplicitSelfDependencyThroughExplicitRegs) {
@@ -131,8 +131,8 @@ TEST_F(LatencySnippetGeneratorTest, ImplicitSelfDependencyThroughExplicitRegs) {
   ASSERT_THAT(CT.Instructions, SizeIs(1));
   const InstructionTemplate &IT = CT.Instructions[0];
   EXPECT_THAT(IT.getOpcode(), Opcode);
-  ASSERT_THAT(IT.VariableValues, SizeIs(3));
-  EXPECT_THAT(IT.VariableValues,
+  ASSERT_THAT(IT.getVariableValues(), SizeIs(3));
+  EXPECT_THAT(IT.getVariableValues(),
               AnyOf(ElementsAre(IsReg(), IsInvalid(), IsReg()),
                     ElementsAre(IsReg(), IsReg(), IsInvalid())))
       << "Op0 is either set to Op1 or to Op2";
@@ -173,9 +173,10 @@ TEST_F(LatencySnippetGeneratorTest, DependencyThroughOtherOpcode) {
     ASSERT_THAT(CT.Instructions, SizeIs(2));
     const InstructionTemplate &IT = CT.Instructions[0];
     EXPECT_THAT(IT.getOpcode(), Opcode);
-    ASSERT_THAT(IT.VariableValues, SizeIs(2));
-    EXPECT_THAT(IT.VariableValues, AnyOf(ElementsAre(IsReg(), IsInvalid()),
-                                         ElementsAre(IsInvalid(), IsReg())));
+    ASSERT_THAT(IT.getVariableValues(), SizeIs(2));
+    EXPECT_THAT(IT.getVariableValues(),
+                AnyOf(ElementsAre(IsReg(), IsInvalid()),
+                      ElementsAre(IsInvalid(), IsReg())));
     EXPECT_THAT(CT.Instructions[1].getOpcode(), Not(Opcode));
     // TODO: check that the two instructions alias each other.
   }
@@ -193,7 +194,7 @@ TEST_F(LatencySnippetGeneratorTest, LAHF) {
     ASSERT_THAT(CT.Instructions, SizeIs(2));
     const InstructionTemplate &IT = CT.Instructions[0];
     EXPECT_THAT(IT.getOpcode(), Opcode);
-    ASSERT_THAT(IT.VariableValues, SizeIs(0));
+    ASSERT_THAT(IT.getVariableValues(), SizeIs(0));
   }
 }
 
@@ -212,9 +213,9 @@ TEST_F(UopsSnippetGeneratorTest, ParallelInstruction) {
   ASSERT_THAT(CT.Instructions, SizeIs(1));
   const InstructionTemplate &IT = CT.Instructions[0];
   EXPECT_THAT(IT.getOpcode(), Opcode);
-  ASSERT_THAT(IT.VariableValues, SizeIs(2));
-  EXPECT_THAT(IT.VariableValues[0], IsInvalid());
-  EXPECT_THAT(IT.VariableValues[1], IsInvalid());
+  ASSERT_THAT(IT.getVariableValues(), SizeIs(2));
+  EXPECT_THAT(IT.getVariableValues()[0], IsInvalid());
+  EXPECT_THAT(IT.getVariableValues()[1], IsInvalid());
 }
 
 TEST_F(UopsSnippetGeneratorTest, SerialInstruction) {
@@ -233,7 +234,7 @@ TEST_F(UopsSnippetGeneratorTest, SerialInstruction) {
   ASSERT_THAT(CT.Instructions, SizeIs(1));
   const InstructionTemplate &IT = CT.Instructions[0];
   EXPECT_THAT(IT.getOpcode(), Opcode);
-  ASSERT_THAT(IT.VariableValues, SizeIs(0));
+  ASSERT_THAT(IT.getVariableValues(), SizeIs(0));
 }
 
 TEST_F(UopsSnippetGeneratorTest, StaticRenaming) {
@@ -260,8 +261,8 @@ TEST_F(UopsSnippetGeneratorTest, StaticRenaming) {
   ASSERT_THAT(CT.Instructions, SizeIs(kInstructionCount));
   std::unordered_set<unsigned> AllDefRegisters;
   for (const auto &IT : CT.Instructions) {
-    ASSERT_THAT(IT.VariableValues, SizeIs(3));
-    AllDefRegisters.insert(IT.VariableValues[0].getReg());
+    ASSERT_THAT(IT.getVariableValues(), SizeIs(3));
+    AllDefRegisters.insert(IT.getVariableValues()[0].getReg());
   }
   EXPECT_THAT(AllDefRegisters, SizeIs(kInstructionCount))
       << "Each instruction writes to a 
diff erent register";
@@ -291,12 +292,14 @@ TEST_F(UopsSnippetGeneratorTest, NoTiedVariables) {
   ASSERT_THAT(CT.Instructions, SizeIs(1));
   const InstructionTemplate &IT = CT.Instructions[0];
   EXPECT_THAT(IT.getOpcode(), Opcode);
-  ASSERT_THAT(IT.VariableValues, SizeIs(4));
-  EXPECT_THAT(IT.VariableValues[0].getReg(), Not(IT.VariableValues[1].getReg()))
+  ASSERT_THAT(IT.getVariableValues(), SizeIs(4));
+  EXPECT_THAT(IT.getVariableValues()[0].getReg(),
+              Not(IT.getVariableValues()[1].getReg()))
       << "Def is 
diff erent from first Use";
-  EXPECT_THAT(IT.VariableValues[0].getReg(), Not(IT.VariableValues[2].getReg()))
+  EXPECT_THAT(IT.getVariableValues()[0].getReg(),
+              Not(IT.getVariableValues()[2].getReg()))
       << "Def is 
diff erent from second Use";
-  EXPECT_THAT(IT.VariableValues[3], IsInvalid());
+  EXPECT_THAT(IT.getVariableValues()[3], IsInvalid());
 }
 
 TEST_F(UopsSnippetGeneratorTest, MemoryUse) {
@@ -326,11 +329,11 @@ TEST_F(UopsSnippetGeneratorTest, MemoryUse) {
               SizeIs(UopsSnippetGenerator::kMinNumDifferentAddresses));
   const InstructionTemplate &IT = CT.Instructions[0];
   EXPECT_THAT(IT.getOpcode(), Opcode);
-  ASSERT_THAT(IT.VariableValues, SizeIs(6));
-  EXPECT_EQ(IT.VariableValues[2].getImm(), 1);
-  EXPECT_EQ(IT.VariableValues[3].getReg(), 0u);
-  EXPECT_EQ(IT.VariableValues[4].getImm(), 0);
-  EXPECT_EQ(IT.VariableValues[5].getReg(), 0u);
+  ASSERT_THAT(IT.getVariableValues(), SizeIs(6));
+  EXPECT_EQ(IT.getVariableValues()[2].getImm(), 1);
+  EXPECT_EQ(IT.getVariableValues()[3].getReg(), 0u);
+  EXPECT_EQ(IT.getVariableValues()[4].getImm(), 0);
+  EXPECT_EQ(IT.getVariableValues()[5].getReg(), 0u);
 }
 
 class FakeSnippetGenerator : public SnippetGenerator {
@@ -338,10 +341,14 @@ class FakeSnippetGenerator : public SnippetGenerator {
   FakeSnippetGenerator(const LLVMState &State, const Options &Opts)
       : SnippetGenerator(State, Opts) {}
 
-  Instruction createInstruction(unsigned Opcode) {
+  const Instruction &getInstr(unsigned Opcode) {
     return State.getIC().getInstr(Opcode);
   }
 
+  InstructionTemplate getInstructionTemplate(unsigned Opcode) {
+    return {&getInstr(Opcode)};
+  }
+
 private:
   Expected<std::vector<CodeTemplate>>
   generateCodeTemplates(const Instruction &, const BitVector &) const override {
@@ -389,8 +396,8 @@ TEST_F(FakeSnippetGeneratorTest, ComputeRegisterInitialValuesAdd16ri) {
   // explicit use 1       : reg RegClass=GR16 | TIED_TO:0
   // explicit use 2       : imm
   // implicit def         : EFLAGS
-  InstructionTemplate IT(Generator.createInstruction(X86::ADD16ri));
-  IT.getValueFor(IT.Instr.Variables[0]) = MCOperand::createReg(X86::AX);
+  InstructionTemplate IT = Generator.getInstructionTemplate(X86::ADD16ri);
+  IT.getValueFor(IT.getInstr().Variables[0]) = MCOperand::createReg(X86::AX);
   std::vector<InstructionTemplate> Snippet;
   Snippet.push_back(std::move(IT));
   const auto RIV = Generator.computeRegisterInitialValues(Snippet);
@@ -404,15 +411,18 @@ TEST_F(FakeSnippetGeneratorTest, ComputeRegisterInitialValuesAdd64rr) {
   // -> only rbx needs defining.
   std::vector<InstructionTemplate> Snippet;
   {
-    InstructionTemplate Mov(Generator.createInstruction(X86::MOV64ri));
-    Mov.getValueFor(Mov.Instr.Variables[0]) = MCOperand::createReg(X86::RAX);
-    Mov.getValueFor(Mov.Instr.Variables[1]) = MCOperand::createImm(42);
+    InstructionTemplate Mov = Generator.getInstructionTemplate(X86::MOV64ri);
+    Mov.getValueFor(Mov.getInstr().Variables[0]) =
+        MCOperand::createReg(X86::RAX);
+    Mov.getValueFor(Mov.getInstr().Variables[1]) = MCOperand::createImm(42);
     Snippet.push_back(std::move(Mov));
   }
   {
-    InstructionTemplate Add(Generator.createInstruction(X86::ADD64rr));
-    Add.getValueFor(Add.Instr.Variables[0]) = MCOperand::createReg(X86::RAX);
-    Add.getValueFor(Add.Instr.Variables[1]) = MCOperand::createReg(X86::RBX);
+    InstructionTemplate Add = Generator.getInstructionTemplate(X86::ADD64rr);
+    Add.getValueFor(Add.getInstr().Variables[0]) =
+        MCOperand::createReg(X86::RAX);
+    Add.getValueFor(Add.getInstr().Variables[1]) =
+        MCOperand::createReg(X86::RBX);
     Snippet.push_back(std::move(Add));
   }
 

diff  --git a/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp b/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp
index e15b7f2dbba3..eefed6dd5441 100644
--- a/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp
+++ b/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp
@@ -119,6 +119,10 @@ class X86TargetTest : public ::testing::Test {
                                               Value);
   }
 
+  const Instruction &getInstr(unsigned OpCode) {
+    return State.getIC().getInstr(OpCode);
+  }
+
   LLVMState State;
 };
 
@@ -355,8 +359,8 @@ TEST_F(Core2TargetTest, SetRegToFP1_4Bits) {
 }
 
 TEST_F(Core2Avx512TargetTest, FillMemoryOperands_ADD64rm) {
-  Instruction I(State.getInstrInfo(), State.getRATC(), X86::ADD64rm);
-  InstructionTemplate IT(I);
+  const Instruction &I = getInstr(X86::ADD64rm);
+  InstructionTemplate IT(&I);
   constexpr const int kOffset = 42;
   State.getExegesisTarget().fillMemoryOperands(IT, X86::RDI, kOffset);
   // Memory is operands 2-6.
@@ -368,8 +372,8 @@ TEST_F(Core2Avx512TargetTest, FillMemoryOperands_ADD64rm) {
 }
 
 TEST_F(Core2Avx512TargetTest, FillMemoryOperands_VGATHERDPSZ128rm) {
-  Instruction I(State.getInstrInfo(), State.getRATC(), X86::VGATHERDPSZ128rm);
-  InstructionTemplate IT(I);
+  const Instruction &I = getInstr(X86::VGATHERDPSZ128rm);
+  InstructionTemplate IT(&I);
   constexpr const int kOffset = 42;
   State.getExegesisTarget().fillMemoryOperands(IT, X86::RDI, kOffset);
   // Memory is operands 4-8.


        


More information about the llvm-commits mailing list