add fib sample

pull/81/head
Dibyendu Majumdar 9 years ago
parent 4b5b871819
commit 9d09555735

@ -43,7 +43,7 @@ llvm.dump(gcobject)
-- At this stage the function will get a module and
-- execution engine but no body
myfunc = context:lua_CFunction("myfunc")
assert(getmetatable(myfunc).type == "LLVMfunction")
assert(getmetatable(myfunc).type == "LLVMmainfunction")
-- Get a new IRBuilder intance
-- this will be garbage collected by Lua
@ -62,10 +62,10 @@ irbuilder:setinsertpoint(block)
-- Get printf decl
-----------------------------------------------
printf = myfunc:extern("printf")
assert(getmetatable(printf).type == "LLVMexternfunc")
assert(getmetatable(printf).type == "LLVMconstant")
luaL_checklstring = myfunc:extern("luaL_checklstring")
assert(getmetatable(luaL_checklstring).type == "LLVMexternfunc")
assert(getmetatable(luaL_checklstring).type == "LLVMconstant")
hellostr = irbuilder:stringconstant("hello world!\n")
irbuilder:call(printf, { hellostr })

@ -0,0 +1,141 @@
-- This program demonstrates creating a
-- recursive fibonacci calc function in LLVM
-- Example based upon
-- https://llvm.org/svn/llvm-project/llvm/trunk/examples/Fibonacci/fibonacci.cpp
-- ensure that LLVM bindings are available
assert(llvm)
-- Generate the fibonacci function
local function makefib(context, module, types)
-- The goal of this snippet is to create in the memory the LLVM module
-- consisting of one function as follow:
--
-- int fib(int x) {
-- if(x<=2) return 1;
-- return fib(x-1)+fib(x-2);
-- }
--
-- Create the fib function and insert it into module M. This function is said
-- to return an int and take an int parameter.
local fibtype = context:functiontype(types.int, {types.int})
local FibF = module:newfunction("fib", fibtype)
-- Get a new IRBuilder intance
-- this will be garbage collected by Lua
local ir = context:irbuilder()
-- Add a basic block to the function.
local BB = context:basicblock("EntryBlock");
FibF:appendblock(BB)
ir:setinsertpoint(BB)
-- Get pointers to the constants.
local One = context:intconstant(1);
local Two = context:intconstant(2);
-- Get pointer to the integer argument of the add1 function...
local ArgX = FibF:arg(1); -- Get the arg.
-- Create the true_block.
local RetBB = context:basicblock("return");
FibF:appendblock(RetBB)
-- Create an exit block.
local RecurseBB = context:basicblock("recurse");
FibF:appendblock(RecurseBB)
-- Create the "if (arg <= 2) goto exitbb"
local CondInst = ir:icmpsle(ArgX, Two);
ir:condbr(CondInst, RetBB, RecurseBB);
ir:setinsertpoint(RetBB)
-- Create: ret int 1
ir:ret(One);
-- create fib(x-1)
ir:setinsertpoint(RecurseBB)
local Sub = ir:nswsub(ArgX, One);
local CallFibX1 = ir:call(FibF, {Sub}, {tailcall=true});
-- create fib(x-2)
Sub = ir:nswsub(ArgX, Two);
local CallFibX2 = ir:call(FibF, {Sub}, {tailcall=true});
-- fib(x-1)+fib(x-2)
local Sum = ir:nswadd(CallFibX1, CallFibX2);
-- Create the return instruction and add it to the basic block
ir:ret(Sum);
return FibF
end
-- Get the LLVM context - right now this is the
-- global context
local context = llvm.context()
-- The bindings provide a number of predefined types that
-- are Lua specific plus some standard C types such as 'int',
-- 'double', 'int64_t', etc.
local types = context:types()
-- Create a lua_CFunction instance
-- At this stage the function will get a module and
-- execution engine but no body
local mainfunc = context:lua_CFunction("demofib")
-- Get hold of the module
-- as we will create the fib function as an
-- iternal function
local module = mainfunc:module()
-- The actual fibonacci function is an internal
-- function so that it is pure native function
local fib = makefib(context, module, types)
-- Get a new IRBuilder
local ir = context:irbuilder()
-- Our main Lua function has only one block
local BB = context:basicblock("entry")
mainfunc:appendblock(BB)
ir:setinsertpoint(BB)
-- Declare prototypes
local luaL_checkinteger = mainfunc:extern("luaL_checkinteger")
local lua_pushinteger = mainfunc:extern("lua_pushinteger")
-- Get lua_State*
local L = mainfunc:arg(1)
-- We are expecting one integer parameter
local intparam = ir:call(luaL_checkinteger, {L, context:intconstant(1)})
-- cast from 64 to 32 bit
intparam = ir:truncorbitcast(intparam, types.int)
-- Call the fib calculator
local result = ir:call(fib, {intparam})
-- Extend from 32 to 64 bit
result = ir:zext(result, types.lua_Integer)
-- Push the final integer result
ir:call(lua_pushinteger, {L, result})
-- Return 1
ir:ret(context:intconstant(1))
---- We are done! ---
-- Dump the module for info
module:dump()
-- compile the Lua callable function
local runnable = mainfunc:compile()
assert(runnable(11) == 89)
print 'Ok'

