PageRenderTime 347ms CodeModel.GetById 100ms app.highlight 156ms RepoModel.GetById 86ms app.codeStats 0ms

/Objects/_llvmfunctionobject.cc

http://unladen-swallow.googlecode.com/
C++ | 354 lines | 274 code | 39 blank | 41 comment | 28 complexity | b462ede15959cbea5b7b82259526466e MD5 | raw file
  1// Definition of _llvmfunction, the llvm::Function wrapper.
  2
  3#include "Python.h"
  4#include "_llvmfunctionobject.h"
  5
  6#include "frameobject.h"
  7#include "structmember.h"
  8#include "JIT/global_llvm_data.h"
  9#include "Util/Stats.h"
 10
 11#include "llvm/BasicBlock.h"
 12#include "llvm/Constants.h"
 13#include "llvm/Function.h"
 14#include "llvm/Instructions.h"
 15#include "llvm/Module.h"
 16#include "llvm/ADT/SmallPtrSet.h"
 17#include "llvm/CodeGen/MachineCodeInfo.h"
 18#include "llvm/ExecutionEngine/ExecutionEngine.h"
 19#include "llvm/Support/Casting.h"
 20#include "llvm/Support/ManagedStatic.h"
 21#include "llvm/Support/ValueHandle.h"
 22#include "llvm/Support/raw_ostream.h"
 23
 24#include <sstream>
 25#include <string>
 26#include <vector>
 27
 28using llvm::BasicBlock;
 29using llvm::Function;
 30using llvm::Type;
 31using llvm::Value;
 32
 33struct _LlvmFunction {
 34    // This should be an AssertingVH, but that runs into problems on
 35    // shutdown, where the Module is destroyed without destroying all
 36    // code objects first.
 37    Function *lf_function;
 38};
 39
 40#ifdef Py_WITH_INSTRUMENTATION
 41// Collect statistics about the number of lines of LLVM IR we're writing,
 42// and the amount of native code that translates to. Even if we're not changing
 43// the amount of generated native code, reducing the number of LLVM IR lines
 44// helps compilation time.
 45class NativeSizeStats : public DataVectorStats<size_t> {
 46public:
 47    NativeSizeStats() : DataVectorStats<size_t>("Native code size in bytes") {}
 48};
 49
 50class LlvmIrSizeStats : public DataVectorStats<size_t> {
 51public:
 52    LlvmIrSizeStats() : DataVectorStats<size_t>("LLVM IR size in lines") {}
 53};
 54
 55// Count the number of non-blank lines of LLVM IR for the given function.
 56static size_t
 57count_ir_lines(llvm::Function *const function)
 58{
 59    size_t result = 1;  // Function's 'define' line.
 60    for (llvm::Function::iterator bb = function->begin(),
 61         bb_end = function->end(); bb != bb_end; ++bb) {
 62        ++result;  // 'bb_name:' line.
 63        for (llvm::BasicBlock::iterator inst = bb->begin(),
 64             inst_end = bb->end(); inst != inst_end; ++inst) {
 65            ++result;
 66        }
 67    }
 68    return result;
 69}
 70
 71static llvm::ManagedStatic<NativeSizeStats> native_size_stats;
 72static llvm::ManagedStatic<LlvmIrSizeStats> llvm_ir_size_stats;
 73#endif  // Py_WITH_INSTRUMENTATION
 74
 75_LlvmFunction *
 76_LlvmFunction_New(void *llvm_function)
 77{
 78    llvm::Function *typed_function = (llvm::Function*)llvm_function;
 79    _LlvmFunction *wrapper = new _LlvmFunction();
 80    wrapper->lf_function = typed_function;
 81    return wrapper;
 82}
 83
 84void
 85_LlvmFunction_Dealloc(_LlvmFunction *functionobj)
 86{
 87    llvm::Function *function = functionobj->lf_function;
 88    // Clear the AssertingVH to avoid crashing when we delete the function.
 89    functionobj->lf_function = NULL;
 90    // Allow global optimizations to destroy the function.
 91    function->setLinkage(llvm::GlobalValue::InternalLinkage);
 92    if (function->use_empty()) {
 93        // Delete the function if it's already unused.
 94        function->eraseFromParent();
 95    }
 96    delete functionobj;
 97}
 98
 99// Deletes most of the contents of function but keeps all references
