diff --git a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h --- a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -174,6 +174,15 @@ MCSection *getSectionForJumpTable(const Function &F, const TargetMachine &TM) const override; + MCSection * + getSectionForMachineBasicBlock(const Function &F, + const MachineBasicBlock &MBB, + const TargetMachine &TM) const override; + + MCSection * + getUniqueSectionForFunction(const Function &F, + const TargetMachine &TM) const override; + /// Emit Obj-C garbage collection and linker options. void emitModuleMetadata(MCStreamer &Streamer, Module &M) const override; diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -1693,6 +1693,68 @@ COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID); } +/// Returns a unique section for the given machine basic block. +MCSection *TargetLoweringObjectFileCOFF::getSectionForMachineBasicBlock( + const Function &F, const MachineBasicBlock &MBB, + const TargetMachine &TM) const { + assert(MBB.isBeginSection() && "Basic block does not start a section!"); + SectionKind Kind = SectionKind::getText(); + unsigned Characteristics = getCOFFSectionFlags(Kind, TM); + // If we have -ffunction-sections then we should emit the global value to a + // uniqued section specifically for it. + bool EmitUniquedSection; + if (Kind.isText()) + EmitUniquedSection = TM.getFunctionSections(); + else + EmitUniquedSection = TM.getDataSections(); + + if ((EmitUniquedSection && !Kind.isCommon()) || F.hasComdat()) + Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; + unsigned UniqueID = MCContext::GenericSectionID; + StringRef COMDATSymName; + if (TM.getUniqueBasicBlockSectionNames()) + COMDATSymName = MBB.getSymbol()->getName(); + else { + UniqueID = NextUniqueID++; + COMDATSymName = MBB.getParent()->getName(); + } + + SmallString<128> Name; + // 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. + if (getTargetTriple().isWindowsGNUEnvironment()) { + Name += getCOFFSectionNameForUniqueGlobal(SectionKind::getText()); + Name += '$'; + Name += COMDATSymName; + } else + Name += MBB.getParent()->getSection()->getName(); + + return getContext().getCOFFSection( + Name, Characteristics, SectionKind::getText(), COMDATSymName, + COFF::IMAGE_COMDAT_SELECT_NODUPLICATES, UniqueID); +} + +MCSection *TargetLoweringObjectFileCOFF::getUniqueSectionForFunction( + const Function &F, const TargetMachine &TM) const { + SectionKind Kind = SectionKind::getText(); + unsigned Characteristics = getCOFFSectionFlags(Kind, TM); + // If we have -ffunction-sections then we should emit the global value to a + // uniqued section specifically for it. + bool EmitUniquedSection; + if (Kind.isText()) + EmitUniquedSection = TM.getFunctionSections(); + else + EmitUniquedSection = TM.getDataSections(); + + if ((EmitUniquedSection && !Kind.isCommon()) || F.hasComdat()) + Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; + return getContext().getCOFFSection( + getCOFFSectionNameForUniqueGlobal(Kind), Characteristics, Kind, + TM.getSymbol(&F)->getName(), COFF::IMAGE_COMDAT_SELECT_NODUPLICATES, + NextUniqueID++); +} + void TargetLoweringObjectFileCOFF::emitModuleMetadata(MCStreamer &Streamer, Module &M) const { emitLinkerDirectives(Streamer, M); diff --git a/llvm/test/CodeGen/X86/basic-block-sections.ll b/llvm/test/CodeGen/X86/basic-block-sections.ll --- a/llvm/test/CodeGen/X86/basic-block-sections.ll +++ b/llvm/test/CodeGen/X86/basic-block-sections.ll @@ -3,6 +3,10 @@ ; RUN: llc < %s -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=all -unique-basic-block-section-names -split-machine-functions | FileCheck %s -check-prefix=LINUX-SECTIONS ; RUN: llc < %s -mtriple=i386-unknown-linux-gnu -function-sections -basic-block-sections=all -unique-basic-block-section-names | FileCheck %s -check-prefix=LINUX-SECTIONS ; RUN: llc < %s -mtriple=i386-unknown-linux-gnu -basic-block-sections=all -unique-basic-block-section-names | FileCheck %s -check-prefix=LINUX-SECTIONS +; RUN: llc < %s -mtriple=x86_64-windows-msvc -function-sections -basic-block-sections=all -unique-basic-block-section-names | FileCheck %s -check-prefix=WINDOWS-MSVC-SECTIONS +; RUN: llc < %s -mtriple=x86_64-windows-msvc -basic-block-sections=all -unique-basic-block-section-names | FileCheck %s -check-prefix=WINDOWS-MSVC-SECTIONS +; RUN: llc < %s -mtriple=x86_64-windows-gnu -function-sections -basic-block-sections=all -unique-basic-block-section-names | FileCheck %s -check-prefix=WINDOWS-GNU-FUNCTION-SECTIONS +; RUN: llc < %s -mtriple=x86_64-windows-gnu -basic-block-sections=all -unique-basic-block-section-names | FileCheck %s -check-prefix=WINDOWS-GNU-SECTIONS define void @_Z3bazb(i1 zeroext) nounwind { %2 = alloca i8, align 1 @@ -39,3 +43,27 @@ ; LINUX-SECTIONS: [[SECTION_LABEL_2]]: ; LINUX-SECTIONS: .LBB_END0_2: ; LINUX-SECTIONS-NEXT: .size [[SECTION_LABEL_2]], .LBB_END0_2-[[SECTION_LABEL_2]] +; WINDOWS-MSVC-FUNCTION-SECTIONS: .section .text,"xr",one_only,_Z3bazb +; WINDOWS-MSVC-FUNCTION-SECTIONS: _Z3bazb: +; WINDOWS-MSVC-FUNCTION-SECTIONS: .section .text,"xr",one_only,[[SECTION_LABEL_1:_Z3bazb.__part.[0-9]+]] +; WINDOWS-MSVC-FUNCTION-SECTIONS: [[SECTION_LABEL_1]]: +; WINDOWS-MSVC-FUNCTION-SECTIONS: .section .text,"xr",one_only,[[SECTION_LABEL_2:_Z3bazb.__part.[0-9]+]] +; WINDOWS-MSVC-FUNCTION-SECTIONS: [[SECTION_LABEL_2]]: +; WINDOWS-MSVC-SECTIONS: .section .text,"xr" +; WINDOWS-MSVC-SECTIONS: _Z3bazb: +; WINDOWS-MSVC-SECTIONS: je [[SECTION_LABEL_2:_Z3bazb.__part.[0-9]+]] +; WINDOWS-MSVC-SECTIONS: jmp [[SECTION_LABEL_1:_Z3bazb.__part.[0-9]+]] +; WINDOWS-MSVC-SECTIONS: [[SECTION_LABEL_1]]: +; WINDOWS-MSVC-SECTIONS: [[SECTION_LABEL_2]]: +; WINDOWS-GNU-FUNCTION-SECTIONS: .section .text$_Z3bazb,"xr",one_only,_Z3bazb +; WINDOWS-GNU-FUNCTION-SECTIONS: _Z3bazb: +; WINDOWS-GNU-FUNCTION-SECTIONS: .section .text$[[SECTION_LABLE_1:_Z3bazb.__part.[0-9]+]],"xr",one_only,[[SECTION_LABEL_1:_Z3bazb.__part.[0-9]+]] +; WINDOWS-GNU-FUNCTION-SECTIONS: [[SECTION_LABEL_1]]: +; WINDOWS-GNU-FUNCTION-SECTIONS: .section .text$[[SECTION_LABEL_2:_Z3bazb.__part.[0-9]+]],"xr",one_only,[[SECTION_LABEL_2:_Z3bazb.__part.[0-9]+]] +; WINDOWS-GNU-FUNCTION-SECTIONS: [[SECTION_LABEL_2]]: +; WINDOWS-GNU-SECTIONS: .section .text,"xr" +; WINDOWS-GNU-SECTIONS: _Z3bazb: +; WINDOWS-GNU-SECTIONS: .section .text$[[SECTION_LABEL_1:_Z3bazb.__part.[0-9]+]],"xr" +; WINDOWS-GNU-SECTIONS: [[SECTION_LABEL_1]]: +; WINDOWS-GNU-SECTIONS: .section .text$[[SECTION_LABEL_2:_Z3bazb.__part.[0-9]+]],"xr" +; WINDOWS-GNU-SECTIONS: [[SECTION_LABEL_2]]: