From ba3c1f9ce30cf4f8aee5f1961df74d65e11d53bc Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Wed, 21 Feb 2024 03:35:36 +0900 Subject: [WebAssembly] Add segment RETAIN flag to support private retained data (#81539) In WebAssembly, we have `WASM_SYMBOL_NO_STRIP` symbol flag to mark the referenced content as retained. However, the flag is not enough to express retained data that is not referenced by any symbol. This patch adds a new segment flag`WASM_SEG_FLAG_RETAIN` to support "private" linkage data that is retained by llvm.used. This kind of data that is not referenced but must be retained is usually used with encapsulation symbols (__start/__stop). Swift runtime uses this technique and depends on the fact "all metadata sections in live objects are retained", which was not guaranteed with `--gc-sections` before this patch. This is a revised version of https://reviews.llvm.org/D126950 (has been reverted) based on @MaskRay's comments --- llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 29 +++++++++++++++++------ 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp') diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 3cf59bc..654a615 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -2142,7 +2142,7 @@ static const Comdat *getWasmComdat(const GlobalValue *GV) { return C; } -static unsigned getWasmSectionFlags(SectionKind K) { +static unsigned getWasmSectionFlags(SectionKind K, bool Retain) { unsigned Flags = 0; if (K.isThreadLocal()) @@ -2151,11 +2151,22 @@ static unsigned getWasmSectionFlags(SectionKind K) { if (K.isMergeableCString()) Flags |= wasm::WASM_SEG_FLAG_STRINGS; + if (Retain) + Flags |= wasm::WASM_SEG_FLAG_RETAIN; + // TODO(sbc): Add suport for K.isMergeableConst() return Flags; } +void TargetLoweringObjectFileWasm::getModuleMetadata(Module &M) { + SmallVector Vec; + collectUsedGlobalVariables(M, Vec, false); + for (GlobalValue *GV : Vec) + if (auto *GO = dyn_cast(GV)) + Used.insert(GO); +} + 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 @@ -2179,16 +2190,18 @@ MCSection *TargetLoweringObjectFileWasm::getExplicitSectionGlobal( Group = C->getName(); } - unsigned Flags = getWasmSectionFlags(Kind); + unsigned Flags = getWasmSectionFlags(Kind, Used.count(GO)); MCSectionWasm *Section = getContext().getWasmSection( Name, Kind, Flags, Group, MCContext::GenericSectionID); return Section; } -static MCSectionWasm *selectWasmSectionForGlobal( - MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang, - const TargetMachine &TM, bool EmitUniqueSection, unsigned *NextUniqueID) { +static MCSectionWasm * +selectWasmSectionForGlobal(MCContext &Ctx, const GlobalObject *GO, + SectionKind Kind, Mangler &Mang, + const TargetMachine &TM, bool EmitUniqueSection, + unsigned *NextUniqueID, bool Retain) { StringRef Group = ""; if (const Comdat *C = getWasmComdat(GO)) { Group = C->getName(); @@ -2213,7 +2226,7 @@ static MCSectionWasm *selectWasmSectionForGlobal( (*NextUniqueID)++; } - unsigned Flags = getWasmSectionFlags(Kind); + unsigned Flags = getWasmSectionFlags(Kind, Retain); return Ctx.getWasmSection(Name, Kind, Flags, Group, UniqueID); } @@ -2231,9 +2244,11 @@ MCSection *TargetLoweringObjectFileWasm::SelectSectionForGlobal( else EmitUniqueSection = TM.getDataSections(); EmitUniqueSection |= GO->hasComdat(); + bool Retain = Used.count(GO); + EmitUniqueSection |= Retain; return selectWasmSectionForGlobal(getContext(), GO, Kind, getMangler(), TM, - EmitUniqueSection, &NextUniqueID); + EmitUniqueSection, &NextUniqueID, Retain); } bool TargetLoweringObjectFileWasm::shouldPutJumpTableInFunctionSection( -- cgit v1.1