There are three hooks that have a different, more complicated API than
the other ones: allocationFn, memCpyFn, castFn. All three are called via
"helper" functions that check whether the hooks are set to call them and
fall back to default implementations otherwise.
Other hooks (e.g. unknownTypeConverterFn) in the bufferization options
have a different "API": they are always set to some default
implementation and can be overwritten by the user. This is a simpler API
overall and seems it can be universal.
Note for LLVM integration: BufferizationOptions::{createAlloc,
createMemCpy, createCast} functions are "replaced" with direct calls to
the underlying std::function objects. At any call-site that relied on
any of the removed APIs, a call to the respective hook should now be
used instead. The exception is the `allocationFn` hook which needs an
explicit "bufferAlignment" parameter. Beforehand, it was implicitly
taken from BufferizationOptions::bufferAlignment field, so a
non-functional migration path is to go from
`options.createAlloc(builder, loc, destType, value)` to
`options.allocationFn(builder, loc, destType, value,
options.bufferAlignment)`.