[LLVMdev] A limitation of LLVM with regard to marking sret functions as readonly.
Nicholas Chapman
admin at indigorenderer.com
Sun Mar 8 09:55:39 PDT 2015
Hi all,
I have identified what seems to be a limitation of LLVM with regard to
marking 'sret functions' as pure/readonly.
For some context - I have some JITed code produced by LLVM, and that
code calls back into the host application occasionally.
Since my language is purely functional, no functions have side-effects.
Therefore I would like to be able to cache the value of identical calls
back into the host application, e.g.
if f is a function exported by the host application,
f(1) + f(1)
should only call f(1) once, then cache and reuse the value instead of
making a second call.
The problem is is that some of the exported functions need to return
structures. As such a pointer to the returned structure is passed as
the first argument and marked with the sret attribute.
However due to this, that function can no longer be marked with the
'readonly' attribute (as it needs to write to the returned structure).
(I tried marking the function as readonly anyway and the function is
incorrectly compiled to 'ret void' or similar)
There seems to be a similar problem with C++ code:
------------------------------------
class s
{
public:
float x;
float y;
};
extern s g(void* env) __attribute__ ((pure));
float func(float x, void* env)
{
return g(env).x + g(env).x;
}
------------------------------------
Compiles the function 'func' to just make a single call to g. Note that
's' is returned directly instead of being converted into an SRET arg,
due to the small size of the class 's'. See http://goo.gl/ezXxrI
If we make the class bigger, so it gets returned by SRET:
----------------------------------
class s
{
public:
float x;
float y;
int a;
int b;
int c;
};
extern s g(void* env) __attribute__ ((pure));
float func(float x, void* env)
{
return g(env).x + g(env).x;
}
---------------------------------
Then LLVM compiles 'func' to have 2 calls to g, and g is no longer
marked as 'readonly' See http://goo.gl/YW0n3V
So it doesn't seem possible to me to mark an SRET function as readonly.
To me this seems like a problem.
One way to fix this could be to change the semantics of the readonly
attribute - it could be changed to allow writing through the SRET
pointer argument only.
Cheers,
Nick C.
More information about the llvm-dev
mailing list