aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--llvm/docs/CommandGuide/llc.rst6
-rw-r--r--llvm/docs/ReleaseNotes.md1
-rw-r--r--llvm/include/llvm/CodeGen/TargetInstrInfo.h3
-rw-r--r--llvm/lib/CodeGen/MachineSink.cpp4
-rw-r--r--llvm/test/tools/llc/save-stats.ll15
-rw-r--r--llvm/tools/llc/llc.cpp74
6 files changed, 99 insertions, 4 deletions
diff --git a/llvm/docs/CommandGuide/llc.rst b/llvm/docs/CommandGuide/llc.rst
index cc670f6..ffcccfb 100644
--- a/llvm/docs/CommandGuide/llc.rst
+++ b/llvm/docs/CommandGuide/llc.rst
@@ -129,6 +129,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
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 23bba99..fd78c97 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -182,6 +182,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.
* `llvm-config` gained a new flag `--quote-paths` which quotes and escapes paths
emitted on stdout, to account for spaces or other special characters in path.
diff --git a/llvm/include/llvm/CodeGen/TargetInstrInfo.h b/llvm/include/llvm/CodeGen/TargetInstrInfo.h
index 2dcedfb..7010cff 100644
--- a/llvm/include/llvm/CodeGen/TargetInstrInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetInstrInfo.h
@@ -436,7 +436,10 @@ public:
/// MachineSink determines on its own whether the instruction is safe to sink;
/// this gives the target a hook to override the default behavior with regards
/// to which instructions should be sunk.
+ ///
+ /// shouldPostRASink() is used by PostRAMachineSink.
virtual bool shouldSink(const MachineInstr &MI) const { return true; }
+ virtual bool shouldPostRASink(const MachineInstr &MI) const { return true; }
/// Return false if the instruction should not be hoisted by MachineLICM.
///
diff --git a/llvm/lib/CodeGen/MachineSink.cpp b/llvm/lib/CodeGen/MachineSink.cpp
index cdcb29d9..94ed82e 100644
--- a/llvm/lib/CodeGen/MachineSink.cpp
+++ b/llvm/lib/CodeGen/MachineSink.cpp
@@ -2287,6 +2287,10 @@ bool PostRAMachineSinkingImpl::tryToSinkCopy(MachineBasicBlock &CurBB,
continue;
}
+ // Don't postRASink instructions that the target prefers not to sink.
+ if (!TII->shouldPostRASink(MI))
+ continue;
+
if (MI.isDebugOrPseudoInstr())
continue;
diff --git a/llvm/test/tools/llc/save-stats.ll b/llvm/test/tools/llc/save-stats.ll
new file mode 100644
index 0000000..94b17e5
--- /dev/null
+++ b/llvm/test/tools/llc/save-stats.ll
@@ -0,0 +1,15 @@
+; REQUIRES: asserts
+
+; RUN: llc -mtriple=arm64-apple-macosx --save-stats=obj -o %t.s %s && cat %t.stats | FileCheck %s
+; RUN: llc -mtriple=arm64-apple-macosx --save-stats=cwd -o %t.s %s && cat %{t:stem}.tmp.stats | FileCheck %s
+; RUN: llc -mtriple=arm64-apple-macosx --save-stats -o %t.s %s && cat %{t:stem}.tmp.stats | FileCheck %s
+; RUN: not llc -mtriple=arm64-apple-macosx --save-stats=invalid -o %t.s %s 2>&1 | FileCheck %s --check-prefix=INVALID_ARG
+
+; CHECK: {
+; CHECK: "asm-printer.EmittedInsts":
+; CHECK: }
+
+; INVALID_ARG: {{.*}}llc{{.*}}: for the --save-stats option: Cannot find option named 'invalid'!
+define i32 @func() {
+ ret i32 0
+}
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;