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

Reply via email to