Index: include/llvm/Analysis/OptimizationDiagnosticInfo.h =================================================================== --- include/llvm/Analysis/OptimizationDiagnosticInfo.h +++ include/llvm/Analysis/OptimizationDiagnosticInfo.h @@ -68,7 +68,10 @@ FunctionAnalysisManager::Invalidator &Inv); /// The new interface to emit remarks. - void emit(DiagnosticInfoOptimizationBase &OptDiag); + /// + /// This takes a ...CommonBase rather than a ...Base because that is what + /// operator<< returns. + void emit(DiagnosticInfoOptimizationCommonBase &OptDiag); /// Emit an optimization-applied message. /// Index: include/llvm/IR/DiagnosticInfo.h =================================================================== --- include/llvm/IR/DiagnosticInfo.h +++ include/llvm/IR/DiagnosticInfo.h @@ -376,8 +376,10 @@ DebugLoc DLoc; }; -/// Common features for diagnostics dealing with optimization remarks. -class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithDebugLocBase { +/// \brief Common features for diagnostics dealing with optimization remarks +/// that are used by both IR and MIR passes. +class DiagnosticInfoOptimizationCommonBase + : public DiagnosticInfoWithDebugLocBase { public: /// \brief Used to set IsVerbose via the stream interface. struct setIsVerbose {}; @@ -408,57 +410,19 @@ /// 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. - DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind, - enum DiagnosticSeverity Severity, - const char *PassName, StringRef RemarkName, - const Function &Fn, const DebugLoc &DLoc, - Value *CodeRegion = nullptr) + /// diagnostic will include the source code location. + DiagnosticInfoOptimizationCommonBase(enum DiagnosticKind Kind, + enum DiagnosticSeverity Severity, + const char *PassName, + StringRef RemarkName, const Function &Fn, + const DebugLoc &DLoc) : DiagnosticInfoWithDebugLocBase(Kind, Severity, Fn, DLoc), - PassName(PassName), RemarkName(RemarkName), CodeRegion(CodeRegion) {} + PassName(PassName), RemarkName(RemarkName) {} - /// \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) - : DiagnosticInfoWithDebugLocBase(Kind, Severity, Fn, DLoc), - PassName(PassName), Hotness(Hotness) { - Args.push_back(Argument(Msg.str())); - } - - DiagnosticInfoOptimizationBase &operator<<(StringRef S); - DiagnosticInfoOptimizationBase &operator<<(Argument A); - DiagnosticInfoOptimizationBase &operator<<(setIsVerbose V); - DiagnosticInfoOptimizationBase &operator<<(setExtraArgs EA); + DiagnosticInfoOptimizationCommonBase &operator<<(StringRef S); + DiagnosticInfoOptimizationCommonBase &operator<<(Argument A); + DiagnosticInfoOptimizationCommonBase &operator<<(setIsVerbose V); + DiagnosticInfoOptimizationCommonBase &operator<<(setExtraArgs EA); /// \see DiagnosticInfo::print. void print(DiagnosticPrinter &DP) const override; @@ -475,8 +439,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 +446,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 +460,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; @@ -513,7 +471,72 @@ /// output. int FirstExtraArgIndex = -1; - friend struct yaml::MappingTraits; + friend struct yaml::MappingTraits; +}; + +/// \brief Common features for diagnostics dealing with optimization remarks +/// that are used IR passes. +class DiagnosticInfoOptimizationBase + : public DiagnosticInfoOptimizationCommonBase { +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. + DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind, + enum DiagnosticSeverity Severity, + const char *PassName, StringRef RemarkName, + const Function &Fn, const DebugLoc &DLoc, + Value *CodeRegion = nullptr) + : DiagnosticInfoOptimizationCommonBase(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. + DiagnosticInfoOptimizationBase(const char *PassName, StringRef Prepend, + const DiagnosticInfoOptimizationBase &Orig) + : DiagnosticInfoOptimizationCommonBase( + (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. + DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind, + enum DiagnosticSeverity Severity, + const char *PassName, const Function &Fn, + const DebugLoc &DLoc, const Twine &Msg, + Optional Hotness = None) + : DiagnosticInfoOptimizationCommonBase(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. Index: lib/Analysis/OptimizationDiagnosticInfo.cpp =================================================================== --- lib/Analysis/OptimizationDiagnosticInfo.cpp +++ lib/Analysis/OptimizationDiagnosticInfo.cpp @@ -67,8 +67,8 @@ namespace llvm { namespace yaml { -template <> struct MappingTraits { - static void mapping(IO &io, DiagnosticInfoOptimizationBase *&OptDiag) { +template <> struct MappingTraits { + static void mapping(IO &io, DiagnosticInfoOptimizationCommonBase *&OptDiag) { assert(io.outputting() && "input not yet implemented"); if (io.mapTag("!Passed", OptDiag->getKind() == DK_OptimizationRemark)) @@ -124,8 +124,10 @@ }; // Implement this as a mapping for now to get proper quotation for the value. -template <> struct MappingTraits { - static void mapping(IO &io, DiagnosticInfoOptimizationBase::Argument &A) { +template <> +struct MappingTraits { + static void mapping(IO &io, + DiagnosticInfoOptimizationCommonBase::Argument &A) { assert(io.outputting() && "input not yet implemented"); io.mapRequired(A.Key.data(), A.Val); if (A.DLoc) @@ -136,7 +138,7 @@ } // end namespace yaml } // end namespace llvm -LLVM_YAML_IS_SEQUENCE_VECTOR(DiagnosticInfoOptimizationBase::Argument) +LLVM_YAML_IS_SEQUENCE_VECTOR(DiagnosticInfoOptimizationCommonBase::Argument) void OptimizationRemarkEmitter::computeHotness( DiagnosticInfoOptimizationBase &OptDiag) { @@ -145,18 +147,21 @@ OptDiag.setHotness(computeHotness(V)); } -void OptimizationRemarkEmitter::emit(DiagnosticInfoOptimizationBase &OptDiag) { - computeHotness(OptDiag); +void OptimizationRemarkEmitter::emit( + DiagnosticInfoOptimizationCommonBase &OptDiagCommon) { + auto *OptDiag = cast(&OptDiagCommon); + computeHotness(*OptDiag); yaml::Output *Out = F->getContext().getDiagnosticsOutputFile(); if (Out) { - auto *P = &const_cast(OptDiag); + auto *P = + const_cast(&OptDiagCommon); *Out << P; } // FIXME: now that IsVerbose is part of DI, filtering for this will be moved // from here to clang. - if (!OptDiag.isVerbose() || shouldEmitVerbose()) - F->getContext().diagnose(OptDiag); + if (!OptDiag->isVerbose() || shouldEmitVerbose()) + F->getContext().diagnose(*OptDiag); } void OptimizationRemarkEmitter::emitOptimizationRemark(const char *PassName, Index: lib/IR/DiagnosticInfo.cpp =================================================================== --- lib/IR/DiagnosticInfo.cpp +++ lib/IR/DiagnosticInfo.cpp @@ -171,7 +171,8 @@ return (Filename + ":" + Twine(Line) + ":" + Twine(Column)).str(); } -DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, Value *V) +DiagnosticInfoOptimizationCommonBase::Argument::Argument(StringRef Key, + Value *V) : Key(Key) { if (auto *F = dyn_cast(V)) { if (DISubprogram *SP = F->getSubprogram()) @@ -191,19 +192,20 @@ Val = I->getOpcodeName(); } -DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, Type *T) +DiagnosticInfoOptimizationCommonBase::Argument::Argument(StringRef Key, Type *T) : Key(Key) { raw_string_ostream OS(Val); OS << *T; } -DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, int N) +DiagnosticInfoOptimizationCommonBase::Argument::Argument(StringRef Key, int N) : Key(Key), Val(itostr(N)) {} -DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, unsigned N) +DiagnosticInfoOptimizationCommonBase::Argument::Argument(StringRef Key, + unsigned N) : Key(Key), Val(utostr(N)) {} -void DiagnosticInfoOptimizationBase::print(DiagnosticPrinter &DP) const { +void DiagnosticInfoOptimizationCommonBase::print(DiagnosticPrinter &DP) const { DP << getLocationStr() << ": " << getMsg(); if (Hotness) DP << " (hotness: " << *Hotness << ")"; @@ -352,37 +354,37 @@ DP << "Instruction selection used fallback path for " << getFunction(); } -DiagnosticInfoOptimizationBase &DiagnosticInfoOptimizationBase:: +DiagnosticInfoOptimizationCommonBase &DiagnosticInfoOptimizationCommonBase:: operator<<(StringRef S) { Args.emplace_back(S); return *this; } -DiagnosticInfoOptimizationBase &DiagnosticInfoOptimizationBase:: +DiagnosticInfoOptimizationCommonBase &DiagnosticInfoOptimizationCommonBase:: operator<<(Argument A) { Args.push_back(std::move(A)); return *this; } -DiagnosticInfoOptimizationBase &DiagnosticInfoOptimizationBase:: +DiagnosticInfoOptimizationCommonBase &DiagnosticInfoOptimizationCommonBase:: operator<<(setIsVerbose V) { IsVerbose = true; return *this; } -DiagnosticInfoOptimizationBase &DiagnosticInfoOptimizationBase:: +DiagnosticInfoOptimizationCommonBase &DiagnosticInfoOptimizationCommonBase:: operator<<(setExtraArgs EA) { FirstExtraArgIndex = Args.size(); return *this; } -std::string DiagnosticInfoOptimizationBase::getMsg() const { +std::string DiagnosticInfoOptimizationCommonBase::getMsg() const { std::string Str; raw_string_ostream OS(Str); - for (const DiagnosticInfoOptimizationBase::Argument &Arg : - make_range(Args.begin(), FirstExtraArgIndex == -1 - ? Args.end() - : Args.begin() + FirstExtraArgIndex)) + for (const DiagnosticInfoOptimizationCommonBase::Argument &Arg : + make_range(Args.begin(), + FirstExtraArgIndex == -1 ? Args.end() + : Args.begin() + FirstExtraArgIndex)) OS << Arg.Val; return OS.str(); } Index: lib/IR/LLVMContext.cpp =================================================================== --- lib/IR/LLVMContext.cpp +++ lib/IR/LLVMContext.cpp @@ -172,7 +172,7 @@ // pattern, passed via one of the -pass-remarks* flags, matches the name of // the pass that is emitting the diagnostic. If there is no match, ignore the // diagnostic and return. - if (auto *Remark = dyn_cast(&DI)) + if (auto *Remark = dyn_cast(&DI)) return Remark->isEnabled(); return true;