[llvm-dev] Purpose of various register classes in X86 target

Arvind via llvm-dev llvm-dev at lists.llvm.org
Thu Jul 27 23:47:43 PDT 2017

On 28 July 2017 at 12:08, Matthias Braun <mbraun at apple.com> wrote:

> On Jul 27, 2017, at 10:47 PM, Arvind <sraj.arvind at gmail.com> wrote:
> Hello Matthias,
> On 28 July 2017 at 04:13, Matthias Braun <mbraun at apple.com> wrote:
>> It's not that hard in principle:
>> - A register class is a set of registers.
>> - Virtual Registers have a register class assigned.
>> - If you have register constraints (like x86 8bit operations only work on
>> al,ah,etc.) then you have to create a new register class to express that.
>> (The only exception being limited to a single register, which instead we
>> express by assigning the physreg directly instead of using a vreg).
>> - Tablegen may create more regsiter classes for register coalescing where
>> we want to accomodate constraints of multiple instructions at the same time.
>> - All the information is in the .td file; you just have to put some
>> effort into learning tablegen as the information is often expressed by
>> using functions (i.e. the use add/sub/rotate/etc.) instead of just writing
>> a table/list of registers).
> Thanks a lot for the response! The TableGen language is fairly
> straightforward(at least commands used in X86 td file). However, some of
> the comments about the classes didn't fully make sense: I suppose the
> constraints are probably derived from the X86 assembly language and I
> should look there? In addition, some classes don't have any comments(eg:
> GR64_TCW64) and I couldn't find much info elsewhere.
> The GR64_TCW64 class doesn’t seem to be used in an instruction but for
> modeling an ABI constraint. Search the sourcecode you will find the only
> user:
> const TargetRegisterClass *
> X86RegisterInfo::getGPRsForTailCall(const MachineFunction &MF) const {
>   const Function *F = MF.getFunction();
>   if (IsWin64 || (F && F->getCallingConv() == CallingConv::Win64))
>     return &X86::GR64_TCW64RegClass;
>> (And I can’t tell you much more about; I don’t know windows ABIs)

Ah I see. Thanks for the explanations and tips Matthias and Craig! I will
inspect the source code to figure things out and ask again if I'm stuck
somewhere specifically.

> Also, I don't know how the TableGen'erated classes are derived. Would
> reading TableGen's code help understand why those were generated and what
> constraints they encode? Or should I take another approach?
> You probably have to read the tablegen source to see everything. I can
> attempt to explain typical cases:
> * Common Sub Classes: For example when you need a vreg that works for both
> an GR32_NOAX and an GR32_NOSP operand at the same time, then you would need
> a class that contains GR32 without eax and without nosp. As that class is
> not defined the tablegen file itself but someone could be calling
> TargetRegisterInfo::getCommonSubClass(GR32_NOAX, GR32_NOSP) tablegen will
> precompute it and give it a name like “GR32_NOAX_and_GR32_NOSP”.
> * Similar for TargetRegisterInfo::getSubClassWithSubReg which returns a
> subclass containing all registers that support a specific subregister
> index. Again tablegen precompute all possible combinations and gives it a
> name like “GR64_with_sub_8bitReg”.

 Thanks for this example - helps clear few things up! I will dive into
TableGen's code to understand the complete picture.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170728/58ad8c66/attachment.html>

More information about the llvm-dev mailing list