Index: test/tools/llvm-xray/X86/account-deduce-tail-call.yaml
===================================================================
--- /dev/null
+++ test/tools/llvm-xray/X86/account-deduce-tail-call.yaml
@@ -0,0 +1,36 @@
+#RUN: llvm-xray account %s -i=yaml -o - -m %S/Inputs/simple-instrmap.yaml -t yaml -d | FileCheck %s
+---
+header:
+  version: 1
+  type: 0
+  constant-tsc: true
+  nonstop-tsc: true
+  cycle-frequency: 0
+records:
+# Here we reconstruct the following call trace:
+#
+#   f1()
+#     f2()
+#       f3()
+#
+# But we find that we're missing an exit record for f2() because it's
+# tail-called f3(). We make sure that if we see a trace like this that we can
+# deduce tail calls, and account the time (potentially wrongly) to f2() when
+# f1() exits. That is because we don't go back to f3()'s entry record to
+# properly do the math on the timing of f2().
+#
+# Note that by default, tail/sibling call deduction is disabled, and is enabled
+# with a flag "-d" or "-deduce-sibling-calls".
+#
+  - { type: 0, func-id: 1, cpu: 1, thread: 111, kind: function-enter, tsc: 10000 }
+  - { type: 0, func-id: 2, cpu: 1, thread: 111, kind: function-enter, tsc: 10001 }
+  - { type: 0, func-id: 3, cpu: 1, thread: 111, kind: function-enter, tsc: 10002 }
+  - { type: 0, func-id: 3, cpu: 1, thread: 111, kind: function-exit,  tsc: 10003 }
+  - { type: 0, func-id: 1, cpu: 1, thread: 111, kind: function-exit,  tsc: 10004 }
+...
+
+#CHECK:       Functions with latencies: 3
+#CHECK-NEXT:  funcid  count  [min, median, 90%ile, 99%ile, max] debug function
+#CHECK-NEXT:  1 1 [4.{{.*}}, 4.{{.*}}, 4.{{.*}}, 4.{{.*}}, 4.{{.*}}] {{.*}} {{.*}}
+#CHECK-NEXT:  2 1 [3.{{.*}}, 3.{{.*}}, 3.{{.*}}, 3.{{.*}}, 3.{{.*}}] {{.*}} {{.*}}
+#CHECK-NEXT:  3 1 [1.{{.*}}, 1.{{.*}}, 1.{{.*}}, 1.{{.*}}, 1.{{.*}}] {{.*}} {{.*}}
Index: test/tools/llvm-xray/X86/account-simple-case.yaml
===================================================================
--- /dev/null
+++ test/tools/llvm-xray/X86/account-simple-case.yaml
@@ -0,0 +1,18 @@
+#RUN: llvm-xray account %s -i=yaml -o - -m %S/Inputs/simple-instrmap.yaml -t yaml | FileCheck %s
+---
+header:
+  version: 1
+  type: 0
+  constant-tsc: true
+  nonstop-tsc: true
+  cycle-frequency: 2601000000
+records:
+  - { type: 0, func-id: 1, cpu: 1, thread: 111, kind: function-enter,
+    tsc: 10001 }
+  - { type: 0, func-id: 1, cpu: 1, thread: 111, kind: function-exit,
+    tsc: 10100 }
+...
+
+#CHECK:       Functions with latencies: 1
+#CHECK-NEXT:  funcid  count  [min, median, 90%ile, 99%ile, max] debug function
+#CHECK-NEXT:  1 1 [{{.*}}, {{.*}}, {{.*}}, {{.*}}, {{.*}}] {{.*}} {{.*}}
Index: tools/llvm-xray/CMakeLists.txt
===================================================================
--- tools/llvm-xray/CMakeLists.txt
+++ tools/llvm-xray/CMakeLists.txt
@@ -7,6 +7,7 @@
 
 set(LLVM_XRAY_TOOLS
   func-id-helper.cc
+  xray-account.cc
   xray-converter.cc
   xray-extract.cc
   xray-log-reader.cc)
