[mips] Remove Triple:mips from SupportedArchs in MCJIT unittests
[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/ExecutionEngine/SectionMemoryManager.h"
21 #include "llvm/Support/Host.h"
22 #include "MCJITTestAPICommon.h"
23 #include "gtest/gtest.h"
24
25 using namespace llvm;
26
27 static bool didCallAllocateCodeSection;
28
29 static uint8_t *roundTripAllocateCodeSection(void *object, uintptr_t size,
30                                              unsigned alignment,
31                                              unsigned sectionID) {
32   didCallAllocateCodeSection = true;
33   return static_cast<SectionMemoryManager*>(object)->allocateCodeSection(
34     size, alignment, sectionID);
35 }
36
37 static uint8_t *roundTripAllocateDataSection(void *object, uintptr_t size,
38                                              unsigned alignment,
39                                              unsigned sectionID,
40                                              LLVMBool isReadOnly) {
41   return static_cast<SectionMemoryManager*>(object)->allocateDataSection(
42     size, alignment, sectionID, isReadOnly);
43 }
44
45 static LLVMBool roundTripFinalizeMemory(void *object, char **errMsg) {
46   std::string errMsgString;
47   bool result =
48     static_cast<SectionMemoryManager*>(object)->finalizeMemory(&errMsgString);
49   if (result) {
50     *errMsg = LLVMCreateMessage(errMsgString.c_str());
51     return 1;
52   }
53   return 0;
54 }
55
56 static void roundTripDestroy(void *object) {
57   delete static_cast<SectionMemoryManager*>(object);
58 }
59
60 class MCJITCAPITest : public testing::Test, public MCJITTestAPICommon {
61 protected:
62   MCJITCAPITest() {
63     // The architectures below are known to be compatible with MCJIT as they
64     // are copied from test/ExecutionEngine/MCJIT/lit.local.cfg and should be
65     // kept in sync.
66     SupportedArchs.push_back(Triple::aarch64);
67     SupportedArchs.push_back(Triple::arm);
68     SupportedArchs.push_back(Triple::mips);
69     SupportedArchs.push_back(Triple::x86);
70     SupportedArchs.push_back(Triple::x86_64);
71
72     // Some architectures have sub-architectures in which tests will fail, like
73     // ARM. These two vectors will define if they do have sub-archs (to avoid
74     // extra work for those who don't), and if so, if they are listed to work
75     HasSubArchs.push_back(Triple::arm);
76     SupportedSubArchs.push_back("armv6");
77     SupportedSubArchs.push_back("armv7");
78
79     // The operating systems below are known to be sufficiently incompatible
80     // that they will fail the MCJIT C API tests.
81     UnsupportedOSs.push_back(Triple::Cygwin);
82   }
83   
84   virtual void SetUp() {
85     didCallAllocateCodeSection = false;
86     Module = 0;
87     Function = 0;
88     Engine = 0;
89     Error = 0;
90   }
91   
92   virtual void TearDown() {
93     if (Engine)
94       LLVMDisposeExecutionEngine(Engine);
95     else if (Module)
96       LLVMDisposeModule(Module);
97   }
98   
99   void buildSimpleFunction() {
100     Module = LLVMModuleCreateWithName("simple_module");
101     
102     LLVMSetTarget(Module, HostTriple.c_str());
103     
104     Function = LLVMAddFunction(
105       Module, "simple_function", LLVMFunctionType(LLVMInt32Type(), 0, 0, 0));
106     LLVMSetFunctionCallConv(Function, LLVMCCallConv);
107     
108     LLVMBasicBlockRef entry = LLVMAppendBasicBlock(Function, "entry");
109     LLVMBuilderRef builder = LLVMCreateBuilder();
110     LLVMPositionBuilderAtEnd(builder, entry);
111     LLVMBuildRet(builder, LLVMConstInt(LLVMInt32Type(), 42, 0));
112     
113     LLVMVerifyModule(Module, LLVMAbortProcessAction, &Error);
114     LLVMDisposeMessage(Error);
115     
116     LLVMDisposeBuilder(builder);
117   }
118   
119   void buildMCJITOptions() {
120     LLVMInitializeMCJITCompilerOptions(&Options, sizeof(Options));
121     Options.OptLevel = 2;
122     
123     // Just ensure that this field still exists.
124     Options.NoFramePointerElim = false;
125   }
126   
127   void useRoundTripSectionMemoryManager() {
128     Options.MCJMM = LLVMCreateSimpleMCJITMemoryManager(
129       new SectionMemoryManager(),
130       roundTripAllocateCodeSection,
131       roundTripAllocateDataSection,
132       roundTripFinalizeMemory,
133       roundTripDestroy);
134   }
135   
136   void buildMCJITEngine() {
137     ASSERT_EQ(
138       0, LLVMCreateMCJITCompilerForModule(&Engine, Module, &Options,
139                                           sizeof(Options), &Error));
140   }
141   
142   void buildAndRunPasses() {
143     LLVMPassManagerRef pass = LLVMCreatePassManager();
144     LLVMAddTargetData(LLVMGetExecutionEngineTargetData(Engine), pass);
145     LLVMAddConstantPropagationPass(pass);
146     LLVMAddInstructionCombiningPass(pass);
147     LLVMRunPassManager(pass, Module);
148     LLVMDisposePassManager(pass);
149   }
150   
151   LLVMModuleRef Module;
152   LLVMValueRef Function;
153   LLVMMCJITCompilerOptions Options;
154   LLVMExecutionEngineRef Engine;
155   char *Error;
156 };
157
158 TEST_F(MCJITCAPITest, simple_function) {
159   SKIP_UNSUPPORTED_PLATFORM;
160   
161   buildSimpleFunction();
162   buildMCJITOptions();
163   buildMCJITEngine();
164   buildAndRunPasses();
165   
166   union {
167     void *raw;
168     int (*usable)();
169   } functionPointer;
170   functionPointer.raw = LLVMGetPointerToGlobal(Engine, Function);
171   
172   EXPECT_EQ(42, functionPointer.usable());
173 }
174
175 TEST_F(MCJITCAPITest, custom_memory_manager) {
176   SKIP_UNSUPPORTED_PLATFORM;
177   
178   buildSimpleFunction();
179   buildMCJITOptions();
180   useRoundTripSectionMemoryManager();
181   buildMCJITEngine();
182   buildAndRunPasses();
183   
184   union {
185     void *raw;
186     int (*usable)();
187   } functionPointer;
188   functionPointer.raw = LLVMGetPointerToGlobal(Engine, Function);
189   
190   EXPECT_EQ(42, functionPointer.usable());
191   EXPECT_TRUE(didCallAllocateCodeSection);
192 }