Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions llvm/docs/CommandGuide/llc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,12 @@ End-user Options

Print statistics recorded by code-generation passes.

.. option:: --save-stats, --save-stats=cwd, --save-stats=obj

Save LLVM statistics to a file in the current directory
(:option:`--save-stats`/"--save-stats=cwd") or the directory
of the output file ("--save-stats=obj") in JSON format.

.. option:: --time-passes

Record the amount of time needed for each pass and print a report to standard
Expand Down
1 change: 1 addition & 0 deletions llvm/docs/ReleaseNotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ Changes to the LLVM tools
* `llvm-readelf` now dumps all hex format values in lower-case mode.
* Some code paths for supporting Python 2.7 in `llvm-lit` have been removed.
* Support for `%T` in lit has been removed.
* Add `--save-stats` option to `llc` to save LLVM statistics to a file. Compatible with the Clang option.

Changes to LLDB
---------------------------------
Expand Down
10 changes: 10 additions & 0 deletions llvm/test/tools/llc/save-stats.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

; RUN: rm -f %t.stats && llc -mtriple=arm64-apple-macosx --save-stats=obj -o %t.s %s && test -f %t.stats
; RUN: rm -f %{t:stem}.tmp.stats && llc -mtriple=arm64-apple-macosx --save-stats=cwd -o %t.s %s && test -f %{t:stem}.tmp.stats
; RUN: rm -f %{t:stem}.tmp.stats && llc -mtriple=arm64-apple-macosx --save-stats -o %t.s %s && test -f %{t:stem}.tmp.stats
; RUN: not llc -mtriple=arm64-apple-macosx --save-stats=invalid -o %t.s %s 2>&1 | FileCheck %s --check-prefix=INVALID_ARG

; INVALID_ARG: {{.*}}llc{{.*}}: for the --save-stats option: Cannot find option named 'invalid'!
define i32 @func() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be some CHECK lines in here for at least a little bit of the structure of the stats file.

ret i32 0
}
76 changes: 72 additions & 4 deletions llvm/tools/llc/llc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand All @@ -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;
Expand Down Expand Up @@ -203,6 +206,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));

Expand Down Expand Up @@ -276,7 +293,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;
Expand Down Expand Up @@ -355,6 +373,47 @@ static std::unique_ptr<ToolOutputFile> GetOutputStream(const char *TargetName,
return FDOut;
}

static int MaybeEnableStats() {
if (SaveStats == SaveStatsMode::None) {
return 0;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (SaveStats == SaveStatsMode::None)
return 0;


llvm::EnableStatistics(false);
return 0;
}

static int MaybeSaveStats(std::string &&OutputFilename) {
if (SaveStats == SaveStatsMode::None) {
return 0;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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) &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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) {
Expand Down Expand Up @@ -432,18 +491,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,
Expand Down Expand Up @@ -475,7 +539,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;
Expand Down Expand Up @@ -659,6 +724,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;
Expand Down