Get the arguments of a function in bitcasts in calls, llvm - llvm

I am pretty new with llvm and having trouble digging deep into the following IR line:
%call2 = call float bitcast (float (float, i32*)* #function to float (float, i32 addrspace(1)*)*)(float %11, i32 addrspace(1)* %arrayidx)
What I need to extract from this is line the type of the arguments of the function (i.e., (float %11, i32 addrspace(1)* %arrayidx))
I have tried the following, and played arround with ConstExpr a little as well, but cannot get to extract that addrspace(1)
for (Function::iterator block = F.begin(), blockEnd = F.end(); block != blockEnd; ++block) {
for (BasicBlock::iterator inst = block->begin(), instEnd = block->end(); inst != instEnd; ++inst) {
if (CallInst *call = dyn_cast<CallInst>(inst)) {
Function *calledFunction = call->getCalledFunction();
if (calledFunction == NULL) { // Called function is wrapped in a bitcast
Value* v = call->getCalledValue();
calledFunction = dyn_cast<Function>(v->stripPointerCasts());
FunctionType *ft = calledFunction->getFunctionType(); // This gives me the type "from" (the args without addrspace(1)
for( Function::arg_iterator arg = calledFunction->arg_begin(), marg_end = calledFunction->arg_end(); arg != marg_end ; arg++){
Type *argTy = arg->getType();
if (PointerType *ptrTy = dyn_cast<PointerType>(argTy)) {
if( ptrTy->getAddressSpace() !=0)
...
}
}
}
}
}
}
The above code gives me the types (float, i32*) and not (float, i32 addrspace(1)*)
Any help please?

The llvm ir
%call2 = call float bitcast (float (float, i32*)* #function to float (float, i32 addrspace(1)*)*)(float %11, i32 addrspace(1)* %arrayidx)
is casting function type float (float, i32*) to float (float, i32 addrspace(1)*) and calling it with argument (%11, %arrayidx).
If you want the types of argument you can check it using callInst::getArgOperand to get arguments in call instruction itself.
for (Function::iterator block = F.begin(), blockEnd = F.end(); block != blockEnd; ++block) {
for (BasicBlock::iterator inst = block->begin(), instEnd = block->end(); inst != instEnd; ++inst) {
if (CallInst *call = dyn_cast<CallInst>(inst)) {
Value *val11 = call->getArgOperand(0);
Value *valarrayIdx = call->getArgOperand(1);
Type *val11ty = val11->getType(); // this should be of float
Type *valarrayIdx = valarrayIdx->getType(); // this should be of i32 address(1)*
}
}
}
CallInst::getCalledFunction will give you the function.
For more info you can go through http://llvm.org/docs/doxygen/html/classllvm_1_1CallInst.html

Related

LLVM retrieve name of AllocaInst

I am trying to retrieve the name of the pointer passed to a cudaMalloc call.
CallInst *CUMallocCI = ... ; // CI of cudaMalloc call
Value *Ptr = CUMallocCI->getOperand(0);
if (AllocaInst *AI = dyn_cast<AllocaInst>(Ptr) != nullptr) {
errs() << AI->getName() << "\n";
}
The above however just prints an empty line. Is is possible to get the pointer name out of this alloca?
This is the relevant IR:
%28 = alloca i8*, align 8
...
...
call void #llvm.dbg.declare(metadata i8** %28, metadata !926, metadata !DIExpression()), !dbg !927
%257 = call i32 #cudaMalloc(i8** %28, i64 1), !dbg !928
...
...
!926 = !DILocalVariable(name: "d_over", scope: !677, file: !3, line: 191, type: !22)
!927 = !DILocation(line: 191, column: 10, scope: !677)
Answering my own question. It turns out that there is an llvm.dbg.declare call (DbgDeclareInst) corresponding to the alloca but it may appear anywhere in the caller function's basic blocks. Probably it comes after the first use of this Alloca value? Not sure. In any case, my solution is to search for DbgDeclareInst instructions, check if it is for an AllocaInst and if so compare that alloca with the alloca of interest and if equal get the variable name. Something like this:
CallInst *CUMallocCI = ... ; // CI of cudaMalloc call
Value *Ptr = CUMallocCI->getOperand(0);
if (AllocaInst *AI = dyn_cast<AllocaInst>(Ptr) != nullptr) {
if ( !AI->hasName() ) {
// Function this AllocaInst belongs
Function *Caller = AI->getParent()->getParent();
// Search for llvm.dbg.declare
for ( BasicBlock& BB : *Caller)
for (Instruction &I : BB) {
if ( DbgDeclareInst *dbg = dyn_cast<DbgDeclareInst>(&I))
// found. is it for an AllocaInst?
if ( AllocaInst *dbgAI = dyn_cast<AllocaInst>(dbg->getAddress()))
// is it for our AllocaInst?
if (dbgAI == AI)
if (DILocalVariable *varMD = dbg->getVariable()) // probably not needed?
errs() << varMD->getName() << "\n";
} else {
errs() << AI->getName() << "\n";
}
}

LLVM Insert function call into another function

I am trying to insert function call inside a main function, so then when i run generated binary file, function will be executed automatically. Since language i am trying to "compile" looks like a "scripted" language :
function foo () begin 3 end;
function boo () begin 4 end;
writeln (foo()+boo()) ;
writeln (8) ;
writeln (9) ;
where writeln is a function available by default, and after executing binary i expect to see 7 8 9. Is there a way to insert last function call right before return statement of a main function ?
Right now I have
define i32 #main() {
entry:
ret i32 0
}
and i want to have something like
define i32 #main() {
entry:
%calltmp = call double #writeln(double 7.000000e+00)
%calltmp = call double #writeln(double 8.000000e+00)
%calltmp = call double #writeln(double 9.000000e+00)
ret i32 0
}
editing IR file manually and compile it afterwards works, but i want to do it in codegen part of my code.
edit
what i generate right now is
define double #__anon_expr() {
entry:
%main = call double #writeln(double 3.000000e+00)
ret double %main
}
define i32 #main() {
entry:
ret i32 0
}
so when i execute binary - nothing happens
feel free to source your inspiration from here
Type * returnType = Type::getInt32Ty(TheContext);
std::vector<Type *> argTypes;
FunctionType * functionType = FunctionType::get(returnType, argTypes, false);
Function * function = Function::Create(functionType, Function::ExternalLinkage, "main", TheModule.get());
BasicBlock * BB = BasicBlock::Create(TheContext, "entry", function);
Builder.SetInsertPoint(BB);
vector<Value *> args;
args.push_back(ConstantFP::get(TheContext, APFloat(4.0)));
Builder.CreateCall(getFunction("writeln"), args, "call");
Value * returnValue = Builder.getInt32(0);
Builder.CreateRet(returnValue);

How to get LLVM global variable constant value?

I'm trying to get the float value from a global variable and set it as an instruction's operand.
Here is what I want to do:
#a = private constant float 0x3FB99999A0000000
...
%1 = load float, float* #a ---> removed
%3 = fmul fast %1, %2 ---> %3 = fmul fast float 0x3FB99999A0000000, %2
Below is what I haved tried so far:
for (auto gv_iter = llvm_module.global_begin();gv_iter != llvm_module.global_end(); gv_iter++){
llvm::GlobalVariable* gv = &*gv_iter;
for(auto user_of_gv : gv->users()){
llvm::Instruction *instr_ld_gv = llvm::dyn_cast<llvm::Instruction>(user_of_gv);
llvm::Value *val_gv = llvm::cast<llvm::Value>(instr_ld_gv);
llvm::Constant *const_gv = gv->getInitializer();
llvm::ConstantFP *constfp_gv = llvm::dyn_cast<llvm::ConstantFP>(const_gv);
float gv_fpval = (constfp_gv->getValueAPF()).convertToFloat();
llvm::Constant *const_gv_opd = llvm::ConstantFP::get(llvm::Type::getFloatTy(llvm_context),gv_fpval);
for(auto user_of_load : val_gv->users()){
llvm::Instruction *instr_exe_gv = llvm::dyn_cast<llvm::Instruction>(user_of_load);
//P
for(int operand_num = 0;operand_num < instr_exe_gv->getNumOperands();operand_num++){
llvm::Value *val_instr_op = instr_exe_gv->getOperand(operand_num);
if(val_instr_op == val_gv){
instr_exe_gv->setOperand(operand_num,const_gv_opd);
instr_ld_gv->removeFromParent();
}
}
}
}
}
However, it'll cause segmentation fault when I tried to run my code.
I'm sure that I have accessed the global variable and instruction I wanted
by printing the value of
gv_fpval which is 0.1 because 0x3FB99999A0000000 equals 0.10000000149011612 in double
precision. It seems that the program crashes at setOperand().
Consider the following example
hello.cpp
#include <stdio.h>
// Global Constant value
float a=1.4f;
float Multiply(){
float b=2.2f;
float c=4.32f;
float d= a*c;
return d;
}
int main(int argc, char const *argv[])
{
printf("%f\n",Multiply());
return 0;
}
The module pass will loop for Floating point global variable and any use in the program will be replaced by the constant FP value. The LLVM pass are as follow ConstantReplacementPass.cpp:-
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/DebugInfo.h"
using namespace llvm;
/* StackOverflow : https://stackoverflow.com/questions/48212351/how-to-get-llvm-global-variable-constant-value* /
/**Bernard Nongpoh */
namespace {
class ConstantReplacementPass : public ModulePass {
public:
static char ID;
ConstantReplacementPass() : ModulePass(ID) {
srand (time(NULL));
}
virtual bool runOnModule(Module &M) {
// list to collect instruction
/*
* You cannot change an iterator while iterating over it
• To remove instructions or modify, first collect the instructions to remove/modify
•
*
* **/
// This are the list of load to delete
SmallVector<Instruction*,128> *WorkListLoad=new SmallVector<Instruction*,128>();
// This is the list of instruction to modify the source operand
SmallVector<Instruction*,128> *WorkListUserOfLoad=new SmallVector<Instruction*,128>();
for (auto gv_iter = M.global_begin();gv_iter != M.global_end(); gv_iter++) {
/* GLOBAL DATA INFO*/
GlobalVariable *gv = &*gv_iter;
Constant *const_gv = gv->getInitializer();
ConstantFP *Fvalue;
if(!const_gv->isNullValue()) {
if (ConstantFP *constfp_gv = llvm::dyn_cast<llvm::ConstantFP>(const_gv)) {
float gv_fpval = (constfp_gv->getValueAPF()).convertToFloat();
Fvalue = constfp_gv;
errs() << gv_fpval; // Value retrieved here
// Collect Instruction to modify
}
for (auto user_of_gv: gv->users()) {
// Collect in a worklist
if (llvm::Instruction *instr_ld_gv = llvm::dyn_cast<Instruction>(user_of_gv)) {
if (LoadInst *loadInst = dyn_cast<LoadInst>(instr_ld_gv)) {
WorkListLoad->push_back(loadInst);
for (auto user_of_load:loadInst->users()) {
user_of_load->dump();
Instruction *instruction1 = dyn_cast<Instruction>(user_of_load);
instruction1->dump();
//instruction1->setOperand(0, Fvalue);
//instruction1->dump();
// if(Instruction *instruction1 = dyn_cast<Instruction>(user_of_load))
WorkListUserOfLoad->push_back(instruction1);
//instruction1->setOperand(0, Fvalue);
//instruction1->dump();
}
}
}
}
// Modify Here
while (!WorkListUserOfLoad->empty()) {
Instruction *instruction = WorkListUserOfLoad->pop_back_val();
instruction->setOperand(0, Fvalue);
instruction->dump();
}
// Removing all loads that are used by the global variable
while (!WorkListLoad->empty()) {
Instruction *instruction = WorkListLoad->pop_back_val();
instruction->eraseFromParent();
}
}
}
return true;
}
};
}
char ConstantReplacementPass::ID = 0;
static RegisterPass<ConstantReplacementPass> F0("constantREP", "Constant Replacement Pass "
, false,true);
Key points:-
Before doing any modification on the instruction. Collect first in the worklist.
perform the modification on the worklist.
you cannot do the modification while using the iterator.
I successfully tested on the above source code hello.cpp the corresponding IR after the pass is as follow:-
entry:
%b = alloca float, align 4
%c = alloca float, align 4
%d = alloca float, align 4
call void #llvm.dbg.declare(metadata float* %b, metadata !14, metadata !15),
... !dbg !16
store float 0x40019999A0000000, float* %b, align 4, !dbg !16
call void #llvm.dbg.declare(metadata float* %c, metadata !17, metadata !15),
... !dbg !18
store float 0x401147AE20000000, float* %c, align 4, !dbg !18
call void #llvm.dbg.declare(metadata float* %d, metadata !19, metadata !15),
... !dbg !20
%0 = load float, float* %c, align 4, !dbg !21
%mul = fmul float 0x3FF6666660000000, %0, !dbg !22
store float %mul, float* %d, align 4, !dbg !20
%1 = load float, float* %d, align 4, !dbg !23
ret float %1, !dbg !24
Maybe using -O3 optimization flag will wipe out everything...
Hope this helps..

