add phi instruction to LLVM binding

pull/81/head
Dibyendu Majumdar 9 years ago
parent f209f76876
commit a3f201da53

@ -72,10 +72,8 @@ typedef union { double u; void *s; lua_Integer i; long l; } L_Umaxalign;
typedef LUAI_UACNUMBER l_uacNumber;
typedef LUAI_UACINT l_uacInt;
#ifndef lua_assert
#undef NDEBUG
#ifndef NDEBUG
#include <assert.h>
#define lua_assert assert
#endif

@ -63,6 +63,7 @@ The bindings provide a number of Lua types::
+ LLVMvalue
+ LLVMinstruction
+ LLVMconstant
+ LLVMphinode
+ LLVMirbuilder
+ LLVMbasicblock
@ -144,8 +145,10 @@ The following table lists the Lua LLVM api functions available.
| Emit call instruction; 'tailcall' option is false by default |
| ``br(basicblock) -> LLVMinstruction`` |
| Emit a branch instruction |
| ``condbr(vavlue, true_block, false_block) -> LLVMinstruction`` |
| ``condbr(value, true_block, false_block) -> LLVMinstruction`` |
| Emit a conditional branch |
| ``phi(type, num_values[, name]) -> LLVMphinode`` |
| Generate a PHINode |
| |
| GEP Operators |
| |
@ -234,3 +237,8 @@ The following table lists the Lua LLVM api functions available.
| * ``pointercast`` |
| * ``fpcast`` |
+----------------------------------------------------------------------------------------------+
| **LLVMphinode methods** |
+----------------------------------------------------------------------------------------------+
| ``addincoming(value, basicblock)`` |
| Adds incoming edge |
+----------------------------------------------------------------------------------------------+

@ -888,9 +888,8 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
RAVI - when parsing something like (10)[3] - t->ravi_type is RAVI_TNUMINT
which is wrong so we need to check for this situation. Problem is that
because of metatables the index [] operator can even be applied to numeric
values (see for example Lua test events.lua line 1114). It feels wrong to
have to change it here ... needs to investigated further as there may be
a defect elsewhere.
values (see for example Lua test events.lua) so we can't raise an error
here.
*/
if (t->ravi_type != RAVI_TTABLE && t->ravi_type != RAVI_TARRAYFLT && t->ravi_type != RAVI_TARRAYINT)
t->ravi_type = RAVI_TANY;

