From: Clement Courbet Date: Tue, 26 Mar 2019 15:44:57 +0000 (+0000) Subject: [llvm-exegesis] Allow the target to disable the selection of some registers. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2626e5e9d3613f8cb65787659a98876860bb7fb6;p=llvm [llvm-exegesis] Allow the target to disable the selection of some registers. Summary: This prevents "Cannot encode high byte register in REX-prefixed instruction" from happening on instructions that require REX encoding when AH & co get selected. On the down side, these 4 registers can no longer be selected automatically, but this avoids having to expose all the X86 encoding complexity. Reviewers: gchatelet Subscribers: tschuett, jdoerfert, llvm-commits, bdb Tags: #llvm Differential Revision: https://reviews.llvm.org/D59821 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@357003 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/tools/llvm-exegesis/X86/latency-SBB8rr.s b/test/tools/llvm-exegesis/X86/latency-SBB8rr.s new file mode 100644 index 00000000000..d98d547cbd3 --- /dev/null +++ b/test/tools/llvm-exegesis/X86/latency-SBB8rr.s @@ -0,0 +1,11 @@ +# RUN: llvm-exegesis -mode=latency -opcode-name=SBB8rr | FileCheck %s + +CHECK: --- +CHECK-NEXT: mode: latency +CHECK-NEXT: key: +CHECK-NEXT: instructions: +CHECK-NEXT: SBB8rr +CHECK-NEXT: config: '' +CHECK-NEXT: register_initial_values: +CHECK-DAG: - '[[REG1:[A-Z0-9]+]]=0x0' +CHECK-LAST: ... diff --git a/tools/llvm-exegesis/lib/LlvmState.cpp b/tools/llvm-exegesis/lib/LlvmState.cpp index ab487fd3897..059e8cb8c60 100644 --- a/tools/llvm-exegesis/lib/LlvmState.cpp +++ b/tools/llvm-exegesis/lib/LlvmState.cpp @@ -38,8 +38,11 @@ LLVMState::LLVMState(const std::string &Triple, const std::string &CpuName, } PfmCounters = &TheExegesisTarget->getPfmCounters(CpuName); - RATC.reset(new RegisterAliasingTrackerCache( - getRegInfo(), getFunctionReservedRegs(getTargetMachine()))); + BitVector ReservedRegs = getFunctionReservedRegs(getTargetMachine()); + for (const unsigned Reg : TheExegesisTarget->getUnavailableRegisters()) + ReservedRegs.set(Reg); + RATC.reset( + new RegisterAliasingTrackerCache(getRegInfo(), std::move(ReservedRegs))); IC.reset(new InstructionsCache(getInstrInfo(), getRATC())); } diff --git a/tools/llvm-exegesis/lib/Target.h b/tools/llvm-exegesis/lib/Target.h index f3429b79a34..ab760bfa820 100644 --- a/tools/llvm-exegesis/lib/Target.h +++ b/tools/llvm-exegesis/lib/Target.h @@ -90,6 +90,11 @@ public: "fillMemoryOperands() requires getScratchMemoryRegister() > 0"); } + // Returns a list of unavailable registers. + // Targets can use this to prevent some registers to be automatically selected + // for use in snippets. + virtual ArrayRef getUnavailableRegisters() const { return {}; } + // Returns the maximum number of bytes a load/store instruction can access at // once. This is typically the size of the largest register available on the // processor. Note that this only used as a hint to generate independant diff --git a/tools/llvm-exegesis/lib/X86/Target.cpp b/tools/llvm-exegesis/lib/X86/Target.cpp index 2d705c9d18a..369ed2f97d7 100644 --- a/tools/llvm-exegesis/lib/X86/Target.cpp +++ b/tools/llvm-exegesis/lib/X86/Target.cpp @@ -435,6 +435,12 @@ private: unsigned Reg, const llvm::APInt &Value) const override; + ArrayRef getUnavailableRegisters() const override { + return makeArrayRef(kUnavailableRegisters, + sizeof(kUnavailableRegisters) / + sizeof(kUnavailableRegisters[0])); + } + std::unique_ptr createLatencySnippetGenerator(const LLVMState &State) const override { return llvm::make_unique(State); @@ -448,7 +454,14 @@ private: bool matchesArch(llvm::Triple::ArchType Arch) const override { return Arch == llvm::Triple::x86_64 || Arch == llvm::Triple::x86; } + + static const unsigned kUnavailableRegisters[4]; }; + +// We disable a few registers that cannot be encoded on instructions with a REX +// prefix. +const unsigned ExegesisX86Target::kUnavailableRegisters[4] = {X86::AH, X86::BH, + X86::CH, X86::DH}; } // namespace void ExegesisX86Target::addTargetSpecificPasses( diff --git a/unittests/tools/llvm-exegesis/X86/TargetTest.cpp b/unittests/tools/llvm-exegesis/X86/TargetTest.cpp index 15a1d8381fd..344ec6027d2 100644 --- a/unittests/tools/llvm-exegesis/X86/TargetTest.cpp +++ b/unittests/tools/llvm-exegesis/X86/TargetTest.cpp @@ -144,6 +144,10 @@ public: Core2Avx512TargetTest() : X86TargetTest("+avx512vl") {} }; +TEST_F(Core2TargetTest, NoHighByteRegs) { + EXPECT_TRUE(State.getRATC().reservedRegisters().test(X86::AH)); +} + TEST_F(Core2TargetTest, SetFlags) { const unsigned Reg = llvm::X86::EFLAGS; EXPECT_THAT(