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/Target/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 TEST_F(JITTest, FarCallToKnownFunction) { 288 // x86-64 can only make direct calls to functions within 32 bits of 289 // the current PC. To call anything farther away, we have to load 290 // the address into a register and call through the register. The 291 // current JIT does this by allocating a stub for any far call. 292 // There was a bug in which the JIT tried to emit a direct call when 293 // the target was already in the JIT's global mappings and lazy 294 // compilation was disabled. 295 296 Function *KnownFunction = Function::Create( 297 TypeBuilder<int(int), false>::get(Context), 298 GlobalValue::ExternalLinkage, "known", M); 299 TheJIT->addGlobalMapping(KnownFunction, (void*)(intptr_t)PlusOne); 300 301 // int test() { return known(7); } 302 Function *TestFunction = Function::Create( 303 TypeBuilder<int(), false>::get(Context), 304 GlobalValue::ExternalLinkage, "test", M); 305 BasicBlock *Entry = BasicBlock::Create(Context, "entry", TestFunction); 306 IRBuilder<> Builder(Entry); 307 Value *result = Builder.CreateCall( 308 KnownFunction, 309 ConstantInt::get(TypeBuilder<int, false>::get(Context), 7)); 310 Builder.CreateRet(result); 311 312 TheJIT->DisableLazyCompilation(true); 313 int (*TestFunctionPtr)() = reinterpret_cast<int(*)()>( 314 (intptr_t)TheJIT->getPointerToFunction(TestFunction)); 315 // This used to crash in trying to call PlusOne(). 316 EXPECT_EQ(8, TestFunctionPtr()); 317 } 318 319 // Test a function C which calls A and B which call each other. 320 TEST_F(JITTest, NonLazyCompilationStillNeedsStubs) { 321 TheJIT->DisableLazyCompilation(true); 322 323 FunctionType *Func1Ty = 324 cast<FunctionType>(TypeBuilder<void(void), false>::get(Context)); 325 std::vector<Type*> arg_types; 326 arg_types.push_back(Type::getInt1Ty(Context)); 327 FunctionType *FuncTy = FunctionType::get( 328 Type::getVoidTy(Context), arg_types, false); 329 Function *Func1 = Function::Create(Func1Ty, Function::ExternalLinkage, 330 "func1", M); 331 Function *Func2 = Function::Create(FuncTy, Function::InternalLinkage, 332 "func2", M); 333 Function *Func3 = Function::Create(FuncTy, Function::InternalLinkage, 334 "func3", M); 335 BasicBlock *Block1 = BasicBlock::Create(Context, "block1", Func1); 336 BasicBlock *Block2 = BasicBlock::Create(Context, "block2", Func2); 337 BasicBlock *True2 = BasicBlock::Create(Context, "cond_true", Func2); 338 BasicBlock *False2 = BasicBlock::Create(Context, "cond_false", Func2); 339 BasicBlock *Block3 = BasicBlock::Create(Context, "block3", Func3); 340 BasicBlock *True3 = BasicBlock::Create(Context, "cond_true", Func3); 341 BasicBlock *False3 = BasicBlock::Create(Context, "cond_false", Func3); 342 343 // Make Func1 call Func2(0) and Func3(0). 344 IRBuilder<> Builder(Block1); 345 Builder.CreateCall(Func2, ConstantInt::getTrue(Context)); 346 Builder.CreateCall(Func3, ConstantInt::getTrue(Context)); 347 Builder.CreateRetVoid(); 348 349 // void Func2(bool b) { if (b) { Func3(false); return; } return; } 350 Builder.SetInsertPoint(Block2); 351 Builder.CreateCondBr(Func2->arg_begin(), True2, False2); 352 Builder.SetInsertPoint(True2); 353 Builder.CreateCall(Func3, ConstantInt::getFalse(Context)); 354 Builder.CreateRetVoid(); 355 Builder.SetInsertPoint(False2); 356 Builder.CreateRetVoid(); 357 358 // void Func3(bool b) { if (b) { Func2(false); return; } return; } 359 Builder.SetInsertPoint(Block3); 360 Builder.CreateCondBr(Func3->arg_begin(), True3, False3); 361 Builder.SetInsertPoint(True3); 362 Builder.CreateCall(Func2, ConstantInt::getFalse(Context)); 363 Builder.CreateRetVoid(); 364 Builder.SetInsertPoint(False3); 365 Builder.CreateRetVoid(); 366 367 // Compile the function to native code 368 void (*F1Ptr)() = 369 reinterpret_cast<void(*)()>((intptr_t)TheJIT->getPointerToFunction(Func1)); 370 371 F1Ptr(); 372 } 373 374 // Regression test for PR5162. This used to trigger an AssertingVH inside the 375 // JIT's Function to stub mapping. 376 TEST_F(JITTest, NonLazyLeaksNoStubs) { 377 TheJIT->DisableLazyCompilation(true); 378 379 // Create two functions with a single basic block each. 380 FunctionType *FuncTy = 381 cast<FunctionType>(TypeBuilder<int(), false>::get(Context)); 382 Function *Func1 = Function::Create(FuncTy, Function::ExternalLinkage, 383 "func1", M); 384 Function *Func2 = Function::Create(FuncTy, Function::InternalLinkage, 385 "func2", M); 386 BasicBlock *Block1 = BasicBlock::Create(Context, "block1", Func1); 387 BasicBlock *Block2 = BasicBlock::Create(Context, "block2", Func2); 388 389 // The first function calls the second and returns the result 390 IRBuilder<> Builder(Block1); 391 Value *Result = Builder.CreateCall(Func2); 392 Builder.CreateRet(Result); 393 394 // The second function just returns a constant 395 Builder.SetInsertPoint(Block2); 396 Builder.CreateRet(ConstantInt::get(TypeBuilder<int, false>::get(Context),42)); 397 398 // Compile the function to native code 399 (void)TheJIT->getPointerToFunction(Func1); 400 401 // Free the JIT state for the functions 402 TheJIT->freeMachineCodeForFunction(Func1); 403 TheJIT->freeMachineCodeForFunction(Func2); 404 405 // Delete the first function (and show that is has no users) 406 EXPECT_EQ(Func1->getNumUses(), 0u); 407 Func1->eraseFromParent(); 408 409 // Delete the second function (and show that it has no users - it had one, 410 // func1 but that's gone now) 411 EXPECT_EQ(Func2->getNumUses(), 0u); 412 Func2->eraseFromParent(); 413 } 414 415 TEST_F(JITTest, ModuleDeletion) { 416 TheJIT->DisableLazyCompilation(false); 417 LoadAssembly("define void @main() { " 418 " call i32 @computeVal() " 419 " ret void " 420 "} " 421 " " 422 "define internal i32 @computeVal() { " 423 " ret i32 0 " 424 "} "); 425 Function *func = M->getFunction("main"); 426 TheJIT->getPointerToFunction(func); 427 TheJIT->removeModule(M); 428 delete M; 429 430 SmallPtrSet<const void*, 2> FunctionsDeallocated; 431 for (unsigned i = 0, e = RJMM->deallocateFunctionBodyCalls.size(); 432 i != e; ++i) { 433 FunctionsDeallocated.insert(RJMM->deallocateFunctionBodyCalls[i].Body); 434 } 435 for (unsigned i = 0, e = RJMM->startFunctionBodyCalls.size(); i != e; ++i) { 436 EXPECT_TRUE(FunctionsDeallocated.count( 437 RJMM->startFunctionBodyCalls[i].Result)) 438 << "Function leaked: \n" << RJMM->startFunctionBodyCalls[i].F_dump; 439 } 440 EXPECT_EQ(RJMM->startFunctionBodyCalls.size(), 441 RJMM->deallocateFunctionBodyCalls.size()); 442 443 SmallPtrSet<const void*, 2> ExceptionTablesDeallocated; 444 unsigned NumTablesDeallocated = 0; 445 for (unsigned i = 0, e = RJMM->deallocateExceptionTableCalls.size(); 446 i != e; ++i) { 447 ExceptionTablesDeallocated.insert( 448 RJMM->deallocateExceptionTableCalls[i].ET); 449 if (RJMM->deallocateExceptionTableCalls[i].ET != NULL) { 450 // If JITEmitDebugInfo is off, we'll "deallocate" NULL, which doesn't 451 // appear in startExceptionTableCalls. 452 NumTablesDeallocated++; 453 } 454 } 455 for (unsigned i = 0, e = RJMM->startExceptionTableCalls.size(); i != e; ++i) { 456 EXPECT_TRUE(ExceptionTablesDeallocated.count( 457 RJMM->startExceptionTableCalls[i].Result)) 458 << "Function's exception table leaked: \n" 459 << RJMM->startExceptionTableCalls[i].F_dump; 460 } 461 EXPECT_EQ(RJMM->startExceptionTableCalls.size(), 462 NumTablesDeallocated); 463 } 464 465 // ARM and PPC still emit stubs for calls since the target may be too far away 466 // to call directly. This #if can probably be removed when 467 // http://llvm.org/PR5201 is fixed. 468 #if !defined(__arm__) && !defined(__powerpc__) && !defined(__ppc__) 469 typedef int (*FooPtr) (); 470 471 TEST_F(JITTest, NoStubs) { 472 LoadAssembly("define void @bar() {" 473 "entry: " 474 "ret void" 475 "}" 476 " " 477 "define i32 @foo() {" 478 "entry:" 479 "call void @bar()" 480 "ret i32 undef" 481 "}" 482 " " 483 "define i32 @main() {" 484 "entry:" 485 "%0 = call i32 @foo()" 486 "call void @bar()" 487 "ret i32 undef" 488 "}"); 489 Function *foo = M->getFunction("foo"); 490 uintptr_t tmp = (uintptr_t)(TheJIT->getPointerToFunction(foo)); 491 FooPtr ptr = (FooPtr)(tmp); 492 493 (ptr)(); 494 495 // We should now allocate no more stubs, we have the code to foo 496 // and the existing stub for bar. 497 int stubsBefore = RJMM->stubsAllocated; 498 Function *func = M->getFunction("main"); 499 TheJIT->getPointerToFunction(func); 500 501 Function *bar = M->getFunction("bar"); 502 TheJIT->getPointerToFunction(bar); 503 504 ASSERT_EQ(stubsBefore, RJMM->stubsAllocated); 505 } 506 #endif // !ARM && !PPC 507 508 TEST_F(JITTest, FunctionPointersOutliveTheirCreator) { 509 TheJIT->DisableLazyCompilation(true); 510 LoadAssembly("define i8()* @get_foo_addr() { " 511 " ret i8()* @foo " 512 "} " 513 " " 514 "define i8 @foo() { " 515 " ret i8 42 " 516 "} "); 517 Function *F_get_foo_addr = M->getFunction("get_foo_addr"); 518 519 typedef char(*fooT)(); 520 fooT (*get_foo_addr)() = reinterpret_cast<fooT(*)()>( 521 (intptr_t)TheJIT->getPointerToFunction(F_get_foo_addr)); 522 fooT foo_addr = get_foo_addr(); 523 524 // Now free get_foo_addr. This should not free the machine code for foo or 525 // any call stub returned as foo's canonical address. 526 TheJIT->freeMachineCodeForFunction(F_get_foo_addr); 527 528 // Check by calling the reported address of foo. 529 EXPECT_EQ(42, foo_addr()); 530 531 // The reported address should also be the same as the result of a subsequent 532 // getPointerToFunction(foo). 533 #if 0 534 // Fails until PR5126 is fixed: 535 Function *F_foo = M->getFunction("foo"); 536 fooT foo = reinterpret_cast<fooT>( 537 (intptr_t)TheJIT->getPointerToFunction(F_foo)); 538 EXPECT_EQ((intptr_t)foo, (intptr_t)foo_addr); 539 #endif 540 } 541 542 // ARM doesn't have an implementation of replaceMachineCodeForFunction(), so 543 // recompileAndRelinkFunction doesn't work. 544 #if !defined(__arm__) 545 TEST_F(JITTest, FunctionIsRecompiledAndRelinked) { 546 Function *F = Function::Create(TypeBuilder<int(void), false>::get(Context), 547 GlobalValue::ExternalLinkage, "test", M); 548 BasicBlock *Entry = BasicBlock::Create(Context, "entry", F); 549 IRBuilder<> Builder(Entry); 550 Value *Val = ConstantInt::get(TypeBuilder<int, false>::get(Context), 1); 551 Builder.CreateRet(Val); 552 553 TheJIT->DisableLazyCompilation(true); 554 // Compile the function once, and make sure it works. 555 int (*OrigFPtr)() = reinterpret_cast<int(*)()>( 556 (intptr_t)TheJIT->recompileAndRelinkFunction(F)); 557 EXPECT_EQ(1, OrigFPtr()); 558 559 // Now change the function to return a different value. 560 Entry->eraseFromParent(); 561 BasicBlock *NewEntry = BasicBlock::Create(Context, "new_entry", F); 562 Builder.SetInsertPoint(NewEntry); 563 Val = ConstantInt::get(TypeBuilder<int, false>::get(Context), 2); 564 Builder.CreateRet(Val); 565 // Recompile it, which should produce a new function pointer _and_ update the 566 // old one. 567 int (*NewFPtr)() = reinterpret_cast<int(*)()>( 568 (intptr_t)TheJIT->recompileAndRelinkFunction(F)); 569 570 EXPECT_EQ(2, NewFPtr()) 571 << "The new pointer should call the new version of the function"; 572 EXPECT_EQ(2, OrigFPtr()) 573 << "The old pointer's target should now jump to the new version"; 574 } 575 #endif // !defined(__arm__) 576 577 } // anonymous namespace 578 // This variable is intentionally defined differently in the statically-compiled 579 // program from the IR input to the JIT to assert that the JIT doesn't use its 580 // definition. 581 extern "C" int32_t JITTest_AvailableExternallyGlobal; 582 int32_t JITTest_AvailableExternallyGlobal = 42; 583 namespace { 584 585 TEST_F(JITTest, AvailableExternallyGlobalIsntEmitted) { 586 TheJIT->DisableLazyCompilation(true); 587 LoadAssembly("@JITTest_AvailableExternallyGlobal = " 588 " available_externally global i32 7 " 589 " " 590 "define i32 @loader() { " 591 " %result = load i32* @JITTest_AvailableExternallyGlobal " 592 " ret i32 %result " 593 "} "); 594 Function *loaderIR = M->getFunction("loader"); 595 596 int32_t (*loader)() = reinterpret_cast<int32_t(*)()>( 597 (intptr_t)TheJIT->getPointerToFunction(loaderIR)); 598 EXPECT_EQ(42, loader()) << "func should return 42 from the external global," 599 << " not 7 from the IR version."; 600 } 601 602 } // anonymous namespace 603 // This function is intentionally defined differently in the statically-compiled 604 // program from the IR input to the JIT to assert that the JIT doesn't use its 605 // definition. 606 extern "C" int32_t JITTest_AvailableExternallyFunction() { 607 return 42; 608 } 609 namespace { 610 611 TEST_F(JITTest, AvailableExternallyFunctionIsntCompiled) { 612 TheJIT->DisableLazyCompilation(true); 613 LoadAssembly("define available_externally i32 " 614 " @JITTest_AvailableExternallyFunction() { " 615 " ret i32 7 " 616 "} " 617 " " 618 "define i32 @func() { " 619 " %result = tail call i32 " 620 " @JITTest_AvailableExternallyFunction() " 621 " ret i32 %result " 622 "} "); 623 Function *funcIR = M->getFunction("func"); 624 625 int32_t (*func)() = reinterpret_cast<int32_t(*)()>( 626 (intptr_t)TheJIT->getPointerToFunction(funcIR)); 627 EXPECT_EQ(42, func()) << "func should return 42 from the static version," 628 << " not 7 from the IR version."; 629 } 630 631 TEST_F(JITTest, EscapedLazyStubStillCallable) { 632 TheJIT->DisableLazyCompilation(false); 633 LoadAssembly("define internal i32 @stubbed() { " 634 " ret i32 42 " 635 "} " 636 " " 637 "define i32()* @get_stub() { " 638 " ret i32()* @stubbed " 639 "} "); 640 typedef int32_t(*StubTy)(); 641 642 // Call get_stub() to get the address of @stubbed without actually JITting it. 643 Function *get_stubIR = M->getFunction("get_stub"); 644 StubTy (*get_stub)() = reinterpret_cast<StubTy(*)()>( 645 (intptr_t)TheJIT->getPointerToFunction(get_stubIR)); 646 StubTy stubbed = get_stub(); 647 // Now get_stubIR is the only reference to stubbed's stub. 648 get_stubIR->eraseFromParent(); 649 // Now there are no references inside the JIT, but we've got a pointer outside 650 // it. The stub should be callable and return the right value. 651 EXPECT_EQ(42, stubbed()); 652 } 653 654 // Converts the LLVM assembly to bitcode and returns it in a std::string. An 655 // empty string indicates an error. 656 std::string AssembleToBitcode(LLVMContext &Context, const char *Assembly) { 657 Module TempModule("TempModule", Context); 658 if (!LoadAssemblyInto(&TempModule, Assembly)) { 659 return ""; 660 } 661 662 std::string Result; 663 raw_string_ostream OS(Result); 664 WriteBitcodeToFile(&TempModule, OS); 665 OS.flush(); 666 return Result; 667 } 668 669 // Returns a newly-created ExecutionEngine that reads the bitcode in 'Bitcode' 670 // lazily. The associated Module (owned by the ExecutionEngine) is returned in 671 // M. Both will be NULL on an error. Bitcode must live at least as long as the 672 // ExecutionEngine. 673 ExecutionEngine *getJITFromBitcode( 674 LLVMContext &Context, const std::string &Bitcode, Module *&M) { 675 // c_str() is null-terminated like MemoryBuffer::getMemBuffer requires. 676 MemoryBuffer *BitcodeBuffer = 677 MemoryBuffer::getMemBuffer(Bitcode, "Bitcode for test"); 678 std::string errMsg; 679 M = getLazyBitcodeModule(BitcodeBuffer, Context, &errMsg); 680 if (M == NULL) { 681 ADD_FAILURE() << errMsg; 682 delete BitcodeBuffer; 683 return NULL; 684 } 685 ExecutionEngine *TheJIT = EngineBuilder(M) 686 .setEngineKind(EngineKind::JIT) 687 .setErrorStr(&errMsg) 688 .create(); 689 if (TheJIT == NULL) { 690 ADD_FAILURE() << errMsg; 691 delete M; 692 M = NULL; 693 return NULL; 694 } 695 return TheJIT; 696 } 697 698 TEST(LazyLoadedJITTest, MaterializableAvailableExternallyFunctionIsntCompiled) { 699 LLVMContext Context; 700 const std::string Bitcode = 701 AssembleToBitcode(Context, 702 "define available_externally i32 " 703 " @JITTest_AvailableExternallyFunction() { " 704 " ret i32 7 " 705 "} " 706 " " 707 "define i32 @func() { " 708 " %result = tail call i32 " 709 " @JITTest_AvailableExternallyFunction() " 710 " ret i32 %result " 711 "} "); 712 ASSERT_FALSE(Bitcode.empty()) << "Assembling failed"; 713 Module *M; 714 OwningPtr<ExecutionEngine> TheJIT(getJITFromBitcode(Context, Bitcode, M)); 715 ASSERT_TRUE(TheJIT.get()) << "Failed to create JIT."; 716 TheJIT->DisableLazyCompilation(true); 717 718 Function *funcIR = M->getFunction("func"); 719 Function *availableFunctionIR = 720 M->getFunction("JITTest_AvailableExternallyFunction"); 721 722 // Double-check that the available_externally function is still unmaterialized 723 // when getPointerToFunction needs to find out if it's available_externally. 724 EXPECT_TRUE(availableFunctionIR->isMaterializable()); 725 726 int32_t (*func)() = reinterpret_cast<int32_t(*)()>( 727 (intptr_t)TheJIT->getPointerToFunction(funcIR)); 728 EXPECT_EQ(42, func()) << "func should return 42 from the static version," 729 << " not 7 from the IR version."; 730 } 731 732 TEST(LazyLoadedJITTest, EagerCompiledRecursionThroughGhost) { 733 LLVMContext Context; 734 const std::string Bitcode = 735 AssembleToBitcode(Context, 736 "define i32 @recur1(i32 %a) { " 737 " %zero = icmp eq i32 %a, 0 " 738 " br i1 %zero, label %done, label %notdone " 739 "done: " 740 " ret i32 3 " 741 "notdone: " 742 " %am1 = sub i32 %a, 1 " 743 " %result = call i32 @recur2(i32 %am1) " 744 " ret i32 %result " 745 "} " 746 " " 747 "define i32 @recur2(i32 %b) { " 748 " %result = call i32 @recur1(i32 %b) " 749 " ret i32 %result " 750 "} "); 751 ASSERT_FALSE(Bitcode.empty()) << "Assembling failed"; 752 Module *M; 753 OwningPtr<ExecutionEngine> TheJIT(getJITFromBitcode(Context, Bitcode, M)); 754 ASSERT_TRUE(TheJIT.get()) << "Failed to create JIT."; 755 TheJIT->DisableLazyCompilation(true); 756 757 Function *recur1IR = M->getFunction("recur1"); 758 Function *recur2IR = M->getFunction("recur2"); 759 EXPECT_TRUE(recur1IR->isMaterializable()); 760 EXPECT_TRUE(recur2IR->isMaterializable()); 761 762 int32_t (*recur1)(int32_t) = reinterpret_cast<int32_t(*)(int32_t)>( 763 (intptr_t)TheJIT->getPointerToFunction(recur1IR)); 764 EXPECT_EQ(3, recur1(4)); 765 } 766 767 // This code is copied from JITEventListenerTest, but it only runs once for all 768 // the tests in this directory. Everything seems fine, but that's strange 769 // behavior. 770 class JITEnvironment : public testing::Environment { 771 virtual void SetUp() { 772 // Required to create a JIT. 773 InitializeNativeTarget(); 774 } 775 }; 776 testing::Environment* const jit_env = 777 testing::AddGlobalTestEnvironment(new JITEnvironment); 778 779 } 780