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

2013-05-05 Thread Mathias Fröhlich

Hi,

Sorry for these late response. I am in the middle of moving to a new 
appartements coordinating work in the new one and so on.
It might even be that I do have no good network access for a few days ...

On Wednesday, May 01, 2013 17:56:33 Tom Stellard wrote:
> Thanks for pointing this out, I'll look into it.  Do you know if there is
> any way to add C++ symbols to the EXPORT() command?
No, sorry.
To be honest I do not even know if the export command is the right way to go. 
>From the documentation I had expected this to work slightly different, but in 
the end it pulls these symbols and did what I need.
So, this is to work around the --whole-archive problem
If we can teach libtool to take the -Wl,-{no--,}whole-archive argument or 
achieve a similar result, we can skip the EXPORT command. Also listing all the 
llvm libs in the linker script was only to get the small proof of concept hack 
together. It's probably better to take the llvm libraries that we get from the 
configure step and use them on the command line instead of just squashing all 
possible llvm libs in this GROUP line ...

> > > I didn't do much testing yet, but glxgears works for me with r600g and
> > > llvmpipe.
> > 
> > I tried to test against the driver-isolation piglit test that I sent. But
> > this still fails.
> > 
> > So, this simplest and least intrusive variant appears not to work as
> > expected. Not sure what the exact reason is:
> > Either, non versioned symbols take precedence or you cannot shield symbols
> > from different libraries by symbol versions. Keep in mind that this
> > mechanism was invented to maintain backwards compatibility for functions
> > that changed in a newer libc library in a api incompatible way, but still
> > provide the old variant for executables/libraries that linked against an
> > older libc. So what remains is either dig deeper there, or we use the
> > much more intrusive explicit Mesa prefix to the C api functions. The
> > direct c++ use is still unsolved then.
> 
> Today, I spent some time on this and implemented your solution using the
> MesaLLVM prefix on all LLVM functions.  The branch is here:
> http://cgit.freedesktop.org/~tstellar/mesa/log/?h=libmesallvm-prefix
> 
> It's pretty hacky right now.  Only the r600 driver will build, and I've
> commented all the c++ code out of gallivm.  However, it passes your
> driver-isolation test and even works with clover as long as clover
> links to the stock libLLVM-3.3.so library.
Ok, that sounds good so far.

> We still need to figure out what to do about he c++ usage.  I think some
> of it can be replaced with LLVM C API calls, but we may need to use our own
> C wrappers for some of the code.
Yes, I think so.

So, for example, lp_disassemble() would move into something like 
MesaLLVMDisassemble() and lp_bld_debug.cpp would pull the MesaLLVMDisassemble 
function?
Jose, does this fit your plans?

> It seems like the prefixing the LLVM calls may be the way to go, let me
> know if you have any suggestions for improvements.
Not more ideas than are already floating around I think.
Thank you very much for doing all this!

Greetings

Mathias
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


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

2013-05-01 Thread Tom Stellard
On Wed, May 01, 2013 at 04:11:51PM +0200, Mathias Fröhlich wrote:
> 
> Tom, Jose,
> 
> On Tuesday, April 30, 2013 16:56:56 Tom Stellard wrote:
> > I took the linker script from your email and took at shot at creating
> > libMesaLLVM.so within Mesa.  I've pushed my initial code here:
> > http://cgit.freedesktop.org/~tstellar/mesa/log/?h=libmesallvm
> Thank you very much and sorry for the late reply.
> 
> > I ran into a few minor issues:
> > 
> > I had to export all the LLVM symbols in libMesaLLVM.so, because gallivm
> > still uses some C++ functions, and I was unsure how to handle the name
> > mangling in the linker script.
> You can even add c++ symbols directly there. See
> http://sourceware.org/binutils/docs/ld/VERSION.html
> 

Thanks for pointing this out, I'll look into it.  Do you know if there is
any way to add C++ symbols to the EXPORT() command?

> > Clover still has a number of undefined symbols.  I'm still not quite
> > sure what the problem is, but I think the problem has something
> > to do with the LLVM symbols in the clang libraries clover is using.
> Also not sure, but I assume that some .o files from the .a libs are not 
> pulled 
> because they are unused by the C api. The C api is explicitly pulled in the 
> linker script. Which works around the lack of --whole-archive in the linker 
> script. So, probably these missing symbols do just not end up in the shared 
> library.
> 

Yeah, this was the problem, clang needed symbols that weren't used by
the C API, so they weren't included in libMesaLLVM.so.

> > I didn't do much testing yet, but glxgears works for me with r600g and
> > llvmpipe.
> I tried to test against the driver-isolation piglit test that I sent. But 
> this 
> still fails.
> 
> So, this simplest and least intrusive variant appears not to work as expected.
> Not sure what the exact reason is:
> Either, non versioned symbols take precedence or you cannot shield symbols 
> from different libraries by symbol versions. Keep in mind that this mechanism 
> was invented to maintain backwards compatibility for functions that changed 
> in 
> a newer libc library in a api incompatible way, but still provide the old 
> variant for executables/libraries that linked against an older libc.
> So what remains is either dig deeper there, or we use the much more intrusive 
> explicit Mesa prefix to the C api functions. The direct c++ use is still 
> unsolved then.
> 

Today, I spent some time on this and implemented your solution using the
MesaLLVM prefix on all LLVM functions.  The branch is here:
http://cgit.freedesktop.org/~tstellar/mesa/log/?h=libmesallvm-prefix

It's pretty hacky right now.  Only the r600 driver will build, and I've
commented all the c++ code out of gallivm.  However, it passes your
driver-isolation test and even works with clover as long as clover
links to the stock libLLVM-3.3.so library.

We still need to figure out what to do about he c++ usage.  I think some
of it can be replaced with LLVM C API calls, but we may need to use our own
C wrappers for some of the code.

It seems like the prefixing the LLVM calls may be the way to go, let me
know if you have any suggestions for improvements.

-Tom

> > Also, note that there are 4 new commits in that repo, the first three
> > are just variations from my previous C API patches for drivers/radeon.
> > The biggest change is that I moved the static initializer that calls
> > the llvm_multithreaded* functions into gallivm/lp_bld_misc.cpp
> From my point of view this part is fine.
> 
> > Let me know if you have any questions, concerns or other ideas.
> Currently not.
> Thank you for integrating that all and trying that all out!
> 
> Greetings
> 
> Mathias
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


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

2013-05-01 Thread Mathias Fröhlich

Tom, Jose,

On Tuesday, April 30, 2013 16:56:56 Tom Stellard wrote:
> I took the linker script from your email and took at shot at creating
> libMesaLLVM.so within Mesa.  I've pushed my initial code here:
> http://cgit.freedesktop.org/~tstellar/mesa/log/?h=libmesallvm
Thank you very much and sorry for the late reply.

> I ran into a few minor issues:
> 
> I had to export all the LLVM symbols in libMesaLLVM.so, because gallivm
> still uses some C++ functions, and I was unsure how to handle the name
> mangling in the linker script.
You can even add c++ symbols directly there. See
http://sourceware.org/binutils/docs/ld/VERSION.html

> Clover still has a number of undefined symbols.  I'm still not quite
> sure what the problem is, but I think the problem has something
> to do with the LLVM symbols in the clang libraries clover is using.
Also not sure, but I assume that some .o files from the .a libs are not pulled 
because they are unused by the C api. The C api is explicitly pulled in the 
linker script. Which works around the lack of --whole-archive in the linker 
script. So, probably these missing symbols do just not end up in the shared 
library.

> I didn't do much testing yet, but glxgears works for me with r600g and
> llvmpipe.
I tried to test against the driver-isolation piglit test that I sent. But this 
still fails.

So, this simplest and least intrusive variant appears not to work as expected.
Not sure what the exact reason is:
Either, non versioned symbols take precedence or you cannot shield symbols 
from different libraries by symbol versions. Keep in mind that this mechanism 
was invented to maintain backwards compatibility for functions that changed in 
a newer libc library in a api incompatible way, but still provide the old 
variant for executables/libraries that linked against an older libc.
So what remains is either dig deeper there, or we use the much more intrusive 
explicit Mesa prefix to the C api functions. The direct c++ use is still 
unsolved then.

> Also, note that there are 4 new commits in that repo, the first three
> are just variations from my previous C API patches for drivers/radeon.
> The biggest change is that I moved the static initializer that calls
> the llvm_multithreaded* functions into gallivm/lp_bld_misc.cpp
>From my point of view this part is fine.

> Let me know if you have any questions, concerns or other ideas.
Currently not.
Thank you for integrating that all and trying that all out!

Greetings

Mathias
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


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

2013-04-30 Thread Tom Stellard
On Sat, Apr 27, 2013 at 10:33:29AM +0200, Mathias Fröhlich wrote:
> 
> Hi,
> 
> On Thursday, April 25, 2013 10:29:27 Jose Fonseca wrote:
> > - There are a bunch of options that need to be set via globals, (see
> > lp_set_target_options), so app/drivers could tamper with each other
> > options.
> >
> > - llvm::cl::ParseCommandLineOptions will complain if called multiple times
> > -- I think we no longer need to call it these days though
> >
> > In short, LLVM was not designed for multiple users in the same process.
> Yep.
> 
> Also llvm is still emerging too fast to assume a specific version to be 
> available. At least with r600 we do currently need a somewhat recent version 
> and kind of have this assumption.
> But due to the api not kept strictly backwards compatible and all the 
> pitfalls 
> that happen while emerging fast its very likely that a potential application 
> that also tries to make use of the driver modules just brings its own 
> probably 
> incompatible llvm version in some way. So shielding this in any way makes 
> sense ...
> 
> 
> For the Mesa wrappers:
> I have attached a shell script again as a rapid proof that is able to build a 
> linker script that builds up a wrapper shared library that contains a private 
> llvm copy. That's again non optimal - it contains just all static libs that I 
> have in my current test environment... It's just to sketch how this could 
> work.
> 
> The MesaLLVM-with-prefix.link script can by used with the command
> 
> g++ -shared -o libMesaLLVM.so MesaLLVM-with-prefix.link
> 
> to produce a libMesaLLVM.so that contains all C symbols starting with LLVM 
> from libLLVMCore.a. All of them get prefixed with Mesa and are the only 
> exported symbols then.
> That's close to Joses suggestion but with less work to be done in sources.
> 
> The MesaLLVM-with-version.link script can by used with the command
> 
> g++ -shared -o libMesaLLVM.so MesaLLVM-with-version.link
> 
> to produce a libMesaLLVM.so shared library that uses symbol versioning to 
> distinguish between the llvm versions. I got this idea yesterday and this 
> might simplify the problem a lot.
> By this variant we do not even need to prefix all the callers by Mesa. What 
> this does is to explicitly assign a symbol version to all these calls. At 
> static link symbol resolve time with this libMesaLLVM.so, this symbol version 
>  
> (the 'A MesaLLVM_1.0' entry) is then pulled out of this shared object and all 
> users, in libllvmradeon.so for example, are linked against 
> LLVMCreateContext@MesaLLVM_1,0 instead of just LLVMCreateContext. So we 
> should 
> get a private copy of llvm in libMesaLLVM.so with just the same call names 
> than usual source code wise.
> That's to be tested and verified, but if this works like I think it should, 
> this is the easiest way to get our own LLVM version on linux at least.
> 
> And sorry for just doing these crude proof of concept stuff ...
> 

