Skip to content

Conversation

@mtrofin
Copy link
Member

@mtrofin mtrofin commented Mar 5, 2025

A section for flat profiles (i.e. non-contextual). This is useful for debugging or for intentional cases where a root isn't identified.

This patch adds the reader/writer support. compiler-rt changes follow in a subsequent change.

Copy link
Member Author

mtrofin commented Mar 5, 2025

This stack of pull requests is managed by Graphite. Learn more about stacking.

Copy link
Contributor

@kazutakahirata kazutakahirata left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@mtrofin mtrofin marked this pull request as ready for review March 6, 2025 18:59
@llvmbot llvmbot added the PGO Profile Guided Optimizations label Mar 6, 2025
@llvmbot
Copy link
Member

llvmbot commented Mar 6, 2025

@llvm/pr-subscribers-pgo

Author: Mircea Trofin (mtrofin)

Changes

A section for flat profiles (i.e. non-contextual). This is useful for debugging or for intentional cases where a root isn't identified.

This patch adds the reader/writer support. compiler-rt changes follow in a subsequent change.


Full diff: https://github.com/llvm/llvm-project/pull/129932.diff

11 Files Affected:

  • (modified) llvm/include/llvm/ProfileData/PGOCtxProfReader.h (+3)
  • (modified) llvm/include/llvm/ProfileData/PGOCtxProfWriter.h (+10-1)
  • (modified) llvm/lib/ProfileData/PGOCtxProfReader.cpp (+61-12)
  • (modified) llvm/lib/ProfileData/PGOCtxProfWriter.cpp (+42)
  • (added) llvm/test/tools/llvm-ctxprof-util/Inputs/invalid-flat.yaml (+2)
  • (added) llvm/test/tools/llvm-ctxprof-util/Inputs/valid-ctx-only.yaml (+14)
  • (added) llvm/test/tools/llvm-ctxprof-util/Inputs/valid-flat-first.yaml (+19)
  • (added) llvm/test/tools/llvm-ctxprof-util/Inputs/valid-flat-only.yaml (+6)
  • (modified) llvm/test/tools/llvm-ctxprof-util/Inputs/valid.yaml (+5)
  • (modified) llvm/test/tools/llvm-ctxprof-util/llvm-ctxprof-util-negative.test (+2)
  • (modified) llvm/test/tools/llvm-ctxprof-util/llvm-ctxprof-util.test (+26-1)
