diff options
Diffstat (limited to 'llvm/include')
| -rw-r--r-- | llvm/include/llvm/Analysis/OptimizationDiagnosticInfo.h | 6 | ||||
| -rw-r--r-- | llvm/include/llvm/CodeGen/MachineLoopInfo.h | 7 | ||||
| -rw-r--r-- | llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h | 188 | ||||
| -rw-r--r-- | llvm/include/llvm/IR/DiagnosticInfo.h | 29 | ||||
| -rw-r--r-- | llvm/include/llvm/InitializePasses.h | 1 |
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&); |

