Skip to content

Commit 0d4ec16

Browse files
committed
Extend BasicBlock sections to allow specifying clusters of basic blocks
in the same section. This allows specifying BasicBlock clusters like the following example: !foo !!0 1 2 !!4 This places basic blocks 0, 1, and 2 in one section in this order, and places basic block rust-lang#4 in a single section of its own.
1 parent ec228d7 commit 0d4ec16

22 files changed

+492
-409
lines changed

llvm/include/llvm/CodeGen/AsmPrinter.h

+4
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

+50-29
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

+4-18
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

-4
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

-4
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

+45-46
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)