[OCaml] Enable -g for debug builds.
[oota-llvm.git] / bindings / go / llvm / executionengine_test.go
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         engine, err := NewMCJITCompiler(mod, MCJITCompilerOptions{OptLevel: 2})
70         if err != nil {
71                 t.Errorf("Error creating JIT: %s", err)
72                 return
73         }
74         defer engine.Dispose()
75
76         pass := NewPassManager()
77         defer pass.Dispose()
78
79         pass.Add(engine.TargetData())
80         pass.AddConstantPropagationPass()
81         pass.AddInstructionCombiningPass()
82         pass.AddPromoteMemoryToRegisterPass()
83         pass.AddGVNPass()
84         pass.AddCFGSimplificationPass()
85         pass.Run(mod)
86
87         exec_args := []GenericValue{NewGenericValueFromInt(Int32Type(), 10, false)}
88         exec_res := engine.RunFunction(fac, exec_args)
89         var fac10 uint64 = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1
90         if exec_res.Int(false) != fac10 {
91                 t.Errorf("Expected %d, got %d", fac10, exec_res.Int(false))
92         }
93 }