11e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner//===- Target/TargetJITInfo.h - Target Information for JIT ------*- C++ -*-===//
234695381d626485a560594f162701088079589dfMisha Brukman//
31e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner//                     The LLVM Compiler Infrastructure
41e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner//
57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// This file is distributed under the University of Illinois Open Source
67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// License. See LICENSE.TXT for details.
734695381d626485a560594f162701088079589dfMisha Brukman//
81e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner//===----------------------------------------------------------------------===//
91e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner//
101e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner// This file exposes an abstract interface used by the Just-In-Time code
111e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner// generator to perform target-specific activities, such as emitting stubs.  If
121e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner// a TargetMachine supports JIT code generation, it should provide one of these
131e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner// objects through the getJITInfo() method.
141e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner//
151e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner//===----------------------------------------------------------------------===//
161e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner
171e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner#ifndef LLVM_TARGET_TARGETJITINFO_H
181e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner#define LLVM_TARGET_TARGETJITINFO_H
191e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner
201f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/DataTypes.h"
21255f89faee13dc491cb64fbeae3c763e7e2ea4e6Chandler Carruth#include "llvm/Support/ErrorHandling.h"
226c01492ac40bed9529a2f7c8d40da34b8f04365eCraig Topper#include <cassert>
239da3c56efd98cd9bf55104ca7d484728470eda6aChris Lattner
241e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattnernamespace llvm {
251e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner  class Function;
2651cc3c13eac78da242f0518fc42580e48dd5304fNicolas Geoffray  class GlobalValue;
27a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes  class JITCodeEmitter;
289da3c56efd98cd9bf55104ca7d484728470eda6aChris Lattner  class MachineRelocation;
291e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner
301e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner  /// TargetJITInfo - Target specific information required by the Just-In-Time
311e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner  /// code generator.
32148d2065e4eb60357014a39c8e0d66c908679ffdAlkis Evlogimenos  class TargetJITInfo {
332d24e2a396a1d211baaeedf32148a3b657240170David Blaikie    virtual void anchor();
34148d2065e4eb60357014a39c8e0d66c908679ffdAlkis Evlogimenos  public:
351e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner    virtual ~TargetJITInfo() {}
3634695381d626485a560594f162701088079589dfMisha Brukman
371e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner    /// replaceMachineCodeForFunction - Make it so that calling the function
381e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner    /// whose machine code is at OLD turns into a call to NEW, perhaps by
391e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner    /// overwriting OLD with a branch to NEW.  This is used for self-modifying
401e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner    /// code.
411e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner    ///
42f3ae06ee1f257ff847200d51ed795bba2399e9a2Chris Lattner    virtual void replaceMachineCodeForFunction(void *Old, void *New) = 0;
4334695381d626485a560594f162701088079589dfMisha Brukman
44a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    /// emitGlobalValueIndirectSym - Use the specified JITCodeEmitter object
459ed2f80910160bbf8051d91cd74c82d4619885b4Evan Cheng    /// to emit an indirect symbol which contains the address of the specified
469ed2f80910160bbf8051d91cd74c82d4619885b4Evan Cheng    /// ptr.
479ed2f80910160bbf8051d91cd74c82d4619885b4Evan Cheng    virtual void *emitGlobalValueIndirectSym(const GlobalValue* GV, void *ptr,
48a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes                                             JITCodeEmitter &JCE) {
4950bee42b54cd9aec5f49566307df2b0cf23afcf6Craig Topper      llvm_unreachable("This target doesn't implement "
5050bee42b54cd9aec5f49566307df2b0cf23afcf6Craig Topper                       "emitGlobalValueIndirectSym!");
51be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng    }
52be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng
53108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin    /// Records the required size and alignment for a call stub in bytes.
54108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin    struct StubLayout {
55108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin      size_t Size;
56108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin      size_t Alignment;
57108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin    };
58108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin    /// Returns the maximum size and alignment for a call stub on this target.
59108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin    virtual StubLayout getStubLayout() {
60108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin      llvm_unreachable("This target doesn't implement getStubLayout!");
61108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin    }
62108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin
63a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    /// emitFunctionStub - Use the specified JITCodeEmitter object to emit a
64f3ae06ee1f257ff847200d51ed795bba2399e9a2Chris Lattner    /// small native function that simply calls the function at the specified
65108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin    /// address.  The JITCodeEmitter must already have storage allocated for the
66108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin    /// stub.  Return the address of the resultant function, which may have been
67108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin    /// aligned from the address the JCE was set up to emit at.
68108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin    virtual void *emitFunctionStub(const Function* F, void *Target,
69a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes                                   JITCodeEmitter &JCE) {
7050bee42b54cd9aec5f49566307df2b0cf23afcf6Craig Topper      llvm_unreachable("This target doesn't implement emitFunctionStub!");
71f3ae06ee1f257ff847200d51ed795bba2399e9a2Chris Lattner    }
72f3ae06ee1f257ff847200d51ed795bba2399e9a2Chris Lattner
732a3e08b5961353fa3faeadf81f481ae9f5463427Evan Cheng    /// getPICJumpTableEntry - Returns the value of the jumptable entry for the
742a3e08b5961353fa3faeadf81f481ae9f5463427Evan Cheng    /// specific basic block.
755788d1a169db3346a612a13113348d2709bdd15bEvan Cheng    virtual uintptr_t getPICJumpTableEntry(uintptr_t BB, uintptr_t JTBase) {
7650bee42b54cd9aec5f49566307df2b0cf23afcf6Craig Topper      llvm_unreachable("This target doesn't implement getPICJumpTableEntry!");
772a3e08b5961353fa3faeadf81f481ae9f5463427Evan Cheng    }
782a3e08b5961353fa3faeadf81f481ae9f5463427Evan Cheng
79f3ae06ee1f257ff847200d51ed795bba2399e9a2Chris Lattner    /// LazyResolverFn - This typedef is used to represent the function that
80f3ae06ee1f257ff847200d51ed795bba2399e9a2Chris Lattner    /// unresolved call points should invoke.  This is a target specific
81f3ae06ee1f257ff847200d51ed795bba2399e9a2Chris Lattner    /// function that knows how to walk the stack and find out which stub the
82f3ae06ee1f257ff847200d51ed795bba2399e9a2Chris Lattner    /// call is coming from.
83f3ae06ee1f257ff847200d51ed795bba2399e9a2Chris Lattner    typedef void (*LazyResolverFn)();
84f3ae06ee1f257ff847200d51ed795bba2399e9a2Chris Lattner
85f3ae06ee1f257ff847200d51ed795bba2399e9a2Chris Lattner    /// JITCompilerFn - This typedef is used to represent the JIT function that
86f3ae06ee1f257ff847200d51ed795bba2399e9a2Chris Lattner    /// lazily compiles the function corresponding to a stub.  The JIT keeps
87f3ae06ee1f257ff847200d51ed795bba2399e9a2Chris Lattner    /// track of the mapping between stubs and LLVM Functions, the target
88f3ae06ee1f257ff847200d51ed795bba2399e9a2Chris Lattner    /// provides the ability to figure out the address of a stub that is called
89f3ae06ee1f257ff847200d51ed795bba2399e9a2Chris Lattner    /// by the LazyResolverFn.
90f3ae06ee1f257ff847200d51ed795bba2399e9a2Chris Lattner    typedef void* (*JITCompilerFn)(void *);
91f3ae06ee1f257ff847200d51ed795bba2399e9a2Chris Lattner
92f3ae06ee1f257ff847200d51ed795bba2399e9a2Chris Lattner    /// getLazyResolverFunction - This method is used to initialize the JIT,
93f3ae06ee1f257ff847200d51ed795bba2399e9a2Chris Lattner    /// giving the target the function that should be used to compile a
94f3ae06ee1f257ff847200d51ed795bba2399e9a2Chris Lattner    /// function, and giving the JIT the target function used to do the lazy
95f3ae06ee1f257ff847200d51ed795bba2399e9a2Chris Lattner    /// resolving.
96f3ae06ee1f257ff847200d51ed795bba2399e9a2Chris Lattner    virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn) {
9750bee42b54cd9aec5f49566307df2b0cf23afcf6Craig Topper      llvm_unreachable("Not implemented for this target!");
981e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner    }
999da3c56efd98cd9bf55104ca7d484728470eda6aChris Lattner
1009da3c56efd98cd9bf55104ca7d484728470eda6aChris Lattner    /// relocate - Before the JIT can run a block of code that has been emitted,
1019da3c56efd98cd9bf55104ca7d484728470eda6aChris Lattner    /// it must rewrite the code to contain the actual addresses of any
1029da3c56efd98cd9bf55104ca7d484728470eda6aChris Lattner    /// referenced global symbols.
1039da3c56efd98cd9bf55104ca7d484728470eda6aChris Lattner    virtual void relocate(void *Function, MachineRelocation *MR,
1046a6b2dbd3a6786c6ef3d79a0b685291631245d32Andrew Lenharth                          unsigned NumRelocs, unsigned char* GOTBase) {
1059da3c56efd98cd9bf55104ca7d484728470eda6aChris Lattner      assert(NumRelocs == 0 && "This target does not have relocations!");
1069da3c56efd98cd9bf55104ca7d484728470eda6aChris Lattner    }
10746fa139e26be6ebc00be2fb45820c2560dd22a32Nicolas Geoffray
10846fa139e26be6ebc00be2fb45820c2560dd22a32Nicolas Geoffray
10946fa139e26be6ebc00be2fb45820c2560dd22a32Nicolas Geoffray    /// allocateThreadLocalMemory - Each target has its own way of
11046fa139e26be6ebc00be2fb45820c2560dd22a32Nicolas Geoffray    /// handling thread local variables. This method returns a value only
11146fa139e26be6ebc00be2fb45820c2560dd22a32Nicolas Geoffray    /// meaningful to the target.
11246fa139e26be6ebc00be2fb45820c2560dd22a32Nicolas Geoffray    virtual char* allocateThreadLocalMemory(size_t size) {
11350bee42b54cd9aec5f49566307df2b0cf23afcf6Craig Topper      llvm_unreachable("This target does not implement thread local storage!");
11446fa139e26be6ebc00be2fb45820c2560dd22a32Nicolas Geoffray    }
1156a6b2dbd3a6786c6ef3d79a0b685291631245d32Andrew Lenharth
1166a6b2dbd3a6786c6ef3d79a0b685291631245d32Andrew Lenharth    /// needsGOT - Allows a target to specify that it would like the
1177beace5d061b05bbe5fff24ad46c9d1bbafc2675Dan Gohman    /// JIT to manage a GOT for it.
1186a6b2dbd3a6786c6ef3d79a0b685291631245d32Andrew Lenharth    bool needsGOT() const { return useGOT; }
1196a6b2dbd3a6786c6ef3d79a0b685291631245d32Andrew Lenharth
1208fe95356dd487a79145ec07a9f46cd743b4c9bddJim Grosbach    /// hasCustomConstantPool - Allows a target to specify that constant
1218fe95356dd487a79145ec07a9f46cd743b4c9bddJim Grosbach    /// pool address resolution is handled by the target.
1228fe95356dd487a79145ec07a9f46cd743b4c9bddJim Grosbach    virtual bool hasCustomConstantPool() const { return false; }
123b0b53491ef32b85bd90c8590faeb8a3fb4b17a95Evan Cheng
12447c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng    /// hasCustomJumpTables - Allows a target to specify that jumptables
12547c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng    /// are emitted by the target.
12647c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng    virtual bool hasCustomJumpTables() const { return false; }
12747c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng
128b0b53491ef32b85bd90c8590faeb8a3fb4b17a95Evan Cheng    /// allocateSeparateGVMemory - If true, globals should be placed in
129b0b53491ef32b85bd90c8590faeb8a3fb4b17a95Evan Cheng    /// separately allocated heap memory rather than in the same
130a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    /// code memory allocated by JITCodeEmitter.
131b0b53491ef32b85bd90c8590faeb8a3fb4b17a95Evan Cheng    virtual bool allocateSeparateGVMemory() const { return false; }
1326a6b2dbd3a6786c6ef3d79a0b685291631245d32Andrew Lenharth  protected:
1336a6b2dbd3a6786c6ef3d79a0b685291631245d32Andrew Lenharth    bool useGOT;
1341e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner  };
1351e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner} // End llvm namespace
1361e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner
1371e60a9165dc4d6ce5650dacc026f2942696af920Chris Lattner#endif
138