diff options
-rw-r--r-- | llvm/include/llvm/IR/RemarkStreamer.h | 22 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 13 | ||||
-rw-r--r-- | llvm/lib/IR/RemarkStreamer.cpp | 46 |
3 files changed, 62 insertions, 19 deletions
diff --git a/llvm/include/llvm/IR/RemarkStreamer.h b/llvm/include/llvm/IR/RemarkStreamer.h index 7b2fc95d15e..2abf6f99cb0 100644 --- a/llvm/include/llvm/IR/RemarkStreamer.h +++ b/llvm/include/llvm/IR/RemarkStreamer.h @@ -25,12 +25,12 @@ namespace llvm { /// Streamer for remarks. class RemarkStreamer { - /// The filename that the remark diagnostics are emitted to. - const std::string Filename; /// The regex used to filter remarks based on the passes that emit them. Optional<Regex> PassFilter; /// The object used to serialize the remarks to a specific format. std::unique_ptr<remarks::RemarkSerializer> RemarkSerializer; + /// The filename that the remark diagnostics are emitted to. + const Optional<std::string> Filename; /// Convert diagnostics into remark objects. /// The lifetime of the members of the result is bound to the lifetime of @@ -38,10 +38,12 @@ class RemarkStreamer { remarks::Remark toRemark(const DiagnosticInfoOptimizationBase &Diag); public: - RemarkStreamer(StringRef Filename, - std::unique_ptr<remarks::RemarkSerializer> RemarkSerializer); + RemarkStreamer(std::unique_ptr<remarks::RemarkSerializer> RemarkSerializer, + Optional<StringRef> Filename = None); /// Return the filename that the remark diagnostics are emitted to. - StringRef getFilename() const { return Filename; } + Optional<StringRef> getFilename() const { + return Filename ? Optional<StringRef>(*Filename) : None; + } /// Return stream that the remark diagnostics are emitted to. raw_ostream &getStream() { return RemarkSerializer->OS; } /// Return the serializer used for this stream. @@ -84,13 +86,21 @@ struct RemarkSetupFormatError : RemarkSetupErrorInfo<RemarkSetupFormatError> { using RemarkSetupErrorInfo<RemarkSetupFormatError>::RemarkSetupErrorInfo; }; -/// Setup optimization remarks. +/// Setup optimization remarks that output to a file. Expected<std::unique_ptr<ToolOutputFile>> setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses, StringRef RemarksFormat, bool RemarksWithHotness, unsigned RemarksHotnessThreshold = 0); +/// Setup optimization remarks that output directly to a raw_ostream. +/// \p OS is managed by the caller and should be open for writing as long as \p +/// Context is streaming remarks to it. +Error setupOptimizationRemarks(LLVMContext &Context, raw_ostream &OS, + StringRef RemarksPasses, StringRef RemarksFormat, + bool RemarksWithHotness, + unsigned RemarksHotnessThreshold = 0); + } // 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 ca223f78c16..20c50bb8a2a 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1349,15 +1349,18 @@ void AsmPrinter::emitRemarksSection(Module &M) { return; remarks::RemarkSerializer &RemarkSerializer = RS->getSerializer(); - StringRef FilenameRef = RS->getFilename(); - SmallString<128> Filename = FilenameRef; - sys::fs::make_absolute(Filename); - assert(!Filename.empty() && "The filename can't be empty."); + Optional<SmallString<128>> Filename; + if (Optional<StringRef> FilenameRef = RS->getFilename()) { + Filename = *FilenameRef; + sys::fs::make_absolute(*Filename); + assert(!Filename->empty() && "The filename can't be empty."); + } std::string Buf; raw_string_ostream OS(Buf); std::unique_ptr<remarks::MetaSerializer> MetaSerializer = - RemarkSerializer.metaSerializer(OS, StringRef(Filename)); + Filename ? RemarkSerializer.metaSerializer(OS, StringRef(*Filename)) + : RemarkSerializer.metaSerializer(OS); MetaSerializer->emit(); // Switch to the right section: .remarks/__remarks. diff --git a/llvm/lib/IR/RemarkStreamer.cpp b/llvm/lib/IR/RemarkStreamer.cpp index 73387ecbac1..8a70862de72 100644 --- a/llvm/lib/IR/RemarkStreamer.cpp +++ b/llvm/lib/IR/RemarkStreamer.cpp @@ -22,12 +22,10 @@ using namespace llvm; RemarkStreamer::RemarkStreamer( - StringRef Filename, - std::unique_ptr<remarks::RemarkSerializer> RemarkSerializer) - : Filename(Filename), PassFilter(), - RemarkSerializer(std::move(RemarkSerializer)) { - assert(!Filename.empty() && "This needs to be a real filename."); -} + std::unique_ptr<remarks::RemarkSerializer> RemarkSerializer, + Optional<StringRef> FilenameIn) + : PassFilter(), RemarkSerializer(std::move(RemarkSerializer)), + Filename(FilenameIn ? Optional<std::string>(FilenameIn->str()) : None) {} Error RemarkStreamer::setFilter(StringRef Filter) { Regex R = Regex(Filter); @@ -137,12 +135,13 @@ llvm::setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, return make_error<RemarkSetupFormatError>(std::move(E)); Expected<std::unique_ptr<remarks::RemarkSerializer>> RemarkSerializer = - remarks::createRemarkSerializer(*Format, remarks::SerializerMode::Separate, RemarksFile->os()); + remarks::createRemarkSerializer( + *Format, remarks::SerializerMode::Separate, RemarksFile->os()); if (Error E = RemarkSerializer.takeError()) return make_error<RemarkSetupFormatError>(std::move(E)); Context.setRemarkStreamer(std::make_unique<RemarkStreamer>( - RemarksFilename, std::move(*RemarkSerializer))); + std::move(*RemarkSerializer), RemarksFilename)); if (!RemarksPasses.empty()) if (Error E = Context.getRemarkStreamer()->setFilter(RemarksPasses)) @@ -150,3 +149,34 @@ llvm::setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, return std::move(RemarksFile); } + +Error llvm::setupOptimizationRemarks(LLVMContext &Context, raw_ostream &OS, + StringRef RemarksPasses, + StringRef RemarksFormat, + bool RemarksWithHotness, + unsigned RemarksHotnessThreshold) { + if (RemarksWithHotness) + Context.setDiagnosticsHotnessRequested(true); + + if (RemarksHotnessThreshold) + Context.setDiagnosticsHotnessThreshold(RemarksHotnessThreshold); + + Expected<remarks::Format> Format = remarks::parseFormat(RemarksFormat); + if (Error E = Format.takeError()) + return make_error<RemarkSetupFormatError>(std::move(E)); + + Expected<std::unique_ptr<remarks::RemarkSerializer>> RemarkSerializer = + remarks::createRemarkSerializer(*Format, + remarks::SerializerMode::Separate, OS); + if (Error E = RemarkSerializer.takeError()) + return make_error<RemarkSetupFormatError>(std::move(E)); + + Context.setRemarkStreamer( + std::make_unique<RemarkStreamer>(std::move(*RemarkSerializer))); + + if (!RemarksPasses.empty()) + if (Error E = Context.getRemarkStreamer()->setFilter(RemarksPasses)) + return make_error<RemarkSetupPatternError>(std::move(E)); + + return Error::success(); +} |