aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools')
-rw-r--r--llvm/tools/llc/llc.cpp74
1 files changed, 70 insertions, 4 deletions
diff --git a/llvm/tools/llc/llc.cpp b/llvm/tools/llc/llc.cpp
index 152f7db..dc2f878 100644
--- a/llvm/tools/llc/llc.cpp
+++ b/llvm/tools/llc/llc.cpp
@@ -15,6 +15,7 @@
#include "NewPMDriver.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/ScopeExit.h"
+#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/CodeGen/CommandFlags.h"
#include "llvm/CodeGen/LinkAllAsmWriterComponents.h"
@@ -45,6 +46,7 @@
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/PGOOptions.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetSelect.h"
@@ -57,6 +59,7 @@
#include "llvm/TargetParser/SubtargetFeature.h"
#include "llvm/TargetParser/Triple.h"
#include "llvm/Transforms/Utils/Cloning.h"
+#include <cassert>
#include <memory>
#include <optional>
using namespace llvm;
@@ -208,6 +211,20 @@ static cl::opt<std::string> RemarksFormat(
cl::desc("The format used for serializing remarks (default: YAML)"),
cl::value_desc("format"), cl::init("yaml"));
+enum SaveStatsMode { None, Cwd, Obj };
+
+static cl::opt<SaveStatsMode> SaveStats(
+ "save-stats",
+ cl::desc("Save LLVM statistics to a file in the current directory"
+ "(`-save-stats`/`-save-stats=cwd`) or the directory of the output"
+ "file (`-save-stats=obj`). (default: cwd)"),
+ cl::values(clEnumValN(SaveStatsMode::Cwd, "cwd",
+ "Save to the current working directory"),
+ clEnumValN(SaveStatsMode::Cwd, "", ""),
+ clEnumValN(SaveStatsMode::Obj, "obj",
+ "Save to the output file directory")),
+ cl::init(SaveStatsMode::None), cl::ValueOptional);
+
static cl::opt<bool> EnableNewPassManager(
"enable-new-pm", cl::desc("Enable the new pass manager"), cl::init(false));
@@ -281,7 +298,8 @@ static void setPGOOptions(TargetMachine &TM) {
TM.setPGOOption(PGOOpt);
}
-static int compileModule(char **, LLVMContext &);
+static int compileModule(char **argv, LLVMContext &Context,
+ std::string &OutputFilename);
[[noreturn]] static void reportError(Twine Msg, StringRef Filename = "") {
SmallString<256> Prefix;
@@ -360,6 +378,45 @@ static std::unique_ptr<ToolOutputFile> GetOutputStream(const char *TargetName,
return FDOut;
}
+static int MaybeEnableStats() {
+ if (SaveStats == SaveStatsMode::None)
+ return 0;
+
+ llvm::EnableStatistics(false);
+ return 0;
+}
+
+static int MaybeSaveStats(std::string &&OutputFilename) {
+ if (SaveStats == SaveStatsMode::None)
+ return 0;
+
+ SmallString<128> StatsFilename;
+ if (SaveStats == SaveStatsMode::Obj) {
+ StatsFilename = OutputFilename;
+ llvm::sys::path::remove_filename(StatsFilename);
+ } else {
+ assert(SaveStats == SaveStatsMode::Cwd &&
+ "Should have been a valid --save-stats value");
+ }
+
+ auto BaseName = llvm::sys::path::filename(OutputFilename);
+ llvm::sys::path::append(StatsFilename, BaseName);
+ llvm::sys::path::replace_extension(StatsFilename, "stats");
+
+ auto FileFlags = llvm::sys::fs::OF_TextWithCRLF;
+ std::error_code EC;
+ auto StatsOS =
+ std::make_unique<llvm::raw_fd_ostream>(StatsFilename, EC, FileFlags);
+ if (EC) {
+ WithColor::error(errs(), "llc")
+ << "Unable to open statistics file: " << EC.message() << "\n";
+ return 1;
+ }
+
+ llvm::PrintStatisticsJSON(*StatsOS);
+ return 0;
+}
+
// main - Entry point for the llc compiler.
//
int main(int argc, char **argv) {
@@ -437,18 +494,23 @@ int main(int argc, char **argv) {
reportError(std::move(E), RemarksFilename);
LLVMRemarkFileHandle RemarksFile = std::move(*RemarksFileOrErr);
+ if (int RetVal = MaybeEnableStats())
+ return RetVal;
+ std::string OutputFilename;
+
if (InputLanguage != "" && InputLanguage != "ir" && InputLanguage != "mir")
reportError("input language must be '', 'IR' or 'MIR'");
// Compile the module TimeCompilations times to give better compile time
// metrics.
for (unsigned I = TimeCompilations; I; --I)
- if (int RetVal = compileModule(argv, Context))
+ if (int RetVal = compileModule(argv, Context, OutputFilename))
return RetVal;
if (RemarksFile)
RemarksFile->keep();
- return 0;
+
+ return MaybeSaveStats(std::move(OutputFilename));
}
static bool addPass(PassManagerBase &PM, const char *argv0, StringRef PassName,
@@ -480,7 +542,8 @@ static bool addPass(PassManagerBase &PM, const char *argv0, StringRef PassName,
return false;
}
-static int compileModule(char **argv, LLVMContext &Context) {
+static int compileModule(char **argv, LLVMContext &Context,
+ std::string &OutputFilename) {
// Load the module to be compiled...
SMDiagnostic Err;
std::unique_ptr<Module> M;
@@ -664,6 +727,9 @@ static int compileModule(char **argv, LLVMContext &Context) {
// Ensure the filename is passed down to CodeViewDebug.
Target->Options.ObjectFilenameForDebug = Out->outputFilename();
+ // Return a copy of the output filename via the output param
+ OutputFilename = Out->outputFilename();
+
// Tell target that this tool is not necessarily used with argument ABI
// compliance (i.e. narrow integer argument extensions).
Target->Options.VerifyArgABICompliance = 0;