[llvm] 08aeb7c - Revert "[llvm-exegesis] Introduce Subprocess Executor Mode"
Aiden Grossman via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 20 19:30:37 PDT 2023
Author: Aiden Grossman
Date: 2023-06-21T02:29:48Z
New Revision: 08aeb7c35ddbb8113fa95c4ffee4fc9493259ceb
URL: https://github.com/llvm/llvm-project/commit/08aeb7c35ddbb8113fa95c4ffee4fc9493259ceb
DIFF: https://github.com/llvm/llvm-project/commit/08aeb7c35ddbb8113fa95c4ffee4fc9493259ceb.diff
LOG: Revert "[llvm-exegesis] Introduce Subprocess Executor Mode"
This reverts commit 0d4ef4ff01addbb40b9122a00d6b2f23104cbb3b.
This was causing build failures on certain platforms when built with
-Werror due to unused variable warnings in addition to causing build
failures on Linux systems with older kernel versions as kernels prior to
v5.15 don't support sys_pidfd_getpid. Reverting as I need to setup a
system to properly test the rest of the patches in this series.
Also reverts 8c6668fa42dba59ddc286ba256d71c1b9c5228b8 which fixed the
first issue so that the patch can actually be reverted.
Added:
Modified:
llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
llvm/tools/llvm-exegesis/lib/BenchmarkRunner.h
llvm/tools/llvm-exegesis/llvm-exegesis.cpp
Removed:
llvm/test/tools/llvm-exegesis/X86/latency/subprocess-abnormal-exit-code.s
llvm/test/tools/llvm-exegesis/X86/latency/subprocess-segfault.s
llvm/test/tools/llvm-exegesis/X86/latency/subprocess.s
################################################################################
diff --git a/llvm/test/tools/llvm-exegesis/X86/latency/subprocess-abnormal-exit-code.s b/llvm/test/tools/llvm-exegesis/X86/latency/subprocess-abnormal-exit-code.s
deleted file mode 100644
index 9e28982e4573b..0000000000000
--- a/llvm/test/tools/llvm-exegesis/X86/latency/subprocess-abnormal-exit-code.s
+++ /dev/null
@@ -1,9 +0,0 @@
-# REQUIRES: exegesis-can-execute-x86_64, exegesis-can-measure-latency, x86_64-linux
-
-# RUN: llvm-exegesis -mtriple=x86_64-unknown-unknown -mode=latency -snippets-file=%s -execution-mode=subprocess | FileCheck %s
-
-# CHECK: error: 'Child benchmarking process exited with non-zero exit code: Child process returned with unknown exit code'
-
-movl $60, %eax
-movl $127, %edi
-syscall
diff --git a/llvm/test/tools/llvm-exegesis/X86/latency/subprocess-segfault.s b/llvm/test/tools/llvm-exegesis/X86/latency/subprocess-segfault.s
deleted file mode 100644
index 56a5c181b13d1..0000000000000
--- a/llvm/test/tools/llvm-exegesis/X86/latency/subprocess-segfault.s
+++ /dev/null
@@ -1,8 +0,0 @@
-# REQUIRES: exegesis-can-execute-x86_64, exegesis-can-measure-latency, x86_64-linux
-
-# RUN: llvm-exegesis -mtriple=x86_64-unknown-unknown -mode=latency -snippets-file=%s -execution-mode=subprocess | FileCheck %s
-
-# CHECK: error: 'The benchmarking subprocess sent unexpected signal: Segmentation fault'
-
-# LLVM-EXEGESIS-DEFREG RBX 0
-movq (%rbx), %rax
diff --git a/llvm/test/tools/llvm-exegesis/X86/latency/subprocess.s b/llvm/test/tools/llvm-exegesis/X86/latency/subprocess.s
deleted file mode 100644
index a8cfe9f97b44a..0000000000000
--- a/llvm/test/tools/llvm-exegesis/X86/latency/subprocess.s
+++ /dev/null
@@ -1,11 +0,0 @@
-# REQUIRES: exegesis-can-execute-x86_64, exegesis-can-measure-latency, x86_64-linux
-
-# RUN: llvm-exegesis -mtriple=x86_64-unknown-unknown -mode=latency -snippets-file=%s -execution-mode=subprocess | FileCheck %s
-
-# CHECK: measurements:
-# CHECK-NEXT: value: {{.*}}, per_snippet_value: {{.*}}
-
-# LLVM-EXEGESIS-DEFREG XMM1 42
-# LLVM-EXEGESIS-DEFREG XMM2 42
-# LLVM-EXEGESIS-DEFREG XMM3 42
-vhaddps %xmm2, %xmm2, %xmm3
diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
index 2b0a93a3dba67..09539e84cfaea 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
@@ -25,18 +25,6 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Program.h"
-#include "llvm/Support/Signals.h"
-
-#ifdef __linux__
-#ifdef HAVE_LIBPFM
-#include <perfmon/perf_event.h>
-#endif
-#include <sys/mman.h>
-#include <sys/ptrace.h>
-#include <sys/syscall.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#endif // __linux__
namespace llvm {
namespace exegesis {
@@ -141,178 +129,6 @@ class InProcessFunctionExecutorImpl : public BenchmarkRunner::FunctionExecutor {
const ExecutableFunction Function;
BenchmarkRunner::ScratchSpace *const Scratch;
};
-
-#ifdef __linux__
-// The following class implements a function executor that executes the
-// benchmark code within a subprocess rather than within the main llvm-exegesis
-// process. This allows for much more control over the execution context of the
-// snippet, particularly with regard to memory. This class performs all the
-// necessary functions to create the subprocess, execute the snippet in the
-// subprocess, and report results/handle errors.
-class SubProcessFunctionExecutorImpl
- : public BenchmarkRunner::FunctionExecutor {
-public:
- SubProcessFunctionExecutorImpl(const LLVMState &State,
- object::OwningBinary<object::ObjectFile> Obj,
- const BenchmarkKey &Key)
- : State(State), Function(State.createTargetMachine(), std::move(Obj)),
- Key(Key) {}
-
-private:
- enum ChildProcessExitCodeE {
- CounterFDReadFailed = 1,
- TranslatingCounterFDFailed
- };
-
- StringRef childProcessExitCodeToString(int ExitCode) const {
- switch (ExitCode) {
- case ChildProcessExitCodeE::CounterFDReadFailed:
- return "Counter file descriptor read failed";
- case ChildProcessExitCodeE::TranslatingCounterFDFailed:
- return "Translating counter file descriptor into a file descriptor in "
- "the child process failed. This might be due running an older "
- "Linux kernel that doesn't support the pidfd_getfd system call "
- "(anything before Linux 5.6).";
- default:
- return "Child process returned with unknown exit code";
- }
- }
-
- Error createSubProcessAndRunBenchmark(
- StringRef CounterName, SmallVectorImpl<int64_t> &CounterValues) const {
- int PipeFiles[2];
- int PipeSuccessOrErr = pipe(PipeFiles);
- if (PipeSuccessOrErr != 0) {
- return make_error<Failure>(
- "Failed to create a pipe for interprocess communication between "
- "llvm-exegesis and the benchmarking subprocess");
- }
-
- pid_t ParentOrChildPID = fork();
- if (ParentOrChildPID == 0) {
- // We are in the child process, close the write end of the pipe
- close(PipeFiles[1]);
- // Unregister handlers, signal handling is now handled through ptrace in
- // the host process
- llvm::sys::unregisterHandlers();
- prepareAndRunBenchmark(PipeFiles[0], Key);
- // The child process terminates in the above function, so we should never
- // get to this point.
- llvm_unreachable("Child process didn't exit when expected.");
- }
-
- const ExegesisTarget &ET = State.getExegesisTarget();
- auto CounterOrError =
- ET.createCounter(CounterName, State, ParentOrChildPID);
-
- if (!CounterOrError)
- return CounterOrError.takeError();
-
- pfm::Counter *Counter = CounterOrError.get().get();
-
- close(PipeFiles[0]);
-
- int CounterFileDescriptor = Counter->getFileDescriptor();
- ssize_t BytesWritten =
- write(PipeFiles[1], &CounterFileDescriptor, sizeof(int));
-
- if (BytesWritten != sizeof(int))
- return make_error<Failure>("Writing peformance counter file descriptor "
- "to child process failed: " +
- Twine(strerror(errno)));
-
- if (ptrace(PTRACE_SEIZE, ParentOrChildPID, NULL, NULL) != 0)
- return make_error<Failure>("Failed to seize the child process: " +
- Twine(strerror(errno)));
-
- int ChildStatus;
- if (wait(&ChildStatus) == -1) {
- return make_error<Failure>(
- "Waiting for the child process to complete failed: " +
- Twine(strerror(errno)));
- }
-
- if (WIFEXITED(ChildStatus)) {
- int ChildExitCode = WEXITSTATUS(ChildStatus);
- if (ChildExitCode == 0) {
- // The child exited succesfully, read counter values and return
- // success
- CounterValues[0] = Counter->read();
- return Error::success();
- }
- // The child exited, but not successfully
- return make_error<SnippetCrash>(
- "Child benchmarking process exited with non-zero exit code: " +
- childProcessExitCodeToString(ChildExitCode));
- }
-
- // An error was encountered running the snippet, process it
- siginfo_t ChildSignalInfo;
- if (ptrace(PTRACE_GETSIGINFO, ParentOrChildPID, NULL, &ChildSignalInfo) ==
- -1) {
- return make_error<Failure>("Getting signal info from the child failed: " +
- Twine(strerror(errno)));
- }
-
- return make_error<SnippetCrash>(
- "The benchmarking subprocess sent unexpected signal: " +
- Twine(strsignal(ChildSignalInfo.si_signo)));
- }
-
- [[noreturn]] void prepareAndRunBenchmark(int Pipe,
- const BenchmarkKey &Key) const {
- // The following occurs within the benchmarking subprocess
-
- int ParentCounterFileDescriptor = -1;
- ssize_t BytesRead = read(Pipe, &ParentCounterFileDescriptor, sizeof(int));
-
- if (BytesRead != sizeof(int)) {
- exit(ChildProcessExitCodeE::CounterFDReadFailed);
- }
-
-#ifdef SYS_pidfd_getfd
- pid_t ParentPID = getppid();
- int ParentPIDFD = syscall(SYS_pidfd_open, ParentPID, 0);
- int CounterFileDescriptor =
- syscall(SYS_pidfd_getfd, ParentPIDFD, ParentCounterFileDescriptor, 0);
-#else
- int CounterFileDescriptor = 0;
- exit(ChildProcessExitCodeE::TranslatingCounterFDFailed);
-#endif
-
- if (CounterFileDescriptor == -1) {
- exit(ChildProcessExitCodeE::TranslatingCounterFDFailed);
- }
-
-#ifdef HAVE_LIBPFM
- ioctl(CounterFileDescriptor, PERF_EVENT_IOC_RESET);
-#endif
- this->Function(nullptr);
-#ifdef HAVE_LIBPFM
- ioctl(CounterFileDescriptor, PERF_EVENT_IOC_DISABLE);
-#endif
-
- exit(0);
- }
-
- Expected<llvm::SmallVector<int64_t, 4>>
- runWithCounter(StringRef CounterName) const override {
- SmallVector<int64_t, 4> Value(1, 0);
- Error PossibleBenchmarkError =
- createSubProcessAndRunBenchmark(CounterName, Value);
-
- if (PossibleBenchmarkError) {
- return std::move(PossibleBenchmarkError);
- }
-
- return Value;
- }
-
- const LLVMState &State;
- const ExecutableFunction Function;
- const BenchmarkKey &Key;
-};
-#endif // __linux__
} // namespace
Expected<SmallString<0>> BenchmarkRunner::assembleSnippet(
@@ -385,14 +201,6 @@ BenchmarkRunner::createFunctionExecutor(
case ExecutionModeE::InProcess:
return std::make_unique<InProcessFunctionExecutorImpl>(
State, std::move(ObjectFile), Scratch.get());
- case ExecutionModeE::SubProcess:
-#ifdef __linux__
- return std::make_unique<SubProcessFunctionExecutorImpl>(
- State, std::move(ObjectFile), Key);
-#else
- return make_error<Failure>(
- "The subprocess execution mode is only supported on Linux");
-#endif
}
llvm_unreachable("ExecutionMode is outside expected range");
}
diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.h b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.h
index 8855990128bfc..e5185b4e97e32 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.h
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.h
@@ -34,7 +34,7 @@ namespace exegesis {
// Common code for all benchmark modes.
class BenchmarkRunner {
public:
- enum ExecutionModeE { InProcess, SubProcess };
+ enum ExecutionModeE { InProcess };
explicit BenchmarkRunner(const LLVMState &State, Benchmark::ModeE Mode,
BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
diff --git a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
index 82df07c6a83bb..d890fbb1336b4 100644
--- a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
+++ b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
@@ -254,11 +254,7 @@ static cl::opt<BenchmarkRunner::ExecutionModeE> ExecutionMode(
cl::cat(BenchmarkOptions),
cl::values(clEnumValN(BenchmarkRunner::ExecutionModeE::InProcess,
"inprocess",
- "Executes the snippets within the same process"),
- clEnumValN(BenchmarkRunner::ExecutionModeE::SubProcess,
- "subprocess",
- "Spawns a subprocess for each snippet execution, "
- "allows for the use of memory annotations")),
+ "Executes the snippets within the same process")),
cl::init(BenchmarkRunner::ExecutionModeE::InProcess));
static ExitOnError ExitOnErr("llvm-exegesis error: ");
More information about the llvm-commits
mailing list