1 | //===- PGOCtxProfWriter.cpp - Contextual Instrumentation profile writer ---===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // Write a contextual profile to bitstream. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "llvm/ProfileData/PGOCtxProfWriter.h" |
14 | #include "llvm/Bitstream/BitCodeEnums.h" |
15 | |
16 | using namespace llvm; |
17 | using namespace llvm::ctx_profile; |
18 | |
19 | void PGOCtxProfileWriter::writeCounters(const ContextNode &Node) { |
20 | Writer.EmitCode(Val: bitc::UNABBREV_RECORD); |
21 | Writer.EmitVBR(Val: PGOCtxProfileRecords::Counters, NumBits: VBREncodingBits); |
22 | Writer.EmitVBR(Val: Node.counters_size(), NumBits: VBREncodingBits); |
23 | for (uint32_t I = 0U; I < Node.counters_size(); ++I) |
24 | Writer.EmitVBR64(Val: Node.counters()[I], NumBits: VBREncodingBits); |
25 | } |
26 | |
27 | // recursively write all the subcontexts. We do need to traverse depth first to |
28 | // model the context->subcontext implicitly, and since this captures call |
29 | // stacks, we don't really need to be worried about stack overflow and we can |
30 | // keep the implementation simple. |
31 | void PGOCtxProfileWriter::writeImpl(std::optional<uint32_t> CallerIndex, |
32 | const ContextNode &Node) { |
33 | Writer.EnterSubblock(BlockID: PGOCtxProfileBlockIDs::ContextNodeBlockID, CodeLen); |
34 | Writer.EmitRecord(Code: PGOCtxProfileRecords::Guid, |
35 | Vals: SmallVector<uint64_t, 1>{Node.guid()}); |
36 | if (CallerIndex) |
37 | Writer.EmitRecord(Code: PGOCtxProfileRecords::CalleeIndex, |
38 | Vals: SmallVector<uint64_t, 1>{*CallerIndex}); |
39 | writeCounters(Node); |
40 | for (uint32_t I = 0U; I < Node.callsites_size(); ++I) |
41 | for (const auto *Subcontext = Node.subContexts()[I]; Subcontext; |
42 | Subcontext = Subcontext->next()) |
43 | writeImpl(CallerIndex: I, Node: *Subcontext); |
44 | Writer.ExitBlock(); |
45 | } |
46 | |
47 | void PGOCtxProfileWriter::write(const ContextNode &RootNode) { |
48 | writeImpl(CallerIndex: std::nullopt, Node: RootNode); |
49 | } |
50 | |