RFC: Exposing TargetTransformInfo factories from TargetMachine

Hi all,

I'd like to be able to use TargetTransformInfo to make architecture
specific code generation decisions from the XLA LLVM IR emitter[0].
However, we don't have a great way to do this today --
TargetTransformInfo is wrapped in a TargetIRAnalysis and getting the
TargetTransformInfo out of it requires something like:

  FunctionAnalysisManager DummyFAM;
  TTI = TIRA.run(F, DummyFAM);
  return *TTI;

which isn't ideal.

Given that all in-tree backends have a factory function to directly
construct a TargetTransformInfo implementation anyway, what do you
think about exposing said factory function from the TargetMachine
subclasses directly? Something conceptually like this
https://reviews.llvm.org/D41268 but for all backends and will less
std::function?

[0]: XLA is a machine learning focussed linear algebra compiler
XLA: Optimizing Compiler for Machine Learning  |  TensorFlow that uses LLVM for its CPU
and GPU backends.

-- Sanjoy

Hi all,

I'd like to be able to use TargetTransformInfo to make architecture
specific code generation decisions from the XLA LLVM IR emitter[0].
However, we don't have a great way to do this today --
TargetTransformInfo is wrapped in a TargetIRAnalysis and getting the
TargetTransformInfo out of it requires something like:

   FunctionAnalysisManager DummyFAM;
   TTI = TIRA.run(F, DummyFAM);
   return *TTI;

which isn't ideal.

Given that all in-tree backends have a factory function to directly
construct a TargetTransformInfo implementation anyway, what do you
think about exposing said factory function from the TargetMachine
subclasses directly? Something conceptually like this
https://reviews.llvm.org/D41268 but for all backends and will less
std::function?

Are there reasons why we might not want to do this? Other options we should consider?

  -Hal

Are there reasons why we might not want to do this? Other options we should
consider?

It does make the TargetMachine -> TargetIRAnalysis path less abstract,
but given that all targets have the same pattern of instantiating a
TargetIRAnalysis with a Function->TargetTransformInfo hook, the
abstraction does not seem particularly useful.

I might do even a simpler form of the patch though -- instead of
returning a function pointer from TargetMachine, just add a virtual
function to TargetMachine that creates the TargetTransformInfo
directly from a Function.

-- Sanjoy

Are there reasons why we might not want to do this? Other options we should
consider?

It does make the TargetMachine -> TargetIRAnalysis path less abstract,
but given that all targets have the same pattern of instantiating a
TargetIRAnalysis with a Function->TargetTransformInfo hook, the
abstraction does not seem particularly useful.

I agree.

I might do even a simpler form of the patch though -- instead of
returning a function pointer from TargetMachine, just add a virtual
function to TargetMachine that creates the TargetTransformInfo
directly from a Function.

Okay.

  -Hal

Instead, is there any reason why TTI for a given Subtarget shouldn’t live on the Subtarget? Just construct it the same way we do TargetLowering, etc?

-eric

I think that would make a lot of sense and avoid a lot of the complicated code. Though I think I’d rather see a function in TargetMachine taking a const Function argument, rather than a SubtargetInfo function[1] (you can still implement the TargetMachine function via a sub target function behind the scenes of course).

  • Matthias

[1] At least seeing that the SubtargetInfo has a number of lib/CodeGen specific interfaces in it so it had to be moved to include/llvm/CodeGen I’d rather not see it is used in code outside lib/CodeGen or lib/Target.

Instead, is there any reason why TTI for a given Subtarget shouldn't live on
the Subtarget? Just construct it the same way we do TargetLowering, etc?

Then stuff that depends on Analysis today will have to depend on
CodeGen, which is probably not ideal.

I think I'll go with Matthias' idea -- remove the function pointer
indirection altogether, and instead just have a virtual
getTargetTransformInfo(Function&) in TargetMachine.

I was also wondering if it makes sense to make the llvm::Function
argument optional -- that'll help make XLA's use case slightly cleaner
since we don't (yet) have per-function target attributes.

-- Sanjoy

SGTM. :slight_smile:

Also, you should have per function target attributes from the start.

-eric