Getting target machine specific information at run-time

Hi,

I'm playing with some experimental register allocators for LLVM. One of them needs to build a so-called register
class tree for representing the aliasing information among register classes.
This tree is not function or module specific. It is actually target specific, because it depends only
on the register classes defined for a machine that is used as a target of the current compilation.

I'd like to be able to compute this information only once during the run-time, e.g. when target machine information is being created.
But I couldn't find out how it can be done. Then I thought that it should be possible to do it in the doInitialization() function of my MachineFunctionPass.
Then it would be done once per LLVM module, which is still acceptable. I almost implemented this solution, but I have problems accessing
the architecture dependent bits of the Module, i.e. TargetMachine objects specific for the current architecture, as selected by the --march option of the compiler.
I tried using the getClosestTargetForJIT and getClosestStaticTargetForModule functions of the TargetMachineRegistry class.
But all that was without success. I always get back only X86-based targets (which is the target architecture of my development machine)
even though I explicitly select another target for cross-compilation by doing --march=sparc or --march=alpha.

Could someone explain, what is a correct way to:
1) obtain a TargetMachine object related to the target selected using --march option?
2) compute some target specific data once per compilation/per module and use it in the machine pass(es)?
    Is putting this computation into the doInitialization() function a proper approach?

Thanks,
  Roman

Hi,

I'm playing with some experimental register allocators for LLVM. One of
them needs to build a so-called register class tree for representing the
aliasing information among register classes. This tree is not function or

Hmm, it seems I've been here before... :slight_smile:

I'd like to be able to compute this information only once during the
run-time, e.g. when target machine information is being created. But I
couldn't find out how it can be done. Then I thought that it should be
possible to do it in the doInitialization() function of my
MachineFunctionPass. Then it would be done once per LLVM module, which is
still acceptable. I almost implemented this solution, but I have problems
accessing the architecture dependent bits of the Module, i.e. TargetMachine
objects specific for the current architecture, as selected by the --march
option of the compiler. I tried using the getClosestTargetForJIT and
getClosestStaticTargetForModule functions of the TargetMachineRegistry
class. But all that was without success. I always get back only X86-based
targets (which is the target architecture of my development machine) even
though I explicitly select another target for cross-compilation by doing
--march=sparc or --march=alpha.

I did the once-per-module solution to this exact problem. Here's what it
looks like:

class RA {
    const TargetMachine* tm_;
    const TargetRegisterInfo* tri_;
    const TargetInstrInfo * tii_;
[...]
bool RA::runOnMachineFunction(MachineFunction &fn) {
  mf_ = &fn;
  tm_ = &fn.getTarget();
  tri_ = tm_->getRegisterInfo();
  tii_ = tm_->getInstrInfo();

  if (!initialized) {
    build_class_tree();
    initialized = true;

The "initialized" flag is there to make sure it only happens once per module.
You need a MachineFunction to get at the target info so I don't think it can
be done in doInitialization.

                                           -Dave

Hi,

I'm playing with some experimental register allocators for LLVM. One of them needs to build a so-called register
class tree for representing the aliasing information among register classes.
This tree is not function or module specific. It is actually target specific, because it depends only
on the register classes defined for a machine that is used as a target of the current compilation.

I'd like to be able to compute this information only once during the run-time, e.g. when target machine information is being created.
But I couldn't find out how it can be done. Then I thought that it should be possible to do it in the doInitialization() function of my MachineFunctionPass.
Then it would be done once per LLVM module, which is still acceptable. I almost implemented this solution, but I have problems accessing
the architecture dependent bits of the Module, i.e. TargetMachine objects specific for the current architecture, as selected by the --march option of the compiler.
I tried using the getClosestTargetForJIT and getClosestStaticTargetForModule functions of the TargetMachineRegistry class.
But all that was without success. I always get back only X86-based targets (which is the target architecture of my development machine)
even though I explicitly select another target for cross-compilation by doing --march=sparc or --march=alpha.

Could someone explain, what is a correct way to:
1) obtain a TargetMachine object related to the target selected using --march option?

llc tool does this.

2) compute some target specific data once per compilation/per module and use it in the machine pass(es)?

Write an immutable pass, TargetData is one example.

   Is putting this computation into the doInitialization() function a proper approach?

It is not a good idea to put this in doInitialization().