diff options
author | Diego Novillo <dnovillo@google.com> | 2014-04-16 16:54:24 +0000 |
---|---|---|
committer | Diego Novillo <dnovillo@google.com> | 2014-04-16 16:54:24 +0000 |
commit | 829b1700484d145ca93750384e7f49ef61a8d9b4 (patch) | |
tree | f744f1021f79a0a2822c60da1ece6a62cc7851cd /clang/lib | |
parent | df655013a997cc07dde62316bd4ba0b17fb3c25a (diff) | |
download | bcm5719-llvm-829b1700484d145ca93750384e7f49ef61a8d9b4.tar.gz bcm5719-llvm-829b1700484d145ca93750384e7f49ef61a8d9b4.zip |
Add support for optimization reports.
Summary:
This patch adds a new flag -Rpass=. The flag indicates the name
of the optimization pass that should emit remarks stating when it
made a transformation to the code.
This implements the design I proposed in:
https://docs.google.com/document/d/1FYUatSjZZO-zmFBxjOiuOzAy9mhHA8hqdvklZv68WuQ/edit?usp=sharing
Other changes:
- Add DiagnosticIDs::isRemark(). Use it in printDiagnosticOptions to
print "-R" instead of "-W" in the diagnostic message.
- In BackendConsumer::OptimizationRemarkHandler, get a SourceLocation
object out of the file name, line and column number. Use that location
in the call to Diags.Report().
- When -Rpass is used without debug info a note is emitted alerting
the user that they need to use -gline-tables-only -gcolumn-info to
get this information.
CC: llvm-commits
Differential Revision: http://llvm-reviews.chandlerc.com/D3226
llvm-svn: 206401
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Basic/DiagnosticIDs.cpp | 5 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenAction.cpp | 49 | ||||
-rw-r--r-- | clang/lib/Driver/Tools.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 11 | ||||
-rw-r--r-- | clang/lib/Frontend/TextDiagnosticPrinter.cpp | 3 |
5 files changed, 70 insertions, 1 deletions
diff --git a/clang/lib/Basic/DiagnosticIDs.cpp b/clang/lib/Basic/DiagnosticIDs.cpp index cf6933aeb1c..5334ae88d1c 100644 --- a/clang/lib/Basic/DiagnosticIDs.cpp +++ b/clang/lib/Basic/DiagnosticIDs.cpp @@ -361,6 +361,11 @@ bool DiagnosticIDs::isDefaultMappingAsError(unsigned DiagID) { return GetDefaultDiagMappingInfo(DiagID).getMapping() == diag::MAP_ERROR; } +bool DiagnosticIDs::isRemark(unsigned DiagID) { + return DiagID < diag::DIAG_UPPER_LIMIT && + getBuiltinDiagClass(DiagID) == CLASS_REMARK; +} + /// getDescription - Given a diagnostic ID, return a description of the /// issue. StringRef DiagnosticIDs::getDescription(unsigned DiagID) const { diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp index 573f8e98e77..67859bad2b4 100644 --- a/clang/lib/CodeGen/CodeGenAction.cpp +++ b/clang/lib/CodeGen/CodeGenAction.cpp @@ -20,6 +20,7 @@ #include "clang/Frontend/FrontendDiagnostic.h" #include "llvm/ADT/SmallString.h" #include "llvm/Bitcode/ReaderWriter.h" +#include "llvm/IR/DebugInfo.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/DiagnosticPrinter.h" #include "llvm/IR/LLVMContext.h" @@ -220,6 +221,11 @@ namespace clang { /// \return True if the diagnostic has been successfully reported, false /// otherwise. bool StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D); + /// \brief Specialized handler for the optimization diagnostic. + /// Note that this handler only accepts remarks and it always handles + /// them. + void + OptimizationRemarkHandler(const llvm::DiagnosticInfoOptimizationRemark &D); }; void BackendConsumer::anchor() {} @@ -374,6 +380,44 @@ BackendConsumer::StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D) { return true; } +void BackendConsumer::OptimizationRemarkHandler( + const llvm::DiagnosticInfoOptimizationRemark &D) { + // We only support remarks. + assert (D.getSeverity() == llvm::DS_Remark); + + // Optimization remarks are active only if -Rpass=regexp is given and the + // regular expression pattern in 'regexp' matches the name of the pass + // name in \p D. + if (CodeGenOpts.OptimizationRemarkPattern && + CodeGenOpts.OptimizationRemarkPattern->match(D.getPassName())) { + SourceManager &SourceMgr = Context->getSourceManager(); + FileManager &FileMgr = SourceMgr.getFileManager(); + StringRef Filename; + unsigned Line, Column; + D.getLocation(&Filename, &Line, &Column); + SourceLocation Loc; + if (Line > 0) { + // If -gcolumn-info was not used, Column will be 0. This upsets the + // source manager, so if Column is not set, set it to 1. + if (Column == 0) + Column = 1; + Loc = SourceMgr.translateFileLineCol(FileMgr.getFile(Filename), Line, + Column); + } + Diags.Report(Loc, diag::remark_fe_backend_optimization_remark) + << D.getMsg().str(); + + if (Line == 0) + // If we could not extract a source location for the diagnostic, + // inform the user how they can get source locations back. + // + // FIXME: We should really be generating !srcloc annotations when + // -Rpass is used. !srcloc annotations need to be emitted in + // approximately the same spots as !dbg nodes. + Diags.Report(diag::note_fe_backend_optimization_remark_missing_loc); + } +} + /// \brief This function is invoked when the backend needs /// to report something to the user. void BackendConsumer::DiagnosticHandlerImpl(const DiagnosticInfo &DI) { @@ -391,6 +435,11 @@ void BackendConsumer::DiagnosticHandlerImpl(const DiagnosticInfo &DI) { return; ComputeDiagID(Severity, backend_frame_larger_than, DiagID); break; + case llvm::DK_OptimizationRemark: + // Optimization remarks are always handled completely by this + // handler. There is no generic way of emitting them. + OptimizationRemarkHandler(cast<DiagnosticInfoOptimizationRemark>(DI)); + return; default: // Plugin IDs are not bound to any value as they are set dynamically. ComputeDiagRemarkID(Severity, backend_plugin, DiagID); diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index 018f9ba5748..9f64c3fa461 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -3417,6 +3417,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, A->render(Args, CmdArgs); } + if (Arg *A = Args.getLastArg(options::OPT_Rpass_EQ)) + A->render(Args, CmdArgs); + if (Args.hasArg(options::OPT_mkernel)) { if (!Args.hasArg(options::OPT_fapple_kext) && types::isCXX(InputType)) CmdArgs.push_back("-fapple-kext"); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 6177a96fa7b..e51d2cf8529 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -520,6 +520,17 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.DependentLibraries = Args.getAllArgValues(OPT_dependent_lib); + if (Arg *A = Args.getLastArg(OPT_Rpass_EQ)) { + StringRef Val = A->getValue(); + std::string RegexError; + Opts.OptimizationRemarkPattern = std::make_shared<llvm::Regex>(Val); + if (!Opts.OptimizationRemarkPattern->isValid(RegexError)) { + Diags.Report(diag::err_drv_optimization_remark_pattern) + << RegexError << A->getAsString(Args); + Opts.OptimizationRemarkPattern.reset(); + } + } + return Success; } diff --git a/clang/lib/Frontend/TextDiagnosticPrinter.cpp b/clang/lib/Frontend/TextDiagnosticPrinter.cpp index 994a8f74ed4..3b5eca6dd9d 100644 --- a/clang/lib/Frontend/TextDiagnosticPrinter.cpp +++ b/clang/lib/Frontend/TextDiagnosticPrinter.cpp @@ -81,7 +81,8 @@ static void printDiagnosticOptions(raw_ostream &OS, StringRef Opt = DiagnosticIDs::getWarningOptionForDiag(Info.getID()); if (!Opt.empty()) { - OS << (Started ? "," : " [") << "-W" << Opt; + OS << (Started ? "," : " [") + << (DiagnosticIDs::isRemark(Info.getID()) ? "-R" : "-W") << Opt; Started = true; } } |