[ Content | Sidebar ]

Archives for May, 2017

Another Failed Circumnavigation

May 30th, 2017

A few weekends ago I tried a second time to do a full circumnavigation of High Wycombe, having not quite achieved it back in 2015. Success would be going in a big circle without cutting through any built-up area.

But the weather was a bit miserable and I discovered the bit I cut out last time was interminably dull. So I gave up after 18 miles. One day…

Oriental Pearl Tower

May 28th, 2017

Just one more China post! The evening before I flew home I finally managed to take a half-decent photo of the Oriental Pearl Tower in Shanghai. It’s much more interesting to visit the Pudong area at night instead of in the day. A lot of buildings have cool light shows, but not as impressive or coordinated as in Hong Kong.

Anchang

May 24th, 2017

Anchang 安昌 is a delightful little water town just north of Shaoxing. I went there on a sunny Saturday and it was quite busy, but not crammed. You can get there easily from Shaoxing by taking the regular public bus number 118. It takes around one hour.

The town is very similar to Tongli which I visited around the same time last year. Instead of roads they have canals everywhere and these traditional low whitewashed buildings. Like so many of these “scenic spots” in China you buy a single ticket which lets you get into a variety of attractions like old houses, a 1920s bank, a temple, and so on. And then you spend the whole day strolling around peering at stuff and taking photos. It’s basically my ideal day out, as you might have gathered from this blog recently.

For lunch I had this appetising plate of 田螺 which I think is “river snail” in English. The lady in the restaurant was very keen for me to try it. And then she took a photo of me, which was a bit odd. The toothpick it seems is the standard method to extract them out from their shells. Hm. Anyway I washed it down with some 黄酒 which is the famous “Shaoxing rice wine” that comes from these parts, and also available in your local Tesco.

Shaoxing

May 16th, 2017

And now as Michael Bolton might say, back to the good part. You might, wrongly, think this was part of my previous Chinese adventuring but actually I came back to the UK for a month and then work asked me to go back to Suzhou again for another week. So I dutifully did and after that was over went to Shaoxing in Zhejiang for a long weekend. One of the great things about business trips to China is you’re never short of new places to go on excursions. Unlike say, *cough* Norway *cough*.

Shaoxing canals

Shaoxing reminds me a lot of the older parts of Suzhou. It’s got the same white washed architecture and canals everywhere instead of roads. But it’s quieter, in a good way, and a lot less commercialised.

I didn’t actually spend that much time in the city itself, because I took all of Saturday to go out for a day trip. But I visited the most important site, or at least the one everyone told me to go to, Lu Xun’s birthplace. I hadn’t heard of him either, but he’s a famous early 20th century writer.

Suspicious character posing with Lu Xun

Around his birthplace area there are several well-preserved Qing dynasty houses which you can visit. For free as well! Which is quite unusual in China. And a few hundred meters away is a large classical garden, but not as impressive as the ones in Suzhou.

As an aside, the Chinese name 绍兴 ShaoXing seems to be almost impossible for me to pronounce. Every time I told someone 我周末去绍兴 they would just look at me blankly and be like “where..?”. My teacher is always complaining that I can’t pronounce other sh- words like 书 properly. And that followed by the elusive x-that-sounds-like-an-s is not a good combination. Also the 兴 is first tone like in 兴奋 not fourth tone like in 高兴. Once I figured this out my success rate increased to maybe 20%…

Using ORC with LLVM’s C API

May 11th, 2017

I recently updated the JIT back-end of my VHDL simulator to use LLVM’s new ORC API which was added in version 3.9. It has a couple of advantages, the two important ones for me were re-introduction of lazy-JIT-ing of functions, and that it works on Windows. Both features that were lost moving from the legacy JIT API to the newer MCJIT one. ORC is actually built as a layer on top of MCJIT though.

Documentation seems to be pretty scarce. There’s some example code but it all uses the C++ API so I thought it might be useful to write some notes on how I use it with the C API. You simply need to include this header and then either link against the LLVM shared library or llvm-config --libs orcjit.

