[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