Add PassRegistry, PassSupport, TargetRegistry, TargetOptions, and functions in Host.h

And a few other fixes
This commit is contained in:
Siu Kwan Lam 2013-02-11 18:13:38 -06:00
commit 2d8c6f0a41
20 changed files with 352 additions and 63 deletions

4
llvmpy/.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
api.cpp
api/*.py
api/*/*.py

View file

@ -102,6 +102,13 @@ def release_ownership(old):
_addr2dtor[addr] = None
def obtain_ownership(cap):
cls = cap.get_class()
if cls._has_dtor():
addr = cap.pointer
assert _addr2dtor[addr] is None
_addr2dtor[addr] = cls._delete_
def has_ownership(cap):
addr = Capsule.getPointer(cap)
return _addr2dtor.get(addr) is not None

View file

@ -34,5 +34,4 @@ private:
void operator = (const auto_pyobject&);
};
#endif AUTO_PYOBJECT_H_
#endif // AUTO_PYOBJECT_H_

View file

@ -7,6 +7,7 @@
#include <llvm/Support/FormattedStream.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/Support/DynamicLibrary.h>
#include <llvm/Support/TargetRegistry.h>
#include <llvm/Bitcode/ReaderWriter.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ExecutionEngine/GenericValue.h>
@ -16,6 +17,9 @@
#include <llvm/Constants.h>
#include <llvm/Intrinsics.h>
#include <llvm/IRBuilder.h>
#include <llvm/PassRegistry.h>
#include <llvm/Support/Host.h>
#include "auto_pyobject.h"
@ -774,3 +778,96 @@ PyObject* DynamicLibrary_LoadLibraryPermanently(const char * Filename,
}
}
class PassRegistryEnumerator : public llvm::PassRegistrationListener{
public:
PyObject* List;
public:
PassRegistryEnumerator(PyObject* list) : List(list) { }
inline virtual void passEnumerate(const llvm::PassInfo * pass_info){
PyObject* passArg = PyString_FromString(pass_info->getPassArgument());
PyObject* passName = PyString_FromString(pass_info->getPassName());
PyList_Append(List, Py_BuildValue("(OO)", passArg, passName));
}
};
static
PyObject* PassRegistry_enumerate(llvm::PassRegistry* PR)
{
using namespace llvm;
PassRegistryEnumerator PRE(PyList_New(0));
PR->enumerateWith(&PRE);
return PRE.List;
}
static
PyObject* TargetRegistry_lookupTarget(const std::string &Triple,
PyObject* Error)
{
using namespace llvm;
std::string error;
const Target* target = TargetRegistry::lookupTarget(Triple, error);
if (!target) {
PyFile_WriteString(error.c_str(), Error);
Py_RETURN_NONE;
} else {
return pycapsule_new(const_cast<Target*>(target), "llvm::Target");
}
}
static
PyObject* TargetRegistry_lookupTarget(const std::string &Arch,
llvm::Triple &Triple,
PyObject* Error)
{
using namespace llvm;
std::string error;
const Target* target = TargetRegistry::lookupTarget(Arch, Triple, error);
if (!target) {
PyFile_WriteString(error.c_str(), Error);
Py_RETURN_NONE;
} else {
return pycapsule_new(const_cast<Target*>(target), "llvm::Target");
}
}
static
PyObject* TargetRegistry_getClosestTargetForJIT(PyObject* Error)
{
using namespace llvm;
std::string error;
const Target* target = TargetRegistry::getClosestTargetForJIT(error);
if (!target) {
PyFile_WriteString(error.c_str(), Error);
Py_RETURN_NONE;
} else {
return pycapsule_new(const_cast<Target*>(target), "llvm::Target");
}
}
static
PyObject* llvm_sys_getHostCPUFeatures(PyObject* Features)
{
using namespace llvm::sys;
using namespace llvm;
typedef StringMap<bool>::iterator iterator;
StringMap<bool> features;
bool ok = getHostCPUFeatures(features);
if (ok) {
for (iterator it = features.begin(); it != features.end(); ++it) {
const char *key = it->getKey().data();
PyObject *val = it->getValue() ? Py_True : Py_False;
Py_INCREF(val);
if (-1 == PyDict_SetItemString(Features, key, val)) {
return NULL;
}
}
Py_RETURN_TRUE;
} else {
Py_RETURN_FALSE;
}
}

View file

@ -1,7 +1,7 @@
from binding import *
from ..namespace import llvm
from ..Module import Module
from ..Function import Function
from ..Value import Function
llvm.includes.add('llvm/Analysis/Verifier.h')

View file

@ -1,15 +1,17 @@
from binding import *
from namespace import llvm
from Pass import ImmutablePass
DataLayout = llvm.Class(ImmutablePass)
StructLayout = llvm.Class()
from LLVMContext import LLVMContext
from ADT.StringRef import StringRef
from Module import Module
from Type import Type, IntegerType, StructType
from ADT.SmallVector import SmallVector_Value
from GlobalVariable import GlobalVariable
from Pass import ImmutablePass
DataLayout = llvm.Class(ImmutablePass)
StructLayout = llvm.Class()
@DataLayout
class DataLayout:
@ -93,4 +95,9 @@ class DataLayout:
@StructLayout
class StructLayout:
pass
getSizeInBytes = Method(cast(Uint64, int))
getSizeInBits = Method(cast(Uint64, int))
getAlignment = Method(cast(Unsigned, int))
getElementContainingOffset = Method(cast(Unsigned, int), cast(int, Uint64))
getElementOffset = Method(cast(Uint64, int), cast(int, Unsigned))
getElementOffsetInBits = Method(cast(Uint64, int), cast(int, Unsigned))

View file

@ -34,16 +34,25 @@ class ExecutionEngine:
Reloc.Model,
CodeModel.Model).require_only(1)
addModule = Method(Void, ptr(Module))
addModule = Method(Void, ownedptr(Module))
getDataLayout = Method(const(ownedptr(DataLayout)))
removeModule = Method(cast(Bool, bool), ptr(Module))
_removeModule = Method(cast(Bool, bool), ptr(Module))
_removeModule.realname = 'removeModule'
@CustomPythonMethod
def removeModule(self, module):
if self._removeModule(module):
capsule.obtain_ownership(module._ptr)
return True
return False
FindFunctionNamed = Method(ptr(Function), cast(str, ConstCharPtr))
getPointerToNamedFunction = Method(cast(VoidPtr, int),
cast(str, StdString),
cast(bool, Bool)).require_only(1)
runStaticConstructorsDestructors = Method(Void, cast(Bool, bool))
runStaticConstructorsDestructors = Method(Void,
cast(Bool, bool), # is dtor
)
runStaticConstructorsDestructors |= Method(Void, ptr(Module),
cast(Bool, bool))

View file

@ -4,10 +4,10 @@ from namespace import llvm
from GlobalValue import GlobalValue
GlobalVariable = llvm.Class(GlobalValue)
from Constant import Constant
from Module import Module
from Type import Type
from ADT.StringRef import StringRef
from Value import Constant
@GlobalVariable
class GlobalVariable:

View file

@ -1,11 +1,6 @@
from binding import *
from namespace import llvm
from Value import Value, MDNode, User, BasicBlock, Function
from ADT.StringRef import StringRef
from CallingConv import CallingConv
from Attributes import Attributes
from Constant import ConstantInt
from Type import Type
Instruction = llvm.Class(User)
@ -68,6 +63,13 @@ SynchronizationScope = llvm.Enum('SynchronizationScope',
from ADT.StringRef import StringRef
from CallingConv import CallingConv
from Attributes import Attributes
from Constant import ConstantInt
from Type import Type
@Instruction
class Instruction:

View file

@ -1,14 +1,14 @@
from binding import *
from namespace import llvm
from ADT.StringRef import StringRef
from Module import Module
from Function import Function
Pass = llvm.Class()
ModulePass = llvm.Class(Pass)
FunctionPass = llvm.Class(Pass)
ImmutablePass = llvm.Class(ModulePass)
from ADT.StringRef import StringRef
from Module import Module
from Value import Function
@Pass
class Pass:
@ -16,7 +16,7 @@ class Pass:
delete = Destructor()
getPassName = Method(cast(StringRef, str))
dump = Method()
@ModulePass
class ModulePass:

View file

@ -2,7 +2,7 @@ from binding import *
from namespace import llvm
from Pass import Pass
from Module import Module
from Function import Function
from Value import Function
PassManagerBase = llvm.Class()
PassManager = llvm.Class(PassManagerBase)

View file

@ -0,0 +1,21 @@
from binding import *
from namespace import llvm
from src.ADT.StringRef import StringRef
PassRegistry = llvm.Class()
from src.PassSupport import PassInfo
@PassRegistry
class PassRegistry:
_include_ = 'llvm/PassRegistry.h'
delete = Destructor()
getPassRegistry = StaticMethod(ownedptr(PassRegistry))
getPassInfo = Method(const(ptr(PassInfo)), cast(str, StringRef))
# This is a custom method that wraps enumerateWith
# Returns list of tuples of (pass-arg, pass-name)
enumerate = CustomMethod('PassRegistry_enumerate', PyObjectPtr)

24
llvmpy/src/PassSupport.py Normal file
View file

@ -0,0 +1,24 @@
from binding import *
from namespace import llvm
PassInfo = llvm.Class()
from src.Pass import Pass
from src.PassRegistry import PassRegistry
@PassInfo
class PassInfo:
_include_ = 'llvm/PassSupport.h'
createPass = Method(ptr(Pass))
llvm.Function('initializeCore', Void, ref(PassRegistry))
llvm.Function('initializeScalarOpts', Void, ref(PassRegistry))
llvm.Function('initializeVectorization', Void, ref(PassRegistry))
llvm.Function('initializeIPO', Void, ref(PassRegistry))
llvm.Function('initializeAnalysis', Void, ref(PassRegistry))
llvm.Function('initializeIPA', Void, ref(PassRegistry))
llvm.Function('initializeTransformUtils', Void, ref(PassRegistry))
llvm.Function('initializeInstCombine', Void, ref(PassRegistry))
llvm.Function('initializeInstrumentation', Void, ref(PassRegistry))
llvm.Function('initializeTarget', Void, ref(PassRegistry))

View file

@ -0,0 +1,25 @@
from binding import *
from src.namespace import sys
isLittleEndianHost = sys.Function('isLittleEndianHost',
cast(Bool, bool))
isBigEndianHost = sys.Function('isBigEndianHost',
cast(Bool, bool))
getDefaultTargetTriple = sys.Function('getDefaultTargetTriple',
cast(ConstStdString, str))
# llvm 3.3
#getProcessTriple = sys.Function('getProcessTriple',
# cast(ConstStdString, str))
getHostCPUName = sys.Function('getHostCPUName',
cast(ConstStdString, str))
getHostCPUFeatures = sys.CustomFunction('getHostCPUFeatures',
'llvm_sys_getHostCPUFeatures',
PyObjectPtr, # bool: success?
PyObjectPtr, # dict: store feature map
)

View file

@ -1,27 +0,0 @@
from binding import *
from ..namespace import llvm
from ..ADT.StringRef import StringRef
Target = llvm.Class()
@Target
class Target:
_include_ = 'llvm/Support/TargetRegistry.h'
getNext = Method(const(ptr(Target)))
getName = Method(cast(StringRef, str))
getShortDescription = Method(cast(StringRef, str))
def _has():
return Method(cast(Bool, bool))
hasJIT = _has()
hasTargetMachine = _has()
hasMCAsmBackend = _has()
hasMCAsmParser = _has()
hasAsmPrinter = _has()
hasMCDisassembler = _has()
hasMCInstPrinter = _has()
hasMCCodeEmitter = _has()
hasMCObjectStreamer = _has()
hasAsmStreamer = _has()

View file

@ -0,0 +1,68 @@
from binding import *
from src.namespace import llvm
llvm.includes.add('llvm/Support/TargetRegistry.h')
Target = llvm.Class()
TargetRegistry = llvm.Class()
from src.ADT.Triple import Triple
from src.ADT.StringRef import StringRef
from src.Target.TargetMachine import TargetMachine
from src.Target.TargetOptions import TargetOptions
from src.Support.CodeGen import Reloc, CodeModel, CodeGenOpt
@Target
class Target:
getNext = Method(const(ptr(Target)))
getName = Method(cast(StringRef, str))
getShortDescription = Method(cast(StringRef, str))
def _has():
return Method(cast(Bool, bool))
hasJIT = _has()
hasTargetMachine = _has()
hasMCAsmBackend = _has()
hasMCAsmParser = _has()
hasAsmPrinter = _has()
hasMCDisassembler = _has()
hasMCInstPrinter = _has()
hasMCCodeEmitter = _has()
hasMCObjectStreamer = _has()
hasAsmStreamer = _has()
createTargetMachine = Method(ptr(TargetMachine),
cast(str, StringRef), # triple
cast(str, StringRef), # cpu
cast(str, StringRef), # features
ref(TargetOptions),
Reloc.Model, # = Reloc::Default
CodeModel.Model, # = CodeModel.Default
CodeGenOpt.Level, # = CodeGenOpt.Default
).require_only(4)
@TargetRegistry
class TargetRegistry:
printRegisteredTargetsForVersion = StaticMethod()
lookupTarget = CustomStaticMethod('TargetRegistry_lookupTarget',
PyObjectPtr, # const Target*
cast(str, ConstCharPtr), # triple
PyObjectPtr, # std::string &Error
)
lookupTarget |= CustomStaticMethod('TargetRegistry_lookupTarget',
PyObjectPtr, # const Target*
cast(str, ConstCharPtr), # arch
ref(Triple), # triple
PyObjectPtr, # std::string &Error
)
getClosestTargetForJIT = CustomStaticMethod(
'TargetRegistry_getClosestTargetForJIT',
PyObjectPtr, # const Target*
PyObjectPtr, # std::string &Error
)

View file

@ -1,8 +1,7 @@
from binding import *
from ..namespace import llvm
from ..ADT.Triple import Triple
from ..Pass import ImmutablePass
from ..ADT.StringRef import StringRef
from src.Pass import ImmutablePass
TargetLibraryInfo = llvm.Class(ImmutablePass)
@ -54,6 +53,10 @@ LibFunc.Enum('Func', '''
# not in llvm-3.2 abs, ffs, ffsl, ffsll, fprintf, isascii,
# isdigit, labs, llabs, printf, sprintf, toascii
from src.ADT.Triple import Triple
from src.ADT.StringRef import StringRef
@TargetLibraryInfo
class TargetLibraryInfo:
_include_ = 'llvm/Target/TargetLibraryInfo.h'

View file

@ -1,17 +1,18 @@
from binding import *
from ..namespace import llvm
from ..ADT.StringRef import StringRef
from ..Support.CodeGen import CodeModel, TLSModel, CodeGenOpt, Reloc
from ..GlobalValue import GlobalValue
from ..Support.Target import Target
from ..DataLayout import DataLayout
from ..TargetTransformInfo import (ScalarTargetTransformInfo,
VectorTargetTransformInfo)
from ..PassManager import PassManagerBase
from ..Support.FormattedStream import formatted_raw_ostream
from src.namespace import llvm
TargetMachine = llvm.Class()
from src.Support.TargetRegistry import Target
from src.ADT.StringRef import StringRef
from src.Support.CodeGen import CodeModel, TLSModel, CodeGenOpt, Reloc
from src.GlobalValue import GlobalValue
from src.DataLayout import DataLayout
from src.TargetTransformInfo import (ScalarTargetTransformInfo,
VectorTargetTransformInfo)
from src.PassManager import PassManagerBase
from src.Support.FormattedStream import formatted_raw_ostream
@TargetMachine
class TargetMachine:
_include_ = 'llvm/Target/TargetMachine.h'

View file

@ -0,0 +1,12 @@
from binding import *
from src.namespace import llvm
llvm.includes.add('llvm/Target/TargetOptions.h')
TargetOptions = llvm.Class()
@TargetOptions
class TargetOptions:
new = Constructor()
delete = Destructor()

View file

@ -7,9 +7,10 @@ import llvmpy.capsule
llvmpy.capsule.set_debug(True)
llvm.InitializeNativeTarget()
llvm.InitializeNativeTargetAsmPrinter()
def test_basic_jit_use():
llvm.InitializeNativeTarget()
llvm.InitializeNativeTargetAsmPrinter()
context = llvm.getGlobalContext()
m = llvm.Module.new("modname", context)
@ -332,6 +333,42 @@ def test_intrinsic():
fn.eraseFromParent()
assert 'llvm.sin.f32' not in str(m)
def test_passregistry():
passreg = llvm.PassRegistry.getPassRegistry()
llvm.initializeScalarOpts(passreg)
passinfo = passreg.getPassInfo("dce")
dcepass = passinfo.createPass()
print dcepass.getPassName()
print passreg.enumerate()
def test_targetregistry():
llvm.TargetRegistry.printRegisteredTargetsForVersion()
errmsg = StringIO()
target = llvm.TargetRegistry.getClosestTargetForJIT(errmsg)
errmsg.close()
print target.getName()
print target.getShortDescription()
assert target.hasJIT()
assert target.hasTargetMachine()
next = target.getNext()
if next:
print next.getName()
print next.getShortDescription()
triple = llvm.sys.getDefaultTargetTriple()
cpu = llvm.sys.getHostCPUName()
features = {}
assert not llvm.sys.getHostCPUFeatures(features), "Only for Linux and ARM?"
targetoptions = llvm.TargetOptions.new()
tm = target.createTargetMachine(triple, cpu, "", targetoptions)
def main():
for name, value in globals().items():
if name.startswith('test_') and callable(value):