1 //===- MCJITTest.cpp - Unit tests for the MCJIT ---------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This test suite verifies basic MCJIT functionality when invoked form the C
13 //===----------------------------------------------------------------------===//
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"
27 static bool didCallAllocateCodeSection;
29 static uint8_t *roundTripAllocateCodeSection(void *object, uintptr_t size,
32 didCallAllocateCodeSection = true;
33 return static_cast<SectionMemoryManager*>(object)->allocateCodeSection(
34 size, alignment, sectionID);
37 static uint8_t *roundTripAllocateDataSection(void *object, uintptr_t size,
40 LLVMBool isReadOnly) {
41 return static_cast<SectionMemoryManager*>(object)->allocateDataSection(
42 size, alignment, sectionID, isReadOnly);
45 static LLVMBool roundTripFinalizeMemory(void *object, char **errMsg) {
46 std::string errMsgString;
48 static_cast<SectionMemoryManager*>(object)->finalizeMemory(&errMsgString);
50 *errMsg = LLVMCreateMessage(errMsgString.c_str());
56 static void roundTripDestroy(void *object) {
57 delete static_cast<SectionMemoryManager*>(object);
60 class MCJITCAPITest : public testing::Test, public MCJITTestAPICommon {
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
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);
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");
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);
84 virtual void SetUp() {
85 didCallAllocateCodeSection = false;
92 virtual void TearDown() {
94 LLVMDisposeExecutionEngine(Engine);
96 LLVMDisposeModule(Module);
99 void buildSimpleFunction() {
100 Module = LLVMModuleCreateWithName("simple_module");
102 LLVMSetTarget(Module, HostTriple.c_str());
104 Function = LLVMAddFunction(
105 Module, "simple_function", LLVMFunctionType(LLVMInt32Type(), 0, 0, 0));
106 LLVMSetFunctionCallConv(Function, LLVMCCallConv);
108 LLVMBasicBlockRef entry = LLVMAppendBasicBlock(Function, "entry");
109 LLVMBuilderRef builder = LLVMCreateBuilder();
110 LLVMPositionBuilderAtEnd(builder, entry);
111 LLVMBuildRet(builder, LLVMConstInt(LLVMInt32Type(), 42, 0));
113 LLVMVerifyModule(Module, LLVMAbortProcessAction, &Error);
114 LLVMDisposeMessage(Error);
116 LLVMDisposeBuilder(builder);
119 void buildMCJITOptions() {
120 LLVMInitializeMCJITCompilerOptions(&Options, sizeof(Options));
121 Options.OptLevel = 2;
123 // Just ensure that this field still exists.
124 Options.NoFramePointerElim = false;
127 void useRoundTripSectionMemoryManager() {
128 Options.MCJMM = LLVMCreateSimpleMCJITMemoryManager(
129 new SectionMemoryManager(),
130 roundTripAllocateCodeSection,
131 roundTripAllocateDataSection,
132 roundTripFinalizeMemory,
136 void buildMCJITEngine() {
138 0, LLVMCreateMCJITCompilerForModule(&Engine, Module, &Options,
139 sizeof(Options), &Error));
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);
151 LLVMModuleRef Module;
152 LLVMValueRef Function;
153 LLVMMCJITCompilerOptions Options;
154 LLVMExecutionEngineRef Engine;
158 TEST_F(MCJITCAPITest, simple_function) {
159 SKIP_UNSUPPORTED_PLATFORM;
161 buildSimpleFunction();
170 functionPointer.raw = LLVMGetPointerToGlobal(Engine, Function);
172 EXPECT_EQ(42, functionPointer.usable());
175 TEST_F(MCJITCAPITest, custom_memory_manager) {
176 SKIP_UNSUPPORTED_PLATFORM;
178 buildSimpleFunction();
180 useRoundTripSectionMemoryManager();
188 functionPointer.raw = LLVMGetPointerToGlobal(Engine, Function);
190 EXPECT_EQ(42, functionPointer.usable());
191 EXPECT_TRUE(didCallAllocateCodeSection);