This extracts the implementation of getType, setType, and getBody from
FunctionSupport.h into the mlir::impl namespace and defines them
generically in FunctionSupport.cpp. This allows them to be used
elsewhere for any FunctionLike ops that use FunctionType for their
type signature.
Using the new helpers, FuncOpSignatureConversion is generalized to
work with all such FunctionLike ops. Convenience helpers are added to
configure the pattern for a given concrete FunctionLike op type.
This doesn't generalize to all FunctionLike operations though, just the ones that are similar to FuncOp (e.g. this would crash LLVMFuncOp). I'm +1 on having a simple default implementation that other FunctionLike operations can hook into, but I don't think it needs to match all of them. Could we instead just make it as simple as having the user provide the op name of the function like operation they want to use here?