Version 4 of LLVM

Updated 2010-05-12 12:43:51 by jos

Low Level Virtual Machine

http://llvm.org/

It's being used to speed up Python, check http://code.google.com/p/unladen-swallow/ .

To get started with LLVM, I made a Tcl wrapper for the LLVM C interface. An example:

package require llvmtcl
namespace import llvmtcl::*

# Initialize the JIT
LLVMLinkInJIT
LLVMInitializeNativeTarget

# Create a module and builder
set m [LLVMModuleCreateWithName "testmodule"]
set bld [LLVMCreateBuilder]

# Create a plus10 function, taking one argument and adding 6 and 4 to it
set ft [LLVMFunctionType [LLVMInt32Type] [list [LLVMInt32Type]] 0]
set plus10 [LLVMAddFunction $m "plus10" $ft]

# Create constants
set c6 [LLVMConstInt [LLVMInt32Type] 6 0]
set c4 [LLVMConstInt [LLVMInt32Type] 4 0]

# Create the basic blocks
set entry [LLVMAppendBasicBlock $plus10 entry]

# Put arguments on the stack to avoid having to write select and/or phi nodes
LLVMPositionBuilderAtEnd $bld $entry
set arg0_1 [LLVMGetParam $plus10 0]
set arg0_2 [LLVMBuildAlloca $bld [LLVMInt32Type] arg0]
set arg0_3 [LLVMBuildStore $bld $arg0_1 $arg0_2]

# Do add 10 in two steps to see the optimizer @ work

# Add 6
set arg0_4 [LLVMBuildLoad $bld $arg0_2 "arg0"]
set add6 [LLVMBuildAdd $bld $arg0_4 $c6 "add6"]

# Add 4
set add4 [LLVMBuildAdd $bld $add6 $c4 "add4"]

# Set return
LLVMBuildRet $bld $add4

# Show input
puts [LLVMModuleDump $m]

# Write function as bit code
LLVMWriteBitcodeToFile $m plus10.bc

The resulting LLVM assembly looks like this:

; ModuleID = 'testmodule'

define i32 @plus10(i32) {
entry:
  %arg0 = alloca i32                              ; <i32*> [#uses=2]
  store i32 %0, i32* %arg0
  %arg01 = load i32* %arg0                        ; <i32> [#uses=1]
  %add6 = add i32 %arg01, 6                       ; <i32> [#uses=1]
  %add4 = add i32 %add6, 4                        ; <i32> [#uses=1]
  ret i32 %add4
}

Now run the function:

lassign [LLVMCreateJITCompilerForModule $m 0] rt EE msg
set i [LLVMCreateGenericValueOfInt [LLVMInt32Type] 4 0]
set res [LLVMRunFunction_Tcl $EE $plus10 $i]
puts "plus10(4) = [LLVMGenericValueToInt $res 0]"

Let LLVM optimize the code:

LLVMOptimizeModule $m
puts [LLVMModuleDump $m]

The optimized code looks like this:

; ModuleID = 'testmodule'

define i32 @plus10(i32) nounwind readnone {
  %2 = bitcast i32 0 to i32                       ; <i32> [#uses=0]
  %3 = add i32 %0, 10                             ; <i32> [#uses=1]
  ret i32 %3
}