| //===- MCJITTest.cpp - Unit tests for the MCJIT ---------------------------===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This test suite verifies basic MCJIT functionality when invoked form the C |
| // API. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "llvm-c/Analysis.h" |
| #include "llvm-c/Core.h" |
| #include "llvm-c/ExecutionEngine.h" |
| #include "llvm-c/Target.h" |
| #include "llvm-c/Transforms/Scalar.h" |
| #include "llvm/Support/Host.h" |
| #include "MCJITTestAPICommon.h" |
| #include "gtest/gtest.h" |
| |
| using namespace llvm; |
| |
| class MCJITCAPITest : public testing::Test, public MCJITTestAPICommon { |
| protected: |
| MCJITCAPITest() { |
| // The architectures below are known to be compatible with MCJIT as they |
| // are copied from test/ExecutionEngine/MCJIT/lit.local.cfg and should be |
| // kept in sync. |
| SupportedArchs.push_back(Triple::arm); |
| SupportedArchs.push_back(Triple::mips); |
| SupportedArchs.push_back(Triple::x86); |
| SupportedArchs.push_back(Triple::x86_64); |
| |
| // The operating systems below are known to be sufficiently incompatible |
| // that they will fail the MCJIT C API tests. |
| UnsupportedOSs.push_back(Triple::Cygwin); |
| } |
| }; |
| |
| TEST_F(MCJITCAPITest, simple_function) { |
| SKIP_UNSUPPORTED_PLATFORM; |
| |
| char *error = 0; |
| |
| // Creates a function that returns 42, compiles it, and runs it. |
| |
| LLVMModuleRef module = LLVMModuleCreateWithName("simple_module"); |
| |
| LLVMValueRef function = LLVMAddFunction( |
| module, "simple_function", LLVMFunctionType(LLVMInt32Type(), 0, 0, 0)); |
| LLVMSetFunctionCallConv(function, LLVMCCallConv); |
| |
| LLVMBasicBlockRef entry = LLVMAppendBasicBlock(function, "entry"); |
| LLVMBuilderRef builder = LLVMCreateBuilder(); |
| LLVMPositionBuilderAtEnd(builder, entry); |
| LLVMBuildRet(builder, LLVMConstInt(LLVMInt32Type(), 42, 0)); |
| |
| LLVMVerifyModule(module, LLVMAbortProcessAction, &error); |
| LLVMDisposeMessage(error); |
| |
| LLVMDisposeBuilder(builder); |
| |
| LLVMMCJITCompilerOptions options; |
| memset(&options, 0, sizeof(options)); |
| options.OptLevel = 2; |
| options.NoFramePointerElim = false; // Just ensure that this field still exists. |
| |
| LLVMExecutionEngineRef engine; |
| ASSERT_EQ( |
| 0, LLVMCreateMCJITCompilerForModule(&engine, module, &options, sizeof(options), |
| &error)); |
| |
| LLVMPassManagerRef pass = LLVMCreatePassManager(); |
| LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass); |
| LLVMAddConstantPropagationPass(pass); |
| LLVMAddInstructionCombiningPass(pass); |
| LLVMRunPassManager(pass, module); |
| LLVMDisposePassManager(pass); |
| |
| union { |
| void *raw; |
| int (*usable)(); |
| } functionPointer; |
| functionPointer.raw = LLVMGetPointerToGlobal(engine, function); |
| |
| EXPECT_EQ(42, functionPointer.usable()); |
| |
| LLVMDisposeExecutionEngine(engine); |
| } |
| |