LLVM 17.0.0git
BasicBlockSectionsProfileReader.cpp
Go to the documentation of this file.
1//===-- BasicBlockSectionsProfileReader.cpp -------------------------------===//
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// Implementation of the basic block sections profile reader pass. It parses
10// and stores the basic block sections profile file (which is specified via the
11// `-basic-block-sections` flag).
12//
13//===----------------------------------------------------------------------===//
14
16#include "llvm/ADT/SmallSet.h"
18#include "llvm/ADT/StringMap.h"
19#include "llvm/ADT/StringRef.h"
20#include "llvm/Support/Error.h"
23
24using namespace llvm;
25
28 "Reads and parses a basic block sections profile.", false,
29 false)
30
31bool BasicBlockSectionsProfileReader::isFunctionHot(StringRef FuncName) const {
32 return getBBClusterInfoForFunction(FuncName).first;
33}
34
35std::pair<bool, SmallVector<BBClusterInfo>>
37 StringRef FuncName) const {
38 std::pair<bool, SmallVector<BBClusterInfo>> cluster_info(false, {});
39 auto R = ProgramBBClusterInfo.find(getAliasName(FuncName));
40 if (R != ProgramBBClusterInfo.end()) {
41 cluster_info.second = R->second;
42 cluster_info.first = true;
43 }
44 return cluster_info;
45}
46
47// Basic Block Sections can be enabled for a subset of machine basic blocks.
48// This is done by passing a file containing names of functions for which basic
49// block sections are desired. Additionally, machine basic block ids of the
50// functions can also be specified for a finer granularity. Moreover, a cluster
51// of basic blocks could be assigned to the same section.
52// A file with basic block sections for all of function main and three blocks
53// for function foo (of which 1 and 2 are placed in a cluster) looks like this:
54// ----------------------------
55// list.txt:
56// !main
57// !foo
58// !!1 2
59// !!4
60static Error getBBClusterInfo(const MemoryBuffer *MBuf,
61 ProgramBBClusterInfoMapTy &ProgramBBClusterInfo,
62 StringMap<StringRef> &FuncAliasMap) {
63 assert(MBuf);
64 line_iterator LineIt(*MBuf, /*SkipBlanks=*/true, /*CommentMarker=*/'#');
65
66 auto invalidProfileError = [&](auto Message) {
67 return make_error<StringError>(
68 Twine("Invalid profile " + MBuf->getBufferIdentifier() + " at line " +
69 Twine(LineIt.line_number()) + ": " + Message),
71 };
72
73 auto FI = ProgramBBClusterInfo.end();
74
75 // Current cluster ID corresponding to this function.
76 unsigned CurrentCluster = 0;
77 // Current position in the current cluster.
78 unsigned CurrentPosition = 0;
79
80 // Temporary set to ensure every basic block ID appears once in the clusters
81 // of a function.
82 SmallSet<unsigned, 4> FuncBBIDs;
83
84 for (; !LineIt.is_at_eof(); ++LineIt) {
85 StringRef S(*LineIt);
86 if (S[0] == '@')
87 continue;
88 // Check for the leading "!"
89 if (!S.consume_front("!") || S.empty())
90 break;
91 // Check for second "!" which indicates a cluster of basic blocks.
92 if (S.consume_front("!")) {
93 if (FI == ProgramBBClusterInfo.end())
94 return invalidProfileError(
95 "Cluster list does not follow a function name specifier.");
97 S.split(BBIDs, ' ');
98 // Reset current cluster position.
99 CurrentPosition = 0;
100 for (auto BBIDStr : BBIDs) {
101 unsigned long long BBID;
102 if (getAsUnsignedInteger(BBIDStr, 10, BBID))
103 return invalidProfileError(Twine("Unsigned integer expected: '") +
104 BBIDStr + "'.");
105 if (!FuncBBIDs.insert(BBID).second)
106 return invalidProfileError(Twine("Duplicate basic block id found '") +
107 BBIDStr + "'.");
108 if (BBID == 0 && CurrentPosition)
109 return invalidProfileError("Entry BB (0) does not begin a cluster.");
110
111 FI->second.emplace_back(
112 BBClusterInfo{((unsigned)BBID), CurrentCluster, CurrentPosition++});
113 }
114 CurrentCluster++;
115 } else { // This is a function name specifier.
116 // Function aliases are separated using '/'. We use the first function
117 // name for the cluster info mapping and delegate all other aliases to
118 // this one.
120 S.split(Aliases, '/');
121 for (size_t i = 1; i < Aliases.size(); ++i)
122 FuncAliasMap.try_emplace(Aliases[i], Aliases.front());
123
124 // Prepare for parsing clusters of this function name.
125 // Start a new cluster map for this function name.
126 FI = ProgramBBClusterInfo.try_emplace(Aliases.front()).first;
127 CurrentCluster = 0;
128 FuncBBIDs.clear();
129 }
130 }
131 return Error::success();
132}
133
135 if (!MBuf)
136 return;
137 if (auto Err = getBBClusterInfo(MBuf, ProgramBBClusterInfo, FuncAliasMap))
138 report_fatal_error(std::move(Err));
139}
140
143 return new BasicBlockSectionsProfileReader(Buf);
144}
This file defines the StringMap class.
bool getBBClusterInfoForFunction(const MachineFunction &MF, BasicBlockSectionsProfileReader *BBSectionsProfileReader, DenseMap< unsigned, BBClusterInfo > &V)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:38
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallSet class.
This file defines the SmallVector class.
std::pair< bool, SmallVector< BBClusterInfo > > getBBClusterInfoForFunction(StringRef FuncName) const
void initializePass() override
Read profiles of basic blocks if available here.
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
static ErrorSuccess success()
Create a success value.
Definition: Error.h:330
ImmutablePass class - This class is used to provide information that does not need to be run.
Definition: Pass.h:279
This interface provides simple read-only access to a block of memory, and provides simple methods for...
Definition: MemoryBuffer.h:51
virtual StringRef getBufferIdentifier() const
Return an identifier for this buffer, typically the filename it was read from.
Definition: MemoryBuffer.h:76
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:135
void clear()
Definition: SmallSet.h:216
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition: SmallSet.h:177
size_t size() const
Definition: SmallVector.h:91
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
iterator end()
Definition: StringMap.h:204
iterator find(StringRef Key)
Definition: StringMap.h:217
std::pair< iterator, bool > try_emplace(StringRef Key, ArgsTy &&...Args)
Emplace a new element for the specified key into the map if the key isn't already in the map.
Definition: StringMap.h:340
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
A forward iterator which reads text lines from a buffer.
Definition: LineIterator.h:33
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:79
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:145
bool getAsUnsignedInteger(StringRef Str, unsigned Radix, unsigned long long &Result)
Helper functions for StringRef::getAsInteger.
Definition: StringRef.cpp:492
ImmutablePass * createBasicBlockSectionsProfileReaderPass(const MemoryBuffer *Buf)