PageRenderTime 389ms CodeModel.GetById 205ms app.highlight 17ms RepoModel.GetById 164ms app.codeStats 0ms

/JIT/llvm_state.h

http://unladen-swallow.googlecode.com/
C++ Header | 217 lines | 144 code | 29 blank | 44 comment | 5 complexity | d4a53824d4d3cdcd7db8d198a7375a96 MD5 | raw file
  1// -*- C++ -*-
  2#ifndef PYTHON_LLVM_STATE_H
  3#define PYTHON_LLVM_STATE_H
  4
  5#ifndef __cplusplus
  6#error This header expects to be included only in C++ source
  7#endif
  8
  9#include "Util/EventTimer.h"
 10
 11#include "JIT/PyTypeBuilder.h"
 12#include "llvm/ADT/Twine.h"
 13#include "llvm/Analysis/DebugInfo.h"
 14#include "llvm/Constants.h"
 15#include "llvm/ExecutionEngine/ExecutionEngine.h"
 16#include "llvm/GlobalVariable.h"
 17#include "llvm/Support/IRBuilder.h"
 18#include "llvm/Support/TargetFolder.h"
 19#include "llvm/Type.h"
 20
 21struct PyCodeObject;
 22struct PyGlobalLlvmData;
 23
 24namespace py {
 25
 26llvm::CallInst *
 27TransferAttributes(llvm::CallInst *callsite, const llvm::Value* callee);
 28
 29// LlvmFunctionState contains objects which must only be created once
 30// for every LLVM function. A compiled python function may contain
 31// code from more than one code object.
 32class LlvmFunctionState {
 33    LlvmFunctionState(const LlvmFunctionState &);
 34    void operator=(const LlvmFunctionState &);
 35public:
 36    LlvmFunctionState(PyGlobalLlvmData *global_data, PyCodeObject *code);
 37
 38    llvm::Function *function() { return function_; }
 39    typedef llvm::IRBuilder<true, llvm::TargetFolder> BuilderT;
 40    BuilderT& builder() { return builder_; }
 41    llvm::LLVMContext& context() { return this->context_; }
 42    llvm::Module *module() const { return this->module_; }
 43    PyGlobalLlvmData *llvm_data() const { return this->llvm_data_; }
 44
 45    // Copies the elements from array[0] to array[N-1] to target, bytewise.
 46    void MemCpy(llvm::Value *target, llvm::Value *array, llvm::Value *N);
 47
 48    template<typename T>
 49    llvm::Constant *GetSigned(int64_t val) {
 50        return llvm::ConstantInt::getSigned(
 51             PyTypeBuilder<T>::get(this->context_), val);
 52    }
 53
 54    /// Get the LLVM NULL Value for the given type.
 55    template<typename T>
 56    llvm::Value *GetNull()
 57    {
 58        return llvm::Constant::getNullValue(
 59            PyTypeBuilder<T>::get(this->context_));
 60    }
 61
 62    /// Convenience wrapper for creating named basic blocks using the current
 63    /// context and function.
 64    llvm::BasicBlock *CreateBasicBlock(const llvm::Twine &name);
 65
 66    /// These two functions increment or decrement the reference count
 67    /// of a PyObject*. The behavior is undefined if the Value's type
 68    /// isn't PyObject* or a subclass.
 69    void IncRef(llvm::Value *value);
 70    void DecRef(llvm::Value *value);
 71    void XDecRef(llvm::Value *value);
 72
 73    // These are just like the CreateCall* calls on IRBuilder, except they also
 74    // apply callee's calling convention and attributes to the call site.
 75    llvm::CallInst *CreateCall(llvm::Value *callee,
 76                               const char *name = "");
 77    llvm::CallInst *CreateCall(llvm::Value *callee,
 78                               llvm::Value *arg1,
 79                               const char *name = "");
 80    llvm::CallInst *CreateCall(llvm::Value *callee,
 81                               llvm::Value *arg1,
 82                               llvm::Value *arg2,
 83                               const char *name = "");
 84    llvm::CallInst *CreateCall(llvm::Value *callee,
 85                               llvm::Value *arg1,
 86                               llvm::Value *arg2,
 87                               llvm::Value *arg3,
 88                               const char *name = "");
 89    llvm::CallInst *CreateCall(llvm::Value *callee,
 90                               llvm::Value *arg1,
 91                               llvm::Value *arg2,
 92                               llvm::Value *arg3,
 93                               llvm::Value *arg4,
 94                               const char *name = "");
 95    template<typename InputIterator>
 96    llvm::CallInst *CreateCall(llvm::Value *callee,
 97                               InputIterator begin,
 98                               InputIterator end,
 99                               const char *name = "")
100    {
101        llvm::CallInst *call =
102            this->builder().CreateCall(callee, begin, end, name);
103        return TransferAttributes(call, callee);
104    }
105
106    // Returns the global variable with type T, address 'var_address',
107    // and name 'name'.  If the ExecutionEngine already knows of a
108    // variable with the given address, we name and return it.
109    // Otherwise the variable will be looked up in Python's C runtime.
110    template<typename VariableType>
111    llvm::Constant *GetGlobalVariable(
112        void *var_address, const std::string &name);
113
114    // Returns the global function with type T and name 'name'. The
115    // function will be looked up in Python's C runtime.
116    template<typename FunctionType>
117    llvm::Function *GetGlobalFunction(const std::string &name)
118    {
119        return llvm::cast<llvm::Function>(
120            this->module()->getOrInsertFunction(name,
121                PyTypeBuilder<FunctionType>::get(this->context_)));
122    }
123
124    // Returns a global variable that represents 'obj'.  These get
125    // cached in the ExecutionEngine's global mapping table, and they
126    // incref the object so its address doesn't get re-used while the
127    // GlobalVariable is still alive.  See JIT/ConstantMirror.h for
128    // more details.  Use this in preference to GetGlobalVariable()
129    // for PyObjects that may be immutable.
130    llvm::Constant *GetGlobalVariableFor(PyObject *obj);
131
132    // Returns an i1, true if value represents a NULL pointer.
133    llvm::Value *IsNull(llvm::Value *value);
134    // Returns an i1, true if value is a negative integer.
135    llvm::Value *IsNegative(llvm::Value *value);
136    // Returns an i1, true if value is a non-zero integer.
137    llvm::Value *IsNonZero(llvm::Value *value);
138    // Returns an i1, true if value is a positive (>0) integer.
139    llvm::Value *IsPositive(llvm::Value *value);
140    // Returns an i1, true if value is an instance of the class
141    // represented by the flag argument.  flag should be something
142    // like Py_TPFLAGS_INT_SUBCLASS.
143    llvm::Value *IsInstanceOfFlagClass(llvm::Value *value, int flag);
144
145    /// Implements something like the C assert statement.  If
146    /// should_be_true (an i1) is false, prints failure_message (with
147    /// puts) and aborts.  Compiles to nothing in optimized mode.
148    void Assert(llvm::Value *should_be_true,
149                const std::string &failure_message);
150
151    /// Prints failure_message (with puts) and aborts.
152    void Abort(const std::string &failure_message);
153
154    // Get the address of the idx'th item in a list or tuple object.
155    llvm::Value *GetListItemSlot(llvm::Value *lst, int idx);
156    llvm::Value *GetTupleItemSlot(llvm::Value *tup, int idx);
157
158#ifdef WITH_TSC
159    // Emit code to record a given event with the TSC EventTimer.h system.
160    void LogTscEvent(_PyTscEventId event_id);
161#endif
162
163    // Create an alloca in the entry block, so that LLVM can optimize
164    // it more easily, and return the resulting address. The signature
165    // matches IRBuilder.CreateAlloca()'s.
166    llvm::Value *CreateAllocaInEntryBlock(
167        const llvm::Type *alloca_type,
168        llvm::Value *array_size,
169        const char *name);
170
171    /// Embed a pointer of some type directly into the LLVM IR.
172    template <typename T>
173    llvm::Value *EmbedPointer(void *ptr)
174    {
175        // We assume that the caller has ensured that ptr will stay live for the
176        // life of this native code object.
177        return this->builder_.CreateIntToPtr(
178            llvm::ConstantInt::get(llvm::Type::getInt64Ty(this->context_),
179                             reinterpret_cast<intptr_t>(ptr)),
180            PyTypeBuilder<T>::get(this->context_));
181    }
182
183private:
184    PyGlobalLlvmData *const llvm_data_;
185    llvm::LLVMContext &context_;
186    llvm::Module *const module_;
187
188    llvm::Function *const function_;
189    BuilderT builder_;
190};
191
192template<typename VariableType> llvm::Constant *
193LlvmFunctionState::GetGlobalVariable(void *var_address, const std::string &name)
194{
195    const llvm::Type *expected_type =
196        PyTypeBuilder<VariableType>::get(this->context_);
197    if (llvm::GlobalVariable *global = this->module_->getNamedGlobal(name)) {
198        assert (expected_type == global->getType()->getElementType());
199        return global;
200    }
201    if (llvm::GlobalValue *global = const_cast<llvm::GlobalValue*>(
202            this->llvm_data_->getExecutionEngine()->
203            getGlobalValueAtAddress(var_address))) {
204        assert (expected_type == global->getType()->getElementType());
205        if (!global->hasName())
206            global->setName(name);
207        return global;
208    }
209    return new llvm::GlobalVariable(*this->module_, expected_type,
210                                    /*isConstant=*/false,
211                                    llvm::GlobalValue::ExternalLinkage,
212                                    NULL, name);
213}
214
215}  // namespace py
216
217#endif  // PYTHON_LLVM_STATE_H