[LLVMdev] Explicit register usage in LLVM assembly

Frits van Bommel fvbommel at gmail.com
Sat Jul 9 08:51:20 PDT 2011


On 9 July 2011 17:12, Yiannis Tsiouris <yiannis.tsiouris at gmail.com> wrote:
> On 07/08/2011 10:30 PM, Frits van Bommel wrote:
>> On 8 July 2011 21:10, Yiannis Tsiouris <yiannis.tsiouris at gmail.com> wrote:
>>> The problem with that is the case of an 'invoke' call. According to the
>>> semantics of the invoke instruction the return value is not available  when
>>> a stack unwind happens. From the Language Reference Manual:
>>>  "For the purposes of the SSA form, the definition of the value returned by
>>> the 'invoke' instruction is deemed to occur on the edge from the current
>>> block to the "normal" label. If the callee unwinds then no return value is
>>> available."
>>>
>>> In that case, how can i get the values of the pinned registers, i.e. HP, P
>>> and NSP, needed in the Fail code block?
>>
>> You could store them in the exception, assuming your compiler is the
>> one generating the code that throws it...
> Hi Frits and thanks for your quick response,
>
> Can you elaborate more on this idea? How could i do that?
> Let me explain quickly how i handle the 'register pinning' and what is
> the problem in case it was not clear in the beginning (in llvm pseudocode):
>
> {i64, i64, i64, i64} @main(i64 %in_hp, i64 %in_p, i64 %in_sp) {
>  ;; In the entry block:
>  %hp = alloca i64
>  store %in_hp -> %hp
>  %p = alloca i64
>  store %in_p  -> %p
>  %sp = alloca i64
>  store %in_sp -> %sp
>  ......
>  ;; before normal call
>  %hp1 = load %hp
>  %p1  = load %p
>  %sp1 = load %sp
>  {%hp2, %p2, %nsp2, %val} = call @foo(%hp1, %p1, %sp1, arg1, arg2)
>  ;; in normal continuation
>  store %hp2 -> %hp
>  store %p2  -> %p
>  store %sp2 -> %sp
>  .......
>  .......
>  ;; before invoke call
>  %hp3 = load %hp
>  %p3  = load %p
>  %sp3 = load %sp
>  {%hp4, %p4, %nsp4, %val} = invoke @bar(%hp3, %p3, %sp3, ...) to label
> %Continue unwind label %Cleanup
>  ;; %Continue label (normal return)
>  store %hp4 -> %hp
>  store %p4  -> %p
>  store %sp5 -> %sp
>  .....
>  %Cleanup:
>  ;; In this block i *cannot* access %hp4, %p4, %sp4

Reaching this block means that some kind of exception has been thrown, right?
If the code throwing the exception is generated by your compiler, you
can have it implicitly add some extra fields to it and store the
current hp/p/sp values there.
Here you can then just load those fields and store them to %hp/%p/%sp.

If the exception could have been thrown by code compiled by some other
compiler you need to be compatible with (or even one for an entirely
different language which doesn't know about those values) my
suggestion won't work.

>  .....
>  ;; Return of main
>  %hp5 = load %hp
>  %p5  = load %p
>  %sp5 = load %sp
>  ret {%hp5, %p5, %sp5, 0}
> }
>
> The problem is that in the %Cleanup block i cannot perform the usual
> store as the virtual registers %hp4, %p4, %sp4, are not available (due
> to the semantics of the 'invoke' statement).

I understand, which was why I suggested storing them in the exception object.




More information about the llvm-dev mailing list