Index: tools/llvm-xray/func-id-helper.h
===================================================================
--- tools/llvm-xray/func-id-helper.h
+++ tools/llvm-xray/func-id-helper.h
@@ -10,8 +10,8 @@
 // Defines helper tools dealing with XRay-generated function ids.
 //
 //===----------------------------------------------------------------------===//
-#ifndef FUNC_ID_HELPER_H_
-#define FUNC_ID_HELPER_H_
+#ifndef LLVM_TOOLS_LLVM_XRAY_FUNC_ID_HELPER_H
+#define LLVM_TOOLS_LLVM_XRAY_FUNC_ID_HELPER_H
 
 #include "llvm/DebugInfo/Symbolize/Symbolize.h"
 #include <unordered_map>
@@ -48,4 +48,4 @@
 } // namespace xray
 } // namespace llvm
 
-#endif // FUNC_ID_HELPER_H_
+#endif // LLVM_TOOLS_LLVM_XRAY_FUNC_ID_HELPER_H
Index: tools/llvm-xray/llvm-xray.cc
===================================================================
--- tools/llvm-xray/llvm-xray.cc
+++ tools/llvm-xray/llvm-xray.cc
@@ -18,6 +18,7 @@
 //
 
 #include "func-id-helper.h"
+#include "xray-account.h"
 #include "xray-converter.h"
 #include "xray-extract.h"
 #include "xray-log-reader.h"
@@ -58,7 +59,68 @@
 static cl::alias ExtractFormat2("f", cl::desc("Alias for -format"),
                                 cl::aliasopt(ExtractFormat), cl::sub(Extract));
 
-// llvm-xray convert
+// llvm-xray account
+// ----------------------------------------------------------------------------
+static cl::SubCommand Account("account", "Function call accounting");
+static cl::opt<std::string> AccountInput(cl::Positional,
+                                         cl::desc("<xray log file>"),
+                                         cl::Required, cl::sub(Account));
+static cl::opt<bool>
+    AccountKeepGoing("keep_going", cl::desc("Keep going on errors encountered"),
+                     cl::sub(Account), cl::init(false));
+static cl::alias AccountKeepGoing2("k", cl::aliasopt(AccountKeepGoing),
+                                   cl::desc("Alias for -keep_going"),
+                                   cl::sub(Account));
+static cl::opt<bool> AccountDeduceSiblingCalls(
+    "deduce-sibling-calls",
+    cl::desc("Deduce sibling calls when unrolling function call stacks"),
+    cl::sub(Account), cl::init(false));
+static cl::alias
+    AccountDeduceSiblingCalls2("d", cl::aliasopt(AccountDeduceSiblingCalls),
+                               cl::desc("Alias for -deduce_sibling_calls"),
+                               cl::sub(Account));
+static cl::opt<std::string>
+    AccountOutput("output", cl::value_desc("output file"), cl::init("-"),
+                  cl::desc("output file; use '-' for stdout"),
+                  cl::sub(Account));
+static cl::alias AccountOutput2("o", cl::aliasopt(AccountOutput),
+                                cl::desc("Alias for -output"),
+                                cl::sub(Account));
+enum class AccountOutputFormats { TEXT, CSV };
+static cl::opt<AccountOutputFormats>
+    AccountOutputFormat("format", cl::desc("output format"),
+                        cl::values(clEnumValN(AccountOutputFormats::TEXT,
+                                              "text", "report stats in text"),
+                                   clEnumValN(AccountOutputFormats::CSV, "csv",
+                                              "report stats in csv"),
+                                   clEnumValEnd),
+                        cl::sub(Account));
+static cl::alias AccountOutputFormat2("f", cl::desc("Alias of -format"),
+                                      cl::aliasopt(AccountOutputFormat),
+                                      cl::sub(Account));
+enum class AccountInputFormats { RAW, YAML };
+static cl::opt<AccountInputFormats> AccountInputFormat(
+    "input-format", cl::desc("input format"),
+    cl::values(clEnumValN(AccountInputFormats::RAW, "binary",
+                          "input in binary"),
+               clEnumValN(AccountInputFormats::YAML, "yaml", "input in yaml"),
+               clEnumValEnd),
+    cl::sub(Account));
+static cl::alias AccountInputFormat2("i", cl::desc("Alias for -input-format"),
+                                     cl::aliasopt(AccountInputFormat),
+                                     cl::sub(Account));
+
+static cl::opt<std::string>
+    AccountInstrMap("instr_map",
+                    cl::desc("binary with the instrumentation map, or "
+                             "a separate instrumentation map"),
+                    cl::value_desc("binary with xray_instr_map"),
+                    cl::sub(Account), cl::init(""));
+static cl::alias AccountInstrMap2("m", cl::aliasopt(AccountInstrMap),
+                                  cl::desc("Alias for -instr_map"),
+                                  cl::sub(Account));
+
+// llvm-xray dump
 // ----------------------------------------------------------------------------
 static cl::SubCommand Convert("convert", "Trace Format Conversion");
 static cl::opt<std::string> ConvertInput(cl::Positional,
@@ -159,6 +221,111 @@
     return 0;
   }
 
