Skip to content

Commit c4b73ba

Browse files
committed
feat(AsmPrinter): Add support for emitting prefetch target symbols
1 parent 9697f4b commit c4b73ba

File tree

5 files changed

+174
-2
lines changed

5 files changed

+174
-2
lines changed

llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,17 @@ struct BBClusterInfo {
4242
unsigned PositionInCluster;
4343
};
4444

45+
struct BBPosition {
46+
UniqueBBID BBID;
47+
unsigned BBOffset;
48+
};
49+
50+
struct PrefetchHint {
51+
BBPosition SitePosition;
52+
StringRef TargetFunctionName;
53+
BBPosition TargetPosition;
54+
};
55+
4556
// This represents the raw input profile for one function.
4657
struct FunctionPathAndClusterInfo {
4758
// BB Cluster information specified by `UniqueBBID`s.
@@ -50,16 +61,39 @@ struct FunctionPathAndClusterInfo {
5061
// the edge a -> b (a is not cloned). The index of the path in this vector
5162
// determines the `UniqueBBID::CloneID` of the cloned blocks in that path.
5263
SmallVector<SmallVector<unsigned>> ClonePaths;
64+
SmallVector<PrefetchHint> PrefetchHints;
65+
DenseSet<BBPosition> PrefetchTargets;
5366
// Node counts for each basic block.
5467
DenseMap<UniqueBBID, uint64_t> NodeCounts;
55-
// Edge counts for each edge, stored as a nested map.
68+
// Edge counts for each edge.
5669
DenseMap<UniqueBBID, DenseMap<UniqueBBID, uint64_t>> EdgeCounts;
5770
// Hash for each basic block. The Hashes are stored for every original block
5871
// (not cloned blocks), hence the map key being unsigned instead of
5972
// UniqueBBID.
6073
DenseMap<unsigned, uint64_t> BBHashes;
6174
};
6275

76+
// Provides DenseMapInfo BBPosition.
77+
template <> struct DenseMapInfo<BBPosition> {
78+
static inline BBPosition getEmptyKey() {
79+
return {DenseMapInfo<UniqueBBID>::getEmptyKey(),
80+
DenseMapInfo<unsigned>::getEmptyKey()};
81+
}
82+
static inline BBPosition getTombstoneKey() {
83+
return BBPosition{DenseMapInfo<UniqueBBID>::getTombstoneKey(),
84+
DenseMapInfo<unsigned>::getTombstoneKey()};
85+
}
86+
static unsigned getHashValue(const BBPosition &Val) {
87+
std::pair<unsigned, unsigned> PairVal = std::make_pair(
88+
DenseMapInfo<UniqueBBID>::getHashValue(Val.BBID), Val.BBOffset);
89+
return DenseMapInfo<std::pair<unsigned, unsigned>>::getHashValue(PairVal);
90+
}
91+
static bool isEqual(const BBPosition &LHS, const BBPosition &RHS) {
92+
return DenseMapInfo<UniqueBBID>::isEqual(LHS.BBID, RHS.BBID) &&
93+
DenseMapInfo<unsigned>::isEqual(LHS.BBOffset, RHS.BBOffset);
94+
}
95+
};
96+
6397
class BasicBlockSectionsProfileReader {
6498
public:
6599
friend class BasicBlockSectionsProfileReaderWrapperPass;
@@ -86,6 +120,11 @@ class BasicBlockSectionsProfileReader {
86120
uint64_t getEdgeCount(StringRef FuncName, const UniqueBBID &SrcBBID,
87121
const UniqueBBID &SinkBBID) const;
88122

123+
SmallVector<PrefetchHint>
124+
getPrefetchHintsForFunction(StringRef FuncName) const;
125+
126+
DenseSet<BBPosition> getPrefetchTargetsForFunction(StringRef FuncName) const;
127+
89128
private:
90129
StringRef getAliasName(StringRef FuncName) const {
91130
auto R = FuncAliasMap.find(FuncName);
@@ -194,6 +233,10 @@ class BasicBlockSectionsProfileReaderWrapperPass : public ImmutablePass {
194233

195234
uint64_t getEdgeCount(StringRef FuncName, const UniqueBBID &SrcBBID,
196235
const UniqueBBID &DestBBID) const;
236+
SmallVector<PrefetchHint>
237+
getPrefetchHintsForFunction(StringRef FuncName) const;
238+
239+
DenseSet<BBPosition> getPrefetchTargetsForFunction(StringRef FuncName) const;
197240

198241
// Initializes the FunctionNameToDIFilename map for the current module and
199242
// then reads the profile for the matching functions.

llvm/include/llvm/CodeGen/MachineBasicBlock.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,12 @@ template <> struct DenseMapInfo<MBBSectionID> {
100100
}
101101
};
102102

103+
struct PrefetchTarget {
104+
StringRef TargetFunction;
105+
UniqueBBID TargetBBID;
106+
unsigned TargetBBOffset;
107+
};
108+
103109
template <> struct ilist_traits<MachineInstr> {
104110
private:
105111
friend class MachineBasicBlock; // Set by the owning MachineBasicBlock.
@@ -213,6 +219,8 @@ class MachineBasicBlock
213219
/// basic block sections and basic block labels.
214220
std::optional<UniqueBBID> BBID;
215221

222+
SmallVector<unsigned> PrefetchTargets;
223+
216224
/// With basic block sections, this stores the Section ID of the basic block.
217225
MBBSectionID SectionID{0};
218226

@@ -229,6 +237,8 @@ class MachineBasicBlock
229237
/// is only computed once and is cached.
230238
mutable MCSymbol *CachedMCSymbol = nullptr;
231239

240+
mutable SmallVector<MCSymbol *, 4> CallInstSymbols;
241+
232242
/// Cached MCSymbol for this block (used if IsEHContTarget).
233243
mutable MCSymbol *CachedEHContMCSymbol = nullptr;
234244

@@ -710,6 +720,14 @@ class MachineBasicBlock
710720

711721
std::optional<UniqueBBID> getBBID() const { return BBID; }
712722

723+
const SmallVector<unsigned> &getPrefetchTargets() const {
724+
return PrefetchTargets;
725+
}
726+
727+
void setPrefetchTargets(const SmallVector<unsigned> &V) {
728+
PrefetchTargets = V;
729+
}
730+
713731
/// Returns the section ID of this basic block.
714732
MBBSectionID getSectionID() const { return SectionID; }
715733

@@ -1275,6 +1293,12 @@ class MachineBasicBlock
12751293
/// Return the MCSymbol for this basic block.
12761294
LLVM_ABI MCSymbol *getSymbol() const;
12771295

1296+
MCSymbol *getCallInstSymbol(unsigned CallInstNumber) const;
1297+
1298+
const SmallVector<MCSymbol *, 4>& getCallInstSymbols() const {
1299+
return CallInstSymbols;
1300+
}
1301+
12781302
/// Return the Windows EH Continuation Symbol for this basic block.
12791303
LLVM_ABI MCSymbol *getEHContSymbol() const;
12801304

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "WasmException.h"
1919
#include "WinCFGuard.h"
2020
#include "WinException.h"
21+
#include "llvm/Support/SMLoc.h"
2122
#include "llvm/ADT/APFloat.h"
2223
#include "llvm/ADT/APInt.h"
2324
#include "llvm/ADT/BitmaskEnum.h"
@@ -178,6 +179,11 @@ static cl::opt<bool> EmitJumpTableSizesSection(
178179
cl::desc("Emit a section containing jump table addresses and sizes"),
179180
cl::Hidden, cl::init(false));
180181

182+
static cl::opt<bool> InsertNoopsForPrefetch(
183+
"insert-noops-for-prefetch",
184+
cl::desc("Whether to insert noops instead of prefetches."), cl::init(false),
185+
cl::Hidden);
186+
181187
// This isn't turned on by default, since several of the scheduling models are
182188
// not completely accurate, and we don't want to be misleading.
183189
static cl::opt<bool> PrintLatency(
@@ -1982,10 +1988,34 @@ void AsmPrinter::emitFunctionBody() {
19821988
FunctionCallGraphInfo FuncCGInfo;
19831989
const auto &CallSitesInfoMap = MF->getCallSitesInfo();
19841990
for (auto &MBB : *MF) {
1991+
int NextPrefetchTargetIndex = MBB.getPrefetchTargets().empty() ? -1 : 0;
19851992
// Print a label for the basic block.
19861993
emitBasicBlockStart(MBB);
19871994
DenseMap<StringRef, unsigned> MnemonicCounts;
1995+
unsigned NumCallsInBlock = 0;
19881996
for (auto &MI : MBB) {
1997+
if (NextPrefetchTargetIndex != -1 &&
1998+
NumCallsInBlock >= MBB.getPrefetchTargets()[NextPrefetchTargetIndex]) {
1999+
2000+
MCSymbol *PrefetchTargetSymbol = OutContext.getOrCreateSymbol(
2001+
Twine("__llvm_prefetch_target_") + MF->getName() + Twine("_") + utostr(MBB.getBBID()->BaseID) +
2002+
Twine("_") +
2003+
utostr(MBB.getPrefetchTargets()[NextPrefetchTargetIndex]));
2004+
if (MF->getFunction().isWeakForLinker()) {
2005+
OutStreamer->emitSymbolAttribute(PrefetchTargetSymbol, MCSA_Weak);
2006+
errs() << "Emitting weak symbol: " << PrefetchTargetSymbol->getName() << "\n";
2007+
} else {
2008+
OutStreamer->emitSymbolAttribute(PrefetchTargetSymbol, MCSA_Global);
2009+
errs() << "Emitting global symbol: " << PrefetchTargetSymbol->getName() << "\n";
2010+
}
2011+
// OutStreamer->emitSymbolAttribute(PrefetchTargetSymbol, MCSA_Extern);
2012+
// errs() << "Emitting symbol: " << PrefetchTargetSymbol->getName() << "\n";
2013+
OutStreamer->emitLabel(PrefetchTargetSymbol);
2014+
++NextPrefetchTargetIndex;
2015+
if (NextPrefetchTargetIndex >=
2016+
static_cast<int>(MBB.getPrefetchTargets().size()))
2017+
NextPrefetchTargetIndex = -1;
2018+
}
19892019
// Print the assembly for the instruction.
19902020
if (!MI.isPosition() && !MI.isImplicitDef() && !MI.isKill() &&
19912021
!MI.isDebugInstr()) {
@@ -2099,7 +2129,7 @@ void AsmPrinter::emitFunctionBody() {
20992129
break;
21002130
}
21012131
default:
2102-
emitInstruction(&MI);
2132+
emitInstruction(&MI);
21032133

21042134
auto CountInstruction = [&](const MachineInstr &MI) {
21052135
// Skip Meta instructions inside bundles.
@@ -2136,6 +2166,24 @@ void AsmPrinter::emitFunctionBody() {
21362166
for (auto &Handler : Handlers)
21372167
Handler->endInstruction();
21382168
}
2169+
while (NextPrefetchTargetIndex != -1) {
2170+
MCSymbol *PrefetchTargetSymbol = OutContext.getOrCreateSymbol(
2171+
Twine("__llvm_prefetch_target_") + MF->getName() + Twine("_") + utostr(MBB.getBBID()->BaseID) +
2172+
Twine("_") +
2173+
utostr(MBB.getPrefetchTargets()[NextPrefetchTargetIndex]));
2174+
if (MF->getFunction().hasWeakLinkage()) {
2175+
OutStreamer->emitSymbolAttribute(PrefetchTargetSymbol, MCSA_WeakDefinition);
2176+
} else {
2177+
OutStreamer->emitSymbolAttribute(PrefetchTargetSymbol, MCSA_Global);
2178+
}
2179+
OutStreamer->emitSymbolAttribute(PrefetchTargetSymbol, MCSA_Extern);
2180+
OutStreamer->emitLabel(PrefetchTargetSymbol);
2181+
++NextPrefetchTargetIndex;
2182+
if (NextPrefetchTargetIndex >=
2183+
static_cast<int>(MBB.getPrefetchTargets().size()))
2184+
NextPrefetchTargetIndex = -1;
2185+
}
2186+
21392187

21402188
// We must emit temporary symbol for the end of this basic block, if either
21412189
// we have BBLabels enabled or if this basic blocks marks the end of a

llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,19 @@ uint64_t BasicBlockSectionsProfileReader::getEdgeCount(
9393
return EdgeIt->second;
9494
}
9595

96+
SmallVector<PrefetchHint>
97+
BasicBlockSectionsProfileReader::getPrefetchHintsForFunction(
98+
StringRef FuncName) const {
99+
return ProgramPathAndClusterInfo.lookup(getAliasName(FuncName)).PrefetchHints;
100+
}
101+
102+
DenseSet<BBPosition>
103+
BasicBlockSectionsProfileReader::getPrefetchTargetsForFunction(
104+
StringRef FuncName) const {
105+
return ProgramPathAndClusterInfo.lookup(getAliasName(FuncName))
106+
.PrefetchTargets;
107+
}
108+
96109
// Reads the version 1 basic block sections profile. Profile for each function
97110
// is encoded as follows:
98111
// m <module_name>
@@ -308,6 +321,25 @@ Error BasicBlockSectionsProfileReader::ReadV1Profile() {
308321
}
309322
continue;
310323
}
324+
case 't': { // Prefetch target specifier.
325+
// Skip the profile when we the profile iterator (FI) refers to the
326+
// past-the-end element.
327+
if (FI == ProgramPathAndClusterInfo.end())
328+
continue;
329+
assert(Values.size() == 1);
330+
SmallVector<StringRef, 2> PrefetchTargetStr;
331+
Values[0].split(PrefetchTargetStr, '@');
332+
assert(PrefetchTargetStr.size() == 2);
333+
auto TargetBBID = parseUniqueBBID(PrefetchTargetStr[0]);
334+
if (!TargetBBID)
335+
return TargetBBID.takeError();
336+
unsigned long long TargetBBOffset;
337+
if (getAsUnsignedInteger(PrefetchTargetStr[1], 10, TargetBBOffset))
338+
return createProfileParseError(Twine("unsigned integer expected: '") +
339+
PrefetchTargetStr[1]);
340+
FI->second.PrefetchTargets.insert(BBPosition{*TargetBBID, static_cast<unsigned>(TargetBBOffset)});
341+
continue;
342+
}
311343
default:
312344
return createProfileParseError(Twine("invalid specifier: '") +
313345
Twine(Specifier) + "'");
@@ -514,6 +546,18 @@ uint64_t BasicBlockSectionsProfileReaderWrapperPass::getEdgeCount(
514546
return BBSPR.getEdgeCount(FuncName, SrcBBID, SinkBBID);
515547
}
516548

549+
SmallVector<PrefetchHint>
550+
BasicBlockSectionsProfileReaderWrapperPass::getPrefetchHintsForFunction(
551+
StringRef FuncName) const {
552+
return BBSPR.getPrefetchHintsForFunction(FuncName);
553+
}
554+
555+
DenseSet<BBPosition>
556+
BasicBlockSectionsProfileReaderWrapperPass::getPrefetchTargetsForFunction(
557+
StringRef FuncName) const {
558+
return BBSPR.getPrefetchTargetsForFunction(FuncName);
559+
}
560+
517561
BasicBlockSectionsProfileReader &
518562
BasicBlockSectionsProfileReaderWrapperPass::getBBSPR() {
519563
return BBSPR;

llvm/lib/CodeGen/MachineBasicBlock.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,19 @@ MCSymbol *MachineBasicBlock::getSymbol() const {
9090
return CachedMCSymbol;
9191
}
9292

93+
MCSymbol *MachineBasicBlock::getCallInstSymbol(unsigned CallInstNumber) const {
94+
if (CallInstSymbols.size() <= CallInstNumber) {
95+
const MachineFunction *MF = getParent();
96+
MCContext &Ctx = MF->getContext();
97+
CallInstSymbols.resize(CallInstNumber + 1);
98+
CallInstSymbols[CallInstNumber] = Ctx.createBlockSymbol(
99+
"BB" + Twine(MF->getFunctionNumber()) + "_" + Twine(getNumber()) + "_" +
100+
Twine(CallInstNumber),
101+
/*AlwaysEmit=*/true);
102+
}
103+
return CallInstSymbols[CallInstNumber];
104+
}
105+
93106
MCSymbol *MachineBasicBlock::getEHContSymbol() const {
94107
if (!CachedEHContMCSymbol) {
95108
const MachineFunction *MF = getParent();

0 commit comments

Comments
 (0)