1 //===- JITTest.cpp - Unit tests for the JIT -------------------------------===//
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 #include "llvm/ExecutionEngine/JIT.h"
11 #include "llvm/ADT/OwningPtr.h"
12 #include "llvm/ADT/SmallPtrSet.h"
13 #include "llvm/Assembly/Parser.h"
14 #include "llvm/Bitcode/ReaderWriter.h"
15 #include "llvm/ExecutionEngine/JITMemoryManager.h"
16 #include "llvm/IR/BasicBlock.h"
17 #include "llvm/IR/Constant.h"
18 #include "llvm/IR/Constants.h"
19 #include "llvm/IR/DerivedTypes.h"
20 #include "llvm/IR/Function.h"
21 #include "llvm/IR/GlobalValue.h"
22 #include "llvm/IR/GlobalVariable.h"
23 #include "llvm/IR/IRBuilder.h"
24 #include "llvm/IR/LLVMContext.h"
25 #include "llvm/IR/Module.h"
26 #include "llvm/IR/Type.h"
27 #include "llvm/IR/TypeBuilder.h"
28 #include "llvm/Support/MemoryBuffer.h"
29 #include "llvm/Support/SourceMgr.h"
30 #include "llvm/Support/TargetSelect.h"
31 #include "gtest/gtest.h"
38 Function *makeReturnGlobal(std::string Name, GlobalVariable *G, Module *M) {
39 std::vector<Type*> params;
40 FunctionType *FTy = FunctionType::get(G->getType()->getElementType(),
42 Function *F = Function::Create(FTy, GlobalValue::ExternalLinkage, Name, M);
43 BasicBlock *Entry = BasicBlock::Create(M->getContext(), "entry", F);
44 IRBuilder<> builder(Entry);
45 Value *Load = builder.CreateLoad(G);
46 Type *GTy = G->getType()->getElementType();
47 Value *Add = builder.CreateAdd(Load, ConstantInt::get(GTy, 1LL));
48 builder.CreateStore(Add, G);
49 builder.CreateRet(Add);
53 std::string DumpFunction(const Function *F) {
55 raw_string_ostream(Result) << "" << *F;
59 class RecordingJITMemoryManager : public JITMemoryManager {
60 const OwningPtr<JITMemoryManager> Base;
62 RecordingJITMemoryManager()
63 : Base(JITMemoryManager::CreateDefaultMemManager()) {
66 virtual void *getPointerToNamedFunction(const std::string &Name,
67 bool AbortOnFailure = true) {
68 return Base->getPointerToNamedFunction(Name, AbortOnFailure);
71 virtual void setMemoryWritable() { Base->setMemoryWritable(); }
72 virtual void setMemoryExecutable() { Base->setMemoryExecutable(); }
73 virtual void setPoisonMemory(bool poison) { Base->setPoisonMemory(poison); }
74 virtual void AllocateGOT() { Base->AllocateGOT(); }
75 virtual uint8_t *getGOTBase() const { return Base->getGOTBase(); }
76 struct StartFunctionBodyCall {
77 StartFunctionBodyCall(uint8_t *Result, const Function *F,
78 uintptr_t ActualSize, uintptr_t ActualSizeResult)
79 : Result(Result), F(F), F_dump(DumpFunction(F)),
80 ActualSize(ActualSize), ActualSizeResult(ActualSizeResult) {}
85 uintptr_t ActualSizeResult;
87 std::vector<StartFunctionBodyCall> startFunctionBodyCalls;
88 virtual uint8_t *startFunctionBody(const Function *F,
89 uintptr_t &ActualSize) {
90 uintptr_t InitialActualSize = ActualSize;
91 uint8_t *Result = Base->startFunctionBody(F, ActualSize);
92 startFunctionBodyCalls.push_back(
93 StartFunctionBodyCall(Result, F, InitialActualSize, ActualSize));
97 virtual uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize,
100 return Base->allocateStub(F, StubSize, Alignment);
102 struct EndFunctionBodyCall {
103 EndFunctionBodyCall(const Function *F, uint8_t *FunctionStart,
104 uint8_t *FunctionEnd)
105 : F(F), F_dump(DumpFunction(F)),
106 FunctionStart(FunctionStart), FunctionEnd(FunctionEnd) {}
109 uint8_t *FunctionStart;
110 uint8_t *FunctionEnd;
112 std::vector<EndFunctionBodyCall> endFunctionBodyCalls;
113 virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart,
114 uint8_t *FunctionEnd) {
115 endFunctionBodyCalls.push_back(
116 EndFunctionBodyCall(F, FunctionStart, FunctionEnd));
117 Base->endFunctionBody(F, FunctionStart, FunctionEnd);
119 virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
120 unsigned SectionID, bool IsReadOnly) {
121 return Base->allocateDataSection(Size, Alignment, SectionID, IsReadOnly);
123 virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
124 unsigned SectionID) {
125 return Base->allocateCodeSection(Size, Alignment, SectionID);
127 virtual bool applyPermissions(std::string *ErrMsg) { return false; }
128 virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) {
129 return Base->allocateSpace(Size, Alignment);
131 virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) {
132 return Base->allocateGlobal(Size, Alignment);
134 struct DeallocateFunctionBodyCall {
135 DeallocateFunctionBodyCall(const void *Body) : Body(Body) {}
138 std::vector<DeallocateFunctionBodyCall> deallocateFunctionBodyCalls;
139 virtual void deallocateFunctionBody(void *Body) {
140 deallocateFunctionBodyCalls.push_back(DeallocateFunctionBodyCall(Body));
141 Base->deallocateFunctionBody(Body);
143 struct DeallocateExceptionTableCall {
144 DeallocateExceptionTableCall(const void *ET) : ET(ET) {}
147 std::vector<DeallocateExceptionTableCall> deallocateExceptionTableCalls;
148 virtual void deallocateExceptionTable(void *ET) {
149 deallocateExceptionTableCalls.push_back(DeallocateExceptionTableCall(ET));
150 Base->deallocateExceptionTable(ET);
152 struct StartExceptionTableCall {
153 StartExceptionTableCall(uint8_t *Result, const Function *F,
154 uintptr_t ActualSize, uintptr_t ActualSizeResult)
155 : Result(Result), F(F), F_dump(DumpFunction(F)),
156 ActualSize(ActualSize), ActualSizeResult(ActualSizeResult) {}
160 uintptr_t ActualSize;
161 uintptr_t ActualSizeResult;
163 std::vector<StartExceptionTableCall> startExceptionTableCalls;
164 virtual uint8_t *startExceptionTable(const Function *F,
165 uintptr_t &ActualSize) {
166 uintptr_t InitialActualSize = ActualSize;
167 uint8_t *Result = Base->startExceptionTable(F, ActualSize);
168 startExceptionTableCalls.push_back(
169 StartExceptionTableCall(Result, F, InitialActualSize, ActualSize));
172 struct EndExceptionTableCall {
173 EndExceptionTableCall(const Function *F, uint8_t *TableStart,
174 uint8_t *TableEnd, uint8_t* FrameRegister)
175 : F(F), F_dump(DumpFunction(F)),
176 TableStart(TableStart), TableEnd(TableEnd),
177 FrameRegister(FrameRegister) {}
182 uint8_t *FrameRegister;
184 std::vector<EndExceptionTableCall> endExceptionTableCalls;
185 virtual void endExceptionTable(const Function *F, uint8_t *TableStart,
186 uint8_t *TableEnd, uint8_t* FrameRegister) {
187 endExceptionTableCalls.push_back(
188 EndExceptionTableCall(F, TableStart, TableEnd, FrameRegister));
189 return Base->endExceptionTable(F, TableStart, TableEnd, FrameRegister);
193 bool LoadAssemblyInto(Module *M, const char *assembly) {
196 NULL != ParseAssemblyString(assembly, M, Error, M->getContext());
198 raw_string_ostream os(errMsg);
200 EXPECT_TRUE(success) << os.str();
204 class JITTest : public testing::Test {
206 virtual RecordingJITMemoryManager *createMemoryManager() {
207 return new RecordingJITMemoryManager;
210 virtual void SetUp() {
211 M = new Module("<main>", Context);
212 RJMM = createMemoryManager();
213 RJMM->setPoisonMemory(true);
215 TargetOptions Options;
216 Options.JITExceptionHandling = true;
217 TheJIT.reset(EngineBuilder(M).setEngineKind(EngineKind::JIT)
218 .setJITMemoryManager(RJMM)
220 .setTargetOptions(Options).create());
221 ASSERT_TRUE(TheJIT.get() != NULL) << Error;
224 void LoadAssembly(const char *assembly) {
225 LoadAssemblyInto(M, assembly);
229 Module *M; // Owned by ExecutionEngine.
230 RecordingJITMemoryManager *RJMM;
231 OwningPtr<ExecutionEngine> TheJIT;
234 // Tests on ARM and PowerPC disabled as we're running the old jit
235 #if !defined(__arm__) && !defined(__powerpc__)
237 // Regression test for a bug. The JIT used to allocate globals inside the same
238 // memory block used for the function, and when the function code was freed,
239 // the global was left in the same place. This test allocates a function
240 // that uses and global, deallocates it, and then makes sure that the global
241 // stays alive after that.
242 TEST(JIT, GlobalInFunction) {
244 Module *M = new Module("<main>", context);
246 JITMemoryManager *MemMgr = JITMemoryManager::CreateDefaultMemManager();
247 // Tell the memory manager to poison freed memory so that accessing freed
248 // memory is more easily tested.
249 MemMgr->setPoisonMemory(true);
251 OwningPtr<ExecutionEngine> JIT(EngineBuilder(M)
252 .setEngineKind(EngineKind::JIT)
254 .setJITMemoryManager(MemMgr)
255 // The next line enables the fix:
256 .setAllocateGVsWithCode(false)
258 ASSERT_EQ(Error, "");
260 // Create a global variable.
261 Type *GTy = Type::getInt32Ty(context);
262 GlobalVariable *G = new GlobalVariable(
265 false, // Not constant.
266 GlobalValue::InternalLinkage,
267 Constant::getNullValue(GTy),
270 // Make a function that points to a global.
271 Function *F1 = makeReturnGlobal("F1", G, M);
273 // Get the pointer to the native code to force it to JIT the function and
274 // allocate space for the global.
276 reinterpret_cast<void(*)()>((intptr_t)JIT->getPointerToFunction(F1));
278 // Since F1 was codegen'd, a pointer to G should be available.
279 int32_t *GPtr = (int32_t*)JIT->getPointerToGlobalIfAvailable(G);
280 ASSERT_NE((int32_t*)NULL, GPtr);
283 // F1() should increment G.
287 // Make a second function identical to the first, referring to the same
289 Function *F2 = makeReturnGlobal("F2", G, M);
291 reinterpret_cast<void(*)()>((intptr_t)JIT->getPointerToFunction(F2));
293 // F2() should increment G.
298 JIT->freeMachineCodeForFunction(F1);
300 // F2() should *still* increment G.
305 #endif // !defined(__arm__) && !defined(__powerpc__)
307 // Regression test for a bug. The JITEmitter wasn't checking to verify that
308 // it hadn't run out of space while generating the DWARF exception information
309 // for an emitted function.
311 class ExceptionMemoryManagerMock : public RecordingJITMemoryManager {
313 virtual uint8_t *startExceptionTable(const Function *F,
314 uintptr_t &ActualSize) {
315 // force an insufficient size the first time through.
316 bool ChangeActualSize = false;
318 ChangeActualSize = true;;
320 RecordingJITMemoryManager::startExceptionTable(F, ActualSize);
321 if (ChangeActualSize)
327 class JITExceptionMemoryTest : public JITTest {
329 virtual RecordingJITMemoryManager *createMemoryManager() {
330 return new ExceptionMemoryManagerMock;
334 TEST_F(JITExceptionMemoryTest, ExceptionTableOverflow) {
335 Function *F = Function::Create(TypeBuilder<void(void), false>::get(Context),
336 Function::ExternalLinkage,
338 BasicBlock *Block = BasicBlock::Create(Context, "block", F);
339 IRBuilder<> Builder(Block);
340 Builder.CreateRetVoid();
341 TheJIT->getPointerToFunction(F);
342 ASSERT_TRUE(RJMM->startExceptionTableCalls.size() == 2);
343 ASSERT_TRUE(RJMM->deallocateExceptionTableCalls.size() == 1);
344 ASSERT_TRUE(RJMM->endExceptionTableCalls.size() == 1);
347 int PlusOne(int arg) {
351 // ARM and PowerPC tests disabled pending fix for PR10783.
352 #if !defined(__arm__) && !defined(__powerpc__)
353 TEST_F(JITTest, FarCallToKnownFunction) {
354 // x86-64 can only make direct calls to functions within 32 bits of
355 // the current PC. To call anything farther away, we have to load
356 // the address into a register and call through the register. The
357 // current JIT does this by allocating a stub for any far call.
358 // There was a bug in which the JIT tried to emit a direct call when
359 // the target was already in the JIT's global mappings and lazy
360 // compilation was disabled.
362 Function *KnownFunction = Function::Create(
363 TypeBuilder<int(int), false>::get(Context),
364 GlobalValue::ExternalLinkage, "known", M);
365 TheJIT->addGlobalMapping(KnownFunction, (void*)(intptr_t)PlusOne);
367 // int test() { return known(7); }
368 Function *TestFunction = Function::Create(
369 TypeBuilder<int(), false>::get(Context),
370 GlobalValue::ExternalLinkage, "test", M);
371 BasicBlock *Entry = BasicBlock::Create(Context, "entry", TestFunction);
372 IRBuilder<> Builder(Entry);
373 Value *result = Builder.CreateCall(
375 ConstantInt::get(TypeBuilder<int, false>::get(Context), 7));
376 Builder.CreateRet(result);
378 TheJIT->DisableLazyCompilation(true);
379 int (*TestFunctionPtr)() = reinterpret_cast<int(*)()>(
380 (intptr_t)TheJIT->getPointerToFunction(TestFunction));
381 // This used to crash in trying to call PlusOne().
382 EXPECT_EQ(8, TestFunctionPtr());
385 // Test a function C which calls A and B which call each other.
386 TEST_F(JITTest, NonLazyCompilationStillNeedsStubs) {
387 TheJIT->DisableLazyCompilation(true);
389 FunctionType *Func1Ty =
390 cast<FunctionType>(TypeBuilder<void(void), false>::get(Context));
391 std::vector<Type*> arg_types;
392 arg_types.push_back(Type::getInt1Ty(Context));
393 FunctionType *FuncTy = FunctionType::get(
394 Type::getVoidTy(Context), arg_types, false);
395 Function *Func1 = Function::Create(Func1Ty, Function::ExternalLinkage,
397 Function *Func2 = Function::Create(FuncTy, Function::InternalLinkage,
399 Function *Func3 = Function::Create(FuncTy, Function::InternalLinkage,
401 BasicBlock *Block1 = BasicBlock::Create(Context, "block1", Func1);
402 BasicBlock *Block2 = BasicBlock::Create(Context, "block2", Func2);
403 BasicBlock *True2 = BasicBlock::Create(Context, "cond_true", Func2);
404 BasicBlock *False2 = BasicBlock::Create(Context, "cond_false", Func2);
405 BasicBlock *Block3 = BasicBlock::Create(Context, "block3", Func3);
406 BasicBlock *True3 = BasicBlock::Create(Context, "cond_true", Func3);
407 BasicBlock *False3 = BasicBlock::Create(Context, "cond_false", Func3);
409 // Make Func1 call Func2(0) and Func3(0).
410 IRBuilder<> Builder(Block1);
411 Builder.CreateCall(Func2, ConstantInt::getTrue(Context));
412 Builder.CreateCall(Func3, ConstantInt::getTrue(Context));
413 Builder.CreateRetVoid();
415 // void Func2(bool b) { if (b) { Func3(false); return; } return; }
416 Builder.SetInsertPoint(Block2);
417 Builder.CreateCondBr(Func2->arg_begin(), True2, False2);
418 Builder.SetInsertPoint(True2);
419 Builder.CreateCall(Func3, ConstantInt::getFalse(Context));
420 Builder.CreateRetVoid();
421 Builder.SetInsertPoint(False2);
422 Builder.CreateRetVoid();
424 // void Func3(bool b) { if (b) { Func2(false); return; } return; }
425 Builder.SetInsertPoint(Block3);
426 Builder.CreateCondBr(Func3->arg_begin(), True3, False3);
427 Builder.SetInsertPoint(True3);
428 Builder.CreateCall(Func2, ConstantInt::getFalse(Context));
429 Builder.CreateRetVoid();
430 Builder.SetInsertPoint(False3);
431 Builder.CreateRetVoid();
433 // Compile the function to native code
435 reinterpret_cast<void(*)()>((intptr_t)TheJIT->getPointerToFunction(Func1));
440 // Regression test for PR5162. This used to trigger an AssertingVH inside the
441 // JIT's Function to stub mapping.
442 TEST_F(JITTest, NonLazyLeaksNoStubs) {
443 TheJIT->DisableLazyCompilation(true);
445 // Create two functions with a single basic block each.
446 FunctionType *FuncTy =
447 cast<FunctionType>(TypeBuilder<int(), false>::get(Context));
448 Function *Func1 = Function::Create(FuncTy, Function::ExternalLinkage,
450 Function *Func2 = Function::Create(FuncTy, Function::InternalLinkage,
452 BasicBlock *Block1 = BasicBlock::Create(Context, "block1", Func1);
453 BasicBlock *Block2 = BasicBlock::Create(Context, "block2", Func2);
455 // The first function calls the second and returns the result
456 IRBuilder<> Builder(Block1);
457 Value *Result = Builder.CreateCall(Func2);
458 Builder.CreateRet(Result);
460 // The second function just returns a constant
461 Builder.SetInsertPoint(Block2);
462 Builder.CreateRet(ConstantInt::get(TypeBuilder<int, false>::get(Context),42));
464 // Compile the function to native code
465 (void)TheJIT->getPointerToFunction(Func1);
467 // Free the JIT state for the functions
468 TheJIT->freeMachineCodeForFunction(Func1);
469 TheJIT->freeMachineCodeForFunction(Func2);
471 // Delete the first function (and show that is has no users)
472 EXPECT_EQ(Func1->getNumUses(), 0u);
473 Func1->eraseFromParent();
475 // Delete the second function (and show that it has no users - it had one,
476 // func1 but that's gone now)
477 EXPECT_EQ(Func2->getNumUses(), 0u);
478 Func2->eraseFromParent();
481 TEST_F(JITTest, ModuleDeletion) {
482 TheJIT->DisableLazyCompilation(false);
483 LoadAssembly("define void @main() { "
484 " call i32 @computeVal() "
488 "define internal i32 @computeVal() { "
491 Function *func = M->getFunction("main");
492 TheJIT->getPointerToFunction(func);
493 TheJIT->removeModule(M);
496 SmallPtrSet<const void*, 2> FunctionsDeallocated;
497 for (unsigned i = 0, e = RJMM->deallocateFunctionBodyCalls.size();
499 FunctionsDeallocated.insert(RJMM->deallocateFunctionBodyCalls[i].Body);
501 for (unsigned i = 0, e = RJMM->startFunctionBodyCalls.size(); i != e; ++i) {
502 EXPECT_TRUE(FunctionsDeallocated.count(
503 RJMM->startFunctionBodyCalls[i].Result))
504 << "Function leaked: \n" << RJMM->startFunctionBodyCalls[i].F_dump;
506 EXPECT_EQ(RJMM->startFunctionBodyCalls.size(),
507 RJMM->deallocateFunctionBodyCalls.size());
509 SmallPtrSet<const void*, 2> ExceptionTablesDeallocated;
510 unsigned NumTablesDeallocated = 0;
511 for (unsigned i = 0, e = RJMM->deallocateExceptionTableCalls.size();
513 ExceptionTablesDeallocated.insert(
514 RJMM->deallocateExceptionTableCalls[i].ET);
515 if (RJMM->deallocateExceptionTableCalls[i].ET != NULL) {
516 // If JITEmitDebugInfo is off, we'll "deallocate" NULL, which doesn't
517 // appear in startExceptionTableCalls.
518 NumTablesDeallocated++;
521 for (unsigned i = 0, e = RJMM->startExceptionTableCalls.size(); i != e; ++i) {
522 EXPECT_TRUE(ExceptionTablesDeallocated.count(
523 RJMM->startExceptionTableCalls[i].Result))
524 << "Function's exception table leaked: \n"
525 << RJMM->startExceptionTableCalls[i].F_dump;
527 EXPECT_EQ(RJMM->startExceptionTableCalls.size(),
528 NumTablesDeallocated);
530 #endif // !defined(__arm__) && !defined(__powerpc__)
532 // ARM, MIPS and PPC still emit stubs for calls since the target may be
533 // too far away to call directly. This #if can probably be removed when
534 // http://llvm.org/PR5201 is fixed.
535 #if !defined(__arm__) && !defined(__mips__) && \
536 !defined(__powerpc__) && !defined(__ppc__)
537 typedef int (*FooPtr) ();
539 TEST_F(JITTest, NoStubs) {
540 LoadAssembly("define void @bar() {"
545 "define i32 @foo() {"
551 "define i32 @main() {"
553 "%0 = call i32 @foo()"
557 Function *foo = M->getFunction("foo");
558 uintptr_t tmp = (uintptr_t)(TheJIT->getPointerToFunction(foo));
559 FooPtr ptr = (FooPtr)(tmp);
563 // We should now allocate no more stubs, we have the code to foo
564 // and the existing stub for bar.
565 int stubsBefore = RJMM->stubsAllocated;
566 Function *func = M->getFunction("main");
567 TheJIT->getPointerToFunction(func);
569 Function *bar = M->getFunction("bar");
570 TheJIT->getPointerToFunction(bar);
572 ASSERT_EQ(stubsBefore, RJMM->stubsAllocated);
574 #endif // !ARM && !PPC
576 // Tests on ARM and PowerPC disabled as we're running the old jit
577 #if !defined(__arm__) && !defined(__powerpc__)
579 TEST_F(JITTest, FunctionPointersOutliveTheirCreator) {
580 TheJIT->DisableLazyCompilation(true);
581 LoadAssembly("define i8()* @get_foo_addr() { "
585 "define i8 @foo() { "
588 Function *F_get_foo_addr = M->getFunction("get_foo_addr");
590 typedef char(*fooT)();
591 fooT (*get_foo_addr)() = reinterpret_cast<fooT(*)()>(
592 (intptr_t)TheJIT->getPointerToFunction(F_get_foo_addr));
593 fooT foo_addr = get_foo_addr();
595 // Now free get_foo_addr. This should not free the machine code for foo or
596 // any call stub returned as foo's canonical address.
597 TheJIT->freeMachineCodeForFunction(F_get_foo_addr);
599 // Check by calling the reported address of foo.
600 EXPECT_EQ(42, foo_addr());
602 // The reported address should also be the same as the result of a subsequent
603 // getPointerToFunction(foo).
605 // Fails until PR5126 is fixed:
606 Function *F_foo = M->getFunction("foo");
607 fooT foo = reinterpret_cast<fooT>(
608 (intptr_t)TheJIT->getPointerToFunction(F_foo));
609 EXPECT_EQ((intptr_t)foo, (intptr_t)foo_addr);
613 #endif //!defined(__arm__) && !defined(__powerpc__)
615 // Tests on ARM and PowerPC disabled as we're running the old jit
616 // In addition, ARM does not have an implementation
617 // of replaceMachineCodeForFunction(), so recompileAndRelinkFunction
619 #if !defined(__arm__) && !defined(__powerpc__)
620 TEST_F(JITTest, FunctionIsRecompiledAndRelinked) {
621 Function *F = Function::Create(TypeBuilder<int(void), false>::get(Context),
622 GlobalValue::ExternalLinkage, "test", M);
623 BasicBlock *Entry = BasicBlock::Create(Context, "entry", F);
624 IRBuilder<> Builder(Entry);
625 Value *Val = ConstantInt::get(TypeBuilder<int, false>::get(Context), 1);
626 Builder.CreateRet(Val);
628 TheJIT->DisableLazyCompilation(true);
629 // Compile the function once, and make sure it works.
630 int (*OrigFPtr)() = reinterpret_cast<int(*)()>(
631 (intptr_t)TheJIT->recompileAndRelinkFunction(F));
632 EXPECT_EQ(1, OrigFPtr());
634 // Now change the function to return a different value.
635 Entry->eraseFromParent();
636 BasicBlock *NewEntry = BasicBlock::Create(Context, "new_entry", F);
637 Builder.SetInsertPoint(NewEntry);
638 Val = ConstantInt::get(TypeBuilder<int, false>::get(Context), 2);
639 Builder.CreateRet(Val);
640 // Recompile it, which should produce a new function pointer _and_ update the
642 int (*NewFPtr)() = reinterpret_cast<int(*)()>(
643 (intptr_t)TheJIT->recompileAndRelinkFunction(F));
645 EXPECT_EQ(2, NewFPtr())
646 << "The new pointer should call the new version of the function";
647 EXPECT_EQ(2, OrigFPtr())
648 << "The old pointer's target should now jump to the new version";
650 #endif // !defined(__arm__) && !defined(__powerpc__)
652 } // anonymous namespace
653 // This variable is intentionally defined differently in the statically-compiled
654 // program from the IR input to the JIT to assert that the JIT doesn't use its
656 extern "C" int32_t JITTest_AvailableExternallyGlobal;
657 int32_t JITTest_AvailableExternallyGlobal LLVM_ATTRIBUTE_USED = 42;
660 // Tests on ARM and PowerPC disabled as we're running the old jit
661 #if !defined(__arm__) && !defined(__powerpc__)
663 TEST_F(JITTest, AvailableExternallyGlobalIsntEmitted) {
664 TheJIT->DisableLazyCompilation(true);
665 LoadAssembly("@JITTest_AvailableExternallyGlobal = "
666 " available_externally global i32 7 "
668 "define i32 @loader() { "
669 " %result = load i32* @JITTest_AvailableExternallyGlobal "
672 Function *loaderIR = M->getFunction("loader");
674 int32_t (*loader)() = reinterpret_cast<int32_t(*)()>(
675 (intptr_t)TheJIT->getPointerToFunction(loaderIR));
676 EXPECT_EQ(42, loader()) << "func should return 42 from the external global,"
677 << " not 7 from the IR version.";
679 #endif //!defined(__arm__) && !defined(__powerpc__)
680 } // anonymous namespace
681 // This function is intentionally defined differently in the statically-compiled
682 // program from the IR input to the JIT to assert that the JIT doesn't use its
684 extern "C" int32_t JITTest_AvailableExternallyFunction() LLVM_ATTRIBUTE_USED;
685 extern "C" int32_t JITTest_AvailableExternallyFunction() {
690 // ARM and PowerPC tests disabled pending fix for PR10783.
691 #if !defined(__arm__) && !defined(__powerpc__)
692 TEST_F(JITTest, AvailableExternallyFunctionIsntCompiled) {
693 TheJIT->DisableLazyCompilation(true);
694 LoadAssembly("define available_externally i32 "
695 " @JITTest_AvailableExternallyFunction() { "
699 "define i32 @func() { "
700 " %result = tail call i32 "
701 " @JITTest_AvailableExternallyFunction() "
704 Function *funcIR = M->getFunction("func");
706 int32_t (*func)() = reinterpret_cast<int32_t(*)()>(
707 (intptr_t)TheJIT->getPointerToFunction(funcIR));
708 EXPECT_EQ(42, func()) << "func should return 42 from the static version,"
709 << " not 7 from the IR version.";
712 TEST_F(JITTest, EscapedLazyStubStillCallable) {
713 TheJIT->DisableLazyCompilation(false);
714 LoadAssembly("define internal i32 @stubbed() { "
718 "define i32()* @get_stub() { "
719 " ret i32()* @stubbed "
721 typedef int32_t(*StubTy)();
723 // Call get_stub() to get the address of @stubbed without actually JITting it.
724 Function *get_stubIR = M->getFunction("get_stub");
725 StubTy (*get_stub)() = reinterpret_cast<StubTy(*)()>(
726 (intptr_t)TheJIT->getPointerToFunction(get_stubIR));
727 StubTy stubbed = get_stub();
728 // Now get_stubIR is the only reference to stubbed's stub.
729 get_stubIR->eraseFromParent();
730 // Now there are no references inside the JIT, but we've got a pointer outside
731 // it. The stub should be callable and return the right value.
732 EXPECT_EQ(42, stubbed());
735 // Converts the LLVM assembly to bitcode and returns it in a std::string. An
736 // empty string indicates an error.
737 std::string AssembleToBitcode(LLVMContext &Context, const char *Assembly) {
738 Module TempModule("TempModule", Context);
739 if (!LoadAssemblyInto(&TempModule, Assembly)) {
744 raw_string_ostream OS(Result);
745 WriteBitcodeToFile(&TempModule, OS);
750 // Returns a newly-created ExecutionEngine that reads the bitcode in 'Bitcode'
751 // lazily. The associated Module (owned by the ExecutionEngine) is returned in
752 // M. Both will be NULL on an error. Bitcode must live at least as long as the
754 ExecutionEngine *getJITFromBitcode(
755 LLVMContext &Context, const std::string &Bitcode, Module *&M) {
756 // c_str() is null-terminated like MemoryBuffer::getMemBuffer requires.
757 MemoryBuffer *BitcodeBuffer =
758 MemoryBuffer::getMemBuffer(Bitcode, "Bitcode for test");
760 M = getLazyBitcodeModule(BitcodeBuffer, Context, &errMsg);
762 ADD_FAILURE() << errMsg;
763 delete BitcodeBuffer;
766 ExecutionEngine *TheJIT = EngineBuilder(M)
767 .setEngineKind(EngineKind::JIT)
768 .setErrorStr(&errMsg)
770 if (TheJIT == NULL) {
771 ADD_FAILURE() << errMsg;
779 TEST(LazyLoadedJITTest, MaterializableAvailableExternallyFunctionIsntCompiled) {
781 const std::string Bitcode =
782 AssembleToBitcode(Context,
783 "define available_externally i32 "
784 " @JITTest_AvailableExternallyFunction() { "
788 "define i32 @func() { "
789 " %result = tail call i32 "
790 " @JITTest_AvailableExternallyFunction() "
793 ASSERT_FALSE(Bitcode.empty()) << "Assembling failed";
795 OwningPtr<ExecutionEngine> TheJIT(getJITFromBitcode(Context, Bitcode, M));
796 ASSERT_TRUE(TheJIT.get()) << "Failed to create JIT.";
797 TheJIT->DisableLazyCompilation(true);
799 Function *funcIR = M->getFunction("func");
800 Function *availableFunctionIR =
801 M->getFunction("JITTest_AvailableExternallyFunction");
803 // Double-check that the available_externally function is still unmaterialized
804 // when getPointerToFunction needs to find out if it's available_externally.
805 EXPECT_TRUE(availableFunctionIR->isMaterializable());
807 int32_t (*func)() = reinterpret_cast<int32_t(*)()>(
808 (intptr_t)TheJIT->getPointerToFunction(funcIR));
809 EXPECT_EQ(42, func()) << "func should return 42 from the static version,"
810 << " not 7 from the IR version.";
813 TEST(LazyLoadedJITTest, EagerCompiledRecursionThroughGhost) {
815 const std::string Bitcode =
816 AssembleToBitcode(Context,
817 "define i32 @recur1(i32 %a) { "
818 " %zero = icmp eq i32 %a, 0 "
819 " br i1 %zero, label %done, label %notdone "
823 " %am1 = sub i32 %a, 1 "
824 " %result = call i32 @recur2(i32 %am1) "
828 "define i32 @recur2(i32 %b) { "
829 " %result = call i32 @recur1(i32 %b) "
832 ASSERT_FALSE(Bitcode.empty()) << "Assembling failed";
834 OwningPtr<ExecutionEngine> TheJIT(getJITFromBitcode(Context, Bitcode, M));
835 ASSERT_TRUE(TheJIT.get()) << "Failed to create JIT.";
836 TheJIT->DisableLazyCompilation(true);
838 Function *recur1IR = M->getFunction("recur1");
839 Function *recur2IR = M->getFunction("recur2");
840 EXPECT_TRUE(recur1IR->isMaterializable());
841 EXPECT_TRUE(recur2IR->isMaterializable());
843 int32_t (*recur1)(int32_t) = reinterpret_cast<int32_t(*)(int32_t)>(
844 (intptr_t)TheJIT->getPointerToFunction(recur1IR));
845 EXPECT_EQ(3, recur1(4));
847 #endif // !defined(__arm__) && !defined(__powerpc__)
849 // This code is copied from JITEventListenerTest, but it only runs once for all
850 // the tests in this directory. Everything seems fine, but that's strange
852 class JITEnvironment : public testing::Environment {
853 virtual void SetUp() {
854 // Required to create a JIT.
855 InitializeNativeTarget();
858 testing::Environment* const jit_env =
859 testing::AddGlobalTestEnvironment(new JITEnvironment);