LLVM error: invalid redefinition of function

I'm writing a LLVM IR generator for a pseudo code language. This language should allow redefinition of function.
Here is one case that I have two functions both named "f" but they have different parameters.
function f(int i, float r) returns int { return i; }
function f(float r, float r2) returns int {return i; }
I thought LLVM could distinct that, but I get
error: invalid redefinition of function
And the code I generated is:
define i32 #f(i32 %i, float %r) {
%var.i.0 = alloca i32
store i32 %i, i32* %var.i.0
%var.r.1 = alloca float
store float %r, float* %var.r.1
%int.2 = load i32* %var.i.0
ret i32 %int.2
; -- 0 :: i32
%int.3 = add i32 0, 0
ret i32 %int.3
}
define i32 #f(float %r, float %r2) {
%var.r.2 = alloca float
store float %r, float* %var.r.2
%var.r2.3 = alloca float
store float %r2, float* %var.r2.3
%var.i.4 = alloca i32
%float.3 = load float* %var.r.2
%int.7 = fptosi float %float.3 to i32
store i32 %int.7, i32* %var.i.4
%int.8 = load i32* %var.i.4
ret i32 %int.8
; -- 0 :: i32
%int.9 = add i32 0, 0
ret i32 %int.9
}
So, I think LLVM do not allow function overloading? Then is it a good idea that I generate a sequential counter, and distinct all these functions by adding this sequential counter as a suffix i.e define i32 #f.1() and define i32 #f.2()?
You're correct that LLVM IR doesn't have function overloading.
Using a sequential counter is probably not a good idea depending on how code in your language is organized. If you're just assigning incrementing integers, those may not be deterministic across the compilation of different files. For example, in C++, you might imagine something like
// library.cpp
int f(int i, float r) { ... }
int f(float r, float r2) { ... }
// user.cpp
extern int f(float r, float r2);
int foo() { return f(1.0, 2.0); }
When compiling user.cpp, there would be no way for the compiler to know that the f being referenced will actually be named f.2.
The typical way to implement function overloading is to use name mangling, somehow encoding the type signature of the function into its name so that it'll be unique in the presence of overloads.
My generator was written in java, so every time I parse a function definition, I will increase the counter for the same function name if the function name has already existed in the scope table.
My table is defined by Map with function name as key, and a list of function def as value:
Map<String,ArrayList<functionSymbol>> = new HashMap<>();
and then the constructor will look like:
static int counter = 0;
public FunctionSymbol(String functionName, Type retType, List<Variable> paramList){
this.functionName = functionName+counter;
this.paramList = paramList;
this.retType = retType;
counter++;
}

