vendredi 5 mars 2010

Phd thesis and LLVM

Hi, due to the poor amount of llvm sample code available on internet,
I decided to create a blog to report my own test and sample.

That's could help someone, somewhere...one day.

I don't have time to write a full "quick start guide" but now, I just throw on paper sheet my recurrents problems, and next time, I'll write something more user-friendly.

For example, trying to JIT a piece of code dynamically constructed via the C++ API of LLVM, I found a lot of big rabbit on my success's road.

Rabbit! Not bugs. Fluffy, funny but huge. Like in the monthy python movie, something that could cut your head off without warning.

1) IRBuilder<>::CreateCall

Don't put a name if your function return "void" :


void llvm::Value::setName(const llvm::Twine&): Assertion `!getType()->isVoidTy() && "Cannot assign a name to void values!"' failed


2)
IRBuilder<>::CreateGEP

All sample on the net about CreateGEP are rotten, or obsolete.
Don't be fool, do something KISS


std::vector args;
// you always must dereference the first, read the FAQ on llvm site
args.push_back(ConstantInt::get(getGlobalContext(), APInt(32, 0, false)));
// N is your indirection level (index of struct field, index of array)
args.push_back(ConstantInt::get(getGlobalContext(), APInt(32, N, false)));
// PTR is your pointer that you try to deref
Value *result = myBuilder.CreateGEP(PTR, args.begin(), args.end(), "myderef");


3) CREATE POINTER TYPE

Not well documented but simple....

to craft a main prototype I want to craft a i8** for my argv parameter (as usual in C function).

JUST USE the PointerType::getUnqual function. Not really mnemonic if your are not really fluant in english.


// create the function prototype
std::vector protof;

// type of the first parameter as 'int ac'
protof.push_back(Type::getInt32Ty(getGlobalContext()));

// made a **i8
const Type *simple_i8 = Type::getInt8Ty(getGlobalContext());
PointerType *ptr_i8 = PointerType::getUnqual(simple_i8);
PointerType *ptr_ptr_i8 = PointerType::getUnqual(ptr_i8);

// type of the second parameter as 'char **av'
protof.push_back(ptr_ptr_i8);

// build the prototype as 'int ()(int, char**)'
FunctionType *ft = FunctionType::get(Type::getInt32Ty(getGlobalContext()), protof, false);

// add and named the function in the module
Function *f = Function::Create(ft, Function::ExternalLinkage, "main", theModule);


Aucun commentaire:

Enregistrer un commentaire