Treat specifying a function in the bbsection profile without any directive as noop. (#167359)
This commit is contained in:
parent
8b1cc2d5f5
commit
95db31e7f6
@ -1 +1,3 @@
|
||||
!world
|
||||
v1
|
||||
f world
|
||||
c 0
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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>>
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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]+}}:
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user