diff --git a/llvm/include/llvm/ProfileData/PGOCtxProfReader.h b/llvm/include/llvm/ProfileData/PGOCtxProfReader.h
index dbd8288caaff5..4026e6b45b938 100644
--- a/llvm/include/llvm/ProfileData/PGOCtxProfReader.h
+++ b/llvm/include/llvm/ProfileData/PGOCtxProfReader.h
@@ -174,6 +174,7 @@ using CtxProfContextualProfiles =
     std::map<GlobalValue::GUID, PGOCtxProfContext>;
 struct PGOCtxProfile {
   CtxProfContextualProfiles Contexts;
+  CtxProfFlatProfile FlatProfiles;
 
   PGOCtxProfile() = default;
   PGOCtxProfile(const PGOCtxProfile &) = delete;
@@ -192,10 +193,12 @@ class PGOCtxProfileReader final {
   Expected<std::pair<std::optional<uint32_t>, PGOCtxProfContext>>
   readProfile(PGOCtxProfileBlockIDs Kind);
 
+  bool tryGetNextKnownBlockID(PGOCtxProfileBlockIDs &ID);
   bool canEnterBlockWithID(PGOCtxProfileBlockIDs ID);
   Error enterBlockWithID(PGOCtxProfileBlockIDs ID);
 
   Error loadContexts(CtxProfContextualProfiles &);
+  Error loadFlatProfiles(CtxProfFlatProfile &);
 
 public:
   PGOCtxProfileReader(StringRef Buffer)
diff --git a/llvm/include/llvm/ProfileData/PGOCtxProfWriter.h b/llvm/include/llvm/ProfileData/PGOCtxProfWriter.h
index 8923fe57c180c..99da9ac9df68b 100644
--- a/llvm/include/llvm/ProfileData/PGOCtxProfWriter.h
+++ b/llvm/include/llvm/ProfileData/PGOCtxProfWriter.h
@@ -22,10 +22,14 @@ namespace llvm {
 enum PGOCtxProfileRecords { Invalid = 0, Version, Guid, CalleeIndex, Counters };
 
 enum PGOCtxProfileBlockIDs {
-  ProfileMetadataBlockID = bitc::FIRST_APPLICATION_BLOCKID,
+  FIRST_VALID = bitc::FIRST_APPLICATION_BLOCKID,
+  ProfileMetadataBlockID = FIRST_VALID,
   ContextsSectionBlockID = ProfileMetadataBlockID + 1,
   ContextRootBlockID = ContextsSectionBlockID + 1,
   ContextNodeBlockID = ContextRootBlockID + 1,
+  FlatProfilesSectionBlockID = ContextNodeBlockID + 1,
+  FlatProfileBlockID = FlatProfilesSectionBlockID + 1,
+  LAST_VALID = FlatProfileBlockID
 };
 
 /// Write one or more ContextNodes to the provided raw_fd_stream.
@@ -83,6 +87,11 @@ class PGOCtxProfileWriter : public ctx_profile::ProfileWriter {
   void writeContextual(const ctx_profile::ContextNode &RootNode) override;
   void endContextSection() override;
 
+  void startFlatSection();
+  void writeFlatSection(ctx_profile::GUID Guid, const uint64_t *Buffer,
+                        size_t BufferSize);
+  void endFlatSection();
+
   // constants used in writing which a reader may find useful.
   static constexpr unsigned CodeLen = 2;
   static constexpr uint32_t CurrentVersion = 2;
diff --git a/llvm/lib/ProfileData/PGOCtxProfReader.cpp b/llvm/lib/ProfileData/PGOCtxProfReader.cpp
index bb912635879d2..8409fe3659f46 100644
--- a/llvm/lib/ProfileData/PGOCtxProfReader.cpp
+++ b/llvm/lib/ProfileData/PGOCtxProfReader.cpp
@@ -57,13 +57,24 @@ Error PGOCtxProfileReader::unsupported(const Twine &Msg) {
   return make_error<InstrProfError>(instrprof_error::unsupported_version, Msg);
 }
 
-bool PGOCtxProfileReader::canEnterBlockWithID(PGOCtxProfileBlockIDs ID) {
+bool PGOCtxProfileReader::tryGetNextKnownBlockID(PGOCtxProfileBlockIDs &ID) {
   auto Blk = advance();
   if (!Blk) {
     consumeError(Blk.takeError());
     return false;
   }
-  return Blk->Kind == BitstreamEntry::SubBlock && Blk->ID == ID;
+  if (Blk->Kind != BitstreamEntry::SubBlock)
+    return false;
+  if (PGOCtxProfileBlockIDs::FIRST_VALID > Blk->ID ||
+      PGOCtxProfileBlockIDs::LAST_VALID < Blk->ID)
+    return false;
+  ID = static_cast<PGOCtxProfileBlockIDs>(Blk->ID);
+  return true;
+}
+
+bool PGOCtxProfileReader::canEnterBlockWithID(PGOCtxProfileBlockIDs ID) {
+  PGOCtxProfileBlockIDs Test = {};
+  return tryGetNextKnownBlockID(Test) && Test == ID;
 }
 
 Error PGOCtxProfileReader::enterBlockWithID(PGOCtxProfileBlockIDs ID) {
@@ -71,10 +82,14 @@ Error PGOCtxProfileReader::enterBlockWithID(PGOCtxProfileBlockIDs ID) {
   return Error::success();
 }
 
+// Note: we use PGOCtxProfContext for flat profiles also, as the latter are
+// structurally similar. Alternative modeling here seems a bit overkill at the
+// moment.
 Expected<std::pair<std::optional<uint32_t>, PGOCtxProfContext>>
 PGOCtxProfileReader::readProfile(PGOCtxProfileBlockIDs Kind) {
   assert((Kind == PGOCtxProfileBlockIDs::ContextRootBlockID ||
-          Kind == PGOCtxProfileBlockIDs::ContextNodeBlockID) &&
+          Kind == PGOCtxProfileBlockIDs::ContextNodeBlockID ||
+          Kind == PGOCtxProfileBlockIDs::FlatProfileBlockID) &&
          "Unexpected profile kind");
   RET_ON_ERR(enterBlockWithID(Kind));
 
@@ -176,14 +191,24 @@ Error PGOCtxProfileReader::readMetadata() {
 }
 
 Error PGOCtxProfileReader::loadContexts(CtxProfContextualProfiles &P) {
-  if (canEnterBlockWithID(PGOCtxProfileBlockIDs::ContextsSectionBlockID)) {
-    RET_ON_ERR(enterBlockWithID(PGOCtxProfileBlockIDs::ContextsSectionBlockID));
-    while (canEnterBlockWithID(PGOCtxProfileBlockIDs::ContextRootBlockID)) {
-      EXPECT_OR_RET(E, readProfile(PGOCtxProfileBlockIDs::ContextRootBlockID));
-      auto Key = E->second.guid();
-      if (!P.insert({Key, std::move(E->second)}).second)
-        return wrongValue("Duplicate roots");
-    }
+  RET_ON_ERR(enterBlockWithID(PGOCtxProfileBlockIDs::ContextsSectionBlockID));
+  while (canEnterBlockWithID(PGOCtxProfileBlockIDs::ContextRootBlockID)) {
+    EXPECT_OR_RET(E, readProfile(PGOCtxProfileBlockIDs::ContextRootBlockID));
+    auto Key = E->second.guid();
+    if (!P.insert({Key, std::move(E->second)}).second)
+      return wrongValue("Duplicate roots");
+  }
+  return Error::success();
+}
+
+Error PGOCtxProfileReader::loadFlatProfiles(CtxProfFlatProfile &P) {
+  RET_ON_ERR(
+      enterBlockWithID(PGOCtxProfileBlockIDs::FlatProfilesSectionBlockID));
+  while (canEnterBlockWithID(PGOCtxProfileBlockIDs::FlatProfileBlockID)) {
+    EXPECT_OR_RET(E, readProfile(PGOCtxProfileBlockIDs::FlatProfileBlockID));
+    auto Guid = E->second.guid();
+    if (!P.insert({Guid, std::move(E->second.counters())}).second)
+      return wrongValue("Duplicate flat profile entries");
   }
   return Error::success();
 }
@@ -191,7 +216,19 @@ Error PGOCtxProfileReader::loadContexts(CtxProfContextualProfiles &P) {
 Expected<PGOCtxProfile> PGOCtxProfileReader::loadProfiles() {
   RET_ON_ERR(readMetadata());
   PGOCtxProfile Ret;
-  RET_ON_ERR(loadContexts(Ret.Contexts));
+  PGOCtxProfileBlockIDs Test = {};
+  for (auto I = 0; I < 2; ++I) {
+    if (!tryGetNextKnownBlockID(Test))
+      break;
+    if (Test == PGOCtxProfileBlockIDs::ContextsSectionBlockID) {
+      RET_ON_ERR(loadContexts(Ret.Contexts));
+    } else if (Test == PGOCtxProfileBlockIDs::FlatProfilesSectionBlockID) {
+      RET_ON_ERR(loadFlatProfiles(Ret.FlatProfiles));
+    } else {
+      return wrongValue("Unexpected section");
+    }
+  }
+
   return std::move(Ret);
 }
 
@@ -288,5 +325,17 @@ void llvm::convertCtxProfToYaml(raw_ostream &OS,
     toYaml(Out, Profiles.Contexts);
     Out.postflightKey(nullptr);
   }
+  if (!Profiles.FlatProfiles.empty()) {
+    Out.preflightKey("FlatProfiles", false, false, UseDefault, SaveInfo);
+    Out.beginSequence();
+    size_t ElemID = 0;
+    for (const auto &[Guid, Counters] : Profiles.FlatProfiles) {
+      Out.preflightElement(ElemID++, SaveInfo);
+      toYaml(Out, Guid, Counters, {});
+      Out.postflightElement(nullptr);
+    }
+    Out.endSequence();
+    Out.postflightKey(nullptr);
+  }
   Out.endMapping();
 }
diff --git a/llvm/lib/ProfileData/PGOCtxProfWriter.cpp b/llvm/lib/ProfileData/PGOCtxProfWriter.cpp
index d4184da1c2509..d099572fc152a 100644
--- a/llvm/lib/ProfileData/PGOCtxProfWriter.cpp
+++ b/llvm/lib/ProfileData/PGOCtxProfWriter.cpp
@@ -13,6 +13,7 @@
 #include "llvm/ProfileData/PGOCtxProfWriter.h"
 #include "llvm/Bitstream/BitCodeEnums.h"
 #include "llvm/ProfileData/CtxInstrContextNode.h"
+#include "llvm/ProfileData/PGOCtxProfReader.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/YAMLTraits.h"
@@ -59,6 +60,11 @@ PGOCtxProfileWriter::PGOCtxProfileWriter(
     DescribeRecord(PGOCtxProfileRecords::Guid, "GUID");
     DescribeRecord(PGOCtxProfileRecords::CalleeIndex, "CalleeIndex");
     DescribeRecord(PGOCtxProfileRecords::Counters, "Counters");
+    DescribeBlock(PGOCtxProfileBlockIDs::FlatProfilesSectionBlockID,
+                  "FlatProfiles");
+    DescribeBlock(PGOCtxProfileBlockIDs::FlatProfileBlockID, "Flat");
+    DescribeRecord(PGOCtxProfileRecords::Guid, "GUID");
+    DescribeRecord(PGOCtxProfileRecords::Counters, "Counters");
   }
   Writer.ExitBlock();
   Writer.EnterSubblock(PGOCtxProfileBlockIDs::ProfileMetadataBlockID, CodeLen);
@@ -108,12 +114,27 @@ void PGOCtxProfileWriter::startContextSection() {
   Writer.EnterSubblock(PGOCtxProfileBlockIDs::ContextsSectionBlockID, CodeLen);
 }
 
+void PGOCtxProfileWriter::startFlatSection() {
+  Writer.EnterSubblock(PGOCtxProfileBlockIDs::FlatProfilesSectionBlockID,
+                       CodeLen);
+}
+
 void PGOCtxProfileWriter::endContextSection() { Writer.ExitBlock(); }
+void PGOCtxProfileWriter::endFlatSection() { Writer.ExitBlock(); }
 
 void PGOCtxProfileWriter::writeContextual(const ContextNode &RootNode) {
   writeImpl(std::nullopt, RootNode);
 }
 
+void PGOCtxProfileWriter::writeFlatSection(ctx_profile::GUID Guid,
+                                           const uint64_t *Buffer,
+                                           size_t Size) {
+  Writer.EnterSubblock(PGOCtxProfileBlockIDs::FlatProfileBlockID, CodeLen);
+  writeGuid(Guid);
+  writeCounters({Buffer, Size});
+  Writer.ExitBlock();
+}
+
 namespace {
 
 /// Representation of the context node suitable for yaml serialization /
@@ -123,8 +144,13 @@ struct SerializableCtxRepresentation {
   std::vector<uint64_t> Counters;
   std::vector<std::vector<SerializableCtxRepresentation>> Callsites;
 };
+
+using SerializableFlatProfileRepresentation =
+    std::pair<ctx_profile::GUID, std::vector<uint64_t>>;
+
 struct SerializableProfileRepresentation {
   std::vector<SerializableCtxRepresentation> Contexts;
+  std::vector<SerializableFlatProfileRepresentation> FlatProfiles;
 };
 
 ctx_profile::ContextNode *
@@ -164,6 +190,7 @@ createNode(std::vector<std::unique_ptr<char[]>> &Nodes,
 
 LLVM_YAML_IS_SEQUENCE_VECTOR(SerializableCtxRepresentation)
 LLVM_YAML_IS_SEQUENCE_VECTOR(std::vector<SerializableCtxRepresentation>)
+LLVM_YAML_IS_SEQUENCE_VECTOR(SerializableFlatProfileRepresentation)
 template <> struct yaml::MappingTraits<SerializableCtxRepresentation> {
   static void mapping(yaml::IO &IO, SerializableCtxRepresentation &SCR) {
     IO.mapRequired("Guid", SCR.Guid);
@@ -175,6 +202,15 @@ template <> struct yaml::MappingTraits<SerializableCtxRepresentation> {
 template <> struct yaml::MappingTraits<SerializableProfileRepresentation> {
   static void mapping(yaml::IO &IO, SerializableProfileRepresentation &SPR) {
     IO.mapOptional("Contexts", SPR.Contexts);
+    IO.mapOptional("FlatProfiles", SPR.FlatProfiles);
+  }
+};
+
+template <> struct yaml::MappingTraits<SerializableFlatProfileRepresentation> {
+  static void mapping(yaml::IO &IO,
+                      SerializableFlatProfileRepresentation &SFPR) {
+    IO.mapRequired("Guid", SFPR.first);
+    IO.mapRequired("Counters", SFPR.second);
   }
 };
 
@@ -201,6 +237,12 @@ Error llvm::createCtxProfFromYAML(StringRef Profile, raw_ostream &Out) {
     }
     Writer.endContextSection();
   }
+  if (!SPR.FlatProfiles.empty()) {
+    Writer.startFlatSection();
+    for (const auto &[Guid, Counters] : SPR.FlatProfiles)
+      Writer.writeFlatSection(Guid, Counters.data(), Counters.size());
+    Writer.endFlatSection();
+  }
   if (EC)
     return createStringError(EC, "failed to write output");
   return Error::success();
diff --git a/llvm/test/tools/llvm-ctxprof-util/Inputs/invalid-flat.yaml b/llvm/test/tools/llvm-ctxprof-util/Inputs/invalid-flat.yaml
new file mode 100644
index 0000000000000..c3bc89a9a3519
--- /dev/null
+++ b/llvm/test/tools/llvm-ctxprof-util/Inputs/invalid-flat.yaml
@@ -0,0 +1,2 @@
+FlatProfiles:
+  - Guid: 1
diff --git a/llvm/test/tools/llvm-ctxprof-util/Inputs/valid-ctx-only.yaml b/llvm/test/tools/llvm-ctxprof-util/Inputs/valid-ctx-only.yaml
new file mode 100644
index 0000000000000..0de489dd0b1eb
--- /dev/null
+++ b/llvm/test/tools/llvm-ctxprof-util/Inputs/valid-ctx-only.yaml
@@ -0,0 +1,14 @@
+
+Contexts:
+  - Guid:            1000
+    Counters:        [ 1, 2, 3 ]
+    Callsites:
+      - [  ]
+      - - Guid:            2000
+          Counters:        [ 4, 5 ]
+        - Guid:            18446744073709551613
+          Counters:        [ 6, 7, 8 ]
+      - - Guid:            3000
+          Counters:        [ 40, 50 ]
+  - Guid:            18446744073709551612
+    Counters:        [ 5, 9, 10 ]
diff --git a/llvm/test/tools/llvm-ctxprof-util/Inputs/valid-flat-first.yaml b/llvm/test/tools/llvm-ctxprof-util/Inputs/valid-flat-first.yaml
new file mode 100644
index 0000000000000..5567faaa9e0a4
--- /dev/null
+++ b/llvm/test/tools/llvm-ctxprof-util/Inputs/valid-flat-first.yaml
@@ -0,0 +1,19 @@
+
+FlatProfiles:
+  - Guid:            1234
+    Counters:        [ 5, 6, 7 ]
+  - Guid:            5555
+    Counters:        [ 1 ]
+Contexts:
+  - Guid:            1000
+    Counters:        [ 1, 2, 3 ]
+    Callsites:
+      - [  ]
+      - - Guid:            2000
+          Counters:        [ 4, 5 ]
+        - Guid:            18446744073709551613
+          Counters:        [ 6, 7, 8 ]
+      - - Guid:            3000
+          Counters:        [ 40, 50 ]
+  - Guid:            18446744073709551612
+    Counters:        [ 5, 9, 10 ]
diff --git a/llvm/test/tools/llvm-ctxprof-util/Inputs/valid-flat-only.yaml b/llvm/test/tools/llvm-ctxprof-util/Inputs/valid-flat-only.yaml
new file mode 100644
index 0000000000000..98231ed70d0ec
--- /dev/null
+++ b/llvm/test/tools/llvm-ctxprof-util/Inputs/valid-flat-only.yaml
@@ -0,0 +1,6 @@
+
+FlatProfiles:
+  - Guid:            1234
+    Counters:        [ 5, 6, 7 ]
+  - Guid:            5555
+    Counters:        [ 1 ]
diff --git a/llvm/test/tools/llvm-ctxprof-util/Inputs/valid.yaml b/llvm/test/tools/llvm-ctxprof-util/Inputs/valid.yaml
index 0de489dd0b1eb..1541b0d136514 100644
--- a/llvm/test/tools/llvm-ctxprof-util/Inputs/valid.yaml
+++ b/llvm/test/tools/llvm-ctxprof-util/Inputs/valid.yaml
@@ -12,3 +12,8 @@ Contexts:
           Counters:        [ 40, 50 ]
   - Guid:            18446744073709551612
     Counters:        [ 5, 9, 10 ]
+FlatProfiles:
+  - Guid:            1234
+    Counters:        [ 5, 6, 7 ]
+  - Guid:            5555
+    Counters:        [ 1 ]
diff --git a/llvm/test/tools/llvm-ctxprof-util/llvm-ctxprof-util-negative.test b/llvm/test/tools/llvm-ctxprof-util/llvm-ctxprof-util-negative.test
index 487d5ae1d17be..f312f50ffee8e 100644
--- a/llvm/test/tools/llvm-ctxprof-util/llvm-ctxprof-util-negative.test
+++ b/llvm/test/tools/llvm-ctxprof-util/llvm-ctxprof-util-negative.test
@@ -9,6 +9,7 @@
 ; RUN: not llvm-ctxprof-util fromYAML --input %S/Inputs/invalid-no-ctx.yaml 2>&1 | FileCheck %s --check-prefix=NO_CTX
 ; RUN: not llvm-ctxprof-util fromYAML --input %S/Inputs/invalid-no-counters.yaml 2>&1 | FileCheck %s --check-prefix=NO_COUNTERS
 ; RUN: not llvm-ctxprof-util fromYAML --input %S/Inputs/invalid-bad-subctx.yaml 2>&1 | FileCheck %s --check-prefix=BAD_SUBCTX
+; RUN: not llvm-ctxprof-util fromYAML --input %S/Inputs/invalid-flat.yaml 2>&1 | FileCheck %s --check-prefix=BAD_FLAT
 ; RUN: rm -rf %t
 ; RUN: not llvm-ctxprof-util fromYAML --input %S/Inputs/valid.yaml --output %t/output.bitstream 2>&1 | FileCheck %s --check-prefix=NO_DIR
 
@@ -21,4 +22,5 @@
 ; NO_CTX: YAML:1:1: error: not a mapping
 ; NO_COUNTERS: YAML:2:5: error: missing required key 'Counters'
 ; BAD_SUBCTX: YAML:4:18: error: not a sequence
+; BAD_FLAT: YAML:2:5: error: missing required key 'Counters'
 ; NO_DIR: failed to open output
diff --git a/llvm/test/tools/llvm-ctxprof-util/llvm-ctxprof-util.test b/llvm/test/tools/llvm-ctxprof-util/llvm-ctxprof-util.test
index 07cbdd97210fb..a9e350388577c 100644
--- a/llvm/test/tools/llvm-ctxprof-util/llvm-ctxprof-util.test
+++ b/llvm/test/tools/llvm-ctxprof-util/llvm-ctxprof-util.test
@@ -8,6 +8,21 @@
 ; RUN: llvm-ctxprof-util toYAML -input %t/valid.bitstream -output %t/valid2.yaml
 ; RUN: diff %t/valid2.yaml %S/Inputs/valid.yaml
 
+
+; RUN: llvm-ctxprof-util fromYAML -input %S/Inputs/valid-ctx-only.yaml -output %t/valid-ctx-only.bitstream
+; RUN: llvm-ctxprof-util toYAML -input %t/valid-ctx-only.bitstream -output %t/valid-ctx-only.yaml
+; RUN: diff %t/valid-ctx-only.yaml %S/Inputs/valid-ctx-only.yaml
+
+; RUN: llvm-ctxprof-util fromYAML -input %S/Inputs/valid-flat-only.yaml -output %t/valid-flat-only.bitstream
+; RUN: llvm-ctxprof-util toYAML -input %t/valid-flat-only.bitstream -output %t/valid-flat-only.yaml
+; RUN: diff %t/valid-flat-only.yaml %S/Inputs/valid-flat-only.yaml
+
+; This case is the "valid.yaml" case but with the flat profile first.
+; The output, though, should match valid.yaml
+; RUN: llvm-ctxprof-util fromYAML -input %S/Inputs/valid-flat-first.yaml -output %t/valid-flat-first.bitstream
+; RUN: llvm-ctxprof-util toYAML -input %t/valid-flat-first.bitstream -output %t/valid-flat-first.yaml
+; RUN: diff %t/valid-flat-first.yaml %S/Inputs/valid.yaml
+
 ; For the valid case, check against a reference output.
 ; Note that uint64_t are printed as signed values by llvm-bcanalyzer:
 ;  * 18446744073709551613 in yaml is -3 in the output
@@ -22,7 +37,7 @@
 ; EMPTY-NEXT: </Metadata>
 
 ; VALID:      <BLOCKINFO_BLOCK/>
-; VALID-NEXT: <Metadata NumWords=33 BlockCodeSize=2>
+; VALID-NEXT: <Metadata NumWords=45 BlockCodeSize=2>
 ; VALID-NEXT:   <Version op0=2/>
 ; VALID-NEXT:   <Contexts NumWords=29 BlockCodeSize=2>
 ; VALID-NEXT:     <Root NumWords=20 BlockCodeSize=2>
@@ -49,4 +64,14 @@
 ; VALID-NEXT:       <Counters op0=5 op1=9 op2=10/>
 ; VALID-NEXT:     </Root>
 ; VALID-NEXT:   </Contexts>
+; VALID-NEXT:   <FlatProfiles NumWords=10 BlockCodeSize=2>
+; VALID-NEXT:       <Flat NumWords=3 BlockCodeSize=2>
+; VALID-NEXT:         <GUID op0=1234/>
+; VALID-NEXT:         <Counters op0=5 op1=6 op2=7/>
+; VALID-NEXT:       </Flat>
+; VALID-NEXT:       <Flat NumWords=2 BlockCodeSize=2>
+; VALID-NEXT:         <GUID op0=5555/>
+; VALID-NEXT:         <Counters op0=1/>
+; VALID-NEXT:       </Flat>
+; VALID-NEXT:   </FlatProfiles>
 ; VALID-NEXT: </Metadata>
\ No newline at end of file

@mtrofin mtrofin force-pushed the users/mtrofin/03-05-_ctxprof_profile_section_for_flat_profiles branch from 08da240 to afc850e Compare March 6, 2025 19:00
@mtrofin mtrofin force-pushed the users/mtrofin/03-05-_ctxprof_profile_section_for_flat_profiles branch from afc850e to ae02425 Compare March 7, 2025 00:35
Copy link
Member Author

mtrofin commented Mar 7, 2025

Merge activity

  • Mar 7, 12:17 AM EST: A user started a stack merge that includes this pull request via Graphite.
  • Mar 7, 12:18 AM EST: A user merged this pull request with Graphite.

@mtrofin mtrofin merged commit c8fd7a8 into main Mar 7, 2025
11 checks passed
@mtrofin mtrofin deleted the users/mtrofin/03-05-_ctxprof_profile_section_for_flat_profiles branch March 7, 2025 05:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

PGO Profile Guided Optimizations

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants