Wednesday, May 27, 2015

Recursive Structs in LLVM experiments, using Clang


You don't get enough science in computer science, like with the whole experimental method.

I'm (currently?) using LLVMlite (https://github.com/numba/llvmlite) in my compiler project. Some things you might want to do aren't well covered in the LLVMlite documentation, or even in the LLVM documentation.

Case in point, I'd like to be able to generate code for something like this:

  Ship bar;
  bar.pos.y = 7;
  bar.vel.y = 3;
  bar.pos.y += bar.vel.y;

I haven't been making a lot of progress lately (you'd know), trying to wrap my head around what I'd even need to keep track of for that to work, including most recently thinking that I'd need to be able to walk the tree to create a path of element offsets, keep track of l-vals and r-vals, and some sort of stack of symbol tables.

But then I recalled that I had used Clang before to figure out how they do things.

  clang -S -emit-llvm teststruct.c 

I just pointed that commandline at some C that does what I want, and it spits out LLVM instructions that I can use as a reference.

For example, some of the instructions generated for the above code is:

  %10 = getelementptr inbounds %struct.Ship* %bar, i32 0, i32 0
  %11 = getelementptr inbounds %struct.Vec2f* %10, i32 0, i32 1
  %12 = load i32* %11, align 4
  %13 = add nsw i32 %12, %9
  store i32 %13, i32* %11, align 4
 
So, there you go. Just get the element pointer, then get the element pointer, and then bam, put the thing in the thing. That's it.

Reverse engineering. One of my top several favorite kinds of engineering.

No comments:

Post a Comment