summaryrefslogtreecommitdiffstats
path: root/llvm/include
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/include')
-rw-r--r--llvm/include/llvm/Analysis/OptimizationDiagnosticInfo.h6
-rw-r--r--llvm/include/llvm/CodeGen/MachineLoopInfo.h7
-rw-r--r--llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h188
-rw-r--r--llvm/include/llvm/IR/DiagnosticInfo.h29
-rw-r--r--llvm/include/llvm/InitializePasses.h1
5 files changed, 226 insertions, 5 deletions
diff --git a/llvm/include/llvm/Analysis/OptimizationDiagnosticInfo.h b/llvm/include/llvm/Analysis/OptimizationDiagnosticInfo.h
index fd821a47a41..426fbb548e6 100644
--- a/llvm/include/llvm/Analysis/OptimizationDiagnosticInfo.h
+++ b/llvm/include/llvm/Analysis/OptimizationDiagnosticInfo.h
@@ -282,5 +282,11 @@ public:
/// \brief Run the analysis pass over a function and produce BFI.
Result run(Function &F, FunctionAnalysisManager &AM);
};
+
+namespace yaml {
+template <> struct MappingTraits<DiagnosticInfoOptimizationBase *> {
+ static void mapping(IO &io, DiagnosticInfoOptimizationBase *&OptDiag);
+};
+}
}
#endif // LLVM_IR_OPTIMIZATIONDIAGNOSTICINFO_H
diff --git a/llvm/include/llvm/CodeGen/MachineLoopInfo.h b/llvm/include/llvm/CodeGen/MachineLoopInfo.h
index dc72ae1810e..5c814f22f99 100644
--- a/llvm/include/llvm/CodeGen/MachineLoopInfo.h
+++ b/llvm/include/llvm/CodeGen/MachineLoopInfo.h
@@ -60,6 +60,13 @@ public:
/// multiple exiting blocks are present.
MachineBasicBlock *findLoopControlBlock();
+ /// Return the debug location of the start of this loop.
+ /// This looks for a BB terminating instruction with a known debug
+ /// location by looking at the preheader and header blocks. If it
+ /// cannot find a terminating instruction with location information,
+ /// it returns an unknown location.
+ DebugLoc getStartLoc() const;
+
void dump() const;
private:
diff --git a/llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h b/llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h
new file mode 100644
index 00000000000..fd48347d51a
--- /dev/null
+++ b/llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h
@@ -0,0 +1,188 @@
+///===- MachineOptimizationRemarkEmitter.h - Opt Diagnostics -*- C++ -*----===//
+///
+/// The LLVM Compiler Infrastructure
+///
+/// This file is distributed under the University of Illinois Open Source
+/// License. See LICENSE.TXT for details.
+///
+///===---------------------------------------------------------------------===//
+/// \file
+/// Optimization diagnostic interfaces for machine passes. It's packaged as an
+/// analysis pass so that by using this service passes become dependent on MBFI
+/// as well. MBFI is used to compute the "hotness" of the diagnostic message.
+///
+///===---------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEOPTIMIZATIONREMARKEMITTER_H
+#define LLVM_CODEGEN_MACHINEOPTIMIZATIONREMARKEMITTER_H
+
+#include "llvm/Analysis/OptimizationDiagnosticInfo.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+
+namespace llvm {
+class MachineBasicBlock;
+class MachineBlockFrequencyInfo;
+
+/// \brief Common features for diagnostics dealing with optimization remarks
+/// that are used by machine passes.
+class DiagnosticInfoMIROptimization : public DiagnosticInfoOptimizationBase {
+public:
+ DiagnosticInfoMIROptimization(enum DiagnosticKind Kind, const char *PassName,
+ StringRef RemarkName, const DebugLoc &DLoc,
+ MachineBasicBlock *MBB)
+ : DiagnosticInfoOptimizationBase(Kind, DS_Remark, PassName, RemarkName,
+ *MBB->getParent()->getFunction(), DLoc),
+ MBB(MBB) {}
+
+ static bool classof(const DiagnosticInfo *DI) {
+ return DI->getKind() >= DK_FirstMachineRemark &&
+ DI->getKind() <= DK_LastMachineRemark;
+ }
+
+ const MachineBasicBlock *getBlock() const { return MBB; }
+
+private:
+ MachineBasicBlock *MBB;
+};
+
+/// Diagnostic information for applied optimization remarks.
+class MachineOptimizationRemark : public DiagnosticInfoMIROptimization {
+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 RemarkName is a textual identifier for the remark. \p
+ /// DLoc is the debug location and \p MBB is the block that the optimization
+ /// operates in.
+ MachineOptimizationRemark(const char *PassName, StringRef RemarkName,
+ const DebugLoc &DLoc, MachineBasicBlock *MBB)
+ : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemark, PassName,
+ RemarkName, DLoc, MBB) {}
+
+ static bool classof(const DiagnosticInfo *DI) {
+ return DI->getKind() == DK_MachineOptimizationRemark;
+ }
+
+ /// \see DiagnosticInfoOptimizationBase::isEnabled.
+ bool isEnabled() const override {
+ return OptimizationRemark::isEnabled(getPassName());
+ }
+};
+
+/// Diagnostic information for missed-optimization remarks.
+class MachineOptimizationRemarkMissed : public DiagnosticInfoMIROptimization {
+public:
+ /// \p PassName is the name of the pass emitting this diagnostic. If this name
+ /// matches the regular expression given in -Rpass-missed=, then the
+ /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
+ /// remark. \p DLoc is the debug location and \p MBB is the block that the
+ /// optimization operates in.
+ MachineOptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
+ const DebugLoc &DLoc, MachineBasicBlock *MBB)
+ : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemarkMissed,
+ PassName, RemarkName, DLoc, MBB) {}
+
+ static bool classof(const DiagnosticInfo *DI) {
+ return DI->getKind() == DK_MachineOptimizationRemarkMissed;
+ }
+
+ /// \see DiagnosticInfoOptimizationBase::isEnabled.
+ bool isEnabled() const override {
+ return OptimizationRemarkMissed::isEnabled(getPassName());
+ }
+};
+
+/// Diagnostic information for optimization analysis remarks.
+class MachineOptimizationRemarkAnalysis : public DiagnosticInfoMIROptimization {
+public:
+ /// \p PassName is the name of the pass emitting this diagnostic. If this name
+ /// matches the regular expression given in -Rpass-analysis=, then the
+ /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
+ /// remark. \p DLoc is the debug location and \p MBB is the block that the
+ /// optimization operates in.
+ MachineOptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
+ const DebugLoc &DLoc,
+ MachineBasicBlock *MBB)
+ : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemarkAnalysis,
+ PassName, RemarkName, DLoc, MBB) {}
+
+ static bool classof(const DiagnosticInfo *DI) {
+ return DI->getKind() == DK_MachineOptimizationRemarkAnalysis;
+ }
+
+ /// \see DiagnosticInfoOptimizationBase::isEnabled.
+ bool isEnabled() const override {
+ return OptimizationRemarkAnalysis::isEnabled(getPassName());
+ }
+};
+
+/// The optimization diagnostic interface.
+///
+/// It allows reporting when optimizations are performed and when they are not
+/// along with the reasons for it. Hotness information of the corresponding
+/// code region can be included in the remark if DiagnosticHotnessRequested is
+/// enabled in the LLVM context.
+class MachineOptimizationRemarkEmitter {
+public:
+ MachineOptimizationRemarkEmitter(MachineFunction &MF,
+ MachineBlockFrequencyInfo *MBFI)
+ : MF(MF), MBFI(MBFI) {}
+
+ /// Emit an optimization remark.
+ void emit(DiagnosticInfoOptimizationBase &OptDiag);
+
+ /// \brief Whether we allow for extra compile-time budget to perform more
+ /// analysis to be more informative.
+ ///
+ /// This is useful to enable additional missed optimizations to be reported
+ /// that are normally too noisy. In this mode, we can use the extra analysis
+ /// (1) to filter trivial false positives or (2) to provide more context so
+ /// that non-trivial false positives can be quickly detected by the user.
+ bool allowExtraAnalysis() const {
+ // For now, only allow this with -fsave-optimization-record since the -Rpass
+ // options are handled in the front-end.
+ return MF.getFunction()->getContext().getDiagnosticsOutputFile();
+ }
+
+private:
+ MachineFunction &MF;
+
+ /// MBFI is only set if hotness is requested.
+ MachineBlockFrequencyInfo *MBFI;
+
+ /// Compute hotness from IR value (currently assumed to be a block) if PGO is
+ /// available.
+ Optional<uint64_t> computeHotness(const MachineBasicBlock &MBB);
+
+ /// Similar but use value from \p OptDiag and update hotness there.
+ void computeHotness(DiagnosticInfoMIROptimization &Remark);
+
+ /// \brief Only allow verbose messages if we know we're filtering by hotness
+ /// (BFI is only set in this case).
+ bool shouldEmitVerbose() { return MBFI != nullptr; }
+};
+
+/// The analysis pass
+///
+/// Note that this pass shouldn't generally be marked as preserved by other
+/// passes. It's holding onto BFI, so if the pass does not preserve BFI, BFI
+/// could be freed.
+class MachineOptimizationRemarkEmitterPass : public MachineFunctionPass {
+ std::unique_ptr<MachineOptimizationRemarkEmitter> ORE;
+
+public:
+ MachineOptimizationRemarkEmitterPass();
+
+ bool runOnMachineFunction(MachineFunction &MF) override;
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+ MachineOptimizationRemarkEmitter &getORE() {
+ assert(ORE && "pass not run yet");
+ return *ORE;
+ }
+
+ static char ID;
+};
+}
+
+#endif
diff --git a/llvm/include/llvm/IR/DiagnosticInfo.h b/llvm/include/llvm/IR/DiagnosticInfo.h
index afa7bba524a..23b37a08a85 100644
--- a/llvm/include/llvm/IR/DiagnosticInfo.h
+++ b/llvm/include/llvm/IR/DiagnosticInfo.h
@@ -69,6 +69,11 @@ enum DiagnosticKind {
DK_OptimizationFailure,
DK_FirstRemark = DK_OptimizationRemark,
DK_LastRemark = DK_OptimizationFailure,
+ DK_MachineOptimizationRemark,
+ DK_MachineOptimizationRemarkMissed,
+ DK_MachineOptimizationRemarkAnalysis,
+ DK_FirstMachineRemark = DK_MachineOptimizationRemark,
+ DK_LastMachineRemark = DK_MachineOptimizationRemarkAnalysis,
DK_MIRParser,
DK_PGOProfile,
DK_Unsupported,
@@ -440,8 +445,10 @@ public:
bool isVerbose() const { return IsVerbose; }
static bool classof(const DiagnosticInfo *DI) {
- return DI->getKind() >= DK_FirstRemark &&
- DI->getKind() <= DK_LastRemark;
+ return (DI->getKind() >= DK_FirstRemark &&
+ DI->getKind() <= DK_LastRemark) ||
+ (DI->getKind() >= DK_FirstMachineRemark &&
+ DI->getKind() <= DK_LastMachineRemark);
}
protected:
@@ -529,6 +536,10 @@ public:
Value *getCodeRegion() const { return CodeRegion; }
+ static bool classof(const DiagnosticInfo *DI) {
+ return DI->getKind() >= DK_FirstRemark && DI->getKind() <= DK_LastRemark;
+ }
+
private:
/// The IR value (currently basic block) that the optimization operates on.
/// This is currently used to provide run-time hotness information with PGO.
@@ -569,8 +580,10 @@ public:
return DI->getKind() == DK_OptimizationRemark;
}
+ static bool isEnabled(StringRef PassName);
+
/// \see DiagnosticInfoOptimizationBase::isEnabled.
- bool isEnabled() const override;
+ bool isEnabled() const override { return isEnabled(getPassName()); }
};
/// Diagnostic information for missed-optimization remarks.
@@ -607,8 +620,10 @@ public:
return DI->getKind() == DK_OptimizationRemarkMissed;
}
+ static bool isEnabled(StringRef PassName);
+
/// \see DiagnosticInfoOptimizationBase::isEnabled.
- bool isEnabled() const override;
+ bool isEnabled() const override { return isEnabled(getPassName()); }
};
/// Diagnostic information for optimization analysis remarks.
@@ -656,8 +671,12 @@ public:
return DI->getKind() == DK_OptimizationRemarkAnalysis;
}
+ static bool isEnabled(StringRef PassName);
+
/// \see DiagnosticInfoOptimizationBase::isEnabled.
- bool isEnabled() const override;
+ bool isEnabled() const override {
+ return shouldAlwaysPrint() || isEnabled(getPassName());
+ }
static const char *AlwaysPrint;
diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h
index c59dfee9693..a6cc44d4387 100644
--- a/llvm/include/llvm/InitializePasses.h
+++ b/llvm/include/llvm/InitializePasses.h
@@ -232,6 +232,7 @@ void initializeMachineFunctionPrinterPassPass(PassRegistry&);
void initializeMachineLICMPass(PassRegistry&);
void initializeMachineLoopInfoPass(PassRegistry&);
void initializeMachineModuleInfoPass(PassRegistry&);
+void initializeMachineOptimizationRemarkEmitterPassPass(PassRegistry&);
void initializeMachinePipelinerPass(PassRegistry&);
void initializeMachinePostDominatorTreePass(PassRegistry&);
void initializeMachineRegionInfoPassPass(PassRegistry&);
OpenPOWER on IntegriCloud