Skip to content

Commit 08cc058

Browse files
committed
Reland "[Propeller] Promote functions with propeller profiles to .text.hot."
This relands commit 4d8d258. The major change here is using 'addUsedIfAvailable<BasicBlockSectionsProfileReader>()` to make sure we don't change the pipeline tests. Differential Revision: https://reviews.llvm.org/D126518
1 parent b709f07 commit 08cc058

12 files changed

+318
-176
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
//===-- BasicBlockSectionsProfileReader.h - BB sections profile reader pass ==//
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+
// This pass creates the basic block cluster info by reading the basic block
10+
// sections profile. The cluster info will be used by the basic-block-sections
11+
// pass to arrange basic blocks in their sections.
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
#ifndef LLVM_ANALYSIS_BASICBLOCKSECTIONSINFO_H
16+
#define LLVM_ANALYSIS_BASICBLOCKSECTIONSINFO_H
17+
18+
#include "llvm/ADT/Optional.h"
19+
#include "llvm/ADT/SmallSet.h"
20+
#include "llvm/ADT/SmallVector.h"
21+
#include "llvm/ADT/StringMap.h"
22+
#include "llvm/ADT/StringRef.h"
23+
#include "llvm/InitializePasses.h"
24+
#include "llvm/Pass.h"
25+
#include "llvm/Support/Error.h"
26+
#include "llvm/Support/LineIterator.h"
27+
#include "llvm/Support/MemoryBuffer.h"
28+
29+
using namespace llvm;
30+
31+
namespace llvm {
32+
33+
// The cluster information for a machine basic block.
34+
struct BBClusterInfo {
35+
// MachineBasicBlock ID.
36+
unsigned MBBNumber;
37+
// Cluster ID this basic block belongs to.
38+
unsigned ClusterID;
39+
// Position of basic block within the cluster.
40+
unsigned PositionInCluster;
41+
};
42+
43+
using ProgramBBClusterInfoMapTy = StringMap<SmallVector<BBClusterInfo>>;
44+
45+
class BasicBlockSectionsProfileReader : public ImmutablePass {
46+
public:
47+
static char ID;
48+
49+
BasicBlockSectionsProfileReader(const MemoryBuffer *Buf)
50+
: ImmutablePass(ID), MBuf(Buf) {
51+
initializeBasicBlockSectionsProfileReaderPass(
52+
*PassRegistry::getPassRegistry());
53+
};
54+
55+
BasicBlockSectionsProfileReader() : ImmutablePass(ID) {
56+
initializeBasicBlockSectionsProfileReaderPass(
57+
*PassRegistry::getPassRegistry());
58+
}
59+
60+
StringRef getPassName() const override {
61+
return "Basic Block Sections Profile Reader";
62+
}
63+
64+
// Returns true if basic block sections profile exist for function \p
65+
// FuncName.
66+
bool isFunctionHot(StringRef FuncName) const;
67+
68+
// Returns a pair with first element representing whether basic block sections
69+
// profile exist for the function \p FuncName, and the second element
70+
// representing the basic block sections profile (cluster info) for this
71+
// function. If the first element is true and the second element is empty, it
72+
// means unique basic block sections are desired for all basic blocks of the
73+
// function.
74+
std::pair<bool, SmallVector<BBClusterInfo>>
75+
getBBClusterInfoForFunction(StringRef FuncName) const;
76+
77+
/// Read profiles of basic blocks if available here.
78+
void initializePass() override;
79+
80+
private:
81+
StringRef getAliasName(StringRef FuncName) const {
82+
auto R = FuncAliasMap.find(FuncName);
83+
return R == FuncAliasMap.end() ? FuncName : R->second;
84+
}
85+
86+
// This contains the basic-block-sections profile.
87+
const MemoryBuffer *MBuf = nullptr;
88+
89+
// This encapsulates the BB cluster information for the whole program.
90+
//
91+
// For every function name, it contains the cluster information for (all or
92+
// some of) its basic blocks. The cluster information for every basic block
93+
// includes its cluster ID along with the position of the basic block in that
94+
// cluster.
95+
ProgramBBClusterInfoMapTy ProgramBBClusterInfo;
96+
97+
// Some functions have alias names. We use this map to find the main alias
98+
// name for which we have mapping in ProgramBBClusterInfo.
99+
StringMap<StringRef> FuncAliasMap;
100+
};
101+
102+
// Creates a BasicBlockSectionsProfileReader pass to parse the basic block
103+
// sections profile. \p Buf is a memory buffer that contains the list of
104+
// functions and basic block ids to selectively enable basic block sections.
105+
ImmutablePass *
106+
createBasicBlockSectionsProfileReaderPass(const MemoryBuffer *Buf);
107+
108+
} // namespace llvm
109+
#endif // LLVM_ANALYSIS_BASICBLOCKSECTIONSINFO_H

