diff --git a/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h b/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h --- a/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h +++ b/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h @@ -39,7 +39,8 @@ unsigned PositionInCluster; }; -using ProgramBBClusterInfoMapTy = StringMap>; +using ProgramBBClusterInfoMapTy = + StringMap>>; class BasicBlockSectionsProfileReader : public ImmutablePass { public: @@ -62,7 +63,7 @@ // Returns true if basic block sections profile exist for function \p // FuncName. - bool isFunctionHot(StringRef FuncName) const; + bool isFunctionHot(StringRef ModuleName, 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 @@ -71,15 +72,18 @@ // means unique basic block sections are desired for all basic blocks of the // function. std::pair> - getBBClusterInfoForFunction(StringRef FuncName) const; + getBBClusterInfoForFunction(StringRef ModuleName, StringRef FuncName) const; /// Read profiles of basic blocks if available here. void initializePass() override; private: - StringRef getAliasName(StringRef FuncName) const { - auto R = FuncAliasMap.find(FuncName); - return R == FuncAliasMap.end() ? FuncName : R->second; + StringRef getAliasName(StringRef ModuleName, StringRef FuncName) const { + auto R = FuncAliasMap.find(ModuleName); + if (R == FuncAliasMap.end()) + return FuncName; + auto S = R->second.find(FuncName); + return S == R->second.end() ? FuncName : S->second; } // This contains the basic-block-sections profile. @@ -95,7 +99,7 @@ // Some functions have alias names. We use this map to find the main alias // name for which we have mapping in ProgramBBClusterInfo. - StringMap FuncAliasMap; + StringMap> FuncAliasMap; }; // Creates a BasicBlockSectionsProfileReader pass to parse the basic block diff --git a/llvm/lib/CodeGen/BasicBlockSections.cpp b/llvm/lib/CodeGen/BasicBlockSections.cpp --- a/llvm/lib/CodeGen/BasicBlockSections.cpp +++ b/llvm/lib/CodeGen/BasicBlockSections.cpp @@ -170,8 +170,9 @@ DenseMap &V) { // Find the assoicated cluster information. + errs() << "MODULE NAME: " << MF.getFunction().getParent()->getSourceFileName() << " " << MF.getFunction().getParent()->getName(); std::pair> P = - BBSectionsProfileReader->getBBClusterInfoForFunction(MF.getName()); + BBSectionsProfileReader->getBBClusterInfoForFunction(MF.getFunction().getParent()->getSourceFileName(), MF.getName()); if (!P.first) return false; diff --git a/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp b/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp --- a/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp +++ b/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp @@ -28,18 +28,24 @@ "Reads and parses a basic block sections profile.", false, false) -bool BasicBlockSectionsProfileReader::isFunctionHot(StringRef FuncName) const { - return getBBClusterInfoForFunction(FuncName).first; +bool BasicBlockSectionsProfileReader::isFunctionHot(StringRef ModuleName, + StringRef FuncName) const { + return getBBClusterInfoForFunction(ModuleName, FuncName).first; } std::pair> BasicBlockSectionsProfileReader::getBBClusterInfoForFunction( - StringRef FuncName) const { + StringRef ModuleName, StringRef FuncName) const { std::pair> cluster_info(false, {}); - auto R = ProgramBBClusterInfo.find(getAliasName(FuncName)); - if (R != ProgramBBClusterInfo.end()) { - cluster_info.second = R->second; - cluster_info.first = true; + for (auto UsedModuleName : {ModuleName, StringRef("")}) { + auto R = ProgramBBClusterInfo.find(UsedModuleName); + if (R == ProgramBBClusterInfo.end()) + continue; + auto S = R->second.find(getAliasName(UsedModuleName, FuncName)); + if (S != R->second.end()) { + cluster_info.second = S->second; + cluster_info.first = true; + } } return cluster_info; } @@ -59,7 +65,7 @@ // !!4 static Error getBBClusterInfo(const MemoryBuffer *MBuf, ProgramBBClusterInfoMapTy &ProgramBBClusterInfo, - StringMap &FuncAliasMap) { + StringMap> &FuncAliasMap) { assert(MBuf); line_iterator LineIt(*MBuf, /*SkipBlanks=*/true, /*CommentMarker=*/'#'); @@ -70,7 +76,8 @@ inconvertibleErrorCode()); }; - auto FI = ProgramBBClusterInfo.end(); + StringMapIterator> FI = + ProgramBBClusterInfo[""].end(); // Current cluster ID corresponding to this function. unsigned CurrentCluster = 0; @@ -90,7 +97,7 @@ break; // Check for second "!" which indicates a cluster of basic blocks. if (S.consume_front("!")) { - if (FI == ProgramBBClusterInfo.end()) + if (FI == ProgramBBClusterInfo[""].end()) return invalidProfileError( "Cluster list does not follow a function name specifier."); SmallVector BBIDs; @@ -116,14 +123,18 @@ // Function aliases are separated using '/'. We use the first function // name for the cluster info mapping and delegate all other aliases to // this one. + SmallVector FunctionAndModule; + S.split(FunctionAndModule, ' '); + StringRef ModuleName = + FunctionAndModule.size() == 1 ? "" : FunctionAndModule[1]; SmallVector Aliases; - S.split(Aliases, '/'); + FunctionAndModule[0].split(Aliases, '/'); for (size_t i = 1; i < Aliases.size(); ++i) - FuncAliasMap.try_emplace(Aliases[i], Aliases.front()); + FuncAliasMap[ModuleName].try_emplace(Aliases[i], Aliases.front()); // Prepare for parsing clusters of this function name. // Start a new cluster map for this function name. - FI = ProgramBBClusterInfo.try_emplace(Aliases.front()).first; + FI = ProgramBBClusterInfo[ModuleName].try_emplace(Aliases.front()).first; CurrentCluster = 0; FuncBBIDs.clear(); } diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -515,7 +515,7 @@ // Use the basic-block-sections profile to promote hot functions to .text.hot // if requested. if (BBSectionsGuidedSectionPrefix && BBSectionsProfileReader && - BBSectionsProfileReader->isFunctionHot(F.getName())) { + BBSectionsProfileReader->isFunctionHot(F.getParent()->getSourceFileName(), F.getName())) { F.setSectionPrefix("hot"); } else if (ProfileGuidedSectionPrefix) { // The hot attribute overwrites profile count based hotness while profile diff --git a/llvm/test/CodeGen/X86/basic-block-sections-listbb-modulename.ll b/llvm/test/CodeGen/X86/basic-block-sections-listbb-modulename.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/X86/basic-block-sections-listbb-modulename.ll @@ -0,0 +1,49 @@ +; RUN: echo '!_Z3bazb ' > %t1 +; RUN: echo '!!2' >> %t1 +; RUN: llc < %s -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=%t1 -unique-basic-block-section-names | FileCheck %s -check-prefixes=RIGHT-MODULE-NAME,LINUX-SECTIONS +; RUN: echo '!_Z3bazb baz.cpp' > %t2 +; RUN: echo '!!2' >> %t2 +; RUN: llc < %s -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=%t2 -unique-basic-block-section-names | FileCheck %s -check-prefixes=WRONG-MODULE-NAME,LINUX-SECTIONS + +define void @_Z3bazb(i1 zeroext) nounwind { + %2 = alloca i8, align 1 + %3 = zext i1 %0 to i8 + store i8 %3, ptr %2, align 1 + %4 = load i8, ptr %2, align 1 + %5 = trunc i8 %4 to i1 + br i1 %5, label %6, label %8 + +6: ; preds = %1 + %7 = call i32 @_Z3barv() + br label %10 + +8: ; preds = %1 + %9 = call i32 @_Z3foov() + br label %10 + +10: ; preds = %8, %6 + ret void +} + +declare i32 @_Z3barv() #1 + +declare i32 @_Z3foov() #1 + +; Check that the correct block is found using the call insts for foo and bar. +; +; RIGHT-MODULE-NAME: .section .text.hot._Z3bazb,"ax",@progbits +; WRONG-MODULE-NAME: .text +; LINUX-SECTIONS: _Z3bazb: +; Check that the basic block with id 1 doesn't get a section. +; LINUX-SECTIONS-NOT: .section .text{{.*}}._Z3bazb.__part.{{[0-9]+}},"ax",@progbits +; LINUX-SECTIONS-LABEL: # %bb.1: +; LINUX-SECTIONS-NEXT: callq _Z3barv +; RIGHT-MODULE-NAME: .section .text.hot._Z3bazb.[[SECTION_LABEL:_Z3bazb.__part.[0-9]+]],"ax",@progbits +; WRONG-MODULE-NAME-NOT: .section .text{{.*}}._Z3bazb.__part.{{[0-9]+}},"ax",@progbits +; RIGHT-MODULE-NAME-NEXT: [[SECTION_LABEL]]: +; RIGHT-MODULE-NAME-NEXT: callq _Z3foov +; RIGHT-MODULE-NAME: .LBB_END0_2: +; RIGHT-MODULE-NAME-NEXT: .size [[SECTION_LABEL]], .LBB_END0_2-[[SECTION_LABEL]] +; RIGHT-MODULE-NAME: .section .text.hot._Z3bazb,"ax",@progbits +; LINUX-SECTIONS: .Lfunc_end0: +; LINUX-SECTIONS-NEXT: .size _Z3bazb, .Lfunc_end0-_Z3bazb