llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-backend-x86 Author: Steffen Larsen (steffenlarsen) <details> <summary>Changes</summary> To avoid the size restriction that may be imposed by the address spaces of the target, this patch changes the embedding of the Clang AST from placing it inside a global variable to placing it inside a metadata node. This is done by introducing a new metadata node, namely `llvm.raw.sections`, which refers to nodes comprised of a section name, an alignment and the section data. The AsmPrinter lowers this to the corresponding sections. Assisted-by: Claude Opus 4.6 --- Full diff: https://github.com/llvm/llvm-project/pull/214135.diff 11 Files Affected: - (modified) clang/lib/CodeGen/ObjectFilePCHContainerWriter.cpp (+18-16) - (modified) clang/test/Modules/lsv-debuginfo.cpp (+6-3) - (added) clang/test/PCH/pch-clangast-raw-section.c (+6) - (modified) llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h (+8) - (modified) llvm/include/llvm/Target/TargetLoweringObjectFile.h (+7) - (modified) llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (+21) - (modified) llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp (+23) - (added) llvm/test/CodeGen/WebAssembly/raw-sections-wasm.ll (+7) - (added) llvm/test/CodeGen/X86/raw-sections-coff.ll (+12) - (added) llvm/test/CodeGen/X86/raw-sections-elf.ll (+7) - (added) llvm/test/CodeGen/X86/raw-sections-macho.ll (+9) ``````````diff diff --git a/clang/lib/CodeGen/ObjectFilePCHContainerWriter.cpp b/clang/lib/CodeGen/ObjectFilePCHContainerWriter.cpp index 074f2a520704d..3a507782bb66e 100644 --- a/clang/lib/CodeGen/ObjectFilePCHContainerWriter.cpp +++ b/clang/lib/CodeGen/ObjectFilePCHContainerWriter.cpp @@ -297,25 +297,27 @@ class PCHContainerGenerator : public ASTConsumer { auto *NameAndContent = llvm::MDTuple::get(*VMContext, Ops); MD->addOperand(NameAndContent); } else { - auto Int8Ty = llvm::Type::getInt8Ty(*VMContext); - auto *Ty = llvm::ArrayType::get(Int8Ty, Size); - auto *Data = llvm::ConstantDataArray::getString( - *VMContext, StringRef(SerializedAST.data(), Size), - /*AddNull=*/false); - auto *ASTSym = new llvm::GlobalVariable( - *M, Ty, /*constant*/ true, llvm::GlobalVariable::InternalLinkage, - Data, "__clang_ast"); - // The on-disk hashtable needs to be aligned. - ASTSym->setAlignment(llvm::Align(8)); - - // Mach-O also needs a segment name. + // Emit the serialized AST into a named section via llvm.raw.sections + // metadata, which the AsmPrinter emits directly at the MC layer. + // This avoids IR-level size constraints from the target's address space. + llvm::NamedMDNode *RawSections = + M->getOrInsertNamedMetadata("llvm.raw.sections"); + + StringRef SectionName; if (Triple.isOSBinFormatMachO()) - ASTSym->setSection("__CLANG,__clangast"); - // COFF has an eight character length limit. + SectionName = "__CLANG,__clangast"; else if (Triple.isOSBinFormatCOFF()) - ASTSym->setSection("clangast"); + SectionName = "clangast"; else - ASTSym->setSection("__clangast"); + SectionName = "__clangast"; + + llvm::Metadata *Ops[] = { + llvm::MDString::get(*VMContext, SectionName), + llvm::ConstantAsMetadata::get( + llvm::ConstantInt::get(llvm::Type::getInt32Ty(*VMContext), 8)), + llvm::MDString::get(*VMContext, + StringRef(SerializedAST.data(), Size))}; + RawSections->addOperand(llvm::MDTuple::get(*VMContext, Ops)); } LLVM_DEBUG({ diff --git a/clang/test/Modules/lsv-debuginfo.cpp b/clang/test/Modules/lsv-debuginfo.cpp index 40455727ecdda..61d2ff9514ed3 100644 --- a/clang/test/Modules/lsv-debuginfo.cpp +++ b/clang/test/Modules/lsv-debuginfo.cpp @@ -21,17 +21,20 @@ // RUN: cat %t-mod.ll | FileCheck %s // ADT -// CHECK: @__clang_ast = +// CHECK: !llvm.raw.sections = !{[[ADT_SEC:![0-9]+]]} +// CHECK: [[ADT_SEC]] = !{!"__clangast", // B -// CHECK: @__clang_ast = +// CHECK: !llvm.raw.sections = !{[[B_SEC:![0-9]+]]} +// CHECK: [[B_SEC]] = !{!"__clangast", // This type isn't anchored anywhere, expect a full definition. // CHECK: !DICompositeType({{.*}}, name: "AlignedCharArray<4U, 16U>", // CHECK-SAME: elements: // C -// CHECK: @__clang_ast = +// CHECK: !llvm.raw.sections = !{[[C_SEC:![0-9]+]]} +// CHECK: [[C_SEC]] = !{!"__clangast", // Here, too. // CHECK: !DICompositeType({{.*}}, name: "AlignedCharArray<4U, 16U>", diff --git a/clang/test/PCH/pch-clangast-raw-section.c b/clang/test/PCH/pch-clangast-raw-section.c new file mode 100644 index 0000000000000..2ef54cf640e1c --- /dev/null +++ b/clang/test/PCH/pch-clangast-raw-section.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-pch -fmodule-format=obj %S/pchpch1.h -o - | llvm-readelf --sections - | FileCheck %s + +// Ensure the serialized AST is emitted via llvm.raw.sections metadata into +// a __clangast section with 8-byte alignment. + +// CHECK: __clangast PROGBITS {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} 00 A 0 0 8 diff --git a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index 78954a8bb2121..a56e8ed6e0879 100644 --- a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -49,6 +49,8 @@ class LLVM_ABI TargetLoweringObjectFileELF : public TargetLoweringObjectFile { /// Emit Obj-C garbage collection and linker options. void emitModuleMetadata(MCStreamer &Streamer, Module &M) const override; + MCSection *getNamedReadOnlySection(StringRef Name) const override; + void emitPersonalityValue(MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym, const MachineModuleInfo *MMI) const override; @@ -144,6 +146,8 @@ class LLVM_ABI TargetLoweringObjectFileMachO : public TargetLoweringObjectFile { /// Emit the module flags that specify the garbage collection information. void emitModuleMetadata(MCStreamer &Streamer, Module &M) const override; + MCSection *getNamedReadOnlySection(StringRef Name) const override; + void emitLinkerDirectives(MCStreamer &Streamer, Module &M) const override; MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind, @@ -207,6 +211,8 @@ class LLVM_ABI TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile { /// Emit Obj-C garbage collection and linker options. void emitModuleMetadata(MCStreamer &Streamer, Module &M) const override; + MCSection *getNamedReadOnlySection(StringRef Name) const override; + void emitLinkerDirectives(MCStreamer &Streamer, Module &M) const override; MCSection *getStaticCtorSection(unsigned Priority, @@ -245,6 +251,8 @@ class LLVM_ABI TargetLoweringObjectFileWasm : public TargetLoweringObjectFile { bool shouldPutJumpTableInFunctionSection(bool UsesLabelDifference, const Function &F) const override; + MCSection *getNamedReadOnlySection(StringRef Name) const override; + void InitializeWasm(); MCSection *getStaticCtorSection(unsigned Priority, const MCSymbol *KeySym) const override; diff --git a/llvm/include/llvm/Target/TargetLoweringObjectFile.h b/llvm/include/llvm/Target/TargetLoweringObjectFile.h index 3cce5974e6705..df8dd3466451e 100644 --- a/llvm/include/llvm/Target/TargetLoweringObjectFile.h +++ b/llvm/include/llvm/Target/TargetLoweringObjectFile.h @@ -90,6 +90,13 @@ class LLVM_ABI TargetLoweringObjectFile : public MCObjectFileInfo { /// Emit the module-level metadata that the platform cares about. virtual void emitModuleMetadata(MCStreamer &Streamer, Module &M) const {} + /// Get a read-only data section with the given name, using format-appropriate + /// defaults. + /// Returns nullptr if not supported by this object file format. + virtual MCSection *getNamedReadOnlySection(StringRef Name) const { + return nullptr; + } + /// Emit Call Graph Profile metadata. void emitCGProfileMetadata(MCStreamer &Streamer, Module &M) const; diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 0580fc0f3a034..af48b444b7991 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -2980,6 +2980,27 @@ bool AsmPrinter::doFinalization(Module &M) { TLOF.emitModuleMetadata(*OutStreamer, M); + // Emit raw section data from llvm.raw.sections metadata. + if (const NamedMDNode *RawSections = + M.getNamedMetadata("llvm.raw.sections")) { + for (const MDNode *Op : RawSections->operands()) { + assert(Op->getNumOperands() == 3 && + "llvm.raw.sections metadata entry must have three operands"); + auto *SectionName = cast<MDString>(Op->getOperand(0)); + auto *AlignCI = mdconst::extract<ConstantInt>(Op->getOperand(1)); + auto *Data = cast<MDString>(Op->getOperand(2)); + + if (MCSection *Section = + TLOF.getNamedReadOnlySection(SectionName->getString())) { + OutStreamer->pushSection(); + OutStreamer->switchSection(Section); + OutStreamer->emitValueToAlignment(Align(AlignCI->getZExtValue())); + OutStreamer->emitBytes(Data->getString()); + OutStreamer->popSection(); + } + } + } + if (Target.isOSBinFormatELF()) { MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>(); diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 84b72321b1f55..bcdb2c3d63715 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -377,6 +377,11 @@ void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer, emitCGProfileMetadata(Streamer, M); } +MCSection * +TargetLoweringObjectFileELF::getNamedReadOnlySection(StringRef Name) const { + return getContext().getELFSection(Name, ELF::SHT_PROGBITS, ELF::SHF_ALLOC); +} + void TargetLoweringObjectFileELF::emitLinkerDirectives(MCStreamer &Streamer, Module &M) const { auto &C = getContext(); @@ -1350,6 +1355,13 @@ void TargetLoweringObjectFileMachO::emitModuleMetadata(MCStreamer &Streamer, Streamer.addBlankLine(); } +MCSection * +TargetLoweringObjectFileMachO::getNamedReadOnlySection(StringRef Name) const { + auto [Segment, SecName] = Name.split(','); + return getContext().getMachOSection(Segment, SecName, 0, + SectionKind::getReadOnly()); +} + void TargetLoweringObjectFileMachO::emitLinkerDirectives(MCStreamer &Streamer, Module &M) const { if (auto *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) { @@ -1944,6 +1956,12 @@ void TargetLoweringObjectFileCOFF::emitModuleMetadata(MCStreamer &Streamer, }); } +MCSection * +TargetLoweringObjectFileCOFF::getNamedReadOnlySection(StringRef Name) const { + return getContext().getCOFFSection( + Name, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ); +} + void TargetLoweringObjectFileCOFF::emitLinkerDirectives( MCStreamer &Streamer, Module &M) const { if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) { @@ -2258,6 +2276,11 @@ void TargetLoweringObjectFileWasm::getModuleMetadata(Module &M) { Used.insert(GO); } +MCSection * +TargetLoweringObjectFileWasm::getNamedReadOnlySection(StringRef Name) const { + return getContext().getWasmSection(Name, SectionKind::getReadOnly()); +} + MCSection *TargetLoweringObjectFileWasm::getExplicitSectionGlobal( const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { // We don't support explict section names for functions in the wasm object diff --git a/llvm/test/CodeGen/WebAssembly/raw-sections-wasm.ll b/llvm/test/CodeGen/WebAssembly/raw-sections-wasm.ll new file mode 100644 index 0000000000000..a326a5e912508 --- /dev/null +++ b/llvm/test/CodeGen/WebAssembly/raw-sections-wasm.ll @@ -0,0 +1,7 @@ +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown %s -o %t.o +; RUN: llvm-readobj --sections %t.o | FileCheck %s + +; CHECK: Name: __clangast + +!0 = !{!"__clangast", i32 8, !"\de\ad\be\ef"} +!llvm.raw.sections = !{!0} diff --git a/llvm/test/CodeGen/X86/raw-sections-coff.ll b/llvm/test/CodeGen/X86/raw-sections-coff.ll new file mode 100644 index 0000000000000..fc9d2e7515f94 --- /dev/null +++ b/llvm/test/CodeGen/X86/raw-sections-coff.ll @@ -0,0 +1,12 @@ +; RUN: llc -filetype=obj -mtriple=x86_64-windows-msvc %s -o %t.o +; RUN: llvm-readobj --sections %t.o | FileCheck %s + +; CHECK: Name: clangast +; CHECK: RawDataSize: +; CHECK: Characteristics [ +; CHECK-DAG: IMAGE_SCN_CNT_INITIALIZED_DATA +; CHECK-DAG: IMAGE_SCN_MEM_READ +; CHECK: ] + +!0 = !{!"clangast", i32 8, !"\de\ad\be\ef"} +!llvm.raw.sections = !{!0} diff --git a/llvm/test/CodeGen/X86/raw-sections-elf.ll b/llvm/test/CodeGen/X86/raw-sections-elf.ll new file mode 100644 index 0000000000000..c1afbb043066b --- /dev/null +++ b/llvm/test/CodeGen/X86/raw-sections-elf.ll @@ -0,0 +1,7 @@ +; RUN: llc -filetype=obj -mtriple=x86_64-linux-gnu %s -o %t.o +; RUN: llvm-readelf --sections %t.o | FileCheck %s + +; CHECK: __clangast PROGBITS {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} 00 A 0 0 8 + +!0 = !{!"__clangast", i32 8, !"\de\ad\be\ef"} +!llvm.raw.sections = !{!0} diff --git a/llvm/test/CodeGen/X86/raw-sections-macho.ll b/llvm/test/CodeGen/X86/raw-sections-macho.ll new file mode 100644 index 0000000000000..54d16b45529c4 --- /dev/null +++ b/llvm/test/CodeGen/X86/raw-sections-macho.ll @@ -0,0 +1,9 @@ +; RUN: llc -filetype=obj -mtriple=x86_64-apple-darwin %s -o %t.o +; RUN: llvm-readobj --sections %t.o | FileCheck %s + +; CHECK: Name: __clangast +; CHECK-NEXT: Segment: __CLANG +; CHECK: Size: + +!0 = !{!"__CLANG,__clangast", i32 8, !"\de\ad\be\ef"} +!llvm.raw.sections = !{!0} `````````` </details> https://github.com/llvm/llvm-project/pull/214135 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
