Skip to content

Commit

Permalink
Add support for PUC Lua.
Browse files Browse the repository at this point in the history
  • Loading branch information
elliottslaughter committed Jan 29, 2020
1 parent 7009c36 commit 52ab569
Show file tree
Hide file tree
Showing 21 changed files with 6,688 additions and 230 deletions.
279 changes: 190 additions & 89 deletions Makefile

Large diffs are not rendered by default.

27 changes: 25 additions & 2 deletions src/asdl.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
local function isluajit()
return type(rawget(_G,"jit")) == "table"
end

local iscdata
if isluajit() then
function iscdata(v)
return type(v) == "cdata"
end
else
local ffi = require("ffi")
local function hastype(v)
return ffi.typeof(v)
end
function iscdata(v)
return type(v) == "userdata" and pcall(hastype, v)
end
end

local List = require("terralist")

local Context = {}
Expand Down Expand Up @@ -163,7 +182,11 @@ local function parseAll(text)
end

local function checkbuiltin(t)
return function(v) return type(v) == t end
if t == "cdata" then
return function(v) return iscdata(v) end
else
return function(v) return type(v) == t end
end
end

local function checkoptional(checkt)
Expand Down Expand Up @@ -398,4 +421,4 @@ function Context:Define(text)
end
end
end
package.loaded["asdl"] = { NewContext = NewContext, List = List }
package.loaded["asdl"] = { NewContext = NewContext, List = List, isluajit = isluajit, iscdata = iscdata }
7 changes: 6 additions & 1 deletion src/cudalib.lua
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ cudalib.useculink = false
-- this this is only needed for cuda compilation, we load this library lazily below
local terracode = [[
local ffi = require('ffi')
local asdl = require('asdl')
local ef = terralib.externfunction
local struct CUctx_st
local struct CUfunc_st
Expand Down Expand Up @@ -347,7 +348,11 @@ local function dumpsass(data,sz)
local nvdisasm = terralib.cudahome..(ffi.os == "Windows" and "\\bin\\nvdisasm.exe" or "/bin/nvdisasm")
os.execute(string.format("%q --print-life-ranges dump.sass",nvdisasm))
end
dumpsass = terralib.cast({&opaque,uint64} -> {},dumpsass)
if asdl.isluajit() then
dumpsass = terralib.cast({&opaque,uint64} -> {},dumpsass)
else
dumpsass = nil -- FIXME: PUC Lua doesn't support callbacks
end
function cudalib.compile(module,dumpmodule,version,jitload)
version = version or cudalib.localversion()
Expand Down
1 change: 0 additions & 1 deletion src/genclangpaths.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
--See Copyright Notice in ../LICENSE.txt
--usage: genclangpaths.lua output /path/to/clang [addition args to parse]
local ffi = require("ffi")
local outputfile,clang = unpack(arg)
local handle = assert(io.popen(clang .. " -v src/dummy.c -o build/dummy.o 2>&1", "r"))
local theline
Expand Down
9 changes: 4 additions & 5 deletions src/geninternalizedfiles.lua
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
local outputfilename = arg[1]
local os,outputfilename = arg[1],arg[2]

local ffi = require("ffi")
local findcmd = ffi.os == "Windows" and "cmd /c dir /b /s \"%s\"" or "find %q"
local findcmd = os == "Windows" and "cmd /c dir /b /s \"%s\"" or "find %q"

local listoffiles = {}
for i = 2,#arg,2 do
for i = 3,#arg,2 do
local path,pattern = arg[i],arg[i+1]
local p = assert(io.popen(findcmd:format(path)))
print(findcmd:format(path))
Expand Down Expand Up @@ -66,4 +65,4 @@ table.insert(output,RegisterTemplate:format(table.concat(names,","),table.concat

local outputfile = io.open(outputfilename,"w")
outputfile:write(table.concat(output))
outputfile:close()
outputfile:close()
9 changes: 9 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,19 @@ static int luapanic(
exit(1);
}

#ifdef TERRA_USE_PUC_LUA
extern "C" {
void preload_ffi(lua_State *L);
}
#endif

int main(int argc, char **argv) {
progname = argv[0];
lua_State *L = luaL_newstate();
luaL_openlibs(L);
#ifdef TERRA_USE_PUC_LUA
preload_ffi(L);
#endif
lua_atpanic(L, luapanic);
terra_Options options;
memset(&options, 0, sizeof(terra_Options));
Expand Down
89 changes: 64 additions & 25 deletions src/tcompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,22 @@ extern "C" {

using namespace llvm;

#ifdef TERRA_USE_PUC_LUA
#include "tffi.h"
#endif

static const void *tocdata(lua_State *L, int idx) {
#ifdef TERRA_USE_PUC_LUA
// libffi uses a 32 byte header for each cdata object,
// which we have to skip here
return ((char *)lua_topointer(L, idx) + sizeof(struct cdata));
#else
return lua_topointer(L, idx);
#endif
}

#define TERRALIB_FUNCTIONS(_) \
_(inittarget, 1) \
_(freetarget, 0) \
_(initcompilationunit, 1) \
_(compilationunitaddvalue, \
1) /*entry point from lua into compiler to generate LLVM for a function, other \
Expand Down Expand Up @@ -305,6 +318,17 @@ bool HostHasAVX() {
return Features["avx"];
}

static inline void terra_pushpointerwithgc(lua_State *L, void *ptr,
lua_CFunction destructor) {
void **blockaddr = (void **)lua_newuserdata(L, sizeof(void *));
*blockaddr = ptr;
lua_newtable(L);
lua_pushcfunction(L, destructor);
lua_setfield(L, -2, "__gc");
lua_setmetatable(L, -2);
}

int terra_freetarget(lua_State *L);
int terra_inittarget(lua_State *L) {
terra_State *T = terra_getstate(L, 1);
TerraTarget *TT = new TerraTarget();
Expand Down Expand Up @@ -388,14 +412,15 @@ int terra_inittarget(lua_State *L) {
CodeGenOpt::Aggressive);
TT->external = new Module("external", *TT->ctx);
TT->external->setTargetTriple(TT->Triple);
lua_pushlightuserdata(L, TT);
terra_pushpointerwithgc(L, TT, terra_freetarget);
return 1;
}

int terra_freecompilationunit(lua_State *L);
int terra_initcompilationunit(lua_State *L) {
terra_State *T = terra_getstate(L, 1);
TerraCompilationUnit *CU = new TerraCompilationUnit();
TerraTarget *TT = (TerraTarget *)terra_tocdatapointer(L, 1);
TerraTarget *TT = terra_totarget(L, 1);
CU->TT = TT;
CU->TT->nreferences++;
CU->nreferences = 1;
Expand All @@ -419,7 +444,7 @@ int terra_initcompilationunit(lua_State *L) {
llvmutil_addtargetspecificpasses(CU->fpm, TT->tm);
llvmutil_addoptimizationpasses(CU->fpm);
CU->fpm->doInitialization();
lua_pushlightuserdata(L, CU);
terra_pushpointerwithgc(L, CU, terra_freecompilationunit);
return 1;
}

Expand Down Expand Up @@ -502,7 +527,7 @@ void freetarget(TerraTarget *TT) {
}
}
int terra_freetarget(lua_State *L) {
freetarget((TerraTarget *)terra_tocdatapointer(L, 1));
freetarget(terra_totarget(L, 1));
return 0;
}

Expand All @@ -524,7 +549,7 @@ static void freecompilationunit(TerraCompilationUnit *CU) {
}
}
int terra_freecompilationunit(lua_State *L) {
freecompilationunit((TerraCompilationUnit *)terra_tocdatapointer(L, 1));
freecompilationunit(terra_tocompilationunit(L, 1));
return 0;
}

Expand Down Expand Up @@ -2166,7 +2191,7 @@ struct FunctionEmitter {
TType *typ = typeOfValue(exp);
Obj value;
exp->pushfield("value");
const void *data = lua_topointer(L, -1);
const void *data = tocdata(L, -1);
assert(data);
size_t size = CU->getDataLayout().getTypeAllocSize(typ->type);
Value *r;
Expand Down Expand Up @@ -2857,8 +2882,10 @@ static int terra_compilationunitaddvalue(
const char *modulename = (lua_isnil(L, 2)) ? NULL : lua_tostring(L, 2);
lua_pushvalue(L, 3); // the function definition
cu.fromStack(&value);
TerraCompilationUnit *CU = (TerraCompilationUnit *)cu.cd("llvm_cu");
cu.pushfield("llvm_cu");
TerraCompilationUnit *CU = terra_tocompilationunit(L, -1);
assert(CU);
lua_pop(L, 1);

Types Ty(CU);
CCallingConv CC(CU, &Ty);
Expand Down Expand Up @@ -2895,25 +2922,32 @@ static int terra_compilationunitaddvalue(
return 1;
}

static int terra_llvmsizeof(lua_State *L) {
static void RetrieveCUAndType(lua_State *L, TerraCompilationUnit **CUp,
TType **llvmtypp) {
terra_State *T = terra_getstate(L, 1);
int ref_table = lobj_newreftable(L);
TType *llvmtyp;
TerraCompilationUnit *CU;
{
Obj cu, typ, globals;
lua_pushvalue(L, 1);
cu.initFromStack(L, ref_table);
lua_pushvalue(L, 2);
typ.initFromStack(L, ref_table);
cu.obj("symbols", &globals);
CU = (TerraCompilationUnit *)cu.cd("llvm_cu");
CU->symbols = &globals;
llvmtyp = Types(CU).Get(&typ);
CU->symbols = NULL;
cu.pushfield("llvm_cu");
(*CUp) = terra_tocompilationunit(L, -1);
lua_pop(L, 1);
(*CUp)->symbols = &globals;
*llvmtypp = Types(*CUp).Get(&typ);
(*CUp)->symbols = NULL;
}
lobj_removereftable(T->L, ref_table);
lua_pushnumber(T->L, CU->getDataLayout().getTypeAllocSize(llvmtyp->type));
}

static int terra_llvmsizeof(lua_State *L) {
TerraCompilationUnit *CU;
TType *llvmtyp;
RetrieveCUAndType(L, &CU, &llvmtyp);
lua_pushnumber(L, CU->getDataLayout().getTypeAllocSize(llvmtyp->type));
return 1;
}

Expand Down Expand Up @@ -2976,7 +3010,7 @@ static void *JITGlobalValue(TerraCompilationUnit *CU, GlobalValue *gv) {

static int terra_jit(lua_State *L) {
terra_getstate(L, 1);
TerraCompilationUnit *CU = (TerraCompilationUnit *)terra_tocdatapointer(L, 1);
TerraCompilationUnit *CU = terra_tocompilationunit(L, 1);
GlobalValue *gv = (GlobalValue *)lua_touserdata(L, 2);
double begin = CurrentTimeInSeconds();
void *ptr = JITGlobalValue(CU, gv);
Expand All @@ -2987,8 +3021,7 @@ static int terra_jit(lua_State *L) {
}

static int terra_deletefunction(lua_State *L) {
TerraCompilationUnit *CU =
(TerraCompilationUnit *)terra_tocdatapointer(L, lua_upvalueindex(1));
TerraCompilationUnit *CU = terra_tocompilationunit(L, lua_upvalueindex(1));
TerraFunctionState *fstate = (TerraFunctionState *)lua_touserdata(L, -1);
assert(fstate);
Function *func = fstate->func;
Expand Down Expand Up @@ -3166,7 +3199,7 @@ static int terra_saveobjimpl(lua_State *L) {
bool optimize = lua_toboolean(L, 5);

lua_getfield(L, 3, "llvm_cu");
TerraCompilationUnit *CU = (TerraCompilationUnit *)terra_tocdatapointer(L, -1);
TerraCompilationUnit *CU = terra_tocompilationunit(L, -1);
assert(CU);
if (optimize) {
llvmutil_optimizemodule(CU->M, CU->TT->tm);
Expand Down Expand Up @@ -3215,15 +3248,21 @@ static int terra_saveobjimpl(lua_State *L) {
}

static int terra_pointertolightuserdata(lua_State *L) {
lua_pushlightuserdata(L, terra_tocdatapointer(L, -1));
if (10 != lua_type(L, 1))
return 0; // not a cdata, 10 is from LuaJIT sources since it is not exposed in
// the normal API
void *const *cdata = (void *const *)lua_topointer(L, 1);
if (!cdata) return 0;
lua_pushlightuserdata(L, *cdata);
return 1;
}

static int terra_bindtoluaapi(lua_State *L) {
int N = lua_gettop(L);
assert(N >= 1);
void *const *fn = (void *const *)lua_topointer(L, 1);
void *fn = lua_touserdata(L, 1);
assert(fn);
lua_pushcclosure(L, (lua_CFunction)*fn, N - 1);
lua_pushcclosure(L, (lua_CFunction)fn, N - 1);
return 1;
}
#ifdef _WIN32
Expand All @@ -3249,7 +3288,7 @@ static int terra_linkllvmimpl(lua_State *L) {
terra_State *T = terra_getstate(L, 1);
(void)T;
std::string Err;
TerraTarget *TT = (TerraTarget *)terra_tocdatapointer(L, 1);
TerraTarget *TT = terra_totarget(L, 1);
size_t length;
const char *filename = lua_tolstring(L, 2, &length);
bool fromstring = lua_toboolean(L, 3);
Expand Down Expand Up @@ -3344,7 +3383,7 @@ static int terra_linkllvmimpl(lua_State *L) {
static int terra_dumpmodule(lua_State *L) {
terra_State *T = terra_getstate(L, 1);
(void)T;
TerraCompilationUnit *CU = (TerraCompilationUnit *)terra_tocdatapointer(L, 1);
TerraCompilationUnit *CU = terra_tocompilationunit(L, 1);
if (CU) TERRA_DUMP_MODULE(CU->M);
return 0;
}
13 changes: 12 additions & 1 deletion src/tcompilerstate.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,15 @@ struct terra_CompilerState {
llvm::DenseMap<const void *, TerraFunctionInfo> functioninfo;
};

#endif
static inline TerraCompilationUnit *terra_tocompilationunit(lua_State *L, int idx) {
void *blockaddr = lua_touserdata(L, idx);
if (!blockaddr) return NULL;
return *(TerraCompilationUnit **)blockaddr;
}
static inline TerraTarget *terra_totarget(lua_State *L, int idx) {
void *blockaddr = lua_touserdata(L, idx);
if (!blockaddr) return NULL;
return *(TerraTarget **)blockaddr;
}

#endif
2 changes: 1 addition & 1 deletion src/tcuda.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ int terra_toptx(lua_State *L) {
terra_State *T = terra_getstate(L, 1);
initializeNVVMState(T);
lua_getfield(L, 1, "llvm_cu");
TerraCompilationUnit *CU = (TerraCompilationUnit *)terra_tocdatapointer(L, -1);
TerraCompilationUnit *CU = terra_tocompilationunit(L, -1);
llvm::Module *M = CU->M;
int annotations = 2;
int dumpmodule = lua_toboolean(L, 3);
Expand Down
2 changes: 1 addition & 1 deletion src/tcuda.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ struct terra_State;
int terra_cudainit(struct terra_State* T);
int terra_cudafree(struct terra_State* T);

#endif
#endif
Loading

0 comments on commit 52ab569

Please sign in to comment.