Diff for: llvm/include/llvm/CodeGen/Passes.h

+2-4
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,8 @@ namespace llvm {
5151
FunctionPass *createUnreachableBlockEliminationPass();
5252

5353
/// createBasicBlockSections Pass - This pass assigns sections to machine
54-
/// basic blocks and is enabled with -fbasic-block-sections. Buf is a memory
55-
/// buffer that contains the list of functions and basic block ids to
56-
/// selectively enable basic block sections.
57-
MachineFunctionPass *createBasicBlockSectionsPass(const MemoryBuffer *Buf);
54+
/// basic blocks and is enabled with -fbasic-block-sections.
55+
MachineFunctionPass *createBasicBlockSectionsPass();
5856

5957
/// createMachineFunctionSplitterPass - This pass splits machine functions
6058
/// using profile information.

Diff for: llvm/include/llvm/InitializePasses.h

+1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ void initializeAssumptionCacheTrackerPass(PassRegistry&);
7676
void initializeAtomicExpandPass(PassRegistry&);
7777
void initializeAttributorLegacyPassPass(PassRegistry&);
7878
void initializeAttributorCGSCCLegacyPassPass(PassRegistry &);
79+
void initializeBasicBlockSectionsProfileReaderPass(PassRegistry &);
7980
void initializeBasicBlockSectionsPass(PassRegistry &);
8081
void initializeBDCELegacyPassPass(PassRegistry&);
8182
void initializeBarrierNoopPass(PassRegistry&);

Diff for: llvm/lib/CodeGen/BasicBlockSections.cpp

+16-153
Original file line numberDiff line numberDiff line change
@@ -69,25 +69,17 @@
6969
//===----------------------------------------------------------------------===//
7070

7171
#include "llvm/ADT/Optional.h"
72-
#include "llvm/ADT/SmallSet.h"
7372
#include "llvm/ADT/SmallVector.h"
74-
#include "llvm/ADT/StringMap.h"
7573
#include "llvm/ADT/StringRef.h"
74+
#include "llvm/CodeGen/BasicBlockSectionsProfileReader.h"
7675
#include "llvm/CodeGen/BasicBlockSectionUtils.h"
7776
#include "llvm/CodeGen/MachineFunction.h"
7877
#include "llvm/CodeGen/MachineFunctionPass.h"
7978
#include "llvm/CodeGen/Passes.h"
8079
#include "llvm/CodeGen/TargetInstrInfo.h"
8180
#include "llvm/InitializePasses.h"
82-
#include "llvm/Support/Error.h"
83-
#include "llvm/Support/LineIterator.h"
84-
#include "llvm/Support/MemoryBuffer.h"
8581
#include "llvm/Target/TargetMachine.h"
8682

87-
using llvm::SmallSet;
88-
using llvm::SmallVector;
89-
using llvm::StringMap;
90-
using llvm::StringRef;
9183
using namespace llvm;
9284

9385
// Placing the cold clusters in a separate section mitigates against poor
@@ -107,41 +99,11 @@ cl::opt<bool> BBSectionsDetectSourceDrift(
10799

108100
namespace {
109101

110-
// This struct represents the cluster information for a machine basic block.
111-
struct BBClusterInfo {
112-
// MachineBasicBlock ID.
113-
unsigned MBBNumber;
114-
// Cluster ID this basic block belongs to.
115-
unsigned ClusterID;
116-
// Position of basic block within the cluster.
117-
unsigned PositionInCluster;
118-
};
119-
120-
using ProgramBBClusterInfoMapTy = StringMap<SmallVector<BBClusterInfo, 4>>;
121-
122102
class BasicBlockSections : public MachineFunctionPass {
123103
public:
124104
static char ID;
125105

126-
// This contains the basic-block-sections profile.
127-
const MemoryBuffer *MBuf = nullptr;
128-
129-
// This encapsulates the BB cluster information for the whole program.
130-
//
131-
// For every function name, it contains the cluster information for (all or
132-
// some of) its basic blocks. The cluster information for every basic block
133-
// includes its cluster ID along with the position of the basic block in that
134-
// cluster.
135-
ProgramBBClusterInfoMapTy ProgramBBClusterInfo;
136-
137-
// Some functions have alias names. We use this map to find the main alias
138-
// name for which we have mapping in ProgramBBClusterInfo.
139-
StringMap<StringRef> FuncAliasMap;
140-
141-
BasicBlockSections(const MemoryBuffer *Buf)
142-
: MachineFunctionPass(ID), MBuf(Buf) {
143-
initializeBasicBlockSectionsPass(*PassRegistry::getPassRegistry());
144-
};
106+
BasicBlockSectionsProfileReader *BBSectionsProfileReader = nullptr;
145107

146108
BasicBlockSections() : MachineFunctionPass(ID) {
147109
initializeBasicBlockSectionsPass(*PassRegistry::getPassRegistry());
@@ -153,9 +115,6 @@ class BasicBlockSections : public MachineFunctionPass {
153115

154116
void getAnalysisUsage(AnalysisUsage &AU) const override;
155117

156-
/// Read profiles of basic blocks if available here.
157-
bool doInitialization(Module &M) override;
158-
159118
/// Identify basic blocks that need separate sections and prepare to emit them
160119
/// accordingly.
161120
bool runOnMachineFunction(MachineFunction &MF) override;
@@ -205,29 +164,26 @@ static void updateBranches(
205164

206165
// This function provides the BBCluster information associated with a function.
207166
// Returns true if a valid association exists and false otherwise.
208-
static bool getBBClusterInfoForFunction(
209-
const MachineFunction &MF, const StringMap<StringRef> FuncAliasMap,
210-
const ProgramBBClusterInfoMapTy &ProgramBBClusterInfo,
167+
bool getBBClusterInfoForFunction(
168+
const MachineFunction &MF,
169+
BasicBlockSectionsProfileReader *BBSectionsProfileReader,
211170
std::vector<Optional<BBClusterInfo>> &V) {
212-
// Get the main alias name for the function.
213-
auto FuncName = MF.getName();
214-
auto R = FuncAliasMap.find(FuncName);
215-
StringRef AliasName = R == FuncAliasMap.end() ? FuncName : R->second;
216171

217172
// Find the assoicated cluster information.
218-
auto P = ProgramBBClusterInfo.find(AliasName);
219-
if (P == ProgramBBClusterInfo.end())
173+
std::pair<bool, SmallVector<BBClusterInfo, 4>> P =
174+
BBSectionsProfileReader->getBBClusterInfoForFunction(MF.getName());
175+
if (!P.first)
220176
return false;
221177

222-
if (P->second.empty()) {
178+
if (P.second.empty()) {
223179
// This indicates that sections are desired for all basic blocks of this
224180
// function. We clear the BBClusterInfo vector to denote this.
225181
V.clear();
226182
return true;
227183
}
228184

229185
V.resize(MF.getNumBlockIDs());
230-
for (auto bbClusterInfo : P->second) {
186+
for (auto bbClusterInfo : P.second) {
231187
// Bail out if the cluster information contains invalid MBB numbers.
232188
if (bbClusterInfo.MBBNumber >= MF.getNumBlockIDs())
233189
return false;
@@ -376,9 +332,11 @@ bool BasicBlockSections::runOnMachineFunction(MachineFunction &MF) {
376332
return true;
377333
}
378334

335+
BBSectionsProfileReader = &getAnalysis<BasicBlockSectionsProfileReader>();
336+
379337
std::vector<Optional<BBClusterInfo>> FuncBBClusterInfo;
380338
if (BBSectionsType == BasicBlockSection::List &&
381-
!getBBClusterInfoForFunction(MF, FuncAliasMap, ProgramBBClusterInfo,
339+
!getBBClusterInfoForFunction(MF, BBSectionsProfileReader,
382340
FuncBBClusterInfo))
383341
return true;
384342
MF.setBBSectionsType(BBSectionsType);
@@ -426,107 +384,12 @@ bool BasicBlockSections::runOnMachineFunction(MachineFunction &MF) {
426384
return true;
427385
}
428386

429-
// Basic Block Sections can be enabled for a subset of machine basic blocks.
430-
// This is done by passing a file containing names of functions for which basic
431-
// block sections are desired. Additionally, machine basic block ids of the
432-
// functions can also be specified for a finer granularity. Moreover, a cluster
433-
// of basic blocks could be assigned to the same section.
434-
// A file with basic block sections for all of function main and three blocks
435-
// for function foo (of which 1 and 2 are placed in a cluster) looks like this:
436-
// ----------------------------
437-
// list.txt:
438-
// !main
439-
// !foo
440-
// !!1 2
441-
// !!4
442-
static Error getBBClusterInfo(const MemoryBuffer *MBuf,
443-
ProgramBBClusterInfoMapTy &ProgramBBClusterInfo,
444-
StringMap<StringRef> &FuncAliasMap) {
445-
assert(MBuf);
446-
line_iterator LineIt(*MBuf, /*SkipBlanks=*/true, /*CommentMarker=*/'#');
447-
448-
auto invalidProfileError = [&](auto Message) {
449-
return make_error<StringError>(
450-
Twine("Invalid profile " + MBuf->getBufferIdentifier() + " at line " +
451-
Twine(LineIt.line_number()) + ": " + Message),
452-
inconvertibleErrorCode());
453-
};
454-
455-
auto FI = ProgramBBClusterInfo.end();
456-
457-
// Current cluster ID corresponding to this function.
458-
unsigned CurrentCluster = 0;
459-
// Current position in the current cluster.
460-
unsigned CurrentPosition = 0;
461-
462-
// Temporary set to ensure every basic block ID appears once in the clusters
463-
// of a function.
464-
SmallSet<unsigned, 4> FuncBBIDs;
465-
466-
for (; !LineIt.is_at_eof(); ++LineIt) {
467-
StringRef S(*LineIt);
468-
if (S[0] == '@')
469-
continue;
470-
// Check for the leading "!"
471-
if (!S.consume_front("!") || S.empty())
472-
break;
473-
// Check for second "!" which indicates a cluster of basic blocks.
474-
if (S.consume_front("!")) {
475-
if (FI == ProgramBBClusterInfo.end())
476-
return invalidProfileError(
477-
"Cluster list does not follow a function name specifier.");
478-
SmallVector<StringRef, 4> BBIndexes;
479-
S.split(BBIndexes, ' ');
480-
// Reset current cluster position.
481-
CurrentPosition = 0;
482-
for (auto BBIndexStr : BBIndexes) {
483-
unsigned long long BBIndex;
484-
if (getAsUnsignedInteger(BBIndexStr, 10, BBIndex))
485-
return invalidProfileError(Twine("Unsigned integer expected: '") +
486-
BBIndexStr + "'.");
487-
if (!FuncBBIDs.insert(BBIndex).second)
488-
return invalidProfileError(Twine("Duplicate basic block id found '") +
489-
BBIndexStr + "'.");
490-
if (!BBIndex && CurrentPosition)
491-
return invalidProfileError("Entry BB (0) does not begin a cluster.");
492-
493-
FI->second.emplace_back(BBClusterInfo{
494-
((unsigned)BBIndex), CurrentCluster, CurrentPosition++});
495-
}
496-
CurrentCluster++;
497-
} else { // This is a function name specifier.
498-
// Function aliases are separated using '/'. We use the first function
499-
// name for the cluster info mapping and delegate all other aliases to
500-
// this one.
501-
SmallVector<StringRef, 4> Aliases;
502-
S.split(Aliases, '/');
503-
for (size_t i = 1; i < Aliases.size(); ++i)
504-
FuncAliasMap.try_emplace(Aliases[i], Aliases.front());
505-
506-
// Prepare for parsing clusters of this function name.
507-
// Start a new cluster map for this function name.
508-
FI = ProgramBBClusterInfo.try_emplace(Aliases.front()).first;
509-
CurrentCluster = 0;
510-
FuncBBIDs.clear();
511-
}
512-
}
513-
return Error::success();
514-
}
515-
516-
bool BasicBlockSections::doInitialization(Module &M) {
517-
if (!MBuf)
518-
return false;
519-
if (auto Err = getBBClusterInfo(MBuf, ProgramBBClusterInfo, FuncAliasMap))
520-
report_fatal_error(std::move(Err));
521-
return false;
522-
}
523-
524387
void BasicBlockSections::getAnalysisUsage(AnalysisUsage &AU) const {
525388
AU.setPreservesAll();
389+
AU.addRequired<BasicBlockSectionsProfileReader>();
526390
MachineFunctionPass::getAnalysisUsage(AU);
527391
}
528392

529-
MachineFunctionPass *
530-
llvm::createBasicBlockSectionsPass(const MemoryBuffer *Buf) {
531-
return new BasicBlockSections(Buf);
393+
MachineFunctionPass *llvm::createBasicBlockSectionsPass() {
394+
return new BasicBlockSections();
532395
}

0 commit comments

Comments
 (0)