llvm exceptions; catch handler not handling, cleanup not called

I i'm trying to create a exception handler inside JIT llvm code. the current documentation regarding exception handling in LLVM is very handwavy at the moment, so i've been trying to reuse most of the snippets i get from http://llvm.org/demo in order to get a working example, but i'm not sure if those are up to date with llvm 2.9 (the version i am using).
This is what the module looks after Module::dump();
; ModuleID = 'testModule'
declare i32 #myfunc()
define i32 #test_function_that_invokes_another() {
entryBlock:
%0 = alloca i8*
%1 = alloca i32
%someName = invoke i32 #myfunc()
to label %exitBlock unwind label %unwindBlock
exitBlock: ; preds = %entryBlock
ret i32 1
unwindBlock: ; preds = %entryBlock
%2 = call i8* #llvm.eh.exception()
store i8* %2, i8** %0
%3 = call i32 (i8*, i8*, ...)* #llvm.eh.selector(i8* %2, i8* bitcast (i32 (...)* #__gxx_personality_v0 to i8*), i8* null)
store i32 1, i32* %1
%4 = load i8** %0
%5 = call i32 (...)* #__cxa_begin_catch(i8* %4) nounwind
%cleanup_call = call i32 #myCleanup()
%6 = call i32 (...)* #__cxa_end_catch()
ret i32 1
}
declare i32 #__gxx_personality_v0(...)
declare i32 #__cxa_begin_catch(...)
declare i32 #__cxa_end_catch(...)
declare i8* #llvm.eh.exception() nounwind readonly
declare i32 #llvm.eh.selector(i8*, i8*, ...) nounwind
declare i32 #myCleanup()
and this is what happens when i try to execute the function:
inside JIT calling C/C++ call
terminate called after throwing an instance of 'int'
Aborted
this shows that the function that throws gets called, it throws, but i never land in the cleanup call. (my cleanup call should have said 'inside JIT calling C/C++ Cleanup')
The function that invokes and (attempts) to catch a thrown exception is:
const inline llvm::FunctionType* getTestFunctionSignature(llvm::LLVMContext& context) {
return llvm::TypeBuilder< unsigned int(), false > ::get(context);
}
llvm::Function* createFunctionThatInvokesAnother( llvm::LLVMContext& ctx, llvm::Module* mod , llvm::Function* another ) {
llvm::Function* result = llvm::Function::Create(getTestFunctionSignature(ctx),
llvm::GlobalValue::ExternalLinkage,
"test_function_that_invokes_another",
mod);
llvm::BasicBlock* entry_block = llvm::BasicBlock::Create(ctx, "entryBlock", result);
llvm::BasicBlock* exit_block = llvm::BasicBlock::Create(ctx, "exitBlock", result);
llvm::BasicBlock* unwind_block = llvm::BasicBlock::Create(ctx, "unwindBlock", result);
llvm::IRBuilder<> builder(entry_block);
llvm::ConstantInt* ci = llvm::ConstantInt::get( mod->getContext() , llvm::APInt( 32 , llvm::StringRef("1"), 10));
llvm::PointerType* pty3 = llvm::PointerType::get(llvm::IntegerType::get(mod->getContext(), 8), 0);
llvm::AllocaInst* ptr_24 = new llvm::AllocaInst(pty3, "", entry_block);
llvm::AllocaInst* ptr_25 = new llvm::AllocaInst(llvm::IntegerType::get(mod->getContext(), 32), "", entry_block);
llvm::Twine name("someName");
builder.CreateInvoke( another , exit_block , unwind_block , "someName" );
builder.SetInsertPoint( exit_block );
builder.CreateRet(ci);
builder.SetInsertPoint( unwind_block );
llvm::Function* func___gxx_personality_v0 = func__gxx_personality_v0(mod);
llvm::Function* func___cxa_begin_catch = func__cxa_begin_catch(mod);
llvm::Function* func___cxa_end_catch = func__cxa_end_catch(mod);
llvm::Function* func_eh_ex = func_llvm_eh_exception(mod);
llvm::Function* func_eh_sel = func__llvm_eh_selector(mod);
llvm::Constant* const_ptr_17 = llvm::ConstantExpr::getCast(llvm::Instruction::BitCast, func___gxx_personality_v0, pty3);
llvm::ConstantPointerNull* const_ptr_18 = llvm::ConstantPointerNull::get(pty3);
llvm::CallInst* get_ex = llvm::CallInst::Create(func_eh_ex, "", unwind_block);
get_ex->setCallingConv(llvm::CallingConv::C);
get_ex->setTailCall(false);
new llvm::StoreInst(get_ex, ptr_24, false, unwind_block);
std::vector<llvm::Value*> int32_37_params;
int32_37_params.push_back(get_ex);
int32_37_params.push_back(const_ptr_17);
int32_37_params.push_back(const_ptr_18);
llvm::CallInst* eh_sel = llvm::CallInst::Create(func_eh_sel, int32_37_params.begin(), int32_37_params.end(), "", unwind_block);
eh_sel->setCallingConv(llvm::CallingConv::C);
eh_sel->setTailCall(false);
new llvm::StoreInst(ci, ptr_25, false, unwind_block);
llvm::LoadInst* ptr_29 = new llvm::LoadInst(ptr_24, "", false, unwind_block);
llvm::CallInst* ptr_30 = llvm::CallInst::Create(func___cxa_begin_catch, ptr_29, "", unwind_block);
ptr_30->setCallingConv(llvm::CallingConv::C);
ptr_30->setTailCall(false);
llvm::AttrListPtr ptr_30_PAL;
{
llvm::SmallVector<llvm::AttributeWithIndex, 4 > Attrs;
llvm::AttributeWithIndex PAWI;
PAWI.Index = 4294967295U;
PAWI.Attrs = 0 | llvm::Attribute::NoUnwind;
Attrs.push_back(PAWI);
ptr_30_PAL = llvm::AttrListPtr::get(Attrs.begin(), Attrs.end());
}
ptr_30->setAttributes(ptr_30_PAL);
llvm::Function* cleanup = call_myCleanup( mod );
builder.CreateCall( cleanup , "cleanup_call");
llvm::CallInst* end_catch = llvm::CallInst::Create(func___cxa_end_catch, "", unwind_block);
builder.CreateRet(ci);
//createCatchHandler( mod , unwind_block );
return result;
}
This gets called like the usual business:
testMain() {
llvm::LLVMContext ctx;
llvm::InitializeNativeTarget();
llvm::StringRef idRef("testModule");
llvm::Module* module = new llvm::Module(idRef, ctx);
std::string jitErrorString;
llvm::ExecutionEngine* execEngine = executionEngine( module , jitErrorString );
llvm::FunctionPassManager* OurFPM = new llvm::FunctionPassManager(module);
llvm::Function *thr = call_my_func_that_throws( module );
llvm::Function* result = createFunctionThatInvokesAnother(ctx, module ,thr);
std::string errorInfo;
llvm::verifyModule(* module, llvm::PrintMessageAction, & errorInfo);
module->dump();
void *fptr = execEngine->getPointerToFunction(result);
unsigned int (*fp)() = (unsigned int (*)())fptr;
try {
unsigned int value = fp();
} catch (...) {
std::cout << " handled a throw from JIT function" << std::endl;
}
}
where my function that throws is:
int myfunc() {
std::cout << " inside JIT calling C/C++ call" << std::endl;
throw 0;
};
llvm::Function* call_my_func_that_throws (llvm::Module* mod) {
std::vector< const llvm::Type* > FuncTy_ex_args;
llvm::FunctionType* FuncTy_ex = llvm::FunctionType::get( llvm::IntegerType::get( mod->getContext() , 32) , FuncTy_ex_args , false);
llvm::Function* result = llvm::Function::Create(FuncTy_ex, llvm::GlobalValue::ExternalLinkage, "myfunc", mod);
result->setCallingConv( llvm::CallingConv::C );
llvm::AttrListPtr PAL;
result->setAttributes( PAL );
llvm::sys::DynamicLibrary::AddSymbol( "myfunc" , (void*) &myfunc );
return result;
}
and my cleanup function is defined in a similar way:
int myCleanup() {
std::cout << " inside JIT calling C/C++ Cleanup" << std::endl;
return 18;
};
llvm::Function* call_myCleanup (llvm::Module* mod) {
std::vector< const llvm::Type* > FuncTy_ex_args;
llvm::FunctionType* FuncTy_ex = llvm::FunctionType::get( llvm::IntegerType::get( mod->getContext() , 32) , FuncTy_ex_args , false);
llvm::Function* result = llvm::Function::Create(FuncTy_ex, llvm::GlobalValue::ExternalLinkage, "myCleanup", mod);
result->setCallingConv( llvm::CallingConv::C );
llvm::AttrListPtr PAL;
result->setAttributes( PAL );
llvm::sys::DynamicLibrary::AddSymbol( "myCleanup" , (void*) &myCleanup );
return result;
}
I've also read this document regarding recent exception handling changes in LLVM, but is not clear how those changes translate to actual, you know, code
Right now the EH code is undergoing a large amount of revision. The demo, if I recall correctly, is not version 2.9, but current development sources - meaning trying to do something with 2.9 is going to be a world of hurt if you try that way.
That said, the EH representation is much better now and numerous patches have gone in to improve the documentation just this week. If you are trying to write a language that uses exceptions via llvm I highly suggest you migrate your code to current development sources.
All of that said, I'm not sure how well exception handling works in the JIT at all right now. It's nominally supported, but you may need to debug the unwind tables that are put into memory to make sure they're correct.