xref: /freebsd/contrib/llvm-project/llvm/include/llvm/ProfileData/PGOCtxProfReader.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1*0fca6ea1SDimitry Andric //===--- PGOCtxProfReader.h - Contextual profile reader ---------*- C++ -*-===//
2*0fca6ea1SDimitry Andric //
3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0fca6ea1SDimitry Andric //
7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
8*0fca6ea1SDimitry Andric ///
9*0fca6ea1SDimitry Andric /// \file
10*0fca6ea1SDimitry Andric ///
11*0fca6ea1SDimitry Andric /// Reader for contextual iFDO profile, which comes in bitstream format.
12*0fca6ea1SDimitry Andric ///
13*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
14*0fca6ea1SDimitry Andric 
15*0fca6ea1SDimitry Andric #ifndef LLVM_PROFILEDATA_CTXINSTRPROFILEREADER_H
16*0fca6ea1SDimitry Andric #define LLVM_PROFILEDATA_CTXINSTRPROFILEREADER_H
17*0fca6ea1SDimitry Andric 
18*0fca6ea1SDimitry Andric #include "llvm/ADT/DenseSet.h"
19*0fca6ea1SDimitry Andric #include "llvm/Bitstream/BitstreamReader.h"
20*0fca6ea1SDimitry Andric #include "llvm/IR/GlobalValue.h"
21*0fca6ea1SDimitry Andric #include "llvm/ProfileData/PGOCtxProfWriter.h"
22*0fca6ea1SDimitry Andric #include "llvm/Support/Error.h"
23*0fca6ea1SDimitry Andric #include <map>
24*0fca6ea1SDimitry Andric #include <vector>
25*0fca6ea1SDimitry Andric 
26*0fca6ea1SDimitry Andric namespace llvm {
27*0fca6ea1SDimitry Andric /// The loaded contextual profile, suitable for mutation during IPO passes. We
28*0fca6ea1SDimitry Andric /// generally expect a fraction of counters and of callsites to be populated.
29*0fca6ea1SDimitry Andric /// We continue to model counters as vectors, but callsites are modeled as a map
30*0fca6ea1SDimitry Andric /// of a map. The expectation is that, typically, there is a small number of
31*0fca6ea1SDimitry Andric /// indirect targets (usually, 1 for direct calls); but potentially a large
32*0fca6ea1SDimitry Andric /// number of callsites, and, as inlining progresses, the callsite count of a
33*0fca6ea1SDimitry Andric /// caller will grow.
34*0fca6ea1SDimitry Andric class PGOContextualProfile final {
35*0fca6ea1SDimitry Andric public:
36*0fca6ea1SDimitry Andric   using CallTargetMapTy = std::map<GlobalValue::GUID, PGOContextualProfile>;
37*0fca6ea1SDimitry Andric   using CallsiteMapTy = DenseMap<uint32_t, CallTargetMapTy>;
38*0fca6ea1SDimitry Andric 
39*0fca6ea1SDimitry Andric private:
40*0fca6ea1SDimitry Andric   friend class PGOCtxProfileReader;
41*0fca6ea1SDimitry Andric   GlobalValue::GUID GUID = 0;
42*0fca6ea1SDimitry Andric   SmallVector<uint64_t, 16> Counters;
43*0fca6ea1SDimitry Andric   CallsiteMapTy Callsites;
44*0fca6ea1SDimitry Andric 
PGOContextualProfile(GlobalValue::GUID G,SmallVectorImpl<uint64_t> && Counters)45*0fca6ea1SDimitry Andric   PGOContextualProfile(GlobalValue::GUID G,
46*0fca6ea1SDimitry Andric                        SmallVectorImpl<uint64_t> &&Counters)
47*0fca6ea1SDimitry Andric       : GUID(G), Counters(std::move(Counters)) {}
48*0fca6ea1SDimitry Andric 
49*0fca6ea1SDimitry Andric   Expected<PGOContextualProfile &>
50*0fca6ea1SDimitry Andric   getOrEmplace(uint32_t Index, GlobalValue::GUID G,
51*0fca6ea1SDimitry Andric                SmallVectorImpl<uint64_t> &&Counters);
52*0fca6ea1SDimitry Andric 
53*0fca6ea1SDimitry Andric public:
54*0fca6ea1SDimitry Andric   PGOContextualProfile(const PGOContextualProfile &) = delete;
55*0fca6ea1SDimitry Andric   PGOContextualProfile &operator=(const PGOContextualProfile &) = delete;
56*0fca6ea1SDimitry Andric   PGOContextualProfile(PGOContextualProfile &&) = default;
57*0fca6ea1SDimitry Andric   PGOContextualProfile &operator=(PGOContextualProfile &&) = default;
58*0fca6ea1SDimitry Andric 
guid()59*0fca6ea1SDimitry Andric   GlobalValue::GUID guid() const { return GUID; }
counters()60*0fca6ea1SDimitry Andric   const SmallVectorImpl<uint64_t> &counters() const { return Counters; }
callsites()61*0fca6ea1SDimitry Andric   const CallsiteMapTy &callsites() const { return Callsites; }
callsites()62*0fca6ea1SDimitry Andric   CallsiteMapTy &callsites() { return Callsites; }
63*0fca6ea1SDimitry Andric 
hasCallsite(uint32_t I)64*0fca6ea1SDimitry Andric   bool hasCallsite(uint32_t I) const {
65*0fca6ea1SDimitry Andric     return Callsites.find(I) != Callsites.end();
66*0fca6ea1SDimitry Andric   }
67*0fca6ea1SDimitry Andric 
callsite(uint32_t I)68*0fca6ea1SDimitry Andric   const CallTargetMapTy &callsite(uint32_t I) const {
69*0fca6ea1SDimitry Andric     assert(hasCallsite(I) && "Callsite not found");
70*0fca6ea1SDimitry Andric     return Callsites.find(I)->second;
71*0fca6ea1SDimitry Andric   }
72*0fca6ea1SDimitry Andric   void getContainedGuids(DenseSet<GlobalValue::GUID> &Guids) const;
73*0fca6ea1SDimitry Andric };
74*0fca6ea1SDimitry Andric 
75*0fca6ea1SDimitry Andric class PGOCtxProfileReader final {
76*0fca6ea1SDimitry Andric   BitstreamCursor &Cursor;
77*0fca6ea1SDimitry Andric   Expected<BitstreamEntry> advance();
78*0fca6ea1SDimitry Andric   Error readMetadata();
79*0fca6ea1SDimitry Andric   Error wrongValue(const Twine &);
80*0fca6ea1SDimitry Andric   Error unsupported(const Twine &);
81*0fca6ea1SDimitry Andric 
82*0fca6ea1SDimitry Andric   Expected<std::pair<std::optional<uint32_t>, PGOContextualProfile>>
83*0fca6ea1SDimitry Andric   readContext(bool ExpectIndex);
84*0fca6ea1SDimitry Andric   bool canReadContext();
85*0fca6ea1SDimitry Andric 
86*0fca6ea1SDimitry Andric public:
PGOCtxProfileReader(BitstreamCursor & Cursor)87*0fca6ea1SDimitry Andric   PGOCtxProfileReader(BitstreamCursor &Cursor) : Cursor(Cursor) {}
88*0fca6ea1SDimitry Andric 
89*0fca6ea1SDimitry Andric   Expected<std::map<GlobalValue::GUID, PGOContextualProfile>> loadContexts();
90*0fca6ea1SDimitry Andric };
91*0fca6ea1SDimitry Andric } // namespace llvm
92*0fca6ea1SDimitry Andric #endif
93