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
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);
llvm::Expected<CodeTemplate>
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<BenchmarkFailure>(
"Infeasible : has memory operands");
llvm::errs() << "no exegesis target for " << Triple << ", using default\n";
TheExegesisTarget = &ExegesisTarget::getDefault();
}
+ RATC.reset(new RegisterAliasingTrackerCache(
+ getRegInfo(), getFunctionReservedRegs(getTargetMachine())));
}
LLVMState::LLVMState()
#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"
const llvm::MCSubtargetInfo &getSubtargetInfo() const {
return *TargetMachine->getMCSubtargetInfo();
}
+ const RegisterAliasingTrackerCache &getRATC() const { return *RATC; }
private:
const ExegesisTarget *TheExegesisTarget;
std::unique_ptr<const llvm::TargetMachine> TargetMachine;
+ std::unique_ptr<const RegisterAliasingTrackerCache> RATC;
};
} // namespace exegesis
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;
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;
#include <random>
+#include "LlvmState.h"
#include "RegisterAliasing.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
// 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.
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;
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()
// 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<RegisterValue> RIV;
for (const InstructionTemplate &IT : Instructions) {
// Returns the register that this Operand sets or uses, or 0 if this is not
protected:
const LLVMState &State;
- const RegisterAliasingTrackerCache RATC;
// Generates a single code template that has a self-dependency.
llvm::Expected<CodeTemplate>
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());
return llvm::make_error<BenchmarkFailure>(
"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) {
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);
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);
}
// 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;
FakeSnippetGenerator(const LLVMState &State) : SnippetGenerator(State) {}
Instruction createInstruction(unsigned Opcode) {
- return Instruction(State.getInstrInfo().get(Opcode), RATC);
+ return Instruction(State, Opcode);
}
private: