Update clang to r339409b.
Change-Id: Ied8a188bb072c40035320acedc86164b66d920af
diff --git a/linux-x64/clang/include/llvm/XRay/BlockIndexer.h b/linux-x64/clang/include/llvm/XRay/BlockIndexer.h
new file mode 100644
index 0000000..46a7243
--- /dev/null
+++ b/linux-x64/clang/include/llvm/XRay/BlockIndexer.h
@@ -0,0 +1,67 @@
+//===- BlockIndexer.h - FDR Block Indexing Visitor ------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// An implementation of the RecordVisitor which generates a mapping between a
+// thread and a range of records representing a block.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIB_XRAY_BLOCKINDEXER_H_
+#define LLVM_LIB_XRAY_BLOCKINDEXER_H_
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/XRay/FDRRecords.h"
+#include <cstdint>
+#include <vector>
+
+namespace llvm {
+namespace xray {
+
+// The BlockIndexer will gather all related records associated with a
+// process+thread and group them by 'Block'.
+class BlockIndexer : public RecordVisitor {
+public:
+ struct Block {
+ uint64_t ProcessID;
+ int32_t ThreadID;
+ WallclockRecord *WallclockTime;
+ std::vector<Record *> Records;
+ };
+
+ // This maps the process + thread combination to a sequence of blocks.
+ using Index = DenseMap<std::pair<uint64_t, int32_t>, std::vector<Block>>;
+
+private:
+ Index &Indices;
+
+ Block CurrentBlock{0, 0, nullptr, {}};
+
+public:
+ explicit BlockIndexer(Index &I) : RecordVisitor(), Indices(I) {}
+
+ Error visit(BufferExtents &) override;
+ Error visit(WallclockRecord &) override;
+ Error visit(NewCPUIDRecord &) override;
+ Error visit(TSCWrapRecord &) override;
+ Error visit(CustomEventRecord &) override;
+ Error visit(CallArgRecord &) override;
+ Error visit(PIDRecord &) override;
+ Error visit(NewBufferRecord &) override;
+ Error visit(EndBufferRecord &) override;
+ Error visit(FunctionRecord &) override;
+
+ /// The flush() function will clear out the current state of the visitor, to
+ /// allow for explicitly flushing a block's records to the currently
+ /// recognized thread and process combination.
+ Error flush();
+};
+
+} // namespace xray
+} // namespace llvm
+
+#endif // LLVM_LIB_XRAY_BLOCKINDEXER_H_
diff --git a/linux-x64/clang/include/llvm/XRay/BlockPrinter.h b/linux-x64/clang/include/llvm/XRay/BlockPrinter.h
new file mode 100644
index 0000000..3a8f6e0
--- /dev/null
+++ b/linux-x64/clang/include/llvm/XRay/BlockPrinter.h
@@ -0,0 +1,60 @@
+//===- BlockPrinter.h - FDR Block Pretty Printer -------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// An implementation of the RecordVisitor which formats a block of records for
+// easier human consumption.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_INCLUDE_LLVM_XRAY_BLOCKPRINTER_H_
+#define LLVM_INCLUDE_LLVM_XRAY_BLOCKPRINTER_H_
+
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/XRay/FDRRecords.h"
+#include "llvm/XRay/RecordPrinter.h"
+
+namespace llvm {
+namespace xray {
+
+class BlockPrinter : public RecordVisitor {
+ enum class State {
+ Start,
+ Preamble,
+ Metadata,
+ Function,
+ Arg,
+ CustomEvent,
+ End,
+ };
+
+ raw_ostream &OS;
+ RecordPrinter &RP;
+ State CurrentState = State::Start;
+
+public:
+ explicit BlockPrinter(raw_ostream &O, RecordPrinter &P)
+ : RecordVisitor(), OS(O), RP(P) {}
+
+ Error visit(BufferExtents &) override;
+ Error visit(WallclockRecord &) override;
+ Error visit(NewCPUIDRecord &) override;
+ Error visit(TSCWrapRecord &) override;
+ Error visit(CustomEventRecord &) override;
+ Error visit(CallArgRecord &) override;
+ Error visit(PIDRecord &) override;
+ Error visit(NewBufferRecord &) override;
+ Error visit(EndBufferRecord &) override;
+ Error visit(FunctionRecord &) override;
+
+ void reset() { CurrentState = State::Start; }
+};
+
+} // namespace xray
+} // namespace llvm
+
+#endif // LLVM_INCLUDE_LLVM_XRAY_BLOCKPRINTER_H_
diff --git a/linux-x64/clang/include/llvm/XRay/BlockVerifier.h b/linux-x64/clang/include/llvm/XRay/BlockVerifier.h
new file mode 100644
index 0000000..b43a435
--- /dev/null
+++ b/linux-x64/clang/include/llvm/XRay/BlockVerifier.h
@@ -0,0 +1,69 @@
+//===- BlockVerifier.h - FDR Block Verifier -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// An implementation of the RecordVisitor which verifies a sequence of records
+// associated with a block, following the FDR mode log format's specifications.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_INCLUDE_LLVM_XRAY_BLOCKVERIFIER_H_
+#define LLVM_INCLUDE_LLVM_XRAY_BLOCKVERIFIER_H_
+
+#include "llvm/XRay/FDRRecords.h"
+#include <array>
+#include <bitset>
+
+namespace llvm {
+namespace xray {
+
+class BlockVerifier : public RecordVisitor {
+public:
+ // We force State elements to be size_t, to be used as indices for containers.
+ enum class State : std::size_t {
+ Unknown,
+ BufferExtents,
+ NewBuffer,
+ WallClockTime,
+ PIDEntry,
+ NewCPUId,
+ TSCWrap,
+ CustomEvent,
+ Function,
+ CallArg,
+ EndOfBuffer,
+ StateMax,
+ };
+
+private:
+ // We keep track of the current record seen by the verifier.
+ State CurrentRecord = State::Unknown;
+
+ // Transitions the current record to the new record, records an error on
+ // invalid transitions.
+ Error transition(State To);
+
+public:
+ Error visit(BufferExtents &) override;
+ Error visit(WallclockRecord &) override;
+ Error visit(NewCPUIDRecord &) override;
+ Error visit(TSCWrapRecord &) override;
+ Error visit(CustomEventRecord &) override;
+ Error visit(CallArgRecord &) override;
+ Error visit(PIDRecord &) override;
+ Error visit(NewBufferRecord &) override;
+ Error visit(EndBufferRecord &) override;
+ Error visit(FunctionRecord &) override;
+
+ Error verify();
+ void reset();
+};
+
+} // namespace xray
+} // namespace llvm
+
+#endif // LLVM_INCLUDE_LLVM_XRAY_BLOCKVERIFIER_H_
diff --git a/linux-x64/clang/include/llvm/XRay/FDRLogBuilder.h b/linux-x64/clang/include/llvm/XRay/FDRLogBuilder.h
new file mode 100644
index 0000000..b5e9ed5
--- /dev/null
+++ b/linux-x64/clang/include/llvm/XRay/FDRLogBuilder.h
@@ -0,0 +1,41 @@
+//===- FDRLogBuilder.h - XRay FDR Log Building Utility --------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_INCLUDE_LLVM_XRAY_FDRLOGBUILDER_H_
+#define LLVM_INCLUDE_LLVM_XRAY_FDRLOGBUILDER_H_
+
+#include "llvm/XRay/FDRRecords.h"
+
+namespace llvm {
+namespace xray {
+
+/// The LogBuilder class allows for creating ad-hoc collections of records
+/// through the `add<...>(...)` function. An example use of this API is in
+/// crafting arbitrary sequences of records:
+///
+/// auto Records = LogBuilder()
+/// .add<BufferExtents>(256)
+/// .add<NewBufferRecord>(1)
+/// .consume();
+///
+class LogBuilder {
+ std::vector<std::unique_ptr<Record>> Records;
+
+public:
+ template <class R, class... T> LogBuilder &add(T &&... A) {
+ Records.emplace_back(new R(std::forward<T>(A)...));
+ return *this;
+ }
+
+ std::vector<std::unique_ptr<Record>> consume() { return std::move(Records); }
+};
+
+} // namespace xray
+} // namespace llvm
+
+#endif // LLVM_INCLUDE_LLVM_XRAY_FDRLOGBUILDER_H_
diff --git a/linux-x64/clang/include/llvm/XRay/FDRRecordConsumer.h b/linux-x64/clang/include/llvm/XRay/FDRRecordConsumer.h
new file mode 100644
index 0000000..e856e15
--- /dev/null
+++ b/linux-x64/clang/include/llvm/XRay/FDRRecordConsumer.h
@@ -0,0 +1,55 @@
+//===- FDRRecordConsumer.h - XRay Flight Data Recorder Mode Records -------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_INCLUDE_LLVM_XRAY_FDRRECORDCONSUMER_H_
+#define LLVM_INCLUDE_LLVM_XRAY_FDRRECORDCONSUMER_H_
+
+#include "llvm/Support/Error.h"
+#include "llvm/XRay/FDRRecords.h"
+#include <algorithm>
+#include <memory>
+#include <vector>
+
+namespace llvm {
+namespace xray {
+
+class RecordConsumer {
+public:
+ virtual Error consume(std::unique_ptr<Record> R) = 0;
+ virtual ~RecordConsumer() = default;
+};
+
+// This consumer will collect all the records into a vector of records, in
+// arrival order.
+class LogBuilderConsumer : public RecordConsumer {
+ std::vector<std::unique_ptr<Record>> &Records;
+
+public:
+ explicit LogBuilderConsumer(std::vector<std::unique_ptr<Record>> &R)
+ : RecordConsumer(), Records(R) {}
+
+ Error consume(std::unique_ptr<Record> R) override;
+};
+
+// A PipelineConsumer applies a set of visitors to every consumed Record, in the
+// order by which the visitors are added to the pipeline in the order of
+// appearance.
+class PipelineConsumer : public RecordConsumer {
+ std::vector<RecordVisitor *> Visitors;
+
+public:
+ PipelineConsumer(std::initializer_list<RecordVisitor *> V)
+ : RecordConsumer(), Visitors(V) {}
+
+ Error consume(std::unique_ptr<Record> R) override;
+};
+
+} // namespace xray
+} // namespace llvm
+
+#endif // LLVM_INCLUDE_LLVM_XRAY_FDRRECORDCONSUMER_H_
diff --git a/linux-x64/clang/include/llvm/XRay/FDRRecordProducer.h b/linux-x64/clang/include/llvm/XRay/FDRRecordProducer.h
new file mode 100644
index 0000000..e67e228
--- /dev/null
+++ b/linux-x64/clang/include/llvm/XRay/FDRRecordProducer.h
@@ -0,0 +1,46 @@
+//===- FDRRecordProducer.h - XRay FDR Mode Record Producer ----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_INCLUDE_LLVM_XRAY_FDRRECORDPRODUCER_H_
+#define LLVM_INCLUDE_LLVM_XRAY_FDRRECORDPRODUCER_H_
+
+#include "llvm/Support/Error.h"
+#include "llvm/XRay/FDRRecords.h"
+#include "llvm/XRay/XRayRecord.h"
+#include <memory>
+
+namespace llvm {
+namespace xray {
+
+class RecordProducer {
+public:
+ /// All producer implementations must yield either an Error or a non-nullptr
+ /// unique_ptr<Record>.
+ virtual Expected<std::unique_ptr<Record>> produce() = 0;
+ virtual ~RecordProducer() = default;
+};
+
+class FileBasedRecordProducer : public RecordProducer {
+ const XRayFileHeader &Header;
+ DataExtractor &E;
+ uint32_t &OffsetPtr;
+
+public:
+ FileBasedRecordProducer(const XRayFileHeader &FH, DataExtractor &DE,
+ uint32_t &OP)
+ : Header(FH), E(DE), OffsetPtr(OP) {}
+
+ /// This producer encapsulates the logic for loading a File-backed
+ /// RecordProducer hidden behind a DataExtractor.
+ Expected<std::unique_ptr<Record>> produce() override;
+};
+
+} // namespace xray
+} // namespace llvm
+
+#endif // LLVM_INCLUDE_LLVM_XRAY_FDRRECORDPRODUCER_H_
diff --git a/linux-x64/clang/include/llvm/XRay/FDRRecords.h b/linux-x64/clang/include/llvm/XRay/FDRRecords.h
new file mode 100644
index 0000000..c524dab
--- /dev/null
+++ b/linux-x64/clang/include/llvm/XRay/FDRRecords.h
@@ -0,0 +1,295 @@
+//===- FDRRecords.h - XRay Flight Data Recorder Mode Records --------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Define types and operations on these types that represent the different kinds
+// of records we encounter in XRay flight data recorder mode traces.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIB_XRAY_FDRRECORDS_H_
+#define LLVM_LIB_XRAY_FDRRECORDS_H_
+
+#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/Error.h"
+#include "llvm/XRay/XRayRecord.h"
+#include <cstdint>
+
+namespace llvm {
+namespace xray {
+
+class RecordVisitor;
+class RecordInitializer;
+
+class Record {
+protected:
+ enum class Type {
+ Unknown,
+ Function,
+ Metadata,
+ };
+
+public:
+ Record(const Record &) = delete;
+ Record(Record &&) = delete;
+ Record &operator=(const Record &) = delete;
+ Record &operator=(Record &&) = delete;
+ Record() = default;
+
+ virtual Type type() const = 0;
+
+ // Each Record should be able to apply an abstract visitor, and choose the
+ // appropriate function in the visitor to invoke, given its own type.
+ virtual Error apply(RecordVisitor &V) = 0;
+
+ virtual ~Record() = default;
+};
+
+class MetadataRecord : public Record {
+protected:
+ static constexpr int kMetadataBodySize = 15;
+ friend class RecordInitializer;
+
+public:
+ enum class MetadataType : unsigned {
+ Unknown,
+ BufferExtents,
+ WallClockTime,
+ NewCPUId,
+ TSCWrap,
+ CustomEvent,
+ CallArg,
+ PIDEntry,
+ NewBuffer,
+ EndOfBuffer,
+ };
+
+ Type type() const override { return Type::Metadata; }
+
+ // All metadata records must know to provide the type of their open
+ // metadata record.
+ virtual MetadataType metadataType() const = 0;
+
+ virtual ~MetadataRecord() = default;
+};
+
+// What follows are specific Metadata record types which encapsulate the
+// information associated with specific metadata record types in an FDR mode
+// log.
+class BufferExtents : public MetadataRecord {
+ uint64_t Size = 0;
+ friend class RecordInitializer;
+
+public:
+ BufferExtents() = default;
+ explicit BufferExtents(uint64_t S) : MetadataRecord(), Size(S) {}
+
+ MetadataType metadataType() const override {
+ return MetadataType::BufferExtents;
+ }
+
+ uint64_t size() const { return Size; }
+
+ Error apply(RecordVisitor &V) override;
+};
+
+class WallclockRecord : public MetadataRecord {
+ uint64_t Seconds = 0;
+ uint32_t Nanos = 0;
+ friend class RecordInitializer;
+
+public:
+ WallclockRecord() = default;
+ explicit WallclockRecord(uint64_t S, uint32_t N)
+ : MetadataRecord(), Seconds(S), Nanos(N) {}
+
+ MetadataType metadataType() const override {
+ return MetadataType::WallClockTime;
+ }
+
+ uint64_t seconds() const { return Seconds; }
+ uint32_t nanos() const { return Nanos; }
+
+ Error apply(RecordVisitor &V) override;
+};
+
+class NewCPUIDRecord : public MetadataRecord {
+ uint16_t CPUId = 0;
+ uint64_t TSC = 0;
+ friend class RecordInitializer;
+
+public:
+ NewCPUIDRecord() = default;
+ NewCPUIDRecord(uint16_t C, uint64_t T) : MetadataRecord(), CPUId(C), TSC(T) {}
+
+ MetadataType metadataType() const override { return MetadataType::NewCPUId; }
+
+ uint16_t cpuid() const { return CPUId; }
+
+ uint64_t tsc() const { return TSC; }
+
+ Error apply(RecordVisitor &V) override;
+};
+
+class TSCWrapRecord : public MetadataRecord {
+ uint64_t BaseTSC = 0;
+ friend class RecordInitializer;
+
+public:
+ TSCWrapRecord() = default;
+ explicit TSCWrapRecord(uint64_t B) : MetadataRecord(), BaseTSC(B) {}
+
+ MetadataType metadataType() const override { return MetadataType::TSCWrap; }
+
+ uint64_t tsc() const { return BaseTSC; }
+
+ Error apply(RecordVisitor &V) override;
+};
+
+class CustomEventRecord : public MetadataRecord {
+ int32_t Size = 0;
+ uint64_t TSC = 0;
+ std::string Data{};
+ friend class RecordInitializer;
+
+public:
+ CustomEventRecord() = default;
+ explicit CustomEventRecord(uint64_t S, uint64_t T, std::string D)
+ : MetadataRecord(), Size(S), TSC(T), Data(std::move(D)) {}
+
+ MetadataType metadataType() const override {
+ return MetadataType::CustomEvent;
+ }
+
+ int32_t size() const { return Size; }
+ uint64_t tsc() const { return TSC; }
+ StringRef data() const { return Data; }
+
+ Error apply(RecordVisitor &V) override;
+};
+
+class CallArgRecord : public MetadataRecord {
+ uint64_t Arg;
+ friend class RecordInitializer;
+
+public:
+ CallArgRecord() = default;
+ explicit CallArgRecord(uint64_t A) : MetadataRecord(), Arg(A) {}
+
+ MetadataType metadataType() const override { return MetadataType::CallArg; }
+
+ uint64_t arg() const { return Arg; }
+
+ Error apply(RecordVisitor &V) override;
+};
+
+class PIDRecord : public MetadataRecord {
+ int32_t PID = 0;
+ friend class RecordInitializer;
+
+public:
+ PIDRecord() = default;
+ explicit PIDRecord(int32_t P) : MetadataRecord(), PID(P) {}
+
+ MetadataType metadataType() const override { return MetadataType::PIDEntry; }
+
+ int32_t pid() const { return PID; }
+
+ Error apply(RecordVisitor &V) override;
+};
+
+class NewBufferRecord : public MetadataRecord {
+ int32_t TID = 0;
+ friend class RecordInitializer;
+
+public:
+ NewBufferRecord() = default;
+ explicit NewBufferRecord(int32_t T) : MetadataRecord(), TID(T) {}
+
+ MetadataType metadataType() const override { return MetadataType::NewBuffer; }
+
+ int32_t tid() const { return TID; }
+
+ Error apply(RecordVisitor &V) override;
+};
+
+class EndBufferRecord : public MetadataRecord {
+public:
+ EndBufferRecord() = default;
+
+ MetadataType metadataType() const override {
+ return MetadataType::EndOfBuffer;
+ }
+
+ Error apply(RecordVisitor &V) override;
+};
+
+class FunctionRecord : public Record {
+ RecordTypes Kind;
+ int32_t FuncId;
+ uint32_t Delta;
+ friend class RecordInitializer;
+
+ static constexpr unsigned kFunctionRecordSize = 8;
+
+public:
+ FunctionRecord() = default;
+ explicit FunctionRecord(RecordTypes K, int32_t F, uint32_t D)
+ : Record(), Kind(K), FuncId(F), Delta(D) {}
+
+ Type type() const override { return Type::Function; }
+
+ // A function record is a concrete record type which has a number of common
+ // properties.
+ RecordTypes recordType() const { return Kind; }
+ int32_t functionId() const { return FuncId; }
+ uint32_t delta() const { return Delta; }
+
+ Error apply(RecordVisitor &V) override;
+};
+
+class RecordVisitor {
+public:
+ virtual ~RecordVisitor() = default;
+
+ // Support all specific kinds of records:
+ virtual Error visit(BufferExtents &) = 0;
+ virtual Error visit(WallclockRecord &) = 0;
+ virtual Error visit(NewCPUIDRecord &) = 0;
+ virtual Error visit(TSCWrapRecord &) = 0;
+ virtual Error visit(CustomEventRecord &) = 0;
+ virtual Error visit(CallArgRecord &) = 0;
+ virtual Error visit(PIDRecord &) = 0;
+ virtual Error visit(NewBufferRecord &) = 0;
+ virtual Error visit(EndBufferRecord &) = 0;
+ virtual Error visit(FunctionRecord &) = 0;
+};
+
+class RecordInitializer : public RecordVisitor {
+ DataExtractor &E;
+ uint32_t &OffsetPtr;
+
+public:
+ explicit RecordInitializer(DataExtractor &DE, uint32_t &OP)
+ : RecordVisitor(), E(DE), OffsetPtr(OP) {}
+
+ Error visit(BufferExtents &) override;
+ Error visit(WallclockRecord &) override;
+ Error visit(NewCPUIDRecord &) override;
+ Error visit(TSCWrapRecord &) override;
+ Error visit(CustomEventRecord &) override;
+ Error visit(CallArgRecord &) override;
+ Error visit(PIDRecord &) override;
+ Error visit(NewBufferRecord &) override;
+ Error visit(EndBufferRecord &) override;
+ Error visit(FunctionRecord &) override;
+};
+
+} // namespace xray
+} // namespace llvm
+
+#endif // LLVM_LIB_XRAY_FDRRECORDS_H_
diff --git a/linux-x64/clang/include/llvm/XRay/FDRTraceExpander.h b/linux-x64/clang/include/llvm/XRay/FDRTraceExpander.h
new file mode 100644
index 0000000..7f8236b
--- /dev/null
+++ b/linux-x64/clang/include/llvm/XRay/FDRTraceExpander.h
@@ -0,0 +1,61 @@
+//===- FDRTraceExpander.h - XRay FDR Mode Log Expander --------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// We define an FDR record visitor which can re-constitute XRayRecord instances
+// from a sequence of FDR mode records in arrival order into a collection.
+//
+//===----------------------------------------------------------------------===//
+#ifndef INCLUDE_LLVM_XRAY_FDRTRACEEXPANDER_H_
+#define INCLUDE_LLVM_XRAY_FDRTRACEEXPANDER_H_
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/XRay/FDRRecords.h"
+#include "llvm/XRay/XRayRecord.h"
+
+namespace llvm {
+namespace xray {
+
+class TraceExpander : public RecordVisitor {
+ // Type-erased callback for handling individual XRayRecord instances.
+ function_ref<void(const XRayRecord &)> C;
+ int32_t PID = 0;
+ int32_t TID = 0;
+ uint64_t BaseTSC = 0;
+ XRayRecord CurrentRecord{0, 0, RecordTypes::ENTER, 0, 0, 0, 0, {}};
+ uint16_t CPUId = 0;
+ uint16_t LogVersion = 0;
+ bool BuildingFunction = false;
+ bool IgnoringRecords = false;
+
+ void resetCurrentRecord();
+
+public:
+ explicit TraceExpander(function_ref<void(const XRayRecord &)> F, uint16_t L)
+ : RecordVisitor(), C(std::move(F)), LogVersion(L) {}
+
+ Error visit(BufferExtents &) override;
+ Error visit(WallclockRecord &) override;
+ Error visit(NewCPUIDRecord &) override;
+ Error visit(TSCWrapRecord &) override;
+ Error visit(CustomEventRecord &) override;
+ Error visit(CallArgRecord &) override;
+ Error visit(PIDRecord &) override;
+ Error visit(NewBufferRecord &) override;
+ Error visit(EndBufferRecord &) override;
+ Error visit(FunctionRecord &) override;
+
+ // Must be called after all the records have been processed, to handle the
+ // most recent record generated.
+ Error flush();
+};
+
+} // namespace xray
+} // namespace llvm
+
+#endif // INCLUDE_LLVM_XRAY_FDRTRACEEXPANDER_H_
diff --git a/linux-x64/clang/include/llvm/XRay/FDRTraceWriter.h b/linux-x64/clang/include/llvm/XRay/FDRTraceWriter.h
new file mode 100644
index 0000000..91488f8
--- /dev/null
+++ b/linux-x64/clang/include/llvm/XRay/FDRTraceWriter.h
@@ -0,0 +1,54 @@
+//===- FDRTraceWriter.h - XRay FDR Trace Writer -----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Test a utility that can write out XRay FDR Mode formatted trace files.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_INCLUDE_LLVM_XRAY_FDRTRACEWRITER_H_
+#define LLVM_INCLUDE_LLVM_XRAY_FDRTRACEWRITER_H_
+
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/EndianStream.h"
+#include "llvm/XRay/FDRRecords.h"
+#include "llvm/XRay/XRayRecord.h"
+
+namespace llvm {
+namespace xray {
+
+/// The FDRTraceWriter allows us to hand-craft an XRay Flight Data Recorder
+/// (FDR) mode log file. This is used primarily for testing, generating
+/// sequences of FDR records that can be read/processed. It can also be used to
+/// generate various kinds of execution traces without using the XRay runtime.
+/// Note that this writer does not do any validation, but uses the types of
+/// records defined in the FDRRecords.h file.
+class FDRTraceWriter : public RecordVisitor {
+public:
+ // Construct an FDRTraceWriter associated with an output stream.
+ explicit FDRTraceWriter(raw_ostream &O, const XRayFileHeader &H);
+ ~FDRTraceWriter();
+
+ Error visit(BufferExtents &) override;
+ Error visit(WallclockRecord &) override;
+ Error visit(NewCPUIDRecord &) override;
+ Error visit(TSCWrapRecord &) override;
+ Error visit(CustomEventRecord &) override;
+ Error visit(CallArgRecord &) override;
+ Error visit(PIDRecord &) override;
+ Error visit(NewBufferRecord &) override;
+ Error visit(EndBufferRecord &) override;
+ Error visit(FunctionRecord &) override;
+
+private:
+ support::endian::Writer OS;
+};
+
+} // namespace xray
+} // namespace llvm
+
+#endif // LLVM_INCLUDE_LLVM_XRAY_FDRTRACEWRITER_H_
diff --git a/linux-x64/clang/include/llvm/XRay/FileHeaderReader.h b/linux-x64/clang/include/llvm/XRay/FileHeaderReader.h
new file mode 100644
index 0000000..3b8809b
--- /dev/null
+++ b/linux-x64/clang/include/llvm/XRay/FileHeaderReader.h
@@ -0,0 +1,33 @@
+//===- FileHeaderReader.h - XRay Trace File Header Reading Function -------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares functions that can load an XRay log header from various
+// sources.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIB_XRAY_FILEHEADERREADER_H_
+#define LLVM_LIB_XRAY_FILEHEADERREADER_H_
+
+#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/Error.h"
+#include "llvm/XRay/XRayRecord.h"
+#include <cstdint>
+
+namespace llvm {
+namespace xray {
+
+/// Convenience function for loading the file header given a data extractor at a
+/// specified offset.
+Expected<XRayFileHeader> readBinaryFormatHeader(DataExtractor &HeaderExtractor,
+ uint32_t &OffsetPtr);
+
+} // namespace xray
+} // namespace llvm
+
+#endif // LLVM_LIB_XRAY_FILEHEADERREADER_H_
diff --git a/linux-x64/clang/include/llvm/XRay/Profile.h b/linux-x64/clang/include/llvm/XRay/Profile.h
new file mode 100644
index 0000000..9365630
--- /dev/null
+++ b/linux-x64/clang/include/llvm/XRay/Profile.h
@@ -0,0 +1,150 @@
+//===- Profile.h - XRay Profile Abstraction -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines the XRay Profile class representing the latency profile generated by
+// XRay's profiling mode.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_XRAY_PROFILE_H
+#define LLVM_XRAY_PROFILE_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+#include <list>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+namespace xray {
+
+class Profile;
+
+// We forward declare the Trace type for turning a Trace into a Profile.
+class Trace;
+
+/// This function will attempt to load an XRay Profiling Mode profile from the
+/// provided |Filename|.
+///
+/// For any errors encountered in the loading of the profile data from
+/// |Filename|, this function will return an Error condition appropriately.
+Expected<Profile> loadProfile(StringRef Filename);
+
+/// This algorithm will merge two Profile instances into a single Profile
+/// instance, aggregating blocks by Thread ID.
+Profile mergeProfilesByThread(const Profile &L, const Profile &R);
+
+/// This algorithm will merge two Profile instances into a single Profile
+/// instance, aggregating blocks by function call stack.
+Profile mergeProfilesByStack(const Profile &L, const Profile &R);
+
+/// This function takes a Trace and creates a Profile instance from it.
+Expected<Profile> profileFromTrace(const Trace &T);
+
+/// Profile instances are thread-compatible.
+class Profile {
+public:
+ using ThreadID = uint64_t;
+ using PathID = unsigned;
+ using FuncID = int32_t;
+
+ struct Data {
+ uint64_t CallCount;
+ uint64_t CumulativeLocalTime;
+ };
+
+ struct Block {
+ ThreadID Thread;
+ std::vector<std::pair<PathID, Data>> PathData;
+ };
+
+ /// Provides a sequence of function IDs from a previously interned PathID.
+ ///
+ /// Returns an error if |P| had not been interned before into the Profile.
+ ///
+ Expected<std::vector<FuncID>> expandPath(PathID P) const;
+
+ /// The stack represented in |P| must be in stack order (leaf to root). This
+ /// will always return the same PathID for |P| that has the same sequence.
+ PathID internPath(ArrayRef<FuncID> P);
+
+ /// Appends a fully-formed Block instance into the Profile.
+ ///
+ /// Returns an error condition in the following cases:
+ ///
+ /// - The PathData component of the Block is empty
+ ///
+ Error addBlock(Block &&B);
+
+ Profile() = default;
+ ~Profile() = default;
+
+ Profile(Profile &&O) noexcept
+ : Blocks(std::move(O.Blocks)), NodeStorage(std::move(O.NodeStorage)),
+ Roots(std::move(O.Roots)), PathIDMap(std::move(O.PathIDMap)),
+ NextID(O.NextID) {}
+
+ Profile &operator=(Profile &&O) noexcept {
+ Blocks = std::move(O.Blocks);
+ NodeStorage = std::move(O.NodeStorage);
+ Roots = std::move(O.Roots);
+ PathIDMap = std::move(O.PathIDMap);
+ NextID = O.NextID;
+ return *this;
+ }
+
+ Profile(const Profile &);
+ Profile &operator=(const Profile &);
+
+ friend void swap(Profile &L, Profile &R) {
+ using std::swap;
+ swap(L.Blocks, R.Blocks);
+ swap(L.NodeStorage, R.NodeStorage);
+ swap(L.Roots, R.Roots);
+ swap(L.PathIDMap, R.PathIDMap);
+ swap(L.NextID, R.NextID);
+ }
+
+private:
+ using BlockList = std::list<Block>;
+
+ struct TrieNode {
+ FuncID Func = 0;
+ std::vector<TrieNode *> Callees{};
+ TrieNode *Caller = nullptr;
+ PathID ID = 0;
+ };
+
+ // List of blocks associated with a Profile.
+ BlockList Blocks;
+
+ // List of TrieNode elements we've seen.
+ std::list<TrieNode> NodeStorage;
+
+ // List of call stack roots.
+ SmallVector<TrieNode *, 4> Roots;
+
+ // Reverse mapping between a PathID to a TrieNode*.
+ DenseMap<PathID, TrieNode *> PathIDMap;
+
+ // Used to identify paths.
+ PathID NextID = 1;
+
+public:
+ using const_iterator = BlockList::const_iterator;
+ const_iterator begin() const { return Blocks.begin(); }
+ const_iterator end() const { return Blocks.end(); }
+ bool empty() const { return Blocks.empty(); }
+};
+
+} // namespace xray
+} // namespace llvm
+
+#endif
diff --git a/linux-x64/clang/include/llvm/XRay/RecordPrinter.h b/linux-x64/clang/include/llvm/XRay/RecordPrinter.h
new file mode 100644
index 0000000..bad1a57
--- /dev/null
+++ b/linux-x64/clang/include/llvm/XRay/RecordPrinter.h
@@ -0,0 +1,48 @@
+//===- RecordPrinter.h - FDR Record Printer -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// An implementation of the RecordVisitor which prints an individual record's
+// data in an adhoc format, suitable for human inspection.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_INCLUDE_LLVM_XRAY_RECORDPRINTER_H_
+#define LLVM_INCLUDE_LLVM_XRAY_RECORDPRINTER_H_
+
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/XRay/FDRRecords.h"
+
+namespace llvm {
+namespace xray {
+
+class RecordPrinter : public RecordVisitor {
+ raw_ostream &OS;
+ std::string Delim;
+
+public:
+ explicit RecordPrinter(raw_ostream &O, std::string D)
+ : RecordVisitor(), OS(O), Delim(std::move(D)) {}
+
+ explicit RecordPrinter(raw_ostream &O) : RecordPrinter(O, ""){};
+
+ Error visit(BufferExtents &) override;
+ Error visit(WallclockRecord &) override;
+ Error visit(NewCPUIDRecord &) override;
+ Error visit(TSCWrapRecord &) override;
+ Error visit(CustomEventRecord &) override;
+ Error visit(CallArgRecord &) override;
+ Error visit(PIDRecord &) override;
+ Error visit(NewBufferRecord &) override;
+ Error visit(EndBufferRecord &) override;
+ Error visit(FunctionRecord &) override;
+};
+
+} // namespace xray
+} // namespace llvm
+
+#endif // LLVM_INCLUDE_LLVM_XRAY_RECORDPRINTER_H
diff --git a/linux-x64/clang/include/llvm/XRay/Trace.h b/linux-x64/clang/include/llvm/XRay/Trace.h
index 6b033d6..924addd 100644
--- a/linux-x64/clang/include/llvm/XRay/Trace.h
+++ b/linux-x64/clang/include/llvm/XRay/Trace.h
@@ -17,8 +17,8 @@
#include <vector>
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Error.h"
-#include "llvm/Support/FileSystem.h"
#include "llvm/XRay/XRayRecord.h"
namespace llvm {
@@ -46,25 +46,35 @@
///
class Trace {
XRayFileHeader FileHeader;
- std::vector<XRayRecord> Records;
+ using RecordVector = std::vector<XRayRecord>;
+ RecordVector Records;
typedef std::vector<XRayRecord>::const_iterator citerator;
- friend Expected<Trace> loadTraceFile(StringRef, bool);
+ friend Expected<Trace> loadTrace(const DataExtractor &, bool);
public:
+ using size_type = RecordVector::size_type;
+ using value_type = RecordVector::value_type;
+ using const_iterator = RecordVector::const_iterator;
+
/// Provides access to the loaded XRay trace file header.
const XRayFileHeader &getFileHeader() const { return FileHeader; }
- citerator begin() const { return Records.begin(); }
- citerator end() const { return Records.end(); }
- size_t size() const { return Records.size(); }
+ const_iterator begin() const { return Records.begin(); }
+ const_iterator end() const { return Records.end(); }
+ bool empty() const { return Records.empty(); }
+ size_type size() const { return Records.size(); }
};
/// This function will attempt to load XRay trace records from the provided
/// |Filename|.
Expected<Trace> loadTraceFile(StringRef Filename, bool Sort = false);
+/// This function will attempt to load XRay trace records from the provided
+/// DataExtractor.
+Expected<Trace> loadTrace(const DataExtractor &Extractor, bool Sort = false);
+
} // namespace xray
} // namespace llvm