[llvm] [llvm-profgen] Remove temporary perf script files (PR #86668)
Haohai Wen via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 26 19:23:26 PDT 2024
https://github.com/HaohaiWen updated https://github.com/llvm/llvm-project/pull/86668
>From 94b08cee11409739e99e1a791af92441ee03e302 Mon Sep 17 00:00:00 2001
From: Haohai Wen <haohai.wen at intel.com>
Date: Tue, 26 Mar 2024 22:10:34 +0800
Subject: [PATCH 1/3] [llvm-profgen] Remove temporary perf script files
The temporary perf script files converted from perf data will occupy lots
of space for large project. This patch removes them when llvm-profgen
exits normally or receives signals.
---
llvm/tools/llvm-profgen/PerfReader.cpp | 19 +++++++++++++++++++
llvm/tools/llvm-profgen/PerfReader.h | 7 +++++++
llvm/tools/llvm-profgen/llvm-profgen.cpp | 2 ++
3 files changed, 28 insertions(+)
diff --git a/llvm/tools/llvm-profgen/PerfReader.cpp b/llvm/tools/llvm-profgen/PerfReader.cpp
index 878147642aa6e7..5ed0f1333cf2eb 100644
--- a/llvm/tools/llvm-profgen/PerfReader.cpp
+++ b/llvm/tools/llvm-profgen/PerfReader.cpp
@@ -11,6 +11,7 @@
#include "llvm/DebugInfo/Symbolize/SymbolizableModule.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Process.h"
+#include "llvm/Support/Signals.h"
#define DEBUG_TYPE "perf-reader"
@@ -375,6 +376,9 @@ PerfScriptReader::convertPerfDataToTrace(ProfiledBinary *Binary,
StringRef(ErrorFile)}; // Stderr
sys::ExecuteAndWait(PerfPath, ScriptMMapArgs, std::nullopt, Redirects);
+ PerfScriptReader::markTempFile(PerfTraceFile);
+ PerfScriptReader::markTempFile(ErrorFile);
+
// Collect the PIDs
TraceStream TraceIt(PerfTraceFile);
std::string PIDs;
@@ -992,6 +996,11 @@ bool PerfScriptReader::extractMMap2EventForBinary(ProfiledBinary *Binary,
return Binary->getName() == BinaryName;
}
+void PerfScriptReader::markTempFile(StringRef FileName) {
+ sys::RemoveFileOnSignal(FileName);
+ TempFiles.push_back(FileName.str());
+}
+
void PerfScriptReader::parseMMap2Event(TraceStream &TraceIt) {
MMapEvent MMap;
if (extractMMap2EventForBinary(Binary, TraceIt.getCurrentLine(), MMap))
@@ -1081,6 +1090,14 @@ PerfContent PerfScriptReader::checkPerfScriptType(StringRef FileName) {
return PerfContent::UnknownContent;
}
+void PerfScriptReader::removeTempFiles() {
+ for (StringRef FileName : TempFiles) {
+ sys::fs::remove(FileName);
+ sys::DontRemoveFileOnSignal(FileName);
+ }
+ TempFiles.clear();
+}
+
void HybridPerfReader::generateUnsymbolizedProfile() {
ProfileIsCS = !IgnoreStackSamples;
if (ProfileIsCS)
@@ -1220,5 +1237,7 @@ void PerfScriptReader::parsePerfTraces() {
writeUnsymbolizedProfile(OutputFilename);
}
+SmallVector<std::string, 2> PerfScriptReader::TempFiles;
+
} // end namespace sampleprof
} // end namespace llvm
diff --git a/llvm/tools/llvm-profgen/PerfReader.h b/llvm/tools/llvm-profgen/PerfReader.h
index e9f619350bf970..6401a4c51c8b10 100644
--- a/llvm/tools/llvm-profgen/PerfReader.h
+++ b/llvm/tools/llvm-profgen/PerfReader.h
@@ -603,6 +603,8 @@ class PerfScriptReader : public PerfReaderBase {
std::optional<uint32_t> PIDFilter);
// Extract perf script type by peaking at the input
static PerfContent checkPerfScriptType(StringRef FileName);
+ // Remove all temporary files.
+ static void removeTempFiles();
protected:
// The parsed MMap event
@@ -622,6 +624,8 @@ class PerfScriptReader : public PerfReaderBase {
// mapping between the binary name and its memory layout.
static bool extractMMap2EventForBinary(ProfiledBinary *Binary, StringRef Line,
MMapEvent &MMap);
+ // Mark temporary file for future clean up.
+ static void markTempFile(StringRef FileName);
// Update base address based on mmap events
void updateBinaryAddress(const MMapEvent &Event);
// Parse mmap event and update binary address
@@ -662,6 +666,9 @@ class PerfScriptReader : public PerfReaderBase {
std::set<uint64_t> InvalidReturnAddresses;
// PID for the process of interest
std::optional<uint32_t> PIDFilter;
+
+ // Temporary files created by perf script command.
+ static SmallVector<std::string, 2> TempFiles;
};
/*
diff --git a/llvm/tools/llvm-profgen/llvm-profgen.cpp b/llvm/tools/llvm-profgen/llvm-profgen.cpp
index 3b974e25103ad4..d0ec463f717677 100644
--- a/llvm/tools/llvm-profgen/llvm-profgen.cpp
+++ b/llvm/tools/llvm-profgen/llvm-profgen.cpp
@@ -189,5 +189,7 @@ int main(int argc, const char *argv[]) {
Generator->write();
}
+ PerfScriptReader::removeTempFiles();
+
return EXIT_SUCCESS;
}
>From 969af1ed4bf5e69957746c3377557d02ff1a81bd Mon Sep 17 00:00:00 2001
From: Haohai Wen <haohai.wen at intel.com>
Date: Wed, 27 Mar 2024 10:13:27 +0800
Subject: [PATCH 2/3] [Support] Make CleanupInstaller public
This can be used by others to automatically remove temp files.
---
llvm/include/llvm/Support/ToolOutputFile.h | 26 ++++++++++++----------
llvm/lib/Support/ToolOutputFile.cpp | 4 ++--
2 files changed, 16 insertions(+), 14 deletions(-)
diff --git a/llvm/include/llvm/Support/ToolOutputFile.h b/llvm/include/llvm/Support/ToolOutputFile.h
index e3fb83fdfd2c3f..c16fb03d9b22b9 100644
--- a/llvm/include/llvm/Support/ToolOutputFile.h
+++ b/llvm/include/llvm/Support/ToolOutputFile.h
@@ -18,6 +18,19 @@
namespace llvm {
+class CleanupInstaller {
+public:
+ /// The name of the file.
+ std::string Filename;
+
+ /// The flag which indicates whether we should not delete the file.
+ bool Keep;
+
+ StringRef getFilename() { return Filename; }
+ explicit CleanupInstaller(StringRef Filename);
+ ~CleanupInstaller();
+};
+
/// This class contains a raw_fd_ostream and adds a few extra features commonly
/// needed for compiler-like tool output files:
/// - The file is automatically deleted if the process is killed.
@@ -28,18 +41,7 @@ class ToolOutputFile {
/// before the raw_fd_ostream is constructed and destructed after the
/// raw_fd_ostream is destructed. It installs cleanups in its constructor and
/// uninstalls them in its destructor.
- class CleanupInstaller {
- public:
- /// The name of the file.
- std::string Filename;
-
- /// The flag which indicates whether we should not delete the file.
- bool Keep;
-
- StringRef getFilename() { return Filename; }
- explicit CleanupInstaller(StringRef Filename);
- ~CleanupInstaller();
- } Installer;
+ CleanupInstaller Installer;
/// Storage for the stream, if we're owning our own stream. This is
/// intentionally declared after Installer.
diff --git a/llvm/lib/Support/ToolOutputFile.cpp b/llvm/lib/Support/ToolOutputFile.cpp
index 01f7095f3499d9..7a07286882fee0 100644
--- a/llvm/lib/Support/ToolOutputFile.cpp
+++ b/llvm/lib/Support/ToolOutputFile.cpp
@@ -17,14 +17,14 @@ using namespace llvm;
static bool isStdout(StringRef Filename) { return Filename == "-"; }
-ToolOutputFile::CleanupInstaller::CleanupInstaller(StringRef Filename)
+CleanupInstaller::CleanupInstaller(StringRef Filename)
: Filename(std::string(Filename)), Keep(false) {
// Arrange for the file to be deleted if the process is killed.
if (!isStdout(Filename))
sys::RemoveFileOnSignal(Filename);
}
-ToolOutputFile::CleanupInstaller::~CleanupInstaller() {
+CleanupInstaller::~CleanupInstaller() {
if (isStdout(Filename))
return;
>From e456fa67b223aa60562773bb759d4c03c5e709f5 Mon Sep 17 00:00:00 2001
From: Haohai Wen <haohai.wen at intel.com>
Date: Wed, 27 Mar 2024 10:15:53 +0800
Subject: [PATCH 3/3] Use CleanupInstaller to make code cleaner
---
llvm/tools/llvm-profgen/PerfReader.cpp | 21 ++++-----------------
llvm/tools/llvm-profgen/PerfReader.h | 15 ++++++++-------
llvm/tools/llvm-profgen/llvm-profgen.cpp | 2 --
3 files changed, 12 insertions(+), 26 deletions(-)
diff --git a/llvm/tools/llvm-profgen/PerfReader.cpp b/llvm/tools/llvm-profgen/PerfReader.cpp
index 5ed0f1333cf2eb..e9442027aed3fa 100644
--- a/llvm/tools/llvm-profgen/PerfReader.cpp
+++ b/llvm/tools/llvm-profgen/PerfReader.cpp
@@ -11,7 +11,7 @@
#include "llvm/DebugInfo/Symbolize/SymbolizableModule.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Process.h"
-#include "llvm/Support/Signals.h"
+#include "llvm/Support/ToolOutputFile.h"
#define DEBUG_TYPE "perf-reader"
@@ -376,8 +376,8 @@ PerfScriptReader::convertPerfDataToTrace(ProfiledBinary *Binary,
StringRef(ErrorFile)}; // Stderr
sys::ExecuteAndWait(PerfPath, ScriptMMapArgs, std::nullopt, Redirects);
- PerfScriptReader::markTempFile(PerfTraceFile);
- PerfScriptReader::markTempFile(ErrorFile);
+ PerfScriptReader::TempFileCleanups.emplace_back(PerfTraceFile);
+ PerfScriptReader::TempFileCleanups.emplace_back(ErrorFile);
// Collect the PIDs
TraceStream TraceIt(PerfTraceFile);
@@ -996,11 +996,6 @@ bool PerfScriptReader::extractMMap2EventForBinary(ProfiledBinary *Binary,
return Binary->getName() == BinaryName;
}
-void PerfScriptReader::markTempFile(StringRef FileName) {
- sys::RemoveFileOnSignal(FileName);
- TempFiles.push_back(FileName.str());
-}
-
void PerfScriptReader::parseMMap2Event(TraceStream &TraceIt) {
MMapEvent MMap;
if (extractMMap2EventForBinary(Binary, TraceIt.getCurrentLine(), MMap))
@@ -1090,14 +1085,6 @@ PerfContent PerfScriptReader::checkPerfScriptType(StringRef FileName) {
return PerfContent::UnknownContent;
}
-void PerfScriptReader::removeTempFiles() {
- for (StringRef FileName : TempFiles) {
- sys::fs::remove(FileName);
- sys::DontRemoveFileOnSignal(FileName);
- }
- TempFiles.clear();
-}
-
void HybridPerfReader::generateUnsymbolizedProfile() {
ProfileIsCS = !IgnoreStackSamples;
if (ProfileIsCS)
@@ -1237,7 +1224,7 @@ void PerfScriptReader::parsePerfTraces() {
writeUnsymbolizedProfile(OutputFilename);
}
-SmallVector<std::string, 2> PerfScriptReader::TempFiles;
+SmallVector<CleanupInstaller, 2> PerfScriptReader::TempFileCleanups;
} // end namespace sampleprof
} // end namespace llvm
diff --git a/llvm/tools/llvm-profgen/PerfReader.h b/llvm/tools/llvm-profgen/PerfReader.h
index 6401a4c51c8b10..b821cbe13efae6 100644
--- a/llvm/tools/llvm-profgen/PerfReader.h
+++ b/llvm/tools/llvm-profgen/PerfReader.h
@@ -21,6 +21,9 @@ using namespace llvm;
using namespace sampleprof;
namespace llvm {
+
+class CleanupInstaller;
+
namespace sampleprof {
// Stream based trace line iterator
@@ -603,8 +606,11 @@ class PerfScriptReader : public PerfReaderBase {
std::optional<uint32_t> PIDFilter);
// Extract perf script type by peaking at the input
static PerfContent checkPerfScriptType(StringRef FileName);
- // Remove all temporary files.
- static void removeTempFiles();
+
+ // Cleanup installers for temporary files created by perf script command.
+ // Those files will be automatically removed when running destructor or
+ // receiving signals.
+ static SmallVector<CleanupInstaller, 2> TempFileCleanups;
protected:
// The parsed MMap event
@@ -624,8 +630,6 @@ class PerfScriptReader : public PerfReaderBase {
// mapping between the binary name and its memory layout.
static bool extractMMap2EventForBinary(ProfiledBinary *Binary, StringRef Line,
MMapEvent &MMap);
- // Mark temporary file for future clean up.
- static void markTempFile(StringRef FileName);
// Update base address based on mmap events
void updateBinaryAddress(const MMapEvent &Event);
// Parse mmap event and update binary address
@@ -666,9 +670,6 @@ class PerfScriptReader : public PerfReaderBase {
std::set<uint64_t> InvalidReturnAddresses;
// PID for the process of interest
std::optional<uint32_t> PIDFilter;
-
- // Temporary files created by perf script command.
- static SmallVector<std::string, 2> TempFiles;
};
/*
diff --git a/llvm/tools/llvm-profgen/llvm-profgen.cpp b/llvm/tools/llvm-profgen/llvm-profgen.cpp
index d0ec463f717677..3b974e25103ad4 100644
--- a/llvm/tools/llvm-profgen/llvm-profgen.cpp
+++ b/llvm/tools/llvm-profgen/llvm-profgen.cpp
@@ -189,7 +189,5 @@ int main(int argc, const char *argv[]) {
Generator->write();
}
- PerfScriptReader::removeTempFiles();
-
return EXIT_SUCCESS;
}
More information about the llvm-commits
mailing list