[Mesa-dev] [PATCH] radeon/llvm: Use LLVM C API for compiling LLVM IR to ISA.

Jose Fonseca jfonseca at vmware.com
Thu Apr 25 01:38:46 PDT 2013



----- Original Message -----
> 
> Hi,
> 
> On Wednesday, April 24, 2013 21:54:02 Jose Fonseca wrote:
> > I don't see how this would work -- llvmpipe/draw has LLVMBuildXxxx calls
> > too.  So to prevent symbol collision with apps that use them, we'd need to
> > expose all LLVM calls we need under nome unique prefix.
> > 
> > Also note that gallivm has a lot of function calls. This would also pollute
> > the app's namespace.
> > 
> > In short, for this to work we should do it not for whole gallivm, but with
> > a
> > new module, just for LLVM C calls + the additional helpers, and use an
> > unique prefix (e.g., MesaLLVMXxxx) for everything.
> > 
> > And we should have a new header, that #defines LLVMFoo MesaLLVMFoo, so that
> > Mesa code doesn't need to be changed all over the place.
> 
> Tom sounded that the symbols are more concentrated.
> The effort is huge if you need a lot of symbols outside this library, as you
> would basically need an own abstraction of llvm on top of llvm.

What I'm suggesting doesn't require huge effort.

In detail, I'm suggesting:

(1) have a custom build of LLVM libraries with -fvisibility=hidden

(2) have a src/mesallvm/mesallvm.c containing wrappers

  #include <llvm-c/Core.h> 

__attribute__((visibility("default")))
  LLVMValueRef
  MesaLLVMBuildAdd(LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) {
     return LLVMBuildAdd(Builder, LHS, RHS, Name);
  }

  ...

  plus a src/mesallvm/mesallvm.cpp with whatever custom C wrappers to C++ functionality we need (e.g, the stuff in lp_build_misc.cpp).

  These two modules would be statically linked against the custom LLVM libraries from (1), producing a shared library libMESALLVM.so, which would be consumed by any Mesa driver that needs it. Because all symbols have the unique MESALLVM prefix, these should not collide with user stuff.

(3) have a src/mesallvm/mesallvm.h

   // Mange LLVM symbols before including them
   #define LLVMBuildAdd MesaLLVMBuildAdd

   ...

   #include <llvm-c/Core.h> 
   ...

   All gallium code would include src/mesallvm/mesallvm.h instead. It can still use the LLVMFoo as befor.

And that's all there is to it.

> Is it possible to hide all llvm calls behind the lp_bld_* interface or
> similar
> and put this layer into a single shared object statically linked with all of
> llvm?

No, gallivm was not intended a full abstration to LLVM C bindings, furthermore it is not self-contained (it depends on lots of stuff from other auxiliary modules).
 
> Again OTOH, the dlopen flags are really made for this kind of module use I
> think ...

Yes, instead of what I propose above, one could have a dynamic dispatch module, that dlopens/dlsyms everything without poluting the global namespace:

   LLVMValueRef
   LLVMBuildAdd((LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name
   {
       LLVMBUILDADD pLLVMBuildAdd = (LLVMBUILDADD)dlsym(dlopen("libMESALLVM.so",RTLD_LOCAL), "LLVMBuildAdd");
       return pLLVMBuildAdd(Builder, LHS, RHS, Name);
   }

   ...

It seems more work, and less efficient.  I'm fine either way though.


Nevertheless, I must insist that the problem of hiding LLVM symbols is handled in a layer underneath gallivm.  Severing gallivm module from the rest auxiliary gallium modules, or making gallivm a full wrapper for all LLVM symbols, seems unsustainable / too limiting IMO.


Jose


More information about the mesa-dev mailing list