Index: include/llvm/IR/DiagnosticInfo.h =================================================================== --- include/llvm/IR/DiagnosticInfo.h +++ include/llvm/IR/DiagnosticInfo.h @@ -26,6 +26,7 @@ class Instruction; class Twine; class Value; +class DebugLoc; /// \brief Defines the different supported severity of a diagnostic. enum DiagnosticSeverity { @@ -44,6 +45,7 @@ DK_StackSize, DK_DebugMetadataVersion, DK_SampleProfile, + DK_OptimizationReport, DK_FirstPluginKind }; @@ -235,6 +237,44 @@ const Twine &Msg; }; +/// Diagnostic information for optimization reports. +class DiagnosticInfoOptimizationReport : public DiagnosticInfo { +public: + DiagnosticInfoOptimizationReport(const char *PassName, const Function &Fn, + const DebugLoc &DLoc, const Twine &Msg) + : DiagnosticInfo(DK_OptimizationReport, DS_Remark), PassName(PassName), + Fn(Fn), DLoc(DLoc), Msg(Msg) { + } + + /// \see DiagnosticInfo::print. + void print(DiagnosticPrinter &DP) const override; + + /// Hand rolled RTTI. + static bool classof(const DiagnosticInfo *DI) { + return DI->getKind() == DK_OptimizationReport; + } + + const char *getPassName() const { return PassName; } + const Function &getFunction() const { return Fn; } + const DebugLoc &getDebugLoc() const { return DLoc; } + const Twine &getMsg() const { return Msg; } + +private: + /// Name of the pass that triggers this report. If this matches the + /// regular expression given in -Rpass=regexp, then the remark will + /// be emitted. + const char *PassName; + + /// Function where this diagnostic is triggered. + const Function &Fn; + + /// Debug location where this diagnostic is triggered. + const DebugLoc &DLoc; + + /// Message to report. + const Twine &Msg; +}; + } // End namespace llvm #endif Index: include/llvm/Transforms/IPO/PassManagerBuilder.h =================================================================== --- include/llvm/Transforms/IPO/PassManagerBuilder.h +++ include/llvm/Transforms/IPO/PassManagerBuilder.h @@ -16,6 +16,7 @@ #define LLVM_TRANSFORMS_IPO_PASSMANAGERBUILDER_H #include +#include namespace llvm { class TargetLibraryInfo; Index: lib/IR/DiagnosticInfo.cpp =================================================================== --- lib/IR/DiagnosticInfo.cpp +++ lib/IR/DiagnosticInfo.cpp @@ -14,6 +14,7 @@ #include "llvm/ADT/Twine.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfo.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/DiagnosticPrinter.h" #include "llvm/IR/Function.h" @@ -64,3 +65,11 @@ DP << getFileName() << ": "; DP << getMsg(); } + +void DiagnosticInfoOptimizationReport::print(DiagnosticPrinter &DP) const { + DILocation DIL(getDebugLoc().getAsMDNode(getFunction().getContext())); + StringRef FileName = DIL.getFilename(); + unsigned LineNum = DIL.getLineNumber(); + unsigned ColumnNum = DIL.getColumnNumber(); + DP << FileName << ":" << LineNum << ":" << ColumnNum << ": " << getMsg(); +} Index: lib/Transforms/IPO/Inliner.cpp =================================================================== --- lib/Transforms/IPO/Inliner.cpp +++ lib/Transforms/IPO/Inliner.cpp @@ -21,6 +21,7 @@ #include "llvm/Analysis/InlineCost.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Module.h" @@ -522,7 +523,13 @@ InlineHistoryID, InsertLifetime, DL)) continue; ++NumInlined; - + + // Report the inline decision. + DiagnosticInfoOptimizationReport Diag( + DEBUG_TYPE, *Caller, CS.getInstruction()->getDebugLoc(), + Twine(Callee->getName() + " inlined into " + Caller->getName())); + Caller->getContext().diagnose(Diag); + // If inlining this function gave us any new call sites, throw them // onto our worklist to process. They are useful inline candidates. if (!InlineInfo.InlinedCalls.empty()) {