Skip to content

Commit 68f7b07

Browse files
authored
[BasicBlockSections] Allow mixing of -basic-block-sections with MFS. (#117076)
This PR allows mixing `-basic-block-sections` with `-enable-machine-function-splitter`. The strategy is to let `-basic-block-sections` take precedence over functions with profiles.
1 parent 9d8a11f commit 68f7b07

File tree

3 files changed

+87
-9
lines changed

3 files changed

+87
-9
lines changed

llvm/lib/CodeGen/MachineFunctionSplitter.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "llvm/Analysis/EHUtils.h"
2929
#include "llvm/Analysis/ProfileSummaryInfo.h"
3030
#include "llvm/CodeGen/BasicBlockSectionUtils.h"
31+
#include "llvm/CodeGen/BasicBlockSectionsProfileReader.h"
3132
#include "llvm/CodeGen/MachineBasicBlock.h"
3233
#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
3334
#include "llvm/CodeGen/MachineFunction.h"
@@ -128,6 +129,9 @@ static bool isColdBlock(const MachineBasicBlock &MBB,
128129
}
129130

130131
bool MachineFunctionSplitter::runOnMachineFunction(MachineFunction &MF) {
132+
// Do not split functions when -basic-block-sections=all is specified.
133+
if (MF.getTarget().getBBSectionsType() == llvm::BasicBlockSection::All)
134+
return false;
131135
// We target functions with profile data. Static information in the form
132136
// of exception handling code may be split to cold if user passes the
133137
// mfs-split-ehcode flag.
@@ -139,6 +143,14 @@ bool MachineFunctionSplitter::runOnMachineFunction(MachineFunction &MF) {
139143
if (!TII.isFunctionSafeToSplit(MF))
140144
return false;
141145

146+
// Do not split functions with BasicBlockSections profiles as they will
147+
// be split by the BasicBlockSections pass.
148+
auto BBSectionsProfile =
149+
getAnalysisIfAvailable<BasicBlockSectionsProfileReaderWrapperPass>();
150+
if (BBSectionsProfile != nullptr &&
151+
BBSectionsProfile->getBBSPR().isFunctionHot(MF.getName()))
152+
return false;
153+
142154
// Renumbering blocks here preserves the order of the blocks as
143155
// sortBasicBlocksAndUpdateBranches uses the numeric identifier to sort
144156
// blocks. Preserving the order of blocks is essential to retaining decisions
@@ -201,6 +213,7 @@ void MachineFunctionSplitter::getAnalysisUsage(AnalysisUsage &AU) const {
201213
AU.addRequired<MachineModuleInfoWrapperPass>();
202214
AU.addRequired<MachineBlockFrequencyInfoWrapperPass>();
203215
AU.addRequired<ProfileSummaryInfoWrapperPass>();
216+
AU.addUsedIfAvailable<BasicBlockSectionsProfileReaderWrapperPass>();
204217
}
205218

206219
char MachineFunctionSplitter::ID = 0;

llvm/lib/CodeGen/TargetPassConfig.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,13 +1235,13 @@ void TargetPassConfig::addMachinePasses() {
12351235
addPass(createMIRAddFSDiscriminatorsPass(
12361236
sampleprof::FSDiscriminatorPass::PassLast));
12371237

1238-
bool NeedsBBSections =
1239-
TM->getBBSectionsType() != llvm::BasicBlockSection::None;
1240-
// Machine function splitter uses the basic block sections feature. Both
1241-
// cannot be enabled at the same time. We do not apply machine function
1242-
// splitter if -basic-block-sections is requested.
1243-
if (!NeedsBBSections && (TM->Options.EnableMachineFunctionSplitter ||
1244-
EnableMachineFunctionSplitter)) {
1238+
// Machine function splitter uses the basic block sections feature.
1239+
// When used along with `-basic-block-sections=`, the basic-block-sections
1240+
// feature takes precedence. This means functions eligible for
1241+
// basic-block-sections optimizations (`=all`, or `=list=` with function
1242+
// included in the list profile) will get that optimization instead.
1243+
if (TM->Options.EnableMachineFunctionSplitter ||
1244+
EnableMachineFunctionSplitter) {
12451245
const std::string ProfileFile = getFSProfileFile(TM);
12461246
if (!ProfileFile.empty()) {
12471247
if (EnableFSDiscriminator) {
@@ -1260,7 +1260,8 @@ void TargetPassConfig::addMachinePasses() {
12601260
}
12611261
// We run the BasicBlockSections pass if either we need BB sections or BB
12621262
// address map (or both).
1263-
if (NeedsBBSections || TM->Options.BBAddrMap) {
1263+
if (TM->getBBSectionsType() != llvm::BasicBlockSection::None ||
1264+
TM->Options.BBAddrMap) {
12641265
if (TM->getBBSectionsType() == llvm::BasicBlockSection::List) {
12651266
addPass(llvm::createBasicBlockSectionsProfileReaderWrapperPass(
12661267
TM->getBBSectionsFuncListBuf()));

llvm/test/CodeGen/Generic/machine-function-splitter.ll

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,21 @@
22
; REQUIRES: x86-registered-target
33

44
; COM: Machine function splitting with FDO profiles
5-
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -split-machine-functions | FileCheck %s -check-prefixes=MFS-DEFAULTS,MFS-DEFAULTS-X86
5+
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -split-machine-functions | FileCheck %s -check-prefixes=MFS-DEFAULTS,MFS-DEFAULTS-X86,MFS-NOBBSECTIONS
66
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -split-machine-functions -mfs-psi-cutoff=0 -mfs-count-threshold=2000 | FileCheck %s --dump-input=always -check-prefixes=MFS-OPTS1,MFS-OPTS1-X86
77
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -split-machine-functions -mfs-psi-cutoff=950000 | FileCheck %s -check-prefixes=MFS-OPTS2,MFS-OPTS2-X86
88
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -split-machine-functions -mfs-split-ehcode | FileCheck %s -check-prefixes=MFS-EH-SPLIT,MFS-EH-SPLIT-X86
99
; RUN: llc < %s -mtriple=x86_64 -split-machine-functions -O0 -mfs-psi-cutoff=0 -mfs-count-threshold=10000 | FileCheck %s -check-prefixes=MFS-O0,MFS-O0-X86
1010

11+
; COM: Machine function splitting along with -basic-block-sections profile
12+
; RUN: echo 'v1' > %t
13+
; RUN: echo 'ffoo21' >> %t
14+
; RUN: echo 'c0' >> %t
15+
; RUN: echo 'ffoo22' >> %t
16+
; RUN: echo 'c0 1' >> %t
17+
; RUN: echo 'c2' >> %t
18+
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -basic-block-sections=%t -split-machine-functions | FileCheck %s --check-prefixes=MFS-BBSECTIONS
19+
1120
; RUN: llc < %s -mtriple=aarch64-unknown-linux-gnu -aarch64-min-jump-table-entries=4 -enable-split-machine-functions | FileCheck %s -check-prefixes=MFS-DEFAULTS,MFS-DEFAULTS-AARCH64
1221
; RUN: llc < %s -mtriple=aarch64-unknown-linux-gnu -aarch64-min-jump-table-entries=4 -enable-split-machine-functions -mfs-psi-cutoff=0 -mfs-count-threshold=2000 | FileCheck %s --dump-input=always -check-prefixes=MFS-OPTS1,MFS-OPTS1-AARCH64
1322
; RUN: llc < %s -mtriple=aarch64-unknown-linux-gnu -aarch64-min-jump-table-entries=4 -enable-split-machine-functions -mfs-psi-cutoff=950000 | FileCheck %s -check-prefixes=MFS-OPTS2,MFS-OPTS2-AARCH64
@@ -610,6 +619,61 @@ cold_asm_target:
610619
ret void
611620
}
612621

622+
define void @foo21(i1 zeroext %0) {
623+
;; Check that a function with basic-block-sections profile (but no pgo profile)
624+
;; is properly split when the profile is used along with mfs.
625+
; MFS-BBSECTIONS: .section .text.hot.foo21
626+
; MFS-NOBBSECTIONS-NOT: .section .text.hot.foo21
627+
; MFS-BBSECTIONS-LABEL: foo21:
628+
; MFS-NOBBSECTIONS-NOT: foo21.cold:
629+
; MFS-BBSECTIONS: .section .text.split.foo21
630+
; MFS-BBSECTIONS: foo21.cold
631+
%2 = alloca i8, align 1
632+
%3 = zext i1 %0 to i8
633+
store i8 %3, ptr %2, align 1
634+
%4 = load i8, ptr %2, align 1
635+
%5 = trunc i8 %4 to i1
636+
br i1 %5, label %6, label %8
637+
638+
6: ; preds = %1
639+
%7 = call i32 @bar()
640+
br label %10
641+
642+
8: ; preds = %1
643+
%9 = call i32 @baz()
644+
br label %10
645+
646+
10: ; preds = %8, %6
647+
ret void
648+
}
649+
650+
define void @foo22(i1 zeroext %0) nounwind !prof !14 !section_prefix !15 {
651+
;; Check that when a function has both basic-block-section and pgo profiles
652+
;; only the basic-block-section profile is used for splitting.
653+
654+
;; Check that we create two hot sections with -basic-block-sections.
655+
; MFS-BBSECTIONS: .section .text.hot.foo22
656+
; MFS-BBSECTIONS-LABEL: foo22:
657+
; MFS-BBSECTIONS: callq bar
658+
; MFS-BBSECTIONS: .section .text.hot.foo22
659+
; MFS-BBSECTIONS-NEXT: foo22.__part.1:
660+
; MFS-BBSECTIONS: callq baz
661+
; MFS-BBSECTIONS-NOT: .section .text.split.foo22
662+
br i1 %0, label %2, label %4, !prof !17
663+
664+
2: ; preds = %1
665+
%3 = call i32 @bar()
666+
br label %6
667+
668+
4: ; preds = %1
669+
%5 = call i32 @baz()
670+
br label %6
671+
672+
6: ; preds = %4, %2
673+
%7 = tail call i32 @qux()
674+
ret void
675+
}
676+
613677
declare i32 @bar()
614678
declare i32 @baz()
615679
declare i32 @bam()

0 commit comments

Comments
 (0)