summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-xray/xray-fdr-dump.cpp
diff options
context:
space:
mode:
authorDean Michael Berris <dberris@google.com>2018-09-11 00:22:53 +0000
committerDean Michael Berris <dberris@google.com>2018-09-11 00:22:53 +0000
commitdd01efc56d7ef3a335aad3d9cfe1b53d0f8524f8 (patch)
treebe83aca2997754fe96526d349cae1cf858baade2 /llvm/tools/llvm-xray/xray-fdr-dump.cpp
parentcec7d3a055ede1655707c1c3a0b6fcc69c1569cf (diff)
downloadbcm5719-llvm-dd01efc56d7ef3a335aad3d9cfe1b53d0f8524f8.tar.gz
bcm5719-llvm-dd01efc56d7ef3a335aad3d9cfe1b53d0f8524f8.zip
[XRay] Add the `llvm-xray fdr-dump` implementation
Summary: In this change, we implement a `BlockPrinter` which orders records in a Block that's been indexed by the `BlockIndexer`. This is used in the `llvm-xray fdr-dump` tool which ties together the various types and utilities we've been working on, to allow for inspection of XRay FDR mode traces both with and without verification. This change is the final step of the refactoring of D50441. Reviewers: mboerger, eizan Subscribers: mgorny, hiraditya, llvm-commits Differential Revision: https://reviews.llvm.org/D51846 llvm-svn: 341887
Diffstat (limited to 'llvm/tools/llvm-xray/xray-fdr-dump.cpp')
-rw-r--r--llvm/tools/llvm-xray/xray-fdr-dump.cpp119
1 files changed, 119 insertions, 0 deletions
diff --git a/llvm/tools/llvm-xray/xray-fdr-dump.cpp b/llvm/tools/llvm-xray/xray-fdr-dump.cpp
new file mode 100644
index 00000000000..389825605b6
--- /dev/null
+++ b/llvm/tools/llvm-xray/xray-fdr-dump.cpp
@@ -0,0 +1,119 @@
+//===- xray-fdr-dump.cpp: XRay FDR Trace Dump Tool ------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implements the FDR trace dumping tool, using the libraries for handling FDR
+// mode traces specifically.
+//
+//===----------------------------------------------------------------------===//
+#include "xray-registry.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/XRay/BlockIndexer.h"
+#include "llvm/XRay/BlockPrinter.h"
+#include "llvm/XRay/BlockVerifier.h"
+#include "llvm/XRay/FDRRecordConsumer.h"
+#include "llvm/XRay/FDRRecordProducer.h"
+#include "llvm/XRay/FDRRecords.h"
+#include "llvm/XRay/FileHeaderReader.h"
+#include "llvm/XRay/RecordPrinter.h"
+
+using namespace llvm;
+using namespace xray;
+
+static cl::SubCommand Dump("fdr-dump", "FDR Trace Dump");
+static cl::opt<std::string> DumpInput(cl::Positional,
+ cl::desc("<xray fdr mode log>"),
+ cl::Required, cl::sub(Dump));
+static cl::opt<bool> DumpVerify("verify",
+ cl::desc("verify structure of the log"),
+ cl::init(false), cl::sub(Dump));
+
+static CommandRegistration Unused(&Dump, []() -> Error {
+ // Open the file provided.
+ int Fd;
+ if (auto EC = sys::fs::openFileForRead(DumpInput, Fd))
+ return createStringError(EC, "Cannot open file '%s' for read.",
+ DumpInput.c_str());
+
+ uint64_t FileSize;
+ if (auto EC = sys::fs::file_size(DumpInput, FileSize))
+ return createStringError(EC, "Failed to get file size for '%s'.",
+ DumpInput.c_str());
+
+ std::error_code EC;
+ sys::fs::mapped_file_region MappedFile(
+ Fd, sys::fs::mapped_file_region::mapmode::readonly, FileSize, 0, EC);
+
+ DataExtractor DE(StringRef(MappedFile.data(), MappedFile.size()), true, 8);
+ uint32_t OffsetPtr = 0;
+
+ auto FileHeaderOrError = readBinaryFormatHeader(DE, OffsetPtr);
+ if (!FileHeaderOrError)
+ return FileHeaderOrError.takeError();
+ auto &H = FileHeaderOrError.get();
+
+ FileBasedRecordProducer P(H, DE, OffsetPtr);
+
+ RecordPrinter RP(outs(), "\n");
+ if (!DumpVerify) {
+ PipelineConsumer C({&RP});
+ while (DE.isValidOffsetForDataOfSize(OffsetPtr, 1)) {
+ auto R = P.produce();
+ if (!R)
+ return R.takeError();
+ if (auto E = C.consume(std::move(R.get())))
+ return E;
+ }
+ return Error::success();
+ }
+
+ BlockPrinter BP(outs(), RP);
+ std::vector<std::unique_ptr<Record>> Records;
+ LogBuilderConsumer C(Records);
+ while (DE.isValidOffsetForDataOfSize(OffsetPtr, 1)) {
+ auto R = P.produce();
+ if (!R) {
+ // Print records we've found so far.
+ for (auto &Ptr : Records)
+ if (auto E = Ptr->apply(RP))
+ return joinErrors(std::move(E), R.takeError());
+ return R.takeError();
+ }
+ if (auto E = C.consume(std::move(R.get())))
+ return E;
+ }
+
+ // Once we have a trace, we then index the blocks.
+ BlockIndexer::Index Index;
+ BlockIndexer BI(Index);
+ for (auto &Ptr : Records)
+ if (auto E = Ptr->apply(BI))
+ return E;
+
+ if (auto E = BI.flush())
+ return E;
+
+ // Then we validate while printing each block.
+ BlockVerifier BV;
+ for (auto ProcessThreadBlocks : Index) {
+ auto &Blocks = ProcessThreadBlocks.second;
+ for (auto &B : Blocks) {
+ for (auto *R : B.Records) {
+ if (auto E = R->apply(BV))
+ return E;
+ if (auto E = R->apply(BP))
+ return E;
+ }
+ BV.reset();
+ BP.reset();
+ }
+ }
+ outs().flush();
+ return Error::success();
+});
OpenPOWER on IntegriCloud