[llvm-dev] llvm.experimental.gc.statepoint genarates wrong Stack Map (or does it?)

vlad via llvm-dev llvm-dev at lists.llvm.org
Mon Nov 16 02:46:06 PST 2015


> Vlad,
> 
> My initial impression is that you've stumbled across a bug.  I suspect
> that we - the only active users of the deopt info in the statepoint I
> know of - have been inverting the meaning of Direct and Indirect
> throughout our code.  (i.e. we're consistent, but swapped on the
> documented meaning)  I've asked Sanjoy to confirm that, and if he
> believes that is actually the case, we will fix upstream to use
> Indirect in this case.
> 
> I'll try to have more information for you early next week.

Hi, Philip! Thank you for taking time to look into it!
May be it's a separate question, but I hope it's OK to ask in this 
thread. Would it be hard to make the statepoint intrinsic produce frame 
pointer based offset (instead of sp-based) if 
"no-frame-pointer-elim"="true" attribute is specified?

> Can I ask what you're using the deopt information for?  Do you have a
> language runtime which supports deoptimization?  Or are you using it
> for something different?  If so, what?  I'm curious to know how others
> are using the infrastructure.

Sure.
I am working on LLV8, which is an attempt to use LLVM MCJIT as a backend 
for Google V8. So yes, we have a language runtime which supports 
deoptimization.
Deoptimization support wasn't hard. We use the stackmap intrinsic for 
that. (And we've encountered each type of Location except Direct so 
far).
Now I am implementing the safepoint functionality which is why I use the 
gc.statepoint intrinsic. The two utility passes have been extremely 
helpful. The use-cases they support are much more general than my needs 
though. So I use a modified version of RewriteStatepointsForGC, which 
only appends the pointer values live across the statepoint to <deopt 
args>.

> Philip
> 
> On 11/13/2015 03:17 AM, vlad via llvm-dev wrote:
>> Hello, list
>> 
>> I am not quite sure if what I'm experiencing is a bug or intentional 
>> behavior.
>> 
>> In the code below the result of a function call is a deopt arg to 
>> llvm.experimental.gc.statepoint
>> (http://llvm.org/docs/Statepoints.html#llvm-experimental-gc-statepoint-intrinsic). 
>> Therefore a Stack Map containing location of this variable is created 
>> upon code generation.
>> 
>> Here's the complete example:
>> 
>>     define i64 addrspace(1)* @func() {
>>         %p = inttoptr i64 42 to i64 addrspace(1)*
>>         ret i64 addrspace(1)* %p
>>     }
>> 
>>     define i8 @main() #0 gc "statepoint-example" {
>>         %result = call i64 addrspace(1)* @func()
>> 
>>         %token = call i32 (i64, i32, i64 addrspace(1)* ()*, i32, i32, 
>> ...) @llvm.experimental.gc.statepoint.p0f_p1i64f (
>>             i64 111, i32 0,
>>             i64 addrspace(1)* ()* @func,
>>             i32 0, i32 0, i32 0,
>>             i32 1,
>>             i64 addrspace(1)* %result) ; the only deopt arg
>> 
>> 
>>         %b = ptrtoint i64 addrspace(1)* %result to i64
>>         %c = trunc i64 %b to i8
>>         ret i8 %c
>>     }
>> 
>> 
>>     declare i32 @llvm.experimental.gc.statepoint.p0f_p1i64f(i64, i32, 
>> i64 addrspace(1)* ()*, i32, i32, ...)
>>     declare i64 addrspace(1)* @llvm.experimental.gc.result.p1i64(i32)
>> 
>>     attributes #0 = { "no-frame-pointer-elim"="true" }
>> 
>> I compile with `llc -O3 -x86-asm-syntax=intel`.
>> 
>> Here is the meat of the emitted asm:
>>     call    func
>>     mov rbx, rax
>>     mov qword ptr [rbp - 16], rbx
>>     call    func
>> 
>> Here is the corresponding Stack Map Location:
>>     .byte   2
>>     .byte   8
>>     .short  7
>>     .long   0
>> Which means, according to 
>> http://llvm.org/docs/StackMaps.html#stack-map-format, that it's a 
>> Direct location rsp + 0 (rsp has DWARF register number 7).
>> Which I find is not exactly true, as it should rather be an Indirect 
>> location [rsp + 0], or better yet, considering I specified 
>> "no-frame-pointer-elim"="true", [rbp - 16].
>> 
>> The only explanation about direct locations in the doc is "If an 
>> alloca value is passed directly to a stack map intrinsic, then LLVM 
>> may fold the frame index into the stack map as an optimization to 
>> avoid allocating a register or stack slot. These frame indices will be 
>> encoded as Direct locations in the form BP + Offset." And as far as I 
>> can see it's not the case here.
>> 
>> I have a new version of LLVM which I built yesterday.
>> 
>> Please help me understand what's happening here. Thanks in advance
>> 
>> 
>> 
>> _______________________________________________
>> LLVM Developers mailing list
>> llvm-dev at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev



More information about the llvm-dev mailing list