e49af05a235db05cb8be636b41870d5908e436d2
[oota-llvm.git] / unittests / ExecutionEngine / MCJIT / MCJITCAPITest.cpp
1 //===- MCJITTest.cpp - Unit tests for the MCJIT ---------------------------===//
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 test suite verifies basic MCJIT functionality when invoked form the C
11 // API.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "llvm-c/Analysis.h"
16 #include "llvm-c/Core.h"
17 #include "llvm-c/ExecutionEngine.h"
18 #include "llvm-c/Target.h"
19 #include "llvm-c/Transforms/Scalar.h"
20 #include "llvm/Support/Host.h"
21 #include "MCJITTestAPICommon.h"
22 #include "gtest/gtest.h"
23
24 using namespace llvm;
25
26 class MCJITCAPITest : public testing::Test, public MCJITTestAPICommon {
27 protected:
28   MCJITCAPITest() {
29     // The architectures below are known to be compatible with MCJIT as they
30     // are copied from test/ExecutionEngine/MCJIT/lit.local.cfg and should be
31     // kept in sync.
32     SupportedArchs.push_back(Triple::aarch64);
33     SupportedArchs.push_back(Triple::arm);
34     SupportedArchs.push_back(Triple::mips);
35     SupportedArchs.push_back(Triple::x86);
36     SupportedArchs.push_back(Triple::x86_64);
37
38     // Some architectures have sub-architectures in which tests will fail, like
39     // ARM. These two vectors will define if they do have sub-archs (to avoid
40     // extra work for those who don't), and if so, if they are listed to work
41     HasSubArchs.push_back(Triple::arm);
42     SupportedSubArchs.push_back("armv6");
43     SupportedSubArchs.push_back("armv7");
44
45     // The operating systems below are known to be sufficiently incompatible
46     // that they will fail the MCJIT C API tests.
47     UnsupportedOSs.push_back(Triple::Cygwin);
48   }
49 };
50
51 TEST_F(MCJITCAPITest, simple_function) {
52   SKIP_UNSUPPORTED_PLATFORM;
53   
54   char *error = 0;
55   
56   // Creates a function that returns 42, compiles it, and runs it.
57   
58   LLVMModuleRef module = LLVMModuleCreateWithName("simple_module");
59
60   LLVMSetTarget(module, HostTriple.c_str());
61   
62   LLVMValueRef function = LLVMAddFunction(
63     module, "simple_function", LLVMFunctionType(LLVMInt32Type(), 0, 0, 0));
64   LLVMSetFunctionCallConv(function, LLVMCCallConv);
65   
66   LLVMBasicBlockRef entry = LLVMAppendBasicBlock(function, "entry");
67   LLVMBuilderRef builder = LLVMCreateBuilder();
68   LLVMPositionBuilderAtEnd(builder, entry);
69   LLVMBuildRet(builder, LLVMConstInt(LLVMInt32Type(), 42, 0));
70   
71   LLVMVerifyModule(module, LLVMAbortProcessAction, &error);
72   LLVMDisposeMessage(error);
73   
74   LLVMDisposeBuilder(builder);
75   
76   LLVMMCJITCompilerOptions options;
77   LLVMInitializeMCJITCompilerOptions(&options, sizeof(options));
78   options.OptLevel = 2;
79   
80   // Just ensure that this field still exists.
81   options.NoFramePointerElim = false;
82   
83   LLVMExecutionEngineRef engine;
84   ASSERT_EQ(
85     0, LLVMCreateMCJITCompilerForModule(&engine, module, &options,
86                                         sizeof(options), &error));
87   
88   LLVMPassManagerRef pass = LLVMCreatePassManager();
89   LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass);
90   LLVMAddConstantPropagationPass(pass);
91   LLVMAddInstructionCombiningPass(pass);
92   LLVMRunPassManager(pass, module);
93   LLVMDisposePassManager(pass);
94   
95   union {
96     void *raw;
97     int (*usable)();
98   } functionPointer;
99   functionPointer.raw = LLVMGetPointerToGlobal(engine, function);
100   
101   EXPECT_EQ(42, functionPointer.usable());
102   
103   LLVMDisposeExecutionEngine(engine);
104 }
105