100// to global variables so they don't get destroyed by globaldce.
101static void
102clear_body(llvm::Function *function)
103{
104    // Gather all the pieces of *function that could be or use globals.
105    llvm::SmallPtrSet<Value*, 8> globals;
106    // For all basic blocks...
107    for (Function::iterator BB = function->begin(), E = function->end();
108         BB != E; ++BB)
109        // For all instructions...
110        for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
111            // For all operands...
112            for (llvm::User::op_iterator U = I->op_begin(), E = I->op_end();
113                 U != E; ++U) {
114                // We could recursively iterate through the Constants
115                // too to find their component GlobalValues, but since
116                // Constants are immortal anyway that doesn't seem
117                // worth it.  GlobalValues are Constants, so this
118                // picks them up too.
119                if (llvm::isa<llvm::Constant>(*U))
120                    globals.insert(*U);
121            }
122    const std::vector<Value*> globals_vect(globals.begin(), globals.end());
123
124    // Clear out the function now that we know what it uses.
125    function->deleteBody();
126
127    BasicBlock *entry =
128        BasicBlock::Create(function->getContext(), "", function);
129
130    // Build a single "call void undef(all_constants)" instruction to
131    // keep a use of all the constants.
132    std::vector<const Type*> types;
133    types.reserve(globals_vect.size());
134    for (std::vector<Value*>::const_iterator C = globals_vect.begin(),
135             E = globals_vect.end(); C != E; ++C)
136        types.push_back((*C)->getType());
137    const llvm::FunctionType *user_t = llvm::FunctionType::get(
138        Type::getVoidTy(function->getContext()), types, false);
139    llvm::CallInst::Create(
140        llvm::UndefValue::get(llvm::PointerType::getUnqual(user_t)),
141        globals_vect.begin(), globals_vect.end(), "", entry);
142}
143
144PyEvalFrameFunction
145_LlvmFunction_Jit(_LlvmFunction *function_obj)
146{
147    llvm::Function *function = (llvm::Function *)function_obj->lf_function;
148    PyGlobalLlvmData *global_llvm_data =
149        PyThreadState_GET()->interp->global_llvm_data;
150    llvm::ExecutionEngine *engine = global_llvm_data->getExecutionEngine();
151
152    PyEvalFrameFunction native_func;
153#ifdef Py_WITH_INSTRUMENTATION
154    llvm::MachineCodeInfo code_info;
155    engine->runJITOnFunction(function, &code_info);
156    native_size_stats->RecordDataPoint(code_info.size());
157
158    size_t llvm_ir_lines = count_ir_lines(function);
159    llvm_ir_size_stats->RecordDataPoint(llvm_ir_lines);
160    // TODO(jyasskin): code_info.address() doesn't work for some reason.
161    void *func = engine->getPointerToGlobalIfAvailable(function);
162    assert(func && "function not installed in the globals");
163    native_func = (PyEvalFrameFunction)func;
164#else
165    native_func = (PyEvalFrameFunction)engine->getPointerToFunction(function);
166#endif
167    // Clear the function body to reduce memory usage. This means we'll
168    // need to re-compile the bytecode to IR and reoptimize it again, if we
169    // need it again.
170    clear_body(function);
171    return native_func;
172}
173
174int
175_LlvmFunction_Optimize(PyGlobalLlvmData *global_data,
176                       _LlvmFunction *llvm_function,
177                       int level)
178{
179    return global_data->Optimize(*llvm_function->lf_function, level);
180}
181
182// Python-level wrapper.
183struct PyLlvmFunctionObject {
184public:
185    PyObject_HEAD
186    PyCodeObject *code_object;  // Hold a reference to the PyCodeObject.
187};
188
189PyObject *
190_PyLlvmFunction_FromCodeObject(PyObject *co)
191{
192    PyLlvmFunctionObject *result =
193        PyObject_NEW(PyLlvmFunctionObject, &PyLlvmFunction_Type);
194    if (result == NULL) {
195        return NULL;
196    }
197    Py_INCREF(co);
198    result->code_object = (PyCodeObject *)co;
199
200    return (PyObject *)result;
201}
202
203static llvm::Function *
204_PyLlvmFunction_GetFunction(PyLlvmFunctionObject *llvm_function)
205{
206    PyCodeObject *code = llvm_function->code_object;
207    return (llvm::Function *)code->co_llvm_function->lf_function;
208}
209
210PyDoc_STRVAR(llvmfunction_doc,
211"_llvmfunction()\n\
212\n\
213A wrapper around an llvm::Function object. Can only be created from\n\
214existing _llvmmodule objects.");
215
216static void
217llvmfunction_dealloc(PyLlvmFunctionObject *functionobj)
218{
219    Py_DECREF(functionobj->code_object);
220}
221
222static _LlvmFunction *
223recompile(PyLlvmFunctionObject *functionobj)
224{
225    // We clear out all llvm::Functions after emitting machine code for
226    // them. Compile the code object back to IR, then throw that IR away. We
227    // assume that people aren't printing out code objects in tight loops.
228    PyCodeObject *code = functionobj->code_object;
229    _LlvmFunction *cur_function = code->co_llvm_function;
230    int cur_opt_level = code->co_optimization;
231    // Null these out to trick _PyCode_ToOptimizedLlvmIr() into recompiling
232    // this function, then restore the original values when we're done.
233    // TODO(collinwinter): this approach is suboptimal.
234    code->co_llvm_function = NULL;
235    code->co_optimization = 0;
236
237    int ret = _PyCode_ToOptimizedLlvmIr(code, cur_opt_level);
238    _LlvmFunction *new_function = code->co_llvm_function;
239    code->co_llvm_function = cur_function;
240    code->co_optimization = cur_opt_level;
241    // The only way we could have rejected compilation is if the code
242    // object changed. I don't know how this could happen, but Python has
243    // surprised me before.
244    if (ret == 1) {  // Compilation rejected.
245      PyErr_BadInternalCall();
246      return NULL;
247    }
248    else if (ret == -1)  // Error during compilation.
249      return NULL;
250
251    return new_function;
252}
253
254static PyObject *
255llvmfunction_str(PyLlvmFunctionObject *function_obj)
256{
257    std::string result;
258    llvm::raw_string_ostream wrapper(result);
259
260    _LlvmFunction *new_function = recompile(function_obj);
261    if (new_function == NULL) {
262        return NULL;
263    }
264    llvm::Function *func = (llvm::Function *)new_function->lf_function;
265    func->print(wrapper);
266    _LlvmFunction_Dealloc(new_function);
267
268    wrapper.flush();
269    return PyString_FromStringAndSize(result.data(), result.size());
270}
271
272static PyObject *
273func_view_cfg(PyLlvmFunctionObject *function_obj)
274{
275    _LlvmFunction *new_function = recompile(function_obj);
276    if (new_function == NULL) {
277        return NULL;
278    }
279    llvm::Function *func = (llvm::Function *)new_function->lf_function;
280    func->viewCFG();
281    _LlvmFunction_Dealloc(new_function);
282    Py_RETURN_NONE;
283}
284
285static PyObject *
286func_get_module(PyLlvmFunctionObject *op)
287{
288    llvm::Module *module = _PyLlvmFunction_GetFunction(op)->getParent();
289    if (module == NULL) {
290        PyErr_BadInternalCall();
291        return NULL;
292    }
293
294    std::string result;
295    llvm::raw_string_ostream wrapper(result);
296    module->print(wrapper, NULL /* No extra annotations in the output */);
297    wrapper.flush();
298
299    return PyString_FromStringAndSize(result.data(),
300                                      result.size());
301}
302
303static PyMethodDef llvmfunction_methods[] = {
304    {"view_cfg",  (PyCFunction)func_view_cfg, METH_NOARGS,
305     "View the CFG for this function."},
306    {NULL, NULL, 0, NULL}        /* Sentinel */
307};
308
309static PyGetSetDef llvmfunction_getsetlist[] = {
310    {"module", (getter)func_get_module, NULL},
311    {NULL, NULL, NULL},
312};
313
314// PyType_Ready is called on this in global_llvm_data.cc:_PyLlvm_Init().
315PyTypeObject PyLlvmFunction_Type = {
316	PyVarObject_HEAD_INIT(&PyType_Type, 0)
317	"_llvmfunction",
318	sizeof(PyLlvmFunctionObject),
319	0,
320	(destructor)llvmfunction_dealloc,   /* tp_dealloc */
321	0,				/* tp_print */
322	0, 				/* tp_getattr */
323	0,				/* tp_setattr */
324	0,				/* tp_compare */
325	0,				/* tp_repr */
326	0,				/* tp_as_number */
327	0,				/* tp_as_sequence */
328	0,				/* tp_as_mapping */
329	0,				/* tp_hash */
330	0,				/* tp_call */
331	(reprfunc)llvmfunction_str,	/* tp_str */
332	PyObject_GenericGetAttr,	/* tp_getattro */
333	0,				/* tp_setattro */
334	0,				/* tp_as_buffer */
335	Py_TPFLAGS_DEFAULT,		/* tp_flags */
336	llvmfunction_doc,		/* tp_doc */
337	0,				/* tp_traverse */
338	0,				/* tp_clear */
339	0,				/* tp_richcompare */
340	0,				/* tp_weaklistoffset */
341	0,				/* tp_iter */
342	0,				/* tp_iternext */
343	llvmfunction_methods,		/* tp_methods */
344	0,				/* tp_members */
345	llvmfunction_getsetlist,	/* tp_getset */
346	0,				/* tp_base */
347	0,				/* tp_dict */
348	0,				/* tp_descr_get */
349	0,				/* tp_descr_set */
350	0,				/* tp_dictoffset */
351	0,				/* tp_init */
352	0,				/* tp_alloc */
353	0,				/* tp_new */
354};