[llvm-exegesis] Refactor how forbidden registers are computed.
Summary:
Right now latency generation can incorrectly select the scratch register
as a dependency-carrying register.
- Move the logic for preventing register selection from Uops
implementation to common SnippetGenerator class.
- Aliasing detection now takes a set of forbidden registers just like
random register assignment does.
Reviewers: gchatelet
Subscribers: tschuett, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D68084
llvm-svn: 373048
diff --git a/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp b/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp
index 8b110f8..1c225bb 100644
--- a/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp
+++ b/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp
@@ -61,7 +61,8 @@
std::vector<CodeTemplate> checkAndGetCodeTemplates(unsigned Opcode) {
randomGenerator().seed(0); // Initialize seed.
const Instruction &Instr = State.getIC().getInstr(Opcode);
- auto CodeTemplateOrError = Generator.generateCodeTemplates(Instr);
+ auto CodeTemplateOrError = Generator.generateCodeTemplates(
+ Instr, State.getRATC().emptyRegisters());
EXPECT_FALSE(CodeTemplateOrError.takeError()); // Valid configuration.
return std::move(CodeTemplateOrError.get());
}
@@ -148,6 +149,26 @@
<< "Op0 is either set to Op1 or to Op2";
}
+TEST_F(LatencySnippetGeneratorTest,
+ ImplicitSelfDependencyThroughExplicitRegsForbidAll) {
+ // - 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 = llvm::X86::VXORPSrr;
+ randomGenerator().seed(0); // Initialize seed.
+ const Instruction &Instr = State.getIC().getInstr(Opcode);
+ auto AllRegisters = State.getRATC().emptyRegisters();
+ AllRegisters.flip();
+ auto Error = Generator.generateCodeTemplates(Instr, AllRegisters).takeError();
+ EXPECT_TRUE((bool)Error);
+ llvm::consumeError(std::move(Error));
+}
+
TEST_F(LatencySnippetGeneratorTest, DependencyThroughOtherOpcode) {
// - CMP64rr
// - Op0 Explicit Use RegClass(GR64)
@@ -323,7 +344,31 @@
EXPECT_EQ(IT.VariableValues[5].getReg(), 0u);
}
-TEST_F(UopsSnippetGeneratorTest, MemoryUse_Movsb) {
+class FakeSnippetGenerator : public SnippetGenerator {
+public:
+ FakeSnippetGenerator(const LLVMState &State) : SnippetGenerator(State) {}
+
+ Instruction createInstruction(unsigned Opcode) {
+ return State.getIC().getInstr(Opcode);
+ }
+
+private:
+ llvm::Expected<std::vector<CodeTemplate>>
+ generateCodeTemplates(const Instruction &, const BitVector &) const override {
+ return llvm::make_error<llvm::StringError>("not implemented",
+ llvm::inconvertibleErrorCode());
+ }
+};
+
+using FakeSnippetGeneratorTest = SnippetGeneratorTest<FakeSnippetGenerator>;
+
+testing::Matcher<const RegisterValue &> IsRegisterValue(unsigned Reg,
+ llvm::APInt Value) {
+ return testing::AllOf(testing::Field(&RegisterValue::Register, Reg),
+ testing::Field(&RegisterValue::Value, Value));
+}
+
+TEST_F(FakeSnippetGeneratorTest, MemoryUse_Movsb) {
// MOVSB writes to scratch memory register.
// - MOVSB
// - Op0 Explicit Use Memory RegClass(GR8)
@@ -342,35 +387,11 @@
// - hasAliasingRegisters
const unsigned Opcode = llvm::X86::MOVSB;
const Instruction &Instr = State.getIC().getInstr(Opcode);
- auto Error = Generator.generateCodeTemplates(Instr).takeError();
+ auto Error = Generator.generateConfigurations(Instr).takeError();
EXPECT_TRUE((bool)Error);
llvm::consumeError(std::move(Error));
}
-class FakeSnippetGenerator : public SnippetGenerator {
-public:
- FakeSnippetGenerator(const LLVMState &State) : SnippetGenerator(State) {}
-
- Instruction createInstruction(unsigned Opcode) {
- return State.getIC().getInstr(Opcode);
- }
-
-private:
- llvm::Expected<std::vector<CodeTemplate>>
- generateCodeTemplates(const Instruction &Instr) const override {
- return llvm::make_error<llvm::StringError>("not implemented",
- llvm::inconvertibleErrorCode());
- }
-};
-
-using FakeSnippetGeneratorTest = SnippetGeneratorTest<FakeSnippetGenerator>;
-
-testing::Matcher<const RegisterValue &> IsRegisterValue(unsigned Reg,
- llvm::APInt Value) {
- return testing::AllOf(testing::Field(&RegisterValue::Register, Reg),
- testing::Field(&RegisterValue::Value, Value));
-}
-
TEST_F(FakeSnippetGeneratorTest, ComputeRegisterInitialValuesAdd16ri) {
// ADD16ri:
// explicit def 0 : reg RegClass=GR16