From c843edd87003c2e823b114df199552681dac7733 Mon Sep 17 00:00:00 2001 From: Matthew Willis Date: Tue, 30 Jun 2009 11:43:04 +0900 Subject: [PATCH] install functions from llvm bytecode, with test --- extra/llvm/core/core.factor | 21 ++++++++- extra/llvm/invoker/invoker.factor | 54 ++++++++++++++++++++++ extra/llvm/jit/jit-tests.factor | 2 +- extra/llvm/jit/jit.factor | 26 ++++++----- extra/llvm/reader/add.bc | Bin 0 -> 204 bytes extra/llvm/reader/add.ll | 5 ++ extra/llvm/reader/reader.factor | 18 ++++++++ extra/llvm/wrappers/wrappers-tests.factor | 4 +- extra/llvm/wrappers/wrappers.factor | 36 ++++++++++----- 9 files changed, 138 insertions(+), 28 deletions(-) create mode 100644 extra/llvm/invoker/invoker.factor create mode 100644 extra/llvm/reader/add.bc create mode 100644 extra/llvm/reader/add.ll create mode 100644 extra/llvm/reader/reader.factor diff --git a/extra/llvm/core/core.factor b/extra/llvm/core/core.factor index 292a25b80b..f63927455a 100644 --- a/extra/llvm/core/core.factor +++ b/extra/llvm/core/core.factor @@ -10,6 +10,8 @@ IN: llvm.core "LLVMCore" "/usr/local/lib/libLLVMCore.dylib" "cdecl" add-library +"LLVMBitReader" "/usr/local/lib/libLLVMBitReader.dylib" "cdecl" add-library + >> ! llvm-c/Core.h @@ -124,9 +126,11 @@ TYPEDEF: void* LLVMBasicBlockRef TYPEDEF: void* LLVMBuilderRef +TYPEDEF: void* LLVMMemoryBufferRef + ! Functions -FUNCTION: void LLVMDisposeMessage ( char *Message ) ; +FUNCTION: void LLVMDisposeMessage ( char* Message ) ; FUNCTION: LLVMModuleRef LLVMModuleCreateWithName ( char* ModuleID ) ; @@ -395,3 +399,18 @@ FUNCTION: LLVMValueRef LLVMBuildExtractValue ( LLVMBuilderRef Builder, LLVMValueRef AggVal, unsigned Index, char* Name ) ; FUNCTION: LLVMValueRef LLVMBuildInsertValue ( LLVMBuilderRef Builder, LLVMValueRef AggVal, LLVMValueRef EltVal, unsigned Index, char* Name ) ; + +! Memory Buffers/Bit Reader + +FUNCTION: int LLVMCreateMemoryBufferWithContentsOfFile +( char* Path, LLVMMemoryBufferRef* OutMemBuf, char** OutMessage ) ; + +FUNCTION: void LLVMDisposeMemoryBuffer ( LLVMMemoryBufferRef MemBuf ) ; + +LIBRARY: LLVMBitReader + +FUNCTION: int LLVMParseBitcode +( LLVMMemoryBufferRef MemBuf, LLVMModuleRef* OutModule, char** OutMessage ) ; + +FUNCTION: int LLVMGetBitcodeModuleProvider +( LLVMMemoryBufferRef MemBuf, LLVMModuleProviderRef* OutMP, char** OutMessage ) ; diff --git a/extra/llvm/invoker/invoker.factor b/extra/llvm/invoker/invoker.factor new file mode 100644 index 0000000000..55ebe6db84 --- /dev/null +++ b/extra/llvm/invoker/invoker.factor @@ -0,0 +1,54 @@ +USING: accessors alien arrays assocs compiler.units effects +io.backend io.pathnames kernel llvm.core llvm.jit llvm.reader +llvm.types make namespaces sequences specialized-arrays.alien +vocabs words ; + +IN: llvm.invoker + +! get function name, ret type, param types and names + +! load module +! iterate through functions in a module + +TUPLE: function name alien return params ; + +: params ( llvm-function -- param-list ) + dup LLVMCountParams + [ LLVMGetParams ] keep >array + [ [ LLVMGetValueName ] [ LLVMTypeOf tref> ] bi 2array ] map ; + +: ( LLVMValueRef -- function ) + function new + over LLVMGetValueName >>name + over LLVMTypeOf tref> type>> return>> >>return + swap params >>params ; + +: (functions) ( llvm-function -- ) + [ dup , LLVMGetNextFunction (functions) ] when* ; + +: functions ( llvm-module -- functions ) + LLVMGetFirstFunction [ (functions) ] { } make [ ] map ; + +: function-effect ( function -- effect ) + [ params>> [ first ] map ] [ void? 0 1 ? ] bi ; + +: install-function ( function -- ) + dup name>> "alien.llvm" create-vocab drop + "alien.llvm" create swap + [ + dup name>> function-pointer , + dup return>> drop "int" , + dup params>> [ drop "int" ] map , + "cdecl" , \ alien-indirect , + ] [ ] make swap function-effect [ define-declared ] with-compilation-unit ; + +: install-module ( name -- ) + thejit get mps>> at [ + module>> functions [ install-function ] each + ] [ "no such module" throw ] if* ; + +: install-bc ( path -- ) + [ normalize-path ] [ file-name ] bi + [ load-into-jit ] keep install-module ; + +<< "alien.llvm" create-vocab drop >> \ No newline at end of file diff --git a/extra/llvm/jit/jit-tests.factor b/extra/llvm/jit/jit-tests.factor index 5a894e5a50..9808ecb953 100644 --- a/extra/llvm/jit/jit-tests.factor +++ b/extra/llvm/jit/jit-tests.factor @@ -1,3 +1,3 @@ USING: destructors llvm.jit llvm.wrappers tools.test ; -[ ] [ "test" [ ] with-disposal [ "test" add-provider ] with-disposal "test" remove-provider ] unit-test \ No newline at end of file +[ ] [ "test" "test" add-module "test" remove-module ] unit-test \ No newline at end of file diff --git a/extra/llvm/jit/jit.factor b/extra/llvm/jit/jit.factor index 5a85742619..9281b609e3 100644 --- a/extra/llvm/jit/jit.factor +++ b/extra/llvm/jit/jit.factor @@ -8,11 +8,7 @@ SYMBOL: thejit TUPLE: jit ee mps ; : empty-engine ( -- engine ) - "initial-module" [ - - ] with-disposal [ - - ] with-disposal ; + "initial-module" ; : ( -- jit ) jit new empty-engine >>ee H{ } clone >>mps ; @@ -25,21 +21,27 @@ TUPLE: jit ee mps ; ! free machine code for each function in module LLVMGetFirstFunction dup ALIEN: 0 = [ drop ] [ (remove-functions) ] if ; -: (remove-provider) ( provider -- ) +: remove-provider ( provider -- ) thejit get ee>> value>> swap value>> f f [ LLVMRemoveModuleProvider drop ] 2keep *void* [ llvm-throw ] when* *void* module new swap >>value [ value>> remove-functions ] with-disposal ; -: remove-provider ( name -- ) +: remove-module ( name -- ) dup thejit get mps>> at [ - (remove-provider) + remove-provider thejit get mps>> delete-at ] [ drop ] if* ; -: add-provider ( provider name -- ) - dup remove-provider - thejit get ee>> value>> pick value>> LLVMAddModuleProvider - [ t >>disposed ] dip thejit get mps>> set-at ; +: add-module ( module name -- ) + [ ] dip [ remove-module ] keep + thejit get ee>> value>> pick + [ [ value>> LLVMAddModuleProvider ] [ t >>disposed drop ] bi ] with-disposal + thejit get mps>> set-at ; + +: function-pointer ( name -- alien ) + thejit get ee>> value>> dup + rot f [ LLVMFindFunction drop ] keep + *void* LLVMGetPointerToGlobal ; thejit [ ] initialize \ No newline at end of file diff --git a/extra/llvm/reader/add.bc b/extra/llvm/reader/add.bc new file mode 100644 index 0000000000000000000000000000000000000000..c0ba738d25855ef9cd68b1504e8c1fc8b061c9ca GIT binary patch literal 204 zcmZ>AK5$Qwhk?O>fq{WhfPn#s7}y(?Cpw;B@njP)vYf=&!lTN{At}ewoz%eN%H%YO z+bKoBNW_9e!jsF$Ma6?_f}*lZQ9}=pVjEW%R|=0j14Ez!0|O_}93!O@915vTEevYT z9;}>d&c|4tjMO+fESU@xrZOJj0IFbMaGnIF7!-I|7`T8;VHQVLrUwFiEI>9Z5Stlz kh$J%}Ol4v$V_?1LBgh6(&QPepz`z7#vl%cPh6*tN01Zmodule ( buffer -- module ) + [ + value>> f f + [ LLVMParseBitcode drop ] 2keep + *void* [ llvm-throw ] when* *void* + module new swap >>value + ] with-disposal ; + +: load-module ( path -- module ) + buffer>module ; + +: load-into-jit ( path name -- ) + [ load-module ] dip add-module ; \ No newline at end of file diff --git a/extra/llvm/wrappers/wrappers-tests.factor b/extra/llvm/wrappers/wrappers-tests.factor index fe90184a5d..321762e2cf 100644 --- a/extra/llvm/wrappers/wrappers-tests.factor +++ b/extra/llvm/wrappers/wrappers-tests.factor @@ -1,5 +1,5 @@ USING: destructors kernel llvm.wrappers sequences tools.test vocabs ; [ ] [ "test" dispose ] unit-test -[ ] [ "test" [ ] with-disposal dispose ] unit-test -[ ] [ "llvm.jit" vocabs member? [ "test" [ ] with-disposal [ ] with-disposal dispose ] unless ] unit-test \ No newline at end of file +[ ] [ "test" dispose ] unit-test +[ ] [ "llvm.jit" vocabs member? [ "test" dispose ] unless ] unit-test \ No newline at end of file diff --git a/extra/llvm/wrappers/wrappers.factor b/extra/llvm/wrappers/wrappers.factor index 2a3e696edc..22da1b36f4 100644 --- a/extra/llvm/wrappers/wrappers.factor +++ b/extra/llvm/wrappers/wrappers.factor @@ -1,10 +1,11 @@ -USING: accessors alien.c-types alien.strings destructors kernel +USING: accessors alien.c-types alien.strings +io.encodings.utf8 destructors kernel llvm.core llvm.engine ; IN: llvm.wrappers : llvm-throw ( char* -- ) - [ alien>string ] [ LLVMDisposeMessage ] bi throw ; + [ utf8 alien>string ] [ LLVMDisposeMessage ] bi throw ; : ( alien class -- disposable ) new swap >>value ; @@ -14,21 +15,21 @@ M: module dispose* value>> LLVMDisposeModule ; : ( name -- module ) LLVMModuleCreateWithName module ; -TUPLE: provider value disposed ; +TUPLE: provider value module disposed ; M: provider dispose* value>> LLVMDisposeModuleProvider ; -: ( module -- module-provider ) - ! we don't want to dispose when an error occurs - ! for example, retries with the same module wouldn't work - ! but we do want to mark the module as disposed on success - [ value>> LLVMCreateModuleProviderForExistingModule ] - [ t >>disposed drop ] bi - provider ; +: (provider) ( module -- provider ) + [ value>> LLVMCreateModuleProviderForExistingModule provider ] + [ t >>disposed value>> ] bi + >>module ; + +: ( module -- provider ) + [ (provider) ] with-disposal ; TUPLE: engine value disposed ; M: engine dispose* value>> LLVMDisposeExecutionEngine ; -: ( provider -- engine ) +: (engine) ( provider -- engine ) [ value>> f f [ swapd 0 swap LLVMCreateJITCompiler drop ] 2keep @@ -37,6 +38,9 @@ M: engine dispose* value>> LLVMDisposeExecutionEngine ; [ t >>disposed drop ] bi engine ; +: ( provider -- engine ) + [ (engine) ] with-disposal ; + : (add-block) ( name -- basic-block ) "function" swap LLVMAppendBasicBlock ; @@ -45,4 +49,12 @@ M: builder dispose* value>> LLVMDisposeBuilder ; : ( name -- builder ) (add-block) LLVMCreateBuilder [ swap LLVMPositionBuilderAtEnd ] keep - builder ; \ No newline at end of file + builder ; + +TUPLE: buffer value disposed ; +M: buffer dispose* value>> LLVMDisposeMemoryBuffer ; + +: ( path -- module ) + f f + [ LLVMCreateMemoryBufferWithContentsOfFile drop ] 2keep + *void* [ llvm-throw ] when* *void* buffer ; \ No newline at end of file -- 2.34.1