LLVM: lib/ProfileData/PGOCtxProfWriter.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

20

21using namespace llvm;

23

26 cl::desc("Also write profiles with all-zero counters. "

27 "Intended for testing/debugging."));

28

30 raw_ostream &Out, std::optional VersionOverride,

31 bool IncludeEmpty)

32 : Writer(Out, 0),

34 : IncludeEmpty) {

37 Writer.EnterBlockInfoBlock();

38 {

39 auto DescribeBlock = [&](unsigned ID, StringRef Name) {

40 Writer.EmitRecord(bitc::BLOCKINFO_CODE_SETBID,

41 SmallVector<unsigned, 1>{ID});

42 Writer.EmitRecord(bitc::BLOCKINFO_CODE_BLOCKNAME,

43 llvm::arrayRefFromStringRef(Name));

44 };

46 auto DescribeRecord = [&](unsigned RecordID, StringRef Name) {

47 Data.clear();

48 Data.push_back(RecordID);

49 llvm::append_range(Data, Name);

50 Writer.EmitRecord(bitc::BLOCKINFO_CODE_SETRECORDNAME, Data);

51 };

53 DescribeRecord(PGOCtxProfileRecords::Version, "Version");

58 "TotalRootEntryCount");

66 "FlatProfiles");

70 }

71 Writer.ExitBlock();

73 const auto Version = VersionOverride.value_or(CurrentVersion);

74 Writer.EmitRecord(PGOCtxProfileRecords::Version,

76}

77

84}

85

88}

89

90void PGOCtxProfileWriter::writeCallsiteIndex(uint32_t CallsiteIndex) {

93}

94

95void PGOCtxProfileWriter::writeRootEntryCount(uint64_t TotalRootEntryCount) {

98}

99

100

101

102

103

104void PGOCtxProfileWriter::writeNode(uint32_t CallsiteIndex,

105 const ContextNode &Node) {

106

107

108 if (!IncludeEmpty && (Node.counters_size() > 0 && Node.entrycount() == 0))

109 return;

111 writeGuid(Node.guid());

113 writeCounters({Node.counters(), Node.counters_size()});

114 writeSubcontexts(Node);

115 Writer.ExitBlock();

116}

117

118void PGOCtxProfileWriter::writeSubcontexts(const ContextNode &Node) {

119 for (uint32_t I = 0U; I < Node.callsites_size(); ++I)

120 for (const auto *Subcontext = Node.subContexts()[I]; Subcontext;

121 Subcontext = Subcontext->next())

122 writeNode(I, *Subcontext);

123}

124

128

133

136

142 return;

144 writeGuid(RootNode.guid());

147

149 for (const auto *P = Unhandled; P; P = P->next())

150 writeFlat(P->guid(), P->counters(), P->counters_size());

151 Writer.ExitBlock();

152

153 writeSubcontexts(RootNode);

154 Writer.ExitBlock();

155}

156

160 writeGuid(Guid);

161 writeCounters({Buffer, Size});

162 Writer.ExitBlock();

163}

164

165namespace {

166

167

168

169using SerializableFlatProfileRepresentation =

170 std::pair<ctx_profile::GUID, std::vector<uint64_t>>;

171

172struct SerializableCtxRepresentation {

174 std::vector<uint64_t> Counters;

175 std::vector<std::vector> Callsites;

176};

177

178struct SerializableRootRepresentation : public SerializableCtxRepresentation {

180 std::vector Unhandled;

181};

182

183struct SerializableProfileRepresentation {

184 std::vector Contexts;

185 std::vector FlatProfiles;

186};

187

189createNode(std::vector<std::unique_ptr<char[]>> &Nodes,

190 const std::vector &DCList);

191

192

193

195createNode(std::vector<std::unique_ptr<char[]>> &Nodes,

196 const SerializableCtxRepresentation &DC,

199 DC.Callsites.size());

200 auto *Mem = Nodes.emplace_back(std::make_unique<char[]>(AllocSize)).get();

201 std::memset(Mem, 0, AllocSize);

203 DC.Callsites.size(), Next);

204 std::memcpy(Ret->counters(), DC.Counters.data(),

205 sizeof(uint64_t) * DC.Counters.size());

206 for (const auto &[I, DCList] : llvm::enumerate(DC.Callsites))

207 Ret->subContexts()[I] = createNode(Nodes, DCList);

208 return Ret;

209}

210

211

212

214createNode(std::vector<std::unique_ptr<char[]>> &Nodes,

215 const std::vector &DCList) {

217 for (const auto &DC : DCList)

218 List = createNode(Nodes, DC, List);

220}

