83
|
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
|
|
14 package llvm
|
|
15
|
|
16 import (
|
|
17 "testing"
|
|
18 )
|
|
19
|
|
20 func 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 }
|