Hi Mathias,

I took the linker script from your email and took at shot at creating
libMesaLLVM.so within Mesa.  I've pushed my initial code here:
http://cgit.freedesktop.org/~tstellar/mesa/log/?h=libmesallvm

I ran into a few minor issues:

I had to export all the LLVM symbols in libMesaLLVM.so, because gallivm
still uses some C++ functions, and I was unsure how to handle the name
mangling in the linker script.

Clover still has a number of undefined symbols.  I'm still not quite
sure what the problem is, but I think the problem has something
to do with the LLVM symbols in the clang libraries clover is using.

I didn't do much testing yet, but glxgears works for me with r600g and
llvmpipe.

Also, note that there are 4 new commits in that repo, the first three
are just variations from my previous C API patches for drivers/radeon.
The biggest change is that I moved the static initializer that calls
the llvm_multithreaded* functions into gallivm/lp_bld_misc.cpp

Let me know if you have any questions, concerns or other ideas.

Thanks,
Tom


> /* Mesa llvm linker script */
> EXTERN(
> LLVMAddAlias
> LLVMAddAttribute
> LLVMAddCase
> LLVMAddClause
> LLVMAddDestination
> LLVMAddFunction
> LLVMAddFunctionAttr
> LLVMAddGlobal
> LLVMAddGlobalInAddressSpace
> LLVMAddIncoming
> LLVMAddInstrAttribute
> LLVMAddNamedMetadataOperand
> LLVMAddTargetDependentFunctionAttr
> LLVMAlignOf
> LLVMAppendBasicBlock
> LLVMAppendBasicBlockInContext
> LLVMArrayType
> LLVMBasicBlockAsValue
> LLVMBlockAddress
> LLVMBuildAdd
> LLVMBuildAggregateRet
> LLVMBuildAlloca
> LLVMBuildAnd
> LLVMBuildArrayAlloca
> LLVMBuildArrayMalloc
> LLVMBuildAShr
> LLVMBuildAtomicRMW
> LLVMBuildBinOp
> LLVMBuildBitCast
> LLVMBuildBr
> LLVMBuildCall
> LLVMBuildCast
> LLVMBuildCondBr
> LLVMBuildExactSDiv
> LLVMBuildExtractElement
> LLVMBuildExtractValue
> LLVMBuildFAdd
> LLVMBuildFCmp
> LLVMBuildFDiv
> LLVMBuildFMul
> LLVMBuildFNeg
> LLVMBuildFPCast
> LLVMBuildFPExt
> LLVMBuildFPToSI
> LLVMBuildFPToUI
> LLVMBuildFPTrunc
> LLVMBuildFree
> LLVMBuildFRem
> LLVMBuildFSub
> LLVMBuildGE

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

2013-04-28 Thread Jose Fonseca


- Original Message -
> 
> Hi,
> 
> On Thursday, April 25, 2013 10:29:27 Jose Fonseca wrote:
> > - There are a bunch of options that need to be set via globals, (see
> > lp_set_target_options), so app/drivers could tamper with each other
> > options.
> >
> > - llvm::cl::ParseCommandLineOptions will complain if called multiple times
> > -- I think we no longer need to call it these days though
> >
> > In short, LLVM was not designed for multiple users in the same process.
> Yep.
> 
> Also llvm is still emerging too fast to assume a specific version to be
> available. At least with r600 we do currently need a somewhat recent version
> and kind of have this assumption.
> But due to the api not kept strictly backwards compatible and all the
> pitfalls
> that happen while emerging fast its very likely that a potential application
> that also tries to make use of the driver modules just brings its own
> probably
> incompatible llvm version in some way. So shielding this in any way makes
> sense ...
> 
> 
> For the Mesa wrappers:
> I have attached a shell script again as a rapid proof that is able to build a
> linker script that builds up a wrapper shared library that contains a private
> llvm copy. 
>
> That's again non optimal - it contains just all static libs that I
> have in my current test environment... It's just to sketch how this could
> work.
> 
> The MesaLLVM-with-prefix.link script can by used with the command
> 
> g++ -shared -o libMesaLLVM.so MesaLLVM-with-prefix.link
> 
> to produce a libMesaLLVM.so that contains all C symbols starting with LLVM
> from libLLVMCore.a. All of them get prefixed with Mesa and are the only
> exported symbols then.
> That's close to Joses suggestion but with less work to be done in sources.
> 
> The MesaLLVM-with-version.link script can by used with the command
> 
> g++ -shared -o libMesaLLVM.so MesaLLVM-with-version.link
> 
> to produce a libMesaLLVM.so shared library that uses symbol versioning to
> distinguish between the llvm versions. I got this idea yesterday and this
> might simplify the problem a lot.
> By this variant we do not even need to prefix all the callers by Mesa. What
> this does is to explicitly assign a symbol version to all these calls. At
> static link symbol resolve time with this libMesaLLVM.so, this symbol version
> (the 'A MesaLLVM_1.0' entry) is then pulled out of this shared object and all
> users, in libllvmradeon.so for example, are linked against
> LLVMCreateContext@MesaLLVM_1,0 instead of just LLVMCreateContext. So we
> should
> get a private copy of llvm in libMesaLLVM.so with just the same call names
> than usual source code wise.
> That's to be tested and verified, but if this works like I think it should,
> this is the easiest way to get our own LLVM version on linux at least.

Wow. I confess I wasn't aware that linker scripts were this powerful. And if it 
works, using a custom version instead of a custom symbol prefix seems a genial 
idea IMO.

Jose
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


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

2013-04-27 Thread Mathias Fröhlich

Hi,

On Thursday, April 25, 2013 10:29:27 Jose Fonseca wrote:
> - There are a bunch of options that need to be set via globals, (see
> lp_set_target_options), so app/drivers could tamper with each other
> options.
>
> - llvm::cl::ParseCommandLineOptions will complain if called multiple times
> -- I think we no longer need to call it these days though
>
> In short, LLVM was not designed for multiple users in the same process.
Yep.

Also llvm is still emerging too fast to assume a specific version to be 
available. At least with r600 we do currently need a somewhat recent version 
and kind of have this assumption.
But due to the api not kept strictly backwards compatible and all the pitfalls 
that happen while emerging fast its very likely that a potential application 
that also tries to make use of the driver modules just brings its own probably 
incompatible llvm version in some way. So shielding this in any way makes 
sense ...


For the Mesa wrappers:
I have attached a shell script again as a rapid proof that is able to build a 
linker script that builds up a wrapper shared library that contains a private 
llvm copy. That's again non optimal - it contains just all static libs that I 
have in my current test environment... It's just to sketch how this could 
work.

The MesaLLVM-with-prefix.link script can by used with the command

g++ -shared -o libMesaLLVM.so MesaLLVM-with-prefix.link

to produce a libMesaLLVM.so that contains all C symbols starting with LLVM 
from libLLVMCore.a. All of them get prefixed with Mesa and are the only 
exported symbols then.
That's close to Joses suggestion but with less work to be done in sources.

The MesaLLVM-with-version.link script can by used with the command

g++ -shared -o libMesaLLVM.so MesaLLVM-with-version.link

to produce a libMesaLLVM.so shared library that uses symbol versioning to 
distinguish between the llvm versions. I got this idea yesterday and this 
might simplify the problem a lot.
By this variant we do not even need to prefix all the callers by Mesa. What 
this does is to explicitly assign a symbol version to all these calls. At 
static link symbol resolve time with this libMesaLLVM.so, this symbol version  
(the 'A MesaLLVM_1.0' entry) is then pulled out of this shared object and all 
users, in libllvmradeon.so for example, are linked against 
LLVMCreateContext@MesaLLVM_1,0 instead of just LLVMCreateContext. So we should 
get a private copy of llvm in libMesaLLVM.so with just the same call names 
than usual source code wise.
That's to be tested and verified, but if this works like I think it should, 
this is the easiest way to get our own LLVM version on linux at least.

And sorry for just doing these crude proof of concept stuff ...

Greetings

Mathias

mklinkerscript.sh
Description: application/shellscript
/* Mesa llvm linker script */
EXTERN(
LLVMAddAlias
LLVMAddAttribute
LLVMAddCase
LLVMAddClause
LLVMAddDestination
LLVMAddFunction
LLVMAddFunctionAttr
LLVMAddGlobal
LLVMAddGlobalInAddressSpace
LLVMAddIncoming
LLVMAddInstrAttribute
LLVMAddNamedMetadataOperand
LLVMAddTargetDependentFunctionAttr
LLVMAlignOf
LLVMAppendBasicBlock
LLVMAppendBasicBlockInContext
LLVMArrayType
LLVMBasicBlockAsValue
LLVMBlockAddress
LLVMBuildAdd
LLVMBuildAggregateRet
LLVMBuildAlloca
LLVMBuildAnd
LLVMBuildArrayAlloca
LLVMBuildArrayMalloc
LLVMBuildAShr
LLVMBuildAtomicRMW
LLVMBuildBinOp
LLVMBuildBitCast
LLVMBuildBr
LLVMBuildCall
LLVMBuildCast
LLVMBuildCondBr
LLVMBuildExactSDiv
LLVMBuildExtractElement
LLVMBuildExtractValue
LLVMBuildFAdd
LLVMBuildFCmp
LLVMBuildFDiv
LLVMBuildFMul
LLVMBuildFNeg
LLVMBuildFPCast
LLVMBuildFPExt
LLVMBuildFPToSI
LLVMBuildFPToUI
LLVMBuildFPTrunc
LLVMBuildFree
LLVMBuildFRem
LLVMBuildFSub
LLVMBuildGEP
LLVMBuildGlobalString
LLVMBuildGlobalStringPtr
LLVMBuildICmp
LLVMBuildInBoundsGEP
LLVMBuildIndirectBr
LLVMBuildInsertElement
LLVMBuildInsertValue
LLVMBuildIntCast
LLVMBuildIntToPtr
LLVMBuildInvoke
LLVMBuildIsNotNull
LLVMBuildIsNull
LLVMBuildLandingPad
LLVMBuildLoad
LLVMBuildLShr
LLVMBuildMalloc
LLVMBuildMul
LLVMBuildNeg
LLVMBuildNot
LLVMBuildNSWAdd
LLVMBuildNSWMul
LLVMBuildNSWNeg
LLVMBuildNSWSub
LLVMBuildNUWAdd
LLVMBuildNUWMul
LLVMBuildNUWNeg
LLVMBuildNUWSub
LLVMBuildOr
LLVMBuildPhi
LLVMBuildPointerCast
LLVMBuildPtrDiff
LLVMBuildPtrToInt
LLVMBuildResume
LLVMBuildRet
LLVMBuildRetVoid
LLVMBuildSDiv
LLVMBuildSelect
LLVMBuildSExt
LLVMBuildSExtOrBitCast
LLVMBuildShl
LLVMBuildShuffleVector
LLVMBuildSIToFP
LLVMBuildSRem
LLVMBuildStore
LLVMBuildStructGEP
LLVMBuildSub
LLVMBuildSwitch
LLVMBuildTrunc
LLVMBuildTruncOrBitCast
LLVMBuildUDiv
LLVMBuildUIToFP
LLVMBuildUnreachable
LLVMBuildURem
LLVMBuildVAArg
LLVMBuildXor
LLVMBuildZExt
LLVMBuildZExtOrBitCast
LLVMClearInsertionPosition
LLVMConstAdd
LLVMConstAllOnes
LLVMConstAnd
LLVMConstArray
LLVMConstAShr
LLVMConstBitCast
LLVMConstExactSDiv
LLVMConstExtractElement
LLVMConstExtractValue
LLVMConstFAdd
LLVMConstFCmp
LLVMConstFDiv
LLVMConstFMul
LLVMConstFNeg
LLVMConstFPCast
LLVMConstFPExt
LLVMConstFPToSI
LLVMConstFPToUI
LLVMConstF

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

2013-04-27 Thread Mathias Fröhlich

Jose,

On Thursday, April 25, 2013 03:52:44 Jose Fonseca wrote:
> There is no paradox.  To be clear:
Ok, thanks!

Mathias
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


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

2013-04-25 Thread Jose Fonseca


- Original Message -
> On Wed, Apr 24, 2013 at 09:54:02PM -0700, Jose Fonseca wrote:
> > - Original Message -
> > > On Wed, Apr 24, 2013 at 09:40:44PM +0200, Mathias Fröhlich wrote:
> > > > 
> > > > Hi Tom,
> > > > 
> > > > On Tuesday, April 23, 2013 20:47:24 Tom Stellard wrote:
> > > > > First of all, thanks for investigating this.  The information you've
> > > > > provided has helped me a lot.
> > > > Good to hear that it helps.
> > > > 
> > > > > I took a shot at implementing it this way with private static copies
> > > > > of
> > > > > llvm.  I've pushed the initial work to this branch:
> > > > > git://people.freedesktop.org/~tstellar/mesa llvm-build
> > > > > 
> > > > > I was able to hide the LLVM symbols by using the --exclude-libs
> > > > > linker
> > > > > flag and so far I've tested with glxgears, an opencl example and also
> > > > > eglgears and they all work.  I still need to do some more testing,
> > > > > but
> > > > > any thoughts on what I've done so far in this branch?
> > > > 
> > > > I will look at this as soon as I find time. Probably not before the
> > > > beginning
> > > > of next week.
> > > > 
> > > 
> > > I've thought about this some more, and I think that the best solution
> > > might be to move all LLVM API calls into gallivm and build it as a
> > > shared object with it's own private copy of LLVM statically linked.  This
> > > way
> > > we
> > > would still have a private copy of LLVM to work with, but without having
> > > to statically link every single gallium target with LLVM.  Any thoughts
> > > about this?
> > 
> > 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.
> >
> 
> I didn't realize this, and actually the radeon drivers use a lot of
> the LLVMBuildXxxx calls too.
>  
> > 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.
> > 
> 
> I think this is a good approach, however before we make big changes to
> Mesa I want to make sure we know what problems we are trying to solve
> with these changes.  As far as I understand it, the current problems
> are:
> 
> 1. If an application is using the LLVM API outside of Mesa, then it is
> impossible for Mesa to safely use the llvm_*_multithreaded() functions.
> 
> 2. If an application is using a different version of LLVM than Mesa,
> then it might incorrectly use the LLVM symbols that are included in
> the Mesa libraries.
> 
> Are there others?

I know a couple more:

- There are a bunch of options that need to be set via globals, (see 
lp_set_target_options), so app/drivers could tamper with each other options.

- llvm::cl::ParseCommandLineOptions will complain if called multiple times -- I 
think we no longer need to call it these days though

In short, LLVM was not designed for multiple users in the same process.

Jose
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


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

2013-04-25 Thread Christian König

Am 25.04.2013 19:08, schrieb Tom Stellard:


[SNIP]

I think this is a good approach, however before we make big changes to
Mesa I want to make sure we know what problems we are trying to solve
with these changes.  As far as I understand it, the current problems
are:

1. If an application is using the LLVM API outside of Mesa, then it is
impossible for Mesa to safely use the llvm_*_multithreaded() functions.

2. If an application is using a different version of LLVM than Mesa,
then it might incorrectly use the LLVM symbols that are included in
the Mesa libraries.

Are there others?


Loading both r600g and radeonsi with the llvm backend into one process.

Those two might want to use different versions of LLVM at the same time, 
so we might want to abstract the interface even further to the dri 
level, but not sure about that.


Christian.


-Tom
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev



___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


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

2013-04-25 Thread Tom Stellard
On Wed, Apr 24, 2013 at 09:54:02PM -0700, Jose Fonseca wrote:
> - Original Message -
> > On Wed, Apr 24, 2013 at 09:40:44PM +0200, Mathias Fröhlich wrote:
> > > 
> > > Hi Tom,
> > > 
> > > On Tuesday, April 23, 2013 20:47:24 Tom Stellard wrote:
> > > > First of all, thanks for investigating this.  The information you've
> > > > provided has helped me a lot.
> > > Good to hear that it helps.
> > > 
> > > > I took a shot at implementing it this way with private static copies of
> > > > llvm.  I've pushed the initial work to this branch:
> > > > git://people.freedesktop.org/~tstellar/mesa llvm-build
> > > > 
> > > > I was able to hide the LLVM symbols by using the --exclude-libs linker
> > > > flag and so far I've tested with glxgears, an opencl example and also
> > > > eglgears and they all work.  I still need to do some more testing, but
> > > > any thoughts on what I've done so far in this branch?
> > > 
> > > I will look at this as soon as I find time. Probably not before the
> > > beginning
> > > of next week.
> > > 
> > 
> > I've thought about this some more, and I think that the best solution
> > might be to move all LLVM API calls into gallivm and build it as a
> > shared object with it's own private copy of LLVM statically linked.  This 
> > way
> > we
> > would still have a private copy of LLVM to work with, but without having
> > to statically link every single gallium target with LLVM.  Any thoughts
> > about this?
> 
> 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.
>

I didn't realize this, and actually the radeon drivers use a lot of
the LLVMBuildXxxx calls too.
 
> 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.
> 

I think this is a good approach, however before we make big changes to
Mesa I want to make sure we know what problems we are trying to solve
with these changes.  As far as I understand it, the current problems
are:

1. If an application is using the LLVM API outside of Mesa, then it is
impossible for Mesa to safely use the llvm_*_multithreaded() functions.

2. If an application is using a different version of LLVM than Mesa,
then it might incorrectly use the LLVM symbols that are included in
the Mesa libraries.

Are there others?

-Tom
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


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

2013-04-25 Thread Jose Fonseca


- Original Message -
> 
> Jose,
> 
> On Thursday, April 25, 2013 01:38:46 Jose Fonseca wrote:
> > 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 
> > 
> > __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 
> >...
> > 
> >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.
> 
> Technically this will work.
> 
> But I fear that this build procedure is too non standard to be really picked
> up by the distribution builders. They would need to build a seperate llvm
> version inside of the mesa package. Doable, but do you think we can convince
> them all?

This is for you and them to decide. I have no experience nor opinion on that.

> The technical problem you try to solve is that we need to force the llvm
> build
> to have the default hidden visibility.
> I think we could achieve the same result by using a default built llvm static
> lib and explicitly mention the to be exported symbols in a linker script.
> IIRC
> we could even use wildcards there. That is only export everything starting
> with MesaLLVM*.
> 
> Remains that we need to write out all the wrappers, which I called 'huge
> effort'.

I think our scales are greatness are too different:

- apitrace has to deal with 2861 entry points

- LLVM C bindings has 588

  $ grep -ro '\ May be this could equally well done by looking with scripts at the llvm
> libraries and create an apropriate version script. Hide all symbols, except
> the ones starting with MesaLLVM and for each LLVM c symbol create an alias
> with the apropriate MesaLLVM symbol. Requires some shell or python hackery to
> generate the version script given the llvm c binding library.

If it works, sounds great by me. Feel free to ignore my suggestion.

My main concern is foremost what happens gallivm, and not so much the symbol 
problem. The motivation of my suggestions was merely to provide alternatives to 
those I foresee problematic.

> > > Again OTOH, the dlopen flags are really made for this kind of module use
> > > I
> > > think ...
> 
> I was referencing the patches that i just packed into the mail yesterday.
> This
> RTLD_LOCAL|RTLD_DEEPBIND flag already does what we need regarding isolation.
> This does not even require more changes than changing a bunch of dlopen flags
> -
> no wrappers to program.
> What I am not sure about is if we isolate too much for mesa/dri internal
> needs
> with this.

I confess I haven't had opportunity to look at them yet. I'm not familiar with 
the semantics of RTLD_DEEPBIND neither, so I can't comment.

> > 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.
> Huch, then I probably do not get you right.
> Aren't you proposing a full wrapper of all the llvm c symbols by MesaLLVM*
> symbols above? Here you are calling exactly the same too limiting?

There is no paradox.  To be clear:

 - Severing gallivm from rest of auxiliary modules is too limiting -- gallivm 
needs those modules. The wrappers I recommmended are self sufficient. They are 
in no way limited by being isolated from other gallium auxiliary modules.

 - making gallivm a wrapper for all symbols is unsustainable, ugly. Take a look 
at gallivm abstraction for add operation:

/**
 * Generate a + b
 */
LLVMValueRef
lp_build_add(struct lp_build_context *bld,
 LLVMValueRef a,
 LLVMValueRef b)
{
   LLVMBuilderRef builder = bld->gallivm->builder;
   const struct lp_type type = bld->type;
   LLVMValueRef res;

   assert(lp_check_value(type, a));
   assert(lp_check_value(type, b));

   if(a == bld->zero)
  return b;
   if(b == bld->zero)
  return a;
   if(a == bld->undef || b == bld->undef)
  return bld->undef;

   if(bld->type.norm) 

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

2013-04-25 Thread Mathias Fröhlich

Jose,

On Thursday, April 25, 2013 01:38:46 Jose Fonseca wrote:
> 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 
> 
> __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 
>...
> 
>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.

Technically this will work.

But I fear that this build procedure is too non standard to be really picked 
up by the distribution builders. They would need to build a seperate llvm 
version inside of the mesa package. Doable, but do you think we can convince 
them all?

The technical problem you try to solve is that we need to force the llvm build 
to have the default hidden visibility.
I think we could achieve the same result by using a default built llvm static 
lib and explicitly mention the to be exported symbols in a linker script. IIRC 
we could even use wildcards there. That is only export everything starting 
with MesaLLVM*.

Remains that we need to write out all the wrappers, which I called 'huge 
effort'.

May be this could equally well done by looking with scripts at the llvm 
libraries and create an apropriate version script. Hide all symbols, except 
the ones starting with MesaLLVM and for each LLVM c symbol create an alias 
with the apropriate MesaLLVM symbol. Requires some shell or python hackery to 
generate the version script given the llvm c binding library.

> > 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).
Ok.

> > Again OTOH, the dlopen flags are really made for this kind of module use I
> > think ...

I was referencing the patches that i just packed into the mail yesterday. This 
RTLD_LOCAL|RTLD_DEEPBIND flag already does what we need regarding isolation. 
This does not even require more changes than changing a bunch of dlopen flags - 
no wrappers to program.
What I am not sure about is if we isolate too much for mesa/dri internal needs 
with this.

> 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.
Huch, then I probably do not get you right.
Aren't you proposing a full wrapper of all the llvm c symbols by MesaLLVM* 
symbols above? Here you are calling exactly the same too limiting?

Greetings

Mathias

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


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

2013-04-25 Thread Jose Fonseca


- 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  

__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  
   ...

   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
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


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

2013-04-24 Thread Mathias Fröhlich

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.

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?

Again OTOH, the dlopen flags are really made for this kind of module use I 
think ...

Greetings

Mathias
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


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

2013-04-24 Thread Mathias Fröhlich

Hi,

On Wednesday, April 24, 2013 14:15:06 Tom Stellard wrote:
> I've thought about this some more, and I think that the best solution
> might be to move all LLVM API calls into gallivm and build it as a
> shared object with it's own private copy of LLVM statically linked.  This
> way we would still have a private copy of LLVM to work with, but without
> having to statically link every single gallium target with LLVM.  Any
> thoughts about this?
That should work as well.

As the test program shows, you would need to make sure that no llvm native api 
symbol is visible outside of this library. That means you baiscally have to 
build an own abstraction layer around llvm. Than you are safe for llvm at 
least.
More notes to that below.

> > For now, I have attached the patch series I mentioned regarding dlopen
> > flags which could be an other approach for this. I don't mind which
> > approach you really take in the end. Anyway this appears to work up to
> > now. It would have the advantage that it also helps other drivers beside
> > r600g with the llvm issues and it would help much further for all the non
> > static private symbols we have in the drivers. The series is running here
> > in my private tree since about half a year.
> 
> A few questions about the RTL_DEEPBIND patches:
> 
> 1. Does this only work for linux?
As far as I know yes.
At first even only glibc like targets.
So for android I don't know for example. And I don't have one available to 
look into at this moment.
Anyway, I think the desire to have a stronger seperation of dynamically loaded 
modules to be more independent of prebuilt binaries is there - especially on 
bsd license based userspaces. So I assume that you see more than just linux 
offering this or a similar flag. Sadly the times that I had access to all sorts 
of unices at work is gone.
So for example solaris10 has RTLD_GROUP which seems to be similar.

Which operating systems do we care for as of today? Is amds or intels list 
longer than the current list of systems for mesa?

> 2. Does RTL_DEEPBIND only make a difference if we are statically linking to
> LLVM?
As far as I understand this should also work for a shared llvm. You should 
really get an own instance of all the symbols in the shared object pulled by 
the .so you dlopen. This should include all statics and whatnot.

The limitation would be to make sure that the driver shared object finds the 
correct llvm libraries. In face of LD_LIBRARY_PATH or similar being set to 
something application defined you could still get the one provided by an 
application bringing its own one. This would still help for the thread safe 
initialization problem, but for this case you will never know which api 
version you are going to pull and if this might work.
But, if a (closed) application ships it's own llvm libraries - which is an 
appealing thought because of the still fast chaning llvm libraries - you can 
just run into this kind of problems with about any system library that pulls 
llvm under the hood. So this remaining problem is nothing we can really fix in 
mesa.
But you proposal with a libgalliumllvm abstraction helps for gallium based 
llvm clashes then, since the library file is called different than 
libllvmwhatevernativename.

In general, if you care for win32 targets with such a dynamic module 
structure, windows dynamic linking works somehow different than the linux one. 
But for this problem it's most notable that the default symbol visibility is 
set to hidden unless stated otherwise on win32. On *nix, you can see all 
symbols in a shared object unless explicitly marked hidden. So by default you 
get symbol clashes on *nix variants. But less of them on win32.
By your proposal with having a libgalliumllvm, statically linked with llvm and 
only exporting non llvm native symbol names you would have cought this problem 
already on win32.

Greetings

Mathias
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


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

2013-04-24 Thread Jose Fonseca
- Original Message -
> On Wed, Apr 24, 2013 at 09:40:44PM +0200, Mathias Fröhlich wrote:
> > 
> > Hi Tom,
> > 
> > On Tuesday, April 23, 2013 20:47:24 Tom Stellard wrote:
> > > First of all, thanks for investigating this.  The information you've
> > > provided has helped me a lot.
> > Good to hear that it helps.
> > 
> > > I took a shot at implementing it this way with private static copies of
> > > llvm.  I've pushed the initial work to this branch:
> > > git://people.freedesktop.org/~tstellar/mesa llvm-build
> > > 
> > > I was able to hide the LLVM symbols by using the --exclude-libs linker
> > > flag and so far I've tested with glxgears, an opencl example and also
> > > eglgears and they all work.  I still need to do some more testing, but
> > > any thoughts on what I've done so far in this branch?
> > 
> > I will look at this as soon as I find time. Probably not before the
> > beginning
> > of next week.
> > 
> 
> I've thought about this some more, and I think that the best solution
> might be to move all LLVM API calls into gallivm and build it as a
> shared object with it's own private copy of LLVM statically linked.  This way
> we
> would still have a private copy of LLVM to work with, but without having
> to statically link every single gallium target with LLVM.  Any thoughts
> about this?

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.

Jose
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


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

2013-04-24 Thread Tom Stellard
On Wed, Apr 24, 2013 at 09:40:44PM +0200, Mathias Fröhlich wrote:
> 
> Hi Tom,
> 
> On Tuesday, April 23, 2013 20:47:24 Tom Stellard wrote:
> > First of all, thanks for investigating this.  The information you've
> > provided has helped me a lot.
> Good to hear that it helps.
> 
> > I took a shot at implementing it this way with private static copies of
> > llvm.  I've pushed the initial work to this branch:
> > git://people.freedesktop.org/~tstellar/mesa llvm-build
> > 
> > I was able to hide the LLVM symbols by using the --exclude-libs linker
> > flag and so far I've tested with glxgears, an opencl example and also
> > eglgears and they all work.  I still need to do some more testing, but
> > any thoughts on what I've done so far in this branch?
> 
> I will look at this as soon as I find time. Probably not before the beginning 
> of next week.
> 

I've thought about this some more, and I think that the best solution
might be to move all LLVM API calls into gallivm and build it as a
shared object with it's own private copy of LLVM statically linked.  This way we
would still have a private copy of LLVM to work with, but without having
to statically link every single gallium target with LLVM.  Any thoughts
about this?

> For now, I have attached the patch series I mentioned regarding dlopen flags 
> which could be an other approach for this. I don't mind which approach you 
> really take in the end. Anyway this appears to work up to now. It would have 
> the advantage that it also helps other drivers beside r600g with the llvm 
> issues and it would help much further for all the non static private symbols 
> we have in the drivers. The series is running here in my private tree since 
> about half a year.
> 

A few questions about the RTL_DEEPBIND patches:

1. Does this only work for linux?

2. Does RTL_DEEPBIND only make a difference if we are statically linking to
LLVM?


> I have also done a testcase in piglit that shows the current problem with 
> r600g and llvm. To be really general we should put an other symbol there 
> instead of the llvm context initializer. But as a first test case you can 
> work 
> with, this should be sufficient. That one really fails with current 
> r600g/llvm 
> and works with the dlopen patch series. Consequently if you want to make sure 
> your branch works on a private llvm version, this test needs to pass also.
> 

This testcase is great, thanks.

-Tom

> Feel free to take and improove the provided patches.
> 
> Greetings
> 
> Mathias

> From 757a111221774703d558b5807e7465a026d6a3f8 Mon Sep 17 00:00:00 2001
> Message-Id: 
> <757a111221774703d558b5807e7465a026d6a3f8.1366832004.git.mathias.froehl...@gmx.net>
> From: Mathias Froehlich 
> Date: Wed, 24 Apr 2013 09:35:17 +0200
> Subject: [PATCH] Add test for driver private symbol isolation.
> 
> ---
>  tests/general/CMakeLists.gl.txt  |  5 
>  tests/general/driver-isolation-library.c | 36 ++
>  tests/general/driver-isolation.c | 51 
> 
>  3 files changed, 92 insertions(+)
>  create mode 100644 tests/general/driver-isolation-library.c
>  create mode 100644 tests/general/driver-isolation.c
> 
> diff --git a/tests/general/CMakeLists.gl.txt b/tests/general/CMakeLists.gl.txt
> index 0e87baa..6beb745 100644
> --- a/tests/general/CMakeLists.gl.txt
> +++ b/tests/general/CMakeLists.gl.txt
> @@ -81,6 +81,11 @@ piglit_add_executable (line-aa-width line-aa-width.c)
>  IF (UNIX)
>   target_link_libraries (line-aa-width m)
>  ENDIF (UNIX)
> +IF (UNIX)
> + add_library (driver-isolation-library SHARED driver-isolation-library.c)
> + piglit_add_executable (driver-isolation driver-isolation.c)
> + target_link_libraries (driver-isolation driver-isolation-library)
> +ENDIF (UNIX)
>  piglit_add_executable (longprim longprim.c)
>  piglit_add_executable (masked-clear masked-clear.c)
>  piglit_add_executable (pos-array pos-array.c)
> diff --git a/tests/general/driver-isolation-library.c 
> b/tests/general/driver-isolation-library.c
> new file mode 100644
> index 000..ef307a3
> --- /dev/null
> +++ b/tests/general/driver-isolation-library.c
> @@ -0,0 +1,36 @@
> +/*
> + * Copyright (c) 2013 Mathias Fröhlich.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * on the rights to use, copy, modify, merge, publish, distribute, sub
> + * license, and/or sell copies of the Software, and to permit persons to whom
> + * the Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> + * EXPRESS OR IMPLIED, INCLUDIN

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

2013-04-24 Thread Mathias Fröhlich

Hi Tom,

On Tuesday, April 23, 2013 20:47:24 Tom Stellard wrote:
> First of all, thanks for investigating this.  The information you've
> provided has helped me a lot.
Good to hear that it helps.

> I took a shot at implementing it this way with private static copies of
> llvm.  I've pushed the initial work to this branch:
> git://people.freedesktop.org/~tstellar/mesa llvm-build
> 
> I was able to hide the LLVM symbols by using the --exclude-libs linker
> flag and so far I've tested with glxgears, an opencl example and also
> eglgears and they all work.  I still need to do some more testing, but
> any thoughts on what I've done so far in this branch?

I will look at this as soon as I find time. Probably not before the beginning 
of next week.

For now, I have attached the patch series I mentioned regarding dlopen flags 
which could be an other approach for this. I don't mind which approach you 
really take in the end. Anyway this appears to work up to now. It would have 
the advantage that it also helps other drivers beside r600g with the llvm 
issues and it would help much further for all the non static private symbols 
we have in the drivers. The series is running here in my private tree since 
about half a year.

I have also done a testcase in piglit that shows the current problem with 
r600g and llvm. To be really general we should put an other symbol there 
instead of the llvm context initializer. But as a first test case you can work 
with, this should be sufficient. That one really fails with current r600g/llvm 
and works with the dlopen patch series. Consequently if you want to make sure 
your branch works on a private llvm version, this test needs to pass also.

Feel free to take and improove the provided patches.

Greetings

Mathias
>From 757a111221774703d558b5807e7465a026d6a3f8 Mon Sep 17 00:00:00 2001
Message-Id: <757a111221774703d558b5807e7465a026d6a3f8.1366832004.git.mathias.froehl...@gmx.net>
From: Mathias Froehlich 
Date: Wed, 24 Apr 2013 09:35:17 +0200
Subject: [PATCH] Add test for driver private symbol isolation.

---
 tests/general/CMakeLists.gl.txt  |  5 
 tests/general/driver-isolation-library.c | 36 ++
 tests/general/driver-isolation.c | 51 
 3 files changed, 92 insertions(+)
 create mode 100644 tests/general/driver-isolation-library.c
 create mode 100644 tests/general/driver-isolation.c

diff --git a/tests/general/CMakeLists.gl.txt b/tests/general/CMakeLists.gl.txt
index 0e87baa..6beb745 100644
--- a/tests/general/CMakeLists.gl.txt
+++ b/tests/general/CMakeLists.gl.txt
@@ -81,6 +81,11 @@ piglit_add_executable (line-aa-width line-aa-width.c)
 IF (UNIX)
 	target_link_libraries (line-aa-width m)
 ENDIF (UNIX)
+IF (UNIX)
+	add_library (driver-isolation-library SHARED driver-isolation-library.c)
+	piglit_add_executable (driver-isolation driver-isolation.c)
+	target_link_libraries (driver-isolation driver-isolation-library)
+ENDIF (UNIX)
 piglit_add_executable (longprim longprim.c)
 piglit_add_executable (masked-clear masked-clear.c)
 piglit_add_executable (pos-array pos-array.c)
diff --git a/tests/general/driver-isolation-library.c b/tests/general/driver-isolation-library.c
new file mode 100644
index 000..ef307a3
--- /dev/null
+++ b/tests/general/driver-isolation-library.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2013 Mathias Fröhlich.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT.  IN NO EVENT SHALL VMWARE AND/OR THEIR SUPPLIERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+void
+my_important_function()
+{
+}
+
+void*
+LLVMContextCreate()
+{
+	/* If we really get here, symbol isolation does not work.
+	 */
+	exit(-1);
+}
diff --git a/tests/general/driver-isolation.c b/tests/general/driver-isolation.c
new file mode 100644
index 000..ee81202
--- /dev/null
+++ b/tests/general/driver-isolation.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2013 Mathias Fröhlich.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining

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

2013-04-23 Thread Tom Stellard
On Sat, Apr 20, 2013 at 09:27:16AM +0200, Mathias Fröhlich wrote:
> 
> Hi Tom,
> 
> May be I need to tell where the problem really appears in real life.
> OpenSceneGraph has some nifty features regarding multi channel rendering.
> Assume a setup of multiple full screen views running on different graphics 
> boards into a single mashine composing a view into a single scene.
> Now the recommended way to do this with osg is to set up a X screen per 
> graphics board. Even if this spans multiple monitors/projectors. Set up a GL 
> graphics context per graphics board and set up a viewport per projector in 
> the 
> graphics contexts. Rendering happens now in parallel for each graphics 
> context. I do drive such a thing here with two radeons and three monitors for 
> testing and here the problem appears.
> 
> When I start the favourite flight simulation application of my choice with 
> this 
> setup, then it crashes almost immediately without llvm_start_multithreaded 
> being called. Wheres it works stable if we ensure llvm being multithreaded.
> 
> So, I tried to distill a piglit testcase out of this somehow huger setup with 
> flightgear, OpenSceneGraph, multiple gpu's and what not.
> 
> On Friday, April 19, 2013 20:08:54 Tom Stellard wrote:
> > On Wed, Apr 17, 2013 at 07:54:32AM +0200, Mathias Fröhlich wrote:
> > > Tom,
> > > 
> > > > -class LLVMEnsureMultithreaded {
> > > > -public:
> > > > -   LLVMEnsureMultithreaded()
> > > > -   {
> > > > -  llvm_start_multithreaded();
> > > > -   }
> > > > -};
> > > > -
> > > > -static LLVMEnsureMultithreaded lLVMEnsureMultithreaded;
> > > 
> > > Removing this leads to crashes in llvm with applications that concurrently
> > > work on different gl contexts.
> > 
> > The test you wrote still passes with this patch.  Do you see that
> > we are now calling the C API version of llvm_start_multithreaded(),
> > LLVMStartMutithreaded() from inside radeon_llvm_compile() protected by a
> > static variable?
> 
> Oh, no I did not see this. I did not realize that the 
> llvm_start_multithreaded 
> call is not just plain C. So I thought grepping for the call I used is 
> sufficient.
> 
> But negative. If I really apply your patch and try to run this with the above 
> setup I get the crashes. The same with the piglit test here.
> 
> Too bad, that reproducing races is racy for itself.
> With the piglit test I get about 2/3 of the runs either glibc memory 
> corruption aborts. Or one of the below asserts from llvm:
> 
> bool llvm::llvm_start_multithreaded(): Assertion `!multithreaded_mode && 
> "Already multithreaded!"' failed.
> 
> void 
> llvm::PassRegistry::removeRegistrationListener(llvm::PassRegistrationListener*):
>  
> Assertion `I != Impl->Listeners.end() && "PassRegistrationListener not 
> registered!"' failed.
> 
> bool llvm::sys::SmartMutex::release() [with bool mt_only = true]: 
> Assertion `((recursive && acquired) || (acquired == 1)) && "Lock not acquired 
> before release!"' failed.
> 
> So the biggest problem IIRC was that use of llvm::sys::SmartMutex 
> which is spread around here and there in llvm. The pass registry was (is?) 
> one 
> of the users for that. If you did not tell llvm to run multithreaded these 
> locks get noops and you concurrently access containers and that ...
> 
> Looking at the first assert, the llvm guys have made this problem even worse 
> IMO since I looked at this before. We need to check for multithreading being 
> enabled before trying to set this. Both of which being racy for itself in 
> this 
> way and all of them not being save against already happening llvm access from 
> an other thread and an other foreign use.
> 
> > Sorry about that. I didn't have piglit commit access at the time, and
> > I forgot about the patch.  I fixed a few things and sent v3 to the list.
> The same here. Thanks for this.
> 
> > > Regarding the point where this funciton is called I had choosen static
> > > initialization time since llvm requires this function to be called single
> > > threaded which we cannot guarantee in any case. Keep in mind that you need
> > > to ensure this function called non concurrently even against applications
> > > that itself already use the llvm libs in some way while the driver is
> > > loaded. But the best bet is to do this in the dynamic loder which is
> > > itself serialized, so I could avoid calling this function concurrently by
> > > initialization of different contexts. That should at least shield against
> > > applications that itself do the same trick by calling this funtion in the
> > > dlopen phase in some static initializer ...
> > > We may get around part of this problem with dlopening the driver with
> > > better isolation but up to now the problem can get that far.
> > 
> > This is a tricky problem, and I'm not sure that radeon_llvm_compile() is
> > the best place to call llvm_start_multithreaded().  Maybe it would be
> > better to move this into gallivm, because this problem could affect any
> > driver that uses 

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

2013-04-21 Thread Mathias Fröhlich

Hi all,

On Monday, April 22, 2013 00:39:57 Tom Stellard wrote:
[...]

The only pro for further investigating the dlopen flags is that I fear the 
distribution builders who invented dynamic linking in the drivers. That change 
destroyed symbol isolation in the drivers at that point. They will probably 
argue again about the memory footprint on disc and insist on using the 
distribution provided shared llvm at some point, which can only be solved then 
with the dlopen approach.

Tom, to untangle your patch in question from symbol isolation, I think if you 
put 

static void ensure_llvm_is_multithreaded() __attribute__ ((__constructor__));
void ensure_llvm_is_multithreaded()
{
   if (LLVMIsMultithreaded())
  return;
   LLVMStartMultithreaded();
}

into your new created c file, we should be no worse than we were before.

Regarding reproducing the problem at your site:
Does it help to increase the amount of concurrent context creations to a 
higher number than the now coded 100?

> > completely agree with Mathias here. I also suggested on IRC a couple of
> > weeks ago that libllvmradeon should definitely be static and hide all
> > internal symbols and only export those needed by the drivers. That
> > should isolate us mostly from the mess that comes with having multiple
> > LLVM instances (and probably also different versions) around at the same
> > time.
> 
> How would you recommend doing this?  Version scripts?
Probably yes.

Greetings and Thanks

Mathias
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


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

2013-04-21 Thread Tom Stellard
On Sat, Apr 20, 2013 at 02:20:23PM +0200, Christian König wrote:
> Am 20.04.2013 09:27, schrieb Mathias Fröhlich:
> > Hi Tom,
> >
> > May be I need to tell where the problem really appears in real life.
> > OpenSceneGraph has some nifty features regarding multi channel rendering.
> > Assume a setup of multiple full screen views running on different graphics
> > boards into a single mashine composing a view into a single scene.
> > Now the recommended way to do this with osg is to set up a X screen per
> > graphics board. Even if this spans multiple monitors/projectors. Set up a GL
> > graphics context per graphics board and set up a viewport per projector in 
> > the
> > graphics contexts. Rendering happens now in parallel for each graphics
> > context. I do drive such a thing here with two radeons and three monitors 
> > for
> > testing and here the problem appears.
> >
> > When I start the favourite flight simulation application of my choice with 
> > this
> > setup, then it crashes almost immediately without llvm_start_multithreaded
> > being called. Wheres it works stable if we ensure llvm being multithreaded.
> >
> > So, I tried to distill a piglit testcase out of this somehow huger setup 
> > with
> > flightgear, OpenSceneGraph, multiple gpu's and what not.
> >
> > On Friday, April 19, 2013 20:08:54 Tom Stellard wrote:
> >> On Wed, Apr 17, 2013 at 07:54:32AM +0200, Mathias Fröhlich wrote:
> >>> Tom,
> >>>
>  -class LLVMEnsureMultithreaded {
>  -public:
>  -   LLVMEnsureMultithreaded()
>  -   {
>  -  llvm_start_multithreaded();
>  -   }
>  -};
>  -
>  -static LLVMEnsureMultithreaded lLVMEnsureMultithreaded;
> >>> Removing this leads to crashes in llvm with applications that concurrently
> >>> work on different gl contexts.
> >> The test you wrote still passes with this patch.  Do you see that
> >> we are now calling the C API version of llvm_start_multithreaded(),
> >> LLVMStartMutithreaded() from inside radeon_llvm_compile() protected by a
> >> static variable?
> > Oh, no I did not see this. I did not realize that the 
> > llvm_start_multithreaded
> > call is not just plain C. So I thought grepping for the call I used is
> > sufficient.
> >
> > But negative. If I really apply your patch and try to run this with the 
> > above
> > setup I get the crashes. The same with the piglit test here.
> >
> > Too bad, that reproducing races is racy for itself.
> > With the piglit test I get about 2/3 of the runs either glibc memory
> > corruption aborts. Or one of the below asserts from llvm:
> >
> > bool llvm::llvm_start_multithreaded(): Assertion `!multithreaded_mode &&
> > "Already multithreaded!"' failed.
> >
> > void
> > llvm::PassRegistry::removeRegistrationListener(llvm::PassRegistrationListener*):
> > Assertion `I != Impl->Listeners.end() && "PassRegistrationListener not
> > registered!"' failed.
> >
> > bool llvm::sys::SmartMutex::release() [with bool mt_only = true]:
> > Assertion `((recursive && acquired) || (acquired == 1)) && "Lock not 
> > acquired
> > before release!"' failed.
> >
> > So the biggest problem IIRC was that use of llvm::sys::SmartMutex
> > which is spread around here and there in llvm. The pass registry was (is?) 
> > one
> > of the users for that. If you did not tell llvm to run multithreaded these
> > locks get noops and you concurrently access containers and that ...
> >
> > Looking at the first assert, the llvm guys have made this problem even worse
> > IMO since I looked at this before. We need to check for multithreading being
> > enabled before trying to set this. Both of which being racy for itself in 
> > this
> > way and all of them not being save against already happening llvm access 
> > from
> > an other thread and an other foreign use.
> >
> >> Sorry about that. I didn't have piglit commit access at the time, and
> >> I forgot about the patch.  I fixed a few things and sent v3 to the list.
> > The same here. Thanks for this.
> >
> >>> Regarding the point where this funciton is called I had choosen static
> >>> initialization time since llvm requires this function to be called single
> >>> threaded which we cannot guarantee in any case. Keep in mind that you need
> >>> to ensure this function called non concurrently even against applications
> >>> that itself already use the llvm libs in some way while the driver is
> >>> loaded. But the best bet is to do this in the dynamic loder which is
> >>> itself serialized, so I could avoid calling this function concurrently by
> >>> initialization of different contexts. That should at least shield against
> >>> applications that itself do the same trick by calling this funtion in the
> >>> dlopen phase in some static initializer ...
> >>> We may get around part of this problem with dlopening the driver with
> >>> better isolation but up to now the problem can get that far.
> >> This is a tricky problem, and I'm not sure that radeon_llvm_compile() is
> >> the best place to call llvm_start_mu

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

2013-04-20 Thread Christian König

Am 20.04.2013 09:27, schrieb Mathias Fröhlich:

Hi Tom,

May be I need to tell where the problem really appears in real life.
OpenSceneGraph has some nifty features regarding multi channel rendering.
Assume a setup of multiple full screen views running on different graphics
boards into a single mashine composing a view into a single scene.
Now the recommended way to do this with osg is to set up a X screen per
graphics board. Even if this spans multiple monitors/projectors. Set up a GL
graphics context per graphics board and set up a viewport per projector in the
graphics contexts. Rendering happens now in parallel for each graphics
context. I do drive such a thing here with two radeons and three monitors for
testing and here the problem appears.

When I start the favourite flight simulation application of my choice with this
setup, then it crashes almost immediately without llvm_start_multithreaded
being called. Wheres it works stable if we ensure llvm being multithreaded.

So, I tried to distill a piglit testcase out of this somehow huger setup with
flightgear, OpenSceneGraph, multiple gpu's and what not.

On Friday, April 19, 2013 20:08:54 Tom Stellard wrote:

On Wed, Apr 17, 2013 at 07:54:32AM +0200, Mathias Fröhlich wrote:

Tom,


-class LLVMEnsureMultithreaded {
-public:
-   LLVMEnsureMultithreaded()
-   {
-  llvm_start_multithreaded();
-   }
-};
-
-static LLVMEnsureMultithreaded lLVMEnsureMultithreaded;

Removing this leads to crashes in llvm with applications that concurrently
work on different gl contexts.

The test you wrote still passes with this patch.  Do you see that
we are now calling the C API version of llvm_start_multithreaded(),
LLVMStartMutithreaded() from inside radeon_llvm_compile() protected by a
static variable?

Oh, no I did not see this. I did not realize that the llvm_start_multithreaded
call is not just plain C. So I thought grepping for the call I used is
sufficient.

But negative. If I really apply your patch and try to run this with the above
setup I get the crashes. The same with the piglit test here.

Too bad, that reproducing races is racy for itself.
With the piglit test I get about 2/3 of the runs either glibc memory
corruption aborts. Or one of the below asserts from llvm:

bool llvm::llvm_start_multithreaded(): Assertion `!multithreaded_mode &&
"Already multithreaded!"' failed.

void
llvm::PassRegistry::removeRegistrationListener(llvm::PassRegistrationListener*):
Assertion `I != Impl->Listeners.end() && "PassRegistrationListener not
registered!"' failed.

bool llvm::sys::SmartMutex::release() [with bool mt_only = true]:
Assertion `((recursive && acquired) || (acquired == 1)) && "Lock not acquired
before release!"' failed.

So the biggest problem IIRC was that use of llvm::sys::SmartMutex
which is spread around here and there in llvm. The pass registry was (is?) one
of the users for that. If you did not tell llvm to run multithreaded these
locks get noops and you concurrently access containers and that ...

Looking at the first assert, the llvm guys have made this problem even worse
IMO since I looked at this before. We need to check for multithreading being
enabled before trying to set this. Both of which being racy for itself in this
way and all of them not being save against already happening llvm access from
an other thread and an other foreign use.


Sorry about that. I didn't have piglit commit access at the time, and
I forgot about the patch.  I fixed a few things and sent v3 to the list.

The same here. Thanks for this.


Regarding the point where this funciton is called I had choosen static
initialization time since llvm requires this function to be called single
threaded which we cannot guarantee in any case. Keep in mind that you need
to ensure this function called non concurrently even against applications
that itself already use the llvm libs in some way while the driver is
loaded. But the best bet is to do this in the dynamic loder which is
itself serialized, so I could avoid calling this function concurrently by
initialization of different contexts. That should at least shield against
applications that itself do the same trick by calling this funtion in the
dlopen phase in some static initializer ...
We may get around part of this problem with dlopening the driver with
better isolation but up to now the problem can get that far.

This is a tricky problem, and I'm not sure that radeon_llvm_compile() is
the best place to call llvm_start_multithreaded().  Maybe it would be
better to move this into gallivm, because this problem could affect any
driver that uses the gallivm code, which includes: llvmpipe, r300g, r600g,
radeonsi, and i915g.  What do you think?

Yep, an other place would be better.

I do not know the llvm tools well enough, but If I move the current c++ code
into src/gallium/auxiliary/gallivm/lp_bld_misc.cpp it works for me (TM).
Seriously, I know of one guy who wants to use llvmpipe with windows and he
would benefit from the c++ solution s

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

2013-04-20 Thread Mathias Fröhlich

Hi Tom,

May be I need to tell where the problem really appears in real life.
OpenSceneGraph has some nifty features regarding multi channel rendering.
Assume a setup of multiple full screen views running on different graphics 
boards into a single mashine composing a view into a single scene.
Now the recommended way to do this with osg is to set up a X screen per 
graphics board. Even if this spans multiple monitors/projectors. Set up a GL 
graphics context per graphics board and set up a viewport per projector in the 
graphics contexts. Rendering happens now in parallel for each graphics 
context. I do drive such a thing here with two radeons and three monitors for 
testing and here the problem appears.

When I start the favourite flight simulation application of my choice with this 
setup, then it crashes almost immediately without llvm_start_multithreaded 
being called. Wheres it works stable if we ensure llvm being multithreaded.

So, I tried to distill a piglit testcase out of this somehow huger setup with 
flightgear, OpenSceneGraph, multiple gpu's and what not.

On Friday, April 19, 2013 20:08:54 Tom Stellard wrote:
> On Wed, Apr 17, 2013 at 07:54:32AM +0200, Mathias Fröhlich wrote:
> > Tom,
> > 
> > > -class LLVMEnsureMultithreaded {
> > > -public:
> > > -   LLVMEnsureMultithreaded()
> > > -   {
> > > -  llvm_start_multithreaded();
> > > -   }
> > > -};
> > > -
> > > -static LLVMEnsureMultithreaded lLVMEnsureMultithreaded;
> > 
> > Removing this leads to crashes in llvm with applications that concurrently
> > work on different gl contexts.
> 
> The test you wrote still passes with this patch.  Do you see that
> we are now calling the C API version of llvm_start_multithreaded(),
> LLVMStartMutithreaded() from inside radeon_llvm_compile() protected by a
> static variable?

Oh, no I did not see this. I did not realize that the llvm_start_multithreaded 
call is not just plain C. So I thought grepping for the call I used is 
sufficient.

But negative. If I really apply your patch and try to run this with the above 
setup I get the crashes. The same with the piglit test here.

Too bad, that reproducing races is racy for itself.
With the piglit test I get about 2/3 of the runs either glibc memory 
corruption aborts. Or one of the below asserts from llvm:

bool llvm::llvm_start_multithreaded(): Assertion `!multithreaded_mode && 
"Already multithreaded!"' failed.

void 
llvm::PassRegistry::removeRegistrationListener(llvm::PassRegistrationListener*):
 
Assertion `I != Impl->Listeners.end() && "PassRegistrationListener not 
registered!"' failed.

bool llvm::sys::SmartMutex::release() [with bool mt_only = true]: 
Assertion `((recursive && acquired) || (acquired == 1)) && "Lock not acquired 
before release!"' failed.

So the biggest problem IIRC was that use of llvm::sys::SmartMutex 
which is spread around here and there in llvm. The pass registry was (is?) one 
of the users for that. If you did not tell llvm to run multithreaded these 
locks get noops and you concurrently access containers and that ...

Looking at the first assert, the llvm guys have made this problem even worse 
IMO since I looked at this before. We need to check for multithreading being 
enabled before trying to set this. Both of which being racy for itself in this 
way and all of them not being save against already happening llvm access from 
an other thread and an other foreign use.

> Sorry about that. I didn't have piglit commit access at the time, and
> I forgot about the patch.  I fixed a few things and sent v3 to the list.
The same here. Thanks for this.

> > Regarding the point where this funciton is called I had choosen static
> > initialization time since llvm requires this function to be called single
> > threaded which we cannot guarantee in any case. Keep in mind that you need
> > to ensure this function called non concurrently even against applications
> > that itself already use the llvm libs in some way while the driver is
> > loaded. But the best bet is to do this in the dynamic loder which is
> > itself serialized, so I could avoid calling this function concurrently by
> > initialization of different contexts. That should at least shield against
> > applications that itself do the same trick by calling this funtion in the
> > dlopen phase in some static initializer ...
> > We may get around part of this problem with dlopening the driver with
> > better isolation but up to now the problem can get that far.
> 
> This is a tricky problem, and I'm not sure that radeon_llvm_compile() is
> the best place to call llvm_start_multithreaded().  Maybe it would be
> better to move this into gallivm, because this problem could affect any
> driver that uses the gallivm code, which includes: llvmpipe, r300g, r600g,
> radeonsi, and i915g.  What do you think?

Yep, an other place would be better.

I do not know the llvm tools well enough, but If I move the current c++ code 
into src/gallium/auxiliary/gallivm/lp_bld_misc.cpp it works f

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

2013-04-19 Thread Tom Stellard
On Wed, Apr 17, 2013 at 07:54:32AM +0200, Mathias Fröhlich wrote:
> 
> Tom,
> 
> > -class LLVMEnsureMultithreaded {
> > -public:
> > -   LLVMEnsureMultithreaded()
> > -   {
> > -  llvm_start_multithreaded();
> > -   }
> > -};
> > -
> > -static LLVMEnsureMultithreaded lLVMEnsureMultithreaded;
> 
> Removing this leads to crashes in llvm with applications that concurrently 
> work on different gl contexts.

The test you wrote still passes with this patch.  Do you see that
we are now calling the C API version of llvm_start_multithreaded(),
LLVMStartMutithreaded() from inside radeon_llvm_compile() protected by a
static variable?

> 
> When I did this change I also provided a testcase that never made it into 
> piglit. See:
> http://lists.freedesktop.org/archives/piglit/2012-August/003100.html
> I had addresssed the concerns at that time with a v2 patch but got lost 
> without being checked in. May be somebody can push this now?
>

Sorry about that. I didn't have piglit commit access at the time, and
I forgot about the patch.  I fixed a few things and sent v3 to the list.
 
> Regarding the point where this funciton is called I had choosen static 
> initialization time since llvm requires this function to be called single 
> threaded which we cannot guarantee in any case. Keep in mind that you need to 
> ensure this function called non concurrently even against applications that 
> itself already use the llvm libs in some way while the driver is loaded.
> But the best bet is to do this in the dynamic loder which is itself 
> serialized, so I could avoid calling this function concurrently by 
> initialization of different contexts. That should at least shield against 
> applications that itself do the same trick by calling this funtion in the 
> dlopen phase in some static initializer ...
> We may get around part of this problem with dlopening the driver with better 
> isolation but up to now the problem can get that far.
> 

This is a tricky problem, and I'm not sure that radeon_llvm_compile() is
the best place to call llvm_start_multithreaded().  Maybe it would be
better to move this into gallivm, because this problem could affect any
driver that uses the gallivm code, which includes: llvmpipe, r300g, r600g,
radeonsi, and i915g.  What do you think?

-Tom

> You can find more thoughts about that problem regarding llvmpipe which still 
> has this problem is written down here:
> http://lists.freedesktop.org/archives/mesa-dev/2013-January/033015.html
> 
> So, a better place where you can switch llvm to be multithreaded is 
> apprecheated. But please make sure it happens at some point, the earlier, the 
> better.
> 
> If you want to have plain c files that behaves the same like what we have 
> today 
> you can use a gcc extension (untested):
> 
> static void r600_llvm_init() __attribute__ ((__constructor__));
> void r600_llvm_init()
> {
>   llvm_start_multithreaded();
> }
> 
> Greetings
> 
> Mathias
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


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

2013-04-17 Thread Christian König

Am 17.04.2013 01:13, schrieb Tom Stellard:

From: Tom Stellard 

The LLVM C API is considered stable and should never change, so it
is much more desirable to use than the LLVM C++ API, which is constantly in
flux.


Looks good on first glance, but I would separate the initialization and 
finding the correct target machine into their own functions.


Also I would guess that we need to destroy the target machine after use, 
cause in the C++ version that was an autoptr.


Christian.


---
  src/gallium/drivers/radeon/Makefile.am  |   2 -
  src/gallium/drivers/radeon/Makefile.sources |   4 +-
  src/gallium/drivers/radeon/radeon_llvm_emit.c   | 150 ++
  src/gallium/drivers/radeon/radeon_llvm_emit.cpp | 193 
  src/gallium/drivers/radeon/radeon_llvm_emit.h   |  14 --
  5 files changed, 151 insertions(+), 212 deletions(-)
  create mode 100644 src/gallium/drivers/radeon/radeon_llvm_emit.c
  delete mode 100644 src/gallium/drivers/radeon/radeon_llvm_emit.cpp

diff --git a/src/gallium/drivers/radeon/Makefile.am 
b/src/gallium/drivers/radeon/Makefile.am
index 6522598..9b4255e 100644
--- a/src/gallium/drivers/radeon/Makefile.am
+++ b/src/gallium/drivers/radeon/Makefile.am
@@ -27,7 +27,6 @@ endif
  
  libllvmradeon@VERSION@_la_CXXFLAGS = \

$(GALLIUM_CFLAGS) \
-   $(filter-out -DDEBUG, $(LLVM_CXXFLAGS)) \
$(DEFINES)
  
  libllvmradeon@VERSION@_la_CFLAGS = \

@@ -35,7 +34,6 @@ libllvmradeon@VERSION@_la_CFLAGS = \
$(LLVM_CFLAGS)
  
  libllvmradeon@VERSION@_la_SOURCES = \

-   $(LLVM_CPP_FILES) \
$(LLVM_C_FILES)
  
  libllvmradeon@VERSION@_la_LIBADD = \

diff --git a/src/gallium/drivers/radeon/Makefile.sources 
b/src/gallium/drivers/radeon/Makefile.sources
index a23d5c4..d33c81b 100644
--- a/src/gallium/drivers/radeon/Makefile.sources
+++ b/src/gallium/drivers/radeon/Makefile.sources
@@ -1,9 +1,7 @@
  C_SOURCES := \
radeon_uvd.c
  
-LLVM_CPP_FILES := \

-   radeon_llvm_emit.cpp
-
  LLVM_C_FILES := \
radeon_setup_tgsi_llvm.c \
+   radeon_llvm_emit.c \
radeon_llvm_util.c
diff --git a/src/gallium/drivers/radeon/radeon_llvm_emit.c 
b/src/gallium/drivers/radeon/radeon_llvm_emit.c
new file mode 100644
index 000..d25b962
--- /dev/null
+++ b/src/gallium/drivers/radeon/radeon_llvm_emit.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
THE
+ * SOFTWARE.
+ *
+ * Authors: Tom Stellard 
+ *
+ */
+#include "radeon_llvm_emit.h"
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CPU_STRING_LEN 30
+#define FS_STRING_LEN 30
+#define TRIPLE_STRING_LEN 7
+
+/**
+ * Set the shader type we want to compile
+ *
+ * @param type shader type to set
+ */
+void radeon_llvm_shader_type(LLVMValueRef F, unsigned type)
+{
+  char Str[2];
+  sprintf(Str, "%1d", type);
+
+  LLVMAddTargetDependentFunctionAttr(F, "ShaderType", Str);
+}
+
+/**
+ * Compile an LLVM module to machine code.
+ *
+ * @param bytes This function allocates memory for the byte stream, it is the
+ * caller's responsibility to free it.
+ */
+unsigned radeon_llvm_compile(LLVMModuleRef M, struct radeon_llvm_binary 
*binary,
+ const char * gpu_family, unsigned 
dump) {
+
+   static unsigned initialized = 0;
+   LLVMTargetRef target;
+   LLVMTargetMachineRef tm;
+   char cpu[CPU_STRING_LEN];
+   char fs[FS_STRING_LEN];
+   char *err;
+   LLVMMemoryBufferRef out_buffer;
+   unsigned buffer_size;
+   const char *buffer_data;
+   char triple[TRIPLE_STRING_LEN];
+   char *elf_buffer;
+   Elf *elf;
+   Elf_Scn *section = NULL;
+   size_t section_str_index;
+   int r;
+
+   if (!initialized) {
+   LLVMInitializeR600TargetInfo();
+   LLVMInitializeR600Target();
+   LLVMInitializeR600

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

2013-04-16 Thread Mathias Fröhlich

Tom,

> -class LLVMEnsureMultithreaded {
> -public:
> -   LLVMEnsureMultithreaded()
> -   {
> -  llvm_start_multithreaded();
> -   }
> -};
> -
> -static LLVMEnsureMultithreaded lLVMEnsureMultithreaded;

Removing this leads to crashes in llvm with applications that concurrently 
work on different gl contexts.

When I did this change I also provided a testcase that never made it into 
piglit. See:
http://lists.freedesktop.org/archives/piglit/2012-August/003100.html
I had addresssed the concerns at that time with a v2 patch but got lost 
without being checked in. May be somebody can push this now?

Regarding the point where this funciton is called I had choosen static 
initialization time since llvm requires this function to be called single 
threaded which we cannot guarantee in any case. Keep in mind that you need to 
ensure this function called non concurrently even against applications that 
itself already use the llvm libs in some way while the driver is loaded.
But the best bet is to do this in the dynamic loder which is itself 
serialized, so I could avoid calling this function concurrently by 
initialization of different contexts. That should at least shield against 
applications that itself do the same trick by calling this funtion in the 
dlopen phase in some static initializer ...
We may get around part of this problem with dlopening the driver with better 
isolation but up to now the problem can get that far.

You can find more thoughts about that problem regarding llvmpipe which still 
has this problem is written down here:
http://lists.freedesktop.org/archives/mesa-dev/2013-January/033015.html

So, a better place where you can switch llvm to be multithreaded is 
apprecheated. But please make sure it happens at some point, the earlier, the 
better.

If you want to have plain c files that behaves the same like what we have today 
you can use a gcc extension (untested):

static void r600_llvm_init() __attribute__ ((__constructor__));
void r600_llvm_init()
{
  llvm_start_multithreaded();
}

Greetings

Mathias
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


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

2013-04-16 Thread Tom Stellard
From: Tom Stellard 

The LLVM C API is considered stable and should never change, so it
is much more desirable to use than the LLVM C++ API, which is constantly in
flux.
---
 src/gallium/drivers/radeon/Makefile.am  |   2 -
 src/gallium/drivers/radeon/Makefile.sources |   4 +-
 src/gallium/drivers/radeon/radeon_llvm_emit.c   | 150 ++
 src/gallium/drivers/radeon/radeon_llvm_emit.cpp | 193 
 src/gallium/drivers/radeon/radeon_llvm_emit.h   |  14 --
 5 files changed, 151 insertions(+), 212 deletions(-)
 create mode 100644 src/gallium/drivers/radeon/radeon_llvm_emit.c
 delete mode 100644 src/gallium/drivers/radeon/radeon_llvm_emit.cpp

diff --git a/src/gallium/drivers/radeon/Makefile.am 
b/src/gallium/drivers/radeon/Makefile.am
index 6522598..9b4255e 100644
--- a/src/gallium/drivers/radeon/Makefile.am
+++ b/src/gallium/drivers/radeon/Makefile.am
@@ -27,7 +27,6 @@ endif
 
 libllvmradeon@VERSION@_la_CXXFLAGS = \
$(GALLIUM_CFLAGS) \
-   $(filter-out -DDEBUG, $(LLVM_CXXFLAGS)) \
$(DEFINES)
 
 libllvmradeon@VERSION@_la_CFLAGS = \
@@ -35,7 +34,6 @@ libllvmradeon@VERSION@_la_CFLAGS = \
$(LLVM_CFLAGS)
 
 libllvmradeon@VERSION@_la_SOURCES = \
-   $(LLVM_CPP_FILES) \
$(LLVM_C_FILES)
 
 libllvmradeon@VERSION@_la_LIBADD = \
diff --git a/src/gallium/drivers/radeon/Makefile.sources 
b/src/gallium/drivers/radeon/Makefile.sources
index a23d5c4..d33c81b 100644
--- a/src/gallium/drivers/radeon/Makefile.sources
+++ b/src/gallium/drivers/radeon/Makefile.sources
@@ -1,9 +1,7 @@
 C_SOURCES := \
radeon_uvd.c
 
-LLVM_CPP_FILES := \
-   radeon_llvm_emit.cpp
-
 LLVM_C_FILES := \
radeon_setup_tgsi_llvm.c \
+   radeon_llvm_emit.c \
radeon_llvm_util.c
diff --git a/src/gallium/drivers/radeon/radeon_llvm_emit.c 
b/src/gallium/drivers/radeon/radeon_llvm_emit.c
new file mode 100644
index 000..d25b962
--- /dev/null
+++ b/src/gallium/drivers/radeon/radeon_llvm_emit.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
THE
+ * SOFTWARE.
+ *
+ * Authors: Tom Stellard 
+ *
+ */
+#include "radeon_llvm_emit.h"
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CPU_STRING_LEN 30
+#define FS_STRING_LEN 30
+#define TRIPLE_STRING_LEN 7
+
+/**
+ * Set the shader type we want to compile
+ *
+ * @param type shader type to set
+ */
+void radeon_llvm_shader_type(LLVMValueRef F, unsigned type)
+{
+  char Str[2];
+  sprintf(Str, "%1d", type);
+
+  LLVMAddTargetDependentFunctionAttr(F, "ShaderType", Str);
+}
+
+/**
+ * Compile an LLVM module to machine code.
+ *
+ * @param bytes This function allocates memory for the byte stream, it is the
+ * caller's responsibility to free it.
+ */
+unsigned radeon_llvm_compile(LLVMModuleRef M, struct radeon_llvm_binary 
*binary,
+ const char * gpu_family, unsigned 
dump) {
+
+   static unsigned initialized = 0;
+   LLVMTargetRef target;
+   LLVMTargetMachineRef tm;
+   char cpu[CPU_STRING_LEN];
+   char fs[FS_STRING_LEN];
+   char *err;
+   LLVMMemoryBufferRef out_buffer;
+   unsigned buffer_size;
+   const char *buffer_data;
+   char triple[TRIPLE_STRING_LEN];
+   char *elf_buffer;
+   Elf *elf;
+   Elf_Scn *section = NULL;
+   size_t section_str_index;
+   int r;
+
+   if (!initialized) {
+   LLVMInitializeR600TargetInfo();
+   LLVMInitializeR600Target();
+   LLVMInitializeR600TargetMC();
+   LLVMInitializeR600AsmPrinter();
+   if (!LLVMIsMultithreaded()) {
+   LLVMStartMultithreaded();
+   }
+   initialized = 1;
+   }
+
+   for (target = LLVMGetFirstTarget(); target;
+   target = LLVMGetNextTarget(targ