Skip to content

Commit 05192e5

Browse files
committed
Extend BasicBlock sections to allow specifying clusters of basic blocks in the same section.
Differential Revision: https://reviews.llvm.org/D76954
1 parent 4ddf7ab commit 05192e5

26 files changed

+742
-409
lines changed

llvm/include/llvm/CodeGen/AsmPrinter.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,10 @@ class AsmPrinter : public MachineFunctionPass {
141141
MCSymbol *CurrentFnEnd = nullptr;
142142
MCSymbol *CurExceptionSym = nullptr;
143143

144+
// The symbol used to represent the start of the current BB section of the
145+
// function. This is used to calculate the size of the BB section.
146+
MCSymbol *CurrentSectionBeginSym = nullptr;
147+
144148
// The garbage collection metadata printer table.
145149
void *GCMetadataPrinters = nullptr; // Really a DenseMap.
146150

llvm/include/llvm/CodeGen/MachineBasicBlock.h

Lines changed: 50 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,35 @@ class raw_ostream;
4646
class TargetRegisterClass;
4747
class TargetRegisterInfo;
4848

49-
enum MachineBasicBlockSection : unsigned {
50-
/// This is also the order of sections in a function. Basic blocks that are
51-
/// part of the original function section (entry block) come first, followed
52-
/// by exception handling basic blocks, cold basic blocks and finally basic
53-
// blocks that need unique sections.
54-
MBBS_Entry,
55-
MBBS_Exception,
56-
MBBS_Cold,
57-
MBBS_Unique,
58-
/// None implies no sections for any basic block, the default.
59-
MBBS_None,
49+
// This structure uniquely identifies a basic block section.
50+
// Possible values are
51+
// {Type: Default, Number: (unsigned)} (These are regular section IDs)
52+
// {Type: Exception, Number: 0} (ExceptionSectionID)
53+
// {Type: Cold, Number: 0} (ColdSectionID)
54+
struct MBBSectionID {
55+
enum SectionType {
56+
Default = 0, // Regular section (these sections are distinguished by the
57+
// Number field).
58+
Exception, // Special section type for exception handling blocks
59+
Cold, // Special section type for cold blocks
60+
} Type;
61+
unsigned Number;
62+
63+
MBBSectionID(unsigned N) : Type(Default), Number(N) {}
64+
65+
// Special unique sections for cold and exception blocks.
66+
const static MBBSectionID ColdSectionID;
67+
const static MBBSectionID ExceptionSectionID;
68+
69+
bool operator==(const MBBSectionID &Other) const {
70+
return Type == Other.Type && Number == Other.Number;
71+
}
72+
73+
bool operator!=(const MBBSectionID &Other) const { return !(*this == Other); }
74+
75+
private:
76+
// This is only used to construct the special cold and exception sections.
77+
MBBSectionID(SectionType T) : Type(T), Number(0) {}
6078
};
6179

6280
template <> struct ilist_traits<MachineInstr> {
@@ -143,8 +161,14 @@ class MachineBasicBlock
143161
/// Indicate that this basic block is the entry block of a cleanup funclet.
144162
bool IsCleanupFuncletEntry = false;
145163

146-
/// Stores the Section type of the basic block with basic block sections.
147-
MachineBasicBlockSection SectionType = MBBS_None;
164+
/// With basic block sections, this stores the Section ID of the basic block.
165+
MBBSectionID SectionID{0};
166+
167+
// Indicate that this basic block begins a section.
168+
bool IsBeginSection = false;
169+
170+
// Indicate that this basic block ends a section.
171+
bool IsEndSection = false;
148172

149173
/// Default target of the callbr of a basic block.
150174
bool InlineAsmBrDefaultTarget = false;
@@ -435,16 +459,20 @@ class MachineBasicBlock
435459
void setIsCleanupFuncletEntry(bool V = true) { IsCleanupFuncletEntry = V; }
436460

437461
/// Returns true if this block begins any section.
438-
bool isBeginSection() const;
462+
bool isBeginSection() const { return IsBeginSection; }
439463

440464
/// Returns true if this block ends any section.
441-
bool isEndSection() const;
465+
bool isEndSection() const { return IsEndSection; }
442466

443-
/// Returns the type of section this basic block belongs to.
444-
MachineBasicBlockSection getSectionType() const { return SectionType; }
467+
void setIsBeginSection(bool V = true) { IsBeginSection = V; }
445468

446-
/// Indicate that the basic block belongs to a Section Type.
447-
void setSectionType(MachineBasicBlockSection V) { SectionType = V; }
469+
void setIsEndSection(bool V = true) { IsEndSection = V; }
470+
471+
/// Returns the section ID of this basic block.
472+
MBBSectionID getSectionID() const { return SectionID; }
473+
474+
/// Sets the section ID for this basic block.
475+
void setSectionID(MBBSectionID V) { SectionID = V; }
448476

449477
/// Returns true if this is the indirect dest of an INLINEASM_BR.
450478
bool isInlineAsmBrIndirectTarget(const MachineBasicBlock *Tgt) const {
@@ -485,10 +513,9 @@ class MachineBasicBlock
485513
void moveAfter(MachineBasicBlock *NewBefore);
486514

487515
/// Returns true if this and MBB belong to the same section.
488-
bool sameSection(const MachineBasicBlock *MBB) const;
489-
490-
/// Returns the basic block that ends the section which contains this one.
491-
const MachineBasicBlock *getSectionEndMBB() const;
516+
bool sameSection(const MachineBasicBlock *MBB) const {
517+
return getSectionID() == MBB->getSectionID();
518+
}
492519

493520
/// Update the terminator instructions in block to account for changes to the
494521
/// layout. If the block previously used a fallthrough, it may now need a
@@ -876,12 +903,6 @@ class MachineBasicBlock
876903
/// Return the MCSymbol for this basic block.
877904
MCSymbol *getSymbol() const;
878905

879-
/// Sets the MCSymbol corresponding to the end of this basic block.
880-
void setEndMCSymbol(MCSymbol *Sym) { EndMCSymbol = Sym; }
881-
882-
/// Returns the MCSymbol corresponding to the end of this basic block.
883-
MCSymbol *getEndMCSymbol() const { return EndMCSymbol; }
884-
885906
Optional<uint64_t> getIrrLoopHeaderWeight() const {
886907
return IrrLoopHeaderWeight;
887908
}

llvm/include/llvm/CodeGen/MachineFunction.h

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -346,11 +346,6 @@ class MachineFunction {
346346
/// Section Type for basic blocks, only relevant with basic block sections.
347347
BasicBlockSection BBSectionsType = BasicBlockSection::None;
348348

349-
/// With Basic Block Sections, this stores the bb ranges of cold and
350-
/// exception sections.
351-
std::pair<int, int> ColdSectionRange = {-1, -1};
352-
std::pair<int, int> ExceptionSectionRange = {-1, -1};
353-
354349
/// List of C++ TypeInfo used.
355350
std::vector<const GlobalValue *> TypeInfos;
356351

@@ -508,22 +503,13 @@ class MachineFunction {
508503

509504
void setBBSectionsType(BasicBlockSection V) { BBSectionsType = V; }
510505

511-
void setSectionRange();
512-
513-
/// Returns true if this basic block number starts a cold or exception
514-
/// section.
515-
bool isSectionStartMBB(int N) const {
516-
return (N == ColdSectionRange.first || N == ExceptionSectionRange.first);
517-
}
518-
519-
/// Returns true if this basic block ends a cold or exception section.
520-
bool isSectionEndMBB(int N) const {
521-
return (N == ColdSectionRange.second || N == ExceptionSectionRange.second);
522-
}
523-
524506
/// Creates basic block Labels for this function.
525507
void createBBLabels();
526508

509+
/// Assign IsBeginSection IsEndSection fields for basic blocks in this
510+
/// function.
511+
void assignBeginEndSections();
512+
527513
/// getTarget - Return the target machine this machine code is compiled with
528514
const LLVMTargetMachine &getTarget() const { return Target; }
529515

llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,6 @@ class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
6969
const MachineBasicBlock &MBB,
7070
const TargetMachine &TM) const override;
7171

72-
MCSection *getNamedSectionForMachineBasicBlock(
73-
const Function &F, const MachineBasicBlock &MBB, const TargetMachine &TM,
74-
const char *Suffix) const override;
75-
7672
bool shouldPutJumpTableInFunctionSection(bool UsesLabelDifference,
7773
const Function &F) const override;
7874

llvm/include/llvm/Target/TargetLoweringObjectFile.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,6 @@ class TargetLoweringObjectFile : public MCObjectFileInfo {
9292
const MachineBasicBlock &MBB,
9393
const TargetMachine &TM) const;
9494

95-
virtual MCSection *getNamedSectionForMachineBasicBlock(
96-
const Function &F, const MachineBasicBlock &MBB, const TargetMachine &TM,
97-
const char *Suffix) const;
98-
9995
/// Classify the specified global variable into a set of target independent
10096
/// categories embodied in SectionKind.
10197
static SectionKind getKindForGlobal(const GlobalObject *GO,

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Lines changed: 45 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,14 +1097,6 @@ void AsmPrinter::emitFunctionBody() {
10971097
// Print out code for the function.
10981098
bool HasAnyRealCode = false;
10991099
int NumInstsInFunction = 0;
1100-
bool emitBBSections = MF->hasBBSections();
1101-
MachineBasicBlock *EndOfRegularSectionMBB = nullptr;
1102-
if (emitBBSections) {
1103-
EndOfRegularSectionMBB =
1104-
const_cast<MachineBasicBlock *>(MF->front().getSectionEndMBB());
1105-
assert(EndOfRegularSectionMBB->isEndSection() &&
1106-
"The MBB at the end of the regular section must end a section");
1107-
}
11081100

11091101
for (auto &MBB : *MF) {
11101102
// Print a label for the basic block.
@@ -1185,17 +1177,41 @@ void AsmPrinter::emitFunctionBody() {
11851177
}
11861178
}
11871179
}
1188-
if (&MBB != EndOfRegularSectionMBB &&
1189-
(MF->hasBBLabels() || MBB.isEndSection())) {
1190-
// Emit size directive for the size of this basic block. Create a symbol
1191-
// for the end of the basic block.
1192-
MCSymbol *CurrentBBEnd = OutContext.createTempSymbol();
1180+
1181+
// We need a temporary symbol for the end of this basic block, if either we
1182+
// have BBLabels enabled and we want to emit size directive for the BBs, or
1183+
// if this basic blocks marks the end of a section (except the section
1184+
// containing the entry basic block as the end symbol for that section is
1185+
// CurrentFnEnd).
1186+
MCSymbol *CurrentBBEnd = nullptr;
1187+
if ((MAI->hasDotTypeDotSizeDirective() && MF->hasBBLabels()) ||
1188+
(MBB.isEndSection() && !MBB.sameSection(&MF->front()))) {
1189+
CurrentBBEnd = OutContext.createTempSymbol();
1190+
OutStreamer->emitLabel(CurrentBBEnd);
1191+
}
1192+
1193+
// Helper for emitting the size directive associated with a basic block
1194+
// symbol.
1195+
auto emitELFSizeDirective = [&](MCSymbol *SymForSize) {
1196+
assert(CurrentBBEnd && "Basicblock end symbol not set!");
11931197
const MCExpr *SizeExp = MCBinaryExpr::createSub(
11941198
MCSymbolRefExpr::create(CurrentBBEnd, OutContext),
1195-
MCSymbolRefExpr::create(MBB.getSymbol(), OutContext), OutContext);
1196-
OutStreamer->emitLabel(CurrentBBEnd);
1197-
MBB.setEndMCSymbol(CurrentBBEnd);
1198-
OutStreamer->emitELFSize(MBB.getSymbol(), SizeExp);
1199+
MCSymbolRefExpr::create(SymForSize, OutContext), OutContext);
1200+
OutStreamer->emitELFSize(SymForSize, SizeExp);
1201+
};
1202+
1203+
// Emit size directive for the size of each basic block, if BBLabels is
1204+
// enabled.
1205+
if (MAI->hasDotTypeDotSizeDirective() && MF->hasBBLabels())
1206+
emitELFSizeDirective(MBB.getSymbol());
1207+
1208+
// Emit size directive for the size of each basic block section once we
1209+
// get to the end of that section.
1210+
if (MBB.isEndSection()) {
1211+
if (!MBB.sameSection(&MF->front())) {
1212+
if (MAI->hasDotTypeDotSizeDirective())
1213+
emitELFSizeDirective(CurrentSectionBeginSym);
1214+
}
11991215
}
12001216
emitBasicBlockEnd(MBB);
12011217
}
@@ -1230,9 +1246,8 @@ void AsmPrinter::emitFunctionBody() {
12301246
}
12311247
}
12321248

1233-
// Switch to the original section if basic block sections was used.
1234-
if (emitBBSections)
1235-
OutStreamer->SwitchSection(MF->getSection());
1249+
// Switch to the original section in case basic block sections was used.
1250+
OutStreamer->SwitchSection(MF->getSection());
12361251

12371252
const Function &F = MF->getFunction();
12381253
for (const auto &BB : F) {
@@ -1249,7 +1264,7 @@ void AsmPrinter::emitFunctionBody() {
12491264
emitFunctionBodyEnd();
12501265

12511266
if (needFuncLabelsForEHOrDebugInfo(*MF, MMI) ||
1252-
MAI->hasDotTypeDotSizeDirective() || emitBBSections) {
1267+
MAI->hasDotTypeDotSizeDirective()) {
12531268
// Create a symbol for the end of function.
12541269
CurrentFnEnd = createTempSymbol("func_end");
12551270
OutStreamer->emitLabel(CurrentFnEnd);
@@ -1272,8 +1287,6 @@ void AsmPrinter::emitFunctionBody() {
12721287
HI.Handler->markFunctionEnd();
12731288
}
12741289

1275-
if (emitBBSections)
1276-
EndOfRegularSectionMBB->setEndMCSymbol(CurrentFnEnd);
12771290

12781291
// Print out jump tables referenced by the function.
12791292
emitJumpTableInfo();
@@ -1753,6 +1766,7 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
17531766

17541767
CurrentFnSymForSize = CurrentFnSym;
17551768
CurrentFnBegin = nullptr;
1769+
CurrentSectionBeginSym = nullptr;
17561770
CurExceptionSym = nullptr;
17571771
bool NeedsLocalForSize = MAI->needsLocalForSize();
17581772
if (F.hasFnAttribute("patchable-function-entry") ||
@@ -2981,7 +2995,6 @@ static void emitBasicBlockLoopComments(const MachineBasicBlock &MBB,
29812995
/// MachineBasicBlock, an alignment (if present) and a comment describing
29822996
/// it if appropriate.
29832997
void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) {
2984-
bool BBSections = MF->hasBBSections();
29852998
// End the previous funclet and start a new one.
29862999
if (MBB.isEHFuncletEntry()) {
29873000
for (const HandlerInfo &HI : Handlers) {
@@ -2991,11 +3004,9 @@ void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) {
29913004
}
29923005

29933006
// Emit an alignment directive for this block, if needed.
2994-
if (MBB.pred_empty() || !BBSections) {
2995-
const Align Alignment = MBB.getAlignment();
2996-
if (Alignment != Align(1))
2997-
emitAlignment(Alignment);
2998-
}
3007+
const Align Alignment = MBB.getAlignment();
3008+
if (Alignment != Align(1))
3009+
emitAlignment(Alignment);
29993010

30003011
// If the block has its address taken, emit any labels that were used to
30013012
// reference the block. It is possible that there is more than one label
@@ -3027,9 +3038,8 @@ void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) {
30273038
emitBasicBlockLoopComments(MBB, MLI, *this);
30283039
}
30293040

3030-
bool emitBBLabels = BBSections || MF->hasBBLabels();
30313041
if (MBB.pred_empty() ||
3032-
(!emitBBLabels && isBlockOnlyReachableByFallthrough(&MBB) &&
3042+
(!MF->hasBBLabels() && isBlockOnlyReachableByFallthrough(&MBB) &&
30333043
!MBB.isEHFuncletEntry() && !MBB.hasLabelMustBeEmitted())) {
30343044
if (isVerbose()) {
30353045
// NOTE: Want this comment at start of line, don't emit with AddComment.
@@ -3040,23 +3050,12 @@ void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) {
30403050
if (isVerbose() && MBB.hasLabelMustBeEmitted()) {
30413051
OutStreamer->AddComment("Label of block must be emitted");
30423052
}
3043-
// With -fbasicblock-sections, a basic block can start a new section.
3044-
if (MBB.getSectionType() == MachineBasicBlockSection::MBBS_Exception) {
3045-
// Create the exception section for this function.
3046-
OutStreamer->SwitchSection(
3047-
getObjFileLowering().getNamedSectionForMachineBasicBlock(
3048-
MF->getFunction(), MBB, TM, ".eh"));
3049-
} else if (MBB.getSectionType() == MachineBasicBlockSection::MBBS_Cold) {
3050-
// Create the cold section here.
3051-
OutStreamer->SwitchSection(
3052-
getObjFileLowering().getNamedSectionForMachineBasicBlock(
3053-
MF->getFunction(), MBB, TM, ".unlikely"));
3054-
} else if (MBB.isBeginSection() && MBB.isEndSection()) {
3053+
// Switch to a new section if this basic block must begin a section.
3054+
if (MBB.isBeginSection()) {
30553055
OutStreamer->SwitchSection(
30563056
getObjFileLowering().getSectionForMachineBasicBlock(MF->getFunction(),
30573057
MBB, TM));
3058-
} else if (BBSections) {
3059-
OutStreamer->SwitchSection(MF->getSection());
3058+
CurrentSectionBeginSym = MBB.getSymbol();
30603059
}
30613060
OutStreamer->emitLabel(MBB.getSymbol());
30623061
}
@@ -3090,7 +3089,7 @@ void AsmPrinter::emitVisibility(MCSymbol *Sym, unsigned Visibility,
30903089
/// the predecessor and this block is a fall-through.
30913090
bool AsmPrinter::
30923091
isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
3093-
// With BasicBlock Sections, no block is a fall through.
3092+
// With BasicBlock Sections, beginning of the section is not a fallthrough.
30943093
if (MBB->isBeginSection())
30953094
return false;
30963095

0 commit comments

Comments
 (0)