1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 03:02:36 +01:00

[llvm-exegesis] Save target state before running the benchmark.

Some benchmarked instructions might set target state. Preserve this
state. See PR26418.

Differential Revision: https://reviews.llvm.org/D90592
This commit is contained in:
Clement Courbet 2020-11-02 09:15:17 +01:00
parent 330e9dc042
commit 0a181c6ec2
5 changed files with 46 additions and 2 deletions

View File

@ -0,0 +1,6 @@
# RUN: llvm-exegesis -mode=uops -opcode-name=FLDENVm,FLDL2E -repetition-mode=duplicate | FileCheck %s
CHECK: mode: uops
CHECK-NEXT: key:
CHECK-NEXT: instructions:
CHECK-NEXT: FLDENVm

View File

@ -71,10 +71,10 @@ private:
SmallVector<StringRef, 2> CounterNames; SmallVector<StringRef, 2> CounterNames;
StringRef(Counters).split(CounterNames, '+'); StringRef(Counters).split(CounterNames, '+');
char *const ScratchPtr = Scratch->ptr(); char *const ScratchPtr = Scratch->ptr();
const ExegesisTarget &ET = State.getExegesisTarget();
for (auto &CounterName : CounterNames) { for (auto &CounterName : CounterNames) {
CounterName = CounterName.trim(); CounterName = CounterName.trim();
auto CounterOrError = auto CounterOrError = ET.createCounter(CounterName, State);
State.getExegesisTarget().createCounter(CounterName, State);
if (!CounterOrError) if (!CounterOrError)
return CounterOrError.takeError(); return CounterOrError.takeError();
@ -93,6 +93,7 @@ private:
.concat(std::to_string(Reserved))); .concat(std::to_string(Reserved)));
Scratch->clear(); Scratch->clear();
{ {
auto PS = ET.withSavedState();
CrashRecoveryContext CRC; CrashRecoveryContext CRC;
CrashRecoveryContext::Enable(); CrashRecoveryContext::Enable();
const bool Crashed = !CRC.RunSafely([this, Counter, ScratchPtr]() { const bool Crashed = !CRC.RunSafely([this, Counter, ScratchPtr]() {
@ -101,6 +102,7 @@ private:
Counter->stop(); Counter->stop();
}); });
CrashRecoveryContext::Disable(); CrashRecoveryContext::Disable();
PS.reset();
if (Crashed) { if (Crashed) {
std::string Msg = "snippet crashed while running"; std::string Msg = "snippet crashed while running";
#ifdef LLVM_ON_UNIX #ifdef LLVM_ON_UNIX

View File

@ -147,6 +147,8 @@ const PfmCountersInfo &ExegesisTarget::getPfmCounters(StringRef CpuName) const {
return *Found->PCI; return *Found->PCI;
} }
ExegesisTarget::SavedState::~SavedState() {} // anchor.
namespace { namespace {
// Default implementation. // Default implementation.

View File

@ -172,6 +172,16 @@ public:
// counters are defined for this CPU). // counters are defined for this CPU).
const PfmCountersInfo &getPfmCounters(StringRef CpuName) const; const PfmCountersInfo &getPfmCounters(StringRef CpuName) const;
// Saves the CPU state that needs to be preserved when running a benchmark,
// and returns and RAII object that restores the state on destruction.
// By default no state is preserved.
struct SavedState {
virtual ~SavedState();
};
virtual std::unique_ptr<SavedState> withSavedState() const {
return std::make_unique<SavedState>();
}
private: private:
virtual bool matchesArch(Triple::ArchType Arch) const = 0; virtual bool matchesArch(Triple::ArchType Arch) const = 0;

View File

@ -23,6 +23,7 @@
#include "llvm/Support/Error.h" #include "llvm/Support/Error.h"
#include "llvm/Support/FormatVariadic.h" #include "llvm/Support/FormatVariadic.h"
#include <immintrin.h>
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
@ -594,6 +595,25 @@ void ConstantInliner::initStack(unsigned Bytes) {
namespace { namespace {
class X86SavedState : public ExegesisTarget::SavedState {
public:
X86SavedState() { _fxsave64(FPState); }
~X86SavedState() {
// Restoring the X87 state does not flush pending exceptions, make sure
// these exceptions are flushed now.
#if defined(_MSC_VER)
_clearfp();
#elif defined(__GNUC__)
asm volatile("fwait");
#endif
_fxrstor64(FPState);
}
private:
alignas(16) char FPState[512];
};
class ExegesisX86Target : public ExegesisTarget { class ExegesisX86Target : public ExegesisTarget {
public: public:
ExegesisX86Target() : ExegesisTarget(X86CpuPfmCounters) {} ExegesisX86Target() : ExegesisTarget(X86CpuPfmCounters) {}
@ -691,6 +711,10 @@ private:
#endif #endif
} }
std::unique_ptr<SavedState> withSavedState() const override {
return std::make_unique<X86SavedState>();
}
static const unsigned kUnavailableRegisters[4]; static const unsigned kUnavailableRegisters[4];
}; };