[LLVMdev] Explicit register usage in LLVM assembly

David Terei davidterei at gmail.com
Sat Apr 2 16:58:33 PDT 2011


Hi Yiannis,

As has been said GHC had this problem (I'm the author of GHC's LLVM
backend). GHC uses 4 pinned registers on x86-32 and 16 on x86-64. The
solution is to use a custom calling convention. I would argue that
this is a better solution then having the registers completely
reserved as in the middle of a function llvm can spill those registers
to free them up for temporary use. Also, if when generating code you
know that one of the pinned registers doesn't actually store anything
useful for this function then you can avoid passing it on to the next
function so that the register will be free to use during the function.

Here is a link to the original discussion about this problem and the solution:

http://nondot.org/sabre/LLVMNotes/GlobalRegisterVariables.txt

You should also check out the GHC calling convention as there is a
good chance you could use it to get what you want and not have to
modify llvm at all. The calling conventions for X86 are defined in
'lib/Target/X86/X86CallingConv.td' in a very easy to read format.

On X86-64 the arguments are passed in R13, RBP, R12, RBX, R14, RSI,
RDI, R8, R9, R15, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, in that order.

So lets say the compiler you are trying to work with currently stores
a Sp and a Hp in %R13 and %R12 respectively. You could define your
functions like so:

function cc 10 void f (Sp, tmp1, Hp) {
  [...]
  tail call g (Sp', undef, Hp');
  ret void;
}

Cheers,
David

On 2 April 2011 15:51, Yiannis Tsiouris <yiannis.tsiouris at gmail.com> wrote:
> On 04/03/2011 12:43 AM, Frits van Bommel wrote:
>> On Sat, Apr 2, 2011 at 9:46 PM, Yiannis Tsiouris
>> <yiannis.tsiouris at gmail.com> wrote:
>>
>>>  I am not sure i made myself clear about what i want. I was wondering
>>> if there
>>> is a way to communicate to LLVM's register allocator and define which
>>> registers are pre-coloured and should not be used for allocation.
>>>
>> Do you really need that, or would it be enough to be able to get the
>> value of the register at the start of a function and be able to set it
>> (or pass it along) when calling other functions? If so, the easiest
>> way really is to define a calling convention that uses it as e.g. the
>> first parameter register. Then you can just read the value from that
>> parameter, and have your compiler automatically pass it as that
>> parameter to other functions.
>>
>> If it ever changes you'll also need to add it as e.g. the first return
>> register so functions can return the current value in it (note that
>> functions can return multiple values by returning structs). To keep
>> things simple, it's probably best to treat it as a local variable in
>> your frontend: alloca at the start of the function, store to it at the
>> start of the function and after every call that returns the current
>> value for it, then load it whenever you need it. Optimization passes
>> will easily clean this up.
>> This is probably a good idea even if it doesn't change, simply because
>> it tells the code generator that the parameter register isn't changed.
>> Or at least, that the value in the register after the call is still
>> the value it needs to use. Otherwise, it would likely store it to the
>> stack before the first call and load it before every subsequent call.
>>
>> After optimization, the code generator would most likely prefer to
>> keep the value in the right register (since it starts there and later
>> needs to be there), but it might get moved elsewhere if there's a lot
>> of code between uses of the variable and the register is better used
>> for other things. This is usually a *good* thing, because it should be
>> better for performance.
>> As Sam said, the only place this might mess things up is when
>> interrupt functions (which aren't explicitly called, meaning LLVM
>> wouldn't know the register needs to contain the variable at that point
>> in the code) are involved. Well, and maybe debuggers I suppose, if the
>> register is hardcoded somewhere or you explicitly ask for the register
>> instead of the variable.
>>
>>
>> P.S. If it's important (or just convenient) for you to use a
>> unmodified LLVM, you might be able to get these changes into the
>> repository if you post a patch to the commits list. GHC had their own
>> special calling convention committed, for example.
>>
> First of all, i would like to thank you both for your quick answers!
>
> I am working on creating a backend for a language that already has a
> compiler. This compiler already maps some virtual registers of the VM,
> such as stack and heap pointers, to physical ones for performance and
> interoperability. If I understood well, there is no simple, predefined
> way to retain these conventions (custom pre-coloured registers) with
> LLVM compiler infrastructure. I would be surprised if I was the first
> one to have ever stumbled upon this problem!
>
> ~y.
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>




More information about the llvm-dev mailing list