LLVMExamples.st
changeset 24 7e7ddd55174c
parent 23 0744cd9c0acc
child 28 97013ae2abae
equal deleted inserted replaced
23:0744cd9c0acc 24:7e7ddd55174c
   120 
   120 
   121     callerFunctionType := LLVMType function: { LLVMType intptr . LLVMType intptr } returning: LLVMType intptr.
   121     callerFunctionType := LLVMType function: { LLVMType intptr . LLVMType intptr } returning: LLVMType intptr.
   122     callerFunction := module addFunctionNamed: 'sum_caller' type: callerFunctionType.
   122     callerFunction := module addFunctionNamed: 'sum_caller' type: callerFunctionType.
   123 
   123 
   124     asm := callerFunction builder.
   124     asm := callerFunction builder.
   125     asm ret: (asm call: calleeFunction with: (callerFunction parameterAt: 1) with: (callerFunction parameterAt: 2)).
   125     asm ret: (asm call: calleeFunction _: { (callerFunction parameterAt: 1) . (callerFunction parameterAt: 2) }).
   126      self assert: (module dumpString = 
   126     self assert: (module dumpString = 
   127 '; ModuleID = ''example2_function_call''
   127 '; ModuleID = ''example2_function_call''
   128 
   128 
   129 define i64 @sum(i64, i64) {
   129 define i64 @sum(i64, i64) {
   130 entry:
   130 entry:
   131   %2 = add i64 %0, %1
   131   %2 = add i64 %0, %1
   147     "
   147     "
   148     LLVMExamples example2_function_call
   148     LLVMExamples example2_function_call
   149     "
   149     "
   150 
   150 
   151     "Created: / 17-07-2015 / 12:45:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   151     "Created: / 17-07-2015 / 12:45:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   152     "Modified: / 08-08-2015 / 04:34:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   152     "Modified: / 10-08-2015 / 18:58:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   153 !
   153 !
   154 
   154 
   155 example3_hello_world
   155 example3_hello_world
   156     "
   156     "
   157     Creates a function @main() which calls @printf() to print
   157     Creates a function @main() which calls @printf() to print
   172 
   172 
   173     mainFunctionType := LLVMType function: #() returning: LLVMType int32.
   173     mainFunctionType := LLVMType function: #() returning: LLVMType int32.
   174     mainFunction := module addFunctionNamed: 'main' type: mainFunctionType.
   174     mainFunction := module addFunctionNamed: 'main' type: mainFunctionType.
   175 
   175 
   176     asm := mainFunction builder.
   176     asm := mainFunction builder.
   177     asm call: printfFunction with: (asm gep: helloWorldString at: #(0 0)).
   177     asm call: printfFunction _: { asm gep: helloWorldString at: #(0 0) }.
   178     asm ret: (LLVMConstant sint32: 0).
   178     asm ret: (LLVMConstant sint32: 0).
   179     "
   179     "
   180     module writeBitcodeToFile: '/tmp/main.bc'
   180     module writeBitcodeToFile: '/tmp/main.bc'
   181     "    
   181     "    
   182     jit := LLVMExecutionEngine newForModule: module.
   182     jit := LLVMExecutionEngine newForModule: module.
   188     "
   188     "
   189     LLVMExamples example3_hello_world
   189     LLVMExamples example3_hello_world
   190     "
   190     "
   191 
   191 
   192     "Created: / 03-08-2015 / 10:28:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   192     "Created: / 03-08-2015 / 10:28:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   193     "Modified: / 08-08-2015 / 04:34:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   193     "Modified: / 10-08-2015 / 18:58:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   194 !
   194 !
   195 
   195 
   196 example4_cond
   196 example4_cond
   197     "
   197     "
   198     Creates a function @even(intpr) which returns
   198     Creates a function @even(intpr) which returns
   301     "
   301     "
   302     LLVMExamples example3_cond
   302     LLVMExamples example3_cond
   303     "
   303     "
   304 
   304 
   305     "Created: / 10-08-2015 / 09:46:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   305     "Created: / 10-08-2015 / 09:46:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   306 !
       
   307 
       
   308 example5_factorial_with_overflow
       
   309     "
       
   310     Simple factorial using recursive algorithm.
       
   311     This one checks for overflow, if overflow happens,
       
   312     return -1
       
   313     "    
       
   314 
       
   315     | module 
       
   316       functionType function asm 
       
   317       "Variables" result i 
       
   318       "Blocks"    entry loop loopBody1 loopBody2 exit overflow
       
   319       smulWithOverflow
       
   320       smulWithOverflowValue
       
   321       jit externalFunction |
       
   322 
       
   323     module := LLVMModule newWithName: testSelector.
       
   324 
       
   325     functionType := LLVMType function: { LLVMType intptr } returning: LLVMType intptr.
       
   326     function := module addFunctionNamed: 'factorial' type: functionType.
       
   327 
       
   328     asm := LLVMBuilder new.
       
   329     entry := function entry.
       
   330     loop  := function addBasicBlockNamed: 'loop'.
       
   331     loopBody1  := function addBasicBlockNamed: 'loopBody1'.
       
   332     loopBody2  := function addBasicBlockNamed: 'loopBody2'.
       
   333     exit  := function addBasicBlockNamed: 'exit'.
       
   334     overflow  := function addBasicBlockNamed: 'overflow'.  
       
   335 
       
   336     "/ Generate function setup
       
   337     "/ 
       
   338     "/   function f(v) {
       
   339     "/     var result;
       
   340     "/     var i;
       
   341     "/     result = 0;
       
   342     "/     i := v;
       
   343     asm block: entry.
       
   344     result := asm alloca: LLVMType intptr as: 'result'.
       
   345     i := asm alloca: LLVMType intptr as: 'i'.
       
   346     asm store: (function parameterAt: 1)   _: i.
       
   347     asm store: (function parameterAt: 1) _: result.
       
   348     asm br: loop.
       
   349 
       
   350     "/ Generate loop that computes the factorial
       
   351     "/ 
       
   352     "/     while ( i > 1 ) {
       
   353     "/       result = result * i if overflow goto overflow;
       
   354     "/       i = i - 1.
       
   355     "/     }
       
   356     "/ 
       
   357     "/ First, get the llvm.smul.with.overflow intrinsic:
       
   358     smulWithOverflow := module getIntrinsicNamed: 'llvm.smul.with.overflow' types: {  LLVMType intptr }.
       
   359 
       
   360     "/ Now code the loop
       
   361     asm block: loop.
       
   362     asm if: (asm icmp: (asm load: i) _: (LLVMConstant sintptr:1) cond: LLVMIntSGT) then: loopBody1 else: exit.
       
   363     asm block: loopBody1.
       
   364     smulWithOverflowValue := asm call: smulWithOverflow _: { (asm load: result) . (asm load: i) }.
       
   365     asm if: (asm extractvalue: smulWithOverflowValue at: 1) then: overflow else: loopBody2.
       
   366     asm block: loopBody2.
       
   367     asm store: (asm extractvalue: smulWithOverflowValue at: 0) _: result.
       
   368     asm store: (asm sub: (asm load: i) _: (LLVMConstant sintptr:1)) _: i.
       
   369     asm br: loop.
       
   370 
       
   371     "/ Generate return from function
       
   372     "/ 
       
   373     "/     return result;
       
   374     "/ 
       
   375     asm block: exit.
       
   376     asm ret: (asm load: result).
       
   377 
       
   378     "/ Generate overflow handler
       
   379     "/     overflow:
       
   380     "/     return -1;
       
   381     "/ 
       
   382     asm block: overflow.
       
   383     asm ret: (LLVMConstant sintptr: -1).  
       
   384     
       
   385 
       
   386     jit := LLVMExecutionEngine newForModule: module.
       
   387     externalFunction := jit externalOfFunction: function.
       
   388 
       
   389     self assert: (externalFunction callWith: 5)   ==  120.
       
   390     self assert: (externalFunction callWith: 1)   ==  1.
       
   391     self assert: (externalFunction callWith: 120) == -1.
       
   392 
       
   393     "sly    LLVMExamples example3_cond
       
   394     "
       
   395 
       
   396     "Created: / 10-08-2015 / 17:12:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   397     "Modified: / 10-08-2015 / 18:58:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   306 ! !
   398 ! !
   307 
   399