+  if (Account) {
+    int Fd;
+    auto EC = sys::fs::openFileForRead(AccountInput, Fd);
+    if (EC) {
+      errs() << "Cannot open file '" << AccountInput << "' for reading.\n";
+      return 1;
+    }
+    raw_fd_ostream OS(AccountOutput, EC, sys::fs::OpenFlags::F_Text);
+    if (EC) {
+      errs() << "Cannot open file '" << AccountOutput << "' for writing.\n";
+      return 1;
+    }
+    xray::InstrumentationMapExtractor Extractor(AccountInstrMap, InstrMapFormat,
+                                                EC);
+    if (EC) {
+      errs() << "Cannot load instrumentation map from '" << AccountInstrMap
+             << "'\n";
+      if (!AccountKeepGoing)
+        return 1;
+    }
+    const auto &FunctionAddresses = Extractor.getFunctionAddresses();
+    symbolize::LLVMSymbolizer::Options Opts(
+        symbolize::FunctionNameKind::LinkageName, true, true, false, "");
+    symbolize::LLVMSymbolizer Symbolizer(Opts);
+    llvm::xray::FuncIdConversionHelper FuncIdHelper(AccountInstrMap, Symbolizer,
+                                                    FunctionAddresses);
+    xray::LatencyAccountant FCA(FuncIdHelper, AccountDeduceSiblingCalls);
+    const llvm::xray::XRayFileHeader *Header = nullptr;
+    switch (AccountInputFormat) {
+    case AccountInputFormats::RAW: {
+      xray::NaiveLogReader LogReader(Fd, EC);
+      if (EC) {
+        errs() << "Errors reading file '" << AccountInput << "'.\n";
+        return 1;
+      }
+      if (LogReader.getFileHeader().Version != 1) {
+        errs() << "Unsupported XRay file version: "
+               << LogReader.getFileHeader().Version << '\n';
+        return 1;
+      }
+      Header = &LogReader.getFileHeader();
+      for (const auto &Record : LogReader) {
+        if (!FCA.accountRecord(Record)) {
+          for (const auto &ThreadStack : FCA.getPerThreadFunctionStack()) {
+            errs() << "Thread ID: " << ThreadStack.first << "\n";
+            auto Level = ThreadStack.second.size();
+            for (const auto &Entry : llvm::reverse(ThreadStack.second)) {
+              errs() << "#" << Level-- << "\t"
+                     << FuncIdHelper.SymbolOrNumber(Entry.first) << '\n';
+            }
+          }
+          if (!AccountKeepGoing) {
+            errs() << "Failed accounting function calls in file '"
+                   << AccountInput << "'.\n";
+            return 1;
+          }
+        }
+      }
+      break;
+    }
+    case AccountInputFormats::YAML: {
+      xray::YAMLLogReader LogReader(Fd, EC);
+      if (EC) {
+        errs() << "Errors reading file '" << AccountInput << "'.\n";
+        return 1;
+      }
+      if (LogReader.getFileHeader().Version != 1) {
+        errs() << "Unsupported XRay file version: "
+               << LogReader.getFileHeader().Version << '\n';
+        return 1;
+      }
+      Header = &LogReader.getFileHeader();
+      llvm::xray::XRayRecordStorage Buf;
+      for (const auto &Y : LogReader) {
+        auto &Record = toXRayRecord(Y, Buf);
+        if (!FCA.accountRecord(Record)) {
+          for (const auto &ThreadStack : FCA.getPerThreadFunctionStack()) {
+            errs() << "Thread ID: " << ThreadStack.first << "\n";
+            auto Level = ThreadStack.second.size();
+            for (const auto &Entry : llvm::reverse(ThreadStack.second)) {
+              errs() << "#" << Level-- << "\t"
+                     << FuncIdHelper.SymbolOrNumber(Entry.first) << '\n';
+            }
+          }
+          if (!AccountKeepGoing) {
+            errs() << "Failed accounting function calls in file '"
+                   << AccountInput << "'.\n";
+            return 1;
+          }
+        }
+      }
+      break;
+    }
+    }
+    switch (AccountOutputFormat) {
+    case AccountOutputFormats::TEXT:
+      FCA.exportStatsAsTEXT(OS, *Header);
+      break;
+    case AccountOutputFormats::CSV:
+      FCA.exportStatsAsCSV(OS, *Header);
+      break;
+    }
+    return 0;
+  }
+
   if (Convert) {
     if (ConvertInputFormat == ConvertOutputFormat) {
       errs() << "-input-format and -output-format are the same, bailing out.\n";
Index: tools/llvm-xray/xray-account.h
===================================================================
--- /dev/null
+++ tools/llvm-xray/xray-account.h
@@ -0,0 +1,104 @@
+//===- xray-account.h - XRay Function Call Accounting ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the interface for performing some basic function call
+// accounting from an XRay trace.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_TOOLS_LLVM_XRAY_XRAY_ACCOUNT_H
+#define LLVM_TOOLS_LLVM_XRAY_XRAY_ACCOUNT_H
+
+#include <map>
+#include <utility>
+#include <vector>
+
+#include "func-id-helper.h"
+#include "xray-record.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+namespace xray {
+
+class LatencyAccountant {
+public:
+  typedef std::map<int32_t, std::vector<uint64_t>> FunctionLatencyMap;
+  typedef std::map<pid_t, std::pair<uint64_t, uint64_t>> PerThreadMinMaxTSCMap;
+  typedef std::map<uint8_t, std::pair<uint64_t, uint64_t>> PerCPUMinMaxTSCMap;
+  typedef std::vector<std::pair<int32_t, uint64_t>> FunctionStack;
+  typedef std::map<pid_t, FunctionStack> PerThreadFunctionStackMap;
+
+private:
+  PerThreadFunctionStackMap PerThreadFunctionStack;
+  FunctionLatencyMap FunctionLatencies;
+  PerThreadMinMaxTSCMap PerThreadMinMaxTSC;
+  PerCPUMinMaxTSCMap PerCPUMinMaxTSC;
+  FuncIdConversionHelper &FuncIdHelper;
+
+  bool DeduceSiblingCalls = false;
+  uint64_t CurrentMaxTSC = 0;
+
+  void recordLatency(int32_t FuncId, uint64_t Latency) {
+    FunctionLatencies[FuncId].push_back(Latency);
+  }
+
+public:
+  explicit LatencyAccountant(FuncIdConversionHelper &FuncIdHelper,
+                             bool DeduceSiblingCalls)
+      : FuncIdHelper(FuncIdHelper), DeduceSiblingCalls(DeduceSiblingCalls) {}
+
+  const FunctionLatencyMap &getFunctionLatencies() const {
+    return FunctionLatencies;
+  }
+
+  const PerThreadMinMaxTSCMap &getPerThreadMinMaxTSC() const {
+    return PerThreadMinMaxTSC;
+  }
+
+  const PerCPUMinMaxTSCMap &getPerCPUMinMaxTSC() const {
+    return PerCPUMinMaxTSC;
+  }
+
+  /// Returns false in case we fail to account the provided record. This happens
+  /// in the following cases:
+  ///
+  ///   - An exit record does not match any entry records for the same function.
+  ///     If we've been set to deduce sibling calls, we try walking up the stack
+  ///     and recording times for the higher level functions.
+  ///   - A record has a TSC that's before the latest TSC that has been
+  ///     recorded. We still record the TSC for the min-max.
+  ///
+  bool accountRecord(const XRayRecord &Record);
+
+  const FunctionStack *getThreadFunctionStack(pid_t TId) const {
+    auto I = PerThreadFunctionStack.find(TId);
+    if (I == PerThreadFunctionStack.end())
+      return nullptr;
+    return &I->second;
+  }
+
+  const PerThreadFunctionStackMap &getPerThreadFunctionStack() const {
+    return PerThreadFunctionStack;
+  }
+
+  // Output Functions
+  // ================
+
+  void exportStatsAsTEXT(raw_ostream &OS, const XRayFileHeader &Header) const;
+  void exportStatsAsCSV(raw_ostream &OS, const XRayFileHeader &Header) const;
+
+private:
+  // Internal helper to implement common parts of the exportStatsAs...
+  // functions.
+  template <class F> void exportStats(const XRayFileHeader &Header, F fn) const;
+};
+
+} // namespace xray
+} // namespace llvm
+
+#endif // LLVM_TOOLS_LLVM_XRAY_XRAY_ACCOUNT_H
Index: tools/llvm-xray/xray-account.cc
===================================================================
--- /dev/null
+++ tools/llvm-xray/xray-account.cc
@@ -0,0 +1,169 @@
+//===- xray-account.h - XRay Function Call Accounting ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements basic function call accounting from an XRay trace.
+//
+//===----------------------------------------------------------------------===//
+
+#include <algorithm>
+#include <utility>
+
+#include "xray-account.h"
+#include "llvm/Support/ErrorHandling.h"
+
+using namespace llvm;
+using namespace llvm::xray;
+
+namespace {
+
+template <class T, class U> void setMinMax(std::pair<T, T> &MM, U &&V) {
+  if (MM.first == 0 || MM.second == 0)
+    MM = std::make_pair(std::forward<U>(V), std::forward<U>(V));
+  else
+    MM = std::make_pair(std::min(MM.first, V), std::max(MM.second, V));
+}
+
+template <class T> T diff(T L, T R) { return std::max(L, R) - std::min(L, R); }
+
+} // namespace
+
+bool LatencyAccountant::accountRecord(const XRayRecord &Record) {
+  setMinMax(PerThreadMinMaxTSC[Record.TId], Record.TSC);
+  setMinMax(PerCPUMinMaxTSC[Record.CPU], Record.TSC);
+
+  if (CurrentMaxTSC == 0)
+    CurrentMaxTSC = Record.TSC;
+
+  if (Record.TSC < CurrentMaxTSC)
+    return false;
+
+  auto &ThreadStack = PerThreadFunctionStack[Record.TId];
+  switch (Record.Type) {
+  case 0: {
+    // Function Enter
+    ThreadStack.push_back({Record.FuncId, Record.TSC});
+    break;
+  }
+  case 1: {
+    // Function Exit
+    if (ThreadStack.back().first != Record.FuncId) {
+      if (!DeduceSiblingCalls)
+        return false;
+      auto Parent =
+          std::find_if(ThreadStack.rbegin(), ThreadStack.rend(),
+                       [&](const std::pair<const int32_t, uint64_t> &E) {
+                         return E.first == Record.FuncId;
+                       });
+      if (Parent != ThreadStack.rend()) {
+        // We found a matching entry for this function.
+        auto I = ThreadStack.rbegin();
+        while (I <= Parent) {
+          const auto &Top = *I;
+          recordLatency(Top.first, diff(Top.second, Record.TSC));
+          ThreadStack.pop_back();
+          I = ThreadStack.rbegin();
+        }
+        return true;
+      }
+
+      // We didn't find a matching entry for this exit
+      return false;
+    }
+
+    // We did find that the top of the function call stack matches this exit.
+    assert(ThreadStack.back().first == Record.FuncId);
+    const auto &Top = ThreadStack.back();
+    recordLatency(Top.first, diff(Top.second, Record.TSC));
+    ThreadStack.pop_back();
+    break;
+  }
+  default:
+    llvm_unreachable("Unsupported record type.");
+    return false;
+  }
+
+  return true;
+}
+
+namespace {
+
+// We consolidate the data into a struct which we can output in various forms.
+struct ResultRow {
+  uint64_t Count;
+  double Min;
+  double Median;
+  double Pct90;
+  double Pct99;
+  double Max;
+  std::string DebugInfo;
+  std::string Function;
+};
+
+ResultRow getStats(std::vector<uint64_t> &Timings) {
+  ResultRow R;
+  std::nth_element(Timings.begin(), Timings.end(), Timings.end());
+  R.Min = Timings.front();
+  auto MedianOff = Timings.size() / 2;
+  std::nth_element(Timings.begin(), Timings.begin() + MedianOff, Timings.end());
+  R.Median = Timings[MedianOff];
+  auto Pct90Off = std::floor(Timings.size() * 0.9);
+  std::nth_element(Timings.begin(), Timings.begin() + Pct90Off, Timings.end());
+  R.Pct90 = Timings[Pct90Off];
+  auto Pct99Off = std::floor(Timings.size() * 0.99);
+  std::nth_element(Timings.begin(), Timings.begin() + Pct90Off, Timings.end());
+  R.Pct99 = Timings[Pct99Off];
+  R.Max = *std::max_element(Timings.begin(), Timings.end());
+  R.Count = Timings.size();
+  return R;
+}
+
+} // namespace
+
+template <class F>
+void LatencyAccountant::exportStats(const XRayFileHeader &Header, F Fn) const {
+  for (auto FT : FunctionLatencies) {
+    const auto &FuncId = FT.first;
+    auto &Timings = FT.second;
+    ResultRow Row = getStats(Timings);
+    if (Header.CycleFrequency) {
+      double CycleFrequency = Header.CycleFrequency;
+      Row.Min /= CycleFrequency;
+      Row.Median /= CycleFrequency;
+      Row.Pct90 /= CycleFrequency;
+      Row.Pct99 /= CycleFrequency;
+      Row.Max /= CycleFrequency;
+    }
+
+    Row.Function = FuncIdHelper.SymbolOrNumber(FuncId);
+    Row.DebugInfo = FuncIdHelper.FileLineAndColumn(FuncId);
+    Fn(FuncId, Timings.size(), Row);
+  }
+}
+
+void LatencyAccountant::exportStatsAsTEXT(raw_ostream &OS,
+                                          const XRayFileHeader &Header) const {
+  OS << "Functions with latencies: " << FunctionLatencies.size() << "\n";
+  OS << "funcid\t\tcount\t\t[min, median, 90%ile, 99%ile, "
+        "max]\tdebug\t\tfunction\n";
+  exportStats(Header, [&](int32_t FuncId, size_t Count, const ResultRow &Row) {
+    OS << FuncId << "\t\t" << Count << "\t\t[" << Row.Min << ", " << Row.Median
+       << ", " << Row.Pct90 << ", " << Row.Pct99 << ", " << Row.Max << "]  "
+       << Row.DebugInfo << "  " << Row.Function << "\n";
+  });
+}
+
+void LatencyAccountant::exportStatsAsCSV(raw_ostream &OS,
+                                         const XRayFileHeader &Header) const {
+  OS << "funcid,count,min,median,90%ile,99%ile,max,debug,function\n";
+  exportStats(Header, [&](int32_t FuncId, size_t Count, const ResultRow &Row) {
+    OS << FuncId << ',' << Count << ',' << Row.Min << ',' << Row.Median << ','
+       << Row.Pct90 << ',' << Row.Pct99 << ',' << Row.Max << ",\""
+       << Row.DebugInfo << "\",\"" << Row.Function << "\"\n";
+  });
+}
Index: tools/llvm-xray/xray-converter.h
===================================================================
--- tools/llvm-xray/xray-converter.h
+++ tools/llvm-xray/xray-converter.h
@@ -11,8 +11,8 @@
 // human-readable text and vice versa.
 //
 //===----------------------------------------------------------------------===//
