[jdc] 21-may-2010 To learn [LLVM] I made a wrapper got LLVM's C API. This wrapper is available at: http://github.com/jdc8/llvmtcl **Building the wrapper** The wrapper uses LLVM's C API as found in LLVM's header file `Core.h` in `include\llvm-c`. Requirements: * [LLVM] 2.7 * [Tcl] 8.5 (most test have been done with Tcl HEAD) There is a `Makefile` to build the extension; 1. Edit the `Makefile` to specify the paths to your Tcl and LLVM. 1. Run `make` to build the extension. 1. You'll also have to add LLVM's lib path to `LD_LIBRARY_PATH`. 1. Run `make test` to check it the extension is working **Using the LLVM API** Building a factorial function: ====== lappend auto_path . package require llvmtcl namespace import llvmtcl::* LLVMLinkInJIT LLVMInitializeNativeTarget set m [LLVMModuleCreateWithName "testmodule"] set bld [LLVMCreateBuilder] # Create a function with an int32 argument returning an int32 set ft [LLVMFunctionType [LLVMInt32Type] [list [LLVMInt32Type]] 0] set fac [LLVMAddFunction $m "fac" $ft] # Create constants set two [LLVMConstInt [LLVMInt32Type] 2 0] set one [LLVMConstInt [LLVMInt32Type] 1 0] # Create the basic blocks set entry [LLVMAppendBasicBlock $fac entry] set exit_lt_2 [LLVMAppendBasicBlock $fac exit_lt_2] set recurse [LLVMAppendBasicBlock $fac recurse] # Put arguments on the stack to avoid having to write select and/or phi nodes LLVMPositionBuilderAtEnd $bld $entry set arg0_1 [LLVMGetParam $fac 0] set arg0_2 [LLVMBuildAlloca $bld [LLVMInt32Type] arg0] set arg0_3 [LLVMBuildStore $bld $arg0_1 $arg0_2] # Compare input < 2 set arg0_4 [LLVMBuildLoad $bld $arg0_2 "n"] set cc [LLVMBuildICmp $bld LLVMIntSLT $arg0_4 $two "cc"] # Branch LLVMBuildCondBr $bld $cc $exit_lt_2 $recurse # If n < 2, return 1 LLVMPositionBuilderAtEnd $bld $exit_lt_2 LLVMBuildRet $bld $one # If >= 2, return n*fac(n-1) LLVMPositionBuilderAtEnd $bld $recurse set arg0_5 [LLVMBuildLoad $bld $arg0_2 "n"] set arg0_minus_1 [LLVMBuildSub $bld $arg0_5 $one "arg0_minus_1"] set fc [LLVMBuildCall $bld $fac [list $arg0_minus_1] "rec"] set rt [LLVMBuildMul $bld $arg0_5 $fc "rt"] LLVMBuildRet $bld $rt # Done # Create function returning fac(10) set ft [LLVMFunctionType [LLVMInt32Type] [list] 0] set fac10 [LLVMAddFunction $m "fac10" $ft] set ten [LLVMConstInt [LLVMInt32Type] 10 0] set main [LLVMAppendBasicBlock $fac10 main] LLVMPositionBuilderAtEnd $bld $main set rt [LLVMBuildCall $bld $fac [list $ten] "rec"] LLVMBuildRet $bld $rt # Write LLVM bit code to file LLVMWriteBitcodeToFile $m fac.bc # Write LLVM textual representation to file set f [open fac.ll w] puts $f [LLVMDumpModule $m] close $f # Verify the module lassign [LLVMVerifyModule $m LLVMReturnStatusAction] rt msg if {$rt} { error $msg } # Run the fac and fac10 functions lassign [LLVMCreateJITCompilerForModule $m 0] rt EE msg set i [LLVMCreateGenericValueOfInt [LLVMInt32Type] 10 0] set res [LLVMRunFunction $EE $fac $i] puts "res=$res=[LLVMGenericValueToInt $res 0]" set res [LLVMRunFunction $EE $fac10 {}] puts "res=$res=[LLVMGenericValueToInt $res 0]" # Time runs of fac and fac10 puts [time {LLVMRunFunction $EE $fac $i} 1000] puts [time {LLVMRunFunction $EE $fac10 {}} 1000] # Optimize functions and module set td [LLVMCreateTargetData ""] LLVMSetDataLayout $m [LLVMCopyStringRepOfTargetData $td] for {set t 0} {$t < 10} {incr t} { LLVMOptimizeFunction $m $fac 3 $td LLVMOptimizeFunction $m $fac10 3 $td LLVMOptimizeModule $m 3 0 1 1 1 0 $td } # Write LLVM bit code to file LLVMWriteBitcodeToFile $m fac-optimized.bc # Write LLVM textual representation to file set f [open fac-optimized.ll w] puts $f [LLVMDumpModule $m] close $f # Time runs of fac and fac10 puts [time {LLVMRunFunction $EE $fac $i} 1000] puts [time {LLVMRunFunction $EE $fac10 {}} 1000] ====== **Transforming Tcl into LLVM bit code** <>Enter Category Here