This allows the TTI to specify an alias analysis specifically for its
target.
Example usage (in MyTargetTTI.cpp):
class MyTargetAAresult : public AAResultBase<MyTargetAAResult> { ... }; class MyTargetAAResultProvider : public AAResultProvider { MyTargetAAResult Result; public: void addAAResult(AAResults &AAR) override { // AAR only keeps a reference to Result; we have to keep it alive. AAR.addResult(Result); } }; std::unique_ptr<AAResultProvider> MyTargetTTI::getAAResultProvider(const Function *) { return make_unique<MyTargetAAResultProvider>(); }
A simpler API (that doesn't end up working) would be to have a different
function on TTI:
TargetTransformInfo::addAAResult(const Function *, AAResults &)
This would also more closely mirror how external AAs work.
The problem with this is that AAResults::addAAResult takes a reference
to the result it's given, so that object must be stored somewhere. With
the external AA framework, the external target is expected to register a
pass and store its AAResult in that pass. But that doesn't work for our
purposes; we have no way to get the TTI to register a pass (nor do I
think that's desirable).
So instead, we essentially have the TTI return a closure which stores
the AAResult and provides access to it via
AAResultProvider::addAAResult. We use a custom class rather than
std::function for this closure because std::functions must be copyable,
but it's natural for this closure to capture non-copyable objects.