1//===- executionengine_test.go - Tests for executionengine ----------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file tests bindings for the executionengine component. 11// 12//===----------------------------------------------------------------------===// 13 14package llvm 15 16import ( 17 "testing" 18) 19 20func TestFactorial(t *testing.T) { 21 LinkInMCJIT() 22 InitializeNativeTarget() 23 InitializeNativeAsmPrinter() 24 25 mod := NewModule("fac_module") 26 27 fac_args := []Type{Int32Type()} 28 fac_type := FunctionType(Int32Type(), fac_args, false) 29 fac := AddFunction(mod, "fac", fac_type) 30 fac.SetFunctionCallConv(CCallConv) 31 n := fac.Param(0) 32 33 entry := AddBasicBlock(fac, "entry") 34 iftrue := AddBasicBlock(fac, "iftrue") 35 iffalse := AddBasicBlock(fac, "iffalse") 36 end := AddBasicBlock(fac, "end") 37 38 builder := NewBuilder() 39 defer builder.Dispose() 40 41 builder.SetInsertPointAtEnd(entry) 42 If := builder.CreateICmp(IntEQ, n, ConstInt(Int32Type(), 0, false), "cmptmp") 43 builder.CreateCondBr(If, iftrue, iffalse) 44 45 builder.SetInsertPointAtEnd(iftrue) 46 res_iftrue := ConstInt(Int32Type(), 1, false) 47 builder.CreateBr(end) 48 49 builder.SetInsertPointAtEnd(iffalse) 50 n_minus := builder.CreateSub(n, ConstInt(Int32Type(), 1, false), "subtmp") 51 call_fac_args := []Value{n_minus} 52 call_fac := builder.CreateCall(fac, call_fac_args, "calltmp") 53 res_iffalse := builder.CreateMul(n, call_fac, "multmp") 54 builder.CreateBr(end) 55 56 builder.SetInsertPointAtEnd(end) 57 res := builder.CreatePHI(Int32Type(), "result") 58 phi_vals := []Value{res_iftrue, res_iffalse} 59 phi_blocks := []BasicBlock{iftrue, iffalse} 60 res.AddIncoming(phi_vals, phi_blocks) 61 builder.CreateRet(res) 62 63 err := VerifyModule(mod, ReturnStatusAction) 64 if err != nil { 65 t.Errorf("Error verifying module: %s", err) 66 return 67 } 68 69 options := NewMCJITCompilerOptions() 70 options.SetMCJITOptimizationLevel(2) 71 options.SetMCJITEnableFastISel(true) 72 options.SetMCJITNoFramePointerElim(true) 73 options.SetMCJITCodeModel(CodeModelJITDefault) 74 engine, err := NewMCJITCompiler(mod, options) 75 if err != nil { 76 t.Errorf("Error creating JIT: %s", err) 77 return 78 } 79 defer engine.Dispose() 80 81 pass := NewPassManager() 82 defer pass.Dispose() 83 84 pass.Add(engine.TargetData()) 85 pass.AddConstantPropagationPass() 86 pass.AddInstructionCombiningPass() 87 pass.AddPromoteMemoryToRegisterPass() 88 pass.AddGVNPass() 89 pass.AddCFGSimplificationPass() 90 pass.Run(mod) 91 92 exec_args := []GenericValue{NewGenericValueFromInt(Int32Type(), 10, false)} 93 exec_res := engine.RunFunction(fac, exec_args) 94 var fac10 uint64 = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 95 if exec_res.Int(false) != fac10 { 96 t.Errorf("Expected %d, got %d", fac10, exec_res.Int(false)) 97 } 98} 99