diff --git a/newbinding/gen/binding.py b/newbinding/gen/binding.py index d9b44af..09cd9bf 100644 --- a/newbinding/gen/binding.py +++ b/newbinding/gen/binding.py @@ -69,6 +69,7 @@ LongLong = BuiltinTypes('long long') Float = BuiltinTypes('float') Double = BuiltinTypes('double') Uint64 = BuiltinTypes('uint64_t') +Int64 = BuiltinTypes('int64_t') Size_t = BuiltinTypes('size_t') VoidPtr = BuiltinTypes('void*') Bool = BuiltinTypes('bool') diff --git a/newbinding/include/llvm_binding/conversion.h b/newbinding/include/llvm_binding/conversion.h index a1fc87c..cf4e639 100644 --- a/newbinding/include/llvm_binding/conversion.h +++ b/newbinding/include/llvm_binding/conversion.h @@ -64,6 +64,28 @@ int py_str_to(PyObject *strobj, const char* &strref){ return 1; } + +static +int py_int_to(PyObject *intobj, int64_t & val){ + if (!PyInt_Check(intobj)) { + // raise TypeError + PyErr_SetString(PyExc_TypeError, "Expecting an int"); + return 0; + } + if (PyLong_Check(intobj)) { + val = PyLong_AsLongLong(intobj); + } else { + val = PyInt_AsLong(intobj); + } + if (PyErr_Occurred()){ + return NULL; + } + // success + return 1; +} + + + static int py_int_to(PyObject *intobj, unsigned & val){ if (!PyInt_Check(intobj)) { diff --git a/newbinding/include/llvm_binding/extra.h b/newbinding/include/llvm_binding/extra.h index fd4eb4e..85e1ea5 100644 --- a/newbinding/include/llvm_binding/extra.h +++ b/newbinding/include/llvm_binding/extra.h @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include "auto_pyobject.h" @@ -171,6 +173,33 @@ PyObject* iplist_to_pylist(iplist &IPL, const char * capsuleName, className); } +template +struct extract { + + template + static + bool from_py_sequence(VecTy& vec, PyObject* seq, const char *capsuleName) + { + Py_ssize_t N = PySequence_Size(seq); + for (Py_ssize_t i = 0; i < N; ++i) { + auto_pyobject item = PySequence_GetItem(seq, i); + if (!item) { + return false; + } + auto_pyobject capsule = PyObject_GetAttrString(*item, "_ptr"); + if (!capsule) { + return false; + } + void* ptr = PyCapsule_GetPointer(*capsule, capsuleName); + if (!ptr) { + return false; + } + vec.push_back(static_cast(ptr)); + } + return true; + } + +}; //static //bool string_equal(const char *A, const char *B){ // for (; *A and *B; ++A, ++B) { @@ -492,7 +521,7 @@ PyObject* TargetMachine_addPassesToEmitFile( if (!buf) { return NULL; } - if ( -1 == PyFile_WriteObject(buf, Out, Py_PRINT_RAW) ){ + if (-1 == PyFile_WriteObject(buf, Out, Py_PRINT_RAW)){ return NULL; } Py_RETURN_TRUE; @@ -501,6 +530,30 @@ PyObject* TargetMachine_addPassesToEmitFile( } } +static +PyObject* Constant_getIntegerValue(llvm::Type* Ty, PyObject* pyint) +{ + using namespace llvm; + if (!Ty->isIntegerTy()) { + PyErr_SetString(PyExc_ValueError, "Type should be of integer type."); + return NULL; + } + unsigned width = Ty->getIntegerBitWidth(); + if (width > sizeof(unsigned long long)*8) { + PyErr_SetString(PyExc_ValueError, "Integer value is too large."); + } + Constant* K; + if (PyLong_Check(pyint)){ + APInt apint(width, PyLong_AsLongLong(pyint), true); + K = Constant::getIntegerValue(Ty, apint); + } else { + APInt apint(width, PyInt_AsLong(pyint), true); + K = Constant::getIntegerValue(Ty, apint); + } + return pycapsule_new(K, "llvm::Value", "llvm::Constant"); +} + + static PyObject* Linker_LinkInModule(llvm::Linker* Linker, llvm::Module* Mod, @@ -543,24 +596,8 @@ PyObject* StructType_setBody(llvm::StructType* Self, { using namespace llvm; std::vector elements; - Py_ssize_t N = PySequence_Size(Elems); - elements.reserve(N); - for (Py_ssize_t i=0; i < N; ++i) { - auto_pyobject obj = PySequence_GetItem(Elems, i); - auto_pyobject capsule = PyObject_GetAttrString(*obj, "_ptr"); - if (!capsule) { - return NULL; - } - void * ptr = PyCapsule_GetPointer(*capsule, "llvm::Type"); - if (!ptr) { - return NULL; - } - Type* type = static_cast(ptr); - elements.push_back(type); - } - + extract::from_py_sequence(elements, Elems, "llvm::Type"); Self->setBody(elements, isPacked); - Py_RETURN_NONE; } @@ -578,3 +615,82 @@ PyObject* Module_list_functions(llvm::Module* Mod) "llvm::Value", "llvm::Function"); } +static +PyObject* Module_list_named_metadata(llvm::Module* Mod) +{ + return iplist_to_pylist(Mod->getFunctionList(), + "llvm::NamedMDNode", "llvm::NamedMDNode"); + +} + +static +PyObject* llvm_verifyModule(const llvm::Module& Fn, + llvm::VerifierFailureAction Action, + PyObject* ErrMsg) +{ + std::string errmsg; + bool failed = llvm::verifyModule(Fn, Action, &errmsg); + + if (failed) { + if (-1 == PyFile_WriteString(errmsg.c_str(), ErrMsg)) { + return NULL; + } + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } +} + +static +PyObject* ConstantArray_get(llvm::ArrayType* Ty, PyObject* Consts) +{ + using namespace llvm; + + std::vector vec_consts; + bool ok = extract::from_py_sequence(vec_consts, Consts, + "llvm::Value"); + if (not ok) return NULL; + Constant* ary = ConstantArray::get(Ty, vec_consts); + return pycapsule_new(ary, "llvm::Value", "llvm::Constant"); +} + +static +PyObject* ConstantStruct_get(llvm::StructType* Ty, PyObject* Elems) +{ + using namespace llvm; + + std::vector vec_consts; + bool ok = extract::from_py_sequence(vec_consts, Elems, + "llvm::Value"); + if (not ok) return NULL; + Constant* ary = ConstantStruct::get(Ty, vec_consts); + return pycapsule_new(ary, "llvm::Value", "llvm::Constant"); +} + +static +PyObject* ConstantStruct_getAnon(PyObject* Elems, + bool isPacked=false) +{ + using namespace llvm; + + std::vector vec_consts; + bool ok = extract::from_py_sequence(vec_consts, Elems, + "llvm::Value"); + if (not ok) return NULL; + Constant* ary = ConstantStruct::getAnon(vec_consts, isPacked); + return pycapsule_new(ary, "llvm::Value", "llvm::Constant"); +} + +static +PyObject* ConstantVector_get(PyObject* Elems) +{ + using namespace llvm; + + std::vector vec_consts; + bool ok = extract::from_py_sequence(vec_consts, Elems, + "llvm::Value"); + if (not ok) return NULL; + Constant* ary = ConstantVector::get(vec_consts); + return pycapsule_new(ary, "llvm::Value", "llvm::Constant"); +} + diff --git a/newbinding/src/Analysis/Verifier.py b/newbinding/src/Analysis/Verifier.py new file mode 100644 index 0000000..5b47740 --- /dev/null +++ b/newbinding/src/Analysis/Verifier.py @@ -0,0 +1,25 @@ +from binding import * +from ..namespace import llvm +from ..Module import Module +from ..Function import Function + +llvm.includes.add('llvm/Analysis/Verifier.h') + +VerifierFailureAction = llvm.Enum('VerifierFailureAction', + '''AbortProcessAction + PrintMessageAction + ReturnStatusAction''') + +verifyModule = llvm.CustomFunction('verifyModule', + 'llvm_verifyModule', + PyObjectPtr, # boolean -- failed? + ref(Module), + VerifierFailureAction, + PyObjectPtr, # errmsg + ) + +verifyFunction = llvm.Function('verifyFunction', + cast(Bool, bool), # failed? + ref(Function), + VerifierFailureAction) + diff --git a/newbinding/src/Analysis/__init__.py b/newbinding/src/Analysis/__init__.py new file mode 100644 index 0000000..da0beed --- /dev/null +++ b/newbinding/src/Analysis/__init__.py @@ -0,0 +1,10 @@ +import os.path, importlib + +def _init(): + for fname in os.listdir(os.path.dirname(__file__)): + if ((fname.endswith('.py') or fname.endswith('.pyc')) and + not fname.startswith('__init__')): + modname = os.path.basename(fname).rsplit('.', 1)[0] + importlib.import_module('.' + modname, __name__) + +_init() diff --git a/newbinding/src/Argument.py b/newbinding/src/Argument.py index 08b35be..eac4b07 100644 --- a/newbinding/src/Argument.py +++ b/newbinding/src/Argument.py @@ -1,9 +1,13 @@ from binding import * from namespace import llvm from Value import Argument +from Attributes import Attributes @Argument class Argument: _include_ = 'llvm/Argument.h' + addAttr = Method(Void, ref(Attributes)) + removeAttr = Method(Void, ref(Attributes)) + getParamAlignment = Method(cast(Unsigned, int)) diff --git a/newbinding/src/Attributes.py b/newbinding/src/Attributes.py new file mode 100644 index 0000000..235d2c8 --- /dev/null +++ b/newbinding/src/Attributes.py @@ -0,0 +1,39 @@ +from binding import * +from namespace import llvm +from LLVMContext import LLVMContext + +llvm.includes.add('llvm/Attributes.h') + +Attributes = llvm.Class() +AttrBuilder = llvm.Class() + + +@Attributes +class Attributes: + AttrVal = Enum('''None, AddressSafety, Alignment, AlwaysInline, + ByVal, InlineHint, InReg, MinSize, + Naked, Nest, NoAlias, NoCapture, + NoImplicitFloat, NoInline, NonLazyBind, NoRedZone, + NoReturn, NoUnwind, OptimizeForSize, ReadNone, + ReadOnly, ReturnsTwice, SExt, StackAlignment, + StackProtect, StackProtectReq, StructRet, UWTable, ZExt''') + + delete = Destructor() + + get = Method(Attributes, ref(LLVMContext), ref(AttrBuilder)) + + +@AttrBuilder +class AttrBuilder: + + new = Constructor() + delete = Destructor() + + clear = Method() + + addAttribute = Method(ref(AttrBuilder), Attributes.AttrVal) + removeAttribute = Method(ref(AttrBuilder), Attributes.AttrVal) + + addAlignmentAttr = Method(ref(AttrBuilder), cast(int, Unsigned)) + + diff --git a/newbinding/src/CallingConv.py b/newbinding/src/CallingConv.py new file mode 100644 index 0000000..6d0baea --- /dev/null +++ b/newbinding/src/CallingConv.py @@ -0,0 +1,11 @@ +from binding import * +from namespace import llvm + +@llvm.Class() # actually a namespace +class CallingConv: + ID = Enum(''' + C, Fast, Cold, GHC, FirstTargetCC, X86_StdCall, X86_FastCall, + ARM_APCS, ARM_AAPCS, ARM_AAPCS_VFP, MSP430_INTR, X86_ThisCall, + PTX_Kernel, PTX_Device, MBLAZE_INTR, MBLAZE_SVOL, SPIR_FUNC, + SPIR_KERNEL, Intel_OCL_BI + ''') # HiPE diff --git a/newbinding/src/Constant.py b/newbinding/src/Constant.py index c59fef4..9027e3f 100644 --- a/newbinding/src/Constant.py +++ b/newbinding/src/Constant.py @@ -1,8 +1,266 @@ from binding import * from namespace import llvm -from Value import Constant +from LLVMContext import LLVMContext +from ADT.StringRef import StringRef +from ADT.SmallVector import SmallVector_Value, SmallVector_Unsigned +from Type import Type, IntegerType, ArrayType, StructType +from Value import Constant, Value +from Instruction import CmpInst @Constant class Constant: + _downcast_ = Value + + isNullValue = Method(cast(bool, Bool)) + isAllOnesValue = Method(cast(bool, Bool)) + isNegativeZeroValue = Method(cast(bool, Bool)) + #isZeroValue = Method(cast(bool, Bool)) + canTrap = Method(cast(bool, Bool)) + isThreadDependent = Method(cast(bool, Bool)) + isConstantUsed = Method(cast(bool, Bool)) + + _getAggregateElement_by_int = Method(ptr(Constant), cast(int, Unsigned)) + _getAggregateElement_by_int.realname = 'getAggregateElement' + _getAggregateElement_by_const = Method(ptr(Constant), ptr(Constant)) + _getAggregateElement_by_const.realname = 'getAggregateElement' + + @CustomPythonMethod + def getAggregateElement(self, elt): + if isinstance(elt, Constant): + return self._getAggregateElement_by_const(elt) + else: + return self._getAggregateElement_by_int(elt) + + + removeDeadConstantUsers = Method() + + getNullValue = StaticMethod(ptr(Constant), ptr(Type)) + getAllOnesValue = StaticMethod(ptr(Constant), ptr(Type)) + getIntegerValue = CustomStaticMethod('Constant_getIntegerValue', + PyObjectPtr, # ptr(Constant), + ptr(Type), + PyObjectPtr) + + +UndefValue = llvm.Class(Constant) + +@UndefValue +class UndefValue: + getSequentialElement = Method(ptr(UndefValue)) + getStructElement = Method(ptr(UndefValue), cast(int, Unsigned)) + + _getElementValue_by_const = Method(ptr(UndefValue), ptr(Constant)) + _getElementValue_by_const.realname = 'getElementValue' + + _getElementValue_by_int = Method(ptr(UndefValue), cast(int, Unsigned)) + _getElementValue_by_int.realname = 'getElementValue' + + @CustomPythonMethod + def getElementValue(self, idx): + if isinstance(idx, Constant): + return self._getElementValue_by_const(idx) + else: + return self._getElementValue_by_int(idx) + + destroyConstant = Method() + + get = StaticMethod(ptr(UndefValue), ptr(Type)) + + +ConstantInt = llvm.Class(Constant) + +@ConstantInt +class ConstantInt: + get = StaticMethod(ptr(ConstantInt), + ptr(IntegerType), + cast(int, Unsigned), + cast(bool, Bool), + ).require_only(2) + isValueValidForType = StaticMethod(cast(Bool, bool), + ptr(Type), + cast(int, Int64)) + getZExtValue = Method(cast(Uint64, int)) + getSExtValue = Method(cast(Int64, int)) + +ConstantFP = llvm.Class(Constant) + +@ConstantFP +class ConstantFP: + get = StaticMethod(ptr(Constant), ptr(Type), cast(float, Double)) + getNegativeZero = StaticMethod(ptr(ConstantFP), ptr(Type)) + getInfinity = StaticMethod(ptr(ConstantFP), ptr(Type), cast(bool, Bool)) + + isZero = Method(cast(Bool, bool)) + isNegative = Method(cast(Bool, bool)) + isNaN = Method(cast(Bool, bool)) + + +ConstantArray = llvm.Class(Constant) + +@ConstantArray +class ConstantArray: + get = CustomStaticMethod('ConstantArray_get', + PyObjectPtr, # ptr(Constant), + ptr(ArrayType), + PyObjectPtr, # Constants + ) + +ConstantStruct = llvm.Class(Constant) + +@ConstantStruct +class ConstantStruct: + get = CustomStaticMethod('ConstantStruct_get', + PyObjectPtr, # ptr(Constant) + ptr(StructType), + PyObjectPtr, # Constants + ) + getAnon = CustomStaticMethod('ConstantStruct_getAnon', + PyObjectPtr, # ptr(Constant) + PyObjectPtr, # constants + cast(bool, Bool), # packed + ).require_only(1) + +ConstantVector = llvm.Class(Constant) + +@ConstantVector +class ConstantVector: + get = CustomStaticMethod('ConstantVector_get', + PyObjectPtr, # ptr(Constant) + PyObjectPtr, # constants + ) + +ConstantDataSequential = llvm.Class(Constant) + +@ConstantDataSequential +class ConstantDataSequential: pass +ConstantDataArray = llvm.Class(ConstantDataSequential) + +@ConstantDataArray +class ConstantDataArray: + getString = StaticMethod(ptr(Constant), + ref(LLVMContext), + cast(str, StringRef), + cast(bool, Bool) + ).require_only(2) + + +ConstantExpr = llvm.Class(Constant) + +def _factory(*args): + return StaticMethod(ptr(Constant), *args) + +def _factory_const(*args): + return _factory(ptr(Constant), *args) + +def _factory_const2(*args): + return _factory(ptr(Constant), ptr(Constant), *args) + +def _factory_const_nuw_nsw(): + return _factory_const(cast(bool, Bool), cast(bool, Bool)).require_only(1) + +def _factory_const2_nuw_nsw(): + return _factory_const2(cast(bool, Bool), cast(bool, Bool)).require_only(2) + +def _factory_const2_exact(): + return _factory_const2(cast(bool, Bool)).require_only(2) + +def _factory_const_type(): + return _factory_const(ptr(Type)) + +@ConstantExpr +class ConstantExpr: + getAlignOf = _factory(ptr(Type)) + getSizeOf = _factory(ptr(Type)) + getOffsetOf = _factory(ptr(Type), ptr(Constant)) + getNeg = _factory_const_nuw_nsw() + getFNeg = _factory_const() + getNot = _factory_const() + getAdd = _factory_const2_nuw_nsw() + getFAdd = _factory_const2() + getSub = _factory_const2_nuw_nsw() + getFSub = _factory_const2() + getMul = _factory_const2_nuw_nsw() + getFMul = _factory_const2() + getUDiv = _factory_const2_exact() + getSDiv = _factory_const2_exact() + getFDiv = _factory_const2() + getURem = _factory_const2() + getSRem = _factory_const2() + getFRem = _factory_const2() + getAnd = _factory_const2() + getOr = _factory_const2() + getXor = _factory_const2() + getShl = _factory_const2_nuw_nsw() + getLShr = _factory_const2_exact() + getAShr = _factory_const2_exact() + getTrunc = _factory_const_type() + getSExt = _factory_const_type() + getZExt = _factory_const_type() + getFPTrunc = _factory_const_type() + getFPExtend = _factory_const_type() + getUIToFP = _factory_const_type() + getSIToFP = _factory_const_type() + getFPToUI = _factory_const_type() + getFPToSI = _factory_const_type() + getPtrToInt = _factory_const_type() + getIntToPtr = _factory_const_type() + getBitCast = _factory_const_type() + + getCompare = _factory(CmpInst.Predicate, ptr(Constant), ptr(Constant)) + getICmp = _factory(CmpInst.Predicate, ptr(Constant), ptr(Constant)) + getFCmp = _factory(CmpInst.Predicate, ptr(Constant), ptr(Constant)) + + getPointerCast = _factory_const_type() + getIntegerCast = _factory_const(ptr(Type), cast(bool, Bool)) + getFPCast = _factory_const_type() + getSelect = _factory(ptr(Constant), ptr(Constant), ptr(Constant)) + + + _getGEP = _factory(ptr(Constant), ref(SmallVector_Value), cast(bool, Bool)) + _getGEP.require_only(2) + _getGEP.realname = 'getGetElementPtr' + + @CustomPythonStaticMethod + def getGetElementPtr(*args): + import extra + args = list(args) + valuelist = args[1] + args[1] = extra.make_small_vector_from_values(*valuelist) + return ConstantExpr._getGEP(*args) + + getExtractElement = _factory_const2() + getInsertElement = _factory_const2(ptr(Constant)) + getShuffleVector = _factory_const2(ptr(Constant)) + + _getExtractValue = _factory(ptr(Constant), ref(SmallVector_Unsigned)) + _getExtractValue.realname = 'getExtractValue' + + @CustomPythonStaticMethod + def getExtractValue(*args): + import extra + args = list(args) + valuelist = args[1] + args[1] = extra.make_small_vector_from_unsigned(*valuelist) + return ConstantExpr._getExtractValue(*args) + + _getInsertValue = _factory(ptr(Constant), ptr(Constant), + ref(SmallVector_Unsigned)) + _getInsertValue.realname = 'getInsertValue' + + @CustomPythonStaticMethod + def getInsertValue(*args): + import extra + args = list(args) + valuelist = args[2] + args[1] = extra.make_small_vector_from_unsigned(*valuelist) + return ConstantExpr._getInsertValue(*args) + + getOpcode = Method(cast(Unsigned, int)) + getOpcodeName = Method(cast(ConstCharPtr, str)) + isCast = Method(cast(Bool, bool)) + isCompare = Method(cast(Bool, bool)) + hasIndices = Method(cast(Bool, bool)) + isGEPWithNoNotionalOverIndexing = Method(cast(Bool, bool)) + diff --git a/newbinding/src/DerivedTypes.py b/newbinding/src/DerivedTypes.py index af9e757..e71f1a8 100644 --- a/newbinding/src/DerivedTypes.py +++ b/newbinding/src/DerivedTypes.py @@ -25,7 +25,6 @@ class FunctionType: else: return FunctionType._get(*args) - isVarArg = Method(cast(Bool, bool)) getReturnType = Method(ptr(Type)) getParamType = Method(ptr(Type), cast(int, Unsigned)) diff --git a/newbinding/src/Function.py b/newbinding/src/Function.py index 5cebf84..ee59990 100644 --- a/newbinding/src/Function.py +++ b/newbinding/src/Function.py @@ -4,6 +4,7 @@ from Value import GlobalValue, Constant, Function, Argument from Type import Type from DerivedTypes import FunctionType from LLVMContext import LLVMContext +from CallingConv import CallingConv @Function class Function: @@ -17,5 +18,9 @@ class Function: getIntrinsicID = Method(cast(Unsigned, int)) isIntrinsic = Method(cast(Bool, bool)) + getCallingConv = Method(CallingConv.ID) + setCallingConv = Method(Void, CallingConv.ID) + + getArgumentList = CustomMethod('Function_getArgumentList', PyObjectPtr) getBasicBlockList = CustomMethod('Function_getBasicBlockList', PyObjectPtr) diff --git a/newbinding/src/GlobalValue.py b/newbinding/src/GlobalValue.py index d14d48a..02ba4ea 100644 --- a/newbinding/src/GlobalValue.py +++ b/newbinding/src/GlobalValue.py @@ -1,6 +1,8 @@ from binding import * from namespace import llvm from Value import GlobalValue +from Module import Module +from ADT.StringRef import StringRef @GlobalValue class GlobalValue: @@ -24,3 +26,22 @@ class GlobalValue: setVisibility = Method(Void, VisibilityTypes) getVisibility = Method(VisibilityTypes) + setLinkage = Method(Void, LinkageTypes) + getLinkage = Method(LinkageTypes) + + getAlignment = Method(cast(Unsigned, int)) + setAlignment = Method(Void, cast(int, Unsigned)) + + hasSection = Method(cast(Bool, bool)) + getSection = Method(cast(ConstStdString, str)) + setSection = Method(Void, cast(str, StringRef)) + + isDiscardableIfUnused = Method(cast(Bool, bool)) + mayBeOverridden = Method(cast(Bool, bool)) + isWeakForLinker = Method(cast(Bool, bool)) + copyAttributesFrom = Method(Void, ptr(GlobalValue)) + destroyConstant = Method() + isDeclaration = Method(cast(Bool, bool)) + removeFromParent = Method() + eraseFromParent = Method() + getParent = Method(ptr(Module)) diff --git a/newbinding/src/GlobalVariable.py b/newbinding/src/GlobalVariable.py index 70203d5..a11f259 100644 --- a/newbinding/src/GlobalVariable.py +++ b/newbinding/src/GlobalVariable.py @@ -33,7 +33,7 @@ class GlobalVariable: isThreadLocal = Method(cast(Bool, bool)) isConstant = Method(cast(Bool, bool)) - setConstant = Method(Void, ptr(Constant)) + setConstant = Method(Void, cast(bool, Bool)) setInitializer = Method(Void, ptr(Constant)) getInitializer = Method(ptr(Constant)) @@ -45,4 +45,5 @@ class GlobalVariable: # isExternallyInitialized = Method(cast(Bool, bool)) # setExternallyinitialized = Method(Void, cast(bool, Bool)) + eraseFromParent = Method() \ No newline at end of file diff --git a/newbinding/src/IRBuilder.py b/newbinding/src/IRBuilder.py index 61dd99b..e0cac79 100644 --- a/newbinding/src/IRBuilder.py +++ b/newbinding/src/IRBuilder.py @@ -242,13 +242,32 @@ class IRBuilder: ptr(Value), cast(str, StringRef)) CreateShuffleVector.require_only(3) - CreateExtractValue = Method(ptr(Value), ptr(Value), ref(SmallVector_Unsigned), - cast(str, StringRef)) - CreateExtractValue.require_only(2) + _CreateExtractValue = Method(ptr(Value), ptr(Value), + ref(SmallVector_Unsigned), + cast(str, StringRef)) + _CreateExtractValue.require_only(2) + _CreateExtractValue.realname = 'CreateExtractValue' - CreateInsertValue = Method(ptr(Value), ptr(Value), ptr(Value), + @CustomPythonMethod + def CreateExtractValue(self, args): + import extra + args = list(args) + valuelist = args[1] + args[1] = extra.make_small_vector_from_unsigned(*valuelist) + return self._CreateExtractValue(*args) + + _CreateInsertValue = Method(ptr(Value), ptr(Value), ptr(Value), ref(SmallVector_Unsigned), cast(str, StringRef)) - CreateInsertValue.require_only(3) + _CreateInsertValue.require_only(3) + _CreateInsertValue.realname = 'CreateInsertValue' + + @CustomPythonMethod + def CreateInsertValue(self, args): + import extra + args = list(args) + valuelist = args[2] + args[1] = extra.make_small_vector_from_unsigned(*valuelist) + return self._CreateInsertValue(*args) CreateLandingPad = Method(ptr(LandingPadInst), ptr(Type), ptr(Value), cast(int, Unsigned), cast(str, StringRef)) diff --git a/newbinding/src/Metadata.py b/newbinding/src/Metadata.py index 78dbe15..96dbc01 100644 --- a/newbinding/src/Metadata.py +++ b/newbinding/src/Metadata.py @@ -1,7 +1,24 @@ from binding import * from namespace import llvm from Value import MDNode +from ADT.StringRef import StringRef +from Module import Module +from Support.raw_ostream import raw_ostream +from Assembly.AssemblyAnnotationWriter import AssemblyAnnotationWriter @MDNode class MDNode: pass + +@llvm.Class() +class NamedMDNode: + eraseFromParent = Method() + dropAllReferences = Method() + getParent = Method(ptr(Module)) + getOperand = Method(ptr(MDNode), cast(int, Unsigned)) + getNumOperands = Method(cast(Unsigned, int)) + getName = Method(cast(StringRef, str)) + print_ = Method(Void, ref(raw_ostream), ptr(AssemblyAnnotationWriter)) + print_.realname = "print" + dump = Method() + diff --git a/newbinding/src/Module.py b/newbinding/src/Module.py index 706fe48..7718cd6 100644 --- a/newbinding/src/Module.py +++ b/newbinding/src/Module.py @@ -12,6 +12,7 @@ from DerivedTypes import FunctionType from Support.raw_ostream import raw_ostream from Assembly.AssemblyAnnotationWriter import AssemblyAnnotationWriter from Type import Type, StructType +from Metadata import NamedMDNode @Module class Module: @@ -59,6 +60,16 @@ class Module: # GlobalVariable Iteration list_globals = CustomMethod('Module_list_globals', PyObjectPtr) + # Named MetaData Accessors + getNamedMetadata = Method(ptr(NamedMDNode), cast(str, StringRef)) + getOrInsertNamedMetadata = Method(ptr(NamedMDNode), cast(str, StringRef)) + eraseNamedMetadata = Method(Void, ptr(NamedMDNode)) + + # Named MetaData Iteration + list_named_metadata = CustomMethod('Module_list_named_metadata', + PyObjectPtr) + + # Utilities dump = Method(Void) print_ = Method(Void, ref(raw_ostream), ptr(AssemblyAnnotationWriter)) @@ -74,5 +85,3 @@ class Module: dropAllReferences = Method() getTypeByName = Method(ptr(StructType), cast(str, StringRef)) - - \ No newline at end of file diff --git a/newbinding/src/Transforms/Utils/Cloning.py b/newbinding/src/Transforms/Utils/Cloning.py new file mode 100644 index 0000000..c7f7a86 --- /dev/null +++ b/newbinding/src/Transforms/Utils/Cloning.py @@ -0,0 +1,8 @@ +from binding import * +from src.namespace import llvm +from src.Module import Module + +llvm.includes.add('llvm/Transforms/Utils/Cloning.h') +CloneModule = llvm.Function('CloneModule', ptr(Module), ptr(Module)) + + diff --git a/newbinding/src/Transforms/Utils/__init__.py b/newbinding/src/Transforms/Utils/__init__.py new file mode 100644 index 0000000..98c06fc --- /dev/null +++ b/newbinding/src/Transforms/Utils/__init__.py @@ -0,0 +1,15 @@ +import os.path, importlib + +def _init(): + base = os.path.dirname(__file__) + for fname in os.listdir(base): + print fname + is_python_script = fname.endswith('.py') or fname.endswith('.pyc') + is_init_script = fname.startswith('__init__') + is_directory = os.path.isdir(os.path.join(base, fname)) + if (is_directory or is_python_script) and not is_init_script : + modname = os.path.basename(fname).rsplit('.', 1)[0] + importlib.import_module('.' + modname, __name__) + +_init() + diff --git a/newbinding/src/Transforms/__init__.py b/newbinding/src/Transforms/__init__.py index da0beed..98c06fc 100644 --- a/newbinding/src/Transforms/__init__.py +++ b/newbinding/src/Transforms/__init__.py @@ -1,10 +1,15 @@ import os.path, importlib def _init(): - for fname in os.listdir(os.path.dirname(__file__)): - if ((fname.endswith('.py') or fname.endswith('.pyc')) and - not fname.startswith('__init__')): + base = os.path.dirname(__file__) + for fname in os.listdir(base): + print fname + is_python_script = fname.endswith('.py') or fname.endswith('.pyc') + is_init_script = fname.startswith('__init__') + is_directory = os.path.isdir(os.path.join(base, fname)) + if (is_directory or is_python_script) and not is_init_script : modname = os.path.basename(fname).rsplit('.', 1)[0] importlib.import_module('.' + modname, __name__) _init() + diff --git a/newbinding/src/Type.py b/newbinding/src/Type.py index 09b8ba9..4078a9d 100644 --- a/newbinding/src/Type.py +++ b/newbinding/src/Type.py @@ -9,17 +9,29 @@ IntegerType = llvm.Class(Type) CompositeType = llvm.Class(Type) StructType = llvm.Class(CompositeType) SequentialType = llvm.Class(CompositeType) +ArrayType = llvm.Class(SequentialType) PointerType = llvm.Class(SequentialType) +VectorType = llvm.Class(SequentialType) @Type class Type: _include_ = 'llvm/Type.h' + TypeID = Enum(''' + VoidTyID, HalfTyID, FloatTyID, DoubleTyID, + X86_FP80TyID, FP128TyID, PPC_FP128TyID, LabelTyID, + MetadataTyID, X86_MMXTyID, IntegerTyID, FunctionTyID, + StructTyID, ArrayTyID, PointerTyID, VectorTyID, + NumTypeIDs, LastPrimitiveTyID, FirstDerivedTyID + ''') + getContext = Method(ref(LLVMContext)) dump = Method() print_ = Method(Void, ref(raw_ostream)) print_.realname = 'print' + getTypeID = Method(TypeID) + def type_checker(): return Method(cast(Bool, bool)) @@ -81,7 +93,8 @@ class Type: getPPC_FP128Ty = type_factory() getX86_MMXTy = type_factory() - getIntNTy = StaticMethod(ptr(IntegerType), ref(LLVMContext), cast(Unsigned, int)) + getIntNTy = StaticMethod(ptr(IntegerType), + ref(LLVMContext), cast(Unsigned, int)) def integer_factory(): return StaticMethod(ptr(IntegerType), ref(LLVMContext)) @@ -117,6 +130,20 @@ class Type: self.print_(os) return os.str() + getContainedType = Method(ptr(Type), cast(int, Unsigned)) + getNumContainedTypes = Method(cast(int, Unsigned)) + + getArrayNumElements = Method(cast(Uint64, int)) + getArrayElementType = Method(ptr(Type)) + + getVectorNumElements = Method(cast(Unsigned, int)) + getVectorElementType = Method(ptr(Type)) + + getPointerElementType = Method(ptr(Type)) + getPointerAddressSpace = Method(cast(Unsigned, int)) + getPointerTo = Method(ptr(PointerType), cast(int, Unsigned)) + + @IntegerType class IntegerType: pass @@ -130,9 +157,30 @@ class CompositeType: class SequentialType: pass +@ArrayType +class ArrayType: + getNumElements = Method(cast(Uint64, int)) + get = StaticMethod(ptr(ArrayType), ptr(Type), cast(int, Uint64)) + isValidElementType = StaticMethod(cast(Bool, bool), ptr(Type)) + @PointerType class PointerType: - pass + getAddressSpace = Method(cast(Unsigned, int)) + get = StaticMethod(ptr(PointerType), ptr(Type), cast(int, Unsigned)) + getUnqual = StaticMethod(ptr(PointerType), ptr(Type)) + isValidElementType = StaticMethod(cast(Bool, bool), ptr(Type)) + +@VectorType +class VectorType: + getNumElements = Method(cast(Unsigned, int)) + getBitWidth = Method(cast(Unsigned, int)) + get = StaticMethod(ptr(VectorType), ptr(Type), cast(int, Unsigned)) + getInteger = StaticMethod(ptr(VectorType), ptr(VectorType)) + getExtendedElementVectorType = StaticMethod(ptr(VectorType), + ptr(VectorType)) + getTruncatedElementVectorType = StaticMethod(ptr(VectorType), + ptr(VectorType)) + isValidElementType = StaticMethod(cast(Bool, bool), ptr(Type)) @StructType class StructType: @@ -154,5 +202,12 @@ class StructType: ref(LLVMContext), cast(str, StringRef), ).require_only(1) + + get = StaticMethod(ptr(StructType), + ref(LLVMContext), + cast(bool, Bool), # is packed + ).require_only(1) + + isValidElementType = StaticMethod(cast(Bool, bool), ptr(Type)) diff --git a/newbinding/src/User.py b/newbinding/src/User.py index 57d58bc..9a077c1 100644 --- a/newbinding/src/User.py +++ b/newbinding/src/User.py @@ -1,7 +1,11 @@ from binding import * from namespace import llvm -from Value import User +from Value import Value, User @User class User: - pass + _downcast_ = Value + getOperand = Method(ptr(Value), cast(int, Unsigned)) + setOperand = Method(Void, cast(int, Unsigned), ptr(Value)) + getNumOperands = Method(cast(Unsigned, int)) + diff --git a/newbinding/src/Value.py b/newbinding/src/Value.py index 5675fa5..5d8c0a9 100644 --- a/newbinding/src/Value.py +++ b/newbinding/src/Value.py @@ -21,6 +21,16 @@ from ADT.StringRef import StringRef @Value class Value: + ValueTy = Enum(''' + ArgumentVal, BasicBlockVal, FunctionVal, GlobalAliasVal, + GlobalVariableVal, UndefValueVal, BlockAddressVal, ConstantExprVal, + ConstantAggregateZeroVal, ConstantDataArrayVal, ConstantDataVectorVal, + ConstantIntVal, ConstantFPVal, ConstantArrayVal, ConstantStructVal, + ConstantVectorVal, ConstantPointerNullVal, MDNodeVal, MDStringVal, + InlineAsmVal, PseudoSourceValueVal, FixedStackPseudoSourceValueVal, + InstructionVal, ConstantFirstVal, ConstantLastVal + ''') + dump = Method() print_ = Method(Void, ref(raw_ostream), ptr(AssemblyAnnotationWriter)) @@ -41,6 +51,7 @@ class Value: hasOneUse = Method(cast(Bool, bool)) hasNUses = Method(cast(Bool, bool), cast(int, Unsigned)) isUsedInBasicBlock = Method(cast(Bool, bool), BasicBlock) + getNumUses = Method(cast(Unsigned, int)) @CustomPythonMethod def __str__(self): @@ -48,3 +59,5 @@ class Value: os = extra.make_raw_ostream_for_printing() self.print_(os, None) return os.str() + + getValueID = Method(cast(Unsigned, int))