diff options
Diffstat (limited to 'lib/ExecutionEngine/JIT')
-rw-r--r-- | lib/ExecutionEngine/JIT/JIT.cpp | 15 | ||||
-rw-r--r-- | lib/ExecutionEngine/JIT/JIT.h | 37 | ||||
-rw-r--r-- | lib/ExecutionEngine/JIT/JITEmitter.cpp | 43 | ||||
-rw-r--r-- | lib/ExecutionEngine/JIT/JITMemoryManager.cpp | 99 | ||||
-rw-r--r-- | lib/ExecutionEngine/JIT/LLVMBuild.txt | 2 |
5 files changed, 99 insertions, 97 deletions
diff --git a/lib/ExecutionEngine/JIT/JIT.cpp b/lib/ExecutionEngine/JIT/JIT.cpp index 246a675..d3ad77b 100644 --- a/lib/ExecutionEngine/JIT/JIT.cpp +++ b/lib/ExecutionEngine/JIT/JIT.cpp @@ -26,6 +26,7 @@ #include "llvm/IR/Function.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Instructions.h" +#include "llvm/IR/Module.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/ErrorHandling.h" @@ -151,7 +152,8 @@ JIT::JIT(Module *M, TargetMachine &tm, TargetJITInfo &tji, // Add target data MutexGuard locked(lock); FunctionPassManager &PM = jitstate->getPM(locked); - PM.add(new DataLayout(*TM.getDataLayout())); + M->setDataLayout(TM.getDataLayout()); + PM.add(new DataLayoutPass(M)); // Turn the machine code intermediate representation into bytes in memory that // may be executed. @@ -183,7 +185,8 @@ void JIT::addModule(Module *M) { jitstate = new JITState(M); FunctionPassManager &PM = jitstate->getPM(locked); - PM.add(new DataLayout(*TM.getDataLayout())); + M->setDataLayout(TM.getDataLayout()); + PM.add(new DataLayoutPass(M)); // Turn the machine code intermediate representation into bytes in memory // that may be executed. @@ -214,7 +217,8 @@ bool JIT::removeModule(Module *M) { jitstate = new JITState(Modules[0]); FunctionPassManager &PM = jitstate->getPM(locked); - PM.add(new DataLayout(*TM.getDataLayout())); + M->setDataLayout(TM.getDataLayout()); + PM.add(new DataLayoutPass(M)); // Turn the machine code intermediate representation into bytes in memory // that may be executed. @@ -446,9 +450,8 @@ void JIT::runJITOnFunction(Function *F, MachineCodeInfo *MCI) { MachineCodeInfo *const MCI; public: MCIListener(MachineCodeInfo *mci) : MCI(mci) {} - virtual void NotifyFunctionEmitted(const Function &, - void *Code, size_t Size, - const EmittedFunctionDetails &) { + void NotifyFunctionEmitted(const Function &, void *Code, size_t Size, + const EmittedFunctionDetails &) override { MCI->setAddress(Code); MCI->setSize(Size); } diff --git a/lib/ExecutionEngine/JIT/JIT.h b/lib/ExecutionEngine/JIT/JIT.h index 2ae155b..b1b0768 100644 --- a/lib/ExecutionEngine/JIT/JIT.h +++ b/lib/ExecutionEngine/JIT/JIT.h @@ -15,8 +15,8 @@ #define JIT_H #include "llvm/ExecutionEngine/ExecutionEngine.h" +#include "llvm/IR/ValueHandle.h" #include "llvm/PassManager.h" -#include "llvm/Support/ValueHandle.h" namespace llvm { @@ -106,16 +106,16 @@ public: RM, CMM); } - virtual void addModule(Module *M); + void addModule(Module *M) override; /// removeModule - Remove a Module from the list of modules. Returns true if /// M is found. - virtual bool removeModule(Module *M); + bool removeModule(Module *M) override; /// runFunction - Start execution with the specified function and arguments. /// - virtual GenericValue runFunction(Function *F, - const std::vector<GenericValue> &ArgValues); + GenericValue runFunction(Function *F, + const std::vector<GenericValue> &ArgValues) override; /// getPointerToNamedFunction - This method returns the address of the /// specified function by using the MemoryManager. As such it is only @@ -125,8 +125,8 @@ public: /// found, this function silently returns a null pointer. Otherwise, /// it prints a message to stderr and aborts. /// - virtual void *getPointerToNamedFunction(const std::string &Name, - bool AbortOnFailure = true); + void *getPointerToNamedFunction(const std::string &Name, + bool AbortOnFailure = true) override; // CompilationCallback - Invoked the first time that a call site is found, // which causes lazy compilation of the target function. @@ -136,7 +136,7 @@ public: /// getPointerToFunction - This returns the address of the specified function, /// compiling it if necessary. /// - void *getPointerToFunction(Function *F); + void *getPointerToFunction(Function *F) override; /// addPointerToBasicBlock - Adds address of the specific basic block. void addPointerToBasicBlock(const BasicBlock *BB, void *Addr); @@ -146,18 +146,18 @@ public: /// getPointerToBasicBlock - This returns the address of the specified basic /// block, assuming function is compiled. - void *getPointerToBasicBlock(BasicBlock *BB); + void *getPointerToBasicBlock(BasicBlock *BB) override; /// getOrEmitGlobalVariable - Return the address of the specified global /// variable, possibly emitting it to memory if needed. This is used by the /// Emitter. - void *getOrEmitGlobalVariable(const GlobalVariable *GV); + void *getOrEmitGlobalVariable(const GlobalVariable *GV) override; /// getPointerToFunctionOrStub - If the specified function has been /// code-gen'd, return a pointer to the function. If not, compile it, or use /// a stub to implement lazy compilation if available. /// - void *getPointerToFunctionOrStub(Function *F); + void *getPointerToFunctionOrStub(Function *F) override; /// recompileAndRelinkFunction - This method is used to force a function /// which has already been compiled, to be compiled again, possibly @@ -165,12 +165,12 @@ public: /// with a branch to the new copy. If there was no old copy, this acts /// just like JIT::getPointerToFunction(). /// - void *recompileAndRelinkFunction(Function *F); + void *recompileAndRelinkFunction(Function *F) override; /// freeMachineCodeForFunction - deallocate memory used to code-generate this /// Function. /// - void freeMachineCodeForFunction(Function *F); + void freeMachineCodeForFunction(Function *F) override; /// addPendingFunction - while jitting non-lazily, a called but non-codegen'd /// function was encountered. Add it to a pending list to be processed after @@ -189,10 +189,13 @@ public: TargetMachine *TM); // Run the JIT on F and return information about the generated code - void runJITOnFunction(Function *F, MachineCodeInfo *MCI = 0); + void runJITOnFunction(Function *F, MachineCodeInfo *MCI = 0) override; + + void RegisterJITEventListener(JITEventListener *L) override; + void UnregisterJITEventListener(JITEventListener *L) override; + + TargetMachine *getTargetMachine() override { return &TM; } - virtual void RegisterJITEventListener(JITEventListener *L); - virtual void UnregisterJITEventListener(JITEventListener *L); /// These functions correspond to the methods on JITEventListener. They /// iterate over the registered listeners and call the corresponding method on /// each. @@ -217,7 +220,7 @@ private: protected: /// getMemoryforGV - Allocate memory for a global variable. - virtual char* getMemoryForGV(const GlobalVariable* GV); + char* getMemoryForGV(const GlobalVariable* GV) override; }; diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp index acbbfa1..9d215ec 100644 --- a/lib/ExecutionEngine/JIT/JITEmitter.cpp +++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp @@ -15,11 +15,9 @@ #define DEBUG_TYPE "jit" #include "JIT.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" -#include "llvm/ADT/ValueMap.h" #include "llvm/CodeGen/JITCodeEmitter.h" #include "llvm/CodeGen/MachineCodeInfo.h" #include "llvm/CodeGen/MachineConstantPool.h" @@ -27,21 +25,22 @@ #include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineRelocation.h" -#include "llvm/DebugInfo.h" #include "llvm/ExecutionEngine/GenericValue.h" #include "llvm/ExecutionEngine/JITEventListener.h" #include "llvm/ExecutionEngine/JITMemoryManager.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/DebugInfo.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Module.h" +#include "llvm/IR/ValueHandle.h" +#include "llvm/IR/ValueMap.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Disassembler.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Memory.h" #include "llvm/Support/MutexGuard.h" -#include "llvm/Support/ValueHandle.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetJITInfo.h" @@ -376,8 +375,8 @@ namespace { JITResolver &getJITResolver() { return Resolver; } - virtual void startFunction(MachineFunction &F); - virtual bool finishFunction(MachineFunction &F); + void startFunction(MachineFunction &F) override; + bool finishFunction(MachineFunction &F) override; void emitConstantPool(MachineConstantPool *MCP); void initJumpTableInfo(MachineJumpTableInfo *MJTI); @@ -387,24 +386,23 @@ namespace { unsigned StubSize, unsigned Alignment = 1); void startGVStub(void *Buffer, unsigned StubSize); void finishGVStub(); - virtual void *allocIndirectGV(const GlobalValue *GV, - const uint8_t *Buffer, size_t Size, - unsigned Alignment); + void *allocIndirectGV(const GlobalValue *GV, const uint8_t *Buffer, + size_t Size, unsigned Alignment) override; /// allocateSpace - Reserves space in the current block if any, or /// allocate a new one of the given size. - virtual void *allocateSpace(uintptr_t Size, unsigned Alignment); + void *allocateSpace(uintptr_t Size, unsigned Alignment) override; /// allocateGlobal - Allocate memory for a global. Unlike allocateSpace, /// this method does not allocate memory in the current output buffer, /// because a global may live longer than the current function. - virtual void *allocateGlobal(uintptr_t Size, unsigned Alignment); + void *allocateGlobal(uintptr_t Size, unsigned Alignment) override; - virtual void addRelocation(const MachineRelocation &MR) { + void addRelocation(const MachineRelocation &MR) override { Relocations.push_back(MR); } - virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) { + void StartMachineBasicBlock(MachineBasicBlock *MBB) override { if (MBBLocations.size() <= (unsigned)MBB->getNumber()) MBBLocations.resize((MBB->getNumber()+1)*2); MBBLocations[MBB->getNumber()] = getCurrentPCValue(); @@ -415,10 +413,11 @@ namespace { << (void*) getCurrentPCValue() << "]\n"); } - virtual uintptr_t getConstantPoolEntryAddress(unsigned Entry) const; - virtual uintptr_t getJumpTableEntryAddress(unsigned Entry) const; + uintptr_t getConstantPoolEntryAddress(unsigned Entry) const override; + uintptr_t getJumpTableEntryAddress(unsigned Entry) const override; - virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const{ + uintptr_t + getMachineBasicBlockAddress(MachineBasicBlock *MBB) const override { assert(MBBLocations.size() > (unsigned)MBB->getNumber() && MBBLocations[MBB->getNumber()] && "MBB not emitted!"); return MBBLocations[MBB->getNumber()]; @@ -433,22 +432,22 @@ namespace { /// function body. void deallocateMemForFunction(const Function *F); - virtual void processDebugLoc(DebugLoc DL, bool BeforePrintingInsn); + void processDebugLoc(DebugLoc DL, bool BeforePrintingInsn) override; - virtual void emitLabel(MCSymbol *Label) { + void emitLabel(MCSymbol *Label) override { LabelLocations[Label] = getCurrentPCValue(); } - virtual DenseMap<MCSymbol*, uintptr_t> *getLabelLocations() { + DenseMap<MCSymbol*, uintptr_t> *getLabelLocations() override { return &LabelLocations; } - virtual uintptr_t getLabelAddress(MCSymbol *Label) const { + uintptr_t getLabelAddress(MCSymbol *Label) const override { assert(LabelLocations.count(Label) && "Label not emitted!"); return LabelLocations.find(Label)->second; } - virtual void setModuleInfo(MachineModuleInfo* Info) { + void setModuleInfo(MachineModuleInfo* Info) override { MMI = Info; } @@ -689,7 +688,7 @@ void *JITEmitter::getPointerToGlobal(GlobalValue *V, void *Reference, return TheJIT->getOrEmitGlobalVariable(GV); if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) - return TheJIT->getPointerToGlobal(GA->resolveAliasedGlobal(false)); + return TheJIT->getPointerToGlobal(GA->getAliasedGlobal()); // If we have already compiled the function, return a pointer to its body. Function *F = cast<Function>(V); diff --git a/lib/ExecutionEngine/JIT/JITMemoryManager.cpp b/lib/ExecutionEngine/JIT/JITMemoryManager.cpp index f58d31b..0d1ea02 100644 --- a/lib/ExecutionEngine/JIT/JITMemoryManager.cpp +++ b/lib/ExecutionEngine/JIT/JITMemoryManager.cpp @@ -274,8 +274,8 @@ namespace { public: JITSlabAllocator(DefaultJITMemoryManager &jmm) : JMM(jmm) { } virtual ~JITSlabAllocator() { } - virtual MemSlab *Allocate(size_t Size); - virtual void Deallocate(MemSlab *Slab); + MemSlab *Allocate(size_t Size) override; + void Deallocate(MemSlab *Slab) override; }; /// DefaultJITMemoryManager - Manage memory for the JIT code generation. @@ -285,7 +285,21 @@ namespace { /// middle of emitting a function, and we don't know how large the function we /// are emitting is. class DefaultJITMemoryManager : public JITMemoryManager { + public: + /// DefaultCodeSlabSize - When we have to go map more memory, we allocate at + /// least this much unless more is requested. Currently, in 512k slabs. + static const size_t DefaultCodeSlabSize = 512 * 1024; + + /// DefaultSlabSize - Allocate globals and stubs into slabs of 64K (probably + /// 16 pages) unless we get an allocation above SizeThreshold. + static const size_t DefaultSlabSize = 64 * 1024; + /// DefaultSizeThreshold - For any allocation larger than 16K (probably + /// 4 pages), we should allocate a separate slab to avoid wasted space at + /// the end of a normal slab. + static const size_t DefaultSizeThreshold = 16 * 1024; + + private: // Whether to poison freed memory. bool PoisonMemory; @@ -300,8 +314,8 @@ namespace { // confuse them with the blocks of memory described above. std::vector<sys::MemoryBlock> CodeSlabs; JITSlabAllocator BumpSlabAllocator; - BumpPtrAllocator StubAllocator; - BumpPtrAllocator DataAllocator; + BumpPtrAllocatorImpl<DefaultSlabSize, DefaultSizeThreshold> StubAllocator; + BumpPtrAllocatorImpl<DefaultSlabSize, DefaultSizeThreshold> DataAllocator; // Circular list of free blocks. FreeRangeHeader *FreeMemoryList; @@ -318,37 +332,26 @@ namespace { /// last slab it allocated, so that subsequent allocations follow it. sys::MemoryBlock allocateNewSlab(size_t size); - /// DefaultCodeSlabSize - When we have to go map more memory, we allocate at - /// least this much unless more is requested. - static const size_t DefaultCodeSlabSize; - - /// DefaultSlabSize - Allocate data into slabs of this size unless we get - /// an allocation above SizeThreshold. - static const size_t DefaultSlabSize; - - /// DefaultSizeThreshold - For any allocation larger than this threshold, we - /// should allocate a separate slab. - static const size_t DefaultSizeThreshold; - /// getPointerToNamedFunction - This method returns the address of the /// specified function by using the dlsym function call. - virtual void *getPointerToNamedFunction(const std::string &Name, - bool AbortOnFailure = true); + void *getPointerToNamedFunction(const std::string &Name, + bool AbortOnFailure = true) override; - void AllocateGOT(); + void AllocateGOT() override; // Testing methods. - virtual bool CheckInvariants(std::string &ErrorStr); - size_t GetDefaultCodeSlabSize() { return DefaultCodeSlabSize; } - size_t GetDefaultDataSlabSize() { return DefaultSlabSize; } - size_t GetDefaultStubSlabSize() { return DefaultSlabSize; } - unsigned GetNumCodeSlabs() { return CodeSlabs.size(); } - unsigned GetNumDataSlabs() { return DataAllocator.GetNumSlabs(); } - unsigned GetNumStubSlabs() { return StubAllocator.GetNumSlabs(); } + bool CheckInvariants(std::string &ErrorStr) override; + size_t GetDefaultCodeSlabSize() override { return DefaultCodeSlabSize; } + size_t GetDefaultDataSlabSize() override { return DefaultSlabSize; } + size_t GetDefaultStubSlabSize() override { return DefaultSlabSize; } + unsigned GetNumCodeSlabs() override { return CodeSlabs.size(); } + unsigned GetNumDataSlabs() override { return DataAllocator.GetNumSlabs(); } + unsigned GetNumStubSlabs() override { return StubAllocator.GetNumSlabs(); } /// startFunctionBody - When a function starts, allocate a block of free /// executable memory, returning a pointer to it and its actual size. - uint8_t *startFunctionBody(const Function *F, uintptr_t &ActualSize) { + uint8_t *startFunctionBody(const Function *F, + uintptr_t &ActualSize) override { FreeRangeHeader* candidateBlock = FreeMemoryList; FreeRangeHeader* head = FreeMemoryList; @@ -422,7 +425,7 @@ namespace { /// endFunctionBody - The function F is now allocated, and takes the memory /// in the range [FunctionStart,FunctionEnd). void endFunctionBody(const Function *F, uint8_t *FunctionStart, - uint8_t *FunctionEnd) { + uint8_t *FunctionEnd) override { assert(FunctionEnd > FunctionStart); assert(FunctionStart == (uint8_t *)(CurBlock+1) && "Mismatched function start/end!"); @@ -435,7 +438,7 @@ namespace { /// allocateSpace - Allocate a memory block of the given size. This method /// cannot be called between calls to startFunctionBody and endFunctionBody. - uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) { + uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) override { CurBlock = FreeMemoryList; FreeMemoryList = FreeMemoryList->AllocateBlock(); @@ -453,18 +456,19 @@ namespace { /// allocateStub - Allocate memory for a function stub. uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize, - unsigned Alignment) { + unsigned Alignment) override { return (uint8_t*)StubAllocator.Allocate(StubSize, Alignment); } /// allocateGlobal - Allocate memory for a global. - uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) { + uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) override { return (uint8_t*)DataAllocator.Allocate(Size, Alignment); } /// allocateCodeSection - Allocate memory for a code section. uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID, StringRef SectionName) { + unsigned SectionID, + StringRef SectionName) override { // Grow the required block size to account for the block header Size += sizeof(*CurBlock); @@ -511,15 +515,15 @@ namespace { /// allocateDataSection - Allocate memory for a data section. uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, StringRef SectionName, - bool IsReadOnly) { + bool IsReadOnly) override { return (uint8_t*)DataAllocator.Allocate(Size, Alignment); } - bool finalizeMemory(std::string *ErrMsg) { + bool finalizeMemory(std::string *ErrMsg) override { return false; } - uint8_t *getGOTBase() const { + uint8_t *getGOTBase() const override { return GOTBase; } @@ -539,28 +543,26 @@ namespace { /// deallocateFunctionBody - Deallocate all memory for the specified /// function body. - void deallocateFunctionBody(void *Body) { + void deallocateFunctionBody(void *Body) override { if (Body) deallocateBlock(Body); } /// setMemoryWritable - When code generation is in progress, /// the code pages may need permissions changed. - void setMemoryWritable() - { + void setMemoryWritable() override { for (unsigned i = 0, e = CodeSlabs.size(); i != e; ++i) sys::Memory::setWritable(CodeSlabs[i]); } /// setMemoryExecutable - When code generation is done and we're ready to /// start execution, the code pages may need permissions changed. - void setMemoryExecutable() - { + void setMemoryExecutable() override { for (unsigned i = 0, e = CodeSlabs.size(); i != e; ++i) sys::Memory::setExecutable(CodeSlabs[i]); } /// setPoisonMemory - Controls whether we write garbage over freed memory. /// - void setPoisonMemory(bool poison) { + void setPoisonMemory(bool poison) override { PoisonMemory = poison; } }; @@ -588,8 +590,8 @@ DefaultJITMemoryManager::DefaultJITMemoryManager() #endif LastSlab(0, 0), BumpSlabAllocator(*this), - StubAllocator(DefaultSlabSize, DefaultSizeThreshold, BumpSlabAllocator), - DataAllocator(DefaultSlabSize, DefaultSizeThreshold, BumpSlabAllocator) { + StubAllocator(BumpSlabAllocator), + DataAllocator(BumpSlabAllocator) { // Allocate space for code. sys::MemoryBlock MemBlock = allocateNewSlab(DefaultCodeSlabSize); @@ -902,11 +904,6 @@ JITMemoryManager *JITMemoryManager::CreateDefaultMemManager() { return new DefaultJITMemoryManager(); } -// Allocate memory for code in 512K slabs. -const size_t DefaultJITMemoryManager::DefaultCodeSlabSize = 512 * 1024; - -// Allocate globals and stubs in slabs of 64K. (probably 16 pages) -const size_t DefaultJITMemoryManager::DefaultSlabSize = 64 * 1024; - -// Waste at most 16K at the end of each bump slab. (probably 4 pages) -const size_t DefaultJITMemoryManager::DefaultSizeThreshold = 16 * 1024; +const size_t DefaultJITMemoryManager::DefaultCodeSlabSize; +const size_t DefaultJITMemoryManager::DefaultSlabSize; +const size_t DefaultJITMemoryManager::DefaultSizeThreshold; diff --git a/lib/ExecutionEngine/JIT/LLVMBuild.txt b/lib/ExecutionEngine/JIT/LLVMBuild.txt index ca2a565..dd22f1b 100644 --- a/lib/ExecutionEngine/JIT/LLVMBuild.txt +++ b/lib/ExecutionEngine/JIT/LLVMBuild.txt @@ -19,4 +19,4 @@ type = Library name = JIT parent = ExecutionEngine -required_libraries = CodeGen Core ExecutionEngine MC RuntimeDyld Support Target +required_libraries = CodeGen Core ExecutionEngine Support |