#include <llvm-c/OrcBindings.h>

Initialise the LLVM libraries and MCJIT back-end which ORC is built on:

LLVMInitializeNativeTarget();
LLVMInitializeNativeAsmPrinter();
LLVMLinkInMCJIT();

Let’s assume you already have an LLVM bitcode module from somewhere else:

LLVMModuleRef module = ...;

Unlike the MCJIT API and the original LLVM JIT API you need a “target machine” reference to create the ORC object. This is probably the only non-obvious part but a bit of searching in the other headers finds some functions to do it:

char *def_triple = LLVMGetDefaultTargetTriple();   // E.g. "x86_64-linux-gnu"
char *error;
LLVMTargetRef target_ref;
if (LLVMGetTargetFromTriple(def_triple, &target_ref, &error)) {
   // Fatal error
}
 
if (!LLVMTargetHasJIT(target_ref)) {
   // Fatal error, cannot do JIT on this platform
}
 
LLVMTargetMachineRef tm_ref =
   LLVMCreateTargetMachine(target_ref, def_triple, "", "",
                           LLVMCodeGenLevelDefault,
                           LLVMRelocDefault,
                           LLVMCodeModelJITDefault);
assert(tm_ref);
LLVMDisposeMessage(def_triple);

The two empty string arguments to LLVMCreateTargetMachine are CPU and Features. I can’t work out what these are used for and everything works fine if you pass an empty string. On LLVM 4.0 you can pass NULL here but this crashes on 3.9.

I haven’t experimented with anything other the default relocation model, which seems to work everywhere I tried it, or the optimisation level.

Now we can actually create the ORC object:

LLVMOrcJITStackRef orc_ref = LLVMOrcCreateInstance(tm_ref);
LLVMOrcAddLazilyCompiledIR(orc_ref, module, orc_sym_resolver, NULL);

The only interesting argument is orc_sym_resolver. This is a pointer to callback ORC will use when it needs you to resolve a symbol.

static uint64_t orc_sym_resolver(const char *name, void *ctx)
{
   return (uint64_t)(uintptr_t)LLVMOrcGetSymbolAddress(orc_ref, name);
}

The function LLVMOrcGetSymbolAddress seems to do exactly what we want, but you could do some custom symbol lookup if required.

You can also use this function to trigger the lazy compilation and get a function pointer to the result. For example:

int (*main_fn)(void) = LLVMOrcGetSymbolAddress(orc_ref, "main");
int result = (*main_fn)();

VHDL Compiler Updates

May 5th, 2017

It’s been a long time since I wrote anything about the VHDL compiler and simulator I’m working on, nvc, but I am still developing it, albeit at a slightly slower pace than before.

Since the last update I’ve started making stable releases, and yesterday I released version 1.2.1. Actually I think most people are better off using the master branch: one thing I’m really proud of is the coverage of the regression tests, and they run on every commit using Travis so it should always be stable enough for everyday usage. The “stable” versioning is really to satisfy the requirements of packagers. For instance it is now part of Homebrew for OS X.

The big change in the last year has been the removal of the old hacky constant folding pass and replacing it with one based on the “vcode” intermediate code layer that I wrote about before. The old version used to walk over the AST nodes and attempt to collapse them into a simpler form by evaluating expressions and even evaluating function calls. Unfortunately this was often buggy and sometimes didn’t match the run-time result the code generator would have produced. Now constant folding is done using the same AST-to-vcode lowering pass the code generator uses, to generate vcode “thunks” for compile-time constant expression. These are then evaluated using a new vcode interpreter. This now means almost all side-effect free functions with constant arguments will be folded at compile time. Even those with complex looping, recursion, memory allocation, etc.

Unfortunately this rewrite took way longer than expected, partly due to not having much time to work on it, and partly because all the dependencies into the rest of the code got very complex.

Apart from that I’ve fixed a lot of bugs. And this means you can simulate some quite complex designs in it, for instance the J-Core open source SuperH CPU clone.