LLVMExamples.st
changeset 22 789a35bd30ac
parent 19 706be0fcef22
child 23 0744cd9c0acc
--- 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>"
 ! !