Index: cfe/trunk/lib/Driver/ToolChains/Darwin.cpp =================================================================== --- cfe/trunk/lib/Driver/ToolChains/Darwin.cpp +++ cfe/trunk/lib/Driver/ToolChains/Darwin.cpp @@ -514,6 +514,14 @@ } } + // Setup statistics file output. + SmallString<128> StatsFile = + getStatsFileName(Args, Output, Inputs[0], getToolChain().getDriver()); + if (!StatsFile.empty()) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back(Args.MakeArgString("-lto-stats-file=" + StatsFile.str())); + } + // It seems that the 'e' option is completely ignored for dynamic executables // (the default), and with static executables, the last one wins, as expected. Args.AddAllArgs(CmdArgs, {options::OPT_d_Flag, options::OPT_s, options::OPT_t, Index: llvm/trunk/include/llvm/LTO/LTO.h =================================================================== --- llvm/trunk/include/llvm/LTO/LTO.h +++ llvm/trunk/include/llvm/LTO/LTO.h @@ -87,6 +87,10 @@ StringRef LTORemarksPasses, bool LTOPassRemarksWithHotness, int Count = -1); +/// Setups the output file for saving statistics. +Expected> +setupStatsFile(StringRef StatsFilename); + class LTO; struct SymbolResolution; class ThinBackendProc; Index: llvm/trunk/include/llvm/LTO/legacy/LTOCodeGenerator.h =================================================================== --- llvm/trunk/include/llvm/LTO/legacy/LTOCodeGenerator.h +++ llvm/trunk/include/llvm/LTO/legacy/LTOCodeGenerator.h @@ -241,6 +241,7 @@ TargetMachine::CodeGenFileType FileType = TargetMachine::CGFT_ObjectFile; std::unique_ptr DiagnosticOutputFile; bool Freestanding = false; + std::unique_ptr StatsFile = nullptr; }; } #endif Index: llvm/trunk/lib/LTO/LTO.cpp =================================================================== --- llvm/trunk/lib/LTO/LTO.cpp +++ llvm/trunk/lib/LTO/LTO.cpp @@ -885,16 +885,10 @@ isPrevailing, Conf.OptLevel > 0); // Setup output file to emit statistics. - std::unique_ptr StatsFile = nullptr; - if (!Conf.StatsFile.empty()) { - EnableStatistics(false); - std::error_code EC; - StatsFile = - llvm::make_unique(Conf.StatsFile, EC, sys::fs::F_None); - if (EC) - return errorCodeToError(EC); - StatsFile->keep(); - } + auto StatsFileOrErr = setupStatsFile(Conf.StatsFile); + if (!StatsFileOrErr) + return StatsFileOrErr.takeError(); + std::unique_ptr StatsFile = std::move(StatsFileOrErr.get()); // Finalize linking of regular LTO modules containing summaries now that // we have computed liveness information. @@ -1343,3 +1337,20 @@ DiagnosticFile->keep(); return std::move(DiagnosticFile); } + +Expected> +lto::setupStatsFile(StringRef StatsFilename) { + // Setup output file to emit statistics. + if (StatsFilename.empty()) + return nullptr; + + llvm::EnableStatistics(false); + std::error_code EC; + auto StatsFile = + llvm::make_unique(StatsFilename, EC, sys::fs::F_None); + if (EC) + return errorCodeToError(EC); + + StatsFile->keep(); + return std::move(StatsFile); +} Index: llvm/trunk/lib/LTO/LTOCodeGenerator.cpp =================================================================== --- llvm/trunk/lib/LTO/LTOCodeGenerator.cpp +++ llvm/trunk/lib/LTO/LTOCodeGenerator.cpp @@ -95,6 +95,11 @@ "lto-pass-remarks-with-hotness", cl::desc("With PGO, include profile count in optimization remarks"), cl::Hidden); + +cl::opt LTOStatsFile( + "lto-stats-file", + cl::desc("Save statistics to the specified file"), + cl::Hidden); } LTOCodeGenerator::LTOCodeGenerator(LLVMContext &Context) @@ -518,6 +523,14 @@ } DiagnosticOutputFile = std::move(*DiagFileOrErr); + // Setup output file to emit statistics. + auto StatsFileOrErr = lto::setupStatsFile(LTOStatsFile); + if (!StatsFileOrErr) { + errs() << "Error: " << toString(StatsFileOrErr.takeError()) << "\n"; + report_fatal_error("Can't get an output file for the statistics"); + } + StatsFile = std::move(StatsFileOrErr.get()); + // We always run the verifier once on the merged module, the `DisableVerify` // parameter only applies to subsequent verify. verifyMergedModuleOnce(); @@ -584,9 +597,13 @@ [&]() { return createTargetMachine(); }, FileType, ShouldRestoreGlobalsLinkage); - // If statistics were requested, print them out after codegen. - if (llvm::AreStatisticsEnabled()) - llvm::PrintStatistics(); + // If statistics were requested, save them to the specified file or + // print them out after codegen. + if (StatsFile) + PrintStatisticsJSON(StatsFile->os()); + else if (AreStatisticsEnabled()) + PrintStatistics(); + reportAndResetTimings(); finishOptimizationRemarks();