[LLVMdev] Endian Emulation Help

Herbie Robinson hrob at curbside-recording.com
Tue Jan 27 09:00:19 PST 2015


I've been working on a little home project to port llvm/clang to the 
Stratus VOS operating system.  So far, it's been pretty straightforward, 
but I have hit an area where I could use some advice.

The biggest issue with a VOS port is the compilers are expected to 
always present a big endian view of memory to the programmer.  There are 
a number of reasons we do that, but the over-riding one is that we are a 
high availability company and have customers who run 24/7. Even when 
upgrading to new hardware, the customers expect to only be down for a 
few minutes.  This doesn't allow for converting large databases from big 
endian to little endian.  Also, it turns out that doing endian emulation 
is only about a 10% performance hit when optimized appropriately.  This 
is often acceptable just to avoid a lot of software maintenance.

I am doing the endian emulation by writing a function pass to insert 
bswap intrinsics for scalars and shuffles for vectors (with the 
appropriate casting).  The LLVM IR is an amazingly good fit for this, BTW.

I thought I was just about done -- all I had left was dealing with the 
initialization (and some function pointer issues, but that's another 
story).  That's where things get interesting.  Integers aren't a 
problem, but I have to be able to emit ELF for byte swapped relocatable 
pointers (VOS extensions) in GlobalVariable initialization.  It also 
seemed unwise to mess with byte swapping floating point constants until 
they actually get emitted.

It looks to me like the best way to represent this is to represent the 
bswap as a constant expression.  Am I on the right track there?

If I am going to do that, there would be three approaches:

A.  Cast everything as a vector of i8 and use the shuffle constant 
expression operator.  The catch is that instruction doesn't appear to be 
supported everywhere (in particular ExecutionEngine.cpp).  It will also 
make constant propagation harder, because one should turn some of the 
shuffles into bswaps when transforming constant expressions into 
instructions.

B.  Add a new constant expression subclass that will bswap any first 
class type.  This might  well be too disruptive.  Also, it has the same 
problem with constant propagation.

C.  Use shifts and masks.  Except they also aren't implemented 
everywhere.  And there is the same problem with constant propagation.

D.  Implement the BSWAP intrinsic in constant expressions (with the call 
instruction limited to just intrinsics when used in constant 
expressions).  I like this, because it parallels the instruction IR and 
this looks like it mostly just works in the constant folding code.

Any advice here?

TIA
Herbie Robinson



More information about the llvm-dev mailing list