Andrew Kaylor | d2755af | 2013-04-29 17:49:40 +0000 | [diff] [blame] | 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. |
Tim Northover | 233a4d7 | 2013-05-19 19:44:56 +0000 | [diff] [blame] | 32 | SupportedArchs.push_back(Triple::aarch64); |
Andrew Kaylor | d2755af | 2013-04-29 17:49:40 +0000 | [diff] [blame] | 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 | // The operating systems below are known to be sufficiently incompatible |
| 39 | // that they will fail the MCJIT C API tests. |
| 40 | UnsupportedOSs.push_back(Triple::Cygwin); |
| 41 | } |
| 42 | }; |
| 43 | |
| 44 | TEST_F(MCJITCAPITest, simple_function) { |
| 45 | SKIP_UNSUPPORTED_PLATFORM; |
| 46 | |
| 47 | char *error = 0; |
| 48 | |
| 49 | // Creates a function that returns 42, compiles it, and runs it. |
| 50 | |
| 51 | LLVMModuleRef module = LLVMModuleCreateWithName("simple_module"); |
Andrew Kaylor | 50be71d | 2013-05-10 17:58:41 +0000 | [diff] [blame] | 52 | |
| 53 | LLVMSetTarget(module, HostTriple.c_str()); |
Andrew Kaylor | d2755af | 2013-04-29 17:49:40 +0000 | [diff] [blame] | 54 | |
| 55 | LLVMValueRef function = LLVMAddFunction( |
| 56 | module, "simple_function", LLVMFunctionType(LLVMInt32Type(), 0, 0, 0)); |
| 57 | LLVMSetFunctionCallConv(function, LLVMCCallConv); |
| 58 | |
| 59 | LLVMBasicBlockRef entry = LLVMAppendBasicBlock(function, "entry"); |
| 60 | LLVMBuilderRef builder = LLVMCreateBuilder(); |
| 61 | LLVMPositionBuilderAtEnd(builder, entry); |
| 62 | LLVMBuildRet(builder, LLVMConstInt(LLVMInt32Type(), 42, 0)); |
| 63 | |
| 64 | LLVMVerifyModule(module, LLVMAbortProcessAction, &error); |
| 65 | LLVMDisposeMessage(error); |
| 66 | |
| 67 | LLVMDisposeBuilder(builder); |
| 68 | |
| 69 | LLVMMCJITCompilerOptions options; |
Filip Pizlo | 0e1327e | 2013-05-01 22:58:00 +0000 | [diff] [blame] | 70 | LLVMInitializeMCJITCompilerOptions(&options, sizeof(options)); |
Andrew Kaylor | d2755af | 2013-04-29 17:49:40 +0000 | [diff] [blame] | 71 | options.OptLevel = 2; |
Filip Pizlo | a4fa74e | 2013-05-01 06:46:59 +0000 | [diff] [blame] | 72 | |
| 73 | // Just ensure that this field still exists. |
| 74 | options.NoFramePointerElim = false; |
Andrew Kaylor | d2755af | 2013-04-29 17:49:40 +0000 | [diff] [blame] | 75 | |
| 76 | LLVMExecutionEngineRef engine; |
| 77 | ASSERT_EQ( |
Filip Pizlo | a4fa74e | 2013-05-01 06:46:59 +0000 | [diff] [blame] | 78 | 0, LLVMCreateMCJITCompilerForModule(&engine, module, &options, |
| 79 | sizeof(options), &error)); |
Andrew Kaylor | d2755af | 2013-04-29 17:49:40 +0000 | [diff] [blame] | 80 | |
| 81 | LLVMPassManagerRef pass = LLVMCreatePassManager(); |
| 82 | LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass); |
| 83 | LLVMAddConstantPropagationPass(pass); |
| 84 | LLVMAddInstructionCombiningPass(pass); |
| 85 | LLVMRunPassManager(pass, module); |
| 86 | LLVMDisposePassManager(pass); |
| 87 | |
| 88 | union { |
| 89 | void *raw; |
| 90 | int (*usable)(); |
| 91 | } functionPointer; |
| 92 | functionPointer.raw = LLVMGetPointerToGlobal(engine, function); |
| 93 | |
| 94 | EXPECT_EQ(42, functionPointer.usable()); |
| 95 | |
| 96 | LLVMDisposeExecutionEngine(engine); |
| 97 | } |
| 98 | |