issue #180 removing llvm lua api

old-c-tests
Dibyendu Majumdar 4 years ago
parent 7834343893
commit ea5e34f447

@ -57,11 +57,6 @@ LUAMOD_API int (raviopen_llvmjit)(lua_State *L);
#define LUA_ASTLIBNAME "ast"
LUAMOD_API int (raviopen_ast_library)(lua_State *L);
//#ifdef USE_LLVM
//#define LUA_LLVMLIBNAME "llvm"
//LUAMOD_API int (raviopen_llvmluaapi)(lua_State *L);
//#endif
/** RAVI change end */
/* open all previous libraries */
LUALIB_API void (luaL_openlibs) (lua_State *L);

@ -1,8 +0,0 @@
These are examples using the Lua LLVM bindings.
``helloworld.lua``
This illustrates creating a Lua callable C function that prints hello world.
``fib.lua``
This illustrates implementing a fibonacci sequence in LLVM using Lua.

@ -1,107 +0,0 @@
-- ensure that LLVM bindings are available
assert(llvm)
-- Get the LLVM context - right now this is the
-- global context
context = llvm.context()
assert(ravitype(context) == "LLVMcontext")
-- The bindings provide a number of predefined types that
-- are Lua specific plus some standard C types such as 'int',
-- 'double', 'int64_t', etc.
types = context:types()
print 'Listing types'
for k,v in pairs(types) do
print('\t', k, ravitype(v))
llvm.dump(v)
end
-- ***************************************************\
-- Test creating a struct type
-- Just as an exercise create a struct type
-- Initially we have an opaque struct
gcobject = context:structtype("GCObject")
assert(ravitype(gcobject) == "LLVMstructtype")
-- Create pointer to GCObject
gcobject_p = context:pointertype(gcobject)
assert(ravitype(gcobject_p) == "LLVMpointertype")
-- Add the members of the struct
-- Following demonstrates the use of predefined Lua types
gcobject:setbody {gcobject_p, types.lu_byte, types.lu_byte}
-- Display structure of gcobject
llvm.dump(gcobject)
-- ****************************************************/
-- ****************************************************\
-- Test building a Lua C function without writing C code!
--
-- Create a lua_CFunction instance
-- At this stage the function will get a module and
-- execution engine but no body
myfunc = context:lua_CFunction("myfunc")
assert(ravitype(myfunc) == "LLVMmainfunction")
-- Get a new IRBuilder intance
-- this will be garbage collected by Lua
irbuilder = context:irbuilder()
assert(ravitype(irbuilder) == "LLVMirbuilder")
-- Create a basic block
block = context:basicblock("entry")
-- Add it to the end of the function
myfunc:appendblock(block)
-- Set this as the next instruction point
irbuilder:setinsertpoint(block)
-----------------------------------------------
-- Test calling a predefined extern function
-- Get printf decl
-----------------------------------------------
printf = myfunc:extern("printf")
assert(ravitype(printf) == "LLVMconstant")
luaL_checklstring = myfunc:extern("luaL_checklstring")
assert(ravitype(luaL_checklstring) == "LLVMconstant")
hellostr = irbuilder:stringconstant("hello world!\n")
irbuilder:call(printf, { hellostr })
-------------------------------------------------
-- Test calling a random function
-------------------------------------------------
puts_type = context:functiontype(types.int, {types.pchar}, {vararg=false})
assert(ravitype(puts_type) == "LLVMfunctiontype")
-- Declare extern puts()
puts = myfunc:extern("puts", puts_type);
assert(ravitype(puts) == "LLVMconstant")
-- Get the L parameter of myfunc
L = myfunc:arg(1)
-- get the first argument as a string
str = irbuilder:call(luaL_checklstring, {L, context:intconstant(1),
context:nullconstant(types.psize_t)} )
-- Call puts
irbuilder:call(puts, { str })
-- add CreateRet(0)
inst = irbuilder:ret(context:intconstant(0))
assert(ravitype(inst) == "LLVMinstruction")
-- **************************************************/
-- what did we get?
llvm.dump(myfunc)
-- JIT compile the function
-- returns a C Closure
runnable = myfunc:compile()
print('Type of compiled function is', type(runnable))
assert(not runnable('ok\n'))

@ -1,141 +0,0 @@
-- 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'

@ -1,63 +0,0 @@
-- This small demo creates a compiled function
-- takes a string parameter and calls puts() to
-- print this
-- ensure that LLVM bindings are available
assert(llvm)
-- Get the LLVM context - right now this is the
-- global context
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.
types = context:types()
-- Create a lua_CFunction instance
-- At this stage the function will get a module and
-- execution engine but no body
myfunc = context:lua_CFunction("myfunc")
-- Get a new IRBuilder intance
-- this will be garbage collected by Lua
irbuilder = context:irbuilder()
-- Create a basic block
block = context:basicblock("entry")
-- Add it to the end of the function
myfunc:appendblock(block)
-- Set this as the next instruction point
irbuilder:setinsertpoint(block)
-- get declaration for luaL_checklstring
luaL_checklstring = myfunc:extern("luaL_checklstring")
-- Get the L parameter of myfunc
L = myfunc:arg(1)
-- get the first argument as a string
str = irbuilder:call(luaL_checklstring,
{L, context:intconstant(1),
context:nullconstant(types.psize_t)})
-- declare puts
puts_type = context:functiontype(types.int, {types.pchar})
puts = myfunc:extern("puts", puts_type);
-- Call puts
irbuilder:call(puts, {str})
-- add CreateRet(0)
irbuilder:ret(context:intconstant(0))
-- **************************************************/
-- what did we get?
llvm.dump(myfunc)
-- JIT compile the function
-- returns a C Closure
runnable = myfunc:compile()
assert(not runnable('hello world\n'))

