summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrancis Visoiu Mistrih <francisvm@yahoo.com>2019-03-06 14:32:08 +0000
committerFrancis Visoiu Mistrih <francisvm@yahoo.com>2019-03-06 14:32:08 +0000
commit9052f50cb4c927fd316bb41b17a950d182c9b945 (patch)
treef9a7d882186ba715e0b4a2478d9099c6c26f758e
parent1bdc2d1874e7035f86e5b9e3d3a6b005f27b8224 (diff)
downloadbcm5719-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.cpp5
-rw-r--r--llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h4
-rw-r--r--llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h14
-rw-r--r--llvm/include/llvm/IR/LLVMContext.h33
-rw-r--r--llvm/include/llvm/IR/RemarkStreamer.h44
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp1
-rw-r--r--llvm/lib/IR/CMakeLists.txt1
-rw-r--r--llvm/lib/IR/DiagnosticInfo.cpp1
-rw-r--r--llvm/lib/IR/LLVMContext.cpp26
-rw-r--r--llvm/lib/IR/LLVMContextImpl.h3
-rw-r--r--llvm/lib/IR/RemarkStreamer.cpp28
-rw-r--r--llvm/lib/LTO/LTO.cpp5
-rw-r--r--llvm/tools/llc/llc.cpp5
-rw-r--r--llvm/tools/opt/opt.cpp5
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...
OpenPOWER on IntegriCloud