Skip to content

[llvm-exegesis] Begin replacing unsigned with MCRegister. NFC #123109

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ static unsigned getLoadImmediateOpcode(unsigned RegBitWidth) {
}

// Generates instruction to load an immediate value into a register.
static MCInst loadImmediate(unsigned Reg, unsigned RegBitWidth,
static MCInst loadImmediate(MCRegister Reg, unsigned RegBitWidth,
const APInt &Value) {
if (Value.getBitWidth() > RegBitWidth)
llvm_unreachable("Value must fit in the Register");
Expand All @@ -45,7 +45,7 @@ class ExegesisAArch64Target : public ExegesisTarget {
: ExegesisTarget(AArch64CpuPfmCounters, AArch64_MC::isOpcodeAvailable) {}

private:
std::vector<MCInst> setRegTo(const MCSubtargetInfo &STI, unsigned Reg,
std::vector<MCInst> setRegTo(const MCSubtargetInfo &STI, MCRegister Reg,
const APInt &Value) const override {
if (AArch64::GPR32RegClass.contains(Reg))
return {loadImmediate(Reg, 32, Value)};
Expand Down
24 changes: 12 additions & 12 deletions llvm/tools/llvm-exegesis/lib/Assembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ static bool generateSnippetSetupCode(const ExegesisTarget &ET,
// If we're generating memory instructions, don't load in the value for
// the register with the stack pointer as it will be used later to finish
// the setup.
if (RV.Register == StackPointerRegister)
if (Register(RV.Register) == StackPointerRegister)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the underlying type should probably be updated in RegisterValue.h rather than casting here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I wasn't super happy about this. StackPointer is probably always a physical register, but the interface it comes from uses Register. All the registers going into RegisterValue are all physical registers, so I wasn't sure about using Register there just to make these 2 compares compile.

In the long run maybe Register and MCRegister should be comparable by operator==.

continue;
}
// Load a constant in the register.
Expand All @@ -98,7 +98,7 @@ static bool generateSnippetSetupCode(const ExegesisTarget &ET,
// Load in the stack register now as we're done using it elsewhere
// and need to set the value in preparation for executing the
// snippet.
if (RV.Register != StackPointerRegister)
if (Register(RV.Register) != StackPointerRegister)
continue;
const auto SetRegisterCode = ET.setRegTo(*MSI, RV.Register, RV.Value);
if (SetRegisterCode.empty())
Expand Down Expand Up @@ -208,7 +208,7 @@ void BasicBlockFiller::addReturn(const ExegesisTarget &ET,
}

FunctionFiller::FunctionFiller(MachineFunction &MF,
std::vector<unsigned> RegistersSetUp)
std::vector<MCRegister> RegistersSetUp)
: MF(MF), MCII(MF.getTarget().getMCInstrInfo()), Entry(addBasicBlock()),
RegistersSetUp(std::move(RegistersSetUp)) {}

Expand All @@ -218,7 +218,7 @@ BasicBlockFiller FunctionFiller::addBasicBlock() {
return BasicBlockFiller(MF, MBB, MCII);
}

ArrayRef<unsigned> FunctionFiller::getRegistersSetUp() const {
ArrayRef<MCRegister> FunctionFiller::getRegistersSetUp() const {
return RegistersSetUp;
}

Expand All @@ -241,7 +241,7 @@ BitVector getFunctionReservedRegs(const TargetMachine &TM) {

Error assembleToStream(const ExegesisTarget &ET,
std::unique_ptr<TargetMachine> TM,
ArrayRef<unsigned> LiveIns, const FillFunction &Fill,
ArrayRef<MCRegister> LiveIns, const FillFunction &Fill,
raw_pwrite_stream &AsmStream, const BenchmarkKey &Key,
bool GenerateMemoryInstructions) {
auto Context = std::make_unique<LLVMContext>();
Expand All @@ -259,35 +259,35 @@ Error assembleToStream(const ExegesisTarget &ET,
Properties.reset(MachineFunctionProperties::Property::IsSSA);
Properties.set(MachineFunctionProperties::Property::NoPHIs);

for (const unsigned Reg : LiveIns)
for (const MCRegister Reg : LiveIns)
MF.getRegInfo().addLiveIn(Reg);

if (GenerateMemoryInstructions) {
for (const unsigned Reg : ET.getArgumentRegisters())
for (const MCRegister Reg : ET.getArgumentRegisters())
MF.getRegInfo().addLiveIn(Reg);
// Add a live in for registers that need saving so that the machine verifier
// doesn't fail if the register is never defined.
for (const unsigned Reg : ET.getRegistersNeedSaving())
for (const MCRegister Reg : ET.getRegistersNeedSaving())
MF.getRegInfo().addLiveIn(Reg);
}

std::vector<unsigned> RegistersSetUp;
std::vector<MCRegister> RegistersSetUp;
RegistersSetUp.reserve(Key.RegisterInitialValues.size());
for (const auto &InitValue : Key.RegisterInitialValues) {
RegistersSetUp.push_back(InitValue.Register);
}
FunctionFiller Sink(MF, std::move(RegistersSetUp));
auto Entry = Sink.getEntry();

for (const unsigned Reg : LiveIns)
for (const MCRegister Reg : LiveIns)
Entry.MBB->addLiveIn(Reg);

if (GenerateMemoryInstructions) {
for (const unsigned Reg : ET.getArgumentRegisters())
for (const MCRegister Reg : ET.getArgumentRegisters())
Entry.MBB->addLiveIn(Reg);
// Add a live in for registers that need saving so that the machine verifier
// doesn't fail if the register is never defined.
for (const unsigned Reg : ET.getRegistersNeedSaving())
for (const MCRegister Reg : ET.getRegistersNeedSaving())
Entry.MBB->addLiveIn(Reg);
}

Expand Down
8 changes: 4 additions & 4 deletions llvm/tools/llvm-exegesis/lib/Assembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class BasicBlockFiller {
// Helper to fill in a function.
class FunctionFiller {
public:
FunctionFiller(MachineFunction &MF, std::vector<unsigned> RegistersSetUp);
FunctionFiller(MachineFunction &MF, std::vector<MCRegister> RegistersSetUp);

// Adds a basic block to the function.
BasicBlockFiller addBasicBlock();
Expand All @@ -73,12 +73,12 @@ class FunctionFiller {
const MCInstrInfo *const MCII;

// Returns the set of registers in the snippet setup code.
ArrayRef<unsigned> getRegistersSetUp() const;
ArrayRef<MCRegister> getRegistersSetUp() const;

private:
BasicBlockFiller Entry;
// The set of registers that are set up in the basic block.
std::vector<unsigned> RegistersSetUp;
std::vector<MCRegister> RegistersSetUp;
};

// A callback that fills a function.
Expand All @@ -90,7 +90,7 @@ using FillFunction = std::function<void(FunctionFiller &)>;
// AsmStream, the temporary function is eventually discarded.
Error assembleToStream(const ExegesisTarget &ET,
std::unique_ptr<TargetMachine> TM,
ArrayRef<unsigned> LiveIns, const FillFunction &Fill,
ArrayRef<MCRegister> LiveIns, const FillFunction &Fill,
raw_pwrite_stream &AsmStreamm, const BenchmarkKey &Key,
bool GenerateMemoryInstructions);

Expand Down
2 changes: 1 addition & 1 deletion llvm/tools/llvm-exegesis/lib/BenchmarkCode.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ struct BenchmarkCode {

// We also need to provide the registers that are live on entry for the
// assembler to generate proper prologue/epilogue.
std::vector<unsigned> LiveIns;
std::vector<MCRegister> LiveIns;

// Informations about how this configuration was built.
std::string Info;
Expand Down
14 changes: 7 additions & 7 deletions llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,17 @@ struct YamlContext {

raw_string_ostream &getErrorStream() { return ErrorStream; }

StringRef getRegName(unsigned RegNo) {
// Special case: RegNo 0 is NoRegister. We have to deal with it explicitly.
if (RegNo == 0)
StringRef getRegName(MCRegister Reg) {
// Special case: Reg may be invalid. We have to deal with it explicitly.
if (!Reg.isValid())
return kNoRegister;
const StringRef RegName = State->getRegInfo().getName(RegNo);
const StringRef RegName = State->getRegInfo().getName(Reg);
if (RegName.empty())
ErrorStream << "No register with enum value '" << RegNo << "'\n";
ErrorStream << "No register with enum value '" << Reg.id() << "'\n";
return RegName;
}

std::optional<unsigned> getRegNo(StringRef RegName) {
std::optional<MCRegister> getRegNo(StringRef RegName) {
std::optional<MCRegister> RegisterNumber =
State->getRegisterNumberFromName(RegName);
if (!RegisterNumber.has_value())
Expand Down Expand Up @@ -261,7 +261,7 @@ template <> struct ScalarTraits<exegesis::RegisterValue> {
String.split(Pieces, "=0x", /* MaxSplit */ -1,
/* KeepEmpty */ false);
YamlContext &Context = getTypedContext(Ctx);
std::optional<unsigned> RegNo;
std::optional<MCRegister> RegNo;
if (Pieces.size() == 2 && (RegNo = Context.getRegNo(Pieces[0]))) {
RV.Register = *RegNo;
const unsigned BitsNeeded = APInt::getBitsNeeded(Pieces[1], kRadix);
Expand Down
2 changes: 1 addition & 1 deletion llvm/tools/llvm-exegesis/lib/BenchmarkResult.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ struct BenchmarkKey {
// being used supports it.
uintptr_t SnippetAddress = 0;
// The register that should be used to hold the loop counter.
unsigned LoopRegister;
MCRegister LoopRegister;
};

struct BenchmarkMeasure {
Expand Down
2 changes: 1 addition & 1 deletion llvm/tools/llvm-exegesis/lib/CodeTemplate.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ struct CodeTemplate {
std::vector<InstructionTemplate> Instructions;
// If the template uses the provided scratch memory, the register in which
// the pointer to this memory is passed in to the function.
unsigned ScratchSpacePointerInReg = 0;
MCRegister ScratchSpacePointerInReg;

#if defined(__GNUC__) && (defined(__clang__) || LLVM_GNUC_PREREQ(8, 0, 0))
// FIXME: GCC7 bug workaround. Drop #if after GCC7 no longer supported.
Expand Down
2 changes: 1 addition & 1 deletion llvm/tools/llvm-exegesis/lib/LlvmState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ LLVMState::LLVMState(std::unique_ptr<const TargetMachine> TM,
OpcodeNameToOpcodeIdxMapping(createOpcodeNameToOpcodeIdxMapping()),
RegNameToRegNoMapping(createRegNameToRegNoMapping()) {
BitVector ReservedRegs = getFunctionReservedRegs(getTargetMachine());
for (const unsigned Reg : TheExegesisTarget->getUnavailableRegisters())
for (const MCPhysReg Reg : TheExegesisTarget->getUnavailableRegisters())
ReservedRegs.set(Reg);
RATC.reset(
new RegisterAliasingTrackerCache(getRegInfo(), std::move(ReservedRegs)));
Expand Down
4 changes: 2 additions & 2 deletions llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ bool Operand::isExplicit() const { return Info; }

bool Operand::isImplicit() const { return !Info; }

bool Operand::isImplicitReg() const { return ImplicitReg; }
bool Operand::isImplicitReg() const { return ImplicitReg.isValid(); }

bool Operand::isDef() const { return IsDef; }

Expand All @@ -64,7 +64,7 @@ unsigned Operand::getTiedToIndex() const { return *TiedToIndex; }

unsigned Operand::getVariableIndex() const { return *VariableIndex; }

unsigned Operand::getImplicitReg() const {
MCRegister Operand::getImplicitReg() const {
assert(ImplicitReg);
return ImplicitReg;
}
Expand Down
4 changes: 2 additions & 2 deletions llvm/tools/llvm-exegesis/lib/MCInstrDescView.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ struct Operand {
unsigned getIndex() const;
unsigned getTiedToIndex() const;
unsigned getVariableIndex() const;
unsigned getImplicitReg() const;
MCRegister getImplicitReg() const;
const RegisterAliasingTracker &getRegisterAliasing() const;
const MCOperandInfo &getExplicitOperandInfo() const;

Expand All @@ -85,7 +85,7 @@ struct Operand {
const RegisterAliasingTracker *Tracker = nullptr; // Set for Register Op.
const MCOperandInfo *Info = nullptr; // Set for Explicit Op.
std::optional<uint8_t> TiedToIndex; // Set for Reg&Explicit Op.
MCPhysReg ImplicitReg = 0; // Non-0 for Implicit Op.
MCRegister ImplicitReg; // Non-0 for Implicit Op.
std::optional<uint8_t> VariableIndex; // Set for Explicit Op.
};

Expand Down
15 changes: 8 additions & 7 deletions llvm/tools/llvm-exegesis/lib/Mips/Target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ class ExegesisMipsTarget : public ExegesisTarget {
: ExegesisTarget(MipsCpuPfmCounters, Mips_MC::isOpcodeAvailable) {}

private:
unsigned getScratchMemoryRegister(const Triple &TT) const override;
MCRegister getScratchMemoryRegister(const Triple &TT) const override;
unsigned getMaxMemoryAccessSize() const override { return 64; }
void fillMemoryOperands(InstructionTemplate &IT, unsigned Reg,
void fillMemoryOperands(InstructionTemplate &IT, MCRegister Reg,
unsigned Offset) const override;

std::vector<MCInst> setRegTo(const MCSubtargetInfo &STI, unsigned Reg,
std::vector<MCInst> setRegTo(const MCSubtargetInfo &STI, MCRegister Reg,
const APInt &Value) const override;
bool matchesArch(Triple::ArchType Arch) const override {
return Arch == Triple::mips || Arch == Triple::mipsel ||
Expand All @@ -73,7 +73,7 @@ class ExegesisMipsTarget : public ExegesisTarget {
} // end anonymous namespace

// Generates instructions to load an immediate value into a register.
static std::vector<MCInst> loadImmediate(unsigned Reg, bool IsGPR32,
static std::vector<MCInst> loadImmediate(MCRegister Reg, bool IsGPR32,
const APInt &Value) {
unsigned ZeroReg;
unsigned ORi, LUi, SLL;
Expand Down Expand Up @@ -134,12 +134,13 @@ static std::vector<MCInst> loadImmediate(unsigned Reg, bool IsGPR32,
llvm_unreachable("Not implemented for values wider than 32 bits");
}

unsigned ExegesisMipsTarget::getScratchMemoryRegister(const Triple &TT) const {
MCRegister
ExegesisMipsTarget::getScratchMemoryRegister(const Triple &TT) const {
return TT.isArch64Bit() ? Mips::A0_64 : Mips::A0;
}

void ExegesisMipsTarget::fillMemoryOperands(InstructionTemplate &IT,
unsigned Reg,
MCRegister Reg,
unsigned Offset) const {
assert(!isInvalidMemoryInstr(IT.getInstr()) &&
"fillMemoryOperands requires a valid memory instruction");
Expand All @@ -149,7 +150,7 @@ void ExegesisMipsTarget::fillMemoryOperands(InstructionTemplate &IT,
}

std::vector<MCInst> ExegesisMipsTarget::setRegTo(const MCSubtargetInfo &STI,
unsigned Reg,
MCRegister Reg,
const APInt &Value) const {
if (Mips::GPR32RegClass.contains(Reg))
return loadImmediate(Reg, true, Value);
Expand Down
10 changes: 5 additions & 5 deletions llvm/tools/llvm-exegesis/lib/ParallelSnippetGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,9 @@ static bool hasVariablesWithTiedOperands(const Instruction &Instr) {
ParallelSnippetGenerator::~ParallelSnippetGenerator() = default;

void ParallelSnippetGenerator::instantiateMemoryOperands(
const unsigned ScratchSpacePointerInReg,
const MCRegister ScratchSpacePointerInReg,
std::vector<InstructionTemplate> &Instructions) const {
if (ScratchSpacePointerInReg == 0)
if (!ScratchSpacePointerInReg)
return; // no memory operands.
const auto &ET = State.getExegesisTarget();
const unsigned MemStep = ET.getMaxMemoryAccessSize();
Expand Down Expand Up @@ -261,10 +261,10 @@ generateSnippetForInstrAvoidingDefUseOverlap(
if (Op.isReg() && Op.isImplicit() && !Op.isMemory()) {
assert(Op.isImplicitReg() && "Not an implicit register operand?");
if (Op.isUse())
ImplicitUses.set(Op.getImplicitReg());
ImplicitUses.set(Op.getImplicitReg().id());
else {
assert(Op.isDef() && "Not a use and not a def?");
ImplicitDefs.set(Op.getImplicitReg());
ImplicitDefs.set(Op.getImplicitReg().id());
}
}
}
Expand Down Expand Up @@ -300,7 +300,7 @@ ParallelSnippetGenerator::generateCodeTemplates(
Instr.hasMemoryOperands()
? State.getExegesisTarget().getScratchMemoryRegister(
State.getTargetMachine().getTargetTriple())
: 0;
: MCRegister();
const AliasingConfigurations SelfAliasing(Instr, Instr, ForbiddenRegisters);
if (SelfAliasing.empty()) {
CT.Info = "instruction is parallel, repeating a random one.";
Expand Down
2 changes: 1 addition & 1 deletion llvm/tools/llvm-exegesis/lib/ParallelSnippetGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class ParallelSnippetGenerator : public SnippetGenerator {
// add eax, [rdi + 192]
// mov eax, [rdi + 256]
void instantiateMemoryOperands(
unsigned ScratchSpaceReg,
MCRegister ScratchSpaceReg,
std::vector<InstructionTemplate> &SnippetTemplate) const;
};

Expand Down
14 changes: 7 additions & 7 deletions llvm/tools/llvm-exegesis/lib/PowerPC/Target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ class ExegesisPowerPCTarget : public ExegesisTarget {
: ExegesisTarget(PPCCpuPfmCounters, PPC_MC::isOpcodeAvailable) {}

private:
std::vector<MCInst> setRegTo(const MCSubtargetInfo &STI, unsigned Reg,
std::vector<MCInst> setRegTo(const MCSubtargetInfo &STI, MCRegister Reg,
const APInt &Value) const override;
bool matchesArch(Triple::ArchType Arch) const override {
return Arch == Triple::ppc64le;
}
unsigned getScratchMemoryRegister(const Triple &) const override;
void fillMemoryOperands(InstructionTemplate &IT, unsigned Reg,
MCRegister getScratchMemoryRegister(const Triple &) const override;
void fillMemoryOperands(InstructionTemplate &IT, MCRegister Reg,
unsigned Offset) const override;
};
} // end anonymous namespace
Expand All @@ -55,7 +55,7 @@ static unsigned getLoadImmediateOpcode(unsigned RegBitWidth) {
}

// Generates instruction to load an immediate value into a register.
static MCInst loadImmediate(unsigned Reg, unsigned RegBitWidth,
static MCInst loadImmediate(MCRegister Reg, unsigned RegBitWidth,
const APInt &Value) {
if (Value.getBitWidth() > RegBitWidth)
llvm_unreachable("Value must fit in the Register");
Expand All @@ -67,15 +67,15 @@ static MCInst loadImmediate(unsigned Reg, unsigned RegBitWidth,
.addImm(Value.getZExtValue());
}

unsigned
MCRegister
ExegesisPowerPCTarget::getScratchMemoryRegister(const Triple &TT) const {
// R13 is reserved as Thread Pointer, we won't use threading in benchmark, so
// use it as scratch memory register
return TT.isArch64Bit() ? PPC::X13 : PPC::R13;
}

void ExegesisPowerPCTarget::fillMemoryOperands(InstructionTemplate &IT,
unsigned Reg,
MCRegister Reg,
unsigned Offset) const {
int MemOpIdx = 0;
if (IT.getInstr().hasTiedRegisters())
Expand All @@ -93,7 +93,7 @@ void ExegesisPowerPCTarget::fillMemoryOperands(InstructionTemplate &IT,
}

std::vector<MCInst> ExegesisPowerPCTarget::setRegTo(const MCSubtargetInfo &STI,
unsigned Reg,
MCRegister Reg,
const APInt &Value) const {
// X11 is optional use in function linkage, should be the least used one
// Use it as scratch reg to load immediate.
Expand Down
Loading
Loading