forked from OSchip/llvm-project
[llvm-exegesis][NFC] Code simplification
Summary: Simplify code by having LLVMState hold the RegisterAliasingTrackerCache. Reviewers: courbet Subscribers: tschuett, llvm-commits Differential Revision: https://reviews.llvm.org/D53078 llvm-svn: 344143
This commit is contained in:
parent
07acc992dc
commit
ee9c2a17b8
|
@ -32,8 +32,7 @@ LatencySnippetGenerator::generateTwoInstructionPrototype(
|
||||||
for (const unsigned OtherOpcode : Opcodes) {
|
for (const unsigned OtherOpcode : Opcodes) {
|
||||||
if (OtherOpcode == Instr.Description->Opcode)
|
if (OtherOpcode == Instr.Description->Opcode)
|
||||||
continue;
|
continue;
|
||||||
const auto &OtherInstrDesc = State.getInstrInfo().get(OtherOpcode);
|
const Instruction OtherInstr(State, OtherOpcode);
|
||||||
const Instruction OtherInstr(OtherInstrDesc, RATC);
|
|
||||||
if (OtherInstr.hasMemoryOperands())
|
if (OtherInstr.hasMemoryOperands())
|
||||||
continue;
|
continue;
|
||||||
const AliasingConfigurations Forward(Instr, OtherInstr);
|
const AliasingConfigurations Forward(Instr, OtherInstr);
|
||||||
|
@ -59,7 +58,7 @@ LatencySnippetGenerator::generateTwoInstructionPrototype(
|
||||||
|
|
||||||
llvm::Expected<CodeTemplate>
|
llvm::Expected<CodeTemplate>
|
||||||
LatencySnippetGenerator::generateCodeTemplate(unsigned Opcode) const {
|
LatencySnippetGenerator::generateCodeTemplate(unsigned Opcode) const {
|
||||||
const Instruction Instr(State.getInstrInfo().get(Opcode), RATC);
|
const Instruction Instr(State, Opcode);
|
||||||
if (Instr.hasMemoryOperands())
|
if (Instr.hasMemoryOperands())
|
||||||
return llvm::make_error<BenchmarkFailure>(
|
return llvm::make_error<BenchmarkFailure>(
|
||||||
"Infeasible : has memory operands");
|
"Infeasible : has memory operands");
|
||||||
|
|
|
@ -35,6 +35,8 @@ LLVMState::LLVMState(const std::string &Triple, const std::string &CpuName) {
|
||||||
llvm::errs() << "no exegesis target for " << Triple << ", using default\n";
|
llvm::errs() << "no exegesis target for " << Triple << ", using default\n";
|
||||||
TheExegesisTarget = &ExegesisTarget::getDefault();
|
TheExegesisTarget = &ExegesisTarget::getDefault();
|
||||||
}
|
}
|
||||||
|
RATC.reset(new RegisterAliasingTrackerCache(
|
||||||
|
getRegInfo(), getFunctionReservedRegs(getTargetMachine())));
|
||||||
}
|
}
|
||||||
|
|
||||||
LLVMState::LLVMState()
|
LLVMState::LLVMState()
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#ifndef LLVM_TOOLS_LLVM_EXEGESIS_LLVMSTATE_H
|
#ifndef LLVM_TOOLS_LLVM_EXEGESIS_LLVMSTATE_H
|
||||||
#define LLVM_TOOLS_LLVM_EXEGESIS_LLVMSTATE_H
|
#define LLVM_TOOLS_LLVM_EXEGESIS_LLVMSTATE_H
|
||||||
|
|
||||||
|
#include "RegisterAliasing.h"
|
||||||
#include "llvm/MC/MCAsmInfo.h"
|
#include "llvm/MC/MCAsmInfo.h"
|
||||||
#include "llvm/MC/MCInst.h"
|
#include "llvm/MC/MCInst.h"
|
||||||
#include "llvm/MC/MCInstrInfo.h"
|
#include "llvm/MC/MCInstrInfo.h"
|
||||||
|
@ -54,10 +55,12 @@ public:
|
||||||
const llvm::MCSubtargetInfo &getSubtargetInfo() const {
|
const llvm::MCSubtargetInfo &getSubtargetInfo() const {
|
||||||
return *TargetMachine->getMCSubtargetInfo();
|
return *TargetMachine->getMCSubtargetInfo();
|
||||||
}
|
}
|
||||||
|
const RegisterAliasingTrackerCache &getRATC() const { return *RATC; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const ExegesisTarget *TheExegesisTarget;
|
const ExegesisTarget *TheExegesisTarget;
|
||||||
std::unique_ptr<const llvm::TargetMachine> TargetMachine;
|
std::unique_ptr<const llvm::TargetMachine> TargetMachine;
|
||||||
|
std::unique_ptr<const RegisterAliasingTrackerCache> RATC;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace exegesis
|
} // namespace exegesis
|
||||||
|
|
|
@ -87,24 +87,24 @@ const llvm::MCOperandInfo &Operand::getExplicitOperandInfo() const {
|
||||||
return *Info;
|
return *Info;
|
||||||
}
|
}
|
||||||
|
|
||||||
Instruction::Instruction(const llvm::MCInstrDesc &MCInstrDesc,
|
Instruction::Instruction(const LLVMState &State, unsigned Opcode)
|
||||||
const RegisterAliasingTrackerCache &RATC)
|
: Description(&State.getInstrInfo().get(Opcode)) {
|
||||||
: Description(&MCInstrDesc) {
|
const auto &RATC = State.getRATC();
|
||||||
unsigned OpIndex = 0;
|
unsigned OpIndex = 0;
|
||||||
for (; OpIndex < MCInstrDesc.getNumOperands(); ++OpIndex) {
|
for (; OpIndex < Description->getNumOperands(); ++OpIndex) {
|
||||||
const auto &OpInfo = MCInstrDesc.opInfo_begin()[OpIndex];
|
const auto &OpInfo = Description->opInfo_begin()[OpIndex];
|
||||||
Operand Operand;
|
Operand Operand;
|
||||||
Operand.Index = OpIndex;
|
Operand.Index = OpIndex;
|
||||||
Operand.IsDef = (OpIndex < MCInstrDesc.getNumDefs());
|
Operand.IsDef = (OpIndex < Description->getNumDefs());
|
||||||
// TODO(gchatelet): Handle isLookupPtrRegClass.
|
// TODO(gchatelet): Handle isLookupPtrRegClass.
|
||||||
if (OpInfo.RegClass >= 0)
|
if (OpInfo.RegClass >= 0)
|
||||||
Operand.Tracker = &RATC.getRegisterClass(OpInfo.RegClass);
|
Operand.Tracker = &RATC.getRegisterClass(OpInfo.RegClass);
|
||||||
Operand.TiedToIndex =
|
Operand.TiedToIndex =
|
||||||
MCInstrDesc.getOperandConstraint(OpIndex, llvm::MCOI::TIED_TO);
|
Description->getOperandConstraint(OpIndex, llvm::MCOI::TIED_TO);
|
||||||
Operand.Info = &OpInfo;
|
Operand.Info = &OpInfo;
|
||||||
Operands.push_back(Operand);
|
Operands.push_back(Operand);
|
||||||
}
|
}
|
||||||
for (const llvm::MCPhysReg *MCPhysReg = MCInstrDesc.getImplicitDefs();
|
for (const llvm::MCPhysReg *MCPhysReg = Description->getImplicitDefs();
|
||||||
MCPhysReg && *MCPhysReg; ++MCPhysReg, ++OpIndex) {
|
MCPhysReg && *MCPhysReg; ++MCPhysReg, ++OpIndex) {
|
||||||
Operand Operand;
|
Operand Operand;
|
||||||
Operand.Index = OpIndex;
|
Operand.Index = OpIndex;
|
||||||
|
@ -113,7 +113,7 @@ Instruction::Instruction(const llvm::MCInstrDesc &MCInstrDesc,
|
||||||
Operand.ImplicitReg = MCPhysReg;
|
Operand.ImplicitReg = MCPhysReg;
|
||||||
Operands.push_back(Operand);
|
Operands.push_back(Operand);
|
||||||
}
|
}
|
||||||
for (const llvm::MCPhysReg *MCPhysReg = MCInstrDesc.getImplicitUses();
|
for (const llvm::MCPhysReg *MCPhysReg = Description->getImplicitUses();
|
||||||
MCPhysReg && *MCPhysReg; ++MCPhysReg, ++OpIndex) {
|
MCPhysReg && *MCPhysReg; ++MCPhysReg, ++OpIndex) {
|
||||||
Operand Operand;
|
Operand Operand;
|
||||||
Operand.Index = OpIndex;
|
Operand.Index = OpIndex;
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
#include <random>
|
#include <random>
|
||||||
|
|
||||||
|
#include "LlvmState.h"
|
||||||
#include "RegisterAliasing.h"
|
#include "RegisterAliasing.h"
|
||||||
#include "llvm/ADT/ArrayRef.h"
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
#include "llvm/ADT/Optional.h"
|
#include "llvm/ADT/Optional.h"
|
||||||
|
@ -92,8 +93,7 @@ struct Operand {
|
||||||
// A view over an MCInstrDesc offering a convenient interface to compute
|
// A view over an MCInstrDesc offering a convenient interface to compute
|
||||||
// Register aliasing.
|
// Register aliasing.
|
||||||
struct Instruction {
|
struct Instruction {
|
||||||
Instruction(const llvm::MCInstrDesc &MCInstrDesc,
|
Instruction(const LLVMState &State, unsigned Opcode);
|
||||||
const RegisterAliasingTrackerCache &ATC);
|
|
||||||
|
|
||||||
// Returns the Operand linked to this Variable.
|
// Returns the Operand linked to this Variable.
|
||||||
// In case the Variable is tied, the primary (i.e. Def) Operand is returned.
|
// In case the Variable is tied, the primary (i.e. Def) Operand is returned.
|
||||||
|
|
|
@ -25,9 +25,7 @@ namespace exegesis {
|
||||||
SnippetGeneratorFailure::SnippetGeneratorFailure(const llvm::Twine &S)
|
SnippetGeneratorFailure::SnippetGeneratorFailure(const llvm::Twine &S)
|
||||||
: llvm::StringError(S, llvm::inconvertibleErrorCode()) {}
|
: llvm::StringError(S, llvm::inconvertibleErrorCode()) {}
|
||||||
|
|
||||||
SnippetGenerator::SnippetGenerator(const LLVMState &State)
|
SnippetGenerator::SnippetGenerator(const LLVMState &State) : State(State) {}
|
||||||
: State(State), RATC(State.getRegInfo(),
|
|
||||||
getFunctionReservedRegs(State.getTargetMachine())) {}
|
|
||||||
|
|
||||||
SnippetGenerator::~SnippetGenerator() = default;
|
SnippetGenerator::~SnippetGenerator() = default;
|
||||||
|
|
||||||
|
@ -35,6 +33,7 @@ llvm::Expected<std::vector<BenchmarkCode>>
|
||||||
SnippetGenerator::generateConfigurations(unsigned Opcode) const {
|
SnippetGenerator::generateConfigurations(unsigned Opcode) const {
|
||||||
if (auto E = generateCodeTemplate(Opcode)) {
|
if (auto E = generateCodeTemplate(Opcode)) {
|
||||||
CodeTemplate &CT = E.get();
|
CodeTemplate &CT = E.get();
|
||||||
|
const auto &RATC = State.getRATC();
|
||||||
const llvm::BitVector &ForbiddenRegs =
|
const llvm::BitVector &ForbiddenRegs =
|
||||||
CT.ScratchSpacePointerInReg
|
CT.ScratchSpacePointerInReg
|
||||||
? RATC.getRegister(CT.ScratchSpacePointerInReg).aliasedBits()
|
? RATC.getRegister(CT.ScratchSpacePointerInReg).aliasedBits()
|
||||||
|
@ -64,7 +63,7 @@ std::vector<RegisterValue> SnippetGenerator::computeRegisterInitialValues(
|
||||||
// Ignore memory operands which are handled separately.
|
// Ignore memory operands which are handled separately.
|
||||||
// Loop invariant: DefinedRegs[i] is true iif it has been set at least once
|
// Loop invariant: DefinedRegs[i] is true iif it has been set at least once
|
||||||
// before the current instruction.
|
// before the current instruction.
|
||||||
llvm::BitVector DefinedRegs = RATC.emptyRegisters();
|
llvm::BitVector DefinedRegs = State.getRATC().emptyRegisters();
|
||||||
std::vector<RegisterValue> RIV;
|
std::vector<RegisterValue> RIV;
|
||||||
for (const InstructionTemplate &IT : Instructions) {
|
for (const InstructionTemplate &IT : Instructions) {
|
||||||
// Returns the register that this Operand sets or uses, or 0 if this is not
|
// Returns the register that this Operand sets or uses, or 0 if this is not
|
||||||
|
|
|
@ -54,7 +54,6 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const LLVMState &State;
|
const LLVMState &State;
|
||||||
const RegisterAliasingTrackerCache RATC;
|
|
||||||
|
|
||||||
// Generates a single code template that has a self-dependency.
|
// Generates a single code template that has a self-dependency.
|
||||||
llvm::Expected<CodeTemplate>
|
llvm::Expected<CodeTemplate>
|
||||||
|
|
|
@ -130,7 +130,7 @@ UopsSnippetGenerator::generateCodeTemplate(unsigned Opcode) const {
|
||||||
CodeTemplate CT;
|
CodeTemplate CT;
|
||||||
|
|
||||||
const llvm::BitVector *ScratchSpaceAliasedRegs = nullptr;
|
const llvm::BitVector *ScratchSpaceAliasedRegs = nullptr;
|
||||||
const Instruction Instr(State.getInstrInfo().get(Opcode), RATC);
|
const Instruction Instr(State, Opcode);
|
||||||
if (Instr.hasMemoryOperands()) {
|
if (Instr.hasMemoryOperands()) {
|
||||||
CT.ScratchSpacePointerInReg =
|
CT.ScratchSpacePointerInReg =
|
||||||
ET.getScratchMemoryRegister(State.getTargetMachine().getTargetTriple());
|
ET.getScratchMemoryRegister(State.getTargetMachine().getTargetTriple());
|
||||||
|
@ -138,7 +138,7 @@ UopsSnippetGenerator::generateCodeTemplate(unsigned Opcode) const {
|
||||||
return llvm::make_error<BenchmarkFailure>(
|
return llvm::make_error<BenchmarkFailure>(
|
||||||
"Infeasible : target does not support memory instructions");
|
"Infeasible : target does not support memory instructions");
|
||||||
ScratchSpaceAliasedRegs =
|
ScratchSpaceAliasedRegs =
|
||||||
&RATC.getRegister(CT.ScratchSpacePointerInReg).aliasedBits();
|
&State.getRATC().getRegister(CT.ScratchSpacePointerInReg).aliasedBits();
|
||||||
// If the instruction implicitly writes to ScratchSpacePointerInReg , abort.
|
// If the instruction implicitly writes to ScratchSpacePointerInReg , abort.
|
||||||
// FIXME: We could make a copy of the scratch register.
|
// FIXME: We could make a copy of the scratch register.
|
||||||
for (const auto &Op : Instr.Operands) {
|
for (const auto &Op : Instr.Operands) {
|
||||||
|
@ -185,12 +185,13 @@ UopsSnippetGenerator::generateCodeTemplate(unsigned Opcode) const {
|
||||||
instantiateMemoryOperands(CT.ScratchSpacePointerInReg, CT.Instructions);
|
instantiateMemoryOperands(CT.ScratchSpacePointerInReg, CT.Instructions);
|
||||||
return std::move(CT);
|
return std::move(CT);
|
||||||
}
|
}
|
||||||
|
const auto &ReservedRegisters = State.getRATC().reservedRegisters();
|
||||||
// No tied variables, we pick random values for defs.
|
// No tied variables, we pick random values for defs.
|
||||||
llvm::BitVector Defs(State.getRegInfo().getNumRegs());
|
llvm::BitVector Defs(State.getRegInfo().getNumRegs());
|
||||||
for (const auto &Op : Instr.Operands) {
|
for (const auto &Op : Instr.Operands) {
|
||||||
if (Op.isReg() && Op.isExplicit() && Op.isDef() && !Op.isMemory()) {
|
if (Op.isReg() && Op.isExplicit() && Op.isDef() && !Op.isMemory()) {
|
||||||
auto PossibleRegisters = Op.getRegisterAliasing().sourceBits();
|
auto PossibleRegisters = Op.getRegisterAliasing().sourceBits();
|
||||||
remove(PossibleRegisters, RATC.reservedRegisters());
|
remove(PossibleRegisters, ReservedRegisters);
|
||||||
// Do not use the scratch memory address register.
|
// Do not use the scratch memory address register.
|
||||||
if (ScratchSpaceAliasedRegs)
|
if (ScratchSpaceAliasedRegs)
|
||||||
remove(PossibleRegisters, *ScratchSpaceAliasedRegs);
|
remove(PossibleRegisters, *ScratchSpaceAliasedRegs);
|
||||||
|
@ -205,7 +206,7 @@ UopsSnippetGenerator::generateCodeTemplate(unsigned Opcode) const {
|
||||||
for (const auto &Op : Instr.Operands) {
|
for (const auto &Op : Instr.Operands) {
|
||||||
if (Op.isReg() && Op.isExplicit() && Op.isUse() && !Op.isMemory()) {
|
if (Op.isReg() && Op.isExplicit() && Op.isUse() && !Op.isMemory()) {
|
||||||
auto PossibleRegisters = Op.getRegisterAliasing().sourceBits();
|
auto PossibleRegisters = Op.getRegisterAliasing().sourceBits();
|
||||||
remove(PossibleRegisters, RATC.reservedRegisters());
|
remove(PossibleRegisters, ReservedRegisters);
|
||||||
// Do not use the scratch memory address register.
|
// Do not use the scratch memory address register.
|
||||||
if (ScratchSpaceAliasedRegs)
|
if (ScratchSpaceAliasedRegs)
|
||||||
remove(PossibleRegisters, *ScratchSpaceAliasedRegs);
|
remove(PossibleRegisters, *ScratchSpaceAliasedRegs);
|
||||||
|
|
|
@ -37,9 +37,9 @@ template <typename Impl> class X86SnippetGenerator : public Impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle X87.
|
// Handle X87.
|
||||||
const auto &InstrDesc = InstrInfo.get(Opcode);
|
const unsigned FPInstClass =
|
||||||
const unsigned FPInstClass = InstrDesc.TSFlags & llvm::X86II::FPTypeMask;
|
InstrInfo.get(Opcode).TSFlags & llvm::X86II::FPTypeMask;
|
||||||
const Instruction Instr(InstrDesc, this->RATC);
|
const Instruction Instr(this->State, Opcode);
|
||||||
switch (FPInstClass) {
|
switch (FPInstClass) {
|
||||||
case llvm::X86II::NotFP:
|
case llvm::X86II::NotFP:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -248,7 +248,7 @@ public:
|
||||||
FakeSnippetGenerator(const LLVMState &State) : SnippetGenerator(State) {}
|
FakeSnippetGenerator(const LLVMState &State) : SnippetGenerator(State) {}
|
||||||
|
|
||||||
Instruction createInstruction(unsigned Opcode) {
|
Instruction createInstruction(unsigned Opcode) {
|
||||||
return Instruction(State.getInstrInfo().get(Opcode), RATC);
|
return Instruction(State, Opcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in New Issue