Summary:
This patch adds backend support for -Rpass=, which indicates the name
of the optimization pass that should emit remarks stating when it
made a transformation to the code.
Pass names are taken from their DEBUG_NAME definitions.
When emitting an optimization report diagnostic, the lack of debug
information causes the diagnostic to use "<unknown>:0:0" as the
location string.
This is the back end counterpart for
http://llvm-reviews.chandlerc.com/D3226
Reviewers: qcolombet
CC: llvm-commits
Differential Revision: http://llvm-reviews.chandlerc.com/D3227
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205774
91177308-0d34-0410-b5e6-
96231b3b80d8
class Instruction;
class Twine;
class Value;
+class DebugLoc;
/// \brief Defines the different supported severity of a diagnostic.
enum DiagnosticSeverity {
DK_StackSize,
DK_DebugMetadataVersion,
DK_SampleProfile,
+ DK_OptimizationRemark,
DK_FirstPluginKind
};
const Twine &Msg;
};
+/// Diagnostic information for optimization remarks.
+class DiagnosticInfoOptimizationRemark : public DiagnosticInfo {
+public:
+ /// \p PassName is the name of the pass emitting this diagnostic. If
+ /// this name matches the regular expression given in -Rpass=, then the
+ /// diagnostic will be emitted. \p Fn is the function where the diagnostic
+ /// is being emitted. \p DLoc is the location information to use in the
+ /// diagnostic. If line table information is available, the diagnostic
+ /// will include the source code location. \p Msg is the message to show.
+ /// Note that this class does not copy this message, so this reference
+ /// must be valid for the whole life time of the diagnostic.
+ DiagnosticInfoOptimizationRemark(const char *PassName, const Function &Fn,
+ const DebugLoc &DLoc, const Twine &Msg)
+ : DiagnosticInfo(DK_OptimizationRemark, 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_OptimizationRemark;
+ }
+
+ /// Return true if location information is available for this diagnostic.
+ bool isLocationAvailable() const;
+
+ /// Return a string with the location information for this diagnostic
+ /// in the format "file:line:col". If location information is not available,
+ /// it returns "<unknown>:0:0".
+ const StringRef getLocationStr() const;
+
+ /// Return location information for this diagnostic in three parts:
+ /// the source file name, line number and column.
+ void getLocation(StringRef *Filename, unsigned *Line, unsigned *Column) const;
+
+ 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
class SMDiagnostic;
class DiagnosticInfo;
template <typename T> class SmallVectorImpl;
+class Function;
+class DebugLoc;
/// This is an important class for using LLVM in a threaded context. It
/// (opaquely) owns and manages the core "global" data of LLVM's core
void emitError(const Instruction *I, const Twine &ErrorStr);
void emitError(const Twine &ErrorStr);
+ /// emitOptimizationRemark - Emit an optimization remark message. \p PassName
+ /// is the name of the pass emitting the message. If -Rpass= is given
+ /// and \p PassName matches the regular expression in -Rpass, then the
+ /// remark will be emitted. \p Fn is the function triggering the remark,
+ /// \p DLoc is the debug location where the diagnostic is generated.
+ /// \p Msg is the message string to use.
+ void emitOptimizationRemark(const char *PassName, const Function &Fn,
+ const DebugLoc &DLoc, const Twine &Msg);
+
private:
LLVMContext(LLVMContext&) LLVM_DELETED_FUNCTION;
void operator=(LLVMContext&) LLVM_DELETED_FUNCTION;
#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"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
#include "llvm/Support/Atomic.h"
#include <string>
DP << getFileName() << ": ";
DP << getMsg();
}
+
+bool DiagnosticInfoOptimizationRemark::isLocationAvailable() const {
+ return getFunction().getParent()->getNamedMetadata("llvm.dbg.cu") != 0;
+}
+
+void DiagnosticInfoOptimizationRemark::getLocation(StringRef *Filename,
+ unsigned *Line,
+ unsigned *Column) const {
+ DILocation DIL(getDebugLoc().getAsMDNode(getFunction().getContext()));
+ *Filename = DIL.getFilename();
+ *Line = DIL.getLineNumber();
+ *Column = DIL.getColumnNumber();
+}
+
+const StringRef DiagnosticInfoOptimizationRemark::getLocationStr() const {
+ StringRef Filename("<unknown>");
+ unsigned Line = 0;
+ unsigned Column = 0;
+ if (isLocationAvailable())
+ getLocation(&Filename, &Line, &Column);
+ return Twine(Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();
+}
+
+void DiagnosticInfoOptimizationRemark::print(DiagnosticPrinter &DP) const {
+ DP << getLocationStr() << ": " << getMsg();
+}
#include "llvm/IR/LLVMContext.h"
#include "LLVMContextImpl.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/IR/Instruction.h"
diagnose(DiagnosticInfoInlineAsm(LocCookie, ErrorStr));
}
+void LLVMContext::emitOptimizationRemark(const char *PassName,
+ const Function &Fn,
+ const DebugLoc &DLoc,
+ const Twine &Msg) {
+ diagnose(DiagnosticInfoOptimizationRemark(PassName, Fn, DLoc, Msg));
+}
+
//===----------------------------------------------------------------------===//
// Metadata Kind Uniquing
//===----------------------------------------------------------------------===//
#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"
InlineHistoryID, InsertLifetime, DL))
continue;
++NumInlined;
-
+
+ // Report the inline decision.
+ Caller->getContext().emitOptimizationRemark(
+ DEBUG_TYPE, *Caller, CS.getInstruction()->getDebugLoc(),
+ Twine(Callee->getName() + " inlined into " + Caller->getName()));
+
// 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()) {