58273ae4616b9c9e6c77c143411b9b4af8be14d9
[oota-llvm.git] / include / llvm / ExecutionEngine / Orc / OrcTargetSupport.h
1 //===-- OrcTargetSupport.h - Code to support specific targets  --*- 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 // Target specific code for Orc, e.g. callback assembly.
11 //
12 // Target classes should be part of the JIT *target* process, not the host
13 // process (except where you're doing hosted JITing and the two are one and the
14 // same).
15 //
16 //===----------------------------------------------------------------------===//
17
18 #ifndef LLVM_EXECUTIONENGINE_ORC_ORCTARGETSUPPORT_H
19 #define LLVM_EXECUTIONENGINE_ORC_ORCTARGETSUPPORT_H
20
21 #include "IndirectionUtils.h"
22 #include "llvm/Support/Memory.h"
23
24 namespace llvm {
25 namespace orc {
26
27 class OrcX86_64 {
28 public:
29   static const char *ResolverBlockName;
30
31   /// @brief Insert module-level inline callback asm into module M for the
32   /// symbols managed by JITResolveCallbackHandler J.
33   static void insertResolverBlock(Module &M,
34                                   JITCompileCallbackManagerBase &JCBM);
35
36   /// @brief Get a label name from the given index.
37   typedef std::function<std::string(unsigned)> LabelNameFtor;
38
39   /// @brief Insert the requested number of trampolines into the given module.
40   /// @param M Module to insert the call block into.
41   /// @param NumCalls Number of calls to create in the call block.
42   /// @param StartIndex Optional argument specifying the index suffix to start
43   ///                   with.
44   /// @return A functor that provides the symbol name for each entry in the call
45   ///         block.
46   ///
47   static LabelNameFtor insertCompileCallbackTrampolines(
48                                                     Module &M,
49                                                     TargetAddress TrampolineAddr,
50                                                     unsigned NumCalls,
51                                                     unsigned StartIndex = 0);
52
53   /// @brief Provide information about stub blocks generated by the
54   ///        makeIndirectStubsBlock function.
55   class IndirectStubsInfo {
56     friend class OrcX86_64;
57   public:
58     const static unsigned StubSize = 8;
59     const static unsigned PtrSize = 8;
60
61     IndirectStubsInfo() : NumStubs(0) {}
62     IndirectStubsInfo(IndirectStubsInfo &&Other)
63         : NumStubs(Other.NumStubs), StubsMem(std::move(Other.StubsMem)) {
64       Other.NumStubs = 0;
65     }
66     IndirectStubsInfo& operator=(IndirectStubsInfo &&Other) {
67       NumStubs = Other.NumStubs;
68       Other.NumStubs = 0;
69       StubsMem = std::move(Other.StubsMem);
70       return *this;
71     }
72
73     /// @brief Number of stubs in this block.
74     unsigned getNumStubs() const { return NumStubs; }
75
76     /// @brief Get a pointer to the stub at the given index, which must be in
77     ///        the range 0 .. getNumStubs() - 1.
78     void* getStub(unsigned Idx) const {
79       return static_cast<uint64_t*>(StubsMem.base()) + Idx;
80     }
81
82     /// @brief Get a pointer to the implementation-pointer at the given index,
83     ///        which must be in the range 0 .. getNumStubs() - 1.
84     void** getPtr(unsigned Idx) const {
85       char *PtrsBase =
86         static_cast<char*>(StubsMem.base()) + NumStubs * StubSize;
87       return reinterpret_cast<void**>(PtrsBase) + Idx;
88     }
89   private:
90     unsigned NumStubs;
91     sys::OwningMemoryBlock StubsMem;
92   };
93
94   /// @brief Emit at least MinStubs worth of indirect call stubs, rounded out to
95   ///        the nearest page size.
96   ///
97   ///   E.g. Asking for 4 stubs on x86-64, where stubs are 8-bytes, with 4k
98   /// pages will return a block of 512 stubs (4096 / 8 = 512). Asking for 513
99   /// will return a block of 1024 (2-pages worth).
100   static std::error_code emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,
101                                                 unsigned MinStubs,
102                                                 void *InitialPtrVal);
103 };
104
105 } // End namespace orc.
106 } // End namespace llvm.
107
108 #endif // LLVM_EXECUTIONENGINE_ORC_ORCTARGETSUPPORT_H