Eduardo Souza via llvm-dev
2020-Sep-15 08:37 UTC
[llvm-dev] RewriteStatepointsForGC and Invoke
Hi all,
I have been trying to use LLVM's GC infrastructure (Statepoints) and ran
into an issue when using exception handling.
The problem happens when I use an invoke instruction to support exception
handling, and try to apply the pass RewriteStatepointsForGC to produce
stackmaps.
I was able to create a minimal example using the example in the
documentation of RewriteStatepointsForGC:
declare void ()* @foo()
declare i8* @__gxx_personality_v0()
define i8 addrspace(1)* @test1(i8 addrspace(1)* %obj)
gc "statepoint-example" personality i8* ()* @__gxx_personality_v0
{
blk_entry:
invoke void ()* @foo() to label %blk_normal unwind label %blk_exc
blk_normal:
ret i8 addrspace(1)* %obj
blk_exc:
%res1 = landingpad { i8*, i32 }
catch i8* null
ret i8 addrspace(1)* %obj
}
The pass is suppose to rewrite the invoke call into a call to
*llvm.experimental.gc.statepoint*, producing a token, and the token can be
used in *llvm.experimental.gc.relocate*, to get the relocated pointer. For
a normal call, the IR after the pass should look like:
blk_entry:
%statepoint_token = call token (i64, i32, void ()* ()*, i32, i32,
...) @llvm.experimental.gc.statepoint.p0f_p0f_isVoidff(i64 2882400000,
i32 0, void ()* ()* @foo, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)*
%obj)
%obj.relocated = call coldcc i8 addrspace(1)*
@llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 7,
i32 7) ; (%obj, %obj)
br label %blk_normal
blk_normal: ; preds = %blk_entry
ret i8 addrspace(1)* %obj.relocated
However, since I'm using an invoke, I do not have access to the token
returned by the call to *llvm.experimental.gc.statepoint* in *blk_exc*,
making it not possible to relocate *%obj* when an exception is thrown. When
running the pass on the initial example I get:
Call parameter type does not match function signature!
%res1 = landingpad { i8*, i32 }
catch i8* null
token %obj.relocated = call coldcc i8 addrspace(1)*
@llvm.experimental.gc.relocate.p1i8({ i8*, i32 } %res1, i32 7, i32 7) ;
(%obj, %obj)
LLVM ERROR: Broken function found, compilation aborted!
I assume the pass does not consider the invoke scenario, but even then, I
would not know how to fix this issue myself, since I cannot access
*%statepoint_token* in the exception block.
Is this a known issue? Is there any way to work around it that I might not
be seeing?
Thanks in advance,
--
Luis Eduardo de Souza Amorim
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20200915/01319eb8/attachment.html>
Denis Antrushin via llvm-dev
2020-Sep-15 16:54 UTC
[llvm-dev] RewriteStatepointsForGC and Invoke
There is a warning in llvm docs about your problem
(https://llvm.org/docs/Statepoints.html#id33) :
```
Relocations along exceptional paths are currently broken in ToT. In particular,
there is current
no way to represent a rethrow on a path which also has relocations. See this
llvm-dev discussion
for more detail.
```
(What's ToT? I don't know)
And it points to this topic:
https://groups.google.com/forum/#!topic/llvm-dev/AE417XjgxvI
Basically it works for cleanup landing pads only and should looks like this:
```
blk_exc:
%res1 = landingpad token
cleanup
ret i8 addrspace(1)* %obj
```
On 15.09.2020 11:37, Eduardo Souza via llvm-dev wrote:> Hi all,
>
> I have been trying to use LLVM's GC infrastructure (Statepoints) and
ran into an issue when using exception handling.
> The problem happens when I use an invoke instruction to support exception
handling, and try to apply the pass RewriteStatepointsForGC to produce
stackmaps.
> I was able to create a minimal example using the example in the
documentation of RewriteStatepointsForGC:
>
> declare void ()* @foo()
> declare i8* @__gxx_personality_v0()
> define i8 addrspace(1)* @test1(i8 addrspace(1)* %obj)
> gc "statepoint-example" personality i8* ()*
@__gxx_personality_v0 {
> blk_entry:
> invoke void ()* @foo() to label %blk_normal unwind label %blk_exc
> blk_normal:
> ret i8 addrspace(1)* %obj
> blk_exc:
> %res1 = landingpad { i8*, i32 }
> catch i8* null
> ret i8 addrspace(1)* %obj
> }
>
> The pass is suppose to rewrite the invoke call into a call to
*llvm.experimental.gc.statepoint*, producing a token, and the token can be used
in *llvm.experimental.gc.relocate*, to get the relocated pointer. For a normal
call, the IR after the pass should look like:
>
> blk_entry:
> %statepoint_token= call token (i64, i32,void ()* ()*, i32, i32, ...)
@llvm.experimental.gc.statepoint.p0f_p0f_isVoidff(i642882400000, i320,void ()*
()* @foo, i320, i320, i320, i320, i8addrspace(1)* %obj)
> %obj.relocated= call coldcc i8addrspace(1)*
@llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i327, i327); (%obj,
%obj)
> br label %blk_normal
>
> blk_normal: ; preds = %blk_entry
> ret i8addrspace(1)* %obj.relocated
>
> However, since I'm using an invoke, I do not have access to the token
returned by the call to *llvm.experimental.gc.statepoint* in *blk_exc*, making
it not possible to relocate *%obj* when an exception is thrown. When running the
pass on the initial example I get:
>
> Call parameter type does not match function signature!
> %res1 = landingpad { i8*, i32 }
> catch i8* null
> token %obj.relocated = call coldcc i8 addrspace(1)*
@llvm.experimental.gc.relocate.p1i8({ i8*, i32 } %res1, i32 7, i32 7) ; (%obj,
%obj)
> LLVM ERROR: Broken function found, compilation aborted!
>
>
> I assume the pass does not consider the invoke scenario, but even then, I
would not know how to fix this issue myself, since I cannot access
*%statepoint_token* in the exception block.
> Is this a known issue? Is there any way to work around it that I might not
be seeing?
>
> Thanks in advance,
>
> --
> Luis Eduardo de Souza Amorim
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>