LLVM and XC Topic is solved

Technical questions regarding the XTC tools and programming with XMOS.
Guest

LLVM and XC

Post by Guest »

I'm experimenting with LLVM's XCore backend, and I've managed to get LLVM to generate ASM I can assemble with xcc.

I'm looking for a way to get LLVM IR from the new LLVM-based XC compiler. I'd like to see how to use XC's special features in LLVM beyond the intrinsics minimally documented in these slides. LLVM IR would also be useful for inlining prewritten XC functions as "instructions" as this tutorial shows.

It looks like xcc 12.0.0beta1 has some kind of special case for clang's `-emit-llvm` option, since it gives an error for a different flag than the one passed:

Code: Select all

xcc src/main.xc -target=XK-1A -emit-llvm -o main.ll
xcc1: error: unrecognized command line option "-emit-llvm-bc"
but I can't get either one of those options to actually do anything.

Is the source code of the new LLVM XC compiler available somewhere? http://www.xmos.com/products/design-tools-source doesn't have anything 12.0.


View Solution
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

Oh my, I completely forgot what LLVM is capable of, those links offer some tantalising usage scenarios that could be really helpful for a project I am working on next year. This has really got me thinking about a much better way to solve my problems using the JIT and intrinsics etc..

Would love to see how much we can dig into LLVM features to use this kind of functionality.


regards
Al
richard
Respected Member
Posts: 318
Joined: Tue Dec 15, 2009 12:46 am

Post by richard »

Hi Kevin,

The option -emit-llvm is a recognised by the frontend but it is only enabled in internal debug builds, sorry.

Are you able to provide more details about what you want to do? I can try and write some documentation / put together examples showing how you can target the intrinsics we've added to LLVM if I know which bits you are interested in.

The source code for the LLVM XC compiler frontend (i.e. the bit that parses / checks XC source code and converts it to LLVM IR) is not available. The source code for the LLVM XC compiler backend (LLVM optimization passes and xCORE codgen) is available from the page you linked if you click on the LLVM. The fact that the source code for 12.0.0 hasn't been uploaded there is an oversight - I'll chase this up.
richard
Respected Member
Posts: 318
Joined: Tue Dec 15, 2009 12:46 am

Post by richard »

Folknology wrote:This has really got me thinking about a much better way to solve my problems using the JIT and intrinsics etc..
You can't compile LLVM for the xCORE as it won't fit in memory. As such using LLVM as a JIT on the xCORE isn't really feasible. You could JIT the code on a host machine and squirt that over to the xCORE, but I'm not sure how useful that would be.
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

richard wrote:
Folknology wrote:This has really got me thinking about a much better way to solve my problems using the JIT and intrinsics etc..
You can't compile LLVM for the xCORE as it won't fit in memory. As such using LLVM as a JIT on the xCORE isn't really feasible. You could JIT the code on a host machine and squirt that over to the xCORE, but I'm not sure how useful that would be.
Sure I guessed as much, and was envisaging it Jiting on the host rather than xcore itself.

Is it possible to host and compile for xcore on Arm (linux based) by the way, this would be really handy?

regards
Al
richard
Respected Member
Posts: 318
Joined: Tue Dec 15, 2009 12:46 am

Post by richard »

Folknology wrote:Is it possible to host and compile for xcore on Arm (linux based) by the way, this would be really handy?
You can certainly build LLVM on ARM so I see no reason why this wouldn't work.
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

richard wrote:
Folknology wrote:Is it possible to host and compile for xcore on Arm (linux based) by the way, this would be really handy?
You can certainly build LLVM on ARM so I see no reason why this wouldn't work.
I figured as much (after all its pretty important platform for Apple!) But the question is how I would go about assembling an ARM cross LLVM for xcore given you are not providing sources. Could you provide binaries for such purposes for example, or is there some intermediary way to achieve it?

regards
Al
Guest

Post by Guest »

richard wrote: The option -emit-llvm is a recognised by the frontend but it is only enabled in internal debug builds, sorry.
Please consider enabling -emit-llvm in future release builds. It's how compilers play nice with the LLVM ecosystem. For me, at least, LLVM support is a big selling point.
richard wrote: Are you able to provide more details about what you want to do? I can try and write some documentation / put together examples showing how you can target the intrinsics we've added to LLVM if I know which bits you are interested in.
I'm working on a product in which user-supplied serial protocols and signal processing are compiled and run on a microcontroller. We're looking at XMOS parts because of their IO capabilities, threads, and LLVM backend. Implementation-wise, the host will compile code with LLVM that will be sent to the device and run in its own XMOS thread or core and communicate with services written in XC over channels.

So, more specifically, how to communicate with XC-compatible channels, and more details on `select{}` (default clause, contitional inputs, timed inputs). Looks like port IO is documented in the architecture manual if there are intrinsics for all the relevant instructions.

