LLVM  16.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"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringMap.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/Support/Error.h"
23 
24 using namespace llvm;
25 
27 INITIALIZE_PASS(BasicBlockSectionsProfileReader, "bbsections-profile-reader",
28  "Reads and parses a basic block sections profile.", false,
29  false)
30 
31 bool BasicBlockSectionsProfileReader::isFunctionHot(StringRef FuncName) const {
32  return getBBClusterInfoForFunction(FuncName).first;
33 }
34 
35 std::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
60 static 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.");
96  SmallVector<StringRef, 4> BBIndexes;
97  S.split(BBIndexes, ' ');
98  // Reset current cluster position.
99  CurrentPosition = 0;
100  for (auto BBIndexStr : BBIndexes) {
101  unsigned long long BBIndex;
102  if (getAsUnsignedInteger(BBIndexStr, 10, BBIndex))
103  return invalidProfileError(Twine("Unsigned integer expected: '") +
104  BBIndexStr + "'.");
105  if (!FuncBBIDs.insert(BBIndex).second)
106  return invalidProfileError(Twine("Duplicate basic block id found '") +
107  BBIndexStr + "'.");
108  if (!BBIndex && CurrentPosition)
109  return invalidProfileError("Entry BB (0) does not begin a cluster.");
110 
111  FI->second.emplace_back(BBClusterInfo{
112  ((unsigned)BBIndex), 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))
139 }
140 
143  return new BasicBlockSectionsProfileReader(Buf);
144 }
i
i
Definition: README.txt:29
MemoryBuffer.h
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::line_iterator
A forward iterator which reads text lines from a buffer.
Definition: LineIterator.h:33
llvm::ImmutablePass
ImmutablePass class - This class is used to provide information that does not need to be run.
Definition: Pass.h:279
StringRef.h
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1183
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:329
Error.h
llvm::StringMap::end
iterator end()
Definition: StringMap.h:204
llvm::SmallSet
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:136
llvm::StringMap::find
iterator find(StringRef Key)
Definition: StringMap.h:217
llvm::MemoryBuffer
This interface provides simple read-only access to a block of memory, and provides simple methods for...
Definition: MemoryBuffer.h:50
llvm::createBasicBlockSectionsProfileReaderPass
ImmutablePass * createBasicBlockSectionsProfileReaderPass(const MemoryBuffer *Buf)
Definition: BasicBlockSectionsProfileReader.cpp:142
llvm::RISCVFenceField::R
@ R
Definition: RISCVBaseInfo.h:241
getBBClusterInfoForFunction
bool getBBClusterInfoForFunction(const MachineFunction &MF, BasicBlockSectionsProfileReader *BBSectionsProfileReader, std::vector< Optional< BBClusterInfo >> &V)
Definition: BasicBlockSections.cpp:167
llvm::getAsUnsignedInteger
bool getAsUnsignedInteger(StringRef Str, unsigned Radix, unsigned long long &Result)
Helper functions for StringRef::getAsInteger.
Definition: StringRef.cpp:492
llvm::BasicBlockSectionsProfileReader::ID
static char ID
Definition: BasicBlockSectionsProfileReader.h:47
LineIterator.h
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:145
INITIALIZE_PASS
INITIALIZE_PASS(BasicBlockSectionsProfileReader, "bbsections-profile-reader", "Reads and parses a basic block sections profile.", false, false) bool BasicBlockSectionsProfileReader
Definition: BasicBlockSectionsProfileReader.cpp:27
StringMap.h
llvm::StringMap< SmallVector< BBClusterInfo > >
llvm::MemoryBuffer::getBufferIdentifier
virtual StringRef getBufferIdentifier() const
Return an identifier for this buffer, typically the filename it was read from.
Definition: MemoryBuffer.h:75
llvm::BasicBlockSectionsProfileReader::initializePass
void initializePass() override
Read profiles of basic blocks if available here.
Definition: BasicBlockSectionsProfileReader.cpp:134
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::BBClusterInfo
Definition: BasicBlockSectionsProfileReader.h:34
llvm::BasicBlockSectionsProfileReader
Definition: BasicBlockSectionsProfileReader.h:45
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
llvm::inconvertibleErrorCode
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:79
BasicBlockSectionsProfileReader.h
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
llvm::BasicBlockSectionsProfileReader::getBBClusterInfoForFunction
std::pair< bool, SmallVector< BBClusterInfo > > getBBClusterInfoForFunction(StringRef FuncName) const
llvm::SmallSet::insert
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:178
SmallVector.h
llvm::SmallSet::clear
void clear()
Definition: SmallSet.h:217
llvm::StringMap::try_emplace
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:329
SmallSet.h