Add support for optimization reports.

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
This commit is contained in:
Diego Novillo 2014-04-08 16:42:34 +00:00
parent 60db02b6fe
commit ccbf1d2a05
5 changed files with 113 additions and 1 deletions

View File

@ -26,6 +26,7 @@ class Function;
class Instruction;
class Twine;
class Value;
class DebugLoc;
/// \brief Defines the different supported severity of a diagnostic.
enum DiagnosticSeverity {
@ -44,6 +45,7 @@ enum DiagnosticKind {
DK_StackSize,
DK_DebugMetadataVersion,
DK_SampleProfile,
DK_OptimizationRemark,
DK_FirstPluginKind
};
@ -235,6 +237,63 @@ private:
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

View File

@ -29,6 +29,8 @@ class Module;
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
@ -125,6 +127,15 @@ public:
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;

View File

@ -14,11 +14,13 @@
#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>
@ -64,3 +66,29 @@ void DiagnosticInfoSampleProfile::print(DiagnosticPrinter &DP) const {
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();
}

View File

@ -15,6 +15,7 @@
#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"
@ -155,6 +156,13 @@ void LLVMContext::emitError(unsigned LocCookie, const Twine &ErrorStr) {
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
//===----------------------------------------------------------------------===//

View File

@ -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,12 @@ bool Inliner::runOnSCC(CallGraphSCC &SCC) {
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()) {