Eventually, I'll need to be able to codegen and link the module so it can be loaded into RAM and run as a thread, but for development, I can just link it into the .xe with XMOS tools. I think run-time loading will require getting any calls into XC code inlined or included into the LLVM module so it doesn't need a dynamic linker, so that's where -emit-llvm would be extremely handy.
Folknology wrote: I figured as much (after all its pretty important platform for Apple!) But the question is how I would go about assembling an ARM cross LLVM for xcore given you are not providing sources. Could you provide binaries for such purposes for example, or is there some intermediary way to achieve it?
I've been using mainline LLVM 3.1, which comes with xCORE support by default. Richard, does mainline differ significantly from what you use in xcc 12 / xcc 11 / have on the open source page? I haven't done more than hello world and some math, so if the XMOS intrinsics are totally broken there, I wouldn't know yet.
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

Assuming XC isn't available (unless there are ways of providing binaries/source) I would like to be able to do the equivalent of selects/switches with non arrayed unique resources and labels, C based select functions, port,timer and channel selection and config, as a bonus logical core/thread spawning would also be nice from C/C++. There are prob a good few of the intrinsics in xs1.h that get ifdef'd out I would also like access to. So as much documentation as possible for me really, although I still personally have a long way to go getting my head around LLVM first.

regards
Al
richard
Respected Member
Posts: 318
Joined: Tue Dec 15, 2009 12:46 am

Post by richard »

kevinm wrote:Please consider enabling -emit-llvm in future release builds. It's how compilers play nice with the LLVM ecosystem. For me, at least, LLVM support is a big selling point.
I discussed this with some people here and I don't think there is a problem enabling this option in future. In the meantime you can get the same effect using: xcc test.xc -mllvm -print-before=verify -c
kevinm wrote:I'm working on a product in which user-supplied serial protocols and signal processing are compiled and run on a microcontroller. We're looking at XMOS parts because of their IO capabilities, threads, and LLVM backend. Implementation-wise, the host will compile code with LLVM that will be sent to the device and run in its own XMOS thread or core and communicate with services written in XC over channels.

So, more specifically, how to communicate with XC-compatible channels, and more details on `select{}` (default clause, contitional inputs, timed inputs). Looks like port IO is documented in the architecture manual if there are intrinsics for all the relevant instructions.
If you have read the architecture manual you are most of the way to understanding the intrinsics - the majority map directly to individual instructions. The main exceptions to this are the llvm.xcore.waitevent() and llvm.xcore.checkevent() instrinsics that are used to implement XC's select statement. Conceptually llvm.xcore.waitevent() enables events and returns the address of the vector (set with llvm.xcore.setv) of the resource that is ready. If no resources are ready it will wait until a resource becomes ready. The result of the intrinsic must be used as the operand of an indirect branch. When the backend generates code it enables events but doesn't emit a branch instruction - the branch is done in hardware when the event is taken.

The llvm.xcore.checkevent() is simlar except that if no resources are ready it returns immediately. The value to return if no resources are ready is given as an operand to the instrinsic - this corresponds to a default case in a select in XC.

There is a very basic example that uses these intrinsics in the LLVM testsuite (test/CodeGen/XCore/events.ll).
kevinm wrote:Eventually, I'll need to be able to codegen and link the module so it can be loaded into RAM and run as a thread, but for development, I can just link it into the .xe with XMOS tools. I think run-time loading will require getting any calls into XC code inlined or included into the LLVM module so it doesn't need a dynamic linker, so that's where -emit-llvm would be extremely handy.
Do you need the backend to emit binary code directly (i.e. without an external assembler)? Currently this isn't supported and the XCoreInstructionInfo.td file don't specify any instruction encoding information. This something I'd like to fix for another reason (I'd like to generate a dissassembler to replace some hand written code in https://github.com/rlsosborne/tool_axe), but I'm not sure when I'll get time to do this.
kevinm wrote:I've been using mainline LLVM 3.1, which comes with xCORE support by default. Richard, does mainline differ significantly from what you use in xcc 12 / xcc 11 / have on the open source page? I haven't done more than hello world and some math, so if the XMOS intrinsics are totally broken there, I wouldn't know yet.
Yes they do differ. We make releases from our own internal branch of LLVM - this allows us to have stability prior to a tools release in cases where LLVM's release schedule doesn't match up with our own. We periodically merge in changes from the upstream and periodically submit patches back to minimize the difference between the two branches. What is present upstream should work - If you anything that doesn't then please submit bugs on llvm.org so I can take a look. However there are a few features that are missing upstream:

* Support for passing XTA information through the compiler.
* Some optimization passes that specificly target xCORE resource intrinsics.
* Support for emitting linker expressions describing maximum resource usage.

There will also be some things missing the other way since our internal branch is currently based off an older version of LLVM (LLVM 3.0). In general I would encourage people to use mainline LLVM if possible as the presence of a public bug trackers, mailing lists and repositories makes collaborating a lot easier.