1 //===- JITTest.cpp - Unit tests for the JIT -------------------------------===// 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 #include "llvm/ExecutionEngine/JIT.h" 11 #include "llvm/ADT/SmallPtrSet.h" 12 #include "llvm/AsmParser/Parser.h" 13 #include "llvm/Bitcode/ReaderWriter.h" 14 #include "llvm/ExecutionEngine/JITMemoryManager.h" 15 #include "llvm/IR/BasicBlock.h" 16 #include "llvm/IR/Constant.h" 17 #include "llvm/IR/Constants.h" 18 #include "llvm/IR/DerivedTypes.h" 19 #include "llvm/IR/Function.h" 20 #include "llvm/IR/GlobalValue.h" 21 #include "llvm/IR/GlobalVariable.h" 22 #include "llvm/IR/IRBuilder.h" 23 #include "llvm/IR/LLVMContext.h" 24 #include "llvm/IR/Module.h" 25 #include "llvm/IR/Type.h" 26 #include "llvm/IR/TypeBuilder.h" 27 #include "llvm/Support/MemoryBuffer.h" 28 #include "llvm/Support/SourceMgr.h" 29 #include "llvm/Support/TargetSelect.h" 30 #include "gtest/gtest.h" 31 #include <vector> 32 33 using namespace llvm; 34 35 // This variable is intentionally defined differently in the statically-compiled 36 // program from the IR input to the JIT to assert that the JIT doesn't use its 37 // definition. Note that this variable must be defined even on platforms where 38 // JIT tests are disabled as it is referenced from the .def file. 39 extern "C" int32_t JITTest_AvailableExternallyGlobal; 40 int32_t JITTest_AvailableExternallyGlobal LLVM_ATTRIBUTE_USED = 42; 41 42 // This function is intentionally defined differently in the statically-compiled 43 // program from the IR input to the JIT to assert that the JIT doesn't use its 44 // definition. Note that this function must be defined even on platforms where 45 // JIT tests are disabled as it is referenced from the .def file. 46 extern "C" int32_t JITTest_AvailableExternallyFunction() LLVM_ATTRIBUTE_USED; 47 extern "C" int32_t JITTest_AvailableExternallyFunction() { 48 return 42; 49 } 50 51 namespace { 52 53 // Tests on ARM, PowerPC and SystemZ disabled as we're running the old jit 54 #if !defined(__arm__) && !defined(__powerpc__) && !defined(__s390__) \ 55 && !defined(__aarch64__) 56 57 Function *makeReturnGlobal(std::string Name, GlobalVariable *G, Module *M) { 58 std::vector<Type*> params; 59 FunctionType *FTy = FunctionType::get(G->getType()->getElementType(), 60 params, false); 61 Function *F = Function::Create(FTy, GlobalValue::ExternalLinkage, Name, M); 62 BasicBlock *Entry = BasicBlock::Create(M->getContext(), "entry", F); 63 IRBuilder<> builder(Entry); 64 Value *Load = builder.CreateLoad(G); 65 Type *GTy = G->getType()->getElementType(); 66 Value *Add = builder.CreateAdd(Load, ConstantInt::get(GTy, 1LL)); 67 builder.CreateStore(Add, G); 68 builder.CreateRet(Add); 69 return F; 70 } 71 72 std::string DumpFunction(const Function *F) { 73 std::string Result; 74 raw_string_ostream(Result) << "" << *F; 75 return Result; 76 } 77 78 class RecordingJITMemoryManager : public JITMemoryManager { 79 const std::unique_ptr<JITMemoryManager> Base; 80 81 public: 82 RecordingJITMemoryManager() 83 : Base(JITMemoryManager::CreateDefaultMemManager()) { 84 stubsAllocated = 0; 85 } 86 virtual void *getPointerToNamedFunction(const std::string &Name, 87 bool AbortOnFailure = true) { 88 return Base->getPointerToNamedFunction(Name, AbortOnFailure); 89 } 90 91 virtual void setMemoryWritable() { Base->setMemoryWritable(); } 92 virtual void setMemoryExecutable() { Base->setMemoryExecutable(); } 93 virtual void setPoisonMemory(bool poison) { Base->setPoisonMemory(poison); } 94 virtual void AllocateGOT() { Base->AllocateGOT(); } 95 virtual uint8_t *getGOTBase() const { return Base->getGOTBase(); } 96 struct StartFunctionBodyCall { 97 StartFunctionBodyCall(uint8_t *Result, const Function *F, 98 uintptr_t ActualSize, uintptr_t ActualSizeResult) 99 : Result(Result), F(F), F_dump(DumpFunction(F)), 100 ActualSize(ActualSize), ActualSizeResult(ActualSizeResult) {} 101 uint8_t *Result; 102 const Function *F; 103 std::string F_dump; 104 uintptr_t ActualSize; 105 uintptr_t ActualSizeResult; 106 }; 107 std::vector<StartFunctionBodyCall> startFunctionBodyCalls; 108 virtual uint8_t *startFunctionBody(const Function *F, 109 uintptr_t &ActualSize) { 110 uintptr_t InitialActualSize = ActualSize; 111 uint8_t *Result = Base->startFunctionBody(F, ActualSize); 112 startFunctionBodyCalls.push_back( 113 StartFunctionBodyCall(Result, F, InitialActualSize, ActualSize)); 114 return Result; 115 } 116 int stubsAllocated; 117 uint8_t *allocateStub(const GlobalValue *F, unsigned StubSize, 118 unsigned Alignment) override { 119 stubsAllocated++; 120 return Base->allocateStub(F, StubSize, Alignment); 121 } 122 struct EndFunctionBodyCall { 123 EndFunctionBodyCall(const Function *F, uint8_t *FunctionStart, 124 uint8_t *FunctionEnd) 125 : F(F), F_dump(DumpFunction(F)), 126 FunctionStart(FunctionStart), FunctionEnd(FunctionEnd) {} 127 const Function *F; 128 std::string F_dump; 129 uint8_t *FunctionStart; 130 uint8_t *FunctionEnd; 131 }; 132 std::vector<EndFunctionBodyCall> endFunctionBodyCalls; 133 virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart, 134 uint8_t *FunctionEnd) { 135 endFunctionBodyCalls.push_back( 136 EndFunctionBodyCall(F, FunctionStart, FunctionEnd)); 137 Base->endFunctionBody(F, FunctionStart, FunctionEnd); 138 } 139 virtual uint8_t *allocateDataSection( 140 uintptr_t Size, unsigned Alignment, unsigned SectionID, 141 StringRef SectionName, bool IsReadOnly) { 142 return Base->allocateDataSection( 143 Size, Alignment, SectionID, SectionName, IsReadOnly); 144 } 145 virtual uint8_t *allocateCodeSection( 146 uintptr_t Size, unsigned Alignment, unsigned SectionID, 147 StringRef SectionName) { 148 return Base->allocateCodeSection( 149 Size, Alignment, SectionID, SectionName); 150 } 151 virtual bool finalizeMemory(std::string *ErrMsg) { return false; } 152 virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) { 153 return Base->allocateSpace(Size, Alignment); 154 } 155 virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) { 156 return Base->allocateGlobal(Size, Alignment); 157 } 158 struct DeallocateFunctionBodyCall { 159 DeallocateFunctionBodyCall(const void *Body) : Body(Body) {} 160 const void *Body; 161 }; 162 std::vector<DeallocateFunctionBodyCall> deallocateFunctionBodyCalls; 163 virtual void deallocateFunctionBody(void *Body) { 164 deallocateFunctionBodyCalls.push_back(DeallocateFunctionBodyCall(Body)); 165 Base->deallocateFunctionBody(Body); 166 } 167 }; 168 169 bool LoadAssemblyInto(Module *M, const char *assembly) { 170 SMDiagnostic Error; 171 bool success = 172 nullptr != ParseAssemblyString(assembly, M, Error, M->getContext()); 173 std::string errMsg; 174 raw_string_ostream os(errMsg); 175 Error.print("", os); 176 EXPECT_TRUE(success) << os.str(); 177 return success; 178 } 179 180 class JITTest : public testing::Test { 181 protected: 182 virtual RecordingJITMemoryManager *createMemoryManager() { 183 return new RecordingJITMemoryManager; 184 } 185 186 virtual void SetUp() { 187 M = new Module("<main>", Context); 188 RJMM = createMemoryManager(); 189 RJMM->setPoisonMemory(true); 190 std::string Error; 191 TargetOptions Options; 192 TheJIT.reset(EngineBuilder(M).setEngineKind(EngineKind::JIT) 193 .setJITMemoryManager(RJMM) 194 .setErrorStr(&Error) 195 .setTargetOptions(Options).create()); 196 ASSERT_TRUE(TheJIT.get() != nullptr) << Error; 197 } 198 199 void LoadAssembly(const char *assembly) { 200 LoadAssemblyInto(M, assembly); 201 } 202 203 LLVMContext Context; 204 Module *M; // Owned by ExecutionEngine. 205 RecordingJITMemoryManager *RJMM; 206 std::unique_ptr<ExecutionEngine> TheJIT; 207 }; 208 209 // Regression test for a bug. The JIT used to allocate globals inside the same 210 // memory block used for the function, and when the function code was freed, 211 // the global was left in the same place. This test allocates a function 212 // that uses and global, deallocates it, and then makes sure that the global 213 // stays alive after that. 214 TEST(JIT, GlobalInFunction) { 215 LLVMContext context; 216 Module *M = new Module("<main>", context); 217 218 JITMemoryManager *MemMgr = JITMemoryManager::CreateDefaultMemManager(); 219 // Tell the memory manager to poison freed memory so that accessing freed 220 // memory is more easily tested. 221 MemMgr->setPoisonMemory(true); 222 std::string Error; 223 std::unique_ptr<ExecutionEngine> JIT(EngineBuilder(M) 224 .setEngineKind(EngineKind::JIT) 225 .setErrorStr(&Error) 226 .setJITMemoryManager(MemMgr) 227 // The next line enables the fix: 228 .setAllocateGVsWithCode(false) 229 .create()); 230 ASSERT_EQ(Error, ""); 231 232 // Create a global variable. 233 Type *GTy = Type::getInt32Ty(context); 234 GlobalVariable *G = new GlobalVariable( 235 *M, 236 GTy, 237 false, // Not constant. 238 GlobalValue::InternalLinkage, 239 Constant::getNullValue(GTy), 240 "myglobal"); 241 242 // Make a function that points to a global. 243 Function *F1 = makeReturnGlobal("F1", G, M); 244 245 // Get the pointer to the native code to force it to JIT the function and 246 // allocate space for the global. 247 void (*F1Ptr)() = 248 reinterpret_cast<void(*)()>((intptr_t)JIT->getPointerToFunction(F1)); 249 250 // Since F1 was codegen'd, a pointer to G should be available. 251 int32_t *GPtr = (int32_t*)JIT->getPointerToGlobalIfAvailable(G); 252 ASSERT_NE((int32_t*)nullptr, GPtr); 253 EXPECT_EQ(0, *GPtr); 254 255 // F1() should increment G. 256 F1Ptr(); 257 EXPECT_EQ(1, *GPtr); 258 259 // Make a second function identical to the first, referring to the same 260 // global. 261 Function *F2 = makeReturnGlobal("F2", G, M); 262 void (*F2Ptr)() = 263 reinterpret_cast<void(*)()>((intptr_t)JIT->getPointerToFunction(F2)); 264 265 // F2() should increment G. 266 F2Ptr(); 267 EXPECT_EQ(2, *GPtr); 268 269 // Deallocate F1. 270 JIT->freeMachineCodeForFunction(F1); 271 272 // F2() should *still* increment G. 273 F2Ptr(); 274 EXPECT_EQ(3, *GPtr); 275 } 276 277 int PlusOne(int arg) { 278 return arg + 1; 279 } 280 281 TEST_F(JITTest, FarCallToKnownFunction) { 282 // x86-64 can only make direct calls to functions within 32 bits of 283 // the current PC. To call anything farther away, we have to load 284 // the address into a register and call through the register. The 285 // current JIT does this by allocating a stub for any far call. 286 // There was a bug in which the JIT tried to emit a direct call when 287 // the target was already in the JIT's global mappings and lazy 288 // compilation was disabled. 289 290 Function *KnownFunction = Function::Create( 291 TypeBuilder<int(int), false>::get(Context), 292 GlobalValue::ExternalLinkage, "known", M); 293 TheJIT->addGlobalMapping(KnownFunction, (void*)(intptr_t)PlusOne); 294 295 // int test() { return known(7); } 296 Function *TestFunction = Function::Create( 297 TypeBuilder<int(), false>::get(Context), 298 GlobalValue::ExternalLinkage, "test", M); 299 BasicBlock *Entry = BasicBlock::Create(Context, "entry", TestFunction); 300 IRBuilder<> Builder(Entry); 301 Value *result = Builder.CreateCall( 302 KnownFunction, 303 ConstantInt::get(TypeBuilder<int, false>::get(Context), 7)); 304 Builder.CreateRet(result); 305 306 TheJIT->DisableLazyCompilation(true); 307 int (*TestFunctionPtr)() = reinterpret_cast<int(*)()>( 308 (intptr_t)TheJIT->getPointerToFunction(TestFunction)); 309 // This used to crash in trying to call PlusOne(). 310 EXPECT_EQ(8, TestFunctionPtr()); 311 } 312 313 // Test a function C which calls A and B which call each other. 314 TEST_F(JITTest, NonLazyCompilationStillNeedsStubs) { 315 TheJIT->DisableLazyCompilation(true); 316 317 FunctionType *Func1Ty = 318 cast<FunctionType>(TypeBuilder<void(void), false>::get(Context)); 319 std::vector<Type*> arg_types; 320 arg_types.push_back(Type::getInt1Ty(Context)); 321 FunctionType *FuncTy = FunctionType::get( 322 Type::getVoidTy(Context), arg_types, false); 323 Function *Func1 = Function::Create(Func1Ty, Function::ExternalLinkage, 324 "func1", M); 325 Function *Func2 = Function::Create(FuncTy, Function::InternalLinkage, 326 "func2", M); 327 Function *Func3 = Function::Create(FuncTy, Function::InternalLinkage, 328 "func3", M); 329 BasicBlock *Block1 = BasicBlock::Create(Context, "block1", Func1); 330 BasicBlock *Block2 = BasicBlock::Create(Context, "block2", Func2); 331 BasicBlock *True2 = BasicBlock::Create(Context, "cond_true", Func2); 332 BasicBlock *False2 = BasicBlock::Create(Context, "cond_false", Func2); 333 BasicBlock *Block3 = BasicBlock::Create(Context, "block3", Func3); 334 BasicBlock *True3 = BasicBlock::Create(Context, "cond_true", Func3); 335 BasicBlock *False3 = BasicBlock::Create(Context, "cond_false", Func3); 336 337 // Make Func1 call Func2(0) and Func3(0). 338 IRBuilder<> Builder(Block1); 339 Builder.CreateCall(Func2, ConstantInt::getTrue(Context)); 340 Builder.CreateCall(Func3, ConstantInt::getTrue(Context)); 341 Builder.CreateRetVoid(); 342 343 // void Func2(bool b) { if (b) { Func3(false); return; } return; } 344 Builder.SetInsertPoint(Block2); 345 Builder.CreateCondBr(Func2->arg_begin(), True2, False2); 346 Builder.SetInsertPoint(True2); 347 Builder.CreateCall(Func3, ConstantInt::getFalse(Context)); 348 Builder.CreateRetVoid(); 349 Builder.SetInsertPoint(False2); 350 Builder.CreateRetVoid(); 351 352 // void Func3(bool b) { if (b) { Func2(false); return; } return; } 353 Builder.SetInsertPoint(Block3); 354 Builder.CreateCondBr(Func3->arg_begin(), True3, False3); 355 Builder.SetInsertPoint(True3); 356 Builder.CreateCall(Func2, ConstantInt::getFalse(Context)); 357 Builder.CreateRetVoid(); 358 Builder.SetInsertPoint(False3); 359 Builder.CreateRetVoid(); 360 361 // Compile the function to native code 362 void (*F1Ptr)() = 363 reinterpret_cast<void(*)()>((intptr_t)TheJIT->getPointerToFunction(Func1)); 364 365 F1Ptr(); 366 } 367 368 // Regression test for PR5162. This used to trigger an AssertingVH inside the 369 // JIT's Function to stub mapping. 370 TEST_F(JITTest, NonLazyLeaksNoStubs) { 371 TheJIT->DisableLazyCompilation(true); 372 373 // Create two functions with a single basic block each. 374 FunctionType *FuncTy = 375 cast<FunctionType>(TypeBuilder<int(), false>::get(Context)); 376 Function *Func1 = Function::Create(FuncTy, Function::ExternalLinkage, 377 "func1", M); 378 Function *Func2 = Function::Create(FuncTy, Function::InternalLinkage, 379 "func2", M); 380 BasicBlock *Block1 = BasicBlock::Create(Context, "block1", Func1); 381 BasicBlock *Block2 = BasicBlock::Create(Context, "block2", Func2); 382 383 // The first function calls the second and returns the result 384 IRBuilder<> Builder(Block1); 385 Value *Result = Builder.CreateCall(Func2); 386 Builder.CreateRet(Result); 387 388 // The second function just returns a constant 389 Builder.SetInsertPoint(Block2); 390 Builder.CreateRet(ConstantInt::get(TypeBuilder<int, false>::get(Context),42)); 391 392 // Compile the function to native code 393 (void)TheJIT->getPointerToFunction(Func1); 394 395 // Free the JIT state for the functions 396 TheJIT->freeMachineCodeForFunction(Func1); 397 TheJIT->freeMachineCodeForFunction(Func2); 398 399 // Delete the first function (and show that is has no users) 400 EXPECT_EQ(Func1->getNumUses(), 0u); 401 Func1->eraseFromParent(); 402 403 // Delete the second function (and show that it has no users - it had one, 404 // func1 but that's gone now) 405 EXPECT_EQ(Func2->getNumUses(), 0u); 406 Func2->eraseFromParent(); 407 } 408 409 TEST_F(JITTest, ModuleDeletion) { 410 TheJIT->DisableLazyCompilation(false); 411 LoadAssembly("define void @main() { " 412 " call i32 @computeVal() " 413 " ret void " 414 "} " 415 " " 416 "define internal i32 @computeVal() { " 417 " ret i32 0 " 418 "} "); 419 Function *func = M->getFunction("main"); 420 TheJIT->getPointerToFunction(func); 421 TheJIT->removeModule(M); 422 delete M; 423 424 SmallPtrSet<const void*, 2> FunctionsDeallocated; 425 for (unsigned i = 0, e = RJMM->deallocateFunctionBodyCalls.size(); 426 i != e; ++i) { 427 FunctionsDeallocated.insert(RJMM->deallocateFunctionBodyCalls[i].Body); 428 } 429 for (unsigned i = 0, e = RJMM->startFunctionBodyCalls.size(); i != e; ++i) { 430 EXPECT_TRUE(FunctionsDeallocated.count( 431 RJMM->startFunctionBodyCalls[i].Result)) 432 << "Function leaked: \n" << RJMM->startFunctionBodyCalls[i].F_dump; 433 } 434 EXPECT_EQ(RJMM->startFunctionBodyCalls.size(), 435 RJMM->deallocateFunctionBodyCalls.size()); 436 } 437 438 // ARM, MIPS and PPC still emit stubs for calls since the target may be 439 // too far away to call directly. This #if can probably be removed when 440 // http://llvm.org/PR5201 is fixed. 441 #if !defined(__arm__) && !defined(__mips__) && \ 442 !defined(__powerpc__) && !defined(__ppc__) && !defined(__aarch64__) 443 typedef int (*FooPtr) (); 444 445 TEST_F(JITTest, NoStubs) { 446 LoadAssembly("define void @bar() {" 447 "entry: " 448 "ret void" 449 "}" 450 " " 451 "define i32 @foo() {" 452 "entry:" 453 "call void @bar()" 454 "ret i32 undef" 455 "}" 456 " " 457 "define i32 @main() {" 458 "entry:" 459 "%0 = call i32 @foo()" 460 "call void @bar()" 461 "ret i32 undef" 462 "}"); 463 Function *foo = M->getFunction("foo"); 464 uintptr_t tmp = (uintptr_t)(TheJIT->getPointerToFunction(foo)); 465 FooPtr ptr = (FooPtr)(tmp); 466 467 (ptr)(); 468 469 // We should now allocate no more stubs, we have the code to foo 470 // and the existing stub for bar. 471 int stubsBefore = RJMM->stubsAllocated; 472 Function *func = M->getFunction("main"); 473 TheJIT->getPointerToFunction(func); 474 475 Function *bar = M->getFunction("bar"); 476 TheJIT->getPointerToFunction(bar); 477 478 ASSERT_EQ(stubsBefore, RJMM->stubsAllocated); 479 } 480 #endif // !ARM && !PPC 481 482 TEST_F(JITTest, FunctionPointersOutliveTheirCreator) { 483 TheJIT->DisableLazyCompilation(true); 484 LoadAssembly("define i8()* @get_foo_addr() { " 485 " ret i8()* @foo " 486 "} " 487 " " 488 "define i8 @foo() { " 489 " ret i8 42 " 490 "} "); 491 Function *F_get_foo_addr = M->getFunction("get_foo_addr"); 492 493 typedef char(*fooT)(); 494 fooT (*get_foo_addr)() = reinterpret_cast<fooT(*)()>( 495 (intptr_t)TheJIT->getPointerToFunction(F_get_foo_addr)); 496 fooT foo_addr = get_foo_addr(); 497 498 // Now free get_foo_addr. This should not free the machine code for foo or 499 // any call stub returned as foo's canonical address. 500 TheJIT->freeMachineCodeForFunction(F_get_foo_addr); 501 502 // Check by calling the reported address of foo. 503 EXPECT_EQ(42, foo_addr()); 504 505 // The reported address should also be the same as the result of a subsequent 506 // getPointerToFunction(foo). 507 #if 0 508 // Fails until PR5126 is fixed: 509 Function *F_foo = M->getFunction("foo"); 510 fooT foo = reinterpret_cast<fooT>( 511 (intptr_t)TheJIT->getPointerToFunction(F_foo)); 512 EXPECT_EQ((intptr_t)foo, (intptr_t)foo_addr); 513 #endif 514 } 515 516 // ARM does not have an implementation of replaceMachineCodeForFunction(), 517 // so recompileAndRelinkFunction doesn't work. 518 #if !defined(__arm__) && !defined(__aarch64__) 519 TEST_F(JITTest, FunctionIsRecompiledAndRelinked) { 520 Function *F = Function::Create(TypeBuilder<int(void), false>::get(Context), 521 GlobalValue::ExternalLinkage, "test", M); 522 BasicBlock *Entry = BasicBlock::Create(Context, "entry", F); 523 IRBuilder<> Builder(Entry); 524 Value *Val = ConstantInt::get(TypeBuilder<int, false>::get(Context), 1); 525 Builder.CreateRet(Val); 526 527 TheJIT->DisableLazyCompilation(true); 528 // Compile the function once, and make sure it works. 529 int (*OrigFPtr)() = reinterpret_cast<int(*)()>( 530 (intptr_t)TheJIT->recompileAndRelinkFunction(F)); 531 EXPECT_EQ(1, OrigFPtr()); 532 533 // Now change the function to return a different value. 534 Entry->eraseFromParent(); 535 BasicBlock *NewEntry = BasicBlock::Create(Context, "new_entry", F); 536 Builder.SetInsertPoint(NewEntry); 537 Val = ConstantInt::get(TypeBuilder<int, false>::get(Context), 2); 538 Builder.CreateRet(Val); 539 // Recompile it, which should produce a new function pointer _and_ update the 540 // old one. 541 int (*NewFPtr)() = reinterpret_cast<int(*)()>( 542 (intptr_t)TheJIT->recompileAndRelinkFunction(F)); 543 544 EXPECT_EQ(2, NewFPtr()) 545 << "The new pointer should call the new version of the function"; 546 EXPECT_EQ(2, OrigFPtr()) 547 << "The old pointer's target should now jump to the new version"; 548 } 549 #endif // !defined(__arm__) 550 551 TEST_F(JITTest, AvailableExternallyGlobalIsntEmitted) { 552 TheJIT->DisableLazyCompilation(true); 553 LoadAssembly("@JITTest_AvailableExternallyGlobal = " 554 " available_externally global i32 7 " 555 " " 556 "define i32 @loader() { " 557 " %result = load i32* @JITTest_AvailableExternallyGlobal " 558 " ret i32 %result " 559 "} "); 560 Function *loaderIR = M->getFunction("loader"); 561 562 int32_t (*loader)() = reinterpret_cast<int32_t(*)()>( 563 (intptr_t)TheJIT->getPointerToFunction(loaderIR)); 564 EXPECT_EQ(42, loader()) << "func should return 42 from the external global," 565 << " not 7 from the IR version."; 566 } 567 568 TEST_F(JITTest, AvailableExternallyFunctionIsntCompiled) { 569 TheJIT->DisableLazyCompilation(true); 570 LoadAssembly("define available_externally i32 " 571 " @JITTest_AvailableExternallyFunction() { " 572 " ret i32 7 " 573 "} " 574 " " 575 "define i32 @func() { " 576 " %result = tail call i32 " 577 " @JITTest_AvailableExternallyFunction() " 578 " ret i32 %result " 579 "} "); 580 Function *funcIR = M->getFunction("func"); 581 582 int32_t (*func)() = reinterpret_cast<int32_t(*)()>( 583 (intptr_t)TheJIT->getPointerToFunction(funcIR)); 584 EXPECT_EQ(42, func()) << "func should return 42 from the static version," 585 << " not 7 from the IR version."; 586 } 587 588 TEST_F(JITTest, EscapedLazyStubStillCallable) { 589 TheJIT->DisableLazyCompilation(false); 590 LoadAssembly("define internal i32 @stubbed() { " 591 " ret i32 42 " 592 "} " 593 " " 594 "define i32()* @get_stub() { " 595 " ret i32()* @stubbed " 596 "} "); 597 typedef int32_t(*StubTy)(); 598 599 // Call get_stub() to get the address of @stubbed without actually JITting it. 600 Function *get_stubIR = M->getFunction("get_stub"); 601 StubTy (*get_stub)() = reinterpret_cast<StubTy(*)()>( 602 (intptr_t)TheJIT->getPointerToFunction(get_stubIR)); 603 StubTy stubbed = get_stub(); 604 // Now get_stubIR is the only reference to stubbed's stub. 605 get_stubIR->eraseFromParent(); 606 // Now there are no references inside the JIT, but we've got a pointer outside 607 // it. The stub should be callable and return the right value. 608 EXPECT_EQ(42, stubbed()); 609 } 610 611 // Converts the LLVM assembly to bitcode and returns it in a std::string. An 612 // empty string indicates an error. 613 std::string AssembleToBitcode(LLVMContext &Context, const char *Assembly) { 614 Module TempModule("TempModule", Context); 615 if (!LoadAssemblyInto(&TempModule, Assembly)) { 616 return ""; 617 } 618 619 std::string Result; 620 raw_string_ostream OS(Result); 621 WriteBitcodeToFile(&TempModule, OS); 622 OS.flush(); 623 return Result; 624 } 625 626 // Returns a newly-created ExecutionEngine that reads the bitcode in 'Bitcode' 627 // lazily. The associated Module (owned by the ExecutionEngine) is returned in 628 // M. Both will be NULL on an error. Bitcode must live at least as long as the 629 // ExecutionEngine. 630 ExecutionEngine *getJITFromBitcode( 631 LLVMContext &Context, const std::string &Bitcode, Module *&M) { 632 // c_str() is null-terminated like MemoryBuffer::getMemBuffer requires. 633 MemoryBuffer *BitcodeBuffer = 634 MemoryBuffer::getMemBuffer(Bitcode, "Bitcode for test"); 635 ErrorOr<Module*> ModuleOrErr = getLazyBitcodeModule(BitcodeBuffer, Context); 636 if (std::error_code EC = ModuleOrErr.getError()) { 637 ADD_FAILURE() << EC.message(); 638 delete BitcodeBuffer; 639 return nullptr; 640 } 641 M = ModuleOrErr.get(); 642 std::string errMsg; 643 ExecutionEngine *TheJIT = EngineBuilder(M) 644 .setEngineKind(EngineKind::JIT) 645 .setErrorStr(&errMsg) 646 .create(); 647 if (TheJIT == nullptr) { 648 ADD_FAILURE() << errMsg; 649 delete M; 650 M = nullptr; 651 return nullptr; 652 } 653 return TheJIT; 654 } 655 656 TEST(LazyLoadedJITTest, MaterializableAvailableExternallyFunctionIsntCompiled) { 657 LLVMContext Context; 658 const std::string Bitcode = 659 AssembleToBitcode(Context, 660 "define available_externally i32 " 661 " @JITTest_AvailableExternallyFunction() { " 662 " ret i32 7 " 663 "} " 664 " " 665 "define i32 @func() { " 666 " %result = tail call i32 " 667 " @JITTest_AvailableExternallyFunction() " 668 " ret i32 %result " 669 "} "); 670 ASSERT_FALSE(Bitcode.empty()) << "Assembling failed"; 671 Module *M; 672 std::unique_ptr<ExecutionEngine> TheJIT( 673 getJITFromBitcode(Context, Bitcode, M)); 674 ASSERT_TRUE(TheJIT.get()) << "Failed to create JIT."; 675 TheJIT->DisableLazyCompilation(true); 676 677 Function *funcIR = M->getFunction("func"); 678 Function *availableFunctionIR = 679 M->getFunction("JITTest_AvailableExternallyFunction"); 680 681 // Double-check that the available_externally function is still unmaterialized 682 // when getPointerToFunction needs to find out if it's available_externally. 683 EXPECT_TRUE(availableFunctionIR->isMaterializable()); 684 685 int32_t (*func)() = reinterpret_cast<int32_t(*)()>( 686 (intptr_t)TheJIT->getPointerToFunction(funcIR)); 687 EXPECT_EQ(42, func()) << "func should return 42 from the static version," 688 << " not 7 from the IR version."; 689 } 690 691 TEST(LazyLoadedJITTest, EagerCompiledRecursionThroughGhost) { 692 LLVMContext Context; 693 const std::string Bitcode = 694 AssembleToBitcode(Context, 695 "define i32 @recur1(i32 %a) { " 696 " %zero = icmp eq i32 %a, 0 " 697 " br i1 %zero, label %done, label %notdone " 698 "done: " 699 " ret i32 3 " 700 "notdone: " 701 " %am1 = sub i32 %a, 1 " 702 " %result = call i32 @recur2(i32 %am1) " 703 " ret i32 %result " 704 "} " 705 " " 706 "define i32 @recur2(i32 %b) { " 707 " %result = call i32 @recur1(i32 %b) " 708 " ret i32 %result " 709 "} "); 710 ASSERT_FALSE(Bitcode.empty()) << "Assembling failed"; 711 Module *M; 712 std::unique_ptr<ExecutionEngine> TheJIT( 713 getJITFromBitcode(Context, Bitcode, M)); 714 ASSERT_TRUE(TheJIT.get()) << "Failed to create JIT."; 715 TheJIT->DisableLazyCompilation(true); 716 717 Function *recur1IR = M->getFunction("recur1"); 718 Function *recur2IR = M->getFunction("recur2"); 719 EXPECT_TRUE(recur1IR->isMaterializable()); 720 EXPECT_TRUE(recur2IR->isMaterializable()); 721 722 int32_t (*recur1)(int32_t) = reinterpret_cast<int32_t(*)(int32_t)>( 723 (intptr_t)TheJIT->getPointerToFunction(recur1IR)); 724 EXPECT_EQ(3, recur1(4)); 725 } 726 #endif // !defined(__arm__) && !defined(__powerpc__) && !defined(__s390__) 727 728 } 729