diff options
| -rw-r--r-- | llvm/docs/CommandGuide/llc.rst | 6 | ||||
| -rw-r--r-- | llvm/docs/ReleaseNotes.md | 1 | ||||
| -rw-r--r-- | llvm/include/llvm/CodeGen/TargetInstrInfo.h | 3 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/MachineSink.cpp | 4 | ||||
| -rw-r--r-- | llvm/test/tools/llc/save-stats.ll | 15 | ||||
| -rw-r--r-- | llvm/tools/llc/llc.cpp | 74 |
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; |
