Auto merge of #52506 - alexcrichton:dont-duplicate-wasm-sections, r=michaelwoerister
rustc: Work around an upstream wasm ThinLTO bug This commit implements a workaround for an [upstream LLVM bug][1] where custom sections were accidentally duplicated amongst codegen units when ThinLTO passes were performed. This is due to the fact that custom sections for wasm are stored as metadata nodes which are automatically imported into modules when ThinLTO happens. The fix here is to forcibly delete the metadata node from imported modules before LLVM has a chance to try to copy it over. [1]: https://bugs.llvm.org/show_bug.cgi?id=38184
This commit is contained in:
commit
5665a2d367
4 changed files with 95 additions and 1 deletions
|
@ -1084,11 +1084,40 @@ LLVMRustPrepareThinLTOInternalize(const LLVMRustThinLTOData *Data, LLVMModuleRef
|
|||
extern "C" bool
|
||||
LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
|
||||
Module &Mod = *unwrap(M);
|
||||
|
||||
const auto &ImportList = Data->ImportLists.lookup(Mod.getModuleIdentifier());
|
||||
auto Loader = [&](StringRef Identifier) {
|
||||
const auto &Memory = Data->ModuleMap.lookup(Identifier);
|
||||
auto &Context = Mod.getContext();
|
||||
return getLazyBitcodeModule(Memory, Context, true, true);
|
||||
auto MOrErr = getLazyBitcodeModule(Memory, Context, true, true);
|
||||
|
||||
if (!MOrErr)
|
||||
return std::move(MOrErr);
|
||||
|
||||
// The rest of this closure is a workaround for
|
||||
// https://bugs.llvm.org/show_bug.cgi?id=38184 where during ThinLTO imports
|
||||
// we accidentally import wasm custom sections into different modules,
|
||||
// duplicating them by in the final output artifact.
|
||||
//
|
||||
// The issue is worked around here by manually removing the
|
||||
// `wasm.custom_sections` named metadata node from any imported module. This
|
||||
// we know isn't used by any optimization pass so there's no need for it to
|
||||
// be imported.
|
||||
//
|
||||
// Note that the metadata is currently lazily loaded, so we materialize it
|
||||
// here before looking up if there's metadata inside. The `FunctionImporter`
|
||||
// will immediately materialize metadata anyway after an import, so this
|
||||
// shouldn't be a perf hit.
|
||||
if (Error Err = (*MOrErr)->materializeMetadata()) {
|
||||
Expected<std::unique_ptr<Module>> Ret(std::move(Err));
|
||||
return std::move(Ret);
|
||||
}
|
||||
|
||||
auto *WasmCustomSections = (*MOrErr)->getNamedMetadata("wasm.custom_sections");
|
||||
if (WasmCustomSections)
|
||||
WasmCustomSections->eraseFromParent();
|
||||
|
||||
return std::move(MOrErr);
|
||||
};
|
||||
FunctionImporter Importer(Data->Index, Loader);
|
||||
Expected<bool> Result = Importer.importFunctions(Mod, ImportList);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue