From ed091a5775eed52f972e17a2a6938bf8a7381ec5 Mon Sep 17 00:00:00 2001 From: Derek Gerstmann Date: Thu, 24 Aug 2023 11:37:19 -0700 Subject: [PATCH 1/4] Enable PIC code generation for WebAssembly for LLVM >18. Enable +mutable-globals to support dynamic linking --- src/CodeGen_WebAssembly.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/CodeGen_WebAssembly.cpp b/src/CodeGen_WebAssembly.cpp index 3f82f66bc2a2..9dd55abd220b 100644 --- a/src/CodeGen_WebAssembly.cpp +++ b/src/CodeGen_WebAssembly.cpp @@ -344,6 +344,14 @@ string CodeGen_WebAssembly::mattrs() const { sep = ","; } + // PIC implies +mutable-globals because the PIC ABI used by the linker + // depends on importing and exporting mutable globals. Also -pthread implies + // mutable-globals too, so quitely enable it if either of these are specified. + if(use_pic() || target.has_feature(Target::WasmThreads)) { + s << sep << "+mutable-globals"; + sep = ","; + } + // Recent Emscripten builds assume that specifying `-pthread` implies bulk-memory too, // so quietly enable it if either of these are specified. if (target.has_feature(Target::WasmBulkMemory) || target.has_feature(Target::WasmThreads)) { @@ -362,7 +370,18 @@ bool CodeGen_WebAssembly::use_soft_float_abi() const { } bool CodeGen_WebAssembly::use_pic() const { +#if LLVM_VERSION >= 180 + // Issues with WASM PIC and dynamic linking only got fixed in LLVM v18.x (June 26th 2023) + // See https://reviews.llvm.org/D153293 + + // Always emitting PIC "does add a little bloat to the object files, due to the extra + // indirection, but when linked into a static binary 100% of this can be removed by + // wasm-opt in release builds." + // See https://github.com/halide/Halide/issues/7796 + return true; +#else return false; +#endif } int CodeGen_WebAssembly::native_vector_bits() const { From 42bd039795c3c02ab8f7fbf49067393a45f68062 Mon Sep 17 00:00:00 2001 From: Derek Gerstmann Date: Thu, 24 Aug 2023 11:39:26 -0700 Subject: [PATCH 2/4] Fix LLVM v18 interface changes for writeArchive() Add RelLookupTableConverterPass for PIC (in LLVM v18) --- src/CodeGen_LLVM.cpp | 11 +++++++++++ src/LLVM_Headers.h | 3 +++ src/LLVM_Output.cpp | 8 ++++++++ 3 files changed, 22 insertions(+) diff --git a/src/CodeGen_LLVM.cpp b/src/CodeGen_LLVM.cpp index b3fc5f176495..02f835481626 100644 --- a/src/CodeGen_LLVM.cpp +++ b/src/CodeGen_LLVM.cpp @@ -1151,6 +1151,17 @@ void CodeGen_LLVM::optimize_module() { using OptimizationLevel = llvm::OptimizationLevel; OptimizationLevel level = OptimizationLevel::O3; +#if LLVM_VERSION >= 180 + if(tm->isPositionIndependent()) { + // Add a pass that converts lookup tables to relative lookup tables to make them PIC-friendly. + // See https://bugs.llvm.org/show_bug.cgi?id=45244 + pb.registerOptimizerLastEPCallback( + [&](ModulePassManager &mpm, OptimizationLevel level) { + mpm.addPass(RelLookupTableConverterPass()); + }); + } +#endif + if (get_target().has_feature(Target::SanitizerCoverage)) { pb.registerOptimizerLastEPCallback( [&](ModulePassManager &mpm, OptimizationLevel level) { diff --git a/src/LLVM_Headers.h b/src/LLVM_Headers.h index 6018c4fedff9..ad3f25365577 100644 --- a/src/LLVM_Headers.h +++ b/src/LLVM_Headers.h @@ -102,6 +102,9 @@ #include #include #include +#if LLVM_VERSION >= 180 +#include +#endif // IWYU pragma: end_exports diff --git a/src/LLVM_Output.cpp b/src/LLVM_Output.cpp index 3106fec840a8..48d1f6f15058 100644 --- a/src/LLVM_Output.cpp +++ b/src/LLVM_Output.cpp @@ -397,6 +397,10 @@ void emit_file(const llvm::Module &module_in, Internal::LLVMOStream &out, pass_manager.add(llvm::createRewriteSymbolsPass()); #endif + if(target_machine->isPositionIndependent()) { + Internal::debug(1) << "Target machine is Position Independent!\n"; + } + // Override default to generate verbose assembly. target_machine->Options.MCOptions.AsmVerbose = true; @@ -593,7 +597,11 @@ void create_static_library(const std::vector &src_files_in, const T return; } +#if LLVM_VERSION < 180 const bool write_symtab = true; +#else + llvm::SymtabWritingMode write_symtab = llvm::SymtabWritingMode::NormalSymtab; +#endif const auto kind = Internal::get_triple_for_target(target).isOSDarwin() ? llvm::object::Archive::K_BSD : llvm::object::Archive::K_GNU; const bool thin = false; auto result = llvm::writeArchive(dst_file, new_members, From e129aa6ffd72836e24693aca1a64db6f4fcf63e2 Mon Sep 17 00:00:00 2001 From: Derek Gerstmann Date: Thu, 24 Aug 2023 11:43:59 -0700 Subject: [PATCH 3/4] Resolve conflict for writeArchive interface changes. --- src/LLVM_Output.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/LLVM_Output.cpp b/src/LLVM_Output.cpp index 48d1f6f15058..ab3f14466c03 100644 --- a/src/LLVM_Output.cpp +++ b/src/LLVM_Output.cpp @@ -597,10 +597,11 @@ void create_static_library(const std::vector &src_files_in, const T return; } -#if LLVM_VERSION < 180 + +#if LLVM_VERSION >= 180 + const llvm::SymtabWritingMode write_symtab = llvm::SymtabWritingMode::NormalSymtab; +#else const bool write_symtab = true; -#else - llvm::SymtabWritingMode write_symtab = llvm::SymtabWritingMode::NormalSymtab; #endif const auto kind = Internal::get_triple_for_target(target).isOSDarwin() ? llvm::object::Archive::K_BSD : llvm::object::Archive::K_GNU; const bool thin = false; From a66c44be314dab7f4019fbe6657cd7cfd64d3f21 Mon Sep 17 00:00:00 2001 From: Derek Gerstmann Date: Thu, 24 Aug 2023 11:55:32 -0700 Subject: [PATCH 4/4] Clang format pass --- src/CodeGen_LLVM.cpp | 4 ++-- src/CodeGen_WebAssembly.cpp | 8 ++++---- src/LLVM_Output.cpp | 5 ++--- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/CodeGen_LLVM.cpp b/src/CodeGen_LLVM.cpp index 02f835481626..b4fd79d88a15 100644 --- a/src/CodeGen_LLVM.cpp +++ b/src/CodeGen_LLVM.cpp @@ -1152,12 +1152,12 @@ void CodeGen_LLVM::optimize_module() { OptimizationLevel level = OptimizationLevel::O3; #if LLVM_VERSION >= 180 - if(tm->isPositionIndependent()) { + if (tm->isPositionIndependent()) { // Add a pass that converts lookup tables to relative lookup tables to make them PIC-friendly. // See https://bugs.llvm.org/show_bug.cgi?id=45244 pb.registerOptimizerLastEPCallback( [&](ModulePassManager &mpm, OptimizationLevel level) { - mpm.addPass(RelLookupTableConverterPass()); + mpm.addPass(RelLookupTableConverterPass()); }); } #endif diff --git a/src/CodeGen_WebAssembly.cpp b/src/CodeGen_WebAssembly.cpp index 9dd55abd220b..69d696ce9f8a 100644 --- a/src/CodeGen_WebAssembly.cpp +++ b/src/CodeGen_WebAssembly.cpp @@ -347,7 +347,7 @@ string CodeGen_WebAssembly::mattrs() const { // PIC implies +mutable-globals because the PIC ABI used by the linker // depends on importing and exporting mutable globals. Also -pthread implies // mutable-globals too, so quitely enable it if either of these are specified. - if(use_pic() || target.has_feature(Target::WasmThreads)) { + if (use_pic() || target.has_feature(Target::WasmThreads)) { s << sep << "+mutable-globals"; sep = ","; } @@ -374,10 +374,10 @@ bool CodeGen_WebAssembly::use_pic() const { // Issues with WASM PIC and dynamic linking only got fixed in LLVM v18.x (June 26th 2023) // See https://reviews.llvm.org/D153293 - // Always emitting PIC "does add a little bloat to the object files, due to the extra - // indirection, but when linked into a static binary 100% of this can be removed by + // Always emitting PIC "does add a little bloat to the object files, due to the extra + // indirection, but when linked into a static binary 100% of this can be removed by // wasm-opt in release builds." - // See https://github.com/halide/Halide/issues/7796 + // See https://github.com/halide/Halide/issues/7796 return true; #else return false; diff --git a/src/LLVM_Output.cpp b/src/LLVM_Output.cpp index ab3f14466c03..04af5aff3609 100644 --- a/src/LLVM_Output.cpp +++ b/src/LLVM_Output.cpp @@ -397,10 +397,10 @@ void emit_file(const llvm::Module &module_in, Internal::LLVMOStream &out, pass_manager.add(llvm::createRewriteSymbolsPass()); #endif - if(target_machine->isPositionIndependent()) { + if (target_machine->isPositionIndependent()) { Internal::debug(1) << "Target machine is Position Independent!\n"; } - + // Override default to generate verbose assembly. target_machine->Options.MCOptions.AsmVerbose = true; @@ -597,7 +597,6 @@ void create_static_library(const std::vector &src_files_in, const T return; } - #if LLVM_VERSION >= 180 const llvm::SymtabWritingMode write_symtab = llvm::SymtabWritingMode::NormalSymtab; #else