-#ifndef XRAY_CONVERTER_H_
-#define XRAY_CONVERTER_H_
+#ifndef LLVM_TOOLS_LLVM_XRAY_XRAY_CONVERTER_H
+#define LLVM_TOOLS_LLVM_XRAY_XRAY_CONVERTER_H
 
 #include "func-id-helper.h"
 #include "xray-log-reader.h"
@@ -36,4 +36,4 @@
 } // namespace xray
 } // namespace llvm
 
-#endif // XRAY_CONVERTER_H_
+#endif // LLVM_TOOLS_LLVM_XRAY_XRAY_CONVERTER_H
Index: tools/llvm-xray/xray-log-reader.h
===================================================================
--- tools/llvm-xray/xray-log-reader.h
+++ tools/llvm-xray/xray-log-reader.h
@@ -11,8 +11,8 @@
 // version of the log (naive log) with fixed-sized records.
 //
 //===----------------------------------------------------------------------===//
-#ifndef XRAY_LOG_READER_H_
-#define XRAY_LOG_READER_H_
+#ifndef LLVM_TOOLS_LLVM_XRAY_XRAY_LOG_READER_H
+#define LLVM_TOOLS_LLVM_XRAY_XRAY_LOG_READER_H
 
 #include <cstdint>
 #include <deque>
