[pypy-svn] r64999 - in pypy/branch/pyjitpl5/pypy/jit/backend/llvm: . test
arigo at codespeak.net
arigo at codespeak.net
Sun May 3 13:49:17 CEST 2009
Author: arigo
Date: Sun May 3 13:49:16 2009
New Revision: 64999
Modified:
pypy/branch/pyjitpl5/pypy/jit/backend/llvm/demo1.c
pypy/branch/pyjitpl5/pypy/jit/backend/llvm/llvm_rffi.py
pypy/branch/pyjitpl5/pypy/jit/backend/llvm/test/test_llvm_rffi.py
Log:
Work hard until the first example of 'llvm-py'is complete
and runs with a JIT.
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llvm/demo1.c
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/llvm/demo1.c (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/llvm/demo1.c Sun May 3 13:49:16 2009
@@ -5,7 +5,7 @@
/* The following list of functions seems to be necessary to force the
* functions to be included in pypy_cache_llvm.so. The list is never
- * used.
+ * used. Actually, any single function seems to be enough...
*/
void* llvm_c_functions[] = {
(void*) LLVMModuleCreateWithName
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llvm/llvm_rffi.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/llvm/llvm_rffi.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/llvm/llvm_rffi.py Sun May 3 13:49:16 2009
@@ -30,10 +30,7 @@
oname = os.path.join(dirname, 'demo1.o')
do("gcc -c '%s' -o '%s'" % (cname, oname))
do("g++ -shared '%s' -o '%s'" % (oname, libname) +
- " `%s --libs jit`" % llvm_config +
- " `%s --cflags`" % llvm_config +
- " `%s --ldflags`" % llvm_config +
- "")
+ " `%s --cflags --ldflags --libs jit engine`" % llvm_config)
compilation_info = ExternalCompilationInfo(
library_dirs = [dirname],
@@ -50,8 +47,87 @@
def opaqueptr(name):
return rffi.VOIDP # lltype.Ptr(rffi.COpaque(name))
-LLVMModuleRef = opaqueptr('struct LLVMModuleOpaque')
+LLVMModuleRef = opaqueptr('struct LLVMOpaqueModule')
+LLVMTypeRef = opaqueptr('struct LLVMOpaqueType')
+LLVMValueRef = opaqueptr('struct LLVMOpaqueValue')
+LLVMBasicBlockRef = opaqueptr('struct LLVMOpaqueBasicBlock')
+LLVMBuilderRef = opaqueptr('struct LLVMOpaqueBuilder')
+LLVMModuleProviderRef = opaqueptr('struct LLVMOpaqueModuleProvider')
+LLVMGenericValueRef = opaqueptr('struct LLVMOpaqueGenericValue')
+LLVMExecutionEngineRef = opaqueptr('struct LLVMOpaqueExecutionEngine')
+
+# ____________________________________________________________
LLVMModuleCreateWithName = llexternal('LLVMModuleCreateWithName',
[rffi.CCHARP],
LLVMModuleRef)
+LLVMDumpModule = llexternal('LLVMDumpModule', [LLVMModuleRef], lltype.Void)
+
+LLVMInt32Type = llexternal('LLVMInt32Type', [], LLVMTypeRef)
+LLVMFunctionType = llexternal('LLVMFunctionType',
+ [LLVMTypeRef, # return type
+ rffi.CArrayPtr(LLVMTypeRef), # param types
+ rffi.UINT, # param count
+ rffi.INT], # flag: is vararg
+ LLVMTypeRef)
+
+LLVMAddFunction = llexternal('LLVMAddFunction',
+ [LLVMModuleRef, # module
+ rffi.CCHARP, # name
+ LLVMTypeRef], # function type
+ LLVMValueRef)
+LLVMGetParam = llexternal('LLVMGetParam',
+ [LLVMValueRef, # function
+ rffi.UINT], # index
+ LLVMValueRef)
+
+LLVMAppendBasicBlock = llexternal('LLVMAppendBasicBlock',
+ [LLVMValueRef, # function
+ rffi.CCHARP], # name
+ LLVMBasicBlockRef)
+
+LLVMCreateBuilder = llexternal('LLVMCreateBuilder', [], LLVMBuilderRef)
+LLVMPositionBuilderAtEnd = llexternal('LLVMPositionBuilderAtEnd',
+ [LLVMBuilderRef, # builder
+ LLVMBasicBlockRef], # block
+ lltype.Void)
+
+LLVMBuildRet = llexternal('LLVMBuildRet', [LLVMBuilderRef, # builder,
+ LLVMValueRef], # result
+ LLVMValueRef)
+LLVMBuildAdd = llexternal('LLVMBuildAdd', [LLVMBuilderRef, # builder
+ LLVMValueRef, # left-hand side
+ LLVMValueRef, # right-hand side
+ rffi.CCHARP], # name of result
+ LLVMValueRef)
+
+LLVMCreateModuleProviderForExistingModule = llexternal(
+ 'LLVMCreateModuleProviderForExistingModule', [LLVMModuleRef],
+ LLVMModuleProviderRef)
+
+# ____________________________________________________________
+
+LLVMCreateGenericValueOfInt = llexternal('LLVMCreateGenericValueOfInt',
+ [LLVMTypeRef, # type
+ rffi.ULONGLONG, # value
+ rffi.INT], # flag: is_signed
+ LLVMGenericValueRef)
+
+LLVMGenericValueToInt = llexternal('LLVMGenericValueToInt',
+ [LLVMGenericValueRef,
+ rffi.INT], # flag: is_signed
+ rffi.ULONGLONG)
+
+LLVMCreateJITCompiler = llexternal('LLVMCreateJITCompiler',
+ [rffi.CArrayPtr(LLVMExecutionEngineRef),
+ LLVMModuleProviderRef,
+ rffi.INT, # "fast"
+ rffi.CArrayPtr(rffi.CCHARP)], # -> error
+ rffi.INT)
+
+LLVMRunFunction = llexternal('LLVMRunFunction',
+ [LLVMExecutionEngineRef,
+ LLVMValueRef, # function
+ rffi.UINT, # num args
+ rffi.CArrayPtr(LLVMGenericValueRef)], # args
+ LLVMGenericValueRef) # return value
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llvm/test/test_llvm_rffi.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/llvm/test/test_llvm_rffi.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/llvm/test/test_llvm_rffi.py Sun May 3 13:49:16 2009
@@ -1,5 +1,91 @@
from pypy.jit.backend.llvm.llvm_rffi import *
-def test_basic():
- LLVMModuleCreateWithName("hello")
+
+def test_from_llvm_py_example_1():
+ # NOTE: no GC so far!!!!!!!!!
+
+ # Create an (empty) module.
+ my_module = LLVMModuleCreateWithName("my_module")
+
+ # All the types involved here are "int"s. This type is represented
+ # by an object of type LLVMTypeRef:
+ ty_int = LLVMInt32Type()
+
+ # We need to represent the class of functions that accept two integers
+ # and return an integer. This is represented by another LLVMTypeRef:
+ arglist = lltype.malloc(rffi.CArray(LLVMTypeRef), 2, flavor='raw')
+ arglist[0] = ty_int
+ arglist[1] = ty_int
+ ty_func = LLVMFunctionType(ty_int, arglist, 2, False)
+ lltype.free(arglist, flavor='raw')
+
+ # Now we need a function named 'sum' of this type. Functions are not
+ # free-standing; it needs to be contained in a module.
+ f_sum = LLVMAddFunction(my_module, "sum", ty_func)
+ f_arg_0 = LLVMGetParam(f_sum, 0)
+ f_arg_1 = LLVMGetParam(f_sum, 1)
+
+ # Our function needs a "basic block" -- a set of instructions that
+ # end with a terminator (like return, branch etc.). By convention
+ # the first block is called "entry".
+ bb = LLVMAppendBasicBlock(f_sum, "entry")
+
+ # Let's add instructions into the block. For this, we need an
+ # instruction builder:
+ builder = LLVMCreateBuilder()
+ LLVMPositionBuilderAtEnd(builder, bb)
+
+ # OK, now for the instructions themselves. We'll create an add
+ # instruction that returns the sum as a value, which we'll use
+ # a ret instruction to return.
+ tmp = LLVMBuildAdd(builder, f_arg_0, f_arg_1, "tmp")
+ LLVMBuildRet(builder, tmp)
+
+ # We've completed the definition now! Let's see the LLVM assembly
+ # language representation of what we've created: (it goes to stderr)
+ LLVMDumpModule(my_module)
+ return locals()
+
+
+class LLVMException(Exception):
+ pass
+
+
+def test_from_llvm_py_example_2():
+ d = test_from_llvm_py_example_1()
+ my_module = d['my_module']
+ ty_int = d['ty_int']
+ f_sum = d['f_sum']
+
+ # Create a module provider object first. Modules can come from
+ # in-memory IRs like what we created now, or from bitcode (.bc)
+ # files. The module provider abstracts this detail.
+ mp = LLVMCreateModuleProviderForExistingModule(my_module)
+
+ # Create an execution engine object. This creates a JIT compiler,
+ # or complain on platforms that don't support it.
+ ee_out = lltype.malloc(rffi.CArray(LLVMExecutionEngineRef), 1, flavor='raw')
+ error_out = lltype.malloc(rffi.CArray(rffi.CCHARP), 1, flavor='raw')
+ try:
+ error = LLVMCreateJITCompiler(ee_out, mp, True, error_out)
+ if rffi.cast(lltype.Signed, error) != 0:
+ raise LLVMException(rffi.charp2str(error_out[0]))
+ ee = ee_out[0]
+ finally:
+ lltype.free(error_out, flavor='raw')
+ lltype.free(ee_out, flavor='raw')
+
+ # The arguments needs to be passed as "GenericValue" objects.
+ args = lltype.malloc(rffi.CArray(LLVMGenericValueRef), 2, flavor='raw')
+ args[0] = LLVMCreateGenericValueOfInt(ty_int, 100, True)
+ args[1] = LLVMCreateGenericValueOfInt(ty_int, 42, True)
+
+ # Now let's compile and run!
+ retval = LLVMRunFunction(ee, f_sum, 2, args)
+ lltype.free(args, flavor='raw')
+
+ # The return value is also GenericValue. Let's check it.
+ ulonglong = LLVMGenericValueToInt(retval, True)
+ res = rffi.cast(lltype.Signed, ulonglong)
+ assert res == 142
More information about the Pypy-commit
mailing list