@ -122,6 +122,7 @@ static const char *LLVM_functiontype = "LLVMfunctiontype";
static const char *LLVM_basicblock = "LLVMbasicblock";
static const char *LLVM_constant = "LLVMconstant";
static const char *LLVM_instruction = "LLVMinstruction";
static const char *LLVM_phinode = "LLVMphinode";
#define test_LLVM_irbuilder(L, idx) \
((IRBuilderHolder *)l_testudata(L, idx, LLVM_irbuilder))
@ -185,6 +186,11 @@ static const char *LLVM_instruction = "LLVMinstruction";
#define check_LLVM_module(L, idx) \
((ModuleHolder *)l_checkudata(L, idx, LLVM_module))
#define test_LLVM_phinode(L, idx) \
((PhiNodeHolder *)l_testudata(L, idx, LLVM_phinode))
#define check_LLVM_phinode(L, idx) \
((PhiNodeHolder *)l_checkudata(L, idx, LLVM_phinode))
struct ContextHolder {
/* Each Ravi instance (Lua instance) has its own
* LLVM context
@ -246,6 +252,10 @@ struct ModuleHolder {
llvm::Module *M;
};
struct PhiNodeHolder {
llvm::PHINode *phi;
};
static int context_new_LLVM_irbuilder(lua_State *L) {
ContextHolder *context = check_LLVM_context(L, 1);
IRBuilderHolder *builder =
@ -342,6 +352,13 @@ static void alloc_LLVM_instruction(lua_State *L, llvm::Instruction *i) {
h->i = i;
}
static void alloc_LLVM_phinode(lua_State *L, llvm::PHINode *phi) {
PhiNodeHolder *h = (PhiNodeHolder *)lua_newuserdata(L, sizeof(PhiNodeHolder));
l_getmetatable(L, LLVM_phinode);
lua_setmetatable(L, -2);
h->phi = phi;
}
static MainFunctionHolder *alloc_LLVM_mainfunction(lua_State *L,
ravi::RaviJITStateImpl *jit,
llvm::FunctionType *type,
@ -496,6 +513,10 @@ static llvm::Value *get_value(lua_State *L, int idx) {
if (f) {
return f->function;
}
PhiNodeHolder *phi = test_LLVM_phinode(L, idx);
if (phi) {
return phi->phi;
}
luaL_argerror(L, idx, "Value expected");
return nullptr;
}
@ -511,6 +532,7 @@ static int dump_content(lua_State *L) {
MainFunctionHolder *f = nullptr;
InstructionHolder *ii = nullptr;
ModuleHolder *m = nullptr;
PhiNodeHolder *phi = nullptr;
th = test_LLVM_type(L, 1);
if (th) {
@ -547,6 +569,11 @@ static int dump_content(lua_State *L) {
m->M->dump();
return 0;
}
phi = test_LLVM_phinode(L, 1);
if (phi) {
phi->phi->dump();
return 0;
}
return 0;
}
@ -1112,6 +1139,28 @@ static int irbuilder_store(lua_State *L) {
return 1;
}
static int irbuilder_phi(lua_State *L) {
IRBuilderHolder *builder = check_LLVM_irbuilder(L, 1);
llvm::Type *ty = get_type(L, 2);
unsigned int num_values = (unsigned int)luaL_checkinteger(L, 3);
const char *name = nullptr;
if (lua_gettop(L) >= 4) {
name = luaL_checkstring(L, 4);
}
llvm::PHINode *phi = builder->builder->CreatePHI(ty, num_values, name);
alloc_LLVM_phinode(L, phi);
return 1;
}
static int phi_addincoming(lua_State *L) {
PhiNodeHolder *phi = check_LLVM_phinode(L, 1);
llvm::Value *value = get_value(L, 2);
BasicBlockHolder *block = check_LLVM_basicblock(L, 3);
phi->phi->addIncoming(value, block->b);
lua_pushinteger(L, phi->phi->getNumOperands());
return 1;
}
/* ops that take a value and value array as arguments */
#define irbuilder_vva(op) \
static int irbuilder_##op(lua_State *L) { \
@ -1239,9 +1288,8 @@ static const luaL_Reg llvmlib[] = {
static const luaL_Reg structtype_methods[] = {{"setbody", struct_add_members},
{NULL, NULL}};
static const luaL_Reg module_methods[] = {{"newfunction", module_newfunction},
{"dump", dump_content},
{NULL, NULL}};
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},
@ -1249,13 +1297,13 @@ static const luaL_Reg main_function_methods[] = {
{"extern", func_addextern},
{"arg", func_getarg},
{"module", func_getmodule},
{"alloca", func_alloca },
{"alloca", func_alloca},
{NULL, NULL}};
static const luaL_Reg function_methods[] = {
{"appendblock", func_append_basicblock},
{"arg", func_getarg},
{"alloca", func_alloca },
{"alloca", func_alloca},
{NULL, NULL}};
static const luaL_Reg context_methods[] = {
@ -1270,6 +1318,9 @@ static const luaL_Reg context_methods[] = {
{"nullconstant", context_nullconstant},
{NULL, NULL}};
static const luaL_Reg phi_methods[] = {{"addincoming", phi_addincoming},
{NULL, NULL}};
static const luaL_Reg irbuilder_methods[] = {
{"setinsertpoint", irbuilder_set_current_block},
{"ret", irbuilder_retval},
@ -1345,6 +1396,7 @@ static const luaL_Reg irbuilder_methods[] = {
{"fpcast", irbuilder_FPCast},
{"load", irbuilder_load},
{"store", irbuilder_store},
{"phi", irbuilder_phi},
{NULL, NULL}};
LUAMOD_API int raviopen_llvmluaapi(lua_State *L) {
@ -1435,6 +1487,14 @@ LUAMOD_API int raviopen_llvmluaapi(lua_State *L) {
lua_setfield(L, -2, "type");
lua_pop(L, 1);
l_newmetatable(L, LLVM_phinode);
lua_pushstring(L, LLVM_phinode);
lua_setfield(L, -2, "type");
lua_pushvalue(L, -1); /* push metatable */
lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
luaL_setfuncs(L, phi_methods, 0);
lua_pop(L, 1);
luaL_newlib(L, llvmlib);
return 1;
}

Loading…
Cancel
Save