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