Index: include/llvm/Analysis/OptimizationDiagnosticInfo.h =================================================================== --- include/llvm/Analysis/OptimizationDiagnosticInfo.h +++ include/llvm/Analysis/OptimizationDiagnosticInfo.h @@ -67,7 +67,11 @@ bool invalidate(Function &F, const PreservedAnalyses &PA, FunctionAnalysisManager::Invalidator &Inv); - /// The new interface to emit remarks. + /// \brief Output the remark via the diagnostic handler and to the + /// optimization record file. + /// + /// This is the new interface that should be now used rather than the legacy + /// emit* APIs. void emit(DiagnosticInfoOptimizationBase &OptDiag); /// Emit an optimization-applied message. @@ -224,7 +228,7 @@ Optional computeHotness(const Value *V); /// Similar but use value from \p OptDiag and update hotness there. - void computeHotness(DiagnosticInfoOptimizationBase &OptDiag); + void computeHotness(DiagnosticInfoIROptimization &OptDiag); /// \brief Only allow verbose messages if we know we're filtering by hotness /// (BFI is only set in this case). Index: include/llvm/IR/DiagnosticInfo.h =================================================================== --- include/llvm/IR/DiagnosticInfo.h +++ include/llvm/IR/DiagnosticInfo.h @@ -376,7 +376,8 @@ DebugLoc DLoc; }; -/// Common features for diagnostics dealing with optimization remarks. +/// \brief Common features for diagnostics dealing with optimization remarks +/// that are used by both IR and MIR passes. class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithDebugLocBase { public: /// \brief Used to set IsVerbose via the stream interface. @@ -408,52 +409,13 @@ /// RemarkName is a textual identifier for the remark. \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 CodeRegion is IR - /// value (currently basic block) that the optimization operates on. This is - /// currently used to provide run-time hotness information with PGO. + /// diagnostic will include the source code location. DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind, enum DiagnosticSeverity Severity, const char *PassName, StringRef RemarkName, - const Function &Fn, const DebugLoc &DLoc, - Value *CodeRegion = nullptr) - : DiagnosticInfoWithDebugLocBase(Kind, Severity, Fn, DLoc), - PassName(PassName), RemarkName(RemarkName), CodeRegion(CodeRegion) {} - - /// \brief This is ctor variant allows a pass to build an optimization remark - /// from an existing remark. - /// - /// This is useful when a transformation pass (e.g LV) wants to emit a remark - /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis - /// remark. The string \p Prepend will be emitted before the original - /// message. - DiagnosticInfoOptimizationBase(const char *PassName, StringRef Prepend, - const DiagnosticInfoOptimizationBase &Orig) - : DiagnosticInfoWithDebugLocBase((DiagnosticKind)Orig.getKind(), - Orig.getSeverity(), Orig.getFunction(), - Orig.getDebugLoc()), - PassName(PassName), RemarkName(Orig.RemarkName), - CodeRegion(Orig.getCodeRegion()) { - *this << Prepend; - std::copy(Orig.Args.begin(), Orig.Args.end(), std::back_inserter(Args)); - } - - /// Legacy interface. - /// \p PassName is the name of the pass emitting this diagnostic. - /// \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. - DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind, - enum DiagnosticSeverity Severity, - const char *PassName, const Function &Fn, - const DebugLoc &DLoc, const Twine &Msg, - Optional Hotness = None) + const Function &Fn, const DebugLoc &DLoc) : DiagnosticInfoWithDebugLocBase(Kind, Severity, Fn, DLoc), - PassName(PassName), Hotness(Hotness) { - Args.push_back(Argument(Msg.str())); - } + PassName(PassName), RemarkName(RemarkName) {} DiagnosticInfoOptimizationBase &operator<<(StringRef S); DiagnosticInfoOptimizationBase &operator<<(Argument A); @@ -475,8 +437,6 @@ Optional getHotness() const { return Hotness; } void setHotness(Optional H) { Hotness = H; } - Value *getCodeRegion() const { return CodeRegion; } - bool isVerbose() const { return IsVerbose; } static bool classof(const DiagnosticInfo *DI) { @@ -484,7 +444,7 @@ DI->getKind() <= DK_LastRemark; } -private: +protected: /// Name of the pass that triggers this report. If this matches the /// regular expression given in -Rpass=regexp, then the remark will /// be emitted. @@ -498,10 +458,6 @@ /// corresponding code was executed in a profile instrumentation run. Optional Hotness; - /// The IR value (currently basic block) that the optimization operates on. - /// This is currently used to provide run-time hotness information with PGO. - Value *CodeRegion; - /// Arguments collected via the streaming interface. SmallVector Args; @@ -516,8 +472,71 @@ friend struct yaml::MappingTraits; }; +/// \brief Common features for diagnostics dealing with optimization remarks +/// that are used by IR passes. +class DiagnosticInfoIROptimization : public DiagnosticInfoOptimizationBase { +public: + /// \p PassName is the name of the pass emitting this diagnostic. \p + /// RemarkName is a textual identifier for the remark. \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 CodeRegion is IR + /// value (currently basic block) that the optimization operates on. This is + /// currently used to provide run-time hotness information with PGO. + DiagnosticInfoIROptimization(enum DiagnosticKind Kind, + enum DiagnosticSeverity Severity, + const char *PassName, StringRef RemarkName, + const Function &Fn, const DebugLoc &DLoc, + Value *CodeRegion = nullptr) + : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, RemarkName, Fn, + DLoc), + CodeRegion(CodeRegion) {} + + /// \brief This is ctor variant allows a pass to build an optimization remark + /// from an existing remark. + /// + /// This is useful when a transformation pass (e.g LV) wants to emit a remark + /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis + /// remark. The string \p Prepend will be emitted before the original + /// message. + DiagnosticInfoIROptimization(const char *PassName, StringRef Prepend, + const DiagnosticInfoIROptimization &Orig) + : DiagnosticInfoOptimizationBase( + (DiagnosticKind)Orig.getKind(), Orig.getSeverity(), PassName, + Orig.RemarkName, Orig.getFunction(), Orig.getDebugLoc()), + CodeRegion(Orig.getCodeRegion()) { + *this << Prepend; + std::copy(Orig.Args.begin(), Orig.Args.end(), std::back_inserter(Args)); + } + + /// Legacy interface. + /// \p PassName is the name of the pass emitting this diagnostic. + /// \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. + DiagnosticInfoIROptimization(enum DiagnosticKind Kind, + enum DiagnosticSeverity Severity, + const char *PassName, const Function &Fn, + const DebugLoc &DLoc, const Twine &Msg, + Optional Hotness = None) + : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, "", Fn, DLoc) { + setHotness(Hotness); + *this << Msg.str(); + } + + Value *getCodeRegion() const { return CodeRegion; } + +private: + /// The IR value (currently basic block) that the optimization operates on. + /// This is currently used to provide run-time hotness information with PGO. + Value *CodeRegion; +}; + /// Diagnostic information for applied optimization remarks. -class OptimizationRemark : public DiagnosticInfoOptimizationBase { +class OptimizationRemark : public DiagnosticInfoIROptimization { public: /// \p PassName is the name of the pass emitting this diagnostic. If /// this name matches the regular expression given in -Rpass=, then the @@ -530,8 +549,8 @@ OptimizationRemark(const char *PassName, const Function &Fn, const DebugLoc &DLoc, const Twine &Msg, Optional Hotness = None) - : DiagnosticInfoOptimizationBase(DK_OptimizationRemark, DS_Remark, - PassName, Fn, DLoc, Msg, Hotness) {} + : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName, + Fn, DLoc, Msg, Hotness) {} /// \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 @@ -555,7 +574,7 @@ }; /// Diagnostic information for missed-optimization remarks. -class OptimizationRemarkMissed : public DiagnosticInfoOptimizationBase { +class OptimizationRemarkMissed : public DiagnosticInfoIROptimization { 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 @@ -568,8 +587,8 @@ OptimizationRemarkMissed(const char *PassName, const Function &Fn, const DebugLoc &DLoc, const Twine &Msg, Optional Hotness = None) - : DiagnosticInfoOptimizationBase(DK_OptimizationRemarkMissed, DS_Remark, - PassName, Fn, DLoc, Msg, Hotness) {} + : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark, + PassName, Fn, DLoc, Msg, Hotness) {} /// \p PassName is the name of the pass emitting this diagnostic. If this name /// matches the regular expression given in -Rpass-missed=, then the @@ -593,7 +612,7 @@ }; /// Diagnostic information for optimization analysis remarks. -class OptimizationRemarkAnalysis : public DiagnosticInfoOptimizationBase { +class OptimizationRemarkAnalysis : public DiagnosticInfoIROptimization { public: /// \p PassName is the name of the pass emitting this diagnostic. If /// this name matches the regular expression given in -Rpass-analysis=, then @@ -606,8 +625,8 @@ OptimizationRemarkAnalysis(const char *PassName, const Function &Fn, const DebugLoc &DLoc, const Twine &Msg, Optional Hotness = None) - : DiagnosticInfoOptimizationBase(DK_OptimizationRemarkAnalysis, DS_Remark, - PassName, Fn, DLoc, Msg, Hotness) {} + : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark, + PassName, Fn, DLoc, Msg, Hotness) {} /// \p PassName is the name of the pass emitting this diagnostic. If this name /// matches the regular expression given in -Rpass-analysis=, then the @@ -626,7 +645,7 @@ /// message. OptimizationRemarkAnalysis(const char *PassName, StringRef Prepend, const OptimizationRemarkAnalysis &Orig) - : DiagnosticInfoOptimizationBase(PassName, Prepend, Orig) {} + : DiagnosticInfoIROptimization(PassName, Prepend, Orig) {} /// \brief Same as above but \p Inst is used to derive code region and debug /// location. @@ -648,8 +667,8 @@ OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName, const Function &Fn, const DebugLoc &DLoc, const Twine &Msg, Optional Hotness) - : DiagnosticInfoOptimizationBase(Kind, DS_Remark, PassName, Fn, DLoc, Msg, - Hotness) {} + : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, Fn, DLoc, Msg, + Hotness) {} OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName, StringRef RemarkName, const DebugLoc &DLoc, @@ -825,8 +844,7 @@ const Twine &Msg); /// Diagnostic information for optimization failures. -class DiagnosticInfoOptimizationFailure - : public DiagnosticInfoOptimizationBase { +class DiagnosticInfoOptimizationFailure : public DiagnosticInfoIROptimization { public: /// \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 @@ -836,8 +854,8 @@ /// of the diagnostic. DiagnosticInfoOptimizationFailure(const Function &Fn, const DebugLoc &DLoc, const Twine &Msg) - : DiagnosticInfoOptimizationBase(DK_OptimizationFailure, DS_Warning, - nullptr, Fn, DLoc, Msg) {} + : DiagnosticInfoIROptimization(DK_OptimizationFailure, DS_Warning, + nullptr, Fn, DLoc, Msg) {} static bool classof(const DiagnosticInfo *DI) { return DI->getKind() == DK_OptimizationFailure; Index: lib/Analysis/OptimizationDiagnosticInfo.cpp =================================================================== --- lib/Analysis/OptimizationDiagnosticInfo.cpp +++ lib/Analysis/OptimizationDiagnosticInfo.cpp @@ -139,18 +139,20 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(DiagnosticInfoOptimizationBase::Argument) void OptimizationRemarkEmitter::computeHotness( - DiagnosticInfoOptimizationBase &OptDiag) { + DiagnosticInfoIROptimization &OptDiag) { Value *V = OptDiag.getCodeRegion(); if (V) OptDiag.setHotness(computeHotness(V)); } -void OptimizationRemarkEmitter::emit(DiagnosticInfoOptimizationBase &OptDiag) { +void OptimizationRemarkEmitter::emit( + DiagnosticInfoOptimizationBase &OptDiagBase) { + auto &OptDiag = cast(OptDiagBase); computeHotness(OptDiag); yaml::Output *Out = F->getContext().getDiagnosticsOutputFile(); if (Out) { - auto *P = &const_cast(OptDiag); + auto *P = const_cast(&OptDiagBase); *Out << P; } // FIXME: now that IsVerbose is part of DI, filtering for this will be moved Index: lib/IR/DiagnosticInfo.cpp =================================================================== --- lib/IR/DiagnosticInfo.cpp +++ lib/IR/DiagnosticInfo.cpp @@ -212,16 +212,15 @@ OptimizationRemark::OptimizationRemark(const char *PassName, StringRef RemarkName, const DebugLoc &DLoc, Value *CodeRegion) - : DiagnosticInfoOptimizationBase( + : DiagnosticInfoIROptimization( DK_OptimizationRemark, DS_Remark, PassName, RemarkName, *cast(CodeRegion)->getParent(), DLoc, CodeRegion) {} OptimizationRemark::OptimizationRemark(const char *PassName, StringRef RemarkName, Instruction *Inst) - : DiagnosticInfoOptimizationBase(DK_OptimizationRemark, DS_Remark, PassName, - RemarkName, - *Inst->getParent()->getParent(), - Inst->getDebugLoc(), Inst->getParent()) {} + : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName, + RemarkName, *Inst->getParent()->getParent(), + Inst->getDebugLoc(), Inst->getParent()) {} bool OptimizationRemark::isEnabled() const { return PassRemarksOptLoc.Pattern && @@ -232,17 +231,17 @@ StringRef RemarkName, const DebugLoc &DLoc, Value *CodeRegion) - : DiagnosticInfoOptimizationBase( + : DiagnosticInfoIROptimization( DK_OptimizationRemarkMissed, DS_Remark, PassName, RemarkName, *cast(CodeRegion)->getParent(), DLoc, CodeRegion) {} OptimizationRemarkMissed::OptimizationRemarkMissed(const char *PassName, StringRef RemarkName, Instruction *Inst) - : DiagnosticInfoOptimizationBase(DK_OptimizationRemarkMissed, DS_Remark, - PassName, RemarkName, - *Inst->getParent()->getParent(), - Inst->getDebugLoc(), Inst->getParent()) {} + : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark, + PassName, RemarkName, + *Inst->getParent()->getParent(), + Inst->getDebugLoc(), Inst->getParent()) {} bool OptimizationRemarkMissed::isEnabled() const { return PassRemarksMissedOptLoc.Pattern && @@ -253,26 +252,26 @@ StringRef RemarkName, const DebugLoc &DLoc, Value *CodeRegion) - : DiagnosticInfoOptimizationBase( + : DiagnosticInfoIROptimization( DK_OptimizationRemarkAnalysis, DS_Remark, PassName, RemarkName, *cast(CodeRegion)->getParent(), DLoc, CodeRegion) {} OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName, Instruction *Inst) - : DiagnosticInfoOptimizationBase(DK_OptimizationRemarkAnalysis, DS_Remark, - PassName, RemarkName, - *Inst->getParent()->getParent(), - Inst->getDebugLoc(), Inst->getParent()) {} + : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark, + PassName, RemarkName, + *Inst->getParent()->getParent(), + Inst->getDebugLoc(), Inst->getParent()) {} OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName, StringRef RemarkName, const DebugLoc &DLoc, Value *CodeRegion) - : DiagnosticInfoOptimizationBase(Kind, DS_Remark, PassName, RemarkName, - *cast(CodeRegion)->getParent(), - DLoc, CodeRegion) {} + : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, RemarkName, + *cast(CodeRegion)->getParent(), + DLoc, CodeRegion) {} bool OptimizationRemarkAnalysis::isEnabled() const { return shouldAlwaysPrint() ||