[Question] How do I get the number of machine registers.

How do I get the total number of machine registers? I have currently a MachineFunction and some derivatives.

How are the machine registers ordered internally? Can I index them off of a zero based array or do I have to create a map to have them be zero based?

Thanks,
Jeff Kunkel

TargetRegisterInfo::getNumRegs().

Generally, it's best not to make any assumptions about the internal ordering or numbering if you can avoid it. What are you looking to do?

-Jim

It’s not too much of a problem then. I can make a DenseMap between the registers and my registers. It’s just one more intermediate step for a lookup.

I wish to mimic all the of the registers on the machine with my std::vector RegisterIndexes; vector. Then when a register is used I can assign it easily. I know about alias register and those are taken care of ever so cleverly.

If this can be done without an extra lookup, it would improve performance. I have one too many as is in some parts.

Thanks,
Jeff Kunkel

It's not too much of a problem then. I can make a DenseMap between the registers and my registers. It's just one more intermediate step for a lookup.

I wish to mimic all the of the registers on the machine with my std::vector<RegisterInfo> RegisterIndexes; vector. Then when a register is used I can assign it easily. I know about alias register and those are taken care of ever so cleverly.

Is this because you want to control the order in which the physical registers are allocated? If so, it'll normally be better to use the TargetRegisterClass::allocation_order_begin() and allocation_order_end() functions to control that. These can be overridden directly in the .td file (see the ARMRegisterInfo.td file for examples) if you want. Other pieces of the compiler also use those iterators to walk the available registers in a register class for local allocation needs, so it's best to keep that logic together (the register scavenger and the anti-dependency breaker, in particular, use them).

Within a register class, the registers will be sorted by name, so if they're named generically ("R0, R1, R2..."), they'll be ordered as you'd expect (including knowing that R10 > R1, I believe). The default allocation order just has begin() be the first register of the class and end() be one past the last register in the class (i.e., it's all the registers in the register class, in order).

One thing to keep in mind is that the an allocator should explicitly check for reserved registers and avoid allocating them. Allocation orders are not required to omit reserved registers (although some do). See the recent series of patches the RegAlloc*.cpp for reference.

Regards,
  Jim

I am using allocation_order_begin() and allocation_order_end(). Thank you about the caveat about reserved registers.

Registers are numbered from 1 to TRI::getNumRegs()-1. Reg 0 is not a register, but it is counted by getNumRegs.

They are currently sorted by name by StringRef::compare_numeric(), but try to avoid depending on that. It could easily change, I have been experimenting with the performance impact of a topological order.

/jakob

Jacob, have you completed the topological sorting or the registers? It
seems I iterate through sub/alias-registers quite often, and I think a
performance gain might occur if the sub-registers were grouped better.

Thanks,
Jeff Kunkel

I abandoned the experiment because it didn't give a significant performance gain.

Another problem is that aliases don't always form a nice tree, so sometimes topological sorting is not possible.

The fast register allocator now avoids iterating over aliases by using a working-set strategy instead.

/jakob

I am just going with a cache strategy where I just eager evaluate the
get alias function.

- Jeff