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