@ -111,7 +111,8 @@ bool l_table_get_bool(lua_State *L, int idx, const char *key, bool *result,
// We need fixed pointer values for metatable keys
static const char *LLVM_context = "LLVMcontext";
static const char *LLVM_irbuilder = "LLVMirbuilder";
// static const char *LLVM_module = "LLVMmodule";
static const char *LLVM_module = "LLVMmodule";
static const char *LLVM_mainfunction = "LLVMmainfunction";
static const char *LLVM_function = "LLVMfunction";
static const char *LLVM_type = "LLVMtype";
static const char *LLVM_value = "LLVMvalue";
@ -119,7 +120,6 @@ static const char *LLVM_structtype = "LLVMstructtype";
static const char *LLVM_pointertype = "LLVMpointertype";
static const char *LLVM_functiontype = "LLVMfunctiontype";
static const char *LLVM_basicblock = "LLVMbasicblock";
static const char *LLVM_externfunc = "LLVMexternfunc";
static const char *LLVM_constant = "LLVMconstant";
static const char *LLVM_instruction = "LLVMinstruction";
@ -151,6 +151,11 @@ static const char *LLVM_instruction = "LLVMinstruction";
#define check_LLVM_functiontype(L, idx) \
((FunctionTypeHolder *)l_checkudata(L, idx, LLVM_functiontype))
#define test_LLVM_mainfunction(L, idx) \
((MainFunctionHolder *)l_testudata(L, idx, LLVM_mainfunction))
#define check_LLVM_mainfunction(L, idx) \
((MainFunctionHolder *)l_checkudata(L, idx, LLVM_mainfunction))
#define test_LLVM_function(L, idx) \
((FunctionHolder *)l_testudata(L, idx, LLVM_function))
#define check_LLVM_function(L, idx) \
@ -165,11 +170,6 @@ static const char *LLVM_instruction = "LLVMinstruction";
#define check_LLVM_value(L, idx) \
((ValueHolder *)l_checkudata(L, idx, LLVM_value))
#define test_LLVM_externfunc(L, idx) \
((ExternFuncHolder *)l_testudata(L, idx, LLVM_externfunc))
#define check_LLVM_externfunc(L, idx) \
((ExternFuncHolder *)l_checkudata(L, idx, LLVM_externfunc))
#define test_LLVM_constant(L, idx) \
((ConstantHolder *)l_testudata(L, idx, LLVM_constant))
#define check_LLVM_constant(L, idx) \
@ -180,6 +180,11 @@ static const char *LLVM_instruction = "LLVMinstruction";
#define check_LLVM_instruction(L, idx) \
((InstructionHolder *)l_checkudata(L, idx, LLVM_instruction))
#define test_LLVM_module(L, idx) \
((ModuleHolder *)l_testudata(L, idx, LLVM_module))
#define check_LLVM_module(L, idx) \
((ModuleHolder *)l_checkudata(L, idx, LLVM_module))
struct ContextHolder {
/* Each Ravi instance (Lua instance) has its own
* LLVM context
@ -215,18 +220,18 @@ struct FunctionTypeHolder {
};
/* garbage collected */
struct FunctionHolder {
struct MainFunctionHolder {
ravi::RaviJITFunctionImpl *func;
lua_CFunction compiled_func;
llvm::Value *arg1;
};
struct BasicBlockHolder {
llvm::BasicBlock *b;
struct FunctionHolder {
llvm::Function *function;
};
struct ExternFuncHolder {
llvm::Function *function;
struct BasicBlockHolder {
llvm::BasicBlock *b;
};
struct ConstantHolder {
@ -237,6 +242,10 @@ struct InstructionHolder {
llvm::Instruction *i;
};
struct ModuleHolder {
llvm::Module *M;
};
static int context_new_LLVM_irbuilder(lua_State *L) {
ContextHolder *context = check_LLVM_context(L, 1);
IRBuilderHolder *builder =
@ -257,6 +266,13 @@ static int collect_LLVM_irbuilder(lua_State *L) {
return 0;
}
static void alloc_LLVM_module(lua_State *L, llvm::Module *M) {
ModuleHolder *mh = (ModuleHolder *)lua_newuserdata(L, sizeof(ModuleHolder));
l_getmetatable(L, LLVM_module);
lua_setmetatable(L, -2);
mh->M = M;
}
static void alloc_LLVM_type(lua_State *L, llvm::Type *t) {
TypeHolder *tt = (TypeHolder *)lua_newuserdata(L, sizeof(TypeHolder));
l_getmetatable(L, LLVM_type);
@ -302,10 +318,10 @@ static void alloc_LLVM_functiontype(lua_State *L, llvm::FunctionType *type) {
h->type = type;
}
static void alloc_LLVM_externfunc(lua_State *L, llvm::Function *f) {
ExternFuncHolder *h =
(ExternFuncHolder *)lua_newuserdata(L, sizeof(ExternFuncHolder));
l_getmetatable(L, LLVM_externfunc);
static void alloc_LLVM_function(lua_State *L, llvm::Function *f) {
FunctionHolder *h =
(FunctionHolder *)lua_newuserdata(L, sizeof(FunctionHolder));
l_getmetatable(L, LLVM_function);
lua_setmetatable(L, -2);
h->function = f;
}
@ -326,16 +342,16 @@ static void alloc_LLVM_instruction(lua_State *L, llvm::Instruction *i) {
h->i = i;
}
static FunctionHolder *alloc_LLVM_function(lua_State *L,
ravi::RaviJITStateImpl *jit,
llvm::FunctionType *type,
const char *name) {
FunctionHolder *h =
(FunctionHolder *)lua_newuserdata(L, sizeof(FunctionHolder));
static MainFunctionHolder *alloc_LLVM_mainfunction(lua_State *L,
ravi::RaviJITStateImpl *jit,
llvm::FunctionType *type,
const char *name) {
MainFunctionHolder *h =
(MainFunctionHolder *)lua_newuserdata(L, sizeof(MainFunctionHolder));
h->func = nullptr;
h->compiled_func = nullptr;
h->arg1 = nullptr;
l_getmetatable(L, LLVM_function);
l_getmetatable(L, LLVM_mainfunction);
lua_setmetatable(L, -2);
h->func = (ravi::RaviJITFunctionImpl *)jit->createFunction(
type, llvm::Function::ExternalLinkage, name);
@ -343,8 +359,8 @@ static FunctionHolder *alloc_LLVM_function(lua_State *L,
}
/* __gc for FunctionHolder */
static int collect_LLVM_function(lua_State *L) {
FunctionHolder *builder = check_LLVM_function(L, 1);
static int collect_LLVM_mainfunction(lua_State *L) {
MainFunctionHolder *builder = check_LLVM_mainfunction(L, 1);
if (builder->func) {
delete builder->func;
builder->func = nullptr;
@ -461,6 +477,31 @@ static int get_llvm_context(lua_State *L) {
return 1;
}
static llvm::Value *get_value(lua_State *L, int idx) {
InstructionHolder *ii = test_LLVM_instruction(L, idx);
if (ii) {
return ii->i;
}
ValueHolder *v = test_LLVM_value(L, idx);
if (v) {
return v->value;
}
ConstantHolder *c = test_LLVM_constant(L, idx);
if (c) {
return c->constant;
}
MainFunctionHolder *m = test_LLVM_mainfunction(L, idx);
if (m) {
return m->func->function();
}
FunctionHolder *f = test_LLVM_function(L, idx);
if (f) {
return f->function;
}
luaL_argerror(L, idx, "Value expected");
return nullptr;
}
/*
Dump an LLVM object
*/
@ -469,41 +510,45 @@ static int dump_content(lua_State *L) {
StructTypeHolder *sth = nullptr;
PointerTypeHolder *ph = nullptr;
FunctionTypeHolder *fh = nullptr;
FunctionHolder *f = nullptr;
MainFunctionHolder *f = nullptr;
InstructionHolder *ii = nullptr;
ModuleHolder *m = nullptr;
th = test_LLVM_type(L, 1);
if (th) {
th->type->dump();
goto done;
return 0;
}
sth = test_LLVM_structtype(L, 1);
if (sth) {
sth->type->dump();
goto done;
return 0;
}
ph = test_LLVM_pointertype(L, 1);
if (ph) {
ph->type->dump();
goto done;
return 0;
}
fh = test_LLVM_functiontype(L, 1);
if (fh) {
fh->type->dump();
goto done;
return 0;
}
f = test_LLVM_function(L, 1);
f = test_LLVM_mainfunction(L, 1);
if (f) {
f->func->dump();
goto done;
return 0;
}
ii = test_LLVM_instruction(L, 1);
if (ii) {
ii->i->dump();
goto done;
return 0;
}
m = test_LLVM_module(L, 1);
if (m) {
m->M->dump();
return 0;
}
done:
return 0;
}
@ -592,10 +637,22 @@ static int context_new_function_type(lua_State *L) {
return 1;
}
llvm::Function *get_function(lua_State *L, int idx) {
llvm::Function *func = nullptr;
MainFunctionHolder *f = test_LLVM_mainfunction(L, idx);
if (f)
func = f->func->function();
else {
FunctionHolder *f = check_LLVM_function(L, idx);
func = f->function;
}
return func;
}
static int context_new_lua_CFunction(lua_State *L) {
ContextHolder *context = check_LLVM_context(L, 1);
const char *name = luaL_checkstring(L, 2);
FunctionHolder *h = alloc_LLVM_function(
MainFunctionHolder *h = alloc_LLVM_mainfunction(
L, context->jitState, context->jitState->types()->lua_CFunctionT, name);
/* set L arg */
h->arg1 = h->func->function()->arg_begin();
@ -603,6 +660,27 @@ static int context_new_lua_CFunction(lua_State *L) {
return 1;
}
static int func_getmodule(lua_State *L) {
llvm::Function *func = get_function(L, 1);
alloc_LLVM_module(L, func->getParent());
return 1;
}
static int module_newfunction(lua_State *L) {
ModuleHolder *mh = check_LLVM_module(L, 1);
const char *name = luaL_checkstring(L, 2);
FunctionTypeHolder *fth = check_LLVM_functiontype(L, 3);
bool extern_linkage = false;
if (lua_istable(L, 4))
l_table_get_bool(L, 4, "extern", &extern_linkage, false);
llvm::Function *f = llvm::Function::Create(
fth->type, extern_linkage ? llvm::Function::ExternalLinkage
: llvm::Function::InternalLinkage,
name, mh->M);
alloc_LLVM_function(L, f);
return 1;
}
static int context_new_basicblock(lua_State *L) {
ContextHolder *context = check_LLVM_context(L, 1);
const char *name = luaL_checkstring(L, 2);
@ -612,9 +690,9 @@ static int context_new_basicblock(lua_State *L) {
}
static int func_append_basicblock(lua_State *L) {
FunctionHolder *f = check_LLVM_function(L, 1);
llvm::Function *func = get_function(L, 1);
BasicBlockHolder *b = check_LLVM_basicblock(L, 2);
f->func->function()->getBasicBlockList().push_back(b->b);
func->getBasicBlockList().push_back(b->b);
return 0;
}
@ -635,10 +713,10 @@ static int context_intconstant(lua_State *L) {
static int irbuilder_retval(lua_State *L) {
IRBuilderHolder *builder = check_LLVM_irbuilder(L, 1);
ValueHolder *v = test_LLVM_value(L, 2);
llvm::Value *v = get_value(L, 2);
llvm::Instruction *i;
if (v)
i = builder->builder->CreateRet(v->value);
i = builder->builder->CreateRet(v);
else
i = builder->builder->CreateRetVoid();
alloc_LLVM_instruction(L, i);
@ -655,18 +733,17 @@ static int irbuilder_branch(lua_State *L) {
static int irbuilder_condbranch(lua_State *L) {
IRBuilderHolder *builder = check_LLVM_irbuilder(L, 1);
ValueHolder *cond = check_LLVM_value(L, 2);
llvm::Value *cond = get_value(L, 2);
BasicBlockHolder *true_br = check_LLVM_basicblock(L, 3);
BasicBlockHolder *false_br = check_LLVM_basicblock(L, 4);
llvm::Instruction *i =
builder->builder->CreateCondBr(cond->value, true_br->b, false_br->b);
builder->builder->CreateCondBr(cond, true_br->b, false_br->b);
alloc_LLVM_instruction(L, i);
return 1;
}
static int func_compile(lua_State *L) {
FunctionHolder *f = check_LLVM_function(L, 1);
MainFunctionHolder *f = check_LLVM_mainfunction(L, 1);
if (!f->compiled_func) {
f->compiled_func = (lua_CFunction)f->func->compile();
}
@ -696,7 +773,7 @@ typedef struct {
llvm::FunctionType::get(jit->types()->ret, args, vararg); \
llvm::Function *extfunc = f->addExternFunction( \
type, reinterpret_cast<void *>(&name), str(name)); \
alloc_LLVM_externfunc(L, extfunc); \
alloc_LLVM_constant(L, extfunc); \
return 1; \
}
@ -713,7 +790,7 @@ typedef struct {
llvm::FunctionType::get(jit->types()->ret, args, vararg); \
llvm::Function *extfunc = f->addExternFunction( \
type, reinterpret_cast<void *>(&name), str(name)); \
alloc_LLVM_externfunc(L, extfunc); \
alloc_LLVM_constant(L, extfunc); \
return 1; \
}
@ -732,7 +809,7 @@ typedef struct {
llvm::FunctionType::get(jit->types()->ret, args, false); \
llvm::Function *extfunc = f->addExternFunction( \
type, reinterpret_cast<void *>(&name), str(name)); \
alloc_LLVM_externfunc(L, extfunc); \
alloc_LLVM_constant(L, extfunc); \
return 1; \
}
@ -747,7 +824,7 @@ typedef struct {
llvm::FunctionType::get(jit->types()->ret, args, false); \
llvm::Function *extfunc = f->addExternFunction( \
type, reinterpret_cast<void *>(&name), str(name)); \
alloc_LLVM_externfunc(L, extfunc); \
alloc_LLVM_constant(L, extfunc); \
return 1; \
}
@ -816,6 +893,7 @@ decl_voidfunc3(lua_rawsetp, plua_StateT, C_intT, C_pcharT);
decl_func2(lua_setmetatable, C_intT, plua_StateT, C_intT);
decl_voidfunc2(lua_setuservalue, plua_StateT, C_intT);
decl_func3(luaL_checklstring, C_pcharT, plua_StateT, C_intT, C_psize_t);
decl_func2(luaL_checkinteger, lua_IntegerT, plua_StateT, C_intT);
/* Sorted array of declared functions */
static FunctionDeclaration builtin_functions[] = {
@ -878,6 +956,7 @@ static FunctionDeclaration builtin_functions[] = {
{"lua_setmetatable", lua_setmetatable_decl},
{"lua_setuservalue", lua_setuservalue_decl},
{"luaL_checklstring", luaL_checklstring_decl},
{"luaL_checkinteger", luaL_checkinteger_decl},
{"printf", printf_decl},
{nullptr, nullptr}};
@ -888,7 +967,7 @@ static FunctionDeclaration builtin_functions[] = {
*/
static int func_addextern(lua_State *L) {
auto jit = RaviJIT(L);
FunctionHolder *f = check_LLVM_function(L, 1);
MainFunctionHolder *f = check_LLVM_mainfunction(L, 1);
const char *name = luaL_checkstring(L, 2);
luaL_argcheck(L, f->compiled_func == nullptr, 1, "function already compiled");
FunctionTypeHolder *tt = test_LLVM_functiontype(L, 3);
@ -924,46 +1003,49 @@ static int context_nullconstant(lua_State *L) {
Get argument of the function
*/
static int func_getarg(lua_State *L) {
FunctionHolder *th = check_LLVM_function(L, 1);
llvm::Function *func = get_function(L, 1);
int argn = luaL_checkinteger(L, 2);
int results = 1;
if (argn == 1 && th->arg1) {
alloc_LLVM_value(L, th->arg1);
} else {
if (argn <= th->func->function()->arg_size()) {
auto B = th->func->function()->arg_begin();
auto E = th->func->function()->arg_end();
for (int i = 1; B != E; B++, i++) {
if (i == argn) {
alloc_LLVM_value(L, B);
break;
}
if (argn <= func->arg_size()) {
auto B = func->arg_begin();
auto E = func->arg_end();
for (int i = 1; B != E; B++, i++) {
if (i == argn) {
alloc_LLVM_value(L, B);
break;
}
} else {
results = 0;
}
} else {
results = 0;
}
return results;
}
static int irbuilder_externcall(lua_State *L) {
static int irbuilder_call(lua_State *L) {
IRBuilderHolder *builder = check_LLVM_irbuilder(L, 1);
ExternFuncHolder *f = test_LLVM_externfunc(L, 2);
ConstantHolder *c = nullptr;
if (f == nullptr)
c = check_LLVM_constant(L, 2);
llvm::Value *func = nullptr;
ConstantHolder *c = test_LLVM_constant(L, 2);
if (c)
func = c->constant;
else {
func = get_function(L, 2);
}
luaL_argcheck(L, lua_istable(L, 3), 3, "table expected");
int len = luaL_len(L, 3);
std::vector<llvm::Value *> elements;
for (int i = 1; i <= len; i++) {
lua_rawgeti(L, 3, i);
ValueHolder *vh = check_LLVM_value(L, -1);
elements.push_back(vh->value);
llvm::Value *v = get_value(L, -1);
elements.push_back(v);
lua_pop(L, 1);
}
llvm::Value *result = builder->builder->CreateCall(
f != nullptr ? f->function : c->constant, elements);
alloc_LLVM_value(L, result);
bool tailcall = false;
if (lua_istable(L, 4))
l_table_get_bool(L, 4, "tailcall", &tailcall, false);
llvm::CallInst *inst = builder->builder->CreateCall(func, elements);
if (tailcall)
inst->setTailCall();
alloc_LLVM_instruction(L, inst);
return 1;
}
@ -987,9 +1069,10 @@ static llvm::Type *get_type(lua_State *L, int idx) {
static int irbuilder_alloca(lua_State *L) {
IRBuilderHolder *builder = check_LLVM_irbuilder(L, 1);
llvm::Type *ty = get_type(L, 2);
ValueHolder *vh = test_LLVM_value(L, 3);
llvm::Value *array_size = vh ? vh->value : nullptr;
llvm::Instruction *inst = builder->builder->CreateAlloca(ty, array_size);
llvm::Value *arraysize = nullptr;
if (lua_gettop(L) >= 3)
arraysize = get_value(L, 3);
llvm::Instruction *inst = builder->builder->CreateAlloca(ty, arraysize);
alloc_LLVM_instruction(L, inst);
return 1;
}
@ -998,17 +1081,17 @@ static int irbuilder_alloca(lua_State *L) {
#define irbuilder_vva(op) \
static int irbuilder_##op(lua_State *L) { \
IRBuilderHolder *builder = check_LLVM_irbuilder(L, 1); \
ValueHolder *c = check_LLVM_value(L, 2); \
llvm::Value *c = get_value(L, 2); \
luaL_argcheck(L, lua_istable(L, 3), 3, "table expected"); \
int len = luaL_len(L, 3); \
std::vector<llvm::Value *> elements; \
for (int i = 1; i <= len; i++) { \
lua_rawgeti(L, 3, i); \
ValueHolder *vh = check_LLVM_value(L, -1); \
elements.push_back(vh->value); \
llvm::Value *v = get_value(L, -1); \
elements.push_back(v); \
lua_pop(L, 1); \
} \
llvm::Value *result = builder->builder->Create##op(c->value, elements); \
llvm::Value *result = builder->builder->Create##op(c, elements); \
alloc_LLVM_value(L, result); \
return 1; \
}
@ -1016,10 +1099,9 @@ static int irbuilder_alloca(lua_State *L) {
#define irbuilder_binop(op) \
static int irbuilder_##op(lua_State *L) { \
IRBuilderHolder *builder = check_LLVM_irbuilder(L, 1); \
ValueHolder *lhs = test_LLVM_value(L, 2); \
ValueHolder *rhs = test_LLVM_value(L, 3); \
llvm::Value *result = \
builder->builder->Create##op(lhs->value, rhs->value); \
llvm::Value *lhs = get_value(L, 2); \
llvm::Value *rhs = get_value(L, 3); \
llvm::Value *result = builder->builder->Create##op(lhs, rhs); \
alloc_LLVM_value(L, result); \
return 1; \
}
@ -1027,8 +1109,8 @@ static int irbuilder_alloca(lua_State *L) {
#define irbuilder_unop(op) \
static int irbuilder_##op(lua_State *L) { \
IRBuilderHolder *builder = check_LLVM_irbuilder(L, 1); \
ValueHolder *lhs = test_LLVM_value(L, 2); \
llvm::Value *result = builder->builder->Create##op(lhs->value); \
llvm::Value *lhs = get_value(L, 2); \
llvm::Value *result = builder->builder->Create##op(lhs); \
alloc_LLVM_value(L, result); \
return 1; \
}
@ -1036,9 +1118,9 @@ static int irbuilder_alloca(lua_State *L) {
#define irbuilder_convert(op) \
static int irbuilder_##op(lua_State *L) { \
IRBuilderHolder *builder = check_LLVM_irbuilder(L, 1); \
ValueHolder *lhs = test_LLVM_value(L, 2); \
llvm::Value *lhs = get_value(L, 2); \
llvm::Type *rhs = get_type(L, 3); \
llvm::Value *result = builder->builder->Create##op(lhs->value, rhs); \
llvm::Value *result = builder->builder->Create##op(lhs, rhs); \
alloc_LLVM_value(L, result); \
return 1; \
}
@ -1122,11 +1204,21 @@ static const luaL_Reg llvmlib[] = {
static const luaL_Reg structtype_methods[] = {{"setbody", struct_add_members},
{NULL, NULL}};
static const luaL_Reg function_methods[] = {
static const luaL_Reg module_methods[] = {{"newfunction", module_newfunction},
{"dump", dump_content},
{NULL, NULL}};
static const luaL_Reg main_function_methods[] = {
{"appendblock", func_append_basicblock},
{"compile", func_compile},
{"extern", func_addextern},
{"arg", func_getarg},
{"module", func_getmodule},
{NULL, NULL}};
static const luaL_Reg function_methods[] = {
{"appendblock", func_append_basicblock},
{"arg", func_getarg},
{NULL, NULL}};
static const luaL_Reg context_methods[] = {
@ -1145,7 +1237,7 @@ static const luaL_Reg irbuilder_methods[] = {
{"setinsertpoint", irbuilder_set_current_block},
{"ret", irbuilder_retval},
{"stringconstant", irbuilder_stringconstant},
{"call", irbuilder_externcall},
{"call", irbuilder_call},
{"br", irbuilder_branch},
{"condbr", irbuilder_condbranch},
{"icmpeq", irbuilder_ICmpEQ},
@ -1226,6 +1318,14 @@ LUAMOD_API int raviopen_llvmluaapi(lua_State *L) {
luaL_setfuncs(L, context_methods, 0);
lua_pop(L, 1);
l_newmetatable(L, LLVM_module);
lua_pushstring(L, LLVM_module);
lua_setfield(L, -2, "type");
lua_pushvalue(L, -1); /* push metatable */
lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
luaL_setfuncs(L, module_methods, 0);
lua_pop(L, 1);
l_newmetatable(L, LLVM_irbuilder);
lua_pushstring(L, LLVM_irbuilder);
lua_setfield(L, -2, "type");
@ -1236,11 +1336,19 @@ LUAMOD_API int raviopen_llvmluaapi(lua_State *L) {
luaL_setfuncs(L, irbuilder_methods, 0);
lua_pop(L, 1);
l_newmetatable(L, LLVM_mainfunction);
lua_pushstring(L, LLVM_mainfunction);
lua_setfield(L, -2, "type");
lua_pushcfunction(L, collect_LLVM_mainfunction);
lua_setfield(L, -2, "__gc");
lua_pushvalue(L, -1); /* push metatable */
lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
luaL_setfuncs(L, main_function_methods, 0);
lua_pop(L, 1);
l_newmetatable(L, LLVM_function);
lua_pushstring(L, LLVM_function);
lua_setfield(L, -2, "type");
lua_pushcfunction(L, collect_LLVM_function);
lua_setfield(L, -2, "__gc");
lua_pushvalue(L, -1); /* push metatable */
lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
luaL_setfuncs(L, function_methods, 0);
@ -1279,11 +1387,6 @@ LUAMOD_API int raviopen_llvmluaapi(lua_State *L) {
lua_setfield(L, -2, "type");
lua_pop(L, 1);
l_newmetatable(L, LLVM_externfunc);
lua_pushstring(L, LLVM_externfunc);
lua_setfield(L, -2, "type");
lua_pop(L, 1);
l_newmetatable(L, LLVM_constant);
lua_pushstring(L, LLVM_constant);
lua_setfield(L, -2, "type");

Loading…
Cancel
Save