This is an archive of the discontinued LLVM Phabricator instance.

[AIX] Remove unused vector registers from allocation order in the default AltiVec ABI
ClosedPublic

Authored by ZarkoCA on Apr 7 2021, 10:27 AM.

Details

Summary

The previous implementation of the default AltiVec ABI marked registers V20-V31
as reserved. This failed to prevent reserved VFRC registers being allocated.
In this patch instead of marking the registers reserved we remove unallowed
registers from the allocation order completely.

This is a slight rework of an implementation by @nemanjai

Diff Detail

Event Timeline

ZarkoCA created this revision.Apr 7 2021, 10:27 AM
ZarkoCA requested review of this revision.Apr 7 2021, 10:27 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 7 2021, 10:27 AM
ZarkoCA edited the summary of this revision. (Show Details)Apr 7 2021, 12:40 PM
jsji added a comment.Apr 8 2021, 7:47 AM

What is the fundamental reason of not fixing the bug in getReservedRegs but doing that by changing allocation order instead ?

jsji added a reviewer: Restricted Project.Apr 8 2021, 7:47 AM

What is the fundamental reason of not fixing the bug in getReservedRegs but doing that by changing allocation order instead ?

We had an offline discussion about this and I decided to go with this approach here for the following reasons:

  1. Applying the fix in getReservedRegs should work, however, removing from the allocation order is technically more correct since they are not actually reserved for any use. Instead they cannot be used at all.
  2. I am concerned about the different register subclasses that we can accidentally omit using the getReservedRegs
  3. In our offline discussion we didn't come to conclusion to which approach is "better" and maybe continuing the discussion here would be good.
jsji added a comment.EditedApr 8 2021, 8:56 AM

Thanks.

  1. Applying the fix in getReservedRegs should work, however, removing from the allocation order is technically more correct since they are not actually reserved for any use. Instead they cannot be used at all.

I am not sure why it is *technically more correct* to change allocation order instead of *reservering reserved reg in designed API*.

I believe these regs are exactly what *Reserved Register* defines.

According to AIX ABI: https://www.ibm.com/docs/en/aix/7.2?topic=concepts-aix-vector-programming

VR20:31	Reserved (default mode)
Nonvolatile (extended ABI mode)

When the default Vector enabled mode is used, these registers are reserved and must not be used.
In the extended ABI vector enabled mode, these registers are nonvolatile and their values are preserved across function calls

And the getReservedRegs API is:

/// Returns a bitset indexed by physical register number indicating if a
/// register is a special register that has particular uses and should be
/// considered unavailable at all times, e.g. stack pointer, return address.
/// A reserved register:
/// - is not allocatable
/// - is considered always live
/// - is ignored by liveness tracking
/// It is often necessary to reserve the super registers of a reserved
/// register as well, to avoid them getting allocated indirectly. You may use
/// markSuperRegs() and checkAllSuperRegsMarked() in this case.
virtual BitVector getReservedRegs(const MachineFunction &MF) const = 0;

My understanding of has particular uses is that compiler will work well if there is some special (or unexpected) use of these regs,
but it does not mean that you *HAVE* to have some use in compiler...

  1. I am concerned about the different register subclasses that we can accidentally omit using the getReservedRegs

I don't think this is a good reason. We should be able to reserve what we want here. If there is bug preventing us to do so, we should fix it.
For missing VFRC in original implementation, that is a bug , we should be able to fix it by marking all alias regs as reserved.

Thanks.

  1. Applying the fix in getReservedRegs should work, however, removing from the allocation order is technically more correct since they are not actually reserved for any use. Instead they cannot be used at all.

I am not sure why it is *technically more correct* to change allocation order instead of *reservering reserved reg in designed API*.

I believe these regs are exactly what *Reserved Register* defines.

According to AIX ABI: https://www.ibm.com/docs/en/aix/7.2?topic=concepts-aix-vector-programming

VR20:31	Reserved (default mode)
Nonvolatile (extended ABI mode)

When the default Vector enabled mode is used, these registers are reserved and must not be used.
In the extended ABI vector enabled mode, these registers are nonvolatile and their values are preserved across function calls

And the getReservedRegs API is:

/// Returns a bitset indexed by physical register number indicating if a
/// register is a special register that has particular uses and should be
/// considered unavailable at all times, e.g. stack pointer, return address.
/// A reserved register:
/// - is not allocatable
/// - is considered always live
/// - is ignored by liveness tracking
/// It is often necessary to reserve the super registers of a reserved
/// register as well, to avoid them getting allocated indirectly. You may use
/// markSuperRegs() and checkAllSuperRegsMarked() in this case.
virtual BitVector getReservedRegs(const MachineFunction &MF) const = 0;

My understanding of has particular uses is that compiler will work well if there is some special (or unexpected) use of these regs,
but it does not mean that you *HAVE* to have some use in compiler...

I understand what you mean. And a further point toward your argument that you made in our offline discussions is that this is how we treat all AltiVec registers for a target that does not support it, that is, we mark all of them as reserved.

ZarkoCA updated this revision to Diff 337563.Apr 14 2021, 2:36 PM

-use getReservedRegs instead
-add correct callee saved regs for the default Altivec ABI in the AllReg calling convention case

jsji accepted this revision as: jsji.Apr 29 2021, 8:43 AM

LGTM.

This revision is now accepted and ready to land.Apr 29 2021, 8:43 AM
This revision was landed with ongoing or failed builds.May 3 2021, 10:51 AM
This revision was automatically updated to reflect the committed changes.