1 //===- Target/TargetJITInfo.h - Target Information for JIT ------*- C++ -*-===// 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 // This file exposes an abstract interface used by the Just-In-Time code 11 // generator to perform target-specific activities, such as emitting stubs. If 12 // a TargetMachine supports JIT code generation, it should provide one of these 13 // objects through the getJITInfo() method. 14 // 15 //===----------------------------------------------------------------------===// 16 17 #ifndef LLVM_TARGET_TARGETJITINFO_H 18 #define LLVM_TARGET_TARGETJITINFO_H 19 20 #include "llvm/Support/DataTypes.h" 21 #include "llvm/Support/ErrorHandling.h" 22 #include <cassert> 23 24 namespace llvm { 25 class Function; 26 class GlobalValue; 27 class JITCodeEmitter; 28 class MachineRelocation; 29 30 /// TargetJITInfo - Target specific information required by the Just-In-Time 31 /// code generator. 32 class TargetJITInfo { 33 virtual void anchor(); 34 public: ~TargetJITInfo()35 virtual ~TargetJITInfo() {} 36 37 /// replaceMachineCodeForFunction - Make it so that calling the function 38 /// whose machine code is at OLD turns into a call to NEW, perhaps by 39 /// overwriting OLD with a branch to NEW. This is used for self-modifying 40 /// code. 41 /// 42 virtual void replaceMachineCodeForFunction(void *Old, void *New) = 0; 43 44 /// emitGlobalValueIndirectSym - Use the specified JITCodeEmitter object 45 /// to emit an indirect symbol which contains the address of the specified 46 /// ptr. emitGlobalValueIndirectSym(const GlobalValue * GV,void * ptr,JITCodeEmitter & JCE)47 virtual void *emitGlobalValueIndirectSym(const GlobalValue* GV, void *ptr, 48 JITCodeEmitter &JCE) { 49 llvm_unreachable("This target doesn't implement " 50 "emitGlobalValueIndirectSym!"); 51 } 52 53 /// Records the required size and alignment for a call stub in bytes. 54 struct StubLayout { 55 size_t Size; 56 size_t Alignment; 57 }; 58 /// Returns the maximum size and alignment for a call stub on this target. getStubLayout()59 virtual StubLayout getStubLayout() { 60 llvm_unreachable("This target doesn't implement getStubLayout!"); 61 } 62 63 /// emitFunctionStub - Use the specified JITCodeEmitter object to emit a 64 /// small native function that simply calls the function at the specified 65 /// address. The JITCodeEmitter must already have storage allocated for the 66 /// stub. Return the address of the resultant function, which may have been 67 /// aligned from the address the JCE was set up to emit at. emitFunctionStub(const Function * F,void * Target,JITCodeEmitter & JCE)68 virtual void *emitFunctionStub(const Function* F, void *Target, 69 JITCodeEmitter &JCE) { 70 llvm_unreachable("This target doesn't implement emitFunctionStub!"); 71 } 72 73 /// getPICJumpTableEntry - Returns the value of the jumptable entry for the 74 /// specific basic block. getPICJumpTableEntry(uintptr_t BB,uintptr_t JTBase)75 virtual uintptr_t getPICJumpTableEntry(uintptr_t BB, uintptr_t JTBase) { 76 llvm_unreachable("This target doesn't implement getPICJumpTableEntry!"); 77 } 78 79 /// LazyResolverFn - This typedef is used to represent the function that 80 /// unresolved call points should invoke. This is a target specific 81 /// function that knows how to walk the stack and find out which stub the 82 /// call is coming from. 83 typedef void (*LazyResolverFn)(); 84 85 /// JITCompilerFn - This typedef is used to represent the JIT function that 86 /// lazily compiles the function corresponding to a stub. The JIT keeps 87 /// track of the mapping between stubs and LLVM Functions, the target 88 /// provides the ability to figure out the address of a stub that is called 89 /// by the LazyResolverFn. 90 typedef void* (*JITCompilerFn)(void *); 91 92 /// getLazyResolverFunction - This method is used to initialize the JIT, 93 /// giving the target the function that should be used to compile a 94 /// function, and giving the JIT the target function used to do the lazy 95 /// resolving. getLazyResolverFunction(JITCompilerFn)96 virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn) { 97 llvm_unreachable("Not implemented for this target!"); 98 } 99 100 /// relocate - Before the JIT can run a block of code that has been emitted, 101 /// it must rewrite the code to contain the actual addresses of any 102 /// referenced global symbols. relocate(void * Function,MachineRelocation * MR,unsigned NumRelocs,unsigned char * GOTBase)103 virtual void relocate(void *Function, MachineRelocation *MR, 104 unsigned NumRelocs, unsigned char* GOTBase) { 105 assert(NumRelocs == 0 && "This target does not have relocations!"); 106 } 107 108 109 /// allocateThreadLocalMemory - Each target has its own way of 110 /// handling thread local variables. This method returns a value only 111 /// meaningful to the target. allocateThreadLocalMemory(size_t size)112 virtual char* allocateThreadLocalMemory(size_t size) { 113 llvm_unreachable("This target does not implement thread local storage!"); 114 } 115 116 /// needsGOT - Allows a target to specify that it would like the 117 /// JIT to manage a GOT for it. needsGOT()118 bool needsGOT() const { return useGOT; } 119 120 /// hasCustomConstantPool - Allows a target to specify that constant 121 /// pool address resolution is handled by the target. hasCustomConstantPool()122 virtual bool hasCustomConstantPool() const { return false; } 123 124 /// hasCustomJumpTables - Allows a target to specify that jumptables 125 /// are emitted by the target. hasCustomJumpTables()126 virtual bool hasCustomJumpTables() const { return false; } 127 128 /// allocateSeparateGVMemory - If true, globals should be placed in 129 /// separately allocated heap memory rather than in the same 130 /// code memory allocated by JITCodeEmitter. allocateSeparateGVMemory()131 virtual bool allocateSeparateGVMemory() const { return false; } 132 protected: 133 bool useGOT; 134 }; 135 } // End llvm namespace 136 137 #endif 138