diff --git a/llvm/tools/llvm-exegesis/lib/Latency.cpp b/llvm/tools/llvm-exegesis/lib/Latency.cpp index 4173cf3f9a1b..ea646f4f2613 100644 --- a/llvm/tools/llvm-exegesis/lib/Latency.cpp +++ b/llvm/tools/llvm-exegesis/lib/Latency.cpp @@ -32,8 +32,7 @@ LatencySnippetGenerator::generateTwoInstructionPrototype( for (const unsigned OtherOpcode : Opcodes) { if (OtherOpcode == Instr.Description->Opcode) continue; - const auto &OtherInstrDesc = State.getInstrInfo().get(OtherOpcode); - const Instruction OtherInstr(OtherInstrDesc, RATC); + const Instruction OtherInstr(State, OtherOpcode); if (OtherInstr.hasMemoryOperands()) continue; const AliasingConfigurations Forward(Instr, OtherInstr); @@ -59,7 +58,7 @@ LatencySnippetGenerator::generateTwoInstructionPrototype( llvm::Expected LatencySnippetGenerator::generateCodeTemplate(unsigned Opcode) const { - const Instruction Instr(State.getInstrInfo().get(Opcode), RATC); + const Instruction Instr(State, Opcode); if (Instr.hasMemoryOperands()) return llvm::make_error( "Infeasible : has memory operands"); diff --git a/llvm/tools/llvm-exegesis/lib/LlvmState.cpp b/llvm/tools/llvm-exegesis/lib/LlvmState.cpp index 9ff42ca71fd2..279792e90316 100644 --- a/llvm/tools/llvm-exegesis/lib/LlvmState.cpp +++ b/llvm/tools/llvm-exegesis/lib/LlvmState.cpp @@ -35,6 +35,8 @@ LLVMState::LLVMState(const std::string &Triple, const std::string &CpuName) { llvm::errs() << "no exegesis target for " << Triple << ", using default\n"; TheExegesisTarget = &ExegesisTarget::getDefault(); } + RATC.reset(new RegisterAliasingTrackerCache( + getRegInfo(), getFunctionReservedRegs(getTargetMachine()))); } LLVMState::LLVMState() diff --git a/llvm/tools/llvm-exegesis/lib/LlvmState.h b/llvm/tools/llvm-exegesis/lib/LlvmState.h index c84db300841e..aa7705a36a69 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 "RegisterAliasing.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstrInfo.h" @@ -54,10 +55,12 @@ public: const llvm::MCSubtargetInfo &getSubtargetInfo() const { return *TargetMachine->getMCSubtargetInfo(); } + const RegisterAliasingTrackerCache &getRATC() const { return *RATC; } private: const ExegesisTarget *TheExegesisTarget; std::unique_ptr TargetMachine; + std::unique_ptr RATC; }; } // namespace exegesis diff --git a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp index 75d85873146a..d54f3ca2a45d 100644 --- a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp +++ b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp @@ -87,24 +87,24 @@ const llvm::MCOperandInfo &Operand::getExplicitOperandInfo() const { return *Info; } -Instruction::Instruction(const llvm::MCInstrDesc &MCInstrDesc, - const RegisterAliasingTrackerCache &RATC) - : Description(&MCInstrDesc) { +Instruction::Instruction(const LLVMState &State, unsigned Opcode) + : Description(&State.getInstrInfo().get(Opcode)) { + const auto &RATC = State.getRATC(); unsigned OpIndex = 0; - for (; OpIndex < MCInstrDesc.getNumOperands(); ++OpIndex) { - const auto &OpInfo = MCInstrDesc.opInfo_begin()[OpIndex]; + for (; OpIndex < Description->getNumOperands(); ++OpIndex) { + const auto &OpInfo = Description->opInfo_begin()[OpIndex]; Operand Operand; Operand.Index = OpIndex; - Operand.IsDef = (OpIndex < MCInstrDesc.getNumDefs()); + Operand.IsDef = (OpIndex < Description->getNumDefs()); // TODO(gchatelet): Handle isLookupPtrRegClass. if (OpInfo.RegClass >= 0) Operand.Tracker = &RATC.getRegisterClass(OpInfo.RegClass); Operand.TiedToIndex = - MCInstrDesc.getOperandConstraint(OpIndex, llvm::MCOI::TIED_TO); + Description->getOperandConstraint(OpIndex, llvm::MCOI::TIED_TO); Operand.Info = &OpInfo; Operands.push_back(Operand); } - for (const llvm::MCPhysReg *MCPhysReg = MCInstrDesc.getImplicitDefs(); + for (const llvm::MCPhysReg *MCPhysReg = Description->getImplicitDefs(); MCPhysReg && *MCPhysReg; ++MCPhysReg, ++OpIndex) { Operand Operand; Operand.Index = OpIndex; @@ -113,7 +113,7 @@ Instruction::Instruction(const llvm::MCInstrDesc &MCInstrDesc, Operand.ImplicitReg = MCPhysReg; Operands.push_back(Operand); } - for (const llvm::MCPhysReg *MCPhysReg = MCInstrDesc.getImplicitUses(); + for (const llvm::MCPhysReg *MCPhysReg = Description->getImplicitUses(); MCPhysReg && *MCPhysReg; ++MCPhysReg, ++OpIndex) { Operand Operand; Operand.Index = OpIndex; diff --git a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h index 39e5c4a5f5b2..914bf51a22b3 100644 --- a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h +++ b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h @@ -21,6 +21,7 @@ #include +#include "LlvmState.h" #include "RegisterAliasing.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" @@ -92,8 +93,7 @@ struct Operand { // A view over an MCInstrDesc offering a convenient interface to compute // Register aliasing. struct Instruction { - Instruction(const llvm::MCInstrDesc &MCInstrDesc, - const RegisterAliasingTrackerCache &ATC); + Instruction(const LLVMState &State, unsigned Opcode); // Returns the Operand linked to this Variable. // In case the Variable is tied, the primary (i.e. Def) Operand is returned. diff --git a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp index 3765776f7249..16dbd214e958 100644 --- a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp +++ b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp @@ -25,9 +25,7 @@ namespace exegesis { SnippetGeneratorFailure::SnippetGeneratorFailure(const llvm::Twine &S) : llvm::StringError(S, llvm::inconvertibleErrorCode()) {} -SnippetGenerator::SnippetGenerator(const LLVMState &State) - : State(State), RATC(State.getRegInfo(), - getFunctionReservedRegs(State.getTargetMachine())) {} +SnippetGenerator::SnippetGenerator(const LLVMState &State) : State(State) {} SnippetGenerator::~SnippetGenerator() = default; @@ -35,6 +33,7 @@ llvm::Expected> SnippetGenerator::generateConfigurations(unsigned Opcode) const { if (auto E = generateCodeTemplate(Opcode)) { CodeTemplate &CT = E.get(); + const auto &RATC = State.getRATC(); const llvm::BitVector &ForbiddenRegs = CT.ScratchSpacePointerInReg ? RATC.getRegister(CT.ScratchSpacePointerInReg).aliasedBits() @@ -64,7 +63,7 @@ std::vector SnippetGenerator::computeRegisterInitialValues( // Ignore memory operands which are handled separately. // Loop invariant: DefinedRegs[i] is true iif it has been set at least once // before the current instruction. - llvm::BitVector DefinedRegs = RATC.emptyRegisters(); + llvm::BitVector DefinedRegs = State.getRATC().emptyRegisters(); std::vector RIV; for (const InstructionTemplate &IT : Instructions) { // Returns the register that this Operand sets or uses, or 0 if this is not diff --git a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.h b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.h index 9493c5848165..24afe95fda03 100644 --- a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.h +++ b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.h @@ -54,7 +54,6 @@ public: protected: const LLVMState &State; - const RegisterAliasingTrackerCache RATC; // Generates a single code template that has a self-dependency. llvm::Expected diff --git a/llvm/tools/llvm-exegesis/lib/Uops.cpp b/llvm/tools/llvm-exegesis/lib/Uops.cpp index 2208e2a38211..fdb6a27ab593 100644 --- a/llvm/tools/llvm-exegesis/lib/Uops.cpp +++ b/llvm/tools/llvm-exegesis/lib/Uops.cpp @@ -130,7 +130,7 @@ UopsSnippetGenerator::generateCodeTemplate(unsigned Opcode) const { CodeTemplate CT; const llvm::BitVector *ScratchSpaceAliasedRegs = nullptr; - const Instruction Instr(State.getInstrInfo().get(Opcode), RATC); + const Instruction Instr(State, Opcode); if (Instr.hasMemoryOperands()) { CT.ScratchSpacePointerInReg = ET.getScratchMemoryRegister(State.getTargetMachine().getTargetTriple()); @@ -138,7 +138,7 @@ UopsSnippetGenerator::generateCodeTemplate(unsigned Opcode) const { return llvm::make_error( "Infeasible : target does not support memory instructions"); ScratchSpaceAliasedRegs = - &RATC.getRegister(CT.ScratchSpacePointerInReg).aliasedBits(); + &State.getRATC().getRegister(CT.ScratchSpacePointerInReg).aliasedBits(); // If the instruction implicitly writes to ScratchSpacePointerInReg , abort. // FIXME: We could make a copy of the scratch register. for (const auto &Op : Instr.Operands) { @@ -185,12 +185,13 @@ UopsSnippetGenerator::generateCodeTemplate(unsigned Opcode) const { instantiateMemoryOperands(CT.ScratchSpacePointerInReg, CT.Instructions); return std::move(CT); } + const auto &ReservedRegisters = State.getRATC().reservedRegisters(); // No tied variables, we pick random values for defs. llvm::BitVector Defs(State.getRegInfo().getNumRegs()); for (const auto &Op : Instr.Operands) { if (Op.isReg() && Op.isExplicit() && Op.isDef() && !Op.isMemory()) { auto PossibleRegisters = Op.getRegisterAliasing().sourceBits(); - remove(PossibleRegisters, RATC.reservedRegisters()); + remove(PossibleRegisters, ReservedRegisters); // Do not use the scratch memory address register. if (ScratchSpaceAliasedRegs) remove(PossibleRegisters, *ScratchSpaceAliasedRegs); @@ -205,7 +206,7 @@ UopsSnippetGenerator::generateCodeTemplate(unsigned Opcode) const { for (const auto &Op : Instr.Operands) { if (Op.isReg() && Op.isExplicit() && Op.isUse() && !Op.isMemory()) { auto PossibleRegisters = Op.getRegisterAliasing().sourceBits(); - remove(PossibleRegisters, RATC.reservedRegisters()); + remove(PossibleRegisters, ReservedRegisters); // Do not use the scratch memory address register. if (ScratchSpaceAliasedRegs) remove(PossibleRegisters, *ScratchSpaceAliasedRegs); diff --git a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp index 4a9cb08e27a6..8c03f1ac8260 100644 --- a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp @@ -37,9 +37,9 @@ template class X86SnippetGenerator : public Impl { } // Handle X87. - const auto &InstrDesc = InstrInfo.get(Opcode); - const unsigned FPInstClass = InstrDesc.TSFlags & llvm::X86II::FPTypeMask; - const Instruction Instr(InstrDesc, this->RATC); + const unsigned FPInstClass = + InstrInfo.get(Opcode).TSFlags & llvm::X86II::FPTypeMask; + const Instruction Instr(this->State, Opcode); switch (FPInstClass) { case llvm::X86II::NotFP: break; diff --git a/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp b/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp index 9685c730b8b5..f2539aaea186 100644 --- a/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp +++ b/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp @@ -248,7 +248,7 @@ public: FakeSnippetGenerator(const LLVMState &State) : SnippetGenerator(State) {} Instruction createInstruction(unsigned Opcode) { - return Instruction(State.getInstrInfo().get(Opcode), RATC); + return Instruction(State, Opcode); } private: