Add target machine

This commit is contained in:
Siu Kwan Lam 2012-08-14 12:04:28 -07:00
commit ec71908874
7 changed files with 124 additions and 9 deletions

View file

@ -993,6 +993,43 @@ _wrap_pass( UnifyFunctionExitNodes )
_wrap_pass( Internalize2 )
*/
/*===----------------------------------------------------------------------===*/
/* Target Machine */
/*===----------------------------------------------------------------------===*/
_wrap_obj2obj(LLVMTargetMachineFromEngineBuilder, LLVMEngineBuilderRef,
LLVMTargetMachineRef)
_wrap_obj2none(LLVMDisposeTargetMachine, LLVMTargetMachineRef)
static PyObject *
_wLLVMTargetMachineEmitFile(PyObject * self, PyObject * args)
{
PyObject * ret;
unsigned len;
unsigned char * bytes;
LLVMTargetMachineRef tm;
LLVMModuleRef m;
PyObject *arg_tm, *arg_m;
int arg_use_asm;
if (!PyArg_ParseTuple(args, "OOi", &arg_tm, &arg_m, &arg_use_asm))
return NULL;
tm = (LLVMTargetMachineRef) PyCapsule_GetPointer(arg_tm, NULL);
m = (LLVMModuleRef) PyCapsule_GetPointer(arg_m, NULL);
if ( !(bytes = LLVMTargetMachineEmitFile(tm, m, arg_use_asm, &len)) )
Py_RETURN_NONE;
ret = PyBytes_FromStringAndSize((char *)bytes, (Py_ssize_t)len);
delete [] bytes;
return ret;
}
/*===----------------------------------------------------------------------===*/
/* Target Data */
/*===----------------------------------------------------------------------===*/
@ -1835,6 +1872,11 @@ static PyMethodDef core_methods[] = {
_pass( Internalize2 )
*/
/* Target Machine */
_method( LLVMTargetMachineFromEngineBuilder )
_method( LLVMDisposeTargetMachine )
_method( LLVMTargetMachineEmitFile )
/* Target Data */
_method( LLVMCreateTargetData )
_method( LLVMDisposeTargetData )

View file

@ -293,3 +293,31 @@ class ExecutionEngine(object):
td._own(self)
return td
#===----------------------------------------------------------------------===
# Target machine
#===----------------------------------------------------------------------===
class TargetMachine(object):
@staticmethod
def from_engine_builder(eb):
'''Construct a TargetMachine from an EngineBuilder
'''
ptr = _core.LLVMTargetMachineFromEngineBuilder(eb.ptr)
return TargetMachine(ptr)
def __init__(self, ptr):
self.ptr = ptr
def __del__(self):
_core.LLVMDisposeTargetMachine(self.ptr)
def emit_assembly(self, module):
'''returns byte string of the module as assembly code of the target machine
'''
return _core.LLVMTargetMachineEmitFile(self.ptr, module.ptr, True)
def emit_object(self, module):
'''returns byte string of the module as assembly code of the target machine
'''
return _core.LLVMTargetMachineEmitFile(self.ptr, module.ptr, False)

View file

@ -84,6 +84,7 @@
namespace llvm{
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(EngineBuilder, LLVMEngineBuilderRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
}
/*
* For use in LLVMDumpPasses to dump passes.
@ -113,15 +114,29 @@ char *do_print(W obj)
return strdup(buf.str().c_str());
}
unsigned char* LLVMGetNativeCodeFromModule(LLVMModuleRef module, int assembly,
unsigned * lenp)
LLVMTargetMachineRef LLVMTargetMachineFromEngineBuilder(LLVMEngineBuilderRef eb)
{
using namespace llvm;
TargetMachine * tm = unwrap(eb)->selectTarget();
return wrap(tm);
}
void LLVMDisposeTargetMachine(LLVMTargetMachineRef tm){
delete llvm::unwrap(tm);
}
unsigned char* LLVMTargetMachineEmitFile(LLVMTargetMachineRef tmref,
LLVMModuleRef modref,
int assembly, unsigned * lenp)
{
using namespace llvm;
assert(lenp);
InitializeNativeTargetAsmPrinter();
Module *modulep = unwrap(module);
Module *modulep = unwrap(modref);
assert(modulep);
// get objectcode into a string
@ -130,17 +145,15 @@ unsigned char* LLVMGetNativeCodeFromModule(LLVMModuleRef module, int assembly,
formatted_raw_ostream fso(buf);
TargetMachine * tm = EngineBuilder(modulep).selectTarget();
TargetMachine * tm = unwrap(tmref);
PassManager pm;
if (!tm->getTargetData()){
printf("No target data in target machine");
fprintf(stderr, "No target data in target machine");
return NULL;
}
//printf("%s\n", modulep->getDataLayout().c_str());
pm.add(new TargetData(*tm->getTargetData()));
bool failed;
@ -151,8 +164,8 @@ unsigned char* LLVMGetNativeCodeFromModule(LLVMModuleRef module, int assembly,
}
if ( failed ) {
printf("No support\n");
printf("%s\n", tm->getTargetData()->getStringRepresentation().c_str());
fprintf(stderr, "No support\n");
fprintf(stderr, "%s\n", tm->getTargetData()->getStringRepresentation().c_str());
return NULL;
}
@ -177,6 +190,21 @@ unsigned char* LLVMGetNativeCodeFromModule(LLVMModuleRef module, int assembly,
return bytes;
}
unsigned char* LLVMGetNativeCodeFromModule(LLVMModuleRef module, int assembly,
unsigned * lenp)
{
using namespace llvm;
assert(lenp);
Module *modulep = unwrap(module);
assert(modulep);
// select native default machine
TargetMachine * tm = EngineBuilder(modulep).selectTarget();
return LLVMTargetMachineEmitFile(wrap(tm), module, assembly, lenp);
}
static
llvm::AtomicOrdering atomic_ordering_from_string(const char * ordering)

View file

@ -45,6 +45,20 @@
extern "C" {
#endif
/*
* Wraps EngineBuilder::selectTarget
*/
LLVMTargetMachineRef LLVMTargetMachineFromEngineBuilder(LLVMEngineBuilderRef eb);
/*
* Wraps operator delete
*/
void LLVMDisposeTargetMachine(LLVMTargetMachineRef tm);
unsigned char* LLVMTargetMachineEmitFile(LLVMTargetMachineRef tmref,
LLVMModuleRef modref,
int assembly, unsigned * lenp);
/*
* Wraps TargetMachine::addPassesToEmitFile
*/

View file

@ -19,6 +19,7 @@ inline ref wrap(const ty *P) { \
}
typedef struct LLVMOpaqueEngineBuilder *LLVMEngineBuilderRef;
typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef;
#ifdef __cplusplus

View file

@ -60,6 +60,7 @@ _define_std_ctor(LLVMGenericValueRef)
_define_std_ctor(LLVMPassManagerBuilderRef)
_define_std_ctor(LLVMEngineBuilderRef)
_define_std_ctor(LLVMTargetMachineRef)
PyObject *ctor_int(int i)
{

View file

@ -93,6 +93,7 @@ _declare_std_ctor(LLVMGenericValueRef)
// extra LLVM classes
_declare_std_ctor(LLVMPassManagerBuilderRef)
_declare_std_ctor(LLVMEngineBuilderRef)
_declare_std_ctor(LLVMTargetMachineRef)
/* standard types */
_declare_std_ctor(int)