[llvm] a5b5631 - [llvm-exegesis] `AliasingConfigurations`: pay attention to forbidden registers
Roman Lebedev via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 20 15:02:05 PST 2022
Author: Roman Lebedev
Date: 2022-12-21T02:01:14+03:00
New Revision: a5b56313dd8cf49a5128f93361a4bcc51b8a5485
URL: https://github.com/llvm/llvm-project/commit/a5b56313dd8cf49a5128f93361a4bcc51b8a5485
DIFF: https://github.com/llvm/llvm-project/commit/a5b56313dd8cf49a5128f93361a4bcc51b8a5485.diff
LOG: [llvm-exegesis] `AliasingConfigurations`: pay attention to forbidden registers
When trying to measure latency of certain opcodes, e.g.
`./bin/llvm-exegesis --opcode-name=BT32ri8 --mode=latency --repetition-mode=loop --benchmarks-file=- --max-configs-per-opcode=65536`,
we'd pick such an aliasing instruction, and such an aliasing registers,
that would alias with forbidden registers.
And in particular with loop counter in `loop` repetition mode,
which made the measurements never finish.
This does not address all such cases, only the most obvious one.
The added test case fails without the patch.
Fixes https://github.com/llvm/llvm-project/issues/59441
Added:
Modified:
llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp
llvm/tools/llvm-exegesis/lib/MCInstrDescView.h
llvm/tools/llvm-exegesis/lib/ParallelSnippetGenerator.cpp
llvm/tools/llvm-exegesis/lib/SerialSnippetGenerator.cpp
llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp
llvm/tools/llvm-exegesis/lib/SnippetGenerator.h
llvm/tools/llvm-exegesis/lib/X86/Target.cpp
llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp
Removed:
################################################################################
diff --git a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp
index 0ad664590957c..a1c3794fd6088 100644
--- a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp
+++ b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp
@@ -351,10 +351,12 @@ bool AliasingConfigurations::hasImplicitAliasing() const {
}
AliasingConfigurations::AliasingConfigurations(
- const Instruction &DefInstruction, const Instruction &UseInstruction) {
- if (UseInstruction.AllUseRegs.anyCommon(DefInstruction.AllDefRegs)) {
- auto CommonRegisters = UseInstruction.AllUseRegs;
- CommonRegisters &= DefInstruction.AllDefRegs;
+ const Instruction &DefInstruction, const Instruction &UseInstruction,
+ const BitVector &ForbiddenRegisters) {
+ auto CommonRegisters = UseInstruction.AllUseRegs;
+ CommonRegisters &= DefInstruction.AllDefRegs;
+ CommonRegisters.reset(ForbiddenRegisters);
+ if (!CommonRegisters.empty()) {
for (const MCPhysReg Reg : CommonRegisters.set_bits()) {
AliasingRegisterOperands ARO;
addOperandIfAlias(Reg, true, DefInstruction.Operands, ARO.Defs);
diff --git a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h
index 743543460e473..58c5317776c2e 100644
--- a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h
+++ b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h
@@ -217,7 +217,8 @@ struct AliasingRegisterOperands {
// to alias with Use registers of UseInstruction.
struct AliasingConfigurations {
AliasingConfigurations(const Instruction &DefInstruction,
- const Instruction &UseInstruction);
+ const Instruction &UseInstruction,
+ const BitVector &ForbiddenRegisters);
bool empty() const; // True if no aliasing configuration is found.
bool hasImplicitAliasing() const;
diff --git a/llvm/tools/llvm-exegesis/lib/ParallelSnippetGenerator.cpp b/llvm/tools/llvm-exegesis/lib/ParallelSnippetGenerator.cpp
index c2691fea6344d..114e274845e53 100644
--- a/llvm/tools/llvm-exegesis/lib/ParallelSnippetGenerator.cpp
+++ b/llvm/tools/llvm-exegesis/lib/ParallelSnippetGenerator.cpp
@@ -301,7 +301,7 @@ ParallelSnippetGenerator::generateCodeTemplates(
? State.getExegesisTarget().getScratchMemoryRegister(
State.getTargetMachine().getTargetTriple())
: 0;
- const AliasingConfigurations SelfAliasing(Instr, Instr);
+ const AliasingConfigurations SelfAliasing(Instr, Instr, ForbiddenRegisters);
if (SelfAliasing.empty()) {
CT.Info = "instruction is parallel, repeating a random one.";
CT.Instructions.push_back(std::move(Variant));
diff --git a/llvm/tools/llvm-exegesis/lib/SerialSnippetGenerator.cpp b/llvm/tools/llvm-exegesis/lib/SerialSnippetGenerator.cpp
index b07a44d2cdde5..07a009c09a047 100644
--- a/llvm/tools/llvm-exegesis/lib/SerialSnippetGenerator.cpp
+++ b/llvm/tools/llvm-exegesis/lib/SerialSnippetGenerator.cpp
@@ -115,8 +115,8 @@ 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(Variant.getInstr(),
- Variant.getInstr());
+ const AliasingConfigurations SelfAliasing(
+ Variant.getInstr(), Variant.getInstr(), ForbiddenRegisters);
assert(!SelfAliasing.empty() && !SelfAliasing.hasImplicitAliasing() &&
"Instr must alias itself explicitly");
// This is a self aliasing instruction so defs and uses are from the same
@@ -134,8 +134,9 @@ static void appendCodeTemplates(const LLVMState &State,
// Select back-to-back non-memory instruction.
for (const auto *OtherInstr : computeAliasingInstructions(
State, &Instr, kMaxAliasingInstructions, ForbiddenRegisters)) {
- const AliasingConfigurations Forward(Instr, *OtherInstr);
- const AliasingConfigurations Back(*OtherInstr, Instr);
+ const AliasingConfigurations Forward(Instr, *OtherInstr,
+ ForbiddenRegisters);
+ const AliasingConfigurations Back(*OtherInstr, Instr, ForbiddenRegisters);
InstructionTemplate ThisIT(Variant);
InstructionTemplate OtherIT(OtherInstr);
if (!Forward.hasImplicitAliasing())
diff --git a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp
index 15c2c60e73152..b80abf73cf47b 100644
--- a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp
+++ b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp
@@ -140,9 +140,10 @@ std::vector<RegisterValue> SnippetGenerator::computeRegisterInitialValues(
}
Expected<std::vector<CodeTemplate>>
-generateSelfAliasingCodeTemplates(InstructionTemplate Variant) {
- const AliasingConfigurations SelfAliasing(Variant.getInstr(),
- Variant.getInstr());
+generateSelfAliasingCodeTemplates(InstructionTemplate Variant,
+ const BitVector &ForbiddenRegisters) {
+ const AliasingConfigurations SelfAliasing(
+ Variant.getInstr(), Variant.getInstr(), ForbiddenRegisters);
if (SelfAliasing.empty())
return make_error<SnippetGeneratorFailure>("empty self aliasing");
std::vector<CodeTemplate> Result;
diff --git a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.h b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.h
index 0c2b61758c31e..9c64d460e685c 100644
--- a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.h
+++ b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.h
@@ -35,7 +35,8 @@ std::vector<CodeTemplate> getSingleton(CodeTemplate &&CT);
// Generates code templates that has a self-dependency.
Expected<std::vector<CodeTemplate>>
-generateSelfAliasingCodeTemplates(InstructionTemplate Variant);
+generateSelfAliasingCodeTemplates(InstructionTemplate Variant,
+ const BitVector &ForbiddenRegisters);
// Generates code templates without assignment constraints.
Expected<std::vector<CodeTemplate>>
diff --git a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
index 2fda99cee7c69..b14857405504d 100644
--- a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
@@ -370,7 +370,7 @@ X86SerialSnippetGenerator::generateCodeTemplates(
// - `ST(0) = fsqrt(ST(0))` (OneArgFPRW)
// - `ST(0) = ST(0) + ST(i)` (TwoArgFP)
// They are intrinsically serial and do not modify the state of the stack.
- return generateSelfAliasingCodeTemplates(Variant);
+ return generateSelfAliasingCodeTemplates(Variant, ForbiddenRegisters);
default:
llvm_unreachable("Unknown FP Type!");
}
@@ -426,7 +426,7 @@ X86ParallelSnippetGenerator::generateCodeTemplates(
// - `ST(0) = ST(0) + ST(i)` (TwoArgFP)
// They are intrinsically serial and do not modify the state of the stack.
// We generate the same code for latency and uops.
- return generateSelfAliasingCodeTemplates(Variant);
+ return generateSelfAliasingCodeTemplates(Variant, ForbiddenRegisters);
case X86II::CompareFP:
case X86II::CondMovFP:
// We can compute uops for any FP instruction that does not grow or shrink
diff --git a/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp b/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp
index 3200ec50d2d5b..2864d3ffe154c 100644
--- a/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp
+++ b/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp
@@ -157,6 +157,39 @@ TEST_F(X86SerialSnippetGeneratorTest,
consumeError(std::move(Error));
}
+TEST_F(X86SerialSnippetGeneratorTest,
+ ImplicitSelfDependencyThroughExplicitRegsForbidAlmostAll) {
+ // - VXORPSrr
+ // - Op0 Explicit Def RegClass(VR128)
+ // - Op1 Explicit Use RegClass(VR128)
+ // - Op2 Explicit Use RegClass(VR128)
+ // - Var0 [Op0]
+ // - Var1 [Op1]
+ // - Var2 [Op2]
+ // - hasAliasingRegisters
+ const unsigned Opcode = X86::VXORPSrr;
+ randomGenerator().seed(0); // Initialize seed.
+ const Instruction &Instr = State.getIC().getInstr(Opcode);
+ auto ForbiddenRegisters = State.getRATC().emptyRegisters();
+ ForbiddenRegisters.flip();
+ ForbiddenRegisters.reset(X86::XMM0);
+ auto Error = Generator.generateCodeTemplates(&Instr, ForbiddenRegisters);
+ EXPECT_FALSE((bool)Error.takeError());
+ auto CodeTemplates = std::move(Error.get());
+ ASSERT_THAT(CodeTemplates, SizeIs(Gt(0U))) << "Templates are available";
+ for (const auto &CT : CodeTemplates) {
+ EXPECT_THAT(CT.Execution, ExecutionMode::SERIAL_VIA_EXPLICIT_REGS);
+ ASSERT_THAT(CT.Instructions, SizeIs(1));
+ const InstructionTemplate &IT = CT.Instructions[0];
+ EXPECT_THAT(IT.getOpcode(), Opcode);
+ ASSERT_THAT(IT.getVariableValues(), SizeIs(3));
+ for (const auto &Var : IT.getVariableValues()) {
+ if (Var.isReg())
+ EXPECT_FALSE(ForbiddenRegisters[Var.getReg()]);
+ }
+ }
+}
+
TEST_F(X86SerialSnippetGeneratorTest, DependencyThroughOtherOpcode) {
// - CMP64rr
// - Op0 Explicit Use RegClass(GR64)
More information about the llvm-commits
mailing list