35 "bbsections-profile-reader",
36 "Reads and parses a basic block sections profile.",
false,
44 return createProfileParseError(
Twine(
"unable to parse basic block id: '") +
46 unsigned long long BaseBBID;
48 return createProfileParseError(
49 Twine(
"unable to parse BB id: '" + Parts[0]) +
50 "': unsigned integer expected");
51 unsigned long long CloneID = 0;
53 return createProfileParseError(
Twine(
"unable to parse clone id: '") +
54 Parts[1] +
"': unsigned integer expected");
55 return UniqueBBID{
static_cast<unsigned>(BaseBBID),
56 static_cast<unsigned>(CloneID)};
63std::pair<bool, SmallVector<BBClusterInfo>>
66 auto R = ProgramPathAndClusterInfo.find(getAliasName(FuncName));
67 return R != ProgramPathAndClusterInfo.end()
68 ? std::pair(
true,
R->second.ClusterInfo)
75 return ProgramPathAndClusterInfo.lookup(getAliasName(FuncName)).ClonePaths;
133Error BasicBlockSectionsProfileReader::ReadV1Profile() {
134 auto FI = ProgramPathAndClusterInfo.end();
137 unsigned CurrentCluster = 0;
139 unsigned CurrentPosition = 0;
151 char Specifier = S[0];
152 S = S.drop_front().trim();
154 S.split(Values,
' ');
159 if (Values.
size() != 1) {
160 return createProfileParseError(
Twine(
"invalid module name value: '") +
167 auto It = FunctionNameToDIFilename.find(Alias);
169 if (It == FunctionNameToDIFilename.end())
173 return DIFilename.
empty() || It->second == DIFilename;
175 if (!FunctionFound) {
178 FI = ProgramPathAndClusterInfo.end();
182 for (
size_t i = 1; i < Values.
size(); ++i)
183 FuncAliasMap.try_emplace(Values[i], Values.
front());
187 auto R = ProgramPathAndClusterInfo.try_emplace(Values.
front());
191 return createProfileParseError(
"duplicate profile for function '" +
192 Values.
front() +
"'");
204 if (FI == ProgramPathAndClusterInfo.end())
208 for (
auto BasicBlockIDStr : Values) {
209 auto BasicBlockID = parseUniqueBBID(BasicBlockIDStr);
211 return BasicBlockID.takeError();
212 if (!FuncBBIDs.
insert(*BasicBlockID).second)
213 return createProfileParseError(
214 Twine(
"duplicate basic block id found '") + BasicBlockIDStr +
218 *std::move(BasicBlockID), CurrentCluster, CurrentPosition++});
225 if (FI == ProgramPathAndClusterInfo.end())
228 FI->second.ClonePaths.push_back({});
229 for (
size_t I = 0;
I < Values.size(); ++
I) {
230 auto BaseBBIDStr = Values[
I];
231 unsigned long long BaseBBID = 0;
233 return createProfileParseError(
Twine(
"unsigned integer expected: '") +
235 if (
I != 0 && !BBsInPath.
insert(BaseBBID).second)
236 return createProfileParseError(
237 Twine(
"duplicate cloned block in path: '") + BaseBBIDStr +
"'");
238 FI->second.ClonePaths.back().push_back(BaseBBID);
243 return createProfileParseError(
Twine(
"invalid specifier: '") +
244 Twine(Specifier) +
"'");
251Error BasicBlockSectionsProfileReader::ReadV0Profile() {
252 auto FI = ProgramPathAndClusterInfo.end();
254 unsigned CurrentCluster = 0;
256 unsigned CurrentPosition = 0;
267 if (!S.consume_front(
"!") || S.empty())
270 if (S.consume_front(
"!")) {
273 if (FI == ProgramPathAndClusterInfo.end())
279 for (
auto BBIDStr : BBIDs) {
280 unsigned long long BBID;
282 return createProfileParseError(
Twine(
"unsigned integer expected: '") +
284 if (!FuncBBIDs.
insert(BBID).second)
285 return createProfileParseError(
286 Twine(
"duplicate basic block id found '") + BBIDStr +
"'");
288 FI->second.ClusterInfo.emplace_back(
291 CurrentPosition++}));
297 auto [AliasesStr, DIFilenameStr] = S.split(
' ');
299 if (DIFilenameStr.starts_with(
"M=")) {
302 if (DIFilename.
empty())
303 return createProfileParseError(
"empty module name specifier");
304 }
else if (!DIFilenameStr.empty()) {
305 return createProfileParseError(
"unknown string found: '" +
306 DIFilenameStr +
"'");
312 AliasesStr.split(Aliases,
'/');
314 auto It = FunctionNameToDIFilename.find(Alias);
316 if (It == FunctionNameToDIFilename.end())
320 return DIFilename.
empty() || It->second == DIFilename;
322 if (!FunctionFound) {
325 FI = ProgramPathAndClusterInfo.end();
328 for (
size_t i = 1; i < Aliases.
size(); ++i)
329 FuncAliasMap.try_emplace(Aliases[i], Aliases.
front());
333 auto R = ProgramPathAndClusterInfo.try_emplace(Aliases.
front());
337 return createProfileParseError(
"duplicate profile for function '" +
338 Aliases.
front() +
"'");
364Error BasicBlockSectionsProfileReader::ReadProfile() {
367 unsigned long long Version = 0;
369 if (FirstLine.consume_front(
"v")) {
371 return createProfileParseError(
Twine(
"version number expected: '") +
375 return createProfileParseError(
Twine(
"invalid profile version: ") +
384 return ReadV0Profile();
386 return ReadV1Profile();
396 BBSPR.FunctionNameToDIFilename.clear();
399 if (
F.isDeclaration())
407 [[maybe_unused]]
bool inserted =
408 BBSPR.FunctionNameToDIFilename.try_emplace(
F.getName(), DIFilename)
412 if (
auto Err =
BBSPR.ReadProfile())
430std::pair<bool, SmallVector<BBClusterInfo>>
This file defines the StringMap class.
This file defines the DenseSet and SmallDenseSet classes.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallSet class.
This file defines the SmallString class.
This file defines the SmallVector class.
A container for analyses that lazily runs them and caches their results.
Result run(Function &F, FunctionAnalysisManager &AM)
bool doInitialization(Module &M) override
doInitialization - Virtual method overridden by subclasses to do any necessary initialization before ...
BasicBlockSectionsProfileReader BBSPR
BasicBlockSectionsProfileReader & getBBSPR()
SmallVector< SmallVector< unsigned > > getClonePathsForFunction(StringRef FuncName) const
bool isFunctionHot(StringRef FuncName) const
std::pair< bool, SmallVector< BBClusterInfo > > getClusterInfoForFunction(StringRef FuncName) const
bool isFunctionHot(StringRef FuncName) const
std::pair< bool, SmallVector< BBClusterInfo > > getClusterInfoForFunction(StringRef FuncName) const
SmallVector< SmallVector< unsigned > > getClonePathsForFunction(StringRef FuncName) const
Implements a dense probed hash-table based set.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
ImmutablePass class - This class is used to provide information that does not need to be run.
This interface provides simple read-only access to a block of memory, and provides simple methods for...
A Module instance is used to store all the information related to an LLVM module.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
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.
constexpr bool empty() const
empty - Check if the string is empty.
const MemoryBuffer * getBBSectionsFuncListBuf() const
Get the list of functions and basic block ids that need unique sections.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
std::pair< iterator, bool > insert(const ValueT &V)
bool is_at_eof() const
Return true if we've reached EOF or are an "end" iterator.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
StringRef remove_leading_dotslash(StringRef path, Style style=Style::native)
Remove redundant leading "./" pieces and consecutive separators.
This is an optimization pass for GlobalISel generic memory operations.
ImmutablePass * createBasicBlockSectionsProfileReaderWrapperPass(const MemoryBuffer *Buf)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
bool getAsUnsignedInteger(StringRef Str, unsigned Radix, unsigned long long &Result)
Helper functions for StringRef::getAsInteger.
Implement std::hash so that hash_code can be used in STL containers.
A special type used by analysis passes to provide an address that identifies that particular analysis...