hfinkel updated this revision to Diff 55907.
hfinkel added a comment.
Renamed the option from -flisting to -foptimization-report as suggested. Moved
I/O-related and formatting-related code into Frontend.
http://reviews.llvm.org/D19678
Files:
include/clang/Driver/CC1Options.td
include/clang/Driver/Options.td
include/clang/Frontend/CompilerInstance.h
include/clang/Frontend/CompilerInvocation.h
include/clang/Frontend/FrontendActions.h
include/clang/Frontend/OptReport.h
lib/CodeGen/CodeGenAction.cpp
lib/Driver/Tools.cpp
lib/Frontend/CMakeLists.txt
lib/Frontend/CompilerInvocation.cpp
lib/Frontend/OptReport.cpp
lib/FrontendTool/ExecuteCompilerInvocation.cpp
test/CodeGen/opt-report.c
test/Driver/opt-report.c
Index: test/Driver/opt-report.c
===================================================================
--- /dev/null
+++ test/Driver/opt-report.c
@@ -0,0 +1,9 @@
+// RUN: %clang -### -S -o FOO -foptimization-report %s 2>&1 | FileCheck %s
+// RUN: %clang -### -S -o FOO -foptimization-report=BAR.txt %s 2>&1 | FileCheck %s -check-prefix=CHECK-EQ
+
+// CHECK: "-cc1"
+// CHECK: "-opt-report-file" "opt-report.lst"
+
+// CHECK-EQ: "-cc1"
+// CHECK-EQ: "-opt-report-file" "BAR.txt"
+
Index: test/CodeGen/opt-report.c
===================================================================
--- /dev/null
+++ test/CodeGen/opt-report.c
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -O3 -triple x86_64-unknown-linux-gnu -target-cpu x86-64 %s -o %t -dwarf-column-info -opt-report-file %t.lst -emit-obj
+// RUN: cat %t.lst | FileCheck %s
+// REQUIRES: x86-registered-target
+
+void bar();
+void foo() { bar(); }
+
+void Test(int *res, int *c, int *d, int *p, int n) {
+ int i;
+
+#pragma clang loop vectorize(assume_safety)
+ for (i = 0; i < 1600; i++) {
+ res[i] = (p[i] == 0) ? res[i] : res[i] + d[i];
+ }
+
+// CHECK: {{[0-9]+}} | #pragma clang loop vectorize(assume_safety)
+// CHECK: {{[0-9]+}} V | for (i = 0; i < 1600; i++) {
+
+ for (i = 0; i < 16; i++) {
+ res[i] = (p[i] == 0) ? res[i] : res[i] + d[i];
+ }
+
+ foo();
+// CHECK: {{[0-9]+}} I | foo();
+
+ foo(); bar(); foo();
+// CHECK: {{[0-9]+}} | foo(); bar(); foo();
+// CHECK-NEXT: I | ^
+// CHECK-NEXT: I | ^
+}
+
Index: lib/FrontendTool/ExecuteCompilerInvocation.cpp
===================================================================
--- lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -165,6 +165,10 @@
Act = llvm::make_unique<ASTMergeAction>(std::move(Act),
FEOpts.ASTMergeFiles);
+ // If an optimization report is requested, generate this after compilation.
+ if (!CI.getOptReportInfo().FileName.empty())
+ Act = llvm::make_unique<OptReportAction>(std::move(Act));
+
return Act;
}
Index: lib/Frontend/OptReport.cpp
===================================================================
--- /dev/null
+++ lib/Frontend/OptReport.cpp
@@ -0,0 +1,123 @@
+//===------------------------ OptReport.cpp -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Frontend/OptReport.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Format.h"
+
+using namespace clang;
+
+void OptReportAction::EndSourceFileAction() {
+ GenerateReportFile();
+ WrapperFrontendAction::EndSourceFileAction();
+}
+
+void OptReportAction::GenerateReportFile() {
+ CompilerInstance &CI = getCompilerInstance();
+ DiagnosticsEngine &Diags = CI.getDiagnostics();
+ OptReportInfo &OptReport = CI.getOptReportInfo();
+ if (OptReport.FileName.empty())
+ return;
+
+ std::error_code EC;
+ llvm::raw_fd_ostream OS(OptReport.FileName, EC,
+ llvm::sys::fs::F_Text);
+ if (EC) {
+ Diags.Report(diag::err_fe_error_opening) << OptReport.FileName <<
+ EC.message();
+ return;
+ }
+
+ SourceManager &SourceMgr = CI.getSourceManager();
+ std::set<FileID> FileIDs;
+ for (auto &I : OptReport.LocationInfo)
+ FileIDs.insert(SourceMgr.getFileID(I.first));
+
+ for (auto &FID : FileIDs) {
+ SourceLocation FirstLoc = SourceMgr.getLocForStartOfFile(FID);
+ OS << "< " << SourceMgr.getFilename(FirstLoc) << "\n";
+
+ auto I = OptReport.LocationInfo.lower_bound(FirstLoc);
+ StringRef MB = SourceMgr.getBufferData(FID);
+ const SrcMgr::ContentCache *
+ Content = SourceMgr.getSLocEntry(FID).getFile().getContentCache();
+ unsigned LNDigits = llvm::utostr(Content->NumLines).size();
+ for (unsigned L = 0; L < Content->NumLines - 1; ++L) {
+ unsigned LStartOff = Content->SourceLineCache[L];
+ unsigned LEndOff = (L == Content->NumLines) ?
+ Content->getSize() :
+ Content->SourceLineCache[L + 1];
+
+ std::map<unsigned, OptReportLocationInfo> ColsInfo;
+ unsigned InlinedCols = 0, UnrolledCols = 0, VectorizedCols = 0;
+
+ OptReportLocationInfo LLI;
+ if (I != OptReport.LocationInfo.end()) {
+ auto DI = SourceMgr.getDecomposedLoc(I->first);
+ while (I != OptReport.LocationInfo.end() && DI.first == FID &&
+ DI.second < LStartOff) {
+ ++I;
+ if (I != OptReport.LocationInfo.end())
+ DI = SourceMgr.getDecomposedLoc(I->first);
+ }
+
+ while (I != OptReport.LocationInfo.end() && DI.first == FID &&
+ DI.second >= LStartOff && DI.second < LEndOff) {
+ unsigned Col = SourceMgr.getColumnNumber(FID, DI.second);
+ ColsInfo[Col] = I->second;
+ InlinedCols += I->second.Inlined.Analyzed;
+ UnrolledCols += I->second.Unrolled.Analyzed;
+ VectorizedCols += I->second.Vectorized.Analyzed;
+ LLI |= I->second;
+
+ ++I;
+ if (I != OptReport.LocationInfo.end())
+ DI = SourceMgr.getDecomposedLoc(I->first);
+ }
+ }
+
+ // We try to keep the output as concise as possible. If only one thing on
+ // a given line could have been inlined, vectorized, etc. then we can put
+ // the marker on the source line itself. If there are multiple options
+ // then we want to distinguish them by placing the marker for each
+ // transformation on a separate line following the source line. When we
+ // do this, we use a '^' character to point to the appropriate column in
+ // the source line.
+
+ OS << llvm::format_decimal(L + 1, LNDigits) << " ";
+ OS << (LLI.Inlined.Transformed && InlinedCols < 2 ? "I" : " ");
+ OS << (LLI.Unrolled.Transformed && UnrolledCols < 2 ? "U" : " ");
+ OS << (LLI.Vectorized.Transformed && VectorizedCols < 2 ? "V" : " ");
+
+ OS << " | " << MB.slice(LStartOff, LEndOff);
+
+ for (auto &J : ColsInfo) {
+ if ((J.second.Inlined.Transformed && InlinedCols > 1) ||
+ (J.second.Unrolled.Transformed && UnrolledCols > 1) ||
+ (J.second.Vectorized.Transformed && VectorizedCols > 1)) {
+ OS << std::string(LNDigits + 1, ' ');
+ OS << (J.second.Inlined.Transformed &&
+ InlinedCols > 1 ? "I" : " ");
+ OS << (J.second.Unrolled.Transformed &&
+ UnrolledCols > 1 ? "U" : " ");
+ OS << (J.second.Vectorized.Transformed &&
+ VectorizedCols > 1 ? "V" : " ");
+
+ OS << " | " << std::string(J.first - 1, ' ') << "^\n";
+ }
+ }
+
+ if (LEndOff == Content->getSize())
+ OS << "\n";
+ }
+ }
+}
+
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -415,7 +415,8 @@
Opts.setProfileUse(CodeGenOptions::ProfileClangInstr);
}
-static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
+static bool ParseCodeGenArgs(CodeGenOptions &Opts, OptReportInfo &OptReport,
+ ArgList &Args, InputKind IK,
DiagnosticsEngine &Diags,
const TargetOptions &TargetOpts) {
using namespace options;
@@ -488,6 +489,8 @@
Opts.DebugTypeExtRefs = Args.hasArg(OPT_dwarf_ext_refs);
Opts.DebugExplicitImport = Triple.isPS4CPU();
+ OptReport.FileName = Args.getLastArgValue(OPT_opt_report_file);
+
for (const auto &Arg : Args.getAllArgValues(OPT_fdebug_prefix_map_EQ))
Opts.DebugPrefixMap.insert(StringRef(Arg).split('='));
@@ -764,6 +767,10 @@
if (!Opts.SampleProfileFile.empty())
NeedLocTracking = true;
+ // To generate an optimization report, source location information is needed.
+ if (!OptReport.FileName.empty())
+ NeedLocTracking = true;
+
// If the user requested a flag that requires source locations available in
// the backend, make sure that the backend tracks source location information.
if (NeedLocTracking && Opts.getDebugInfo() == codegenoptions::NoDebugInfo)
@@ -2130,7 +2137,8 @@
// FIXME: We shouldn't have to pass the DashX option around here
InputKind DashX = ParseFrontendArgs(Res.getFrontendOpts(), Args, Diags);
ParseTargetArgs(Res.getTargetOpts(), Args, Diags);
- Success &= ParseCodeGenArgs(Res.getCodeGenOpts(), Args, DashX, Diags,
+ Success &= ParseCodeGenArgs(Res.getCodeGenOpts(), Res.getOptReportInfo(),
+ Args, DashX, Diags,
Res.getTargetOpts());
ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args);
if (DashX == IK_AST || DashX == IK_LLVM_IR) {
Index: lib/Frontend/CMakeLists.txt
===================================================================
--- lib/Frontend/CMakeLists.txt
+++ lib/Frontend/CMakeLists.txt
@@ -32,6 +32,7 @@
LogDiagnosticPrinter.cpp
ModuleDependencyCollector.cpp
MultiplexConsumer.cpp
+ OptReport.cpp
PCHContainerOperations.cpp
PrintPreprocessedOutput.cpp
SerializedDiagnosticPrinter.cpp
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -3141,23 +3141,29 @@
}
}
-static const char *SplitDebugName(const ArgList &Args, const InputInfo &Input) {
+static const char *getAltExtOutputName(const ArgList &Args,
+ const InputInfo &Input,
+ const char *Ext) {
Arg *FinalOutput = Args.getLastArg(options::OPT_o);
if (FinalOutput && Args.hasArg(options::OPT_c)) {
SmallString<128> T(FinalOutput->getValue());
- llvm::sys::path::replace_extension(T, "dwo");
+ llvm::sys::path::replace_extension(T, Ext);
return Args.MakeArgString(T);
} else {
// Use the compilation dir.
SmallString<128> T(
Args.getLastArgValue(options::OPT_fdebug_compilation_dir));
SmallString<128> F(llvm::sys::path::stem(Input.getBaseInput()));
- llvm::sys::path::replace_extension(F, "dwo");
+ llvm::sys::path::replace_extension(F, Ext);
T += F;
return Args.MakeArgString(F);
}
}
+static const char *SplitDebugName(const ArgList &Args, const InputInfo &Input) {
+ return getAltExtOutputName(Args, Input, "dwo");
+}
+
static void SplitDebugInfo(const ToolChain &TC, Compilation &C, const Tool &T,
const JobAction &JA, const ArgList &Args,
const InputInfo &Output, const char *OutFile) {
@@ -3182,6 +3188,10 @@
C.addCommand(llvm::make_unique<Command>(JA, T, Exec, StripArgs, II));
}
+static const char *getOptReportName(const ArgList &Args, const InputInfo &Input) {
+ return getAltExtOutputName(Args, Input, "lst");
+}
+
/// \brief Vectorize at all optimization levels greater than 1 except for -Oz.
/// For -Oz the loop vectorizer is disable, while the slp vectorizer is enabled.
static bool shouldEnableVectorizerAtOLevel(const ArgList &Args, bool isSlpVec) {
@@ -5650,6 +5660,18 @@
CmdArgs.push_back("-fno-math-builtin");
}
+ if (Args.hasFlag(options::OPT_foptimization_report,
+ options::OPT_foptimization_report_EQ,
+ options::OPT_fno_optimization_report, false)) {
+ CmdArgs.push_back("-opt-report-file");
+
+ const Arg *A = Args.getLastArg(options::OPT_foptimization_report_EQ);
+ if (A)
+ CmdArgs.push_back(A->getValue());
+ else
+ CmdArgs.push_back(getOptReportName(Args, Input));
+ }
+
// Default to -fno-builtin-str{cat,cpy} on Darwin for ARM.
//
// FIXME: Now that PR4941 has been fixed this can be enabled.
Index: lib/CodeGen/CodeGenAction.cpp
===================================================================
--- lib/CodeGen/CodeGenAction.cpp
+++ lib/CodeGen/CodeGenAction.cpp
@@ -20,6 +20,7 @@
#include "clang/CodeGen/ModuleBuilder.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Frontend/OptReport.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Bitcode/ReaderWriter.h"
@@ -31,6 +32,7 @@
#include "llvm/IRReader/IRReader.h"
#include "llvm/Linker/Linker.h"
#include "llvm/Pass.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/Timer.h"
@@ -46,6 +48,7 @@
const CodeGenOptions &CodeGenOpts;
const TargetOptions &TargetOpts;
const LangOptions &LangOpts;
+ OptReportInfo &OptReport;
raw_pwrite_stream *AsmOutStream;
ASTContext *Context;
@@ -66,13 +69,14 @@
const HeaderSearchOptions &HeaderSearchOpts,
const PreprocessorOptions &PPOpts, const CodeGenOptions &CodeGenOpts,
const TargetOptions &TargetOpts, const LangOptions &LangOpts,
- bool TimePasses, const std::string &InFile,
+ OptReportInfo &OptReport, bool TimePasses, const std::string &InFile,
const SmallVectorImpl<std::pair<unsigned, llvm::Module *>> &LinkModules,
raw_pwrite_stream *OS, LLVMContext &C,
CoverageSourceInfo *CoverageInfo = nullptr)
: Diags(Diags), Action(Action), CodeGenOpts(CodeGenOpts),
- TargetOpts(TargetOpts), LangOpts(LangOpts), AsmOutStream(OS),
- Context(nullptr), LLVMIRGeneration("LLVM IR Generation Time"),
+ TargetOpts(TargetOpts), LangOpts(LangOpts), OptReport(OptReport),
+ AsmOutStream(OS), Context(nullptr),
+ LLVMIRGeneration("LLVM IR Generation Time"),
Gen(CreateLLVMCodeGen(Diags, InFile, HeaderSearchOpts, PPOpts,
CodeGenOpts, C, CoverageInfo)) {
llvm::TimePassesIsEnabled = TimePasses;
@@ -254,6 +258,9 @@
const llvm::DiagnosticInfoOptimizationRemarkAnalysisAliasing &D);
void OptimizationFailureHandler(
const llvm::DiagnosticInfoOptimizationFailure &D);
+
+ void OptimizationRemarkOptReportHandler(
+ const llvm::DiagnosticInfoOptimizationBase &D, bool Transformed = false);
};
void BackendConsumer::anchor() {}
@@ -513,6 +520,9 @@
if (CodeGenOpts.OptimizationRemarkPattern &&
CodeGenOpts.OptimizationRemarkPattern->match(D.getPassName()))
EmitOptimizationMessage(D, diag::remark_fe_backend_optimization_remark);
+
+ // Record optimization decisions for the listing file.
+ OptimizationRemarkOptReportHandler(D, true);
}
void BackendConsumer::OptimizationRemarkHandler(
@@ -524,6 +534,9 @@
CodeGenOpts.OptimizationRemarkMissedPattern->match(D.getPassName()))
EmitOptimizationMessage(D,
diag::remark_fe_backend_optimization_remark_missed);
+
+ // Record optimization decisions for the listing file.
+ OptimizationRemarkOptReportHandler(D);
}
void BackendConsumer::OptimizationRemarkHandler(
@@ -537,6 +550,9 @@
CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName())))
EmitOptimizationMessage(
D, diag::remark_fe_backend_optimization_remark_analysis);
+
+ // Record optimization decisions for the listing file.
+ OptimizationRemarkOptReportHandler(D);
}
void BackendConsumer::OptimizationRemarkHandler(
@@ -550,6 +566,9 @@
CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName())))
EmitOptimizationMessage(
D, diag::remark_fe_backend_optimization_remark_analysis_fpcommute);
+
+ // Record optimization decisions for the listing file.
+ OptimizationRemarkOptReportHandler(D);
}
void BackendConsumer::OptimizationRemarkHandler(
@@ -563,13 +582,58 @@
CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName())))
EmitOptimizationMessage(
D, diag::remark_fe_backend_optimization_remark_analysis_aliasing);
+
+ // Record optimization decisions for the listing file.
+ OptimizationRemarkOptReportHandler(D);
}
void BackendConsumer::OptimizationFailureHandler(
const llvm::DiagnosticInfoOptimizationFailure &D) {
EmitOptimizationMessage(D, diag::warn_fe_backend_optimization_failure);
}
+void BackendConsumer::OptimizationRemarkOptReportHandler(
+ const llvm::DiagnosticInfoOptimizationBase &D, bool Transformed) {
+ if (OptReport.FileName.empty() || !D.isLocationAvailable())
+ return;
+
+ SourceManager &SourceMgr = Context->getSourceManager();
+ FileManager &FileMgr = SourceMgr.getFileManager();
+
+ StringRef Filename;
+ unsigned Line, Column;
+ D.getLocation(&Filename, &Line, &Column);
+ const FileEntry *FE = FileMgr.getFile(Filename);
+ if (!FE || !Line)
+ return;
+
+ // If -gcolumn-info was not used, Column will be 0. This upsets the
+ // source manager, so pass 1 if Column is not set.
+ SourceLocation DILoc =
+ SourceMgr.translateFileLineCol(FE, Line, Column ? Column : 1);
+ if (DILoc.isInvalid())
+ return;
+
+ // We track information on both actual and potential transformations. This
+ // way, if there are multiple possible things on a line that are, or could
+ // have been transformed, we can indicate that explicitly in the output.
+ auto UpdateLLII = [Transformed](OptReportLocationItemInfo &LLII) {
+ LLII.Analyzed = true;
+ if (Transformed)
+ LLII.Transformed = true;
+ };
+
+ // FIXME: The backend should use proper diagnostic subclasses here,
+ // and we should match those instead of looking at the pass name.
+ StringRef PassName = D.getPassName();
+ if (PassName == "inline")
+ UpdateLLII(OptReport.LocationInfo[DILoc].Inlined);
+ else if (PassName == "loop-unroll")
+ UpdateLLII(OptReport.LocationInfo[DILoc].Unrolled);
+ else if (PassName == "loop-vectorize")
+ UpdateLLII(OptReport.LocationInfo[DILoc].Vectorized);
+}
+
/// \brief This function is invoked when the backend needs
/// to report something to the user.
void BackendConsumer::DiagnosticHandlerImpl(const DiagnosticInfo &DI) {
@@ -750,8 +814,8 @@
std::unique_ptr<BackendConsumer> Result(new BackendConsumer(
BA, CI.getDiagnostics(), CI.getHeaderSearchOpts(),
CI.getPreprocessorOpts(), CI.getCodeGenOpts(), CI.getTargetOpts(),
- CI.getLangOpts(), CI.getFrontendOpts().ShowTimers, InFile, LinkModules,
- OS, *VMContext, CoverageInfo));
+ CI.getLangOpts(), CI.getOptReportInfo(), CI.getFrontendOpts().ShowTimers,
+ InFile, LinkModules, OS, *VMContext, CoverageInfo));
BEConsumer = Result.get();
return std::move(Result);
}
Index: include/clang/Frontend/OptReport.h
===================================================================
--- /dev/null
+++ include/clang/Frontend/OptReport.h
@@ -0,0 +1,67 @@
+//===---- OptReport.h - Clang Optimization-Report Generation ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_OPTREPORT_H_
+#define LLVM_CLANG_FRONTEND_OPTREPORT_H_
+
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Frontend/FrontendAction.h"
+#include <map>
+#include <string>
+
+namespace clang {
+// For each location in the source file, the common per-transformation state
+// collected.
+struct OptReportLocationItemInfo {
+ bool Analyzed = false;
+ bool Transformed = false;
+
+ OptReportLocationItemInfo &operator |= (
+ const OptReportLocationItemInfo &RHS) {
+ Analyzed |= RHS.Analyzed;
+ Transformed |= RHS.Transformed;
+
+ return *this;
+ }
+};
+
+// The per-location information collected for producing an optimization report.
+struct OptReportLocationInfo {
+ OptReportLocationItemInfo Inlined;
+ OptReportLocationItemInfo Unrolled;
+ OptReportLocationItemInfo Vectorized;
+
+ OptReportLocationInfo &operator |= (const OptReportLocationInfo &RHS) {
+ Inlined |= RHS.Inlined;
+ Unrolled |= RHS.Unrolled;
+ Vectorized |= RHS.Vectorized;
+
+ return *this;
+ }
+};
+
+// The parameters and accumulated state necessary to generate an optimization
+// report.
+struct OptReportInfo {
+ std::string FileName;
+ std::map<SourceLocation, OptReportLocationInfo> LocationInfo;
+};
+
+class OptReportAction : public WrapperFrontendAction {
+public:
+ OptReportAction(std::unique_ptr<FrontendAction> WrappedAction)
+ : WrapperFrontendAction(std::move(WrappedAction)) {}
+
+protected:
+ void EndSourceFileAction() override;
+ void GenerateReportFile();
+};
+} // end namespace clang
+
+#endif
Index: include/clang/Frontend/FrontendActions.h
===================================================================
--- include/clang/Frontend/FrontendActions.h
+++ include/clang/Frontend/FrontendActions.h
@@ -236,7 +236,7 @@
bool hasPCHSupport() const override { return true; }
};
-
+
} // end namespace clang
#endif
Index: include/clang/Frontend/CompilerInvocation.h
===================================================================
--- include/clang/Frontend/CompilerInvocation.h
+++ include/clang/Frontend/CompilerInvocation.h
@@ -19,6 +19,7 @@
#include "clang/Frontend/FrontendOptions.h"
#include "clang/Frontend/LangStandard.h"
#include "clang/Frontend/MigratorOptions.h"
+#include "clang/Frontend/OptReport.h"
#include "clang/Frontend/PreprocessorOutputOptions.h"
#include "clang/Lex/HeaderSearchOptions.h"
#include "clang/Lex/PreprocessorOptions.h"
@@ -117,6 +118,9 @@
/// Options controlling the frontend itself.
FrontendOptions FrontendOpts;
+ /// Optimization-report options and state.
+ OptReportInfo OptReport;
+
/// Options controlling preprocessed output.
PreprocessorOutputOptions PreprocessorOutputOpts;
@@ -196,6 +200,13 @@
return FrontendOpts;
}
+ OptReportInfo &getOptReportInfo() {
+ return OptReport;
+ }
+ const OptReportInfo &getOptReportInfo() const {
+ return OptReport;
+ }
+
PreprocessorOutputOptions &getPreprocessorOutputOpts() {
return PreprocessorOutputOpts;
}
Index: include/clang/Frontend/CompilerInstance.h
===================================================================
--- include/clang/Frontend/CompilerInstance.h
+++ include/clang/Frontend/CompilerInstance.h
@@ -298,6 +298,13 @@
return *Invocation->getLangOpts();
}
+ OptReportInfo &getOptReportInfo() {
+ return Invocation->getOptReportInfo();
+ }
+ const OptReportInfo &getOptReportInfo() const {
+ return Invocation->getOptReportInfo();
+ }
+
PreprocessorOptions &getPreprocessorOpts() {
return Invocation->getPreprocessorOpts();
}
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -1078,6 +1078,12 @@
Group<f_Group>;
def foperator_arrow_depth_EQ : Joined<["-"], "foperator-arrow-depth=">,
Group<f_Group>;
+def foptimization_report : Flag<["-"], "foptimization-report">, Group<f_Group>,
+ HelpText<"Generate an optimization report file">;
+def fno_optimization_report : Flag<["-"], "fno-optimization-report">,
+ Group<f_Group>, Flags<[NoArgumentUnused]>;
+def foptimization_report_EQ : Joined<["-"], "foptimization-report=">,Group<f_Group>,
+ HelpText<"Generate an optimization report file with the specified name">;
def ftest_coverage : Flag<["-"], "ftest-coverage">, Group<f_Group>;
def fvectorize : Flag<["-"], "fvectorize">, Group<f_Group>,
HelpText<"Enable the loop vectorization passes">;
Index: include/clang/Driver/CC1Options.td
===================================================================
--- include/clang/Driver/CC1Options.td
+++ include/clang/Driver/CC1Options.td
@@ -483,6 +483,9 @@
def arcmt_migrate : Flag<["-"], "arcmt-migrate">,
HelpText<"Apply modifications and produces temporary files that conform to ARC">;
+def opt_report_file : Separate<["-"], "opt-report-file">,
+ HelpText<"File name to use for optimization listing output">;
+
def print_stats : Flag<["-"], "print-stats">,
HelpText<"Print performance metrics and statistics">;
def fdump_record_layouts : Flag<["-"], "fdump-record-layouts">,
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits