Merge branch 'master' of github.com:llvmpy/llvmpy
This commit is contained in:
commit
0b63bd7a9f
10 changed files with 465 additions and 34 deletions
112
llvm/_core.cpp
112
llvm/_core.cpp
|
|
@ -200,8 +200,11 @@ _wLLVMGetNativeCodeFromModule(PyObject * self, PyObject * args)
|
||||||
|
|
||||||
m = (LLVMModuleRef) PyCapsule_GetPointer(arg_m, NULL);
|
m = (LLVMModuleRef) PyCapsule_GetPointer(arg_m, NULL);
|
||||||
|
|
||||||
if ( !(bytes = LLVMGetNativeCodeFromModule(m, arg_use_asm, &len)) )
|
std::string error;
|
||||||
Py_RETURN_NONE;
|
bytes = LLVMGetNativeCodeFromModule(m, arg_use_asm, &len, error);
|
||||||
|
if ( !error.empty() ){
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, error.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
ret = PyBytes_FromStringAndSize((char *)bytes, (Py_ssize_t)len);
|
ret = PyBytes_FromStringAndSize((char *)bytes, (Py_ssize_t)len);
|
||||||
delete [] bytes;
|
delete [] bytes;
|
||||||
|
|
@ -888,16 +891,15 @@ _wrap_obj2none(LLVMDisposePassManager, LLVMPassManagerRef)
|
||||||
_wrap_none2str(LLVMDumpPasses)
|
_wrap_none2str(LLVMDumpPasses)
|
||||||
_wrap_objstr2obj(LLVMAddPassByName, LLVMPassManagerRef, int)
|
_wrap_objstr2obj(LLVMAddPassByName, LLVMPassManagerRef, int)
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
_wLLVMInitializePasses(PyObject * self, PyObject * args)
|
_wrap_none2none(LLVMInitializePasses)
|
||||||
{
|
|
||||||
if (!PyArg_ParseTuple(args, ""))
|
|
||||||
return NULL;
|
|
||||||
LLVMInitializePasses();
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
_wrap_none2obj(LLVMInitializeNativeTarget, int)
|
_wrap_none2obj(LLVMInitializeNativeTarget, int)
|
||||||
|
_wrap_none2obj(LLVMInitializeNativeTargetAsmPrinter, int)
|
||||||
|
_wrap_none2none(LLVMInitializePTXTarget)
|
||||||
|
_wrap_none2none(LLVMInitializePTXTargetInfo)
|
||||||
|
_wrap_none2none( LLVMInitializePTXTargetMC )
|
||||||
|
_wrap_none2none(LLVMInitializePTXAsmPrinter)
|
||||||
|
|
||||||
|
|
||||||
/*===----------------------------------------------------------------------===*/
|
/*===----------------------------------------------------------------------===*/
|
||||||
|
|
@ -993,6 +995,77 @@ _wrap_pass( UnifyFunctionExitNodes )
|
||||||
|
|
||||||
_wrap_pass( Internalize2 )
|
_wrap_pass( Internalize2 )
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*===----------------------------------------------------------------------===*/
|
||||||
|
/* Target Machine */
|
||||||
|
/*===----------------------------------------------------------------------===*/
|
||||||
|
|
||||||
|
_wrap_obj2obj(LLVMTargetMachineFromEngineBuilder, LLVMEngineBuilderRef,
|
||||||
|
LLVMTargetMachineRef)
|
||||||
|
_wrap_obj2none(LLVMDisposeTargetMachine, LLVMTargetMachineRef)
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
_wLLVMTargetMachineLookup(PyObject * self, PyObject * args)
|
||||||
|
{
|
||||||
|
const char *arch;
|
||||||
|
const char *cpu;
|
||||||
|
const char *features;
|
||||||
|
int opt;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "sssi", &arch, &cpu, &features, &opt))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
std::string error;
|
||||||
|
LLVMTargetMachineRef tm = LLVMTargetMachineLookup(arch, cpu, features, opt,
|
||||||
|
error);
|
||||||
|
if(!error.empty()){
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, error.c_str());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return ctor_LLVMTargetMachineRef(tm);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
std::string error;
|
||||||
|
bytes = LLVMTargetMachineEmitFile(tm, m, arg_use_asm, &len, error);
|
||||||
|
if ( !error.empty() ){
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, error.c_str());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = PyBytes_FromStringAndSize((char *)bytes, (Py_ssize_t)len);
|
||||||
|
delete [] bytes;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
_wrap_obj2obj(LLVMTargetMachineGetTargetData, LLVMTargetMachineRef,
|
||||||
|
LLVMTargetDataRef)
|
||||||
|
_wrap_obj2str(LLVMTargetMachineGetTargetName, LLVMTargetMachineRef)
|
||||||
|
_wrap_obj2str(LLVMTargetMachineGetTargetShortDescription, LLVMTargetMachineRef)
|
||||||
|
_wrap_obj2str(LLVMTargetMachineGetTriple, LLVMTargetMachineRef)
|
||||||
|
_wrap_obj2str(LLVMTargetMachineGetCPU, LLVMTargetMachineRef)
|
||||||
|
_wrap_obj2str(LLVMTargetMachineGetFS, LLVMTargetMachineRef)
|
||||||
|
_wrap_none2none(LLVMPrintRegisteredTargetsForVersion)
|
||||||
|
|
||||||
|
|
||||||
/*===----------------------------------------------------------------------===*/
|
/*===----------------------------------------------------------------------===*/
|
||||||
/* Target Data */
|
/* Target Data */
|
||||||
/*===----------------------------------------------------------------------===*/
|
/*===----------------------------------------------------------------------===*/
|
||||||
|
|
@ -1744,7 +1817,13 @@ static PyMethodDef core_methods[] = {
|
||||||
_method( LLVMDumpPasses )
|
_method( LLVMDumpPasses )
|
||||||
_method( LLVMAddPassByName )
|
_method( LLVMAddPassByName )
|
||||||
_method( LLVMInitializePasses )
|
_method( LLVMInitializePasses )
|
||||||
|
|
||||||
_method( LLVMInitializeNativeTarget )
|
_method( LLVMInitializeNativeTarget )
|
||||||
|
_method( LLVMInitializeNativeTargetAsmPrinter )
|
||||||
|
_method( LLVMInitializePTXTarget )
|
||||||
|
_method( LLVMInitializePTXTargetInfo )
|
||||||
|
_method( LLVMInitializePTXTargetMC )
|
||||||
|
_method( LLVMInitializePTXAsmPrinter )
|
||||||
|
|
||||||
/* Passes */
|
/* Passes */
|
||||||
|
|
||||||
|
|
@ -1835,6 +1914,19 @@ static PyMethodDef core_methods[] = {
|
||||||
_pass( Internalize2 )
|
_pass( Internalize2 )
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Target Machine */
|
||||||
|
_method( LLVMTargetMachineFromEngineBuilder )
|
||||||
|
_method( LLVMDisposeTargetMachine )
|
||||||
|
_method( LLVMTargetMachineLookup )
|
||||||
|
_method( LLVMTargetMachineEmitFile )
|
||||||
|
_method( LLVMTargetMachineGetTargetData )
|
||||||
|
_method( LLVMTargetMachineGetTargetName )
|
||||||
|
_method( LLVMTargetMachineGetTargetShortDescription )
|
||||||
|
_method( LLVMTargetMachineGetTriple )
|
||||||
|
_method( LLVMTargetMachineGetCPU )
|
||||||
|
_method( LLVMTargetMachineGetFS )
|
||||||
|
_method( LLVMPrintRegisteredTargetsForVersion )
|
||||||
|
|
||||||
/* Target Data */
|
/* Target Data */
|
||||||
_method( LLVMCreateTargetData )
|
_method( LLVMCreateTargetData )
|
||||||
_method( LLVMDisposeTargetData )
|
_method( LLVMDisposeTargetData )
|
||||||
|
|
|
||||||
10
llvm/core.py
10
llvm/core.py
|
|
@ -2143,5 +2143,13 @@ def inline_function(call):
|
||||||
#===----------------------------------------------------------------------===
|
#===----------------------------------------------------------------------===
|
||||||
if _core.LLVMInitializeNativeTarget():
|
if _core.LLVMInitializeNativeTarget():
|
||||||
raise llvm.LLVMException("No native target!?")
|
raise llvm.LLVMException("No native target!?")
|
||||||
|
if _core.LLVMInitializeNativeTargetAsmPrinter():
|
||||||
|
# should this be an optional feature?
|
||||||
|
# should user trigger the initialization?
|
||||||
|
raise llvm.LLVMException("No native asm printer!?")
|
||||||
|
|
||||||
|
if True: # use PTX
|
||||||
|
_core.LLVMInitializePTXTarget()
|
||||||
|
_core.LLVMInitializePTXTargetInfo()
|
||||||
|
_core.LLVMInitializePTXTargetMC()
|
||||||
|
_core.LLVMInitializePTXAsmPrinter()
|
||||||
|
|
|
||||||
77
llvm/ee.py
77
llvm/ee.py
|
|
@ -231,6 +231,12 @@ class EngineBuilder(object):
|
||||||
raise llvm.LLVMException(ret)
|
raise llvm.LLVMException(ret)
|
||||||
return ExecutionEngine(ret, self._module)
|
return ExecutionEngine(ret, self._module)
|
||||||
|
|
||||||
|
def select_target(self):
|
||||||
|
'''get the corresponding target machine
|
||||||
|
'''
|
||||||
|
ptr = _core.LLVMTargetMachineFromEngineBuilder(self.ptr)
|
||||||
|
return TargetMachine(ptr)
|
||||||
|
|
||||||
#===----------------------------------------------------------------------===
|
#===----------------------------------------------------------------------===
|
||||||
# Execution engine
|
# Execution engine
|
||||||
#===----------------------------------------------------------------------===
|
#===----------------------------------------------------------------------===
|
||||||
|
|
@ -293,3 +299,74 @@ class ExecutionEngine(object):
|
||||||
td._own(self)
|
td._own(self)
|
||||||
return td
|
return td
|
||||||
|
|
||||||
|
|
||||||
|
#===----------------------------------------------------------------------===
|
||||||
|
# Target machine
|
||||||
|
#===----------------------------------------------------------------------===
|
||||||
|
|
||||||
|
def print_registered_targets():
|
||||||
|
'''
|
||||||
|
Note: print directly to stdout
|
||||||
|
'''
|
||||||
|
_core.LLVMPrintRegisteredTargetsForVersion()
|
||||||
|
|
||||||
|
class TargetMachine(object):
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def lookup(arch, cpu='', features='', opt=2):
|
||||||
|
'''create a targetmachine given an architecture name
|
||||||
|
|
||||||
|
For a list of architectures,
|
||||||
|
use: `llc -help`
|
||||||
|
|
||||||
|
For a list of available CPUs,
|
||||||
|
use: `llvm-as < /dev/null | llc -march=xyz -mcpu=help`
|
||||||
|
|
||||||
|
For a list of available attributes (features),
|
||||||
|
use: `llvm-as < /dev/null | llc -march=xyz -mattr=help`
|
||||||
|
'''
|
||||||
|
ptr = _core.LLVMTargetMachineLookup(arch, cpu, features, opt)
|
||||||
|
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)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def target_data(self):
|
||||||
|
'''get target data of this machine
|
||||||
|
'''
|
||||||
|
ptr = _core.LLVMTargetMachineGetTargetData(self.ptr)
|
||||||
|
return TargetData(ptr)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def target_name(self):
|
||||||
|
return _core.LLVMTargetMachineGetTargetName(self.ptr)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def target_short_description(self):
|
||||||
|
return _core.LLVMTargetMachineGetTargetShortDescription(self.ptr)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def triple(self):
|
||||||
|
return _core.LLVMTargetMachineGetTriple(self.ptr)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def cpu(self):
|
||||||
|
return _core.LLVMTargetMachineGetCPU(self.ptr)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_string(self):
|
||||||
|
return _core.LLVMTargetMachineGetFS(self.ptr)
|
||||||
|
|
|
||||||
164
llvm/extra.cpp
164
llvm/extra.cpp
|
|
@ -54,6 +54,7 @@
|
||||||
#include "llvm/Support/CallSite.h"
|
#include "llvm/Support/CallSite.h"
|
||||||
#include "llvm/Support/FormattedStream.h"
|
#include "llvm/Support/FormattedStream.h"
|
||||||
#include "llvm/Target/TargetData.h"
|
#include "llvm/Target/TargetData.h"
|
||||||
|
#include "llvm/Support/TargetRegistry.h"
|
||||||
#include "llvm/Support/TargetSelect.h"
|
#include "llvm/Support/TargetSelect.h"
|
||||||
|
|
||||||
#include "llvm/IntrinsicInst.h"
|
#include "llvm/IntrinsicInst.h"
|
||||||
|
|
@ -84,6 +85,7 @@
|
||||||
|
|
||||||
namespace llvm{
|
namespace llvm{
|
||||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(EngineBuilder, LLVMEngineBuilderRef)
|
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(EngineBuilder, LLVMEngineBuilderRef)
|
||||||
|
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* For use in LLVMDumpPasses to dump passes.
|
* For use in LLVMDumpPasses to dump passes.
|
||||||
|
|
@ -113,15 +115,96 @@ char *do_print(W obj)
|
||||||
return strdup(buf.str().c_str());
|
return strdup(buf.str().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char* LLVMGetNativeCodeFromModule(LLVMModuleRef module, int assembly,
|
namespace {
|
||||||
unsigned * lenp)
|
using namespace llvm;
|
||||||
|
const CodeGenOpt::Level OptLevelMap[] = {
|
||||||
|
CodeGenOpt::None,
|
||||||
|
CodeGenOpt::Less,
|
||||||
|
CodeGenOpt::Default,
|
||||||
|
CodeGenOpt::Aggressive,
|
||||||
|
};
|
||||||
|
} // end anony namespace
|
||||||
|
|
||||||
|
|
||||||
|
int LLVMInitializeNativeTargetAsmPrinter()
|
||||||
|
{
|
||||||
|
return llvm::InitializeNativeTargetAsmPrinter();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LLVMTargetMachineRef LLVMTargetMachineLookup(const char *arch, const char *cpu,
|
||||||
|
const char *features, int opt,
|
||||||
|
std::string &error)
|
||||||
|
{
|
||||||
|
using namespace llvm;
|
||||||
|
Triple TheTriple;
|
||||||
|
|
||||||
|
// begin borrow from LLVM 3.2 code
|
||||||
|
// because we don't have 3 argument version of lookup() in 3.1
|
||||||
|
const Target * TheTarget = NULL;
|
||||||
|
|
||||||
|
const std::string ArchName(arch);
|
||||||
|
for (TargetRegistry::iterator it = TargetRegistry::begin(),
|
||||||
|
ie = TargetRegistry::end(); it != ie; ++it) {
|
||||||
|
if (ArchName == it->getName()) {
|
||||||
|
TheTarget = &*it;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TheTarget) {
|
||||||
|
error = "Unknown arch";
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Triple::ArchType Type = Triple::getArchTypeForLLVMName(ArchName);
|
||||||
|
|
||||||
|
if (Type != Triple::UnknownArch){
|
||||||
|
TheTriple.setArch(Type);
|
||||||
|
}
|
||||||
|
// end borrow from LLVM 3.2 code
|
||||||
|
|
||||||
|
if (!TheTarget->hasTargetMachine()){
|
||||||
|
error = "No target machine for the arch";
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
TargetOptions no_target_options;
|
||||||
|
TargetMachine * tm = TheTarget->createTargetMachine(
|
||||||
|
TheTriple.str(), cpu, features,
|
||||||
|
no_target_options,
|
||||||
|
Reloc::Default, CodeModel::Default,
|
||||||
|
OptLevelMap[opt]);
|
||||||
|
|
||||||
|
if (!tm){
|
||||||
|
error = "Cannot create target machine";
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return wrap(tm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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,
|
||||||
|
std::string &error)
|
||||||
{
|
{
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
assert(lenp);
|
assert(lenp);
|
||||||
|
|
||||||
InitializeNativeTargetAsmPrinter();
|
Module *modulep = unwrap(modref);
|
||||||
|
|
||||||
Module *modulep = unwrap(module);
|
|
||||||
assert(modulep);
|
assert(modulep);
|
||||||
|
|
||||||
// get objectcode into a string
|
// get objectcode into a string
|
||||||
|
|
@ -130,17 +213,15 @@ unsigned char* LLVMGetNativeCodeFromModule(LLVMModuleRef module, int assembly,
|
||||||
|
|
||||||
formatted_raw_ostream fso(buf);
|
formatted_raw_ostream fso(buf);
|
||||||
|
|
||||||
TargetMachine * tm = EngineBuilder(modulep).selectTarget();
|
TargetMachine * tm = unwrap(tmref);
|
||||||
|
|
||||||
PassManager pm;
|
PassManager pm;
|
||||||
|
|
||||||
if (!tm->getTargetData()){
|
if (!tm->getTargetData()){
|
||||||
printf("No target data in target machine");
|
error = "No target data in target machine";
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf("%s\n", modulep->getDataLayout().c_str());
|
|
||||||
|
|
||||||
pm.add(new TargetData(*tm->getTargetData()));
|
pm.add(new TargetData(*tm->getTargetData()));
|
||||||
|
|
||||||
bool failed;
|
bool failed;
|
||||||
|
|
@ -151,8 +232,7 @@ unsigned char* LLVMGetNativeCodeFromModule(LLVMModuleRef module, int assembly,
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( failed ) {
|
if ( failed ) {
|
||||||
printf("No support\n");
|
error = "No support for emit file";
|
||||||
printf("%s\n", tm->getTargetData()->getStringRepresentation().c_str());
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -168,6 +248,7 @@ unsigned char* LLVMGetNativeCodeFromModule(LLVMModuleRef module, int assembly,
|
||||||
size_t bclen = bc.size();
|
size_t bclen = bc.size();
|
||||||
unsigned char *bytes = new unsigned char[bclen];
|
unsigned char *bytes = new unsigned char[bclen];
|
||||||
if (!bytes){
|
if (!bytes){
|
||||||
|
error = "Out of memory";
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
memcpy(bytes, bc.data(), bclen);
|
memcpy(bytes, bc.data(), bclen);
|
||||||
|
|
@ -177,6 +258,57 @@ unsigned char* LLVMGetNativeCodeFromModule(LLVMModuleRef module, int assembly,
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* LLVMTargetMachineGetTargetName(LLVMTargetMachineRef tm)
|
||||||
|
{
|
||||||
|
return strdup(llvm::unwrap(tm)->getTarget().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* LLVMTargetMachineGetTargetShortDescription(LLVMTargetMachineRef tm)
|
||||||
|
{
|
||||||
|
return strdup(llvm::unwrap(tm)->getTarget().getShortDescription());
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* LLVMTargetMachineGetTriple(LLVMTargetMachineRef tm)
|
||||||
|
{
|
||||||
|
return strdup(llvm::unwrap(tm)->getTargetTriple().str().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* LLVMTargetMachineGetCPU(LLVMTargetMachineRef tm)
|
||||||
|
{
|
||||||
|
return strdup(llvm::unwrap(tm)->getTargetCPU().str().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* LLVMTargetMachineGetFS(LLVMTargetMachineRef tm)
|
||||||
|
{
|
||||||
|
return strdup(llvm::unwrap(tm)->getTargetFeatureString().str().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLVMPrintRegisteredTargetsForVersion(){
|
||||||
|
llvm::TargetRegistry::printRegisteredTargetsForVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
LLVMTargetDataRef LLVMTargetMachineGetTargetData(LLVMTargetMachineRef tm)
|
||||||
|
{
|
||||||
|
using namespace llvm;
|
||||||
|
return wrap(new TargetData(*unwrap(tm)->getTargetData()));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char* LLVMGetNativeCodeFromModule(LLVMModuleRef module, int assembly,
|
||||||
|
unsigned * lenp, std::string &error)
|
||||||
|
{
|
||||||
|
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, error);
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
llvm::AtomicOrdering atomic_ordering_from_string(const char * ordering)
|
llvm::AtomicOrdering atomic_ordering_from_string(const char * ordering)
|
||||||
|
|
@ -333,15 +465,7 @@ void LLVMEngineBuilderForceInterpreter(LLVMEngineBuilderRef eb)
|
||||||
|
|
||||||
void LLVMEngineBuilderSetOptLevel(LLVMEngineBuilderRef eb, int level)
|
void LLVMEngineBuilderSetOptLevel(LLVMEngineBuilderRef eb, int level)
|
||||||
{
|
{
|
||||||
using namespace llvm;
|
unwrap(eb)->setOptLevel(OptLevelMap[level]);
|
||||||
const CodeGenOpt::Level level_map[] = {
|
|
||||||
CodeGenOpt::None,
|
|
||||||
CodeGenOpt::Less,
|
|
||||||
CodeGenOpt::Default,
|
|
||||||
CodeGenOpt::Aggressive,
|
|
||||||
};
|
|
||||||
|
|
||||||
unwrap(eb)->setOptLevel(level_map[level]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
62
llvm/extra.h
62
llvm/extra.h
|
|
@ -45,11 +45,71 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int LLVMInitializeNativeTargetAsmPrinter();
|
||||||
|
|
||||||
|
|
||||||
|
LLVMTargetMachineRef LLVMTargetMachineLookup(const char *arch, const char *cpu,
|
||||||
|
const char *features, int opt,
|
||||||
|
std::string &error);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wraps EngineBuilder::selectTarget
|
||||||
|
*/
|
||||||
|
LLVMTargetMachineRef LLVMTargetMachineFromEngineBuilder(LLVMEngineBuilderRef eb);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wraps operator delete
|
||||||
|
*/
|
||||||
|
void LLVMDisposeTargetMachine(LLVMTargetMachineRef tm);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wraps TargetMachine::addPassesToEmitFile
|
||||||
|
*/
|
||||||
|
unsigned char* LLVMTargetMachineEmitFile(LLVMTargetMachineRef tmref,
|
||||||
|
LLVMModuleRef modref,
|
||||||
|
int assembly, unsigned * lenp,
|
||||||
|
std::string &error);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wraps TargetMachine::getTargetData
|
||||||
|
*/
|
||||||
|
LLVMTargetDataRef LLVMTargetMachineGetTargetData(LLVMTargetMachineRef tm);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wraps TargetMachine::getTarget().getName()
|
||||||
|
*/
|
||||||
|
const char* LLVMTargetMachineGetTargetName(LLVMTargetMachineRef tm);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wraps TargetMachine::getTarget().getShortDescription()
|
||||||
|
*/
|
||||||
|
const char* LLVMTargetMachineGetTargetShortDescription(LLVMTargetMachineRef tm);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wraps TargetMachine::getTargetTriple
|
||||||
|
*/
|
||||||
|
const char * LLVMTargetMachineGetTriple(LLVMTargetMachineRef tm);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wraps TargetMachine::getTargetCPU
|
||||||
|
*/
|
||||||
|
const char * LLVMTargetMachineGetCPU(LLVMTargetMachineRef tm);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wraps TargetMachine::getTargetFeatureString
|
||||||
|
*/
|
||||||
|
const char * LLVMTargetMachineGetFS(LLVMTargetMachineRef tm);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wraps TargetRegister::printRegisteredTargetsForVersion
|
||||||
|
*/
|
||||||
|
void LLVMPrintRegisteredTargetsForVersion();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wraps TargetMachine::addPassesToEmitFile
|
* Wraps TargetMachine::addPassesToEmitFile
|
||||||
*/
|
*/
|
||||||
unsigned char* LLVMGetNativeCodeFromModule(LLVMModuleRef module, int assembly,
|
unsigned char* LLVMGetNativeCodeFromModule(LLVMModuleRef module, int assembly,
|
||||||
unsigned * lenp);
|
unsigned * lenp, std::string &error);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wraps IRBuilder::CreateFence
|
* Wraps IRBuilder::CreateFence
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ inline ref wrap(const ty *P) { \
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct LLVMOpaqueEngineBuilder *LLVMEngineBuilderRef;
|
typedef struct LLVMOpaqueEngineBuilder *LLVMEngineBuilderRef;
|
||||||
|
typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef;
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@ _define_std_ctor(LLVMGenericValueRef)
|
||||||
|
|
||||||
_define_std_ctor(LLVMPassManagerBuilderRef)
|
_define_std_ctor(LLVMPassManagerBuilderRef)
|
||||||
_define_std_ctor(LLVMEngineBuilderRef)
|
_define_std_ctor(LLVMEngineBuilderRef)
|
||||||
|
_define_std_ctor(LLVMTargetMachineRef)
|
||||||
|
|
||||||
PyObject *ctor_int(int i)
|
PyObject *ctor_int(int i)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
12
llvm/wrap.h
12
llvm/wrap.h
|
|
@ -93,6 +93,7 @@ _declare_std_ctor(LLVMGenericValueRef)
|
||||||
// extra LLVM classes
|
// extra LLVM classes
|
||||||
_declare_std_ctor(LLVMPassManagerBuilderRef)
|
_declare_std_ctor(LLVMPassManagerBuilderRef)
|
||||||
_declare_std_ctor(LLVMEngineBuilderRef)
|
_declare_std_ctor(LLVMEngineBuilderRef)
|
||||||
|
_declare_std_ctor(LLVMTargetMachineRef)
|
||||||
|
|
||||||
/* standard types */
|
/* standard types */
|
||||||
_declare_std_ctor(int)
|
_declare_std_ctor(int)
|
||||||
|
|
@ -145,6 +146,17 @@ PyObject *make_list_from_LLVMValueRef_array(LLVMValueRef *p, unsigned n);
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#define _wrap_none2none(func) \
|
||||||
|
static PyObject * \
|
||||||
|
_w ## func(PyObject * self, PyObject * args) \
|
||||||
|
{ \
|
||||||
|
if (!PyArg_ParseTuple(args, "")) \
|
||||||
|
return NULL; \
|
||||||
|
func(); \
|
||||||
|
Py_RETURN_NONE; \
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrap LLVM functions of the type
|
* Wrap LLVM functions of the type
|
||||||
* outtype func(intype1 arg1)
|
* outtype func(intype1 arg1)
|
||||||
|
|
|
||||||
8
setup.py
8
setup.py
|
|
@ -78,11 +78,15 @@ def call_setup(llvm_config):
|
||||||
incdir = _run(llvm_config + ' --includedir')
|
incdir = _run(llvm_config + ' --includedir')
|
||||||
libdir = _run(llvm_config + ' --libdir')
|
libdir = _run(llvm_config + ' --libdir')
|
||||||
ldflags = _run(llvm_config + ' --ldflags')
|
ldflags = _run(llvm_config + ' --ldflags')
|
||||||
|
|
||||||
|
ptx_components = ['ptx', 'ptxasmprinter', 'ptxcodegen', 'ptxdesc', 'ptxinfo']
|
||||||
|
|
||||||
libs_core, objs_core = get_libs_and_objs(llvm_config,
|
libs_core, objs_core = get_libs_and_objs(llvm_config,
|
||||||
['core', 'analysis', 'scalaropts', 'executionengine',
|
['core', 'analysis', 'scalaropts', 'executionengine',
|
||||||
'jit', 'native', 'interpreter', 'bitreader', 'bitwriter',
|
'jit', 'native', 'interpreter', 'bitreader', 'bitwriter',
|
||||||
'instrumentation', 'ipa', 'ipo', 'transformutils',
|
'instrumentation', 'ipa', 'ipo', 'transformutils',
|
||||||
'asmparser', 'linker', 'support'])
|
'asmparser', 'linker', 'support', 'vectorize']
|
||||||
|
+ ptx_components)
|
||||||
|
|
||||||
std_libs = [ 'pthread', 'm', 'stdc++' ]
|
std_libs = [ 'pthread', 'm', 'stdc++' ]
|
||||||
extra_link_args = ["-fPIC"]
|
extra_link_args = ["-fPIC"]
|
||||||
|
|
@ -91,7 +95,7 @@ def call_setup(llvm_config):
|
||||||
if "darwin" in sys.platform:
|
if "darwin" in sys.platform:
|
||||||
std_libs.append("ffi")
|
std_libs.append("ffi")
|
||||||
extra_link_args += ['-framework', 'Python']
|
extra_link_args += ['-framework', 'Python']
|
||||||
|
|
||||||
|
|
||||||
ext_core = Extension(
|
ext_core = Extension(
|
||||||
'llvm._core',
|
'llvm._core',
|
||||||
|
|
|
||||||
52
test/targetmachines.py
Normal file
52
test/targetmachines.py
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
from llvm.core import *
|
||||||
|
from llvm.ee import TargetMachine, EngineBuilder, print_registered_targets
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
class TestTargetMachines(unittest.TestCase):
|
||||||
|
'''Exercise target machines
|
||||||
|
|
||||||
|
Require PTX backend
|
||||||
|
'''
|
||||||
|
def test_native(self):
|
||||||
|
m, _ = self._build_module()
|
||||||
|
|
||||||
|
tm = EngineBuilder.new(m).select_target()
|
||||||
|
|
||||||
|
self.assertTrue(tm.target_name)
|
||||||
|
self.assertTrue(tm.target_data)
|
||||||
|
self.assertTrue(tm.target_short_description)
|
||||||
|
self.assertTrue(tm.triple)
|
||||||
|
self.assertIn('foo', tm.emit_assembly(m).decode('utf-8'))
|
||||||
|
|
||||||
|
def test_ptx(self):
|
||||||
|
m, func = self._build_module()
|
||||||
|
func.calling_convention = CC_PTX_KERNEL # set calling conv
|
||||||
|
ptxtm = TargetMachine.lookup(arch='ptx64', cpu='compute_20',
|
||||||
|
features='-double')
|
||||||
|
self.assertTrue(ptxtm.triple)
|
||||||
|
self.assertTrue(ptxtm.cpu)
|
||||||
|
self.assertTrue(ptxtm.feature_string)
|
||||||
|
ptxasm = ptxtm.emit_assembly(m).decode('utf-8')
|
||||||
|
self.assertIn('foo', ptxasm)
|
||||||
|
self.assertIn('map_f64_to_f32', ptxasm)
|
||||||
|
self.assertIn('compute_10', ptxasm)
|
||||||
|
|
||||||
|
def _build_module(self):
|
||||||
|
m = Module.new('TestTargetMachines')
|
||||||
|
|
||||||
|
fnty = Type.function(Type.void(), [])
|
||||||
|
func = m.add_function(fnty, name='foo')
|
||||||
|
|
||||||
|
bldr = Builder.new(func.append_basic_block('entry'))
|
||||||
|
bldr.ret_void()
|
||||||
|
m.verify()
|
||||||
|
return m, func
|
||||||
|
|
||||||
|
def _build_bad_archname(self):
|
||||||
|
with self.assertRaises(RuntimeError):
|
||||||
|
tm = TargetMachine.lookup("ain't no arch name")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue