Aiden Grossman 980d66caae
[llvm-exegesis] Error Out If Perf Counter is Not Fully Enabled (#132892)
Perf counters can be multiplexed if there are too many that need to be
scheduled on a core at the same time (and they exceed the available
PMUs). Other processes (especially system ones in certain environments,
not commonly on Desktop Linux from what I've seen) can also interfere.
This will impact the measurement fidelity as the counter is not actually
counting cycles/uops the entire time. This patch makes it so that we
error out in these cases so the user gets a visible indication things
have gone wrong rather than things failing silently.
2025-03-31 10:58:24 -07:00

95 lines
2.7 KiB
C++

//===-- Error.h -------------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TOOLS_LLVM_EXEGESIS_ERROR_H
#define LLVM_TOOLS_LLVM_EXEGESIS_ERROR_H
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Error.h"
namespace llvm {
namespace exegesis {
// A class representing failures that happened within llvm-exegesis, they are
// used to report informations to the user.
class Failure : public StringError {
public:
Failure(const Twine &S) : StringError(S, inconvertibleErrorCode()) {}
};
// A class representing failures that happened during clustering calculations.
class ClusteringError : public ErrorInfo<ClusteringError> {
public:
static char ID;
ClusteringError(const Twine &S) : Msg(S.str()) {}
void log(raw_ostream &OS) const override;
std::error_code convertToErrorCode() const override;
private:
std::string Msg;
};
// A class representing a non-descript snippet execution failure. This class
// is designed to sub-classed into more specific failures that contain
// additional data about the specific error that they represent. Instead of
// halting the program, the errors are reported in the output.
class SnippetExecutionFailure : public ErrorInfo<SnippetExecutionFailure> {
public:
static char ID;
std::error_code convertToErrorCode() const override;
};
// A class representing specifically segmentation faults that happen during
// snippet execution.
class SnippetSegmentationFault : public SnippetExecutionFailure {
public:
static char ID;
SnippetSegmentationFault(uintptr_t SegFaultAddress)
: Address(SegFaultAddress) {};
uintptr_t getAddress() { return Address; }
void log(raw_ostream &OS) const override;
private:
uintptr_t Address;
};
// A class representing all other non-specific failures that happen during
// snippet execution.
class SnippetSignal : public SnippetExecutionFailure {
public:
static char ID;
SnippetSignal(int Signal) : SignalNumber(Signal){};
void log(raw_ostream &OS) const override;
private:
int SignalNumber;
};
// A class representing a case where a perf counter was only partially
// scheduled, most likely due to perf counter contention.
struct PerfCounterNotFullyEnabled
: public ErrorInfo<PerfCounterNotFullyEnabled> {
static char ID;
PerfCounterNotFullyEnabled() {}
void log(raw_ostream &OS) const override;
std::error_code convertToErrorCode() const override;
};
} // namespace exegesis
} // namespace llvm
#endif