xref: /aosp_15_r20/external/llvm/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===- MCJITTest.cpp - Unit tests for the MCJIT -----------------*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This test suite verifies basic MCJIT functionality when invoked form the C
11*9880d681SAndroid Build Coastguard Worker // API.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker 
15*9880d681SAndroid Build Coastguard Worker #include "llvm-c/Analysis.h"
16*9880d681SAndroid Build Coastguard Worker #include "MCJITTestAPICommon.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm-c/Core.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm-c/ExecutionEngine.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm-c/Target.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm-c/Transforms/PassManagerBuilder.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm-c/Transforms/Scalar.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/SectionMemoryManager.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Host.h"
25*9880d681SAndroid Build Coastguard Worker #include "gtest/gtest.h"
26*9880d681SAndroid Build Coastguard Worker 
27*9880d681SAndroid Build Coastguard Worker using namespace llvm;
28*9880d681SAndroid Build Coastguard Worker 
29*9880d681SAndroid Build Coastguard Worker static bool didCallAllocateCodeSection;
30*9880d681SAndroid Build Coastguard Worker static bool didAllocateCompactUnwindSection;
31*9880d681SAndroid Build Coastguard Worker static bool didCallYield;
32*9880d681SAndroid Build Coastguard Worker 
roundTripAllocateCodeSection(void * object,uintptr_t size,unsigned alignment,unsigned sectionID,const char * sectionName)33*9880d681SAndroid Build Coastguard Worker static uint8_t *roundTripAllocateCodeSection(void *object, uintptr_t size,
34*9880d681SAndroid Build Coastguard Worker                                              unsigned alignment,
35*9880d681SAndroid Build Coastguard Worker                                              unsigned sectionID,
36*9880d681SAndroid Build Coastguard Worker                                              const char *sectionName) {
37*9880d681SAndroid Build Coastguard Worker   didCallAllocateCodeSection = true;
38*9880d681SAndroid Build Coastguard Worker   return static_cast<SectionMemoryManager*>(object)->allocateCodeSection(
39*9880d681SAndroid Build Coastguard Worker     size, alignment, sectionID, sectionName);
40*9880d681SAndroid Build Coastguard Worker }
41*9880d681SAndroid Build Coastguard Worker 
roundTripAllocateDataSection(void * object,uintptr_t size,unsigned alignment,unsigned sectionID,const char * sectionName,LLVMBool isReadOnly)42*9880d681SAndroid Build Coastguard Worker static uint8_t *roundTripAllocateDataSection(void *object, uintptr_t size,
43*9880d681SAndroid Build Coastguard Worker                                              unsigned alignment,
44*9880d681SAndroid Build Coastguard Worker                                              unsigned sectionID,
45*9880d681SAndroid Build Coastguard Worker                                              const char *sectionName,
46*9880d681SAndroid Build Coastguard Worker                                              LLVMBool isReadOnly) {
47*9880d681SAndroid Build Coastguard Worker   if (!strcmp(sectionName, "__compact_unwind"))
48*9880d681SAndroid Build Coastguard Worker     didAllocateCompactUnwindSection = true;
49*9880d681SAndroid Build Coastguard Worker   return static_cast<SectionMemoryManager*>(object)->allocateDataSection(
50*9880d681SAndroid Build Coastguard Worker     size, alignment, sectionID, sectionName, isReadOnly);
51*9880d681SAndroid Build Coastguard Worker }
52*9880d681SAndroid Build Coastguard Worker 
roundTripFinalizeMemory(void * object,char ** errMsg)53*9880d681SAndroid Build Coastguard Worker static LLVMBool roundTripFinalizeMemory(void *object, char **errMsg) {
54*9880d681SAndroid Build Coastguard Worker   std::string errMsgString;
55*9880d681SAndroid Build Coastguard Worker   bool result =
56*9880d681SAndroid Build Coastguard Worker     static_cast<SectionMemoryManager*>(object)->finalizeMemory(&errMsgString);
57*9880d681SAndroid Build Coastguard Worker   if (result) {
58*9880d681SAndroid Build Coastguard Worker     *errMsg = LLVMCreateMessage(errMsgString.c_str());
59*9880d681SAndroid Build Coastguard Worker     return 1;
60*9880d681SAndroid Build Coastguard Worker   }
61*9880d681SAndroid Build Coastguard Worker   return 0;
62*9880d681SAndroid Build Coastguard Worker }
63*9880d681SAndroid Build Coastguard Worker 
roundTripDestroy(void * object)64*9880d681SAndroid Build Coastguard Worker static void roundTripDestroy(void *object) {
65*9880d681SAndroid Build Coastguard Worker   delete static_cast<SectionMemoryManager*>(object);
66*9880d681SAndroid Build Coastguard Worker }
67*9880d681SAndroid Build Coastguard Worker 
yield(LLVMContextRef,void *)68*9880d681SAndroid Build Coastguard Worker static void yield(LLVMContextRef, void *) {
69*9880d681SAndroid Build Coastguard Worker   didCallYield = true;
70*9880d681SAndroid Build Coastguard Worker }
71*9880d681SAndroid Build Coastguard Worker 
72*9880d681SAndroid Build Coastguard Worker namespace {
73*9880d681SAndroid Build Coastguard Worker 
74*9880d681SAndroid Build Coastguard Worker // memory manager to test reserve allocation space callback
75*9880d681SAndroid Build Coastguard Worker class TestReserveAllocationSpaceMemoryManager: public SectionMemoryManager {
76*9880d681SAndroid Build Coastguard Worker public:
77*9880d681SAndroid Build Coastguard Worker   uintptr_t ReservedCodeSize;
78*9880d681SAndroid Build Coastguard Worker   uintptr_t UsedCodeSize;
79*9880d681SAndroid Build Coastguard Worker   uintptr_t ReservedDataSizeRO;
80*9880d681SAndroid Build Coastguard Worker   uintptr_t UsedDataSizeRO;
81*9880d681SAndroid Build Coastguard Worker   uintptr_t ReservedDataSizeRW;
82*9880d681SAndroid Build Coastguard Worker   uintptr_t UsedDataSizeRW;
83*9880d681SAndroid Build Coastguard Worker 
TestReserveAllocationSpaceMemoryManager()84*9880d681SAndroid Build Coastguard Worker   TestReserveAllocationSpaceMemoryManager() :
85*9880d681SAndroid Build Coastguard Worker     ReservedCodeSize(0), UsedCodeSize(0), ReservedDataSizeRO(0),
86*9880d681SAndroid Build Coastguard Worker     UsedDataSizeRO(0), ReservedDataSizeRW(0), UsedDataSizeRW(0) {
87*9880d681SAndroid Build Coastguard Worker   }
88*9880d681SAndroid Build Coastguard Worker 
needsToReserveAllocationSpace()89*9880d681SAndroid Build Coastguard Worker   bool needsToReserveAllocationSpace() override { return true; }
90*9880d681SAndroid Build Coastguard Worker 
reserveAllocationSpace(uintptr_t CodeSize,uint32_t CodeAlign,uintptr_t DataSizeRO,uint32_t RODataAlign,uintptr_t DataSizeRW,uint32_t RWDataAlign)91*9880d681SAndroid Build Coastguard Worker   void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign,
92*9880d681SAndroid Build Coastguard Worker 			      uintptr_t DataSizeRO, uint32_t RODataAlign,
93*9880d681SAndroid Build Coastguard Worker                               uintptr_t DataSizeRW, uint32_t RWDataAlign) override {
94*9880d681SAndroid Build Coastguard Worker     ReservedCodeSize = CodeSize;
95*9880d681SAndroid Build Coastguard Worker     ReservedDataSizeRO = DataSizeRO;
96*9880d681SAndroid Build Coastguard Worker     ReservedDataSizeRW = DataSizeRW;
97*9880d681SAndroid Build Coastguard Worker   }
98*9880d681SAndroid Build Coastguard Worker 
useSpace(uintptr_t * UsedSize,uintptr_t Size,unsigned Alignment)99*9880d681SAndroid Build Coastguard Worker   void useSpace(uintptr_t* UsedSize, uintptr_t Size, unsigned Alignment) {
100*9880d681SAndroid Build Coastguard Worker     uintptr_t AlignedSize = (Size + Alignment - 1) / Alignment * Alignment;
101*9880d681SAndroid Build Coastguard Worker     uintptr_t AlignedBegin = (*UsedSize + Alignment - 1) / Alignment * Alignment;
102*9880d681SAndroid Build Coastguard Worker     *UsedSize = AlignedBegin + AlignedSize;
103*9880d681SAndroid Build Coastguard Worker   }
104*9880d681SAndroid Build Coastguard Worker 
allocateDataSection(uintptr_t Size,unsigned Alignment,unsigned SectionID,StringRef SectionName,bool IsReadOnly)105*9880d681SAndroid Build Coastguard Worker   uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
106*9880d681SAndroid Build Coastguard Worker                                unsigned SectionID, StringRef SectionName,
107*9880d681SAndroid Build Coastguard Worker                                bool IsReadOnly) override {
108*9880d681SAndroid Build Coastguard Worker     useSpace(IsReadOnly ? &UsedDataSizeRO : &UsedDataSizeRW, Size, Alignment);
109*9880d681SAndroid Build Coastguard Worker     return SectionMemoryManager::allocateDataSection(Size, Alignment,
110*9880d681SAndroid Build Coastguard Worker       SectionID, SectionName, IsReadOnly);
111*9880d681SAndroid Build Coastguard Worker   }
112*9880d681SAndroid Build Coastguard Worker 
allocateCodeSection(uintptr_t Size,unsigned Alignment,unsigned SectionID,StringRef SectionName)113*9880d681SAndroid Build Coastguard Worker   uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
114*9880d681SAndroid Build Coastguard Worker                                unsigned SectionID,
115*9880d681SAndroid Build Coastguard Worker                                StringRef SectionName) override {
116*9880d681SAndroid Build Coastguard Worker     useSpace(&UsedCodeSize, Size, Alignment);
117*9880d681SAndroid Build Coastguard Worker     return SectionMemoryManager::allocateCodeSection(Size, Alignment,
118*9880d681SAndroid Build Coastguard Worker       SectionID, SectionName);
119*9880d681SAndroid Build Coastguard Worker   }
120*9880d681SAndroid Build Coastguard Worker };
121*9880d681SAndroid Build Coastguard Worker 
122*9880d681SAndroid Build Coastguard Worker class MCJITCAPITest : public testing::Test, public MCJITTestAPICommon {
123*9880d681SAndroid Build Coastguard Worker protected:
MCJITCAPITest()124*9880d681SAndroid Build Coastguard Worker   MCJITCAPITest() {
125*9880d681SAndroid Build Coastguard Worker     // The architectures below are known to be compatible with MCJIT as they
126*9880d681SAndroid Build Coastguard Worker     // are copied from test/ExecutionEngine/MCJIT/lit.local.cfg and should be
127*9880d681SAndroid Build Coastguard Worker     // kept in sync.
128*9880d681SAndroid Build Coastguard Worker     SupportedArchs.push_back(Triple::aarch64);
129*9880d681SAndroid Build Coastguard Worker     SupportedArchs.push_back(Triple::arm);
130*9880d681SAndroid Build Coastguard Worker     SupportedArchs.push_back(Triple::mips);
131*9880d681SAndroid Build Coastguard Worker     SupportedArchs.push_back(Triple::mips64);
132*9880d681SAndroid Build Coastguard Worker     SupportedArchs.push_back(Triple::mips64el);
133*9880d681SAndroid Build Coastguard Worker     SupportedArchs.push_back(Triple::x86);
134*9880d681SAndroid Build Coastguard Worker     SupportedArchs.push_back(Triple::x86_64);
135*9880d681SAndroid Build Coastguard Worker 
136*9880d681SAndroid Build Coastguard Worker     // Some architectures have sub-architectures in which tests will fail, like
137*9880d681SAndroid Build Coastguard Worker     // ARM. These two vectors will define if they do have sub-archs (to avoid
138*9880d681SAndroid Build Coastguard Worker     // extra work for those who don't), and if so, if they are listed to work
139*9880d681SAndroid Build Coastguard Worker     HasSubArchs.push_back(Triple::arm);
140*9880d681SAndroid Build Coastguard Worker     SupportedSubArchs.push_back("armv6");
141*9880d681SAndroid Build Coastguard Worker     SupportedSubArchs.push_back("armv7");
142*9880d681SAndroid Build Coastguard Worker 
143*9880d681SAndroid Build Coastguard Worker     // The operating systems below are known to be sufficiently incompatible
144*9880d681SAndroid Build Coastguard Worker     // that they will fail the MCJIT C API tests.
145*9880d681SAndroid Build Coastguard Worker     UnsupportedEnvironments.push_back(Triple::Cygnus);
146*9880d681SAndroid Build Coastguard Worker   }
147*9880d681SAndroid Build Coastguard Worker 
SetUp()148*9880d681SAndroid Build Coastguard Worker   void SetUp() override {
149*9880d681SAndroid Build Coastguard Worker     didCallAllocateCodeSection = false;
150*9880d681SAndroid Build Coastguard Worker     didAllocateCompactUnwindSection = false;
151*9880d681SAndroid Build Coastguard Worker     didCallYield = false;
152*9880d681SAndroid Build Coastguard Worker     Module = nullptr;
153*9880d681SAndroid Build Coastguard Worker     Function = nullptr;
154*9880d681SAndroid Build Coastguard Worker     Engine = nullptr;
155*9880d681SAndroid Build Coastguard Worker     Error = nullptr;
156*9880d681SAndroid Build Coastguard Worker   }
157*9880d681SAndroid Build Coastguard Worker 
TearDown()158*9880d681SAndroid Build Coastguard Worker   void TearDown() override {
159*9880d681SAndroid Build Coastguard Worker     if (Engine)
160*9880d681SAndroid Build Coastguard Worker       LLVMDisposeExecutionEngine(Engine);
161*9880d681SAndroid Build Coastguard Worker     else if (Module)
162*9880d681SAndroid Build Coastguard Worker       LLVMDisposeModule(Module);
163*9880d681SAndroid Build Coastguard Worker   }
164*9880d681SAndroid Build Coastguard Worker 
buildSimpleFunction()165*9880d681SAndroid Build Coastguard Worker   void buildSimpleFunction() {
166*9880d681SAndroid Build Coastguard Worker     Module = LLVMModuleCreateWithName("simple_module");
167*9880d681SAndroid Build Coastguard Worker 
168*9880d681SAndroid Build Coastguard Worker     LLVMSetTarget(Module, HostTriple.c_str());
169*9880d681SAndroid Build Coastguard Worker 
170*9880d681SAndroid Build Coastguard Worker     Function = LLVMAddFunction(Module, "simple_function",
171*9880d681SAndroid Build Coastguard Worker                                LLVMFunctionType(LLVMInt32Type(), nullptr,0, 0));
172*9880d681SAndroid Build Coastguard Worker     LLVMSetFunctionCallConv(Function, LLVMCCallConv);
173*9880d681SAndroid Build Coastguard Worker 
174*9880d681SAndroid Build Coastguard Worker     LLVMBasicBlockRef entry = LLVMAppendBasicBlock(Function, "entry");
175*9880d681SAndroid Build Coastguard Worker     LLVMBuilderRef builder = LLVMCreateBuilder();
176*9880d681SAndroid Build Coastguard Worker     LLVMPositionBuilderAtEnd(builder, entry);
177*9880d681SAndroid Build Coastguard Worker     LLVMBuildRet(builder, LLVMConstInt(LLVMInt32Type(), 42, 0));
178*9880d681SAndroid Build Coastguard Worker 
179*9880d681SAndroid Build Coastguard Worker     LLVMVerifyModule(Module, LLVMAbortProcessAction, &Error);
180*9880d681SAndroid Build Coastguard Worker     LLVMDisposeMessage(Error);
181*9880d681SAndroid Build Coastguard Worker 
182*9880d681SAndroid Build Coastguard Worker     LLVMDisposeBuilder(builder);
183*9880d681SAndroid Build Coastguard Worker   }
184*9880d681SAndroid Build Coastguard Worker 
buildFunctionThatUsesStackmap()185*9880d681SAndroid Build Coastguard Worker   void buildFunctionThatUsesStackmap() {
186*9880d681SAndroid Build Coastguard Worker     Module = LLVMModuleCreateWithName("simple_module");
187*9880d681SAndroid Build Coastguard Worker 
188*9880d681SAndroid Build Coastguard Worker     LLVMSetTarget(Module, HostTriple.c_str());
189*9880d681SAndroid Build Coastguard Worker 
190*9880d681SAndroid Build Coastguard Worker     LLVMTypeRef stackmapParamTypes[] = { LLVMInt64Type(), LLVMInt32Type() };
191*9880d681SAndroid Build Coastguard Worker     LLVMValueRef stackmap = LLVMAddFunction(
192*9880d681SAndroid Build Coastguard Worker       Module, "llvm.experimental.stackmap",
193*9880d681SAndroid Build Coastguard Worker       LLVMFunctionType(LLVMVoidType(), stackmapParamTypes, 2, 1));
194*9880d681SAndroid Build Coastguard Worker     LLVMSetLinkage(stackmap, LLVMExternalLinkage);
195*9880d681SAndroid Build Coastguard Worker 
196*9880d681SAndroid Build Coastguard Worker     Function = LLVMAddFunction(Module, "simple_function",
197*9880d681SAndroid Build Coastguard Worker                               LLVMFunctionType(LLVMInt32Type(), nullptr, 0, 0));
198*9880d681SAndroid Build Coastguard Worker 
199*9880d681SAndroid Build Coastguard Worker     LLVMBasicBlockRef entry = LLVMAppendBasicBlock(Function, "entry");
200*9880d681SAndroid Build Coastguard Worker     LLVMBuilderRef builder = LLVMCreateBuilder();
201*9880d681SAndroid Build Coastguard Worker     LLVMPositionBuilderAtEnd(builder, entry);
202*9880d681SAndroid Build Coastguard Worker     LLVMValueRef stackmapArgs[] = {
203*9880d681SAndroid Build Coastguard Worker       LLVMConstInt(LLVMInt64Type(), 0, 0), LLVMConstInt(LLVMInt32Type(), 5, 0),
204*9880d681SAndroid Build Coastguard Worker       LLVMConstInt(LLVMInt32Type(), 42, 0)
205*9880d681SAndroid Build Coastguard Worker     };
206*9880d681SAndroid Build Coastguard Worker     LLVMBuildCall(builder, stackmap, stackmapArgs, 3, "");
207*9880d681SAndroid Build Coastguard Worker     LLVMBuildRet(builder, LLVMConstInt(LLVMInt32Type(), 42, 0));
208*9880d681SAndroid Build Coastguard Worker 
209*9880d681SAndroid Build Coastguard Worker     LLVMVerifyModule(Module, LLVMAbortProcessAction, &Error);
210*9880d681SAndroid Build Coastguard Worker     LLVMDisposeMessage(Error);
211*9880d681SAndroid Build Coastguard Worker 
212*9880d681SAndroid Build Coastguard Worker     LLVMDisposeBuilder(builder);
213*9880d681SAndroid Build Coastguard Worker   }
214*9880d681SAndroid Build Coastguard Worker 
buildModuleWithCodeAndData()215*9880d681SAndroid Build Coastguard Worker   void buildModuleWithCodeAndData() {
216*9880d681SAndroid Build Coastguard Worker     Module = LLVMModuleCreateWithName("simple_module");
217*9880d681SAndroid Build Coastguard Worker 
218*9880d681SAndroid Build Coastguard Worker     LLVMSetTarget(Module, HostTriple.c_str());
219*9880d681SAndroid Build Coastguard Worker 
220*9880d681SAndroid Build Coastguard Worker     // build a global int32 variable initialized to 42.
221*9880d681SAndroid Build Coastguard Worker     LLVMValueRef GlobalVar = LLVMAddGlobal(Module, LLVMInt32Type(), "intVal");
222*9880d681SAndroid Build Coastguard Worker     LLVMSetInitializer(GlobalVar, LLVMConstInt(LLVMInt32Type(), 42, 0));
223*9880d681SAndroid Build Coastguard Worker 
224*9880d681SAndroid Build Coastguard Worker     {
225*9880d681SAndroid Build Coastguard Worker         Function = LLVMAddFunction(Module, "getGlobal",
226*9880d681SAndroid Build Coastguard Worker                               LLVMFunctionType(LLVMInt32Type(), nullptr, 0, 0));
227*9880d681SAndroid Build Coastguard Worker         LLVMSetFunctionCallConv(Function, LLVMCCallConv);
228*9880d681SAndroid Build Coastguard Worker 
229*9880d681SAndroid Build Coastguard Worker         LLVMBasicBlockRef Entry = LLVMAppendBasicBlock(Function, "entry");
230*9880d681SAndroid Build Coastguard Worker         LLVMBuilderRef Builder = LLVMCreateBuilder();
231*9880d681SAndroid Build Coastguard Worker         LLVMPositionBuilderAtEnd(Builder, Entry);
232*9880d681SAndroid Build Coastguard Worker 
233*9880d681SAndroid Build Coastguard Worker         LLVMValueRef IntVal = LLVMBuildLoad(Builder, GlobalVar, "intVal");
234*9880d681SAndroid Build Coastguard Worker         LLVMBuildRet(Builder, IntVal);
235*9880d681SAndroid Build Coastguard Worker 
236*9880d681SAndroid Build Coastguard Worker         LLVMVerifyModule(Module, LLVMAbortProcessAction, &Error);
237*9880d681SAndroid Build Coastguard Worker         LLVMDisposeMessage(Error);
238*9880d681SAndroid Build Coastguard Worker 
239*9880d681SAndroid Build Coastguard Worker         LLVMDisposeBuilder(Builder);
240*9880d681SAndroid Build Coastguard Worker     }
241*9880d681SAndroid Build Coastguard Worker 
242*9880d681SAndroid Build Coastguard Worker     {
243*9880d681SAndroid Build Coastguard Worker         LLVMTypeRef ParamTypes[] = { LLVMInt32Type() };
244*9880d681SAndroid Build Coastguard Worker         Function2 = LLVMAddFunction(
245*9880d681SAndroid Build Coastguard Worker           Module, "setGlobal", LLVMFunctionType(LLVMVoidType(), ParamTypes, 1, 0));
246*9880d681SAndroid Build Coastguard Worker         LLVMSetFunctionCallConv(Function2, LLVMCCallConv);
247*9880d681SAndroid Build Coastguard Worker 
248*9880d681SAndroid Build Coastguard Worker         LLVMBasicBlockRef Entry = LLVMAppendBasicBlock(Function2, "entry");
249*9880d681SAndroid Build Coastguard Worker         LLVMBuilderRef Builder = LLVMCreateBuilder();
250*9880d681SAndroid Build Coastguard Worker         LLVMPositionBuilderAtEnd(Builder, Entry);
251*9880d681SAndroid Build Coastguard Worker 
252*9880d681SAndroid Build Coastguard Worker         LLVMValueRef Arg = LLVMGetParam(Function2, 0);
253*9880d681SAndroid Build Coastguard Worker         LLVMBuildStore(Builder, Arg, GlobalVar);
254*9880d681SAndroid Build Coastguard Worker         LLVMBuildRetVoid(Builder);
255*9880d681SAndroid Build Coastguard Worker 
256*9880d681SAndroid Build Coastguard Worker         LLVMVerifyModule(Module, LLVMAbortProcessAction, &Error);
257*9880d681SAndroid Build Coastguard Worker         LLVMDisposeMessage(Error);
258*9880d681SAndroid Build Coastguard Worker 
259*9880d681SAndroid Build Coastguard Worker         LLVMDisposeBuilder(Builder);
260*9880d681SAndroid Build Coastguard Worker     }
261*9880d681SAndroid Build Coastguard Worker   }
262*9880d681SAndroid Build Coastguard Worker 
buildMCJITOptions()263*9880d681SAndroid Build Coastguard Worker   void buildMCJITOptions() {
264*9880d681SAndroid Build Coastguard Worker     LLVMInitializeMCJITCompilerOptions(&Options, sizeof(Options));
265*9880d681SAndroid Build Coastguard Worker     Options.OptLevel = 2;
266*9880d681SAndroid Build Coastguard Worker 
267*9880d681SAndroid Build Coastguard Worker     // Just ensure that this field still exists.
268*9880d681SAndroid Build Coastguard Worker     Options.NoFramePointerElim = false;
269*9880d681SAndroid Build Coastguard Worker   }
270*9880d681SAndroid Build Coastguard Worker 
useRoundTripSectionMemoryManager()271*9880d681SAndroid Build Coastguard Worker   void useRoundTripSectionMemoryManager() {
272*9880d681SAndroid Build Coastguard Worker     Options.MCJMM = LLVMCreateSimpleMCJITMemoryManager(
273*9880d681SAndroid Build Coastguard Worker       new SectionMemoryManager(),
274*9880d681SAndroid Build Coastguard Worker       roundTripAllocateCodeSection,
275*9880d681SAndroid Build Coastguard Worker       roundTripAllocateDataSection,
276*9880d681SAndroid Build Coastguard Worker       roundTripFinalizeMemory,
277*9880d681SAndroid Build Coastguard Worker       roundTripDestroy);
278*9880d681SAndroid Build Coastguard Worker   }
279*9880d681SAndroid Build Coastguard Worker 
buildMCJITEngine()280*9880d681SAndroid Build Coastguard Worker   void buildMCJITEngine() {
281*9880d681SAndroid Build Coastguard Worker     ASSERT_EQ(
282*9880d681SAndroid Build Coastguard Worker       0, LLVMCreateMCJITCompilerForModule(&Engine, Module, &Options,
283*9880d681SAndroid Build Coastguard Worker                                           sizeof(Options), &Error));
284*9880d681SAndroid Build Coastguard Worker   }
285*9880d681SAndroid Build Coastguard Worker 
buildAndRunPasses()286*9880d681SAndroid Build Coastguard Worker   void buildAndRunPasses() {
287*9880d681SAndroid Build Coastguard Worker     LLVMPassManagerRef pass = LLVMCreatePassManager();
288*9880d681SAndroid Build Coastguard Worker     LLVMAddConstantPropagationPass(pass);
289*9880d681SAndroid Build Coastguard Worker     LLVMAddInstructionCombiningPass(pass);
290*9880d681SAndroid Build Coastguard Worker     LLVMRunPassManager(pass, Module);
291*9880d681SAndroid Build Coastguard Worker     LLVMDisposePassManager(pass);
292*9880d681SAndroid Build Coastguard Worker   }
293*9880d681SAndroid Build Coastguard Worker 
buildAndRunOptPasses()294*9880d681SAndroid Build Coastguard Worker   void buildAndRunOptPasses() {
295*9880d681SAndroid Build Coastguard Worker     LLVMPassManagerBuilderRef passBuilder;
296*9880d681SAndroid Build Coastguard Worker 
297*9880d681SAndroid Build Coastguard Worker     passBuilder = LLVMPassManagerBuilderCreate();
298*9880d681SAndroid Build Coastguard Worker     LLVMPassManagerBuilderSetOptLevel(passBuilder, 2);
299*9880d681SAndroid Build Coastguard Worker     LLVMPassManagerBuilderSetSizeLevel(passBuilder, 0);
300*9880d681SAndroid Build Coastguard Worker 
301*9880d681SAndroid Build Coastguard Worker     LLVMPassManagerRef functionPasses =
302*9880d681SAndroid Build Coastguard Worker       LLVMCreateFunctionPassManagerForModule(Module);
303*9880d681SAndroid Build Coastguard Worker     LLVMPassManagerRef modulePasses =
304*9880d681SAndroid Build Coastguard Worker       LLVMCreatePassManager();
305*9880d681SAndroid Build Coastguard Worker 
306*9880d681SAndroid Build Coastguard Worker     LLVMPassManagerBuilderPopulateFunctionPassManager(passBuilder,
307*9880d681SAndroid Build Coastguard Worker                                                       functionPasses);
308*9880d681SAndroid Build Coastguard Worker     LLVMPassManagerBuilderPopulateModulePassManager(passBuilder, modulePasses);
309*9880d681SAndroid Build Coastguard Worker 
310*9880d681SAndroid Build Coastguard Worker     LLVMPassManagerBuilderDispose(passBuilder);
311*9880d681SAndroid Build Coastguard Worker 
312*9880d681SAndroid Build Coastguard Worker     LLVMInitializeFunctionPassManager(functionPasses);
313*9880d681SAndroid Build Coastguard Worker     for (LLVMValueRef value = LLVMGetFirstFunction(Module);
314*9880d681SAndroid Build Coastguard Worker          value; value = LLVMGetNextFunction(value))
315*9880d681SAndroid Build Coastguard Worker       LLVMRunFunctionPassManager(functionPasses, value);
316*9880d681SAndroid Build Coastguard Worker     LLVMFinalizeFunctionPassManager(functionPasses);
317*9880d681SAndroid Build Coastguard Worker 
318*9880d681SAndroid Build Coastguard Worker     LLVMRunPassManager(modulePasses, Module);
319*9880d681SAndroid Build Coastguard Worker 
320*9880d681SAndroid Build Coastguard Worker     LLVMDisposePassManager(functionPasses);
321*9880d681SAndroid Build Coastguard Worker     LLVMDisposePassManager(modulePasses);
322*9880d681SAndroid Build Coastguard Worker   }
323*9880d681SAndroid Build Coastguard Worker 
324*9880d681SAndroid Build Coastguard Worker   LLVMModuleRef Module;
325*9880d681SAndroid Build Coastguard Worker   LLVMValueRef Function;
326*9880d681SAndroid Build Coastguard Worker   LLVMValueRef Function2;
327*9880d681SAndroid Build Coastguard Worker   LLVMMCJITCompilerOptions Options;
328*9880d681SAndroid Build Coastguard Worker   LLVMExecutionEngineRef Engine;
329*9880d681SAndroid Build Coastguard Worker   char *Error;
330*9880d681SAndroid Build Coastguard Worker };
331*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
332*9880d681SAndroid Build Coastguard Worker 
TEST_F(MCJITCAPITest,simple_function)333*9880d681SAndroid Build Coastguard Worker TEST_F(MCJITCAPITest, simple_function) {
334*9880d681SAndroid Build Coastguard Worker   SKIP_UNSUPPORTED_PLATFORM;
335*9880d681SAndroid Build Coastguard Worker 
336*9880d681SAndroid Build Coastguard Worker   buildSimpleFunction();
337*9880d681SAndroid Build Coastguard Worker   buildMCJITOptions();
338*9880d681SAndroid Build Coastguard Worker   buildMCJITEngine();
339*9880d681SAndroid Build Coastguard Worker   buildAndRunPasses();
340*9880d681SAndroid Build Coastguard Worker 
341*9880d681SAndroid Build Coastguard Worker   auto *functionPointer = reinterpret_cast<int (*)()>(
342*9880d681SAndroid Build Coastguard Worker       reinterpret_cast<uintptr_t>(LLVMGetPointerToGlobal(Engine, Function)));
343*9880d681SAndroid Build Coastguard Worker 
344*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(42, functionPointer());
345*9880d681SAndroid Build Coastguard Worker }
346*9880d681SAndroid Build Coastguard Worker 
TEST_F(MCJITCAPITest,gva)347*9880d681SAndroid Build Coastguard Worker TEST_F(MCJITCAPITest, gva) {
348*9880d681SAndroid Build Coastguard Worker   SKIP_UNSUPPORTED_PLATFORM;
349*9880d681SAndroid Build Coastguard Worker 
350*9880d681SAndroid Build Coastguard Worker   Module = LLVMModuleCreateWithName("simple_module");
351*9880d681SAndroid Build Coastguard Worker   LLVMSetTarget(Module, HostTriple.c_str());
352*9880d681SAndroid Build Coastguard Worker   LLVMValueRef GlobalVar = LLVMAddGlobal(Module, LLVMInt32Type(), "simple_value");
353*9880d681SAndroid Build Coastguard Worker   LLVMSetInitializer(GlobalVar, LLVMConstInt(LLVMInt32Type(), 42, 0));
354*9880d681SAndroid Build Coastguard Worker 
355*9880d681SAndroid Build Coastguard Worker   buildMCJITOptions();
356*9880d681SAndroid Build Coastguard Worker   buildMCJITEngine();
357*9880d681SAndroid Build Coastguard Worker   buildAndRunPasses();
358*9880d681SAndroid Build Coastguard Worker 
359*9880d681SAndroid Build Coastguard Worker   uint64_t raw = LLVMGetGlobalValueAddress(Engine, "simple_value");
360*9880d681SAndroid Build Coastguard Worker   int32_t *usable  = (int32_t *) raw;
361*9880d681SAndroid Build Coastguard Worker 
362*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(42, *usable);
363*9880d681SAndroid Build Coastguard Worker }
364*9880d681SAndroid Build Coastguard Worker 
TEST_F(MCJITCAPITest,gfa)365*9880d681SAndroid Build Coastguard Worker TEST_F(MCJITCAPITest, gfa) {
366*9880d681SAndroid Build Coastguard Worker   SKIP_UNSUPPORTED_PLATFORM;
367*9880d681SAndroid Build Coastguard Worker 
368*9880d681SAndroid Build Coastguard Worker   buildSimpleFunction();
369*9880d681SAndroid Build Coastguard Worker   buildMCJITOptions();
370*9880d681SAndroid Build Coastguard Worker   buildMCJITEngine();
371*9880d681SAndroid Build Coastguard Worker   buildAndRunPasses();
372*9880d681SAndroid Build Coastguard Worker 
373*9880d681SAndroid Build Coastguard Worker   uint64_t raw = LLVMGetFunctionAddress(Engine, "simple_function");
374*9880d681SAndroid Build Coastguard Worker   int (*usable)() = (int (*)()) raw;
375*9880d681SAndroid Build Coastguard Worker 
376*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(42, usable());
377*9880d681SAndroid Build Coastguard Worker }
378*9880d681SAndroid Build Coastguard Worker 
TEST_F(MCJITCAPITest,custom_memory_manager)379*9880d681SAndroid Build Coastguard Worker TEST_F(MCJITCAPITest, custom_memory_manager) {
380*9880d681SAndroid Build Coastguard Worker   SKIP_UNSUPPORTED_PLATFORM;
381*9880d681SAndroid Build Coastguard Worker 
382*9880d681SAndroid Build Coastguard Worker   buildSimpleFunction();
383*9880d681SAndroid Build Coastguard Worker   buildMCJITOptions();
384*9880d681SAndroid Build Coastguard Worker   useRoundTripSectionMemoryManager();
385*9880d681SAndroid Build Coastguard Worker   buildMCJITEngine();
386*9880d681SAndroid Build Coastguard Worker   buildAndRunPasses();
387*9880d681SAndroid Build Coastguard Worker 
388*9880d681SAndroid Build Coastguard Worker   auto *functionPointer = reinterpret_cast<int (*)()>(
389*9880d681SAndroid Build Coastguard Worker       reinterpret_cast<uintptr_t>(LLVMGetPointerToGlobal(Engine, Function)));
390*9880d681SAndroid Build Coastguard Worker 
391*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(42, functionPointer());
392*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(didCallAllocateCodeSection);
393*9880d681SAndroid Build Coastguard Worker }
394*9880d681SAndroid Build Coastguard Worker 
TEST_F(MCJITCAPITest,stackmap_creates_compact_unwind_on_darwin)395*9880d681SAndroid Build Coastguard Worker TEST_F(MCJITCAPITest, stackmap_creates_compact_unwind_on_darwin) {
396*9880d681SAndroid Build Coastguard Worker   SKIP_UNSUPPORTED_PLATFORM;
397*9880d681SAndroid Build Coastguard Worker 
398*9880d681SAndroid Build Coastguard Worker   // This test is also not supported on non-x86 platforms.
399*9880d681SAndroid Build Coastguard Worker   if (Triple(HostTriple).getArch() != Triple::x86_64)
400*9880d681SAndroid Build Coastguard Worker     return;
401*9880d681SAndroid Build Coastguard Worker 
402*9880d681SAndroid Build Coastguard Worker   buildFunctionThatUsesStackmap();
403*9880d681SAndroid Build Coastguard Worker   buildMCJITOptions();
404*9880d681SAndroid Build Coastguard Worker   useRoundTripSectionMemoryManager();
405*9880d681SAndroid Build Coastguard Worker   buildMCJITEngine();
406*9880d681SAndroid Build Coastguard Worker   buildAndRunOptPasses();
407*9880d681SAndroid Build Coastguard Worker 
408*9880d681SAndroid Build Coastguard Worker   auto *functionPointer = reinterpret_cast<int (*)()>(
409*9880d681SAndroid Build Coastguard Worker       reinterpret_cast<uintptr_t>(LLVMGetPointerToGlobal(Engine, Function)));
410*9880d681SAndroid Build Coastguard Worker 
411*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(42, functionPointer());
412*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(didCallAllocateCodeSection);
413*9880d681SAndroid Build Coastguard Worker 
414*9880d681SAndroid Build Coastguard Worker   // Up to this point, the test is specific only to X86-64. But this next
415*9880d681SAndroid Build Coastguard Worker   // expectation is only valid on Darwin because it assumes that unwind
416*9880d681SAndroid Build Coastguard Worker   // data is made available only through compact_unwind. It would be
417*9880d681SAndroid Build Coastguard Worker   // worthwhile to extend this to handle non-Darwin platforms, in which
418*9880d681SAndroid Build Coastguard Worker   // case you'd want to look for an eh_frame or something.
419*9880d681SAndroid Build Coastguard Worker   //
420*9880d681SAndroid Build Coastguard Worker   // FIXME: Currently, MCJIT relies on a configure-time check to determine which
421*9880d681SAndroid Build Coastguard Worker   // sections to emit. The JIT client should have runtime control over this.
422*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(
423*9880d681SAndroid Build Coastguard Worker     Triple(HostTriple).getOS() != Triple::Darwin ||
424*9880d681SAndroid Build Coastguard Worker     Triple(HostTriple).isMacOSXVersionLT(10, 7) ||
425*9880d681SAndroid Build Coastguard Worker     didAllocateCompactUnwindSection);
426*9880d681SAndroid Build Coastguard Worker }
427*9880d681SAndroid Build Coastguard Worker 
TEST_F(MCJITCAPITest,reserve_allocation_space)428*9880d681SAndroid Build Coastguard Worker TEST_F(MCJITCAPITest, reserve_allocation_space) {
429*9880d681SAndroid Build Coastguard Worker   SKIP_UNSUPPORTED_PLATFORM;
430*9880d681SAndroid Build Coastguard Worker 
431*9880d681SAndroid Build Coastguard Worker   TestReserveAllocationSpaceMemoryManager* MM = new TestReserveAllocationSpaceMemoryManager();
432*9880d681SAndroid Build Coastguard Worker 
433*9880d681SAndroid Build Coastguard Worker   buildModuleWithCodeAndData();
434*9880d681SAndroid Build Coastguard Worker   buildMCJITOptions();
435*9880d681SAndroid Build Coastguard Worker   Options.MCJMM = wrap(MM);
436*9880d681SAndroid Build Coastguard Worker   buildMCJITEngine();
437*9880d681SAndroid Build Coastguard Worker   buildAndRunPasses();
438*9880d681SAndroid Build Coastguard Worker 
439*9880d681SAndroid Build Coastguard Worker   auto GetGlobalFct = reinterpret_cast<int (*)()>(
440*9880d681SAndroid Build Coastguard Worker       reinterpret_cast<uintptr_t>(LLVMGetPointerToGlobal(Engine, Function)));
441*9880d681SAndroid Build Coastguard Worker 
442*9880d681SAndroid Build Coastguard Worker   auto SetGlobalFct = reinterpret_cast<void (*)(int)>(
443*9880d681SAndroid Build Coastguard Worker       reinterpret_cast<uintptr_t>(LLVMGetPointerToGlobal(Engine, Function2)));
444*9880d681SAndroid Build Coastguard Worker 
445*9880d681SAndroid Build Coastguard Worker   SetGlobalFct(789);
446*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(789, GetGlobalFct());
447*9880d681SAndroid Build Coastguard Worker   EXPECT_LE(MM->UsedCodeSize, MM->ReservedCodeSize);
448*9880d681SAndroid Build Coastguard Worker   EXPECT_LE(MM->UsedDataSizeRO, MM->ReservedDataSizeRO);
449*9880d681SAndroid Build Coastguard Worker   EXPECT_LE(MM->UsedDataSizeRW, MM->ReservedDataSizeRW);
450*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(MM->UsedCodeSize > 0);
451*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(MM->UsedDataSizeRW > 0);
452*9880d681SAndroid Build Coastguard Worker }
453*9880d681SAndroid Build Coastguard Worker 
TEST_F(MCJITCAPITest,yield)454*9880d681SAndroid Build Coastguard Worker TEST_F(MCJITCAPITest, yield) {
455*9880d681SAndroid Build Coastguard Worker   SKIP_UNSUPPORTED_PLATFORM;
456*9880d681SAndroid Build Coastguard Worker 
457*9880d681SAndroid Build Coastguard Worker   buildSimpleFunction();
458*9880d681SAndroid Build Coastguard Worker   buildMCJITOptions();
459*9880d681SAndroid Build Coastguard Worker   buildMCJITEngine();
460*9880d681SAndroid Build Coastguard Worker   LLVMContextRef C = LLVMGetGlobalContext();
461*9880d681SAndroid Build Coastguard Worker   LLVMContextSetYieldCallback(C, yield, nullptr);
462*9880d681SAndroid Build Coastguard Worker   buildAndRunPasses();
463*9880d681SAndroid Build Coastguard Worker 
464*9880d681SAndroid Build Coastguard Worker   auto *functionPointer = reinterpret_cast<int (*)()>(
465*9880d681SAndroid Build Coastguard Worker       reinterpret_cast<uintptr_t>(LLVMGetPointerToGlobal(Engine, Function)));
466*9880d681SAndroid Build Coastguard Worker 
467*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(42, functionPointer());
468*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(didCallYield);
469*9880d681SAndroid Build Coastguard Worker }
470*9880d681SAndroid Build Coastguard Worker 
localTestFunc()471*9880d681SAndroid Build Coastguard Worker static int localTestFunc() {
472*9880d681SAndroid Build Coastguard Worker   return 42;
473*9880d681SAndroid Build Coastguard Worker }
474*9880d681SAndroid Build Coastguard Worker 
TEST_F(MCJITCAPITest,addGlobalMapping)475*9880d681SAndroid Build Coastguard Worker TEST_F(MCJITCAPITest, addGlobalMapping) {
476*9880d681SAndroid Build Coastguard Worker   SKIP_UNSUPPORTED_PLATFORM;
477*9880d681SAndroid Build Coastguard Worker 
478*9880d681SAndroid Build Coastguard Worker   Module = LLVMModuleCreateWithName("testModule");
479*9880d681SAndroid Build Coastguard Worker   LLVMSetTarget(Module, HostTriple.c_str());
480*9880d681SAndroid Build Coastguard Worker   LLVMTypeRef FunctionType = LLVMFunctionType(LLVMInt32Type(), nullptr, 0, 0);
481*9880d681SAndroid Build Coastguard Worker   LLVMValueRef MappedFn = LLVMAddFunction(Module, "mapped_fn", FunctionType);
482*9880d681SAndroid Build Coastguard Worker 
483*9880d681SAndroid Build Coastguard Worker   Function = LLVMAddFunction(Module, "test_fn", FunctionType);
484*9880d681SAndroid Build Coastguard Worker   LLVMBasicBlockRef Entry = LLVMAppendBasicBlock(Function, "");
485*9880d681SAndroid Build Coastguard Worker   LLVMBuilderRef Builder = LLVMCreateBuilder();
486*9880d681SAndroid Build Coastguard Worker   LLVMPositionBuilderAtEnd(Builder, Entry);
487*9880d681SAndroid Build Coastguard Worker   LLVMValueRef RetVal = LLVMBuildCall(Builder, MappedFn, nullptr, 0, "");
488*9880d681SAndroid Build Coastguard Worker   LLVMBuildRet(Builder, RetVal);
489*9880d681SAndroid Build Coastguard Worker   LLVMDisposeBuilder(Builder);
490*9880d681SAndroid Build Coastguard Worker 
491*9880d681SAndroid Build Coastguard Worker   LLVMVerifyModule(Module, LLVMAbortProcessAction, &Error);
492*9880d681SAndroid Build Coastguard Worker   LLVMDisposeMessage(Error);
493*9880d681SAndroid Build Coastguard Worker 
494*9880d681SAndroid Build Coastguard Worker   buildMCJITOptions();
495*9880d681SAndroid Build Coastguard Worker   buildMCJITEngine();
496*9880d681SAndroid Build Coastguard Worker 
497*9880d681SAndroid Build Coastguard Worker   LLVMAddGlobalMapping(
498*9880d681SAndroid Build Coastguard Worker       Engine, MappedFn,
499*9880d681SAndroid Build Coastguard Worker       reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(&localTestFunc)));
500*9880d681SAndroid Build Coastguard Worker 
501*9880d681SAndroid Build Coastguard Worker   buildAndRunPasses();
502*9880d681SAndroid Build Coastguard Worker 
503*9880d681SAndroid Build Coastguard Worker   uint64_t raw = LLVMGetFunctionAddress(Engine, "test_fn");
504*9880d681SAndroid Build Coastguard Worker   int (*usable)() = (int (*)()) raw;
505*9880d681SAndroid Build Coastguard Worker 
506*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(42, usable());
507*9880d681SAndroid Build Coastguard Worker }
508