https://github.com/HaohaiWen created https://github.com/llvm/llvm-project/pull/191347
Enable -fbasic-block-address-map fo X86 COFF. Add COFF section creation for .llvm_bb_addr_map. >From ad2ca2b69e5ba4ba7b6808d9b716fdb269e6f2eb Mon Sep 17 00:00:00 2001 From: Haohai Wen <[email protected]> Date: Tue, 7 Apr 2026 15:44:11 +0800 Subject: [PATCH] [X86][COFF] Enable basic-block-address-map emission Enable -fbasic-block-address-map fo X86 COFF. Add COFF section creation for .llvm_bb_addr_map. --- clang/lib/Driver/ToolChains/Clang.cpp | 3 +- clang/test/Driver/basic-block-address-map.c | 1 + llvm/include/llvm/Object/BBAddrMap.h | 3 ++ llvm/lib/MC/MCObjectFileInfo.cpp | 45 +++++++++++++------ ...sic-block-address-map-function-sections.ll | 32 +++++++++---- .../CodeGen/X86/basic-block-address-map.ll | 13 ++++-- 6 files changed, 70 insertions(+), 27 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 0d5722cd536f2..57f342273fef6 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -6280,7 +6280,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Arg *A = Args.getLastArg(options::OPT_fbasic_block_address_map, options::OPT_fno_basic_block_address_map)) { - if ((Triple.isX86() || Triple.isAArch64()) && Triple.isOSBinFormatELF()) { + if (((Triple.isX86() || Triple.isAArch64()) && Triple.isOSBinFormatELF()) || + (Triple.isX86() && Triple.isOSBinFormatCOFF())) { if (A->getOption().matches(options::OPT_fbasic_block_address_map)) A->render(Args, CmdArgs); } else { diff --git a/clang/test/Driver/basic-block-address-map.c b/clang/test/Driver/basic-block-address-map.c index 12393e8ebfd54..b11dbb3c65548 100644 --- a/clang/test/Driver/basic-block-address-map.c +++ b/clang/test/Driver/basic-block-address-map.c @@ -1,5 +1,6 @@ // RUN: %clang -### --target=x86_64 -fbasic-block-address-map %s -S 2>&1 | FileCheck -check-prefix=CHECK-PRESENT %s // RUN: %clang -### --target=aarch64 -fbasic-block-address-map %s -S 2>&1 | FileCheck -check-prefix=CHECK-PRESENT %s +// RUN: %clang -### --target=x86_64-pc-windows-msvc -fbasic-block-address-map %s -S 2>&1 | FileCheck -check-prefix=CHECK-PRESENT %s // CHECK-PRESENT: -fbasic-block-address-map // RUN: %clang -### --target=x86_64 -fno-basic-block-address-map %s -S 2>&1 | FileCheck %s --check-prefix=CHECK-ABSENT diff --git a/llvm/include/llvm/Object/BBAddrMap.h b/llvm/include/llvm/Object/BBAddrMap.h index 49c9b431822e0..4f710bc19951e 100644 --- a/llvm/include/llvm/Object/BBAddrMap.h +++ b/llvm/include/llvm/Object/BBAddrMap.h @@ -15,6 +15,7 @@ #define LLVM_OBJECT_BBADDRMAP_H #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/BlockFrequency.h" #include "llvm/Support/BranchProbability.h" #include "llvm/Support/DataExtractor.h" @@ -24,6 +25,8 @@ namespace llvm { namespace object { +inline constexpr StringLiteral BBAddrMapSectionName = ".llvm_bb_addr_map"; + // Struct representing the BBAddrMap for one function. struct BBAddrMap { diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp index 56a22241ae5d3..1e78e5fe2cc49 100644 --- a/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/llvm/lib/MC/MCObjectFileInfo.cpp @@ -27,6 +27,7 @@ #include "llvm/MC/MCSectionXCOFF.h" #include "llvm/MC/MCSymbolGOFF.h" #include "llvm/MC/SectionKind.h" +#include "llvm/Object/BBAddrMap.h" #include "llvm/TargetParser/Triple.h" using namespace llvm; @@ -1266,23 +1267,39 @@ MCObjectFileInfo::getStackSizesSection(const MCSection &TextSec) const { MCSection * MCObjectFileInfo::getBBAddrMapSection(const MCSection &TextSec) const { - if (Ctx->getObjectFileType() != MCContext::IsELF) - return nullptr; + StringRef Name = object::BBAddrMapSectionName; + if (Ctx->getObjectFileType() == MCContext::IsELF) { + const MCSectionELF &ElfSec = static_cast<const MCSectionELF &>(TextSec); + unsigned Flags = ELF::SHF_LINK_ORDER; + StringRef GroupName; + if (const MCSymbol *Group = ElfSec.getGroup()) { + GroupName = Group->getName(); + Flags |= ELF::SHF_GROUP; + } - const MCSectionELF &ElfSec = static_cast<const MCSectionELF &>(TextSec); - unsigned Flags = ELF::SHF_LINK_ORDER; - StringRef GroupName; - if (const MCSymbol *Group = ElfSec.getGroup()) { - GroupName = Group->getName(); - Flags |= ELF::SHF_GROUP; + // Use the text section's begin symbol and unique ID to create a separate + // .llvm_bb_addr_map section associated with every unique text section. + return Ctx->getELFSection( + Name, ELF::SHT_LLVM_BB_ADDR_MAP, Flags, 0, GroupName, true, + ElfSec.getUniqueID(), + static_cast<const MCSymbolELF *>(TextSec.getBeginSymbol())); + } else if (Ctx->getObjectFileType() == MCContext::IsCOFF) { + StringRef COMDATSymName = ""; + int Selection = 0; + unsigned Characteristics = COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_DISCARDABLE | + COFF::IMAGE_SCN_MEM_READ; + const auto &COFFSec = static_cast<const MCSectionCOFF &>(TextSec); + if (const MCSymbol *COMDATSym = COFFSec.getCOMDATSymbol()) { + COMDATSymName = COMDATSym->getName(); + Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; + Selection = COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE; + } + return Ctx->getCOFFSection(Name, Characteristics, COMDATSymName, Selection, + COFFSec.getUniqueID()); } - // Use the text section's begin symbol and unique ID to create a separate - // .llvm_bb_addr_map section associated with every unique text section. - return Ctx->getELFSection( - ".llvm_bb_addr_map", ELF::SHT_LLVM_BB_ADDR_MAP, Flags, 0, GroupName, true, - ElfSec.getUniqueID(), - static_cast<const MCSymbolELF *>(TextSec.getBeginSymbol())); + return nullptr; } MCSection * diff --git a/llvm/test/CodeGen/X86/basic-block-address-map-function-sections.ll b/llvm/test/CodeGen/X86/basic-block-address-map-function-sections.ll index 892fa009935d2..2f4be8ab9fd06 100644 --- a/llvm/test/CodeGen/X86/basic-block-address-map-function-sections.ll +++ b/llvm/test/CodeGen/X86/basic-block-address-map-function-sections.ll @@ -1,15 +1,23 @@ -; RUN: llc < %s -mtriple=x86_64 -function-sections -basic-block-address-map | FileCheck %s +; RUN: llc < %s -mtriple=x86_64 -function-sections -basic-block-address-map | FileCheck %s --check-prefixes=CHECK,ELF,ELF-FS +; RUN: llc < %s -mtriple=x86_64 -basic-block-address-map | FileCheck %s --check-prefixes=CHECK,ELF,ELF-NOFS +; RUN: llc < %s -mtriple=x86_64-pc-windows-msvc -function-sections -basic-block-address-map | FileCheck %s --check-prefixes=CHECK,COFF-FS +; RUN: llc < %s -mtriple=x86_64-pc-windows-msvc -basic-block-address-map | FileCheck %s --check-prefixes=CHECK,COFF-NOFS $_Z4fooTIiET_v = comdat any define dso_local i32 @_Z3barv() { ret i32 0 } -;; Check we add SHF_LINK_ORDER for .llvm_bb_addr_map and link it with the corresponding .text sections. -; CHECK: .section .text._Z3barv,"ax",@progbits +;; For ELF, check we add SHF_LINK_ORDER for .llvm_bb_addr_map and link it with the corresponding .text sections. +;; For COFF, it does not have SHF_LINK_ORDER like mechanism, we use function symbol to "link" them. +; ELF-FS: .section .text._Z3barv,"ax",@progbits +; COFF-FS: .section .text,"xr",one_only,_Z3barv ; CHECK-LABEL: _Z3barv: ; CHECK-NEXT: [[BAR_BEGIN:.Lfunc_begin[0-9]+]]: -; CHECK: .section .llvm_bb_addr_map,"o",@llvm_bb_addr_map,.text._Z3barv{{$}} +; ELF-FS: .section .llvm_bb_addr_map,"o",@llvm_bb_addr_map,.text._Z3barv{{$}} +; ELF-NOFS: .section .llvm_bb_addr_map,"o",@llvm_bb_addr_map,.text{{$}} +; COFF-FS: .section .llvm_bb_addr_map,"drD",associative,_Z3barv,unique,0{{$}} +; COFF-NOFS: .section .llvm_bb_addr_map,"drD"{{$}} ; CHECK-NEXT: .byte 5 # version ; CHECK-NEXT: .short 0 # feature ; CHECK-NEXT: .quad [[BAR_BEGIN]] # function address @@ -19,10 +27,14 @@ define dso_local i32 @_Z3foov() { %1 = call i32 @_Z4fooTIiET_v() ret i32 %1 } -; CHECK: .section .text._Z3foov,"ax",@progbits +; ELF-FS: .section .text._Z3foov,"ax",@progbits +; COFF-FS: .section .text,"xr",one_only,_Z3foov ; CHECK-LABEL: _Z3foov: ; CHECK-NEXT: [[FOO_BEGIN:.Lfunc_begin[0-9]+]]: -; CHECK: .section .llvm_bb_addr_map,"o",@llvm_bb_addr_map,.text._Z3foov{{$}} +; ELF-FS: .section .llvm_bb_addr_map,"o",@llvm_bb_addr_map,.text._Z3foov{{$}} +; ELF-NOFS: .section .llvm_bb_addr_map,"o",@llvm_bb_addr_map,.text{{$}} +; COFF-FS: .section .llvm_bb_addr_map,"drD",associative,_Z3foov,unique,1{{$}} +; COFF-NOFS: .section .llvm_bb_addr_map,"drD"{{$}} ; CHECK-NEXT: .byte 5 # version ; CHECK-NEXT: .short 32 # feature ; CHECK-NEXT: .quad [[FOO_BEGIN]] # function address @@ -32,10 +44,14 @@ define linkonce_odr dso_local i32 @_Z4fooTIiET_v() comdat { ret i32 0 } ;; Check we add .llvm_bb_addr_map section to a COMDAT group with the corresponding .text section if such a COMDAT exists. -; CHECK: .section .text._Z4fooTIiET_v,"axG",@progbits,_Z4fooTIiET_v,comdat +; ELF: .section .text._Z4fooTIiET_v,"axG",@progbits,_Z4fooTIiET_v,comdat +; COFF-FS: .section .text,"xr",discard,_Z4fooTIiET_v,unique,2{{$}} +; COFF-NOFS: .section .text,"xr",discard,_Z4fooTIiET_v{{$}} ; CHECK-LABEL: _Z4fooTIiET_v: ; CHECK-NEXT: [[FOOCOMDAT_BEGIN:.Lfunc_begin[0-9]+]]: -; CHECK: .section .llvm_bb_addr_map,"oG",@llvm_bb_addr_map,.text._Z4fooTIiET_v,_Z4fooTIiET_v,comdat{{$}} +; ELF: .section .llvm_bb_addr_map,"oG",@llvm_bb_addr_map,.text._Z4fooTIiET_v,_Z4fooTIiET_v,comdat{{$}} +; COFF-FS: .section .llvm_bb_addr_map,"drD",associative,_Z4fooTIiET_v,unique,2{{$}} +; COFF-NOFS: .section .llvm_bb_addr_map,"drD",associative,_Z4fooTIiET_v{{$}} ; CHECK-NEXT: .byte 5 # version ; CHECK-NEXT: .short 0 # feature ; CHECK-NEXT: .quad [[FOOCOMDAT_BEGIN]] # function address diff --git a/llvm/test/CodeGen/X86/basic-block-address-map.ll b/llvm/test/CodeGen/X86/basic-block-address-map.ll index 5567ccd4f9e75..c716e12a57646 100644 --- a/llvm/test/CodeGen/X86/basic-block-address-map.ll +++ b/llvm/test/CodeGen/X86/basic-block-address-map.ll @@ -1,7 +1,8 @@ ; Check the basic block sections labels option -; RUN: llc < %s -mtriple=x86_64 -function-sections -unique-section-names=true -basic-block-address-map | FileCheck %s --check-prefixes=CHECK,UNIQ -; RUN: llc < %s -mtriple=x86_64 -function-sections -unique-section-names=false -basic-block-address-map | FileCheck %s --check-prefixes=CHECK,NOUNIQ -; RUN: llc < %s -mtriple=x86_64 -function-sections -unique-section-names=true -basic-block-address-map -split-machine-functions | FileCheck %s --check-prefixes=CHECK,UNIQ +; RUN: llc < %s -mtriple=x86_64 -function-sections -unique-section-names=true -basic-block-address-map | FileCheck %s --check-prefixes=CHECK,ELF,UNIQ +; RUN: llc < %s -mtriple=x86_64 -function-sections -unique-section-names=false -basic-block-address-map | FileCheck %s --check-prefixes=CHECK,ELF,NOUNIQ +; RUN: llc < %s -mtriple=x86_64 -function-sections -unique-section-names=true -basic-block-address-map -split-machine-functions | FileCheck %s --check-prefixes=CHECK,ELF,UNIQ +; RUN: llc < %s -mtriple=x86_64-pc-windows-msvc -function-sections -basic-block-address-map | FileCheck %s --check-prefixes=CHECK,COFF define void @_Z3bazb(i1 zeroext, i1 zeroext) personality ptr @__gxx_personality_v0 { br i1 %0, label %3, label %8 @@ -52,6 +53,7 @@ declare i32 @__gxx_personality_v0(...) ; UNIQ: .section .llvm_bb_addr_map,"o",@llvm_bb_addr_map,.text._Z3bazb{{$}} ;; Verify that with -unique-section-names=false, the unique id of the text section gets assigned to the llvm_bb_addr_map section. ; NOUNIQ: .section .llvm_bb_addr_map,"o",@llvm_bb_addr_map,.text,unique,1 +; COFF: .section .llvm_bb_addr_map,"drD",associative,_Z3bazb,unique,0{{$}} ; CHECK-NEXT: .byte 5 # version ; CHECK-NEXT: .short 32 # feature ; CHECK-NEXT: .quad .Lfunc_begin0 # function address @@ -87,4 +89,7 @@ declare i32 @__gxx_personality_v0(...) ; CHECK-NEXT: .uleb128 .LBB0_5-.LBB_END0_4 ; CHECK-NEXT: .byte 0 # number of callsites ; CHECK-NEXT: .uleb128 .LBB_END0_5-.LBB0_5 -; CHECK-NEXT: .byte 5 +;; The landingpad block metadata differs: ELF uses eh_frame (HasReturn set), +;; COFF uses SEH (HasReturn not set). +; ELF-NEXT: .byte 5 +; COFF-NEXT: .byte 4 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
