Treat specifying a function in the bbsection profile without any directive as noop. (#167359)

This commit is contained in:
Rahman Lavaee 2025-11-10 14:19:12 -08:00 committed by GitHub
parent 8b1cc2d5f5
commit 95db31e7f6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 45 additions and 90 deletions

View File

@ -1 +1,3 @@
!world
v1
f world
c 0

View File

@ -30,8 +30,10 @@ int another(int a) {
//
// BB_WORLD: .section .text.world,"ax",@progbits{{$}}
// BB_WORLD: world:
// BB_WORLD: .section .text.world,"ax",@progbits,unique
// BB_WORLD: world.__part.1:
// BB_ALL: .section .text.world,"ax",@progbits,unique
// BB_ALL: world.__part.1:
// BB_LIST: .section .text.split.world,"ax",@progbits
// BB_LIST: world.cold:
// BB_ALL: .section .text.another,"ax",@progbits
// BB_ALL: another.__part.1:
// BB_LIST-NOT: .section .text.another,"ax",@progbits

View File

@ -68,17 +68,13 @@ public:
BasicBlockSectionsProfileReader() = default;
// Returns true if basic block sections profile exist for function \p
// FuncName.
// Returns true if function \p FuncName is hot based on the basic block
// section profile.
bool isFunctionHot(StringRef FuncName) const;
// Returns a pair with first element representing whether basic block sections
// profile exist for the function \p FuncName, and the second element
// representing the basic block sections profile (cluster info) for this
// function. If the first element is true and the second element is empty, it
// means unique basic block sections are desired for all basic blocks of the
// function.
std::pair<bool, SmallVector<BBClusterInfo>>
// Returns the cluster info for the function \p FuncName. Returns an empty
// vector if function has no cluster info.
SmallVector<BBClusterInfo>
getClusterInfoForFunction(StringRef FuncName) const;
// Returns the path clonings for the given function.
@ -190,7 +186,7 @@ public:
bool isFunctionHot(StringRef FuncName) const;
std::pair<bool, SmallVector<BBClusterInfo>>
SmallVector<BBClusterInfo>
getClusterInfoForFunction(StringRef FuncName) const;
SmallVector<SmallVector<unsigned>>

View File

@ -183,8 +183,7 @@ updateBranches(MachineFunction &MF,
// clusters are ordered in increasing order of their IDs, with the "Exception"
// and "Cold" succeeding all other clusters.
// FuncClusterInfo represents the cluster information for basic blocks. It
// maps from BBID of basic blocks to their cluster information. If this is
// empty, it means unique sections for all basic blocks in the function.
// maps from BBID of basic blocks to their cluster information.
static void
assignSections(MachineFunction &MF,
const DenseMap<UniqueBBID, BBClusterInfo> &FuncClusterInfo) {
@ -197,10 +196,8 @@ assignSections(MachineFunction &MF,
for (auto &MBB : MF) {
// With the 'all' option, every basic block is placed in a unique section.
// With the 'list' option, every basic block is placed in a section
// associated with its cluster, unless we want individual unique sections
// for every basic block in this function (if FuncClusterInfo is empty).
if (MF.getTarget().getBBSectionsType() == llvm::BasicBlockSection::All ||
FuncClusterInfo.empty()) {
// associated with its cluster.
if (MF.getTarget().getBBSectionsType() == llvm::BasicBlockSection::All) {
// If unique sections are desired for all basic blocks of the function, we
// set every basic block's section ID equal to its original position in
// the layout (which is equal to its number). This ensures that basic
@ -308,22 +305,22 @@ bool BasicBlockSections::handleBBSections(MachineFunction &MF) {
if (BBSectionsType == BasicBlockSection::List &&
hasInstrProfHashMismatch(MF))
return false;
// Renumber blocks before sorting them. This is useful for accessing the
// original layout positions and finding the original fallthroughs.
MF.RenumberBlocks();
DenseMap<UniqueBBID, BBClusterInfo> FuncClusterInfo;
if (BBSectionsType == BasicBlockSection::List) {
auto [HasProfile, ClusterInfo] =
getAnalysis<BasicBlockSectionsProfileReaderWrapperPass>()
.getClusterInfoForFunction(MF.getName());
if (!HasProfile)
auto ClusterInfo = getAnalysis<BasicBlockSectionsProfileReaderWrapperPass>()
.getClusterInfoForFunction(MF.getName());
if (ClusterInfo.empty())
return false;
for (auto &BBClusterInfo : ClusterInfo) {
FuncClusterInfo.try_emplace(BBClusterInfo.BBID, BBClusterInfo);
}
}
// Renumber blocks before sorting them. This is useful for accessing the
// original layout positions and finding the original fallthroughs.
MF.RenumberBlocks();
MF.setBBSectionsType(BBSectionsType);
assignSections(MF, FuncClusterInfo);

View File

@ -58,22 +58,24 @@ BasicBlockSectionsProfileReader::parseUniqueBBID(StringRef S) const {
}
bool BasicBlockSectionsProfileReader::isFunctionHot(StringRef FuncName) const {
return getClusterInfoForFunction(FuncName).first;
return !getClusterInfoForFunction(FuncName).empty();
}
std::pair<bool, SmallVector<BBClusterInfo>>
SmallVector<BBClusterInfo>
BasicBlockSectionsProfileReader::getClusterInfoForFunction(
StringRef FuncName) const {
auto R = ProgramPathAndClusterInfo.find(getAliasName(FuncName));
return R != ProgramPathAndClusterInfo.end()
? std::pair(true, R->second.ClusterInfo)
: std::pair(false, SmallVector<BBClusterInfo>());
return R != ProgramPathAndClusterInfo.end() ? R->second.ClusterInfo
: SmallVector<BBClusterInfo>();
}
SmallVector<SmallVector<unsigned>>
BasicBlockSectionsProfileReader::getClonePathsForFunction(
StringRef FuncName) const {
return ProgramPathAndClusterInfo.lookup(getAliasName(FuncName)).ClonePaths;
auto R = ProgramPathAndClusterInfo.find(getAliasName(FuncName));
return R != ProgramPathAndClusterInfo.end()
? R->second.ClonePaths
: SmallVector<SmallVector<unsigned>>();
}
uint64_t BasicBlockSectionsProfileReader::getEdgeCount(
@ -494,7 +496,7 @@ bool BasicBlockSectionsProfileReaderWrapperPass::isFunctionHot(
return BBSPR.isFunctionHot(FuncName);
}
std::pair<bool, SmallVector<BBClusterInfo>>
SmallVector<BBClusterInfo>
BasicBlockSectionsProfileReaderWrapperPass::getClusterInfoForFunction(
StringRef FuncName) const {
return BBSPR.getClusterInfoForFunction(FuncName);

View File

@ -1,17 +1,13 @@
;; Check the basic block sections list option.
;; version 0 profile:
; RUN: echo '!_Z3foob' > %t1
;; Check that specifying the function in the basic block sections profile
;; without any other directives is a noop.
;;
;; version 1 profile:
; RUN: echo 'v1' > %t2
; RUN: echo 'f _Z3foob' >> %t2
;; Specify the bb sections profile:
; RUN: echo 'v1' > %t
; RUN: echo 'f _Z3foob' >> %t
;;
; RUN: llc < %s -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=%t1 -unique-basic-block-section-names | FileCheck %s -check-prefix=LINUX-SECTIONS --check-prefix=LINUX-SECTIONS-FUNCTION-SECTION
; RUN: llc < %s -mtriple=x86_64-pc-linux -basic-block-sections=%t1 -unique-basic-block-section-names | FileCheck %s -check-prefix=LINUX-SECTIONS --check-prefix=LINUX-SECTIONS-NO-FUNCTION-SECTION
; RUN: llc < %s -mtriple=x86_64-pc-linux -basic-block-sections=%t1 -unique-basic-block-section-names --bbsections-guided-section-prefix=false | FileCheck %s -check-prefix=LINUX-SECTIONS-NO-GUIDED-PREFIX
; RUN: llc < %s -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=%t2 -unique-basic-block-section-names | FileCheck %s -check-prefix=LINUX-SECTIONS --check-prefix=LINUX-SECTIONS-FUNCTION-SECTION
; RUN: llc < %s -mtriple=x86_64-pc-linux -basic-block-sections=%t2 -unique-basic-block-section-names | FileCheck %s -check-prefix=LINUX-SECTIONS --check-prefix=LINUX-SECTIONS-NO-FUNCTION-SECTION
; RUN: llc < %s -mtriple=x86_64-pc-linux -basic-block-sections=%t2 -unique-basic-block-section-names --bbsections-guided-section-prefix=false | FileCheck %s -check-prefix=LINUX-SECTIONS-NO-GUIDED-PREFIX
; RUN: llc < %s -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=%t > %bbsections
; RUN: llc < %s -mtriple=x86_64-pc-linux -function-sections > %orig
; RUN: diff -u %orig %bbsections
define i32 @_Z3foob(i1 zeroext %0) nounwind {
%2 = alloca i32, align 4
@ -41,45 +37,3 @@ define i32 @_Z3foob(i1 zeroext %0) nounwind {
declare i32 @_Z3barv() #1
declare i32 @_Z3bazv() #1
define i32 @_Z3zipb(i1 zeroext %0) nounwind {
%2 = alloca i32, align 4
%3 = alloca i8, align 1
%4 = zext i1 %0 to i8
store i8 %4, ptr %3, align 1
%5 = load i8, ptr %3, align 1
%6 = trunc i8 %5 to i1
%7 = zext i1 %6 to i32
%8 = icmp sgt i32 %7, 0
br i1 %8, label %9, label %11
9: ; preds = %1
%10 = call i32 @_Z3barv()
store i32 %10, ptr %2, align 4
br label %13
11: ; preds = %1
%12 = call i32 @_Z3bazv()
store i32 %12, ptr %2, align 4
br label %13
13: ; preds = %11, %9
%14 = load i32, ptr %2, align 4
ret i32 %14
}
; LINUX-SECTIONS-NO-GUIDED-PREFIX: .section .text._Z3foob,"ax",@progbits
; LINUX-SECTIONS: .section .text.hot._Z3foob,"ax",@progbits
; LINUX-SECTIONS: _Z3foob:
; LINUX-SECTIONS: .section .text.hot._Z3foob._Z3foob.__part.1,"ax",@progbits
; LINUX-SECTIONS: _Z3foob.__part.1:
; LINUX-SECTIONS: .section .text.hot._Z3foob._Z3foob.__part.2,"ax",@progbits
; LINUX-SECTIONS: _Z3foob.__part.2:
; LINUX-SECTIONS: .section .text.hot._Z3foob._Z3foob.__part.3,"ax",@progbits
; LINUX-SECTIONS: _Z3foob.__part.3:
; LINUX-SECTIONS-FUNCTION-SECTION: .section .text._Z3zipb,"ax",@progbits
; LINUX-SECTIONS-NO-FUNCTION-SECTION-NOT: .section .text{{.*}}._Z3zipb,"ax",@progbits
; LINUX-SECTIONS: _Z3zipb:
; LINUX-SECTIONS-NOT: .section .text{{.*}}._Z3zipb.__part.{{[0-9]+}},"ax",@progbits
; LINUX-SECTIONS-NOT: _Z3zipb.__part.{{[0-9]+}}:

View File

@ -1,6 +1,8 @@
; RUN: echo "!foo" > %t.order.txt
; RUN: llc < %s -mtriple=x86_64-pc-linux -basic-block-sections=%t.order.txt | FileCheck --check-prefix=SOURCE-DRIFT %s
; RUN: llc < %s -mtriple=x86_64-pc-linux -basic-block-sections=%t.order.txt -bbsections-detect-source-drift=false | FileCheck --check-prefix=HASH-CHECK-DISABLED %s
; RUN: echo "v1" > %t
; RUN: echo "f foo" >> %t
; RUN: echo "c 0" >> %t
; RUN: llc < %s -mtriple=x86_64-pc-linux -basic-block-sections=%t | FileCheck --check-prefix=SOURCE-DRIFT %s
; RUN: llc < %s -mtriple=x86_64-pc-linux -basic-block-sections=%t -bbsections-detect-source-drift=false | FileCheck --check-prefix=HASH-CHECK-DISABLED %s
define dso_local i32 @foo(i1 zeroext %0, i1 zeroext %1) !annotation !1 {
br i1 %0, label %5, label %3