221}

222

234

238 IO.mapRequired("TotalRootEntryCount", R.TotalRootEntryCount);

240 }

241};

242

249

252 SerializableFlatProfileRepresentation &SFPR) {

255 }

256};

257

260 SerializableProfileRepresentation SPR;

261 In >> SPR;

262 if (In.error())

264 std::vector<std::unique_ptr<char[]>> Nodes;

265 std::error_code EC;

266 if (EC)

269

270 if (!SPR.Contexts.empty()) {

272 for (const auto &DC : SPR.Contexts) {

273 auto *TopList = createNode(Nodes, DC);

274 if (!TopList)

276 "Unexpected error converting internal structure to ctx profile");

277

279 for (const auto &U : DC.Unhandled) {

280 SerializableCtxRepresentation Unhandled;

281 Unhandled.Guid = U.first;

282 Unhandled.Counters = U.second;

283 FirstUnhandled = createNode(Nodes, Unhandled, FirstUnhandled);

284 }

285 Writer.writeContextual(*TopList, FirstUnhandled, DC.TotalRootEntryCount);

286 }

288 }

289 if (!SPR.FlatProfiles.empty()) {

291 for (const auto &[Guid, Counters] : SPR.FlatProfiles)

294 }

295 if (EC)

298}

static cl::opt< bool > IncludeEmptyOpt("ctx-prof-include-empty", cl::init(false), cl::desc("Also write profiles with all-zero counters. " "Intended for testing/debugging."))

#define LLVM_YAML_IS_SEQUENCE_VECTOR(type)

Utility for declaring that a std::vector of a particular type should be considered a YAML sequence.

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Write one or more ContextNodes to the provided raw_fd_stream.

void startFlatSection() override

Definition PGOCtxProfWriter.cpp:129

void writeContextual(const ctx_profile::ContextNode &RootNode, const ctx_profile::ContextNode *Unhandled, uint64_t TotalRootEntryCount) override

Definition PGOCtxProfWriter.cpp:137

static constexpr unsigned VBREncodingBits

PGOCtxProfileWriter(raw_ostream &Out, std::optional< unsigned > VersionOverride=std::nullopt, bool IncludeEmpty=false)

Definition PGOCtxProfWriter.cpp:29

void endFlatSection() override

Definition PGOCtxProfWriter.cpp:135

static constexpr StringRef ContainerMagic

static constexpr unsigned CodeLen

void startContextSection() override

Definition PGOCtxProfWriter.cpp:125

void endContextSection() override

Definition PGOCtxProfWriter.cpp:134

void writeFlat(ctx_profile::GUID Guid, const uint64_t *Buffer, size_t BufferSize) override

Definition PGOCtxProfWriter.cpp:157

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

StringRef - Represent a constant reference to a string, i.e.

uint64_t entrycount() const

static size_t getAllocSize(uint32_t NumCounters, uint32_t NumCallsites)

uint32_t counters_size() const

This class implements an extremely fast bulk output stream that can only output to a stream.

raw_ostream & write(unsigned char C)

void mapOptional(StringRef Key, T &Val)

void mapRequired(StringRef Key, T &Val)

The Input class is used to parse a yaml document into in-memory structs and vectors.

@ C

The default llvm calling convention, compatible with C.

initializer< Ty > init(const Ty &Val)

NodeAddr< NodeBase * > Node

This is an optimization pass for GlobalISel generic memory operations.

auto enumerate(FirstRange &&First, RestRanges &&...Rest)

Given two or more input ranges, returns a new range whose values are tuples (A, B,...

LLVM_ABI Error createCtxProfFromYAML(StringRef Profile, raw_ostream &Out)

Definition PGOCtxProfWriter.cpp:258

Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)

Create formatted StringError object.

FunctionAddr VTableAddr uintptr_t uintptr_t Version

FunctionAddr VTableAddr uintptr_t uintptr_t Data

FunctionAddr VTableAddr Next

@ FlatProfilesSectionBlockID

This class should be specialized by any type that needs to be converted to/from a YAML mapping.

static void mapping(yaml::IO &IO, SerializableCtxRepresentation &SCR)

Definition PGOCtxProfWriter.cpp:228

static void mapping(yaml::IO &IO, SerializableFlatProfileRepresentation &SFPR)

Definition PGOCtxProfWriter.cpp:251

static void mapping(yaml::IO &IO, SerializableProfileRepresentation &SPR)

Definition PGOCtxProfWriter.cpp:244

static void mapping(yaml::IO &IO, SerializableRootRepresentation &R)

Definition PGOCtxProfWriter.cpp:236