Left: | ||
Right: |
OLD | NEW |
---|---|
1 //===-- JITEmitter.cpp - Write machine code to executable memory ----------===// | 1 //===-- JITEmitter.cpp - Write machine code to executable memory ----------===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file defines a MachineCodeEmitter object that is used by the JIT to | 10 // This file defines a MachineCodeEmitter object that is used by the JIT to |
11 // write machine code to memory and remember where relocatable values are. | 11 // write machine code to memory and remember where relocatable values are. |
12 // | 12 // |
13 //===----------------------------------------------------------------------===// | 13 //===----------------------------------------------------------------------===// |
14 | 14 |
15 #define DEBUG_TYPE "jit" | 15 #define DEBUG_TYPE "jit" |
16 #include "JIT.h" | 16 #include "JIT.h" |
17 #include "JITDebugRegisterer.h" | |
17 #include "JITDwarfEmitter.h" | 18 #include "JITDwarfEmitter.h" |
18 #include "llvm/Constants.h" | 19 #include "llvm/Constants.h" |
20 #include "llvm/Function.h" | |
nlewycky
2009/07/04 01:27:07
Why did you add this #include? It doesn't look lik
Reid Kleckner
2009/07/06 21:07:01
I don't know. Gone.
| |
19 #include "llvm/Module.h" | 21 #include "llvm/Module.h" |
20 #include "llvm/DerivedTypes.h" | 22 #include "llvm/DerivedTypes.h" |
21 #include "llvm/CodeGen/JITCodeEmitter.h" | 23 #include "llvm/CodeGen/JITCodeEmitter.h" |
22 #include "llvm/CodeGen/MachineFunction.h" | 24 #include "llvm/CodeGen/MachineFunction.h" |
23 #include "llvm/CodeGen/MachineConstantPool.h" | 25 #include "llvm/CodeGen/MachineConstantPool.h" |
24 #include "llvm/CodeGen/MachineJumpTableInfo.h" | 26 #include "llvm/CodeGen/MachineJumpTableInfo.h" |
25 #include "llvm/CodeGen/MachineModuleInfo.h" | 27 #include "llvm/CodeGen/MachineModuleInfo.h" |
26 #include "llvm/CodeGen/MachineRelocation.h" | 28 #include "llvm/CodeGen/MachineRelocation.h" |
27 #include "llvm/ExecutionEngine/GenericValue.h" | 29 #include "llvm/ExecutionEngine/GenericValue.h" |
28 #include "llvm/ExecutionEngine/JITEventListener.h" | 30 #include "llvm/ExecutionEngine/JITEventListener.h" |
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
448 /// JumpTable - The jump tables for the current function. | 450 /// JumpTable - The jump tables for the current function. |
449 /// | 451 /// |
450 MachineJumpTableInfo *JumpTable; | 452 MachineJumpTableInfo *JumpTable; |
451 ···· | 453 ···· |
452 /// JumpTableBase - A pointer to the first entry in the jump table. | 454 /// JumpTableBase - A pointer to the first entry in the jump table. |
453 /// | 455 /// |
454 void *JumpTableBase; | 456 void *JumpTableBase; |
455 | 457 |
456 /// Resolver - This contains info about the currently resolved functions. | 458 /// Resolver - This contains info about the currently resolved functions. |
457 JITResolver Resolver; | 459 JITResolver Resolver; |
458 | 460 |
459 /// DE - The dwarf emitter for the jit. | 461 /// DE - The dwarf emitter for the jit. |
460 JITDwarfEmitter *DE; | 462 JITDwarfEmitter *DE; |
461 | 463 |
464 /// DR - The debug registerer for the jit. | |
465 JITDebugRegisterer *DR; | |
466 | |
462 /// LabelLocations - This vector is a mapping from Label ID's to their· | 467 /// LabelLocations - This vector is a mapping from Label ID's to their· |
463 /// address. | 468 /// address. |
464 std::vector<uintptr_t> LabelLocations; | 469 std::vector<uintptr_t> LabelLocations; |
465 | 470 |
466 /// MMI - Machine module info for exception informations | 471 /// MMI - Machine module info for exception informations |
467 MachineModuleInfo* MMI; | 472 MachineModuleInfo* MMI; |
468 | 473 |
469 // GVSet - a set to keep track of which globals have been seen | 474 // GVSet - a set to keep track of which globals have been seen |
470 SmallPtrSet<const GlobalVariable*, 8> GVSet; | 475 SmallPtrSet<const GlobalVariable*, 8> GVSet; |
471 | 476 |
472 // CurFn - The llvm function being emitted. Only valid during· | 477 // CurFn - The llvm function being emitted. Only valid during· |
473 // finishFunction(). | 478 // finishFunction(). |
474 const Function *CurFn; | 479 const Function *CurFn; |
475 ···· | 480 ···· |
476 // CurFnStubUses - For a given Function, a vector of stubs that it | 481 // CurFnStubUses - For a given Function, a vector of stubs that it |
477 // references. This facilitates the JIT detecting that a stub is no | 482 // references. This facilitates the JIT detecting that a stub is no |
478 // longer used, so that it may be deallocated. | 483 // longer used, so that it may be deallocated. |
479 DenseMap<const Function *, SmallVector<void*, 1> > CurFnStubUses; | 484 DenseMap<const Function *, SmallVector<void*, 1> > CurFnStubUses; |
480 ···· | 485 ···· |
481 // StubFnRefs - For a given pointer to a stub, a set of Functions which | 486 // StubFnRefs - For a given pointer to a stub, a set of Functions which |
482 // reference the stub. When the count of a stub's references drops to zero, | 487 // reference the stub. When the count of a stub's references drops to zero, |
483 // the stub is unused. | 488 // the stub is unused. |
484 DenseMap<void *, SmallPtrSet<const Function*, 1> > StubFnRefs; | 489 DenseMap<void *, SmallPtrSet<const Function*, 1> > StubFnRefs; |
485 ···· | 490 ···· |
486 // ExtFnStubs - A map of external function names to stubs which have entries | 491 // ExtFnStubs - A map of external function names to stubs which have entries |
487 // in the JITResolver's ExternalFnToStubMap. | 492 // in the JITResolver's ExternalFnToStubMap. |
488 StringMap<void *> ExtFnStubs; | 493 StringMap<void *> ExtFnStubs; |
489 | 494 |
490 public: | 495 public: |
491 JITEmitter(JIT &jit, JITMemoryManager *JMM) : Resolver(jit), CurFn(0) { | 496 JITEmitter(JIT &jit, JITMemoryManager *JMM, TargetMachine &TM) |
497 : Resolver(jit), CurFn(0) { | |
492 MemMgr = JMM ? JMM : JITMemoryManager::CreateDefaultMemManager(); | 498 MemMgr = JMM ? JMM : JITMemoryManager::CreateDefaultMemManager(); |
493 if (jit.getJITInfo().needsGOT()) { | 499 if (jit.getJITInfo().needsGOT()) { |
494 MemMgr->AllocateGOT(); | 500 MemMgr->AllocateGOT(); |
495 DOUT << "JIT is managing a GOT\n"; | 501 DOUT << "JIT is managing a GOT\n"; |
496 } | 502 } |
497 | 503 |
498 if (ExceptionHandling) DE = new JITDwarfEmitter(jit); | 504 if (ExceptionHandling || JitEmitDebugInfo) { |
505 DE = new JITDwarfEmitter(jit); | |
506 } | |
507 if (JitEmitDebugInfo) { | |
508 DR = new JITDebugRegisterer(TM); | |
509 } | |
499 } | 510 } |
511 | |
500 ~JITEmitter() {· | 512 ~JITEmitter() {· |
501 delete MemMgr; | 513 delete MemMgr; |
502 if (ExceptionHandling) delete DE; | 514 if (ExceptionHandling || JitEmitDebugInfo) { |
Jeffrey Yasskin
2009/07/03 22:01:52
I don't like that the conditions have to match her
Reid Kleckner
2009/07/06 21:07:01
Done.
| |
515 delete DE; | |
516 } | |
517 if (JitEmitDebugInfo) { | |
518 delete DR; | |
519 } | |
503 } | 520 } |
504 | 521 |
505 /// classof - Methods for support type inquiry through isa, cast, and | 522 /// classof - Methods for support type inquiry through isa, cast, and |
506 /// dyn_cast: | 523 /// dyn_cast: |
507 /// | 524 /// |
508 static inline bool classof(const JITEmitter*) { return true; } | 525 static inline bool classof(const JITEmitter*) { return true; } |
509 static inline bool classof(const MachineCodeEmitter*) { return true; } | 526 static inline bool classof(const MachineCodeEmitter*) { return true; } |
510 ···· | 527 ···· |
511 JITResolver &getJITResolver() { return Resolver; } | 528 JITResolver &getJITResolver() { return Resolver; } |
512 | 529 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
568 } | 585 } |
569 | 586 |
570 virtual uintptr_t getLabelAddress(uint64_t LabelID) const { | 587 virtual uintptr_t getLabelAddress(uint64_t LabelID) const { |
571 assert(LabelLocations.size() > (unsigned)LabelID &&· | 588 assert(LabelLocations.size() > (unsigned)LabelID &&· |
572 LabelLocations[LabelID] && "Label not emitted!"); | 589 LabelLocations[LabelID] && "Label not emitted!"); |
573 return LabelLocations[LabelID]; | 590 return LabelLocations[LabelID]; |
574 } | 591 } |
575 · | 592 · |
576 virtual void setModuleInfo(MachineModuleInfo* Info) { | 593 virtual void setModuleInfo(MachineModuleInfo* Info) { |
577 MMI = Info; | 594 MMI = Info; |
578 if (ExceptionHandling) DE->setModuleInfo(Info); | 595 if (ExceptionHandling || JitEmitDebugInfo) { |
596 DE->setModuleInfo(Info); | |
597 } | |
579 } | 598 } |
580 | 599 |
581 void setMemoryExecutable(void) { | 600 void setMemoryExecutable(void) { |
582 MemMgr->setMemoryExecutable(); | 601 MemMgr->setMemoryExecutable(); |
583 } | 602 } |
584 ···· | 603 ···· |
585 JITMemoryManager *getMemMgr(void) const { return MemMgr; } | 604 JITMemoryManager *getMemMgr(void) const { return MemMgr; } |
586 | 605 |
587 private: | 606 private: |
588 void *getPointerToGlobal(GlobalValue *GV, void *Reference, bool NoNeedStub); | 607 void *getPointerToGlobal(GlobalValue *GV, void *Reference, bool NoNeedStub); |
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1063 break; | 1082 break; |
1064 DOUT << ' '; | 1083 DOUT << ' '; |
1065 if (i == 3) | 1084 if (i == 3) |
1066 DOUT << '\n'; | 1085 DOUT << '\n'; |
1067 } | 1086 } |
1068 DOUT << std::dec; | 1087 DOUT << std::dec; |
1069 DOUT<< '\n'; | 1088 DOUT<< '\n'; |
1070 } | 1089 } |
1071 } | 1090 } |
1072 #endif | 1091 #endif |
1073 if (ExceptionHandling) { | 1092 if (ExceptionHandling || JitEmitDebugInfo) { |
Jeffrey Yasskin
2009/07/03 22:01:52
It'd be nice to put this into a JITEventListener,
Reid Kleckner
2009/07/06 21:07:01
I could wrap both exception handling and debug inf
Jeffrey Yasskin
2009/07/08 00:40:45
That sounds good, actually. It makes sense becaus
| |
1074 uintptr_t ActualSize = 0; | 1093 uintptr_t ActualSize = 0; |
1075 SavedBufferBegin = BufferBegin; | 1094 SavedBufferBegin = BufferBegin; |
1076 SavedBufferEnd = BufferEnd; | 1095 SavedBufferEnd = BufferEnd; |
1077 SavedCurBufferPtr = CurBufferPtr; | 1096 SavedCurBufferPtr = CurBufferPtr; |
1078 ···· | 1097 ···· |
1079 if (MemMgr->NeedsExactSize()) { | 1098 if (MemMgr->NeedsExactSize()) { |
1080 ActualSize = DE->GetDwarfTableSizeInBytes(F, *this, FnStart, FnEnd); | 1099 ActualSize = DE->GetDwarfTableSizeInBytes(F, *this, FnStart, FnEnd); |
1081 } | 1100 } |
1082 | 1101 |
1083 BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(), | 1102 BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(), |
1084 ActualSize); | 1103 ActualSize); |
1085 BufferEnd = BufferBegin+ActualSize; | 1104 BufferEnd = BufferBegin+ActualSize; |
1105 uint8_t* EhStart = BufferBegin; | |
1086 uint8_t* FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd); | 1106 uint8_t* FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd); |
1087 MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr, | 1107 MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr, |
1088 FrameRegister); | 1108 FrameRegister); |
1109 uint8_t* EhEnd = CurBufferPtr; | |
1089 BufferBegin = SavedBufferBegin; | 1110 BufferBegin = SavedBufferBegin; |
1090 BufferEnd = SavedBufferEnd; | 1111 BufferEnd = SavedBufferEnd; |
1091 CurBufferPtr = SavedCurBufferPtr; | 1112 CurBufferPtr = SavedCurBufferPtr; |
1092 | 1113 |
1093 TheJIT->RegisterTable(FrameRegister); | 1114 if (ExceptionHandling) { |
1115 TheJIT->RegisterTable(FrameRegister); | |
1116 } | |
1117 | |
1118 if (JitEmitDebugInfo) { | |
1119 DR->RegisterDebugInfo(F.getFunction(), FnStart, FnEnd, EhStart, EhEnd); | |
1120 } | |
1094 } | 1121 } |
1095 | 1122 |
1096 if (MMI) | 1123 if (MMI) |
1097 MMI->EndFunction(); | 1124 MMI->EndFunction(); |
1098 · | 1125 · |
1099 return false; | 1126 return false; |
1100 } | 1127 } |
1101 | 1128 |
1102 /// deallocateMemForFunction - Deallocate all memory for the specified | 1129 /// deallocateMemForFunction - Deallocate all memory for the specified |
1103 /// function body. Also drop any references the function has to stubs. | 1130 /// function body. Also drop any references the function has to stubs. |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1315 ·· | 1342 ·· |
1316 Offset *= EntrySize; | 1343 Offset *= EntrySize; |
1317 ·· | 1344 ·· |
1318 return (uintptr_t)((char *)JumpTableBase + Offset); | 1345 return (uintptr_t)((char *)JumpTableBase + Offset); |
1319 } | 1346 } |
1320 | 1347 |
1321 //===----------------------------------------------------------------------===// | 1348 //===----------------------------------------------------------------------===// |
1322 // Public interface to this file | 1349 // Public interface to this file |
1323 //===----------------------------------------------------------------------===// | 1350 //===----------------------------------------------------------------------===// |
1324 | 1351 |
1325 JITCodeEmitter *JIT::createEmitter(JIT &jit, JITMemoryManager *JMM) { | 1352 JITCodeEmitter *JIT::createEmitter(JIT &jit, JITMemoryManager *JMM, |
1326 return new JITEmitter(jit, JMM); | 1353 TargetMachine &tm) { |
1354 return new JITEmitter(jit, JMM, tm); | |
1327 } | 1355 } |
1328 | 1356 |
1329 // getPointerToNamedFunction - This function is used as a global wrapper to | 1357 // getPointerToNamedFunction - This function is used as a global wrapper to |
1330 // JIT::getPointerToNamedFunction for the purpose of resolving symbols when | 1358 // JIT::getPointerToNamedFunction for the purpose of resolving symbols when |
1331 // bugpoint is debugging the JIT. In that scenario, we are loading an .so and | 1359 // bugpoint is debugging the JIT. In that scenario, we are loading an .so and |
1332 // need to resolve function(s) that are being mis-codegenerated, so we need to | 1360 // need to resolve function(s) that are being mis-codegenerated, so we need to |
1333 // resolve their addresses at runtime, and this is the way to do it. | 1361 // resolve their addresses at runtime, and this is the way to do it. |
1334 extern "C" { | 1362 extern "C" { |
1335 void *getPointerToNamedFunction(const char *Name) { | 1363 void *getPointerToNamedFunction(const char *Name) { |
1336 if (Function *F = TheJIT->FindFunctionNamed(Name)) | 1364 if (Function *F = TheJIT->FindFunctionNamed(Name)) |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1460 // retranslated next time it is used. | 1488 // retranslated next time it is used. |
1461 void *OldPtr = updateGlobalMapping(F, 0); | 1489 void *OldPtr = updateGlobalMapping(F, 0); |
1462 | 1490 |
1463 if (OldPtr) | 1491 if (OldPtr) |
1464 TheJIT->NotifyFreeingMachineCode(*F, OldPtr); | 1492 TheJIT->NotifyFreeingMachineCode(*F, OldPtr); |
1465 | 1493 |
1466 // Free the actual memory for the function body and related stuff. | 1494 // Free the actual memory for the function body and related stuff. |
1467 assert(isa<JITEmitter>(JCE) && "Unexpected MCE?"); | 1495 assert(isa<JITEmitter>(JCE) && "Unexpected MCE?"); |
1468 cast<JITEmitter>(JCE)->deallocateMemForFunction(F); | 1496 cast<JITEmitter>(JCE)->deallocateMemForFunction(F); |
1469 } | 1497 } |
OLD | NEW |