67 static struct LLVMInitializer {
69 llvm::InitializeNativeTarget();
70 llvm::InitializeNativeTargetAsmPrinter();
71 llvm::InitializeNativeTargetAsmParser();
73 LLVMInitializer(
const LLVMInitializer&) =
delete;
74 LLVMInitializer& operator=(
const LLVMInitializer&) =
delete;
75 LLVMInitializer(LLVMInitializer&&) =
delete;
76 LLVMInitializer& operator=(LLVMInitializer&&) =
delete;
77 ~LLVMInitializer() =
default;
81 llvm::cantFail(llvm::orc::JITTargetMachineBuilder::detectHost());
82 jtmb.setCodeGenOptLevel(llvm::CodeGenOptLevel::Aggressive);
84 llvm::StringMap<bool> host_features = llvm::sys::getHostCPUFeatures();
85 if (host_features.size() > 0) {
86 std::vector<std::string> features;
87 for (
auto& f : host_features) {
89 features.push_back(
"+" + f.getKey().str());
92 jtmb.addFeatures(features);
95 llvm::TargetOptions opts;
96 opts.AllowFPOpFusion = llvm::FPOpFusion::Fast;
97#if LLVM_VERSION_MAJOR < 22
98 opts.UnsafeFPMath =
true;
100 opts.NoInfsFPMath =
true;
101 opts.NoNaNsFPMath = no_nans_fp_math;
102 jtmb.setOptions(opts);
104 auto jit_builder = llvm::orc::LLJITBuilder();
105 jit_builder.setJITTargetMachineBuilder(std::move(jtmb));
106 auto temp_jit = jit_builder.create();
108 llvm::errs() <<
"Failed to create LLJIT instance: "
109 << llvm::toString(temp_jit.takeError()) <<
"\n";
110 throw std::runtime_error(
"LLJIT creation failed");
112 lljit = std::move(*temp_jit);
115 auto& main_jd = lljit->getMainJITDylib();
116 llvm::orc::SymbolMap symbols;
118 symbols[lljit->mangleAndIntern(
"llvmexpr_ensure_buffer")] =
119 llvm::orc::ExecutorSymbolDef(
120 llvm::orc::ExecutorAddr(
122 llvm::JITSymbolFlags::Callable | llvm::JITSymbolFlags::Exported);
124 symbols[lljit->mangleAndIntern(
"llvmexpr_get_buffer_size")] =
125 llvm::orc::ExecutorSymbolDef(
126 llvm::orc::ExecutorAddr(
128 llvm::JITSymbolFlags::Callable | llvm::JITSymbolFlags::Exported);
131 symbols[lljit->mangleAndIntern(
"sincosf")] = llvm::orc::ExecutorSymbolDef(
132 llvm::orc::ExecutorAddr(
133 llvm::pointerToJITTargetAddress(&llvmexpr_sincosf)),
134 llvm::JITSymbolFlags::Callable | llvm::JITSymbolFlags::Exported);
136 symbols[lljit->mangleAndIntern(
"sincos")] = llvm::orc::ExecutorSymbolDef(
137 llvm::orc::ExecutorAddr(
138 llvm::pointerToJITTargetAddress(&llvmexpr_sincos)),
139 llvm::JITSymbolFlags::Callable | llvm::JITSymbolFlags::Exported);
142 if (
auto err = main_jd.define(llvm::orc::absoluteSymbols(symbols))) {
143 llvm::errs() <<
"Failed to define host call symbols: "
144 << llvm::toString(std::move(err)) <<
"\n";
145 throw std::runtime_error(
"Failed to define host call symbols in JIT");
158 std::unique_ptr<llvm::LLVMContext> ctx) {
159 std::vector<llvm::Function*> functions_to_remove;
161 if (!f.isDeclaration()) {
162 std::string func_name = f.getName().str();
164 if (!func_name.starts_with(
"process_plane_")) {
165 if (func_name.starts_with(
"fast_") ||
166 func_name.find(
"_v4") != std::string::npos ||
167 func_name.find(
"_v8") != std::string::npos ||
168 func_name.find(
"_v16") != std::string::npos) {
171 auto test_sym = lljit->lookup(func_name);
174 functions_to_remove.push_back(&f);
178 llvm::consumeError(test_sym.takeError());
185 for (
auto* f : functions_to_remove) {
186 f->eraseFromParent();
189 auto tsm = llvm::orc::ThreadSafeModule(std::move(m), std::move(ctx));
190 auto err = lljit->addIRModule(std::move(tsm));
192 llvm::errs() <<
"Failed to add IR module: "
193 << llvm::toString(std::move(err)) <<
"\n";
194 throw std::runtime_error(
"Failed to add IR module to JIT");