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);