1d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor//===- MCJITTest.cpp - Unit tests for the MCJIT ---------------------------===// 2d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor// 3d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor// The LLVM Compiler Infrastructure 4d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor// 5d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor// This file is distributed under the University of Illinois Open Source 6d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor// License. See LICENSE.TXT for details. 7d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor// 8d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor//===----------------------------------------------------------------------===// 9d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor// 10d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor// This test suite verifies basic MCJIT functionality when invoked form the C 11d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor// API. 12d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor// 13d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor//===----------------------------------------------------------------------===// 14d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor 15d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor#include "llvm-c/Analysis.h" 16d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor#include "llvm-c/Core.h" 17d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor#include "llvm-c/ExecutionEngine.h" 18d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor#include "llvm-c/Target.h" 19d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor#include "llvm-c/Transforms/Scalar.h" 206cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo#include "llvm/ExecutionEngine/SectionMemoryManager.h" 21d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor#include "llvm/Support/Host.h" 22d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor#include "MCJITTestAPICommon.h" 23d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor#include "gtest/gtest.h" 24d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor 25d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylorusing namespace llvm; 26d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor 276cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlostatic bool didCallAllocateCodeSection; 286cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo 296cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlostatic uint8_t *roundTripAllocateCodeSection(void *object, uintptr_t size, 306cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo unsigned alignment, 316cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo unsigned sectionID) { 326cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo didCallAllocateCodeSection = true; 336cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo return static_cast<SectionMemoryManager*>(object)->allocateCodeSection( 346cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo size, alignment, sectionID); 356cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo} 366cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo 376cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlostatic uint8_t *roundTripAllocateDataSection(void *object, uintptr_t size, 386cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo unsigned alignment, 396cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo unsigned sectionID, 406cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo LLVMBool isReadOnly) { 416cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo return static_cast<SectionMemoryManager*>(object)->allocateDataSection( 426cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo size, alignment, sectionID, isReadOnly); 436cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo} 446cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo 456cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlostatic LLVMBool roundTripFinalizeMemory(void *object, char **errMsg) { 466cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo std::string errMsgString; 476cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo bool result = 486cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo static_cast<SectionMemoryManager*>(object)->finalizeMemory(&errMsgString); 496cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo if (result) { 506cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo *errMsg = LLVMCreateMessage(errMsgString.c_str()); 516cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo return 1; 526cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo } 536cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo return 0; 546cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo} 556cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo 566cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlostatic void roundTripDestroy(void *object) { 576cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo delete static_cast<SectionMemoryManager*>(object); 586cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo} 596cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo 60d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylorclass MCJITCAPITest : public testing::Test, public MCJITTestAPICommon { 61d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylorprotected: 62d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor MCJITCAPITest() { 63d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor // The architectures below are known to be compatible with MCJIT as they 64d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor // are copied from test/ExecutionEngine/MCJIT/lit.local.cfg and should be 65d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor // kept in sync. 66233a4d7124ecf9611804e3c75102cdcf7d2fd074Tim Northover SupportedArchs.push_back(Triple::aarch64); 67d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor SupportedArchs.push_back(Triple::arm); 68d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor SupportedArchs.push_back(Triple::mips); 69d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor SupportedArchs.push_back(Triple::x86); 70d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor SupportedArchs.push_back(Triple::x86_64); 71d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor 724e4464bf744030ae4a775bf49a30e9e4ea625682Renato Golin // Some architectures have sub-architectures in which tests will fail, like 734e4464bf744030ae4a775bf49a30e9e4ea625682Renato Golin // ARM. These two vectors will define if they do have sub-archs (to avoid 744e4464bf744030ae4a775bf49a30e9e4ea625682Renato Golin // extra work for those who don't), and if so, if they are listed to work 754e4464bf744030ae4a775bf49a30e9e4ea625682Renato Golin HasSubArchs.push_back(Triple::arm); 764e4464bf744030ae4a775bf49a30e9e4ea625682Renato Golin SupportedSubArchs.push_back("armv6"); 774e4464bf744030ae4a775bf49a30e9e4ea625682Renato Golin SupportedSubArchs.push_back("armv7"); 784e4464bf744030ae4a775bf49a30e9e4ea625682Renato Golin 79d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor // The operating systems below are known to be sufficiently incompatible 80d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor // that they will fail the MCJIT C API tests. 81d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor UnsupportedOSs.push_back(Triple::Cygwin); 82d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor } 83d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor 846cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo virtual void SetUp() { 856cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo didCallAllocateCodeSection = false; 866cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo Module = 0; 876cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo Function = 0; 886cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo Engine = 0; 896cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo Error = 0; 906cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo } 91d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor 926cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo virtual void TearDown() { 936cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo if (Engine) 946cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo LLVMDisposeExecutionEngine(Engine); 956cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo else if (Module) 966cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo LLVMDisposeModule(Module); 976cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo } 98d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor 996cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo void buildSimpleFunction() { 1006cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo Module = LLVMModuleCreateWithName("simple_module"); 1016cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo 1026cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo LLVMSetTarget(Module, HostTriple.c_str()); 1036cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo 1046cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo Function = LLVMAddFunction( 1056cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo Module, "simple_function", LLVMFunctionType(LLVMInt32Type(), 0, 0, 0)); 1066cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo LLVMSetFunctionCallConv(Function, LLVMCCallConv); 1076cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo 1086cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo LLVMBasicBlockRef entry = LLVMAppendBasicBlock(Function, "entry"); 1096cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo LLVMBuilderRef builder = LLVMCreateBuilder(); 1106cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo LLVMPositionBuilderAtEnd(builder, entry); 1116cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo LLVMBuildRet(builder, LLVMConstInt(LLVMInt32Type(), 42, 0)); 1126cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo 1136cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo LLVMVerifyModule(Module, LLVMAbortProcessAction, &Error); 1146cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo LLVMDisposeMessage(Error); 1156cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo 1166cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo LLVMDisposeBuilder(builder); 1176cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo } 118d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor 1196cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo void buildMCJITOptions() { 1206cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo LLVMInitializeMCJITCompilerOptions(&Options, sizeof(Options)); 1216cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo Options.OptLevel = 2; 1226cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo 1236cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo // Just ensure that this field still exists. 1246cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo Options.NoFramePointerElim = false; 1256cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo } 126d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor 1276cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo void useRoundTripSectionMemoryManager() { 1286cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo Options.MCJMM = LLVMCreateSimpleMCJITMemoryManager( 1296cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo new SectionMemoryManager(), 1306cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo roundTripAllocateCodeSection, 1316cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo roundTripAllocateDataSection, 1326cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo roundTripFinalizeMemory, 1336cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo roundTripDestroy); 1346cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo } 135d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor 1366cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo void buildMCJITEngine() { 1376cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo ASSERT_EQ( 1386cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo 0, LLVMCreateMCJITCompilerForModule(&Engine, Module, &Options, 1396cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo sizeof(Options), &Error)); 1406cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo } 141d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor 1426cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo void buildAndRunPasses() { 1436cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo LLVMPassManagerRef pass = LLVMCreatePassManager(); 1446cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo LLVMAddTargetData(LLVMGetExecutionEngineTargetData(Engine), pass); 1456cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo LLVMAddConstantPropagationPass(pass); 1466cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo LLVMAddInstructionCombiningPass(pass); 1476cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo LLVMRunPassManager(pass, Module); 1486cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo LLVMDisposePassManager(pass); 1496cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo } 150a4fa74e38163ec3dc652f31ddac2c08e4a05889cFilip Pizlo 1516cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo LLVMModuleRef Module; 1526cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo LLVMValueRef Function; 1536cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo LLVMMCJITCompilerOptions Options; 1546cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo LLVMExecutionEngineRef Engine; 1556cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo char *Error; 1566cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo}; 1576cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo 1586cfed36338d7728076ddbc1331908b887a4302d3Filip PizloTEST_F(MCJITCAPITest, simple_function) { 1596cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo SKIP_UNSUPPORTED_PLATFORM; 16052755c472a738e48a9687240368e4c1f78c45711Filip Pizlo 1616cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo buildSimpleFunction(); 1626cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo buildMCJITOptions(); 1636cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo buildMCJITEngine(); 1646cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo buildAndRunPasses(); 1656cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo 1666cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo union { 1676cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo void *raw; 1686cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo int (*usable)(); 1696cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo } functionPointer; 1706cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo functionPointer.raw = LLVMGetPointerToGlobal(Engine, Function); 171d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor 1726cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo EXPECT_EQ(42, functionPointer.usable()); 1736cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo} 1746cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo 1756cfed36338d7728076ddbc1331908b887a4302d3Filip PizloTEST_F(MCJITCAPITest, custom_memory_manager) { 1766cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo SKIP_UNSUPPORTED_PLATFORM; 177d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor 1786cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo buildSimpleFunction(); 1796cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo buildMCJITOptions(); 1806cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo useRoundTripSectionMemoryManager(); 1816cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo buildMCJITEngine(); 1826cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo buildAndRunPasses(); 183d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor 184d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor union { 185d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor void *raw; 186d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor int (*usable)(); 187d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor } functionPointer; 1886cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo functionPointer.raw = LLVMGetPointerToGlobal(Engine, Function); 189d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor 190d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor EXPECT_EQ(42, functionPointer.usable()); 1916cfed36338d7728076ddbc1331908b887a4302d3Filip Pizlo EXPECT_TRUE(didCallAllocateCodeSection); 192d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor} 193