weliveindetail wrote: @aengelke Thanks for taking the initiative! I got derailed from my backend swapping research after I settled with [this downstream patch](https://github.com/weliveindetail/llvm-project/commit/custom-backend-shlib-dev) "for the moment". It was surprisingly small and effective, but no solid upstreamable implementation.
> @weliveindetail was hoping for something that works cross-frontend Yes, that's right. Adding a frontend-specific mechanism doesn't seem like the best approach to me. Populating and running the codegen pipeline is an inherent responsibility of LLVM. If we provided a generic way to make it configurable without breaking the interface, then all frontends would profit. So what options do we have? Looking at different frontends, we see that all of them invoke `TargetMachine::addPassesToEmitFile()`: * Rust does it in [LLVMRustWriteOutputFile()](https://github.com/rust-lang/rust/blob/12167d7064597993355e41d3a8c20654bccaf0be/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp#L599) * Swift does it in [swift::compileAndWriteLLVM()](https://github.com/swiftlang/swift/blob/f8577a2731be84f11b651232d808b69aa35fa8ad/lib/IRGen/IRGen.cpp#L780) * Clang does it in [EmitAssemblyHelper::AddEmitPasses()](https://github.com/llvm/llvm-project/blob/8c8f2df23239914f3276aef02eb89a78373fcaa3/clang/lib/CodeGen/BackendUtil.cpp#L643) This seems to be a good place to add a hook and it's just two hops away from the entry-point proposed in this patch: ``` llvm::CodeGenTargetMachineImpl::addPassesToEmitFile(...) EmitAssemblyHelper::AddEmitPasses(...) -> EmitAssemblyHelper::RunCodegenPipeline(...) EmitAssemblyHelper::emitAssembly(...) clang::emitBackendOutput(...) ``` The notable difference is, that we *only populate* the codegen pipeline here and execute it later via `PassManager::run()`. This won't implicitly accommodate the hidden **fallback mechanism** in this patch. Let's look at the code: I like the approach with the `Registry` class in this patch. It's simple, it's prepared for the shared library split and it's used in clang as well as LLVM's garbage collectors. And conceptually, it's a good fit at second glace: 1. Alternative backends don't necessarily *add* functionality, they rather *substitute* it. LLVM's builtin backend is the default implementation and it might be overridden. That's not the nature of the `Registry` class, which is adding not overriding. 2. But alternative code generators may also fail. This is the case for TPDE in particular, since it supports only a subset of LLVM. If it reaches an unsupported feature, it bails out gracefully and falls back to LLVM. This makes the `Registry` approach interesting again. I think it's worth investigating, if we can keep the proposed approach, move the hook into `CodeGenTargetMachineImpl` and manage to accommodate the fallback case without breaking the interface. I will take some time to look into it and see where I get. What do you think? On the side, we should note the second entry-point `TargetMachine::addPassesToEmitMC()` here, which is used by ORC and MCJIT. @lhames This code has a long legacy right? Is it time to revisit this distinction? > Independently, have you considered uploading the tpde-llvm to the llvm > project itself? > > Yes, and we concluded that we'd rather not pursue it at this point. I agree and there are more people who want to load alternative backends and/or configure the codegen pipeline @ashermancinelli @jwillbold @vadorovsky Let's see if we can improve the plugin story instead! đ https://github.com/llvm/llvm-project/pull/165257 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
