diff options
author | Clement Courbet <courbet@google.com> | 2019-03-26 15:44:57 +0000 |
---|---|---|
committer | Clement Courbet <courbet@google.com> | 2019-03-26 15:44:57 +0000 |
commit | 52da938cd0e12a2e4ace751732b0ef7c6f9d3235 (patch) | |
tree | ed44586092d7541a8254607083542b60246d099d | |
parent | 72734fc7b5fbbf4be0dd38cffc468e5664981e07 (diff) | |
download | bcm5719-llvm-52da938cd0e12a2e4ace751732b0ef7c6f9d3235.tar.gz bcm5719-llvm-52da938cd0e12a2e4ace751732b0ef7c6f9d3235.zip |
[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
llvm-svn: 357003
-rw-r--r-- | llvm/test/tools/llvm-exegesis/X86/latency-SBB8rr.s | 11 | ||||
-rw-r--r-- | llvm/tools/llvm-exegesis/lib/LlvmState.cpp | 7 | ||||
-rw-r--r-- | llvm/tools/llvm-exegesis/lib/Target.h | 5 | ||||
-rw-r--r-- | llvm/tools/llvm-exegesis/lib/X86/Target.cpp | 13 | ||||
-rw-r--r-- | llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp | 4 |
5 files changed, 38 insertions, 2 deletions
diff --git a/llvm/test/tools/llvm-exegesis/X86/latency-SBB8rr.s b/llvm/test/tools/llvm-exegesis/X86/latency-SBB8rr.s new file mode 100644 index 00000000000..d98d547cbd3 --- /dev/null +++ b/llvm/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/llvm/tools/llvm-exegesis/lib/LlvmState.cpp b/llvm/tools/llvm-exegesis/lib/LlvmState.cpp index ab487fd3897..059e8cb8c60 100644 --- a/llvm/tools/llvm-exegesis/lib/LlvmState.cpp +++ b/llvm/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/llvm/tools/llvm-exegesis/lib/Target.h b/llvm/tools/llvm-exegesis/lib/Target.h index f3429b79a34..ab760bfa820 100644 --- a/llvm/tools/llvm-exegesis/lib/Target.h +++ b/llvm/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<unsigned> 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/llvm/tools/llvm-exegesis/lib/X86/Target.cpp b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp index 2d705c9d18a..369ed2f97d7 100644 --- a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp @@ -435,6 +435,12 @@ private: unsigned Reg, const llvm::APInt &Value) const override; + ArrayRef<unsigned> getUnavailableRegisters() const override { + return makeArrayRef(kUnavailableRegisters, + sizeof(kUnavailableRegisters) / + sizeof(kUnavailableRegisters[0])); + } + std::unique_ptr<SnippetGenerator> createLatencySnippetGenerator(const LLVMState &State) const override { return llvm::make_unique<X86LatencySnippetGenerator>(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/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp b/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp index 15a1d8381fd..344ec6027d2 100644 --- a/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp +++ b/llvm/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( |