Skip to content

Commit a191ea7

Browse files
author
Fabian Parzefall
committed
[BOLT] Make exception handling fragment aware
This adds basic fragment awareness in the exception handling passes and generates the necessary symbols for fragments. Reviewed By: rafauler Differential Revision: https://reviews.llvm.org/D130520
1 parent 275e075 commit a191ea7

File tree

10 files changed

+170
-177
lines changed

10 files changed

+170
-177
lines changed

bolt/include/bolt/Core/BinaryBasicBlock.h

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,9 @@ class BinaryBasicBlock {
133133
/// CFI state at the entry to this basic block.
134134
int32_t CFIState{-1};
135135

136-
/// In cases where the parent function has been split, IsCold == true means
137-
/// this BB will be allocated outside its parent function.
138-
bool IsCold{false};
136+
/// In cases where the parent function has been split, FragmentNum > 0 means
137+
/// this BB will be allocated in a fragment outside its parent function.
138+
FragmentNum Fragment;
139139

140140
/// Indicates if the block could be outlined.
141141
bool CanOutline{true};
@@ -672,13 +672,21 @@ class BinaryBasicBlock {
672672

673673
void markValid(const bool Valid) { IsValid = Valid; }
674674

675-
FragmentNum getFragmentNum() const {
676-
return IsCold ? FragmentNum::cold() : FragmentNum::hot();
677-
}
675+
FragmentNum getFragmentNum() const { return Fragment; }
676+
677+
void setFragmentNum(const FragmentNum Value) { Fragment = Value; }
678678

679-
bool isCold() const { return IsCold; }
679+
bool isSplit() const { return Fragment != FragmentNum::main(); }
680680

681-
void setIsCold(const bool Flag) { IsCold = Flag; }
681+
bool isCold() const {
682+
assert(Fragment.get() < 2 &&
683+
"Function is split into more than two (hot/cold)-fragments");
684+
return Fragment == FragmentNum::cold();
685+
}
686+
687+
void setIsCold(const bool Flag) {
688+
Fragment = Flag ? FragmentNum::cold() : FragmentNum::hot();
689+
}
682690

683691
/// Return true if the block can be outlined. At the moment we disallow
684692
/// outlining of blocks that can potentially throw exceptions or are

bolt/include/bolt/Core/BinaryFunction.h

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -570,11 +570,8 @@ class BinaryFunction {
570570

571571
SmallVector<MCSymbol *, 0> ColdSymbols;
572572

573-
/// Symbol at the end of the function.
574-
mutable MCSymbol *FunctionEndLabel{nullptr};
575-
576-
/// Symbol at the end of the cold part of split function.
577-
mutable MCSymbol *FunctionColdEndLabel{nullptr};
573+
/// Symbol at the end of each fragment of a split function.
574+
mutable SmallVector<MCSymbol *, 0> FunctionEndLabels;
578575

579576
/// Unique number associated with the function.
580577
uint64_t FunctionNumber;
@@ -1152,22 +1149,25 @@ class BinaryFunction {
11521149
bool forEachEntryPoint(EntryPointCallbackTy Callback) const;
11531150

11541151
/// Return MC symbol associated with the end of the function.
1155-
MCSymbol *getFunctionEndLabel() const {
1152+
MCSymbol *
1153+
getFunctionEndLabel(const FragmentNum Fragment = FragmentNum::main()) const {
11561154
assert(BC.Ctx && "cannot be called with empty context");
1157-
if (!FunctionEndLabel) {
1158-
std::unique_lock<std::shared_timed_mutex> Lock(BC.CtxMutex);
1159-
FunctionEndLabel = BC.Ctx->createNamedTempSymbol("func_end");
1155+
1156+
size_t LabelIndex = Fragment.get();
1157+
if (LabelIndex >= FunctionEndLabels.size()) {
1158+
FunctionEndLabels.resize(LabelIndex + 1);
11601159
}
1161-
return FunctionEndLabel;
1162-
}
11631160

1164-
/// Return MC symbol associated with the end of the cold part of the function.
1165-
MCSymbol *getFunctionColdEndLabel() const {
1166-
if (!FunctionColdEndLabel) {
1161+
MCSymbol *&FunctionEndLabel = FunctionEndLabels[LabelIndex];
1162+
if (!FunctionEndLabel) {
11671163
std::unique_lock<std::shared_timed_mutex> Lock(BC.CtxMutex);
1168-
FunctionColdEndLabel = BC.Ctx->createNamedTempSymbol("func_cold_end");
1164+
if (Fragment == FragmentNum::main())
1165+
FunctionEndLabel = BC.Ctx->createNamedTempSymbol("func_end");
1166+
else
1167+
FunctionEndLabel = BC.Ctx->createNamedTempSymbol(
1168+
formatv("func_cold_end.{0}", Fragment.get() - 1));
11691169
}
1170-
return FunctionColdEndLabel;
1170+
return FunctionEndLabel;
11711171
}
11721172

11731173
/// Return a label used to identify where the constant island was emitted
@@ -1872,14 +1872,17 @@ class BinaryFunction {
18721872
}
18731873

18741874
/// Return symbol pointing to function's LSDA for the cold part.
1875-
MCSymbol *getColdLSDASymbol() {
1875+
MCSymbol *getColdLSDASymbol(const FragmentNum Fragment) {
18761876
if (ColdLSDASymbol)
18771877
return ColdLSDASymbol;
18781878
if (ColdCallSites.empty())
18791879
return nullptr;
18801880

1881-
ColdLSDASymbol = BC.Ctx->getOrCreateSymbol(
1882-
Twine("GCC_cold_except_table") + Twine::utohexstr(getFunctionNumber()));
1881+
SmallString<8> SymbolSuffix;
1882+
if (Fragment != FragmentNum::cold())
1883+
SymbolSuffix = formatv(".{0}", Fragment.get());
1884+
ColdLSDASymbol = BC.Ctx->getOrCreateSymbol(formatv(
1885+
"GCC_cold_except_table{0:x-}{1}", getFunctionNumber(), SymbolSuffix));
18831886

18841887
return ColdLSDASymbol;
18851888
}

bolt/include/bolt/Core/FunctionLayout.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class FragmentNum {
4646
return !(*this == Other);
4747
}
4848

49+
static constexpr FragmentNum main() { return FragmentNum(0); }
4950
static constexpr FragmentNum hot() { return FragmentNum(0); }
5051
static constexpr FragmentNum cold() { return FragmentNum(1); }
5152
};

bolt/lib/Core/BinaryBasicBlock.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ bool BinaryBasicBlock::validateSuccessorInvariants() {
102102
if (Valid) {
103103
for (const MCSymbol *Sym : UniqueSyms) {
104104
Valid &= (Sym == Function->getFunctionEndLabel() ||
105-
Sym == Function->getFunctionColdEndLabel());
105+
Sym == Function->getFunctionEndLabel(getFragmentNum()));
106106
if (!Valid) {
107107
errs() << "BOLT-WARNING: Jump table contains illegal entry: "
108108
<< Sym->getName() << "\n";

bolt/lib/Core/BinaryEmitter.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -331,14 +331,13 @@ bool BinaryEmitter::emitFunction(BinaryFunction &Function,
331331

332332
// Emit CFI start
333333
if (Function.hasCFI()) {
334-
assert(Function.getLayout().isHotColdSplit() &&
335-
"Exceptions supported only with hot/cold splitting.");
336334
Streamer.emitCFIStartProc(/*IsSimple=*/false);
337335
if (Function.getPersonalityFunction() != nullptr)
338336
Streamer.emitCFIPersonality(Function.getPersonalityFunction(),
339337
Function.getPersonalityEncoding());
340-
MCSymbol *LSDASymbol = FF.isSplitFragment() ? Function.getColdLSDASymbol()
341-
: Function.getLSDASymbol();
338+
MCSymbol *LSDASymbol = FF.isSplitFragment()
339+
? Function.getColdLSDASymbol(FF.getFragmentNum())
340+
: Function.getLSDASymbol();
342341
if (LSDASymbol)
343342
Streamer.emitCFILsda(LSDASymbol, BC.LSDAEncoding);
344343
else
@@ -383,9 +382,7 @@ bool BinaryEmitter::emitFunction(BinaryFunction &Function,
383382
if (Function.hasCFI())
384383
Streamer.emitCFIEndProc();
385384

386-
MCSymbol *EndSymbol = FF.isSplitFragment()
387-
? Function.getFunctionColdEndLabel()
388-
: Function.getFunctionEndLabel();
385+
MCSymbol *EndSymbol = Function.getFunctionEndLabel(FF.getFragmentNum());
389386
Streamer.emitLabel(EndSymbol);
390387

391388
if (MAI->hasDotTypeDotSizeDirective()) {
@@ -913,8 +910,9 @@ void BinaryEmitter::emitLSDA(BinaryFunction &BF, bool EmitColdPart) {
913910
Streamer.emitValueToAlignment(TTypeAlignment);
914911

915912
// Emit the LSDA label.
916-
MCSymbol *LSDASymbol =
917-
EmitColdPart ? BF.getColdLSDASymbol() : BF.getLSDASymbol();
913+
MCSymbol *LSDASymbol = EmitColdPart
914+
? BF.getColdLSDASymbol(FragmentNum::cold())
915+
: BF.getLSDASymbol();
918916
assert(LSDASymbol && "no LSDA symbol set");
919917
Streamer.emitLabel(LSDASymbol);
920918

bolt/lib/Core/BinaryFunction.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "llvm/MC/MCInst.h"
3232
#include "llvm/MC/MCInstPrinter.h"
3333
#include "llvm/MC/MCRegisterInfo.h"
34+
#include "llvm/MC/MCSymbol.h"
3435
#include "llvm/Object/ObjectFile.h"
3536
#include "llvm/Support/CommandLine.h"
3637
#include "llvm/Support/Debug.h"
@@ -1572,8 +1573,9 @@ bool BinaryFunction::scanExternalRefs() {
15721573
if (BC.HasRelocations) {
15731574
for (std::pair<const uint32_t, MCSymbol *> &LI : Labels)
15741575
BC.UndefinedSymbols.insert(LI.second);
1575-
if (FunctionEndLabel)
1576-
BC.UndefinedSymbols.insert(FunctionEndLabel);
1576+
for (MCSymbol *const EndLabel : FunctionEndLabels)
1577+
if (EndLabel)
1578+
BC.UndefinedSymbols.insert(EndLabel);
15771579
}
15781580

15791581
clearList(Relocations);
@@ -2843,8 +2845,9 @@ void BinaryFunction::clearDisasmState() {
28432845
if (BC.HasRelocations) {
28442846
for (std::pair<const uint32_t, MCSymbol *> &LI : Labels)
28452847
BC.UndefinedSymbols.insert(LI.second);
2846-
if (FunctionEndLabel)
2847-
BC.UndefinedSymbols.insert(FunctionEndLabel);
2848+
for (MCSymbol *const EndLabel : FunctionEndLabels)
2849+
if (EndLabel)
2850+
BC.UndefinedSymbols.insert(EndLabel);
28482851
}
28492852
}
28502853

@@ -4053,7 +4056,7 @@ void BinaryFunction::updateOutputValues(const MCAsmLayout &Layout) {
40534056
const MCSymbol *ColdStartSymbol = getSymbol(FragmentNum::cold());
40544057
assert(ColdStartSymbol && ColdStartSymbol->isDefined() &&
40554058
"split function should have defined cold symbol");
4056-
const MCSymbol *ColdEndSymbol = getFunctionColdEndLabel();
4059+
const MCSymbol *ColdEndSymbol = getFunctionEndLabel(FragmentNum::cold());
40574060
assert(ColdEndSymbol && ColdEndSymbol->isDefined() &&
40584061
"split function should have defined cold end symbol");
40594062
const uint64_t ColdStartOffset = Layout.getSymbolOffset(*ColdStartSymbol);

0 commit comments

Comments
 (0)