mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[CodeGen] Add text section prefix for COFF object file
Text section prefix is created in CodeGenPrepare, it's file format independent implementation, text section name is written into object file in TargetLoweringObjectFile, it's file format dependent implementation, port code of adding text section prefix to text section name from ELF to COFF. Different with ELF that use '.' as concatenation character, COFF use '$' as concatenation character. That is, concatenation character is variable, so split concatenation character from text section prefix. Text section prefix is existing feature of ELF, it can help to reduce icache and itlb misses, it's also make possible aggregate other compilers e.g. v8 created same prefix sections. Furthermore, the recent feature Machine Function Splitter (basic block level text prefix section) is based on text section prefix. Reviewed By: pengfei, rnk Differential Revision: https://reviews.llvm.org/D92073
This commit is contained in:
parent
73794ea227
commit
5725c8779a
@ -33,8 +33,8 @@ class FunctionSamples;
|
||||
|
||||
} // end namespace sampleprof
|
||||
|
||||
inline const char *getHotSectionPrefix() { return ".hot"; }
|
||||
inline const char *getUnlikelySectionPrefix() { return ".unlikely"; }
|
||||
inline const char *getHotSectionPrefix() { return "hot"; }
|
||||
inline const char *getUnlikelySectionPrefix() { return "unlikely"; }
|
||||
|
||||
class ProfileSummaryBuilder {
|
||||
private:
|
||||
|
@ -473,12 +473,12 @@ bool CodeGenPrepare::runOnFunction(Function &F) {
|
||||
OptSize = F.hasOptSize();
|
||||
if (ProfileGuidedSectionPrefix) {
|
||||
if (PSI->isFunctionHotInCallGraph(&F, *BFI))
|
||||
F.setSectionPrefix(".hot");
|
||||
F.setSectionPrefix("hot");
|
||||
else if (PSI->isFunctionColdInCallGraph(&F, *BFI))
|
||||
F.setSectionPrefix(".unlikely");
|
||||
F.setSectionPrefix("unlikely");
|
||||
else if (ProfileUnknownInSpecialSection && PSI->hasPartialSampleProfile() &&
|
||||
PSI->isFunctionHotnessUnknown(F))
|
||||
F.setSectionPrefix(".unknown");
|
||||
F.setSectionPrefix("unknown");
|
||||
}
|
||||
|
||||
/// This optimization identifies DIV instructions that can be
|
||||
|
@ -107,8 +107,8 @@ bool MachineFunctionSplitter::runOnMachineFunction(MachineFunction &MF) {
|
||||
// or functions of unknown hotness. Lukewarm functions have no prefix.
|
||||
Optional<StringRef> SectionPrefix = MF.getFunction().getSectionPrefix();
|
||||
if (SectionPrefix.hasValue() &&
|
||||
(SectionPrefix.getValue().equals(".unlikely") ||
|
||||
SectionPrefix.getValue().equals(".unknown"))) {
|
||||
(SectionPrefix.getValue().equals("unlikely") ||
|
||||
SectionPrefix.getValue().equals("unknown"))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -621,7 +621,7 @@ getELFSectionNameForGlobal(const GlobalObject *GO, SectionKind Kind,
|
||||
bool HasPrefix = false;
|
||||
if (const auto *F = dyn_cast<Function>(GO)) {
|
||||
if (Optional<StringRef> Prefix = F->getSectionPrefix()) {
|
||||
Name += *Prefix;
|
||||
raw_svector_ostream(Name) << '.' << *Prefix;
|
||||
HasPrefix = true;
|
||||
}
|
||||
}
|
||||
@ -1573,6 +1573,10 @@ MCSection *TargetLoweringObjectFileCOFF::SelectSectionForGlobal(
|
||||
MCSymbol *Sym = TM.getSymbol(ComdatGV);
|
||||
StringRef COMDATSymName = Sym->getName();
|
||||
|
||||
if (const auto *F = dyn_cast<Function>(GO))
|
||||
if (Optional<StringRef> Prefix = F->getSectionPrefix())
|
||||
raw_svector_ostream(Name) << '$' << *Prefix;
|
||||
|
||||
// Append "$symbol" to the section name *before* IR-level mangling is
|
||||
// applied when targetting mingw. This is what GCC does, and the ld.bfd
|
||||
// COFF linker will not properly handle comdats otherwise.
|
||||
@ -2020,7 +2024,7 @@ static MCSectionWasm *selectWasmSectionForGlobal(
|
||||
if (const auto *F = dyn_cast<Function>(GO)) {
|
||||
const auto &OptionalPrefix = F->getSectionPrefix();
|
||||
if (OptionalPrefix)
|
||||
Name += *OptionalPrefix;
|
||||
raw_svector_ostream(Name) << '.' << *OptionalPrefix;
|
||||
}
|
||||
|
||||
if (EmitUniqueSection && UniqueSectionNames) {
|
||||
|
@ -207,8 +207,8 @@ declare i32 @__gxx_personality_v0(...)
|
||||
!12 = !{i32 999900, i64 100, i32 1}
|
||||
!13 = !{i32 999999, i64 1, i32 2}
|
||||
!14 = !{!"function_entry_count", i64 7000}
|
||||
!15 = !{!"function_section_prefix", !".hot"}
|
||||
!16 = !{!"function_section_prefix", !".unlikely"}
|
||||
!15 = !{!"function_section_prefix", !"hot"}
|
||||
!16 = !{!"function_section_prefix", !"unlikely"}
|
||||
!17 = !{!"branch_weights", i32 7000, i32 0}
|
||||
!18 = !{!"branch_weights", i32 3000, i32 4000}
|
||||
!19 = !{!"branch_weights", i32 1000, i32 6000}
|
||||
|
@ -74,14 +74,26 @@ entry:
|
||||
; GNU32: .long 42
|
||||
|
||||
|
||||
define linkonce_odr dso_local i32 @_Z3fooj(i32 %x) !section_prefix !0 {
|
||||
entry:
|
||||
%call = tail call i32 @_Z3bari(i32 %x)
|
||||
%0 = load i32, i32* @gv, align 4
|
||||
%add = add nsw i32 %0, %call
|
||||
ret i32 %add
|
||||
}
|
||||
|
||||
; Make sure the assembler puts the .xdata and .pdata in sections with the right
|
||||
; names.
|
||||
; GNUOBJ: .text$_Z3fooi
|
||||
; GNUOBJ: .xdata$_Z3fooi
|
||||
; GNUOBJ: .text$unlikely$_Z3fooj
|
||||
; GNUOBJ: .xdata$unlikely$_Z3fooj
|
||||
; GNUOBJ: .data$gv
|
||||
; GNUOBJ: .pdata$_Z3fooi
|
||||
; GNUOBJ: .pdata$unlikely$_Z3fooj
|
||||
|
||||
declare dso_local i32 @_Z3bari(i32)
|
||||
|
||||
attributes #0 = { norecurse uwtable }
|
||||
attributes #1 = { inlinehint uwtable }
|
||||
!0 = !{!"function_section_prefix", !"unlikely"}
|
||||
|
26
test/CodeGen/X86/text-section-prefix.ll
Normal file
26
test/CodeGen/X86/text-section-prefix.ll
Normal file
@ -0,0 +1,26 @@
|
||||
; RUN: llc -mtriple x86_64-linux-gnu -function-sections %s -o - | FileCheck %s --check-prefix=ELF
|
||||
; RUN: llc -mtriple x86_64-linux-gnu -unique-section-names=0 -function-sections %s -o - | FileCheck %s --check-prefix=ELF-NOUNIQ
|
||||
; RUN: llc -mtriple x86_64-windows-msvc -function-sections %s -o - | FileCheck %s --check-prefix=COFF-MSVC
|
||||
; RUN: llc -mtriple x86_64-windows-gnu -function-sections %s -o - | FileCheck %s --check-prefix=COFF-GNU
|
||||
|
||||
define void @foo1(i1 zeroext %0) nounwind !section_prefix !0 {
|
||||
;; CHECK hot section name
|
||||
; ELF: .section .text.hot.foo1,"ax",@progbits
|
||||
; ELF-NOUNIQ: .section .text.hot.,"ax",@progbits,unique,1
|
||||
; COFF-MSVC: .section .text$hot,"xr",one_only,foo1
|
||||
; COFF-GNU: .section .text$hot$foo1,"xr",one_only,foo1
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo2(i1 zeroext %0) nounwind !section_prefix !1 {
|
||||
;; CHECK unlikely section name
|
||||
; ELF: .section .text.unlikely.foo2,"ax",@progbits
|
||||
; ELF-NOUNIQ: .section .text.unlikely.,"ax",@progbits,unique,2
|
||||
; COFF-MSVC: .section .text$unlikely,"xr",one_only,foo2
|
||||
; COFF-GNU: .section .text$unlikely$foo2,"xr",one_only,foo2
|
||||
ret void
|
||||
}
|
||||
|
||||
!0 = !{!"function_section_prefix", !"hot"}
|
||||
!1 = !{!"function_section_prefix", !"unlikely"}
|
||||
|
@ -34,8 +34,8 @@ define void @cold_func() !prof !16 {
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: ![[HOT_ID]] = !{!"function_section_prefix", !".hot"}
|
||||
; CHECK: ![[COLD_ID]] = !{!"function_section_prefix", !".unlikely"}
|
||||
; CHECK: ![[HOT_ID]] = !{!"function_section_prefix", !"hot"}
|
||||
; CHECK: ![[COLD_ID]] = !{!"function_section_prefix", !"unlikely"}
|
||||
!llvm.module.flags = !{!1}
|
||||
!1 = !{i32 1, !"ProfileSummary", !2}
|
||||
!2 = !{!3, !4, !5, !6, !7, !8, !9, !10}
|
||||
|
@ -66,8 +66,8 @@ define void @cold_func3() !prof !16 {
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: ![[HOT_ID]] = !{!"function_section_prefix", !".hot"}
|
||||
; CHECK: ![[COLD_ID]] = !{!"function_section_prefix", !".unlikely"}
|
||||
; CHECK: ![[HOT_ID]] = !{!"function_section_prefix", !"hot"}
|
||||
; CHECK: ![[COLD_ID]] = !{!"function_section_prefix", !"unlikely"}
|
||||
!llvm.module.flags = !{!1}
|
||||
!1 = !{i32 1, !"ProfileSummary", !2}
|
||||
!2 = !{!3, !4, !5, !6, !7, !8, !9, !10}
|
||||
|
@ -27,9 +27,9 @@ declare void @sink() cold
|
||||
; CHECK: define {{.*}} @fun.cold.1{{.*}} ![[PROF:[0-9]+]] {{.*}}section_prefix ![[UNLIKELY:[0-9]+]]
|
||||
|
||||
; CHECK: ![[HOTPROF]] = !{!"function_entry_count", i64 100}
|
||||
; CHECK: ![[LIKELY]] = !{!"function_section_prefix", !".hot"}
|
||||
; CHECK: ![[LIKELY]] = !{!"function_section_prefix", !"hot"}
|
||||
; CHECK: ![[PROF]] = !{!"function_entry_count", i64 0}
|
||||
; CHECK: ![[UNLIKELY]] = !{!"function_section_prefix", !".unlikely"}
|
||||
; CHECK: ![[UNLIKELY]] = !{!"function_section_prefix", !"unlikely"}
|
||||
|
||||
!llvm.module.flags = !{!0}
|
||||
!0 = !{i32 1, !"ProfileSummary", !1}
|
||||
@ -47,6 +47,6 @@ declare void @sink() cold
|
||||
!12 = !{i32 999000, i64 100, i32 1}
|
||||
!13 = !{i32 999999, i64 1, i32 2}
|
||||
!14 = !{!"function_entry_count", i64 100}
|
||||
!15 = !{!"function_section_prefix", !".hot"}
|
||||
!15 = !{!"function_section_prefix", !"hot"}
|
||||
!16 = !{!"function_entry_count", i64 0}
|
||||
!17 = !{!"function_section_prefix", !".unlikely"}
|
||||
!17 = !{!"function_section_prefix", !"unlikely"}
|
||||
|
@ -36,11 +36,11 @@ attributes #1 = { "use-sample-profile" }
|
||||
|
||||
; CHECK: ![[NOPROFILE_ID]] = !{!"function_entry_count", i64 -1}
|
||||
; CHECK: ![[ZERO_ID]] = !{!"function_entry_count", i64 0}
|
||||
; CHECK: ![[COLD_ID]] = !{!"function_section_prefix", !".unlikely"}
|
||||
; CHECK: ![[COLD_ID]] = !{!"function_section_prefix", !"unlikely"}
|
||||
; UNKNOWN: ![[NOPROFILE_ID]] = !{!"function_entry_count", i64 -1}
|
||||
; UNKNOWN: ![[UNKNOWN_ID]] = !{!"function_section_prefix", !".unknown"}
|
||||
; UNKNOWN: ![[UNKNOWN_ID]] = !{!"function_section_prefix", !"unknown"}
|
||||
; ACCURATE: ![[ZERO_ID]] = !{!"function_entry_count", i64 0}
|
||||
; ACCURATE: ![[COLD_ID]] = !{!"function_section_prefix", !".unlikely"}
|
||||
; ACCURATE: ![[COLD_ID]] = !{!"function_section_prefix", !"unlikely"}
|
||||
!llvm.module.flags = !{!1}
|
||||
!1 = !{i32 1, !"ProfileSummary", !2}
|
||||
!2 = !{!3, !4, !5, !6, !7, !8, !9, !10}
|
||||
|
Loading…
x
Reference in New Issue
Block a user