@@ -76,4 +76,4 @@
 } // namespace xray
 } // namespace llvm
 
-#endif // XRAY_LOG_READER_H_
+#endif // LLVM_TOOLS_LLVM_XRAY_XRAY_LOG_READER_H
Index: tools/llvm-xray/xray-record-yaml.h
===================================================================
--- tools/llvm-xray/xray-record-yaml.h
+++ tools/llvm-xray/xray-record-yaml.h
@@ -10,8 +10,8 @@
 // Types and traits specialisations for YAML I/O of XRay log entries.
 //
 //===----------------------------------------------------------------------===//
-#ifndef XRAY_RECORD_YAML_H
-#define XRAY_RECORD_YAML_H
+#ifndef LLVM_TOOLS_LLVM_XRAY_XRAY_RECORD_YAML_H
+#define LLVM_TOOLS_LLVM_XRAY_XRAY_RECORD_YAML_H
 
 #include <type_traits>
 
@@ -123,4 +123,4 @@
 
 LLVM_YAML_IS_SEQUENCE_VECTOR(xray::YAMLXRayRecord);
 
-#endif // XRAY_RECORD_YAML_H
+#endif // LLVM_TOOLS_LLVM_XRAY_XRAY_RECORD_YAML_H
Index: tools/llvm-xray/xray-record.h
===================================================================
--- tools/llvm-xray/xray-record.h
+++ tools/llvm-xray/xray-record.h
@@ -12,8 +12,8 @@
 // xray project.
 //
 //===----------------------------------------------------------------------===//
-#ifndef XRAY_RECORD_H_
-#define XRAY_RECORD_H_
+#ifndef LLVM_TOOLS_LLVM_XRAY_XRAY_RECORD_H
+#define LLVM_TOOLS_LLVM_XRAY_XRAY_RECORD_H
 
 #include <cstdint>
 
@@ -57,4 +57,4 @@
 } // namespace xray
 } // namespace llvm
 
-#endif // XRAY_RECORD_H_
+#endif // LLVM_TOOLS_LLVM_XRAY_XRAY_RECORD_H