@ -25,7 +25,6 @@ Contents:
ravi-jit-compilation-hook
ravi-lua-types
llvm-tbaa
llvm-bindings
ravi-benchmarks
ravi-jit-status

@ -1,244 +0,0 @@
LLVM Bindings for Lua/Ravi
==========================
As part of the Ravi Programming Language, it is my intention to provide a Lua 5.3 compatible LLVM binding.
This will allow Lua programmers to write their own JIT compilers in Lua!
Right now this is in early development so there is no documentation. But the Lua programs here
demonstrate the features available to date.
LLVM Modules and Execution Engines
----------------------------------
One of the complexities of LLVM is the handling of modules and execution engines in a JIT environment. In Ravi I made the simple decision that each Lua function would get its own module and EE. This allows the function to be
garbage collected as normal and release the associated module and EE. One of
the things that is possible but not yet implemented is releasing the module
and EE early; this requires implementing a custom memory manager (issue #48).
To mimic the Ravi model, the LLVM bindings provide a shortcut to setup
an LLVM module and execution engine for a Lua C function. The following example
illustrates::
-- Get the LLVM context - right now this is the
-- global context
local context = llvm.context()
-- 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("demo")
Above creates an ``llvm::Function`` instance within a new module. An EE is
automatically attached. You can get hold of the module as shown below::
-- Get hold of the module
local module = mainfunc:module()
Other native functions may be created within the same module as normal. However
note that once the Lua function is compiled then no further updates to the
module are possible.
The model I recommend when using this feature is to create one exported
Lua C function in the module, with several private 'internal' supporting functions within the module.
Creating Modules and Execution Engines
--------------------------------------
The LLVM api for these functions are not exposed yet.
Examples
--------
For examples that illustrate the bindings please visit the `llvmbindings folder <https://github.com/dibyendumajumdar/ravi/tree/master/llvmbinding>`_ in the repository.
Type Hierarchy
--------------
The bindings provide a number of Lua types::
+ LLVMcontext
+ LLVMfunction
+ LLVMmainfunction
+ LLVMmodule
+ LLVMtype
+ LLVMstructtype
+ LLVMpointertype
+ LLVMfunctiontype
+ LLVMvalue
+ LLVMinstruction
+ LLVMconstant
+ LLVMphinode
+ LLVMirbuilder
+ LLVMbasicblock
Available Bindings
------------------
The following table lists the Lua LLVM api functions available.
+----------------------------------------------------------------------------------------------+
| Lua LLVM API |
+==============================================================================================+
| ``llvm.context() -> LLVMcontext`` |
| Returns global llvm::Context |
+----------------------------------------------------------------------------------------------+
| **LLVMcontext methods** |
+----------------------------------------------------------------------------------------------+
| ``lua_CFunction(name) -> LLVMmainfunction`` |
| Creates an llvm::Function within a new llvm::Module; and associates an |
| llvm::ExecutionEngine with the module |
| ``types() -> table of predefined type bindings`` |
| Returns a table of predefined LLVM type bindings |
| ``structtype(name) -> LLVMstructtype`` |
| Opaque struct type; body can be added |
| ``pointertype(type) -> LLVMpointertype`` |
| Given a type returns a pointertype |
| ``functiontype(return_type, {argtypes}, {options}) -> LLVMfunctiontype`` |
| Creates a function type with specified return type, argument types. Takes the option |
| 'vararg' which is false by default. |
| ``basicblock(name) -> LLVMbasicblock`` |
| Create a basic block |
| ``intconstant(intgervalue) -> LLVMvalue`` |
| Returns an integer constant value |
| ``nullconstant(pointertype) -> LLVMvalue`` |
| Returns a NULL constant of specified pointertype |
+----------------------------------------------------------------------------------------------+
| **LLVMstructtype methods** |
+----------------------------------------------------------------------------------------------+
| ``setbody({types})`` |
| Adds members to the struct type |
+----------------------------------------------------------------------------------------------+
| **LLVMmainfunction methods** |
+----------------------------------------------------------------------------------------------+
| ``appendblock(LLVMbasicblock)`` |
| Adds a basic block to the end |
| ``compile()`` |
| Compiles the module and returns a reference to the C Closure |
| ``arg(position) -> LLVMvalue`` |
| Returns the argument at position; position >= 1; returns ``nil`` if argument not available |
| ``module() -> LLVMmodule`` |
| Returns the module associated with the function |
| ``extern(name[, functiontype]) -> LLVMconstant`` |
| Returns an extern declaration; A number of Lua Api functions are predefined. |
+----------------------------------------------------------------------------------------------+
| **LLVMmodule methods** |
+----------------------------------------------------------------------------------------------+
| ``newfunction(name, functiontype) -> LLVMfunction`` |
| Returns an internal linkage function within the module |
| ``dump()`` |
| Dumps the module |
+----------------------------------------------------------------------------------------------+
| **LLVMfunction methods** |
+----------------------------------------------------------------------------------------------+
| ``appendblock(LLVMbasicblock)`` |
| Adds a basic block to the end |
| ``arg(position) -> LLVMvalue`` |
| Returns the argument at position; position >= 1; returns ``nil`` if argument not available |
| ``alloca(type[, name [,arraysize]]) -> LLVMinstruction`` |
| Creates a variable in the first block of the function |
+----------------------------------------------------------------------------------------------+
| **LLVMirbuilder methods** |
+----------------------------------------------------------------------------------------------+
| ``setinsertpoint(basicblock)`` |
| Set current basicblock |
| ``ret([value])`` |
| Emit return instruction |
| ``stringconstant(string) -> LLVMvalue`` |
| Create a global string constant |
| ``call({args}, {options}) -> LLVMinstruction`` |
| Emit call instruction; 'tailcall' option is false by default |
| ``br(basicblock) -> LLVMinstruction`` |
| Emit a branch instruction |
| ``condbr(value, true_block, false_block) -> LLVMinstruction`` |
| Emit a conditional branch |
| ``phi(type, num_values[, name]) -> LLVMphinode`` |
| Generate a PHINode |
| |
| GEP Operators |
| |
| ``gep(value, {offsets}) -> LLVMvalue`` |
| getelementptr to obtain ptr to an array or struct element |
| ``inboundsgep(value, {offsets}) -> LLVMvalue`` |
| inbounds version of getelementptr |
| |
| Memory Operators |
| |
| ``load(ptr) -> LLVMinstruction`` |
| Loads the value at ptr |
| ``store(value, ptr) -> LLVMinstruction`` |
| Stores the value to ptr |
| |
| Binary Operators of the form ``op(value1, value2) -> LLVMvalue`` |
| |
| * ``icmpeq`` |
| * ``icmpne`` |
| * ``icmpugt`` |
| * ``icmpuge`` |
| * ``icmpult`` |
| * ``icmpule`` |
| * ``icmpsgt`` |
| * ``icmpsge`` |
| * ``icmpslt`` |
| * ``icmpsle`` |
| * ``fcmpoeq`` |
| * ``fcmpogt`` |
| * ``fcmpoge`` |
| * ``fcmpolt`` |
| * ``fcmpole`` |
| * ``fcmpone`` |
| * ``fcmpord`` |
| * ``fcmpun`` |
| * ``fcmpueq`` |
| * ``fcmpugt`` |
| * ``fcmpuge`` |
| * ``fcmpult`` |
| * ``fcmpule`` |
| * ``fcmpune`` |
| * ``nswadd`` |
| * ``nuwadd`` |
| * ``nswsub`` |
| * ``nuwsub`` |
| * ``udiv`` |
| * ``exactudiv`` |
| * ``sdiv`` |
| * ``exactsdiv`` |
| * ``urem`` |
| * ``srem`` |
| * ``and`` |
| * ``or`` |
| * ``xor`` |
| * ``fadd`` |
| * ``fsub`` |
| * ``fmul`` |
| * ``fdiv`` |
| * ``frem`` |
| |
| Unary Operators of the form ``op(value) -> LLVMvalue`` |
| |
| * ``not`` |
| * ``neg`` |
| * ``fneg`` |
| |
| Conversion Operators of the form ``op(value,type) -> LLVMvalue`` |
| |
| * ``trunc`` |
| * ``zext`` |
| * ``sext`` |
| * ``zextortrunc`` |
| * ``sextortrunc`` |
| * ``fptoui`` |
| * ``fptosi`` |
| * ``uitofp`` |
| * ``sitofp`` |
| * ``fptrunc`` |
| * ``fpext`` |
| * ``ptrtoint`` |
| * ``inttoptr`` |
| * ``bitcast`` |
| * ``sextorbitcast`` |
| * ``zextorbitcast`` |
| * ``truncorbitcast`` |
| * ``pointercast`` |
| * ``fpcast`` |
+----------------------------------------------------------------------------------------------+
| **LLVMphinode methods** |
+----------------------------------------------------------------------------------------------+
| ``addincoming(value, basicblock)`` |
| Adds incoming edge |
+----------------------------------------------------------------------------------------------+

@ -52,9 +52,6 @@ static const luaL_Reg loadedlibs[] = {
{LUA_UTF8LIBNAME, luaopen_utf8},
{LUA_DBLIBNAME, luaopen_debug},
{LUA_RAVILIBNAME, raviopen_llvmjit},
//#ifdef USE_LLVM
// {LUA_LLVMLIBNAME, raviopen_llvmluaapi},
//#endif
#if USE_DMR_C
{ "dmrc", raviopen_dmrcluaapi },
#endif

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save