summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClement Courbet <courbet@google.com>2019-03-26 15:44:57 +0000
committerClement Courbet <courbet@google.com>2019-03-26 15:44:57 +0000
commit52da938cd0e12a2e4ace751732b0ef7c6f9d3235 (patch)
treeed44586092d7541a8254607083542b60246d099d
parent72734fc7b5fbbf4be0dd38cffc468e5664981e07 (diff)
downloadbcm5719-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.s11
-rw-r--r--llvm/tools/llvm-exegesis/lib/LlvmState.cpp7
-rw-r--r--llvm/tools/llvm-exegesis/lib/Target.h5
-rw-r--r--llvm/tools/llvm-exegesis/lib/X86/Target.cpp13
-rw-r--r--llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp4
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(
OpenPOWER on IntegriCloud