IRBuilder helps users manipulate LLVM IR basic blocks. For example, add or remove instructions. So this could be used to build a frontend of a language or build target independent optimizers that manipulate LLVM IRs.
First, we can make Module/Function using the following code:
Module* makeLLVMModule() {
// Module construction
Module* mod = new Module("test", getGlobalContext());
// returns Constant* because it will return a cast of the
// existing function if the function already existed with
// a different prototype.
Constant* c = mod->getOrInsertFunction("mul_add",
IntegerType::get(32),
IntegerType::get(32),
IntegerType::get(32),
IntegerType::get(32),
NULL);
Function* mul_add = cast<Function>(c);
mul_add->setCallingConv(CallingConv::c);
// (not necessary) set names to arguments
Function::arg_iterator args = mul_add->arg_begin();
Value* x = args++;
x->setName("x");
Value* y = args++;
y->setName("y");
Value* z = args++;
z->setName("z");
After creating blocks, we build BasicBlock to contain the function, and use IRBuilder to create and append instructions to the end of a block.
BasicBlock* block = BasicBlock::Create(getGlobalContext(), "entry", mul_add);
IRBuilder<> builder(block);
Value* tmp = builder.CreateBinOp(Instruction::Mul,
x, y, "tmp");
Value* tmp2 = builder.CreateBinOp(Instruction::Add,
tmp, z, "tmp2");
builder.CreateRet(tmp2);
return mod;
}
To build, we need some compiler flags to link with LLVM. Those are done using `llvm-config –cxxflags –ldflags –libs core`
We could actually have multiple BasicBlocks for a function which just requires extra work of instantiating more BasicBlocks and connecting them with control flow using branch instructions.
Reference
LLVM Tutorial: http://releases.llvm.org/2.6/docs/tutorial/ (first two are helpful for this)