Search code examples
llvmllvm-irllvm-c++-api

What is the advantage of LLVM Builder over manual construction of IR code?


I am new to LLVM and trying to learn the basics which is quite hard enough in itself.

I have now reached the point where I try to write simple programs in IR. The documentation is pretty clear on the syntax and usage of IR code. Now, I have worked through 2 or 3 tutorials and was of course introduced to the builder framework. This however is quite complex.

First, there are two interfaces to the builder system, the C++ and the C interface. Both seem to provide the same functionality at first glance. The first question that arises is of course, which one should be used? Is there an advantage of one over the other? Is it a matter of taste? I wasn't able to find answers so I decided to go with the C++ interface.

Frankly, this builder framework is even harder to understand. So now I am not only faced with learning the IR code and how to use it correctly, but on top of it with the builder interface which makes things more confusing

For instance: From my learning of the basic IR language I would naively go and write something like:

%1 = add i32 42, %0 

which is pretty clear. I just spend 3 hours finding out how to do that with the builder framework and my answer isn't even satisfying, since I have to first allocate storage with the alloca call which then leaves me with code that writes through a pointer.

It is my understanding, that the IR language and the underlying SSA system is supposed to use pseudoregisters like the one above and not use memory addresses that my code explicitly allocates.

So after quite some experiments I arrived at a point where I am thinking that it may be better and easier to simply generate IR code manually in my program.

My question is: Are there any major advantages in the IR builder framework that make it highly advisable to use that over a manual approach? Or is it simply supposed to be easier to use and that's all?

Thanks


Solution

  • The IR builder is supposed to make IR construction easier, that's all. It keeps track of an insertion point in the basic block, and in general using it should result in a bit shorter code.

    But don't worry too much about it: it's perfectly possible to create IR with just plain C++ API calls as well. You should also get familiar with the C++ backend in LLVM, which translates IR into the sequence of C++ API calls needed to construct it - it's very useful. For an example, see this online Clang demo - select "LLVM C++ API code" as the Target.