diff options
author | Francis Visoiu Mistrih <francisvm@yahoo.com> | 2019-03-06 14:32:08 +0000 |
---|---|---|
committer | Francis Visoiu Mistrih <francisvm@yahoo.com> | 2019-03-06 14:32:08 +0000 |
commit | 9052f50cb4c927fd316bb41b17a950d182c9b945 (patch) | |
tree | f9a7d882186ba715e0b4a2478d9099c6c26f758e | |
parent | 1bdc2d1874e7035f86e5b9e3d3a6b005f27b8224 (diff) | |
download | bcm5719-llvm-9052f50cb4c927fd316bb41b17a950d182c9b945.tar.gz bcm5719-llvm-9052f50cb4c927fd316bb41b17a950d182c9b945.zip |
[Remarks] Refactor remark diagnostic emission in a RemarkStreamer
This allows us to store more info about where we're emitting the remarks
without cluttering LLVMContext. This is needed for future support for
the remark section.
Differential Revision: https://reviews.llvm.org/D58996
llvm-svn: 355507
-rw-r--r-- | clang/lib/CodeGen/CodeGenAction.cpp | 5 | ||||
-rw-r--r-- | llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h | 4 | ||||
-rw-r--r-- | llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h | 14 | ||||
-rw-r--r-- | llvm/include/llvm/IR/LLVMContext.h | 33 | ||||
-rw-r--r-- | llvm/include/llvm/IR/RemarkStreamer.h | 44 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/IR/CMakeLists.txt | 1 | ||||
-rw-r--r-- | llvm/lib/IR/DiagnosticInfo.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/IR/LLVMContext.cpp | 26 | ||||
-rw-r--r-- | llvm/lib/IR/LLVMContextImpl.h | 3 | ||||
-rw-r--r-- | llvm/lib/IR/RemarkStreamer.cpp | 28 | ||||
-rw-r--r-- | llvm/lib/LTO/LTO.cpp | 5 | ||||
-rw-r--r-- | llvm/tools/llc/llc.cpp | 5 | ||||
-rw-r--r-- | llvm/tools/opt/opt.cpp | 5 |
14 files changed, 131 insertions, 44 deletions
diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp index 0b631f72e6e..f59adcd3fb9 100644 --- a/clang/lib/CodeGen/CodeGenAction.cpp +++ b/clang/lib/CodeGen/CodeGenAction.cpp @@ -30,6 +30,7 @@ #include "llvm/IR/GlobalValue.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" +#include "llvm/IR/RemarkStreamer.h" #include "llvm/IRReader/IRReader.h" #include "llvm/Linker/Linker.h" #include "llvm/Pass.h" @@ -276,8 +277,8 @@ namespace clang { return; } - Ctx.setDiagnosticsOutputFile( - llvm::make_unique<yaml::Output>(OptRecordFile->os())); + Ctx.setRemarkStreamer(llvm::make_unique<RemarkStreamer>( + CodeGenOpts.OptRecordFile, OptRecordFile->os())); if (CodeGenOpts.getProfileUse() != CodeGenOptions::ProfileNone) Ctx.setDiagnosticsHotnessRequested(true); diff --git a/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h b/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h index a2b29555ce5..7b8404404ce 100644 --- a/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h +++ b/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h @@ -77,7 +77,7 @@ public: // remarks enabled. We can't currently check whether remarks are requested // for the calling pass since that requires actually building the remark. - if (F->getContext().getDiagnosticsOutputFile() || + if (F->getContext().getRemarkStreamer() || F->getContext().getDiagHandlerPtr()->isAnyRemarkEnabled()) { auto R = RemarkBuilder(); emit((DiagnosticInfoOptimizationBase &)R); @@ -92,7 +92,7 @@ public: /// provide more context so that non-trivial false positives can be quickly /// detected by the user. bool allowExtraAnalysis(StringRef PassName) const { - return (F->getContext().getDiagnosticsOutputFile() || + return (F->getContext().getRemarkStreamer() || F->getContext().getDiagHandlerPtr()->isAnyRemarkEnabled(PassName)); } diff --git a/llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h b/llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h index 9a0fd562536..a461a299917 100644 --- a/llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h +++ b/llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h @@ -158,9 +158,10 @@ public: /// (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(StringRef PassName) const { - return (MF.getFunction().getContext().getDiagnosticsOutputFile() || - MF.getFunction().getContext() - .getDiagHandlerPtr()->isAnyRemarkEnabled(PassName)); + return ( + MF.getFunction().getContext().getRemarkStreamer() || + MF.getFunction().getContext().getDiagHandlerPtr()->isAnyRemarkEnabled( + PassName)); } /// Take a lambda that returns a remark which will be emitted. Second @@ -171,8 +172,11 @@ public: // remarks enabled. We can't currently check whether remarks are requested // for the calling pass since that requires actually building the remark. - if (MF.getFunction().getContext().getDiagnosticsOutputFile() || - MF.getFunction().getContext().getDiagHandlerPtr()->isAnyRemarkEnabled()) { + if (MF.getFunction().getContext().getRemarkStreamer() || + MF.getFunction() + .getContext() + .getDiagHandlerPtr() + ->isAnyRemarkEnabled()) { auto R = RemarkBuilder(); emit((DiagnosticInfoOptimizationBase &)R); } diff --git a/llvm/include/llvm/IR/LLVMContext.h b/llvm/include/llvm/IR/LLVMContext.h index f28480ee4c6..f737801fffb 100644 --- a/llvm/include/llvm/IR/LLVMContext.h +++ b/llvm/include/llvm/IR/LLVMContext.h @@ -35,12 +35,8 @@ template <typename T> class SmallVectorImpl; class SMDiagnostic; class StringRef; class Twine; - -namespace yaml { - -class Output; - -} // end namespace yaml +class RemarkStreamer; +class raw_ostream; namespace SyncScope { @@ -246,16 +242,23 @@ public: /// included in optimization diagnostics. void setDiagnosticsHotnessThreshold(uint64_t Threshold); - /// Return the YAML file used by the backend to save optimization - /// diagnostics. If null, diagnostics are not saved in a file but only - /// emitted via the diagnostic handler. - yaml::Output *getDiagnosticsOutputFile(); - /// Set the diagnostics output file used for optimization diagnostics. + /// Return the streamer used by the backend to save remark diagnostics. If it + /// does not exist, diagnostics are not saved in a file but only emitted via + /// the diagnostic handler. + RemarkStreamer *getRemarkStreamer(); + const RemarkStreamer *getRemarkStreamer() const; + + /// Set the diagnostics output used for optimization diagnostics. + /// This filename may be embedded in a section for tools to find the + /// diagnostics whenever they're needed. + /// + /// If a remark streamer is already set, it will be replaced with + /// \p RemarkStreamer. /// - /// By default or if invoked with null, diagnostics are not saved in a file - /// but only emitted via the diagnostic handler. Even if an output file is - /// set, the handler is invoked for each diagnostic message. - void setDiagnosticsOutputFile(std::unique_ptr<yaml::Output> F); + /// By default, diagnostics are not saved in a file but only emitted via the + /// diagnostic handler. Even if an output file is set, the handler is invoked + /// for each diagnostic message. + void setRemarkStreamer(std::unique_ptr<RemarkStreamer> RemarkStreamer); /// Get the prefix that should be printed in front of a diagnostic of /// the given \p Severity diff --git a/llvm/include/llvm/IR/RemarkStreamer.h b/llvm/include/llvm/IR/RemarkStreamer.h new file mode 100644 index 00000000000..38baa2b3b4b --- /dev/null +++ b/llvm/include/llvm/IR/RemarkStreamer.h @@ -0,0 +1,44 @@ +//===- llvm/IR/RemarkStreamer.h - Remark Streamer ---------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file declares the main interface for outputting remarks. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_IR_REMARKSTREAMER_H +#define LLVM_IR_REMARKSTREAMER_H + +#include "llvm/IR/DiagnosticInfo.h" +#include "llvm/Support/YAMLTraits.h" +#include "llvm/Support/raw_ostream.h" +#include <string> +#include <vector> + +namespace llvm { +/// Streamer for remarks. +class RemarkStreamer { + /// The filename that the remark diagnostics are emitted to. + const std::string Filename; + /// The open raw_ostream that the remark diagnostics are emitted to. + raw_ostream &OS; + + /// The YAML streamer. + yaml::Output YAMLOutput; + +public: + RemarkStreamer(StringRef Filename, raw_ostream& OS); + /// Return the filename that the remark diagnostics are emitted to. + StringRef getFilename() const { return Filename; } + /// Return stream that the remark diagnostics are emitted to. + raw_ostream &getStream() { return OS; } + /// Emit a diagnostic through the streamer. + void emit(const DiagnosticInfoOptimizationBase &Diag); +}; +} // end namespace llvm + +#endif // LLVM_IR_REMARKSTREAMER_H diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 5319519ddc0..7d95c4d7be7 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -78,6 +78,7 @@ #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" #include "llvm/IR/Operator.h" +#include "llvm/IR/RemarkStreamer.h" #include "llvm/IR/Type.h" #include "llvm/IR/Value.h" #include "llvm/MC/MCAsmInfo.h" diff --git a/llvm/lib/IR/CMakeLists.txt b/llvm/lib/IR/CMakeLists.txt index 2ea01b8a767..b1293194800 100644 --- a/llvm/lib/IR/CMakeLists.txt +++ b/llvm/lib/IR/CMakeLists.txt @@ -46,6 +46,7 @@ add_llvm_library(LLVMCore PassManager.cpp PassRegistry.cpp PassTimingInfo.cpp + RemarkStreamer.cpp SafepointIRVerifier.cpp ProfileSummary.cpp Statepoint.cpp diff --git a/llvm/lib/IR/DiagnosticInfo.cpp b/llvm/lib/IR/DiagnosticInfo.cpp index 14bee35dc29..020305d76cb 100644 --- a/llvm/lib/IR/DiagnosticInfo.cpp +++ b/llvm/lib/IR/DiagnosticInfo.cpp @@ -27,6 +27,7 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" +#include "llvm/IR/RemarkStreamer.h" #include "llvm/IR/Type.h" #include "llvm/IR/Value.h" #include "llvm/Support/Casting.h" diff --git a/llvm/lib/IR/LLVMContext.cpp b/llvm/lib/IR/LLVMContext.cpp index 1cea21461f4..75d0218bcc8 100644 --- a/llvm/lib/IR/LLVMContext.cpp +++ b/llvm/lib/IR/LLVMContext.cpp @@ -21,6 +21,7 @@ #include "llvm/IR/DiagnosticPrinter.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" +#include "llvm/IR/RemarkStreamer.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" @@ -160,12 +161,15 @@ uint64_t LLVMContext::getDiagnosticsHotnessThreshold() const { return pImpl->DiagnosticsHotnessThreshold; } -yaml::Output *LLVMContext::getDiagnosticsOutputFile() { - return pImpl->DiagnosticsOutputFile.get(); +RemarkStreamer *LLVMContext::getRemarkStreamer() { + return pImpl->RemarkStreamer.get(); } - -void LLVMContext::setDiagnosticsOutputFile(std::unique_ptr<yaml::Output> F) { - pImpl->DiagnosticsOutputFile = std::move(F); +const RemarkStreamer *LLVMContext::getRemarkStreamer() const { + return const_cast<LLVMContext *>(this)->getRemarkStreamer(); +} +void LLVMContext::setRemarkStreamer( + std::unique_ptr<RemarkStreamer> RemarkStreamer) { + pImpl->RemarkStreamer = std::move(RemarkStreamer); } DiagnosticHandler::DiagnosticHandlerTy @@ -228,14 +232,10 @@ LLVMContext::getDiagnosticMessagePrefix(DiagnosticSeverity Severity) { } void LLVMContext::diagnose(const DiagnosticInfo &DI) { - if (auto *OptDiagBase = dyn_cast<DiagnosticInfoOptimizationBase>(&DI)) { - yaml::Output *Out = getDiagnosticsOutputFile(); - if (Out) { - // For remarks the << operator takes a reference to a pointer. - auto *P = const_cast<DiagnosticInfoOptimizationBase *>(OptDiagBase); - *Out << P; - } - } + if (auto *OptDiagBase = dyn_cast<DiagnosticInfoOptimizationBase>(&DI)) + if (RemarkStreamer *RS = getRemarkStreamer()) + RS->emit(*OptDiagBase); + // If there is a report handler, use it. if (pImpl->DiagHandler && (!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI)) && diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index f7038ace035..b8974ef9767 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -37,6 +37,7 @@ #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" +#include "llvm/IR/RemarkStreamer.h" #include "llvm/IR/TrackingMDRef.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Casting.h" @@ -1226,7 +1227,7 @@ public: bool RespectDiagnosticFilters = false; bool DiagnosticsHotnessRequested = false; uint64_t DiagnosticsHotnessThreshold = 0; - std::unique_ptr<yaml::Output> DiagnosticsOutputFile; + std::unique_ptr<RemarkStreamer> RemarkStreamer; LLVMContext::YieldCallbackTy YieldCallback = nullptr; void *YieldOpaqueHandle = nullptr; diff --git a/llvm/lib/IR/RemarkStreamer.cpp b/llvm/lib/IR/RemarkStreamer.cpp new file mode 100644 index 00000000000..0b983408e46 --- /dev/null +++ b/llvm/lib/IR/RemarkStreamer.cpp @@ -0,0 +1,28 @@ +//===- llvm/IR/RemarkStreamer.cpp - Remark Streamer -*- C++ -------------*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the implementation of the remark outputting as part of +// LLVMContext. +// +//===----------------------------------------------------------------------===// + +#include "llvm/IR/RemarkStreamer.h" + +using namespace llvm; + +RemarkStreamer::RemarkStreamer(StringRef Filename, raw_ostream &OS) + : Filename(Filename), OS(OS), + YAMLOutput(OS, reinterpret_cast<void *>(this)) { + assert(!Filename.empty() && "This needs to be a real filename."); +} + +void RemarkStreamer::emit(const DiagnosticInfoOptimizationBase &Diag) { + DiagnosticInfoOptimizationBase *DiagPtr = + const_cast<DiagnosticInfoOptimizationBase *>(&Diag); + YAMLOutput << DiagPtr; +} diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp index 8e0d532fa7e..f6e34c5d061 100644 --- a/llvm/lib/LTO/LTO.cpp +++ b/llvm/lib/LTO/LTO.cpp @@ -24,6 +24,7 @@ #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Mangler.h" #include "llvm/IR/Metadata.h" +#include "llvm/IR/RemarkStreamer.h" #include "llvm/LTO/LTOBackend.h" #include "llvm/LTO/SummaryBasedOptimizations.h" #include "llvm/Linker/IRMover.h" @@ -1326,8 +1327,8 @@ lto::setupOptimizationRemarks(LLVMContext &Context, llvm::make_unique<ToolOutputFile>(Filename, EC, sys::fs::F_None); if (EC) return errorCodeToError(EC); - Context.setDiagnosticsOutputFile( - llvm::make_unique<yaml::Output>(DiagnosticFile->os())); + Context.setRemarkStreamer( + llvm::make_unique<RemarkStreamer>(Filename, DiagnosticFile->os())); DiagnosticFile->keep(); return std::move(DiagnosticFile); } diff --git a/llvm/tools/llc/llc.cpp b/llvm/tools/llc/llc.cpp index ae51eef9e9c..a566d15cd81 100644 --- a/llvm/tools/llc/llc.cpp +++ b/llvm/tools/llc/llc.cpp @@ -31,6 +31,7 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" +#include "llvm/IR/RemarkStreamer.h" #include "llvm/IR/Verifier.h" #include "llvm/IRReader/IRReader.h" #include "llvm/MC/SubtargetFeature.h" @@ -333,8 +334,8 @@ int main(int argc, char **argv) { WithColor::error(errs(), argv[0]) << EC.message() << '\n'; return 1; } - Context.setDiagnosticsOutputFile( - llvm::make_unique<yaml::Output>(YamlFile->os())); + Context.setRemarkStreamer( + llvm::make_unique<RemarkStreamer>(RemarksFilename, YamlFile->os())); } if (InputLanguage != "" && InputLanguage != "ir" && diff --git a/llvm/tools/opt/opt.cpp b/llvm/tools/opt/opt.cpp index 2d80b479735..06745b0cca0 100644 --- a/llvm/tools/opt/opt.cpp +++ b/llvm/tools/opt/opt.cpp @@ -33,6 +33,7 @@ #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/LegacyPassNameParser.h" #include "llvm/IR/Module.h" +#include "llvm/IR/RemarkStreamer.h" #include "llvm/IR/Verifier.h" #include "llvm/IRReader/IRReader.h" #include "llvm/InitializePasses.h" @@ -563,8 +564,8 @@ int main(int argc, char **argv) { errs() << EC.message() << '\n'; return 1; } - Context.setDiagnosticsOutputFile( - llvm::make_unique<yaml::Output>(OptRemarkFile->os())); + Context.setRemarkStreamer(llvm::make_unique<RemarkStreamer>( + RemarksFilename, OptRemarkFile->os())); } // Load the input module... |