--- a/LLVMExamples.st Fri Aug 07 14:10:48 2015 +0100
+++ b/LLVMExamples.st Sat Aug 08 04:43:00 2015 +0100
@@ -18,7 +18,7 @@
TestCase subclass:#LLVMExamples
instanceVariableNames:''
classVariableNames:''
- poolDictionaries:''
+ poolDictionaries:'LLVMIntPredicate'
category:'LLVM-S-Core-Examples'
!
@@ -56,7 +56,7 @@
their sum (as intptr_t).
"
- | module functionType function functionEntry asm jit externalFunction |
+ | module functionType function asm jit externalFunction |
"/ 1) create a module to which the function would belong. A module is
"/ a set of functions and globals that are compiled at once by the MCJIT. Once
@@ -68,17 +68,11 @@
functionType := LLVMType function: { LLVMType intptr . LLVMType intptr } returning: LLVMType intptr.
function := module addFunctionNamed: 'sum' type: functionType.
- "/ 3) Generate function code. LLVM IR does not work with
- "/ labels / jumps to labels but rather the user is responsible
- "/ for creating basic blocks and adding them to the function.
- "/ Hence, create a basic block named 'entry'
- functionEntry := function addBasicBlockNamed: 'entry'.
-
- "/ 4) To emit LLVM IR, create an IR builder and position it
- "/ to the end of just created basic block.
- asm := LLVMBuilder new.
- asm positionAtEnd: functionEntry.
- asm ret: (asm add: (function parameterAt: 1) and: (function parameterAt: 2)).
+ "/ 2) To emit LLVM IR, get an IR builder for the function.
+ "/ The LLVMFunction>>builder returns a builder on
+ "/ function's entry point (basic block, strictly speaking)
+ asm := function builder.
+ asm ret: (asm add:(function parameterAt:1) _:(function parameterAt:2)).
"/ Now, the module should look like
self assert: (module dumpString =
'; ModuleID = ''example1_sum''
@@ -91,11 +85,11 @@
').
- "/ 5) To compile a function (strictly speaking, whole module) at runtime,
+ "/ 3) To compile a function (strictly speaking, whole module) at runtime,
"/ create a jit object (called ExecutionEngine in LLVM)
jit := LLVMExecutionEngine newForModule: module.
- "/ 6) Finally, obtain a reference to the function. This cause
+ "/ 4) Finally, obtain a reference to the function. This cause
"/ the module to be closed and compiled to machine code.
externalFunction := jit externalOfFunction: function.
@@ -106,7 +100,7 @@
"
"Created: / 17-07-2015 / 11:47:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
- "Modified: / 03-08-2015 / 10:29:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 08-08-2015 / 04:33:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
example2_function_call
@@ -114,26 +108,20 @@
Creates a module with two functions, @sum and @sum_caller. The latter
calls the former.
"
- | module calleeFunctionType calleeFunction calleFunctionEntry
- callerFunctionType callerFunction callerFunctionEntry
- asm jit externalFunction |
+ | module calleeFunctionType calleeFunction callerFunctionType callerFunction asm jit externalFunction |
module := LLVMModule newWithName: testSelector.
calleeFunctionType := LLVMType function: { LLVMType intptr . LLVMType intptr } returning: LLVMType intptr.
calleeFunction := module addFunctionNamed: 'sum' type: calleeFunctionType.
- calleFunctionEntry := calleeFunction addBasicBlockNamed: 'entry'.
- asm := LLVMBuilder new.
- asm positionAtEnd: calleFunctionEntry.
- asm ret: (asm add: (calleeFunction parameterAt: 1) and: (calleeFunction parameterAt: 2)).
+ asm := calleeFunction builder.
+ asm ret: (asm add:(calleeFunction parameterAt:1) _:(calleeFunction parameterAt:2)).
callerFunctionType := LLVMType function: { LLVMType intptr . LLVMType intptr } returning: LLVMType intptr.
callerFunction := module addFunctionNamed: 'sum_caller' type: callerFunctionType.
- callerFunctionEntry := callerFunction addBasicBlockNamed: 'entry'.
- asm := LLVMBuilder new.
- asm positionAtEnd: callerFunctionEntry.
+ asm := callerFunction builder.
asm ret: (asm call: calleeFunction with: (callerFunction parameterAt: 1) with: (callerFunction parameterAt: 2)).
self assert: (module dumpString =
'; ModuleID = ''example2_function_call''
@@ -161,7 +149,7 @@
"
"Created: / 17-07-2015 / 12:45:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
- "Modified: / 03-08-2015 / 10:29:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 08-08-2015 / 04:34:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
example3_hello_world
@@ -172,7 +160,7 @@
| module printfFunctionType printfFunction
helloWorldString
- mainFunctionType mainFunction mainFunctionEntry
+ mainFunctionType mainFunction
asm jit externalFunction |
module := LLVMModule newWithName: testSelector.
@@ -185,9 +173,7 @@
mainFunctionType := LLVMType function: #() returning: LLVMType int32.
mainFunction := module addFunctionNamed: 'main' type: mainFunctionType.
- mainFunctionEntry := mainFunction addBasicBlockNamed: 'entry'.
- asm := LLVMBuilder new.
- asm positionAtEnd: mainFunctionEntry.
+ asm := mainFunction builder.
asm call: printfFunction with: (asm gep: helloWorldString at: #(0 0)).
asm ret: (LLVMConstant sint32: 0).
"
@@ -204,7 +190,43 @@
"
"Created: / 03-08-2015 / 10:28:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
- "Modified: / 05-08-2015 / 20:59:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
- "Modified (comment): / 05-08-2015 / 22:10:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 08-08-2015 / 04:34:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+example4_cond
+ "
+ Creates a function @even(intpr) which returns
+ 1 if the parameter is even or 0 if not.
+ "
+
+ | module
+ functionType function asm isOdd ifOdd ifEven jit externalFunction |
+
+ module := LLVMModule newWithName: testSelector.
+
+ functionType := LLVMType function: { LLVMType intptr } returning: LLVMType intptr.
+ function := module addFunctionNamed: 'even' type: functionType.
+
+ asm := function builder.
+ isOdd := asm icmp: (asm and: (function parameterAt: 1) _: (LLVMConstant uintptr: 1)) _: (LLVMConstant uintptr: 1) cond: LLVMIntEQ.
+ ifOdd := function addBasicBlock.
+ ifOdd builder
+ ret: (LLVMConstant uintptr: 0).
+ ifEven := function addBasicBlock.
+ ifEven builder
+ ret: (LLVMConstant uintptr: 1).
+ asm if: isOdd then: ifOdd else: ifEven.
+
+ jit := LLVMExecutionEngine newForModule: module.
+ externalFunction := jit externalOfFunction: function.
+
+ self assert: (externalFunction callWith: 10) == 1.
+ self assert: (externalFunction callWith: 11) == 0.
+
+ "
+ LLVMExamples example3_cond
+ "
+
+ "Created: / 08-08-2015 / 04:16:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !