Skip to content

Commit 8383fdd

Browse files
committed
Re-land "[llvm-exegesis] Save target state before running the benchmark."
The X86 exegesis target is never executed run on non-X86 hosts, disable X86 instrinsic code on non-X86 targets. This reverts commit 8cfc872.
1 parent 8475fa6 commit 8383fdd

File tree

5 files changed

+63
-2
lines changed

5 files changed

+63
-2
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# RUN: llvm-exegesis -mode=uops -opcode-name=FLDENVm,FLDL2E -repetition-mode=duplicate | FileCheck %s
2+
3+
CHECK: mode: uops
4+
CHECK-NEXT: key:
5+
CHECK-NEXT: instructions:
6+
CHECK-NEXT: FLDENVm

llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,10 @@ class FunctionExecutorImpl : public BenchmarkRunner::FunctionExecutor {
7171
SmallVector<StringRef, 2> CounterNames;
7272
StringRef(Counters).split(CounterNames, '+');
7373
char *const ScratchPtr = Scratch->ptr();
74+
const ExegesisTarget &ET = State.getExegesisTarget();
7475
for (auto &CounterName : CounterNames) {
7576
CounterName = CounterName.trim();
76-
auto CounterOrError =
77-
State.getExegesisTarget().createCounter(CounterName, State);
77+
auto CounterOrError = ET.createCounter(CounterName, State);
7878

7979
if (!CounterOrError)
8080
return CounterOrError.takeError();
@@ -93,6 +93,7 @@ class FunctionExecutorImpl : public BenchmarkRunner::FunctionExecutor {
9393
.concat(std::to_string(Reserved)));
9494
Scratch->clear();
9595
{
96+
auto PS = ET.withSavedState();
9697
CrashRecoveryContext CRC;
9798
CrashRecoveryContext::Enable();
9899
const bool Crashed = !CRC.RunSafely([this, Counter, ScratchPtr]() {
@@ -101,6 +102,7 @@ class FunctionExecutorImpl : public BenchmarkRunner::FunctionExecutor {
101102
Counter->stop();
102103
});
103104
CrashRecoveryContext::Disable();
105+
PS.reset();
104106
if (Crashed) {
105107
std::string Msg = "snippet crashed while running";
106108
#ifdef LLVM_ON_UNIX

llvm/tools/llvm-exegesis/lib/Target.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ const PfmCountersInfo &ExegesisTarget::getPfmCounters(StringRef CpuName) const {
147147
return *Found->PCI;
148148
}
149149

150+
ExegesisTarget::SavedState::~SavedState() {} // anchor.
151+
150152
namespace {
151153

152154
// Default implementation.

llvm/tools/llvm-exegesis/lib/Target.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,16 @@ class ExegesisTarget {
172172
// counters are defined for this CPU).
173173
const PfmCountersInfo &getPfmCounters(StringRef CpuName) const;
174174

175+
// Saves the CPU state that needs to be preserved when running a benchmark,
176+
// and returns and RAII object that restores the state on destruction.
177+
// By default no state is preserved.
178+
struct SavedState {
179+
virtual ~SavedState();
180+
};
181+
virtual std::unique_ptr<SavedState> withSavedState() const {
182+
return std::make_unique<SavedState>();
183+
}
184+
175185
private:
176186
virtual bool matchesArch(Triple::ArchType Arch) const = 0;
177187

llvm/tools/llvm-exegesis/lib/X86/Target.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
#include <memory>
2727
#include <string>
2828
#include <vector>
29+
#if defined(_MSC_VER)
30+
#include <immintrin.h>
31+
#endif
2932

3033
namespace llvm {
3134
namespace exegesis {
@@ -594,6 +597,40 @@ void ConstantInliner::initStack(unsigned Bytes) {
594597

595598
namespace {
596599

600+
class X86SavedState : public ExegesisTarget::SavedState {
601+
public:
602+
X86SavedState() {
603+
#ifdef __x86_64__
604+
# if defined(_MSC_VER)
605+
_fxsave64(FPState);
606+
# elif defined(__GNUC__)
607+
__builtin_ia32_fxsave64(FPState);
608+
# endif
609+
#else
610+
llvm_unreachable("X86 exegesis running on non-X86 target");
611+
#endif
612+
}
613+
614+
~X86SavedState() {
615+
// Restoring the X87 state does not flush pending exceptions, make sure
616+
// these exceptions are flushed now.
617+
#ifdef __x86_64__
618+
# if defined(_MSC_VER)
619+
_clearfp();
620+
_fxrstor64(FPState);
621+
# elif defined(__GNUC__)
622+
asm volatile("fwait");
623+
__builtin_ia32_fxrstor64(FPState);
624+
# endif
625+
#else
626+
llvm_unreachable("X86 exegesis running on non-X86 target");
627+
#endif
628+
}
629+
630+
private:
631+
alignas(16) char FPState[512];
632+
};
633+
597634
class ExegesisX86Target : public ExegesisTarget {
598635
public:
599636
ExegesisX86Target() : ExegesisTarget(X86CpuPfmCounters) {}
@@ -691,6 +728,10 @@ class ExegesisX86Target : public ExegesisTarget {
691728
#endif
692729
}
693730

731+
std::unique_ptr<SavedState> withSavedState() const override {
732+
return std::make_unique<X86SavedState>();
733+
}
734+
694735
static const unsigned kUnavailableRegisters[4];
695736
};
696737